brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.1 KiB · d5ab699 Raw
291 lines · c
1//===- CursorVisitor.h - CursorVisitor interface ----------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H10#define LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H11 12#include "CXCursor.h"13#include "CXTranslationUnit.h"14#include "Index_Internal.h"15#include "clang/AST/DeclVisitor.h"16#include "clang/AST/TypeLocVisitor.h"17#include <optional>18 19namespace clang {20class PreprocessingRecord;21class ASTUnit;22 23namespace concepts {24class Requirement;25}26 27namespace cxcursor {28 29class VisitorJob {30public:31  enum Kind {32    DeclVisitKind,33    StmtVisitKind,34    MemberExprPartsKind,35    TypeLocVisitKind,36    OverloadExprPartsKind,37    DeclRefExprPartsKind,38    LabelRefVisitKind,39    ExplicitTemplateArgsVisitKind,40    NestedNameSpecifierLocVisitKind,41    DeclarationNameInfoVisitKind,42    MemberRefVisitKind,43    SizeOfPackExprPartsKind,44    LambdaExprPartsKind,45    ConceptSpecializationExprVisitKind,46    RequiresExprVisitKind,47    PostChildrenVisitKind48  };49 50protected:51  const void *data[3];52  CXCursor parent;53  Kind K;54  VisitorJob(CXCursor C, Kind k, const void *d1, const void *d2 = nullptr,55             const void *d3 = nullptr)56      : parent(C), K(k) {57    data[0] = d1;58    data[1] = d2;59    data[2] = d3;60  }61 62public:63  Kind getKind() const { return K; }64  const CXCursor &getParent() const { return parent; }65};66 67typedef SmallVector<VisitorJob, 10> VisitorWorkList;68 69// Cursor visitor.70class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,71                      public TypeLocVisitor<CursorVisitor, bool> {72public:73  /// Callback called after child nodes of a cursor have been visited.74  /// Return true to break visitation or false to continue.75  typedef bool (*PostChildrenVisitorTy)(CXCursor cursor,76                                        CXClientData client_data);77 78private:79  /// The translation unit we are traversing.80  CXTranslationUnit TU;81  ASTUnit *AU;82 83  /// The parent cursor whose children we are traversing.84  CXCursor Parent;85 86  /// The declaration that serves at the parent of any statement or87  /// expression nodes.88  const Decl *StmtParent;89 90  /// The visitor function.91  CXCursorVisitor Visitor;92 93  PostChildrenVisitorTy PostChildrenVisitor;94 95  /// The opaque client data, to be passed along to the visitor.96  CXClientData ClientData;97 98  /// Whether we should visit the preprocessing record entries last,99  /// after visiting other declarations.100  bool VisitPreprocessorLast;101 102  /// Whether we should visit declarations or preprocessing record103  /// entries that are #included inside the \arg RegionOfInterest.104  bool VisitIncludedEntities;105 106  /// When valid, a source range to which the cursor should restrict107  /// its search.108  SourceRange RegionOfInterest;109 110  /// Whether we should only visit declarations and not preprocessing111  /// record entries.112  bool VisitDeclsOnly;113 114  // FIXME: Eventually remove.  This part of a hack to support proper115  // iteration over all Decls contained lexically within an ObjC container.116  DeclContext::decl_iterator *DI_current;117  DeclContext::decl_iterator DE_current;118  SmallVectorImpl<Decl *>::iterator *FileDI_current;119  SmallVectorImpl<Decl *>::iterator FileDE_current;120 121  // Cache of pre-allocated worklists for data-recursion walk of Stmts.122  SmallVector<VisitorWorkList *, 5> WorkListFreeList;123  SmallVector<VisitorWorkList *, 5> WorkListCache;124 125  using DeclVisitor<CursorVisitor, bool>::Visit;126  using TypeLocVisitor<CursorVisitor, bool>::Visit;127 128  /// Determine whether this particular source range comes before, comes129  /// after, or overlaps the region of interest.130  ///131  /// \param R a half-open source range retrieved from the abstract syntax tree.132  RangeComparisonResult CompareRegionOfInterest(SourceRange R);133 134  bool visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length);135 136  class SetParentRAII {137    CXCursor &Parent;138    const Decl *&StmtParent;139    CXCursor OldParent;140 141  public:142    SetParentRAII(CXCursor &Parent, const Decl *&StmtParent, CXCursor NewParent)143        : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) {144      Parent = NewParent;145      if (clang_isDeclaration(Parent.kind))146        StmtParent = getCursorDecl(Parent);147    }148 149    ~SetParentRAII() {150      Parent = OldParent;151      if (clang_isDeclaration(Parent.kind))152        StmtParent = getCursorDecl(Parent);153    }154  };155 156public:157  CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,158                CXClientData ClientData, bool VisitPreprocessorLast,159                bool VisitIncludedPreprocessingEntries = false,160                SourceRange RegionOfInterest = SourceRange(),161                bool VisitDeclsOnly = false,162                PostChildrenVisitorTy PostChildrenVisitor = nullptr)163      : TU(TU), AU(cxtu::getASTUnit(TU)), Visitor(Visitor),164        PostChildrenVisitor(PostChildrenVisitor), ClientData(ClientData),165        VisitPreprocessorLast(VisitPreprocessorLast),166        VisitIncludedEntities(VisitIncludedPreprocessingEntries),167        RegionOfInterest(RegionOfInterest), VisitDeclsOnly(VisitDeclsOnly),168        DI_current(nullptr), FileDI_current(nullptr) {169    Parent.kind = CXCursor_NoDeclFound;170    Parent.data[0] = nullptr;171    Parent.data[1] = nullptr;172    Parent.data[2] = nullptr;173    StmtParent = nullptr;174  }175 176  ~CursorVisitor() {177    // Free the pre-allocated worklists for data-recursion.178    for (SmallVectorImpl<VisitorWorkList *>::iterator I = WorkListCache.begin(),179                                                      E = WorkListCache.end();180         I != E; ++I) {181      delete *I;182    }183  }184 185  ASTUnit *getASTUnit() const { return AU; }186  CXTranslationUnit getTU() const { return TU; }187 188  bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);189 190  /// Visit declarations and preprocessed entities for the file region191  /// designated by \see RegionOfInterest.192  bool visitFileRegion();193 194  bool visitPreprocessedEntitiesInRegion();195 196  bool shouldVisitIncludedEntities() const { return VisitIncludedEntities; }197 198  template <typename InputIterator>199  bool visitPreprocessedEntities(InputIterator First, InputIterator Last,200                                 PreprocessingRecord &PPRec,201                                 FileID FID = FileID());202 203  bool VisitChildren(CXCursor Parent);204 205  // Declaration visitors206  bool VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);207  bool VisitTypeAliasDecl(TypeAliasDecl *D);208  bool VisitAttributes(Decl *D);209  bool VisitBlockDecl(BlockDecl *B);210  bool VisitCXXRecordDecl(CXXRecordDecl *D);211  std::optional<bool> shouldVisitCursor(CXCursor C);212  bool VisitDeclContext(DeclContext *DC);213  bool VisitTranslationUnitDecl(TranslationUnitDecl *D);214  bool VisitTypedefDecl(TypedefDecl *D);215  bool VisitTagDecl(TagDecl *D);216  bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);217  bool VisitClassTemplatePartialSpecializationDecl(218      ClassTemplatePartialSpecializationDecl *D);219  bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);220  bool VisitEnumConstantDecl(EnumConstantDecl *D);221  bool VisitDeclaratorDecl(DeclaratorDecl *DD);222  bool VisitFunctionDecl(FunctionDecl *ND);223  bool VisitFieldDecl(FieldDecl *D);224  bool VisitVarDecl(VarDecl *);225  bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);226  bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);227  bool VisitClassTemplateDecl(ClassTemplateDecl *D);228  bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);229  bool VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);230  bool VisitObjCMethodDecl(ObjCMethodDecl *ND);231  bool VisitObjCContainerDecl(ObjCContainerDecl *D);232  bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);233  bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);234  bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);235  bool VisitObjCTypeParamList(ObjCTypeParamList *typeParamList);236  bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);237  bool VisitObjCImplDecl(ObjCImplDecl *D);238  bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);239  bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);240  // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.241  bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);242  bool VisitLinkageSpecDecl(LinkageSpecDecl *D);243  bool VisitNamespaceDecl(NamespaceDecl *D);244  bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);245  bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);246  bool VisitUsingDecl(UsingDecl *D);247  bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);248  bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);249  bool VisitStaticAssertDecl(StaticAssertDecl *D);250  bool VisitFriendDecl(FriendDecl *D);251  bool VisitDecompositionDecl(DecompositionDecl *D);252  bool VisitConceptDecl(ConceptDecl *D);253  bool VisitTypeConstraint(const TypeConstraint &TC);254  bool VisitConceptRequirement(const concepts::Requirement &R);255 256  // Name visitor257  bool VisitDeclarationNameInfo(DeclarationNameInfo Name);258  bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);259 260  // Template visitors261  bool VisitTemplateParameters(const TemplateParameterList *Params);262  bool VisitTemplateName(TemplateName Name, SourceLocation NameLoc,263                         NestedNameSpecifierLoc NNS);264  bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);265 266  // Type visitors267#define ABSTRACT_TYPELOC(CLASS, PARENT)268#define TYPELOC(CLASS, PARENT) bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);269#include "clang/AST/TypeLocNodes.def"270 271  bool VisitTagTypeLoc(TagTypeLoc TL);272  bool VisitArrayTypeLoc(ArrayTypeLoc TL);273  bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);274 275  // Data-recursive visitor functions.276  bool IsInRegionOfInterest(CXCursor C);277  bool RunVisitorWorkList(VisitorWorkList &WL);278  void EnqueueWorkList(VisitorWorkList &WL, const Stmt *S);279  void EnqueueWorkList(VisitorWorkList &WL, const Attr *A);280  LLVM_ATTRIBUTE_NOINLINE bool Visit(const Stmt *S);281  LLVM_ATTRIBUTE_NOINLINE bool Visit(const Attr *A);282 283private:284  std::optional<bool> handleDeclForVisitation(const Decl *D);285};286 287} // namespace cxcursor288} // namespace clang289 290#endif291