Files
Sourcetrail/src/lib_cxx/data/parser/cxx/CxxAstVisitor.h
T
malte_langkabel 9ba3cf165c logic: improved indexer coverage for using decls, using directives
* moved source code for solving names of NestedNameSpecifiers to new CxxSpecifierNameResolver.
* implemented recording of UsingDirectives.
* implemented using file as context for using directives and using directive decls if no other context is available.
* re-implemented recording of the auto keyword
2016-11-14 13:16:20 +01:00

167 lines
6.5 KiB
C++

#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(const clang::Decl* d) const;
bool shouldVisitDecl(const clang::Decl* decl);
bool shouldVisitReference(const clang::SourceLocation& referenceLocation, const clang::Decl* contextDecl);
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:
ReferenceKind consumeDeclRefContextKind();
typedef clang::RecursiveASTVisitor<CxxAstVisitor> base;
const clang::NamedDecl* getTopmostContextDecl() const;
NameHierarchy getContextName(const size_t skip = 0) const;
NameHierarchy getContextName(const NameHierarchy& fallback, const size_t 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