Home | History | Annotate | Download | only in libclang
      1 //===- CursorVisitor.h - CursorVisitor interface --------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #ifndef LLVM_CLANG_LIBCLANG_CURSORVISITOR_H
     11 #define LLVM_CLANG_LIBCLANG_CURSORVISITOR_H
     12 
     13 #include "Index_Internal.h"
     14 #include "CXCursor.h"
     15 #include "CXTranslationUnit.h"
     16 
     17 #include "clang/AST/DeclVisitor.h"
     18 #include "clang/AST/TypeLocVisitor.h"
     19 
     20 namespace clang {
     21   class PreprocessingRecord;
     22   class ASTUnit;
     23 
     24 namespace cxcursor {
     25 
     26 class VisitorJob {
     27 public:
     28   enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind,
     29               TypeLocVisitKind, OverloadExprPartsKind,
     30               DeclRefExprPartsKind, LabelRefVisitKind,
     31               ExplicitTemplateArgsVisitKind,
     32               NestedNameSpecifierLocVisitKind,
     33               DeclarationNameInfoVisitKind,
     34               MemberRefVisitKind, SizeOfPackExprPartsKind,
     35               LambdaExprPartsKind };
     36 protected:
     37   void *data[3];
     38   CXCursor parent;
     39   Kind K;
     40   VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
     41     : parent(C), K(k) {
     42     data[0] = d1;
     43     data[1] = d2;
     44     data[2] = d3;
     45   }
     46 public:
     47   Kind getKind() const { return K; }
     48   const CXCursor &getParent() const { return parent; }
     49   static bool classof(VisitorJob *VJ) { return true; }
     50 };
     51 
     52 typedef SmallVector<VisitorJob, 10> VisitorWorkList;
     53 
     54 // Cursor visitor.
     55 class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
     56                       public TypeLocVisitor<CursorVisitor, bool>
     57 {
     58   /// \brief The translation unit we are traversing.
     59   CXTranslationUnit TU;
     60   ASTUnit *AU;
     61 
     62   /// \brief The parent cursor whose children we are traversing.
     63   CXCursor Parent;
     64 
     65   /// \brief The declaration that serves at the parent of any statement or
     66   /// expression nodes.
     67   Decl *StmtParent;
     68 
     69   /// \brief The visitor function.
     70   CXCursorVisitor Visitor;
     71 
     72   /// \brief The opaque client data, to be passed along to the visitor.
     73   CXClientData ClientData;
     74 
     75   /// \brief Whether we should visit the preprocessing record entries last,
     76   /// after visiting other declarations.
     77   bool VisitPreprocessorLast;
     78 
     79   /// \brief Whether we should visit declarations or preprocessing record
     80   /// entries that are #included inside the \arg RegionOfInterest.
     81   bool VisitIncludedEntities;
     82 
     83   /// \brief When valid, a source range to which the cursor should restrict
     84   /// its search.
     85   SourceRange RegionOfInterest;
     86 
     87   /// \brief Whether we should only visit declarations and not preprocessing
     88   /// record entries.
     89   bool VisitDeclsOnly;
     90 
     91   // FIXME: Eventually remove.  This part of a hack to support proper
     92   // iteration over all Decls contained lexically within an ObjC container.
     93   DeclContext::decl_iterator *DI_current;
     94   DeclContext::decl_iterator DE_current;
     95   SmallVectorImpl<Decl *>::iterator *FileDI_current;
     96   SmallVectorImpl<Decl *>::iterator FileDE_current;
     97 
     98   // Cache of pre-allocated worklists for data-recursion walk of Stmts.
     99   SmallVector<VisitorWorkList*, 5> WorkListFreeList;
    100   SmallVector<VisitorWorkList*, 5> WorkListCache;
    101 
    102   using DeclVisitor<CursorVisitor, bool>::Visit;
    103   using TypeLocVisitor<CursorVisitor, bool>::Visit;
    104 
    105   /// \brief Determine whether this particular source range comes before, comes
    106   /// after, or overlaps the region of interest.
    107   ///
    108   /// \param R a half-open source range retrieved from the abstract syntax tree.
    109   RangeComparisonResult CompareRegionOfInterest(SourceRange R);
    110 
    111   void visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length);
    112 
    113   class SetParentRAII {
    114     CXCursor &Parent;
    115     Decl *&StmtParent;
    116     CXCursor OldParent;
    117 
    118   public:
    119     SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent)
    120       : Parent(Parent), StmtParent(StmtParent), OldParent(Parent)
    121     {
    122       Parent = NewParent;
    123       if (clang_isDeclaration(Parent.kind))
    124         StmtParent = getCursorDecl(Parent);
    125     }
    126 
    127     ~SetParentRAII() {
    128       Parent = OldParent;
    129       if (clang_isDeclaration(Parent.kind))
    130         StmtParent = getCursorDecl(Parent);
    131     }
    132   };
    133 
    134 public:
    135   CursorVisitor(CXTranslationUnit TU, CXCursorVisitor Visitor,
    136                 CXClientData ClientData,
    137                 bool VisitPreprocessorLast,
    138                 bool VisitIncludedPreprocessingEntries = false,
    139                 SourceRange RegionOfInterest = SourceRange(),
    140                 bool VisitDeclsOnly = false)
    141     : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
    142       Visitor(Visitor), ClientData(ClientData),
    143       VisitPreprocessorLast(VisitPreprocessorLast),
    144       VisitIncludedEntities(VisitIncludedPreprocessingEntries),
    145       RegionOfInterest(RegionOfInterest),
    146       VisitDeclsOnly(VisitDeclsOnly),
    147       DI_current(0), FileDI_current(0)
    148   {
    149     Parent.kind = CXCursor_NoDeclFound;
    150     Parent.data[0] = 0;
    151     Parent.data[1] = 0;
    152     Parent.data[2] = 0;
    153     StmtParent = 0;
    154   }
    155 
    156   ~CursorVisitor() {
    157     // Free the pre-allocated worklists for data-recursion.
    158     for (SmallVectorImpl<VisitorWorkList*>::iterator
    159           I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) {
    160       delete *I;
    161     }
    162   }
    163 
    164   ASTUnit *getASTUnit() const { return static_cast<ASTUnit*>(TU->TUData); }
    165   CXTranslationUnit getTU() const { return TU; }
    166 
    167   bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
    168 
    169   /// \brief Visit declarations and preprocessed entities for the file region
    170   /// designated by \see RegionOfInterest.
    171   void visitFileRegion();
    172 
    173   bool visitPreprocessedEntitiesInRegion();
    174 
    175   bool shouldVisitIncludedEntities() const {
    176     return VisitIncludedEntities;
    177   }
    178 
    179   template<typename InputIterator>
    180   bool visitPreprocessedEntities(InputIterator First, InputIterator Last,
    181                                  PreprocessingRecord &PPRec,
    182                                  FileID FID = FileID());
    183 
    184   bool VisitChildren(CXCursor Parent);
    185 
    186   // Declaration visitors
    187   bool VisitTypeAliasDecl(TypeAliasDecl *D);
    188   bool VisitAttributes(Decl *D);
    189   bool VisitBlockDecl(BlockDecl *B);
    190   bool VisitCXXRecordDecl(CXXRecordDecl *D);
    191   llvm::Optional<bool> shouldVisitCursor(CXCursor C);
    192   bool VisitDeclContext(DeclContext *DC);
    193   bool VisitTranslationUnitDecl(TranslationUnitDecl *D);
    194   bool VisitTypedefDecl(TypedefDecl *D);
    195   bool VisitTagDecl(TagDecl *D);
    196   bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D);
    197   bool VisitClassTemplatePartialSpecializationDecl(
    198                                      ClassTemplatePartialSpecializationDecl *D);
    199   bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
    200   bool VisitEnumConstantDecl(EnumConstantDecl *D);
    201   bool VisitDeclaratorDecl(DeclaratorDecl *DD);
    202   bool VisitFunctionDecl(FunctionDecl *ND);
    203   bool VisitFieldDecl(FieldDecl *D);
    204   bool VisitVarDecl(VarDecl *);
    205   bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
    206   bool VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
    207   bool VisitClassTemplateDecl(ClassTemplateDecl *D);
    208   bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
    209   bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
    210   bool VisitObjCContainerDecl(ObjCContainerDecl *D);
    211   bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
    212   bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
    213   bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
    214   bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
    215   bool VisitObjCImplDecl(ObjCImplDecl *D);
    216   bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
    217   bool VisitObjCImplementationDecl(ObjCImplementationDecl *D);
    218   // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations.
    219   bool VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD);
    220   bool VisitLinkageSpecDecl(LinkageSpecDecl *D);
    221   bool VisitNamespaceDecl(NamespaceDecl *D);
    222   bool VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
    223   bool VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
    224   bool VisitUsingDecl(UsingDecl *D);
    225   bool VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
    226   bool VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
    227 
    228   // Name visitor
    229   bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
    230   bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
    231   bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
    232 
    233   // Template visitors
    234   bool VisitTemplateParameters(const TemplateParameterList *Params);
    235   bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
    236   bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
    237 
    238   // Type visitors
    239 #define ABSTRACT_TYPELOC(CLASS, PARENT)
    240 #define TYPELOC(CLASS, PARENT) \
    241   bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc);
    242 #include "clang/AST/TypeLocNodes.def"
    243 
    244   bool VisitTagTypeLoc(TagTypeLoc TL);
    245   bool VisitArrayTypeLoc(ArrayTypeLoc TL);
    246   bool VisitFunctionTypeLoc(FunctionTypeLoc TL, bool SkipResultType = false);
    247 
    248   // Data-recursive visitor functions.
    249   bool IsInRegionOfInterest(CXCursor C);
    250   bool RunVisitorWorkList(VisitorWorkList &WL);
    251   void EnqueueWorkList(VisitorWorkList &WL, Stmt *S);
    252   LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
    253 };
    254 
    255 }
    256 }
    257 
    258 #endif
    259 
    260