logic: add filename info to static global variables (issue #514)

This commit is contained in:
mlangkabel
2017-11-09 17:29:59 +01:00
parent ead9f9a634
commit e7f9940582
14 changed files with 168 additions and 98 deletions
+2 -2
View File
@@ -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);
}
}
@@ -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;
}
@@ -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
+33
View File
@@ -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(