123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- //===- CursorVisitor.h - CursorVisitor interface ----------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H
- #define LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H
- #include "CXCursor.h"
- #include "CXTranslationUnit.h"
- #include "Index_Internal.h"
- #include "clang/AST/DeclVisitor.h"
- #include "clang/AST/TypeLocVisitor.h"
- namespace clang {
- class PreprocessingRecord;
- class ASTUnit;
- namespace cxcursor {
- class VisitorJob {
- public:
- enum Kind {
- DeclVisitKind,
- StmtVisitKind,
- MemberExprPartsKind,
- TypeLocVisitKind,
- OverloadExprPartsKind,
- DeclRefExprPartsKind,
- LabelRefVisitKind,
- ExplicitTemplateArgsVisitKind,
- NestedNameSpecifierLocVisitKind,
- DeclarationNameInfoVisitKind,
- MemberRefVisitKind,
- SizeOfPackExprPartsKind,
- LambdaExprPartsKind,
- PostChildrenVisitKind
- };
- protected:
- const void *data[3];
- CXCursor parent;
- Kind K;
- VisitorJob(CXCursor C, Kind k, const void *d1, const void *d2 = nullptr,
- const void *d3 = nullptr)
- : parent(C), K(k) {
- data[0] = d1;
- data[1] = d2;
- data[2] = d3;
- }
- public:
- Kind getKind() const { return K; }
- const CXCursor &getParent() const { return parent; }
- };
- typedef SmallVector<VisitorJob, 10> VisitorWorkList;
- // Cursor visitor.
- class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
- public TypeLocVisitor<CursorVisitor, bool> {
- public:
- /// Callback called after child nodes of a cursor have been visited.
- /// Return true to break visitation or false to continue.
- typedef bool (*PostChildrenVisitorTy)(CXCursor cursor,
- CXClientData client_data);
- private:
- /// The translation unit we are traversing.
- CXTranslationUnit TU;
- ASTUnit *AU;
- /// The parent cursor whose children we are traversing.
- CXCursor Parent;
- /// The declaration that serves at the parent of any statement or
- /// expression nodes.
- const Decl *StmtParent;
- /// The visitor function.
- CXCursorVisitor Visitor;
- PostChildrenVisitorTy PostChildrenVisitor;
- /// The opaque client data, to be passed along to the visitor.
- CXClientData ClientData;
- /// Whether we should visit the preprocessing record entries last,
- /// after visiting other declarations.
- bool VisitPreprocessorLast;
- /// Whether we should visit declarations or preprocessing record
- /// entries that are #included inside the \arg RegionOfInterest.
- bool VisitIncludedEntities;
- /// When valid, a source range to which the cursor should restrict
- /// its search.
- SourceRange RegionOfInterest;
- /// Whether we should only visit declarations and not preprocessing
- /// record entries.
- bool VisitDeclsOnly;
- // FIXME: Eventually remove. This part of a hack to support proper
- // iteration over all Decls contained lexically within an ObjC container.
- DeclContext::decl_iterator *DI_current;
- DeclContext::decl_iterator DE_current;
- SmallVectorImpl<Decl *>::iterator *FileDI_current;
- SmallVectorImpl<Decl *>::iterator FileDE_current;
- // Cache of pre-allocated worklists for data-recursion walk of Stmts.
- SmallVector<VisitorWorkList *, 5> WorkListFreeList;
- SmallVector<VisitorWorkList *, 5> WorkListCache;
- using DeclVisitor<CursorVisitor, bool>::Visit;
- using TypeLocVisitor<CursorVisitor, bool>::Visit;
- /// Determine whether this particular source range comes before, comes
- /// after, or overlaps the region of interest.
- ///
- /// \param R a half-open source range retrieved from the abstract syntax tree.
- RangeComparisonResult CompareRegionOfInterest(SourceRange R);
- bool visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length);
- class SetParentRAII {
- CXCursor &Parent;
- const Decl *&StmtParent;
- CXCursor OldParent;
- public:
- SetParentRAII(CXCursor &Parent, const Decl *&StmtParent, CXCursor NewParent)
- : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) {
- Parent = NewParent;
- if (clang_isDeclaration(Parent.kind))
- StmtParent = getCursorDecl(Parent);
- }
- ~SetParentRAII() {
- Parent = OldParent;
- if (clang_isDeclaration(Parent.kind))
- StmtParent = getCursorDecl(Parent);
- }
- };
- public:
- CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
- CXClientData ClientData, bool VisitPreprocessorLast,
- bool VisitIncludedPreprocessingEntries = false,
- SourceRange RegionOfInterest = SourceRange(),
- bool VisitDeclsOnly = false,
- PostChildrenVisitorTy PostChildrenVisitor = nullptr)
- : TU(TU), AU(cxtu::getASTUnit(TU)), Visitor(Visitor),
- PostChildrenVisitor(PostChildrenVisitor), ClientData(ClientData),
- VisitPreprocessorLast(VisitPreprocessorLast),
- VisitIncludedEntities(VisitIncludedPreprocessingEntries),
- RegionOfInterest(RegionOfInterest), VisitDeclsOnly(VisitDeclsOnly),
- DI_current(nullptr), FileDI_current(nullptr) {
- Parent.kind = CXCursor_NoDeclFound;
- Parent.data[0] = nullptr;
- Parent.data[1] = nullptr;
- Parent.data[2] = nullptr;
- StmtParent = nullptr;
- }
- ~CursorVisitor() {
- // Free the pre-allocated worklists for data-recursion.
- for (SmallVectorImpl<VisitorWorkList *>::iterator I = WorkListCache.begin(),
- E = WorkListCache.end();
- I != E; ++I) {
- delete *I;
- }
- }
- ASTUnit *getASTUnit() const { return AU; }
- CXTranslationUnit getTU() const { return TU; }
- bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
- /// Visit declarations and preprocessed entities for the file region
- /// designated by \see RegionOfInterest.
- bool visitFileRegion();
- bool visitPreprocessedEntitiesInRegion();
- bool shouldVisitIncludedEntities() const { return VisitIncludedEntities; }
- template <typename InputIterator>
- bool visitPreprocessedEntities(InputIterator First, InputIterator Last,
- PreprocessingRecord &PPRec,
- FileID FID = FileID());
- bool VisitChildren(CXCursor Parent);
- // Declaration visitors
- bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
- bool VisitTypeAliasDecl(TypeAliasDecl *D);
- bool VisitAttributes(Decl *D);
- bool VisitBlockDecl(BlockDecl *B);
- bool VisitCXXRecordDecl(CXXRecordDecl *D);
- Optional<bool> shouldVisitCursor(CXCursor C);
- bool VisitDeclContext(DeclContext *DC);
- bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
- bool VisitTypedefDecl(TypedefDecl *D);
- bool VisitTagDecl(TagDecl *D);
- bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
- bool VisitClassTemplatePartialSpecializationDecl(
- ClassTemplatePartialSpecializationDecl *D);
- bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
- bool VisitEnumConstantDecl(EnumConstantDecl *D);
- bool VisitDeclaratorDecl(DeclaratorDecl *DD);
- bool VisitFunctionDecl(FunctionDecl *ND);
- bool VisitFieldDecl(FieldDecl *D);
- bool VisitVarDecl(VarDecl *);
- bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
- bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
- bool VisitClassTemplateDecl(ClassTemplateDecl *D);
- bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
- bool VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
- bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
- bool VisitObjCContainerDecl(ObjCContainerDecl *D);
- bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
- bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
- bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
- bool VisitObjCTypeParamList(ObjCTypeParamList *typeParamList);
- bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
- bool VisitObjCImplDecl(ObjCImplDecl *D);
- bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
- bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
- // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
- bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
- bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
- bool VisitNamespaceDecl(NamespaceDecl *D);
- bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
- bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
- bool VisitUsingDecl(UsingDecl *D);
- bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
- bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
- bool VisitStaticAssertDecl(StaticAssertDecl *D);
- bool VisitFriendDecl(FriendDecl *D);
- bool VisitDecompositionDecl(DecompositionDecl *D);
- // Name visitor
- bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
- bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
- bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
- // Template visitors
- bool VisitTemplateParameters(const TemplateParameterList *Params);
- bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
- bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
- // Type visitors
- #define ABSTRACT_TYPELOC(CLASS, PARENT)
- #define TYPELOC(CLASS, PARENT) bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
- #include "clang/AST/TypeLocNodes.def"
- bool VisitTagTypeLoc(TagTypeLoc TL);
- bool VisitArrayTypeLoc(ArrayTypeLoc TL);
- bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
- // Data-recursive visitor functions.
- bool IsInRegionOfInterest(CXCursor C);
- bool RunVisitorWorkList(VisitorWorkList &WL);
- void EnqueueWorkList(VisitorWorkList &WL, const Stmt *S);
- LLVM_ATTRIBUTE_NOINLINE bool Visit(const Stmt *S);
- private:
- Optional<bool> handleDeclForVisitation(const Decl *D);
- };
- } // namespace cxcursor
- } // namespace clang
- #endif
|