logic: add filename info to static global variables (issue #514)
This commit is contained in:
@@ -72,8 +72,8 @@ add_files(
|
||||
data/parser/cxx/CxxVerboseAstVisitor.h
|
||||
data/parser/cxx/PreprocessorCallbacks.cpp
|
||||
data/parser/cxx/PreprocessorCallbacks.h
|
||||
data/parser/cxx/utilityCxxAstVisitor.cpp
|
||||
data/parser/cxx/utilityCxxAstVisitor.h
|
||||
data/parser/cxx/utilityClang.cpp
|
||||
data/parser/cxx/utilityClang.h
|
||||
|
||||
data/storage/StorageTransformationAnonymousTypedef.cpp
|
||||
data/storage/StorageTransformationAnonymousTypedef.h
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "data/parser/cxx/CommentHandler.h"
|
||||
|
||||
#include "data/parser/cxx/utilityCxxAstVisitor.h"
|
||||
#include "data/parser/cxx/utilityClang.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParserClient.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "data/parser/cxx/CxxAstVisitorComponentTypeRefKind.h"
|
||||
#include "data/parser/cxx/CxxAstVisitorComponentImplicitCode.h"
|
||||
#include "data/parser/cxx/CxxAstVisitorComponentIndexer.h"
|
||||
#include "data/parser/cxx/utilityCxxAstVisitor.h"
|
||||
#include "data/parser/cxx/utilityClang.h"
|
||||
#include "data/parser/ParserClient.h"
|
||||
|
||||
#include "data/parser/ParseLocation.h"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "data/parser/cxx/CxxAstVisitorComponentDeclRefKind.h"
|
||||
#include "data/parser/cxx/CxxAstVisitorComponentTypeRefKind.h"
|
||||
|
||||
#include "data/parser/cxx/utilityCxxAstVisitor.h"
|
||||
#include "data/parser/cxx/utilityClang.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParserClient.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
@@ -140,7 +140,7 @@ void CxxAstVisitorComponentIndexer::beginTraverseLambdaCapture(clang::LambdaExpr
|
||||
if ((!lambdaExpr->isInitCapture(capture)) && (capture->capturesVariable()))
|
||||
{
|
||||
clang::VarDecl* d = capture->getCapturedVar();
|
||||
SymbolKind symbolKind = getSymbolKind(d);
|
||||
SymbolKind symbolKind = utility::getSymbolKind(d);
|
||||
if (symbolKind == SYMBOL_LOCAL_VARIABLE || symbolKind == SYMBOL_PARAMETER)
|
||||
{
|
||||
if (!d->getNameAsString().empty()) // don't record anonymous parameters
|
||||
@@ -228,7 +228,7 @@ void CxxAstVisitorComponentIndexer::visitVarDecl(clang::VarDecl* d)
|
||||
{
|
||||
if (shouldVisitDecl(d))
|
||||
{
|
||||
SymbolKind symbolKind = getSymbolKind(d);
|
||||
SymbolKind symbolKind = utility::getSymbolKind(d);
|
||||
if (symbolKind == SYMBOL_LOCAL_VARIABLE || symbolKind == SYMBOL_PARAMETER)
|
||||
{
|
||||
if (!d->getNameAsString().empty()) // don't record anonymous parameters
|
||||
@@ -765,33 +765,6 @@ ReferenceKind CxxAstVisitorComponentIndexer::consumeDeclRefContextKind()
|
||||
return refKind;
|
||||
}
|
||||
|
||||
SymbolKind CxxAstVisitorComponentIndexer::getSymbolKind(clang::VarDecl* d)
|
||||
{
|
||||
SymbolKind symbolKind = SYMBOL_KIND_MAX;
|
||||
|
||||
if (llvm::isa<clang::ParmVarDecl>(d))
|
||||
{
|
||||
symbolKind = SYMBOL_PARAMETER;
|
||||
}
|
||||
else if (d->getParentFunctionOrMethod() == NULL)
|
||||
{
|
||||
if (d->getAccess() == clang::AS_none)
|
||||
{
|
||||
symbolKind = SYMBOL_GLOBAL_VARIABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
symbolKind = SYMBOL_FIELD;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
symbolKind = SYMBOL_LOCAL_VARIABLE;
|
||||
}
|
||||
|
||||
return symbolKind;
|
||||
}
|
||||
|
||||
bool CxxAstVisitorComponentIndexer::shouldVisitDecl(const clang::Decl* decl)
|
||||
{
|
||||
if (decl)
|
||||
|
||||
@@ -67,7 +67,6 @@ private:
|
||||
ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const;
|
||||
|
||||
ReferenceKind consumeDeclRefContextKind();
|
||||
SymbolKind getSymbolKind(clang::VarDecl* d);
|
||||
|
||||
bool shouldVisitDecl(const clang::Decl* decl);
|
||||
bool shouldVisitReference(const clang::SourceLocation& referenceLocation, const clang::Decl* contextDecl);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Tooling/Tooling.h"
|
||||
|
||||
#include "data/parser/cxx/utilityCxxAstVisitor.h"
|
||||
#include "data/parser/cxx/utilityClang.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ParserClient.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "utility/file/FileSystem.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
|
||||
#include "data/parser/cxx/utilityCxxAstVisitor.h"
|
||||
#include "data/parser/cxx/utilityClang.h"
|
||||
#include "data/parser/ParserClient.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "data/parser/cxx/name_resolver/CxxSpecifierNameResolver.h"
|
||||
#include "data/parser/cxx/name_resolver/CxxTemplateArgumentNameResolver.h"
|
||||
#include "data/parser/cxx/name_resolver/CxxTypeNameResolver.h"
|
||||
#include "data/parser/cxx/utilityClang.h"
|
||||
#include "utility/file/FilePath.h"
|
||||
#include "utility/ScopedSwitcher.h"
|
||||
|
||||
@@ -327,7 +328,40 @@ std::shared_ptr<CxxDeclName> CxxDeclNameResolver::getDeclName(const clang::Named
|
||||
CxxTypeNameResolver typenNameResolver(getIgnoredContextDecls());
|
||||
typenNameResolver.ignoreContextDecl(varDecl);
|
||||
std::shared_ptr<CxxTypeName> typeName = CxxTypeName::makeUnsolvedIfNull(typenNameResolver.getName(varDecl->getType()));
|
||||
return std::make_shared<CxxVariableDeclName>(declNameString, std::vector<std::string>(), typeName, isStatic);
|
||||
|
||||
std::string varName = declNameString;
|
||||
if (utility::getSymbolKind(varDecl) == SYMBOL_GLOBAL_VARIABLE &&
|
||||
varDecl->getStorageClass() == clang::SC_Static)
|
||||
{
|
||||
// if a global variable is static it is only visible in the current translation unit. Therefore if multiple instances of that global variable
|
||||
// may be generated (one for each translation unit) we add the name of the translation unit's source file.
|
||||
// If that global variable definition is const, we add the name of the (maybe header) file that variable is defined in instead. This causes
|
||||
// different instances of the variable that all MUST contain the same value to be merged into a single node in Sourcetrail.
|
||||
std::string scopeFileName = "";
|
||||
{
|
||||
const clang::SourceManager& sourceManager = declaration->getASTContext().getSourceManager();
|
||||
if (varDecl->getType().isConstQualified())
|
||||
{
|
||||
const clang::PresumedLoc& presumedBegin = sourceManager.getPresumedLoc(declaration->getLocStart());
|
||||
scopeFileName = FilePath(presumedBegin.getFilename()).fileName();
|
||||
}
|
||||
else
|
||||
{
|
||||
clang::FileID fileId = sourceManager.getMainFileID();
|
||||
if (fileId.isValid())
|
||||
{
|
||||
const clang::FileEntry* fileEntry = sourceManager.getFileEntryForID(fileId);
|
||||
scopeFileName = FilePath(utility::getFileNameOfFileEntry(fileEntry)).fileName();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!scopeFileName.empty())
|
||||
{
|
||||
varName = declNameString + " (" + scopeFileName + ")";
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_shared<CxxVariableDeclName>(varName, std::vector<std::string>(), typeName, isStatic);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+37
-7
@@ -1,4 +1,4 @@
|
||||
#include "data/parser/cxx/utilityCxxAstVisitor.h"
|
||||
#include "data/parser/cxx/utilityClang.h"
|
||||
|
||||
#include <clang/AST/DeclCXX.h>
|
||||
#include <clang/AST/DeclTemplate.h>
|
||||
@@ -64,7 +64,7 @@ AccessKind utility::convertAccessSpecifier(clang::AccessSpecifier access)
|
||||
}
|
||||
}
|
||||
|
||||
SymbolKind utility::convertTagKind(clang::TagTypeKind tagKind)
|
||||
SymbolKind utility::convertTagKind(const clang::TagTypeKind tagKind)
|
||||
{
|
||||
switch (tagKind)
|
||||
{
|
||||
@@ -81,17 +81,47 @@ SymbolKind utility::convertTagKind(clang::TagTypeKind tagKind)
|
||||
}
|
||||
}
|
||||
|
||||
std::string utility::getFileNameOfFileEntry(const clang::FileEntry* entry)
|
||||
SymbolKind utility::getSymbolKind(const clang::VarDecl* d)
|
||||
{
|
||||
std::string fileName = entry->tryGetRealPathName();
|
||||
if (fileName.empty())
|
||||
SymbolKind symbolKind = SYMBOL_KIND_MAX;
|
||||
|
||||
if (llvm::isa<clang::ParmVarDecl>(d))
|
||||
{
|
||||
fileName = entry->getName();
|
||||
symbolKind = SYMBOL_PARAMETER;
|
||||
}
|
||||
else if (d->getParentFunctionOrMethod() == NULL)
|
||||
{
|
||||
if (d->getAccess() == clang::AS_none)
|
||||
{
|
||||
symbolKind = SYMBOL_GLOBAL_VARIABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
symbolKind = SYMBOL_FIELD;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fileName = FilePath(entry->getName().str()).parentDirectory().concat(FilePath(FilePath(fileName).fileName())).str();
|
||||
symbolKind = SYMBOL_LOCAL_VARIABLE;
|
||||
}
|
||||
|
||||
return symbolKind;
|
||||
}
|
||||
|
||||
std::string utility::getFileNameOfFileEntry(const clang::FileEntry* entry)
|
||||
{
|
||||
std::string fileName = "";
|
||||
if (entry)
|
||||
{
|
||||
fileName = entry->tryGetRealPathName();
|
||||
if (fileName.empty())
|
||||
{
|
||||
fileName = entry->getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
fileName = FilePath(entry->getName().str()).parentDirectory().concat(FilePath(FilePath(fileName).fileName())).str();
|
||||
}
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
+5
-4
@@ -1,5 +1,5 @@
|
||||
#ifndef UTILITY_CXX_AST_VISITOR_H
|
||||
#define UTILITY_CXX_AST_VISITOR_H
|
||||
#ifndef UTILITY_CLANG_H
|
||||
#define UTILITY_CLANG_H
|
||||
|
||||
#include <clang/AST/Decl.h>
|
||||
|
||||
@@ -10,8 +10,9 @@ namespace utility
|
||||
{
|
||||
bool isImplicit(const clang::Decl* d);
|
||||
AccessKind convertAccessSpecifier(clang::AccessSpecifier access);
|
||||
SymbolKind convertTagKind(clang::TagTypeKind tagKind);
|
||||
SymbolKind convertTagKind(const clang::TagTypeKind tagKind);
|
||||
SymbolKind getSymbolKind(const clang::VarDecl* d);
|
||||
std::string getFileNameOfFileEntry(const clang::FileEntry* entry);
|
||||
}
|
||||
|
||||
#endif // UTILITY_CXX_AST_VISITOR_H
|
||||
#endif // UTILITY_CLANG_H
|
||||
@@ -54,6 +54,39 @@ public:
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// test finding symbol definitions and declarations
|
||||
|
||||
void test_cxx_parser_finds_global_variable_declaration()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"int x;\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->globalVariables, "int x <1:5 1:5>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_static_global_variable_declaration()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"static int x;\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->globalVariables, "int x (input.cc) <1:12 1:12>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_static_const_global_variable_declaration()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
"static const int x;\n"
|
||||
);
|
||||
|
||||
TS_ASSERT(utility::containsElement<std::string>(
|
||||
client->globalVariables, "const int x (input.cc) <1:18 1:18>"
|
||||
));
|
||||
}
|
||||
|
||||
void test_cxx_parser_finds_global_class_definition()
|
||||
{
|
||||
std::shared_ptr<TestParserClient> client = parseCode(
|
||||
|
||||
Reference in New Issue
Block a user