src: added optional indexer AST logging

* removed old AstVisitor
* added new implementation called CxxAstVisitor
* added CxxVerboseAstVisitor that may wrap the CxxAstVisitor to log the AST while visiting
* added the same structure for the Java visitors
* removed all the logs that were fired when recording stuff
* Added UI setting for verbose indexer logging.
* implemented AST name obfuscation for Java and Cxx
* unified test visitors for Java and Cxx
* implemented recording using directive decl
* removed most of the old onXxxParsed methods
This commit is contained in:
malte_langkabel
2016-11-01 10:37:30 +01:00
parent a4240def56
commit 9e4a02a33a
36 changed files with 2145 additions and 3208 deletions
+12 -4
View File
@@ -1,10 +1,18 @@
#include "data/parser/cxx/ASTConsumer.h"
#include "data/parser/ParserClient.h"
#include "data/parser/cxx/CxxAstVisitor.h"
#include "data/parser/cxx/CxxVerboseAstVisitor.h"
#include "settings/ApplicationSettings.h"
ASTConsumer::ASTConsumer(clang::ASTContext* context, clang::Preprocessor* preprocessor, ParserClient* client, FileRegister* fileRegister)
: m_visitor(context, preprocessor, client, fileRegister)
{
if (ApplicationSettings::getInstance()->getVerboseInderxerLoggingEnabled())
{
m_visitor = std::make_shared<CxxVerboseAstVisitor>(context, preprocessor, client, fileRegister);
}
else
{
m_visitor = std::make_shared<CxxAstVisitor>(context, preprocessor, client, fileRegister);
}
}
ASTConsumer::~ASTConsumer()
@@ -13,5 +21,5 @@ ASTConsumer::~ASTConsumer()
void ASTConsumer::HandleTranslationUnit(clang::ASTContext& context)
{
m_visitor.indexDecl(context.getTranslationUnitDecl());
m_visitor->indexDecl(context.getTranslationUnitDecl());
}
+4 -3
View File
@@ -4,9 +4,10 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "utility/file/FileRegister.h"
#include "data/parser/cxx/ASTVisitor.h"
class CxxAstVisitor;
class FileRegister;
class ParserClient;
class ASTConsumer
: public clang::ASTConsumer
@@ -18,7 +19,7 @@ public:
virtual void HandleTranslationUnit(clang::ASTContext& context);
private:
ASTVisitor m_visitor;
std::shared_ptr<CxxAstVisitor> m_visitor;
};
#endif // AST_CONSUMER_H
File diff suppressed because it is too large Load Diff
-248
View File
@@ -1,248 +0,0 @@
#ifndef AST_VISITOR_H
#define AST_VISITOR_H
#include <unordered_map>
#include "clang/AST/ASTContext.h"
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/Basic/SourceLocation.h>
#include <clang/Basic/SourceManager.h>
#include "data/parser/ParserClient.h"
#include "data/parser/SymbolKind.h"
#include "utility/file/FileRegister.h"
#include "utility/messaging/MessageInterruptTasksCounter.h"
#include "utility/Cache.h"
class ASTVisitor
: clang::RecursiveASTVisitor<ASTVisitor>
{
public:
typedef Cache<const clang::NamedDecl*, NameHierarchy> DeclNameCache;
typedef Cache<const clang::Type*, NameHierarchy> TypeNameCache;
class ContextNameGenerator
{
public:
virtual ~ContextNameGenerator() {}
virtual NameHierarchy getName() const = 0;
};
class ContextDeclNameGenerator: public ContextNameGenerator
{
public:
ContextDeclNameGenerator(const clang::NamedDecl* decl, std::shared_ptr<DeclNameCache> nameCache)
: m_decl(decl)
, m_nameCache(nameCache)
{}
virtual ~ContextDeclNameGenerator() {}
virtual NameHierarchy getName() const
{
return m_nameCache->getValue(m_decl);
}
private:
const clang::NamedDecl* m_decl;
std::shared_ptr<DeclNameCache> m_nameCache;
};
class ContextTypeNameGenerator: public ContextNameGenerator
{
public:
ContextTypeNameGenerator(const clang::Type* type, std::shared_ptr<TypeNameCache> nameCache)
: m_type(type)
, m_nameCache(nameCache)
{}
virtual ~ContextTypeNameGenerator() {}
virtual NameHierarchy getName() const
{
return m_nameCache->getValue(m_type);
}
private:
const clang::Type* m_type;
std::shared_ptr<TypeNameCache> m_nameCache;
};
ASTVisitor(clang::ASTContext* context, clang::Preprocessor* preprocessor, ParserClient* client, FileRegister* fileRegister);
virtual ~ASTVisitor();
// Left for debugging purposes. Uncomment to see a colored ast-dump of the parsed file.
virtual bool VisitTranslationUnitDecl(clang::TranslationUnitDecl* decl);
void indexDecl(clang::Decl *d) { TraverseDecl(d); }
private:
typedef clang::RecursiveASTVisitor<ASTVisitor> base;
friend class clang::RecursiveASTVisitor<ASTVisitor>;
// XXX: The CF_Read flag is useful mostly for lvalues -- for rvalues, we
// don't set the CF_Read flag, but the rvalue is assumed to be read anyway.
enum ContextFlags {
CF_Called = 0x1, // the value is read only to be called
CF_Read = 0x2, // the value is read for any other use
CF_AddressTaken = 0x4, // the gl-value's address escapes
CF_Assigned = 0x8, // the gl-value is assigned to
CF_Modified = 0x10 // the gl-value is updated (i.e. compound assignment)
};
enum RefType : int {
RT_AddressTaken,
RT_Assigned,
RT_BaseClass,
RT_Called,
RT_Declaration,
RT_DefinedTest,
RT_Definition,
RT_Expansion,
RT_Included,
RT_Initialized,
RT_Modified,
RT_NamespaceAlias,
RT_Other,
RT_Qualifier,
RT_Read,
RT_Reference,
RT_TemplateArgument,
RT_TemplateDefaultArgument,
RT_TemplateSpecialization,
RT_Undefinition,
RT_Using,
RT_UsingDirective,
RT_Max
};
typedef unsigned int Context;
clang::ASTContext* m_context;
clang::Preprocessor* m_preprocessor;
ParserClient* m_client;
FileRegister* m_fileRegister;
Context m_thisContext;
Context m_childContext;
RefType m_typeContext;
// Misc routines
bool shouldVisitTemplateInstantiations() const { return true; }
bool shouldVisitImplicitCode() const { return true; }
// Dispatcher routines
bool TraverseStmt(clang::Stmt *stmt);
bool TraverseType(clang::QualType t);
bool TraverseTypeLoc(clang::TypeLoc tl);
bool TraverseDecl(clang::Decl *d);
bool TraverseLambdaExpr(clang::LambdaExpr* e);
bool TraverseFunctionDecl(clang::FunctionDecl* d);
bool TraverseTypedefDecl(clang::TypedefDecl *d);
bool TraverseTypeAliasDecl(clang::TypeAliasDecl *d);
bool TraverseFieldDecl(clang::FieldDecl *d);
bool TraverseVarDecl(clang::VarDecl *d);
bool TraverseClassTemplateDecl(clang::ClassTemplateDecl* d);
bool TraverseFunctionTemplateDecl(clang::FunctionTemplateDecl* d);
bool TraverseTemplateTypeParmDecl(clang::TemplateTypeParmDecl* d);
bool TraverseTemplateTemplateParmDecl(clang::TemplateTemplateParmDecl* d);
bool TraverseClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl* d);
bool TraverseDeclRefExpr(clang::DeclRefExpr* e);
bool TraverseTemplateSpecializationTypeLoc(clang::TemplateSpecializationTypeLoc loc);
bool TraverseUnresolvedLookupExpr(clang::UnresolvedLookupExpr* e);
bool TraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc);
// Expression context propagation
bool TraverseCallExpr(clang::CallExpr *e) { return TraverseCallCommon(e); }
bool TraverseCXXMemberCallExpr(clang::CXXMemberCallExpr *e) { return TraverseCallCommon(e); }
bool TraverseCXXOperatorCallExpr(clang::CXXOperatorCallExpr *e) { return TraverseCallCommon(e); }
bool TraverseBinComma(clang::BinaryOperator *s);
bool TraverseBinAssign(clang::BinaryOperator *e) { return TraverseAssignCommon(e, CF_Assigned); }
#define OPERATOR(NAME) bool TraverseBin##NAME##Assign(clang::CompoundAssignOperator *e) { return TraverseAssignCommon(e, CF_Modified); }
OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub)
OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
#undef OPERATOR
bool VisitParenExpr(clang::ParenExpr *e) { m_childContext = m_thisContext; return true; }
bool VisitCastExpr(clang::CastExpr *e);
bool VisitUnaryAddrOf(clang::UnaryOperator *e);
bool VisitUnaryDeref(clang::UnaryOperator *e);
bool VisitDeclStmt(clang::DeclStmt *s);
bool VisitReturnStmt(clang::ReturnStmt *s);
bool VisitVarDecl(clang::VarDecl *d);
bool VisitInitListExpr(clang::InitListExpr *e);
bool TraverseConstructorInitializer(clang::CXXCtorInitializer *init);
bool TraverseCallCommon(clang::CallExpr *call);
bool TraverseAssignCommon(clang::BinaryOperator *e, ContextFlags lhsFlag);
// Expression reference recording
bool VisitLambdaExpr(clang::LambdaExpr* e);
bool VisitMemberExpr(clang::MemberExpr *e);
bool VisitDeclRefExpr(clang::DeclRefExpr *e);
bool VisitCXXConstructExpr(clang::CXXConstructExpr *e);
void RecordDeclRefExpr(clang::NamedDecl *d, clang::SourceLocation loc, clang::Expr *e, Context context);
// NestedNameSpecifier handling
bool TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc qualifier);
// Declaration and TypeLoc handling
void traverseDeclContextHelper(clang::DeclContext *d);
bool TraverseCXXRecordDecl(clang::CXXRecordDecl *d);
bool TraverseNamespaceAliasDecl(clang::NamespaceAliasDecl *d);
bool TraverseClassTemplateSpecializationDecl(
clang::ClassTemplateSpecializationDecl *d);
void templateParameterListsHelper(clang::DeclaratorDecl *d);
bool VisitDecl(clang::Decl *d);
bool VisitTypeLoc(clang::TypeLoc tl);
// Reference recording
ParseLocation getDeclRefRange(
clang::NamedDecl *decl,
clang::SourceLocation loc);
void RecordTypeRef(
const clang::Type* type,
clang::SourceLocation beginLoc,
RefType refType,
SymbolKind symbolType = SYMBOL_KIND_MAX);
void RecordDeclRef(
clang::NamedDecl *d,
clang::SourceLocation beginLoc,
RefType refType,
SymbolKind symbolType = SYMBOL_KIND_MAX);
bool isImplicit(clang::Decl* d) const;
bool isLocatedInUnparsedProjectFile(clang::SourceLocation loc);
bool isLocatedInProjectFile(clang::SourceLocation loc);
AccessKind convertAccessType(clang::AccessSpecifier access) const;
ParserClient::AbstractionType getAbstractionType(const clang::CXXMethodDecl* methodDecl) const;
ParseLocation getParseLocationOfRecordBody(clang::RecordDecl* decl) const;
ParseLocation getParseLocationOfFunctionBody(const clang::FunctionDecl* decl) const;
ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const;
NameHierarchy getContextName() const;
struct FileIdHash {
size_t operator()(clang::FileID fileID) const {
return fileID.getHashValue();
}
};
std::unordered_map<const clang::FileID, bool, FileIdHash> m_inUnparsedProjectFileMap;
std::unordered_map<const clang::FileID, bool, FileIdHash> m_inProjectFileMap;
std::shared_ptr<ContextNameGenerator> m_contextNameGenerator;
std::shared_ptr<ContextNameGenerator> m_childContextNameGenerator; // TODO: rename templateArgumentContextNameGenerator
std::shared_ptr<DeclNameCache> m_declNameCache;
std::shared_ptr<TypeNameCache> m_typeNameCache;
AccessKind m_contextAccess;
MessageInterruptTasksCounter m_interruptCounter;
};
#endif // AST_VISITOR_H
File diff suppressed because it is too large Load Diff
+161
View File
@@ -0,0 +1,161 @@
#ifndef CXX_AST_VISITOR_H
#define CXX_AST_VISITOR_H
#include <unordered_map>
#include <vector>
#include "clang/AST/ASTContext.h"
#include <clang/AST/RecursiveASTVisitor.h>
#include "data/parser/cxx/CxxContext.h"
#include "data/parser/AccessKind.h"
#include "data/parser/ReferenceKind.h"
#include "data/parser/SymbolKind.h"
#include "utility/messaging/MessageInterruptTasksCounter.h"
#include "utility/Cache.h"
class ParserClient;
struct ParseLocation;
class FileRegister;
// methods are called in this order:
// TraverseDecl()
// `- TraverseFunctionDecl()
// |- WalkUpFromFunctionDecl()
// | |- WalkUpFromNamedDecl()
// | | |- WalkUpFromDecl()
// | | | `- VisitDecl()
// | | `- VisitNamedDecl()
// | `- VisitFunctionDecl()
// `- TraverseChildNodes()
class ScopedContextKindSetter
{
public:
ScopedContextKindSetter(const ReferenceKind refKind, std::vector<ReferenceKind>* stack)
: m_stack(stack)
{
m_stack->push_back(refKind);
}
~ScopedContextKindSetter()
{
m_stack->pop_back();
}
private:
std::vector<ReferenceKind>* m_stack;
};
class CxxAstVisitor: public clang::RecursiveASTVisitor<CxxAstVisitor>
{
public:
CxxAstVisitor(clang::ASTContext* astContext, clang::Preprocessor* preprocessor, ParserClient* client, FileRegister* fileRegister);
virtual ~CxxAstVisitor();
// Indexing entry point
void indexDecl(clang::Decl *d);
// Visitor options
virtual bool shouldVisitTemplateInstantiations() const;
virtual bool shouldVisitImplicitCode() const;
// Traversal methods. These specify how to traverse the AST and record context info.
virtual bool TraverseDecl(clang::Decl *d);
virtual bool TraverseTypeLoc(clang::TypeLoc tl);
virtual bool TraverseType(clang::QualType t);
virtual bool TraverseStmt(clang::Stmt *stmt);
virtual bool TraverseCXXRecordDecl(clang::CXXRecordDecl *d);
virtual bool TraverseTemplateTypeParmDecl(clang::TemplateTypeParmDecl* d);
virtual bool TraverseTemplateTemplateParmDecl(clang::TemplateTemplateParmDecl* d);
virtual bool TraverseNestedNameSpecifierLoc(clang::NestedNameSpecifierLoc loc);
virtual bool TraverseConstructorInitializer(clang::CXXCtorInitializer* init);
virtual bool TraverseCallExpr(clang::CallExpr* s);
virtual bool TraverseCXXMemberCallExpr(clang::CXXMemberCallExpr* s);
virtual bool TraverseCXXOperatorCallExpr(clang::CXXOperatorCallExpr* s);
virtual bool TraverseCXXConstructExpr(clang::CXXConstructExpr* s);
virtual bool TraverseCXXTemporaryObjectExpr(clang::CXXTemporaryObjectExpr* s);
virtual bool TraverseLambdaExpr(clang::LambdaExpr* s);
virtual bool TraverseFunctionDecl(clang::FunctionDecl* d);
virtual bool TraverseClassTemplateSpecializationDecl(clang::ClassTemplateSpecializationDecl *d);
virtual bool TraverseClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl* d);
virtual bool TraverseDeclRefExpr(clang::DeclRefExpr* s);
virtual bool TraverseTemplateSpecializationTypeLoc(clang::TemplateSpecializationTypeLoc loc);
virtual bool TraverseUnresolvedLookupExpr(clang::UnresolvedLookupExpr* s);
virtual bool TraverseTemplateArgumentLoc(const clang::TemplateArgumentLoc& loc);;
void traverseDeclContextHelper(clang::DeclContext *d);
bool TraverseCallCommon(clang::CallExpr* s);
// Visitor methods. These actually record stuff and store it in the database.
virtual bool VisitTagDecl(clang::TagDecl* d);
virtual bool VisitClassTemplateSpecializationDecl(clang::ClassTemplateSpecializationDecl* d);
virtual bool VisitFunctionDecl(clang::FunctionDecl* d);
virtual bool VisitCXXMethodDecl(clang::CXXMethodDecl* d);
virtual bool VisitVarDecl(clang::VarDecl* d);
virtual bool VisitFieldDecl(clang::FieldDecl* d);
virtual bool VisitTypedefDecl(clang::TypedefDecl* d);
virtual bool VisitTypeAliasDecl(clang::TypeAliasDecl* d);
virtual bool VisitNamespaceDecl(clang::NamespaceDecl* d);
virtual bool VisitNamespaceAliasDecl(clang::NamespaceAliasDecl* d);
virtual bool VisitEnumConstantDecl(clang::EnumConstantDecl* d);
virtual bool VisitUsingDirectiveDecl(clang::UsingDirectiveDecl* d);
virtual bool VisitUsingDecl(clang::UsingDecl* d);
virtual bool VisitNonTypeTemplateParmDecl(clang::NonTypeTemplateParmDecl* d);
virtual bool VisitTemplateTypeParmDecl(clang::TemplateTypeParmDecl* d);
virtual bool VisitTemplateTemplateParmDecl(clang::TemplateTemplateParmDecl* d);
virtual bool VisitTypeLoc(clang::TypeLoc tl);
virtual bool VisitDeclRefExpr(clang::DeclRefExpr* s);
virtual bool VisitMemberExpr(clang::MemberExpr* s);
virtual bool VisitCXXConstructExpr(clang::CXXConstructExpr* s);
virtual bool VisitLambdaExpr(clang::LambdaExpr* s);
virtual bool VisitConstructorInitializer(clang::CXXCtorInitializer* init);
protected:
// General helpers
bool isImplicit(clang::Decl* d) const;
bool shouldVisitDecl(clang::Decl* d);
bool isLocatedInUnparsedProjectFile(clang::SourceLocation loc);
bool isLocatedInProjectFile(clang::SourceLocation loc);
ParseLocation getParseLocationOfTagDeclBody(clang::TagDecl* decl) const;
ParseLocation getParseLocationOfFunctionBody(const clang::FunctionDecl* decl) const;
ParseLocation getParseLocation(const clang::SourceLocation& loc) const;
ParseLocation getParseLocation(const clang::SourceRange& sourceRange) const;
AccessKind convertAccessSpecifier(clang::AccessSpecifier access) const;
SymbolKind convertTagKind(clang::TagTypeKind tagKind);
private:
typedef clang::RecursiveASTVisitor<CxxAstVisitor> base;
NameHierarchy getContextName(const int skip = 0) const;
bool checkIgnoresTypeLoc(const clang::TypeLoc& tl);
struct FileIdHash
{
size_t operator()(clang::FileID fileID) const
{
return fileID.getHashValue();
}
};
clang::ASTContext* m_astContext;
clang::Preprocessor* m_preprocessor;
ParserClient* m_client;
FileRegister* m_fileRegister;
MessageInterruptTasksCounter m_interruptCounter;
ReferenceKind m_typeRefContext;
ReferenceKind m_declRefContext;
std::vector<std::shared_ptr<CxxContext>> m_contextStack;
std::shared_ptr<CxxContext> m_templateArgumentContext;
std::shared_ptr<DeclNameCache> m_declNameCache;
std::shared_ptr<TypeNameCache> m_typeNameCache;
std::unordered_map<const clang::FileID, bool, FileIdHash> m_inUnparsedProjectFileMap;
std::unordered_map<const clang::FileID, bool, FileIdHash> m_inProjectFileMap;
};
#endif // CXX_AST_VISITOR_H
@@ -0,0 +1,35 @@
#include "data/parser/cxx/CxxContext.h"
CxxContext::~CxxContext()
{
}
CxxContextDecl::CxxContextDecl(const clang::NamedDecl* decl, std::shared_ptr<DeclNameCache> nameCache)
: m_decl(decl)
, m_nameCache(nameCache)
{
}
CxxContextDecl::~CxxContextDecl()
{
}
NameHierarchy CxxContextDecl::getName()
{
return m_nameCache->getValue(m_decl);
}
CxxContextType::CxxContextType(const clang::Type* type, std::shared_ptr<TypeNameCache> nameCache)
: m_type(type)
, m_nameCache(nameCache)
{
}
CxxContextType::~CxxContextType()
{
}
NameHierarchy CxxContextType::getName()
{
return m_nameCache->getValue(m_type);
}
+44
View File
@@ -0,0 +1,44 @@
#ifndef CXX_CONTEXT_H
#define CXX_CONTEXT_H
#include <clang/AST/Decl.h>
#include "data/name/NameHierarchy.h"
#include "utility/Cache.h"
typedef Cache<const clang::NamedDecl*, NameHierarchy> DeclNameCache;
typedef Cache<const clang::Type*, NameHierarchy> TypeNameCache;
class CxxContext
{
public:
virtual ~CxxContext();
virtual NameHierarchy getName() = 0;
};
class CxxContextDecl: public CxxContext
{
public:
CxxContextDecl(const clang::NamedDecl* decl, std::shared_ptr<DeclNameCache> nameCache);
virtual ~CxxContextDecl();
virtual NameHierarchy getName();
private:
const clang::NamedDecl* m_decl;
std::shared_ptr<DeclNameCache> m_nameCache;
};
class CxxContextType: public CxxContext
{
public:
CxxContextType(const clang::Type* type, std::shared_ptr<TypeNameCache> nameCache);
virtual ~CxxContextType();
virtual NameHierarchy getName();
private:
const clang::Type* m_type;
std::shared_ptr<TypeNameCache> m_nameCache;
};
#endif // CXX_CONTEXT_H
@@ -0,0 +1,110 @@
#include "data/parser/cxx/CxxVerboseAstVisitor.h"
#include <sstream>
#include <clang/Basic/SourceLocation.h>
#include <clang/Basic/SourceManager.h>
#include "data/parser/ParseLocation.h"
#include "data/parser/ParserClient.h"
#include "utility/file/FileRegister.h"
#include "utility/logging/logging.h"
#include "utility/ScopedSwitcher.h"
CxxVerboseAstVisitor::CxxVerboseAstVisitor(clang::ASTContext* context, clang::Preprocessor* preprocessor, ParserClient* client, FileRegister* fileRegister)
: base(context, preprocessor, client, fileRegister)
, m_indentation(0)
{
}
CxxVerboseAstVisitor::~CxxVerboseAstVisitor()
{
}
bool CxxVerboseAstVisitor::TraverseDecl(clang::Decl *d)
{
if (d)
{
std::stringstream stream;
stream << getIndentString() << d->getDeclKindName() << "Decl";
if (clang::NamedDecl *namedDecl = clang::dyn_cast_or_null<clang::NamedDecl>(d))
{
stream << " [" << obfuscateName(namedDecl->getNameAsString()) << "]";
}
ParseLocation loc = getParseLocation(d->getSourceRange());
stream << " <" << loc.startLineNumber << ":" << loc.startColumnNumber << ", " << loc.endLineNumber << ":" << loc.endColumnNumber << ">";
LOG_INFO_STREAM_BARE(<< "Indexer - " << stream.str());
{
ScopedSwitcher<unsigned int> switcher(m_indentation, m_indentation + 1);
return base::TraverseDecl(d);
}
}
return true;
}
bool CxxVerboseAstVisitor::TraverseStmt(clang::Stmt *stmt)
{
if (stmt)
{
ParseLocation loc = getParseLocation(stmt->getSourceRange());
LOG_INFO_STREAM_BARE(
<< "Indexer - "
<< getIndentString() << stmt->getStmtClassName()
<< " <" << loc.startLineNumber << ":" << loc.startColumnNumber
<< ", " << loc.endLineNumber << ":" << loc.endColumnNumber << ">"
);
{
ScopedSwitcher<unsigned int> switcher(m_indentation, m_indentation + 1);
return base::TraverseStmt(stmt);
}
}
return true;
}
bool CxxVerboseAstVisitor::TraverseType(clang::QualType t)
{
LOG_INFO_STREAM_BARE(<< "Indexer - " << getIndentString() << t->getTypeClassName() << "Type");
{
ScopedSwitcher<unsigned int> switcher(m_indentation, m_indentation + 1);
return base::TraverseType(t);
}
}
bool CxxVerboseAstVisitor::TraverseTypeLoc(clang::TypeLoc tl)
{
ParseLocation loc = getParseLocation(tl.getSourceRange());
LOG_INFO_STREAM_BARE(
<< "Indexer - "
<< getIndentString() << typeLocClassToString(tl)
<< "TypeLoc <" << loc.startLineNumber << ":" << loc.startColumnNumber
<< ", " << loc.endLineNumber << ":" << loc.endColumnNumber << ">"
);
{
ScopedSwitcher<unsigned int> switcher(m_indentation, m_indentation + 1);
return base::TraverseTypeLoc(tl);
}
}
std::string CxxVerboseAstVisitor::getIndentString() const
{
std::string indentString = "";
for (unsigned int i = 0; i < m_indentation; i++)
{
indentString += "| ";
}
return indentString;
}
std::string CxxVerboseAstVisitor::obfuscateName(const std::string& name) const
{
if (name.length() <= 2)
{
return name;
}
return name.substr(0, 1) + ".." + name.substr(name.length() - 1);
}
@@ -0,0 +1,47 @@
#ifndef CXX_VERBOSE_AST_VISITOR_H
#define CXX_VERBOSE_AST_VISITOR_H
#include "clang/AST/TypeLoc.h"
#include "data/parser/cxx/CxxAstVisitor.h"
class ParserClient;
class FileRegister;
class CxxVerboseAstVisitor: public CxxAstVisitor
{
public:
CxxVerboseAstVisitor(clang::ASTContext* context, clang::Preprocessor* preprocessor, ParserClient* client, FileRegister* fileRegister);
virtual ~CxxVerboseAstVisitor();
private:
typedef CxxAstVisitor base;
virtual bool TraverseDecl(clang::Decl *d);
virtual bool TraverseStmt(clang::Stmt *stmt);
virtual bool TraverseType(clang::QualType t);
virtual bool TraverseTypeLoc(clang::TypeLoc tl);
std::string getIndentString() const;
std::string obfuscateName(const std::string& name) const;
std::string typeLocClassToString(clang::TypeLoc tl) const
{
switch(tl.getTypeLocClass())
{
#define STRINGIFY(X) #X
#define ABSTRACT_TYPE(Class, Base)
#define TYPE(Class, Base) \
case clang::TypeLoc::Class: \
return STRINGIFY(Class);
#include "clang/AST/TypeNodes.def"
case clang::TypeLoc::TypeLocClass::Qualified:
return "Qualified";
}
return "";
}
unsigned int m_indentation;
};
#endif // CXX_VERBOSE_AST_VISITOR_H
@@ -55,10 +55,18 @@ void PreprocessorCallbacks::InclusionDirective(
FilePath includedFilePath = FilePath(fileEntry->getName()).canonical();
if (m_fileRegister->hasFilePath(includedFilePath))
{
m_client->onFileIncludeParsed(
getParseLocation(fileNameRange.getAsRange()),
m_fileRegister->getFileInfo(m_currentPath),
m_fileRegister->getFileInfo(includedFilePath)
NameHierarchy referencedNameHierarchy;
referencedNameHierarchy.push(std::make_shared<NameElement>(includedFilePath.fileName()));
NameHierarchy contextNameHierarchy;
contextNameHierarchy.push(std::make_shared<NameElement>(m_currentPath.fileName()));
m_client->recordReference(
REFERENCE_INCLUDE,
referencedNameHierarchy,
contextNameHierarchy,
getParseLocation(fileNameRange.getAsRange())
);
}
}
@@ -77,8 +85,12 @@ void PreprocessorCallbacks::MacroDefined(const clang::Token& macroNameToken, con
NameHierarchy nameHierarchy;
nameHierarchy.push(std::make_shared<NameElement>(macroNameToken.getIdentifierInfo()->getName().str()));
m_client->onMacroDefineParsed(
getParseLocation(macroNameToken), nameHierarchy, getParseLocation(macroDirective->getMacroInfo()));
m_client->recordSymbol(
nameHierarchy,
SYMBOL_MACRO,
getParseLocation(macroNameToken),
getParseLocation(macroDirective->getMacroInfo())
);
}
}
@@ -116,10 +128,20 @@ void PreprocessorCallbacks::onMacroUsage(const clang::Token& macroNameToken)
{
if (!m_currentPath.empty())
{
NameHierarchy nameHierarchy;
nameHierarchy.push(std::make_shared<NameElement>(macroNameToken.getIdentifierInfo()->getName().str()));
const ParseLocation loc = getParseLocation(macroNameToken);
m_client->onMacroExpandParsed(getParseLocation(macroNameToken), nameHierarchy);
NameHierarchy referencedNameHierarchy;
referencedNameHierarchy.push(std::make_shared<NameElement>(macroNameToken.getIdentifierInfo()->getName().str()));
NameHierarchy contextNameHierarchy;
contextNameHierarchy.push(std::make_shared<NameElement>(loc.filePath.fileName()));
m_client->recordReference(
REFERENCE_MACRO_USAGE,
referencedNameHierarchy,
contextNameHierarchy,
loc
);
}
}