summaryrefslogtreecommitdiff
path: root/clang/tools/libclang/CursorVisitor.h
diff options
context:
space:
mode:
authorCarlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au>2012-10-15 17:10:06 +1100
committerCarlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au>2012-10-15 17:10:06 +1100
commitbe1de4be954c80875ad4108e0a33e8e131b2f2c0 (patch)
tree1fbbecf276bf7c7bdcbb4dd446099d6d90eaa516 /clang/tools/libclang/CursorVisitor.h
parentc4626a62754862d20b41e8a46a3574264ea80e6d (diff)
parentf1bd2e48c5324d3f7cda4090c87f8a5b6f463ce2 (diff)
Merge branch 'master' of ssh://bitbucket.org/czan/honours
Diffstat (limited to 'clang/tools/libclang/CursorVisitor.h')
-rw-r--r--clang/tools/libclang/CursorVisitor.h259
1 files changed, 259 insertions, 0 deletions
diff --git a/clang/tools/libclang/CursorVisitor.h b/clang/tools/libclang/CursorVisitor.h
new file mode 100644
index 0000000..88b70a4
--- /dev/null
+++ b/clang/tools/libclang/CursorVisitor.h
@@ -0,0 +1,259 @@
+//===- CursorVisitor.h - CursorVisitor interface --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIBCLANG_CURSORVISITOR_H
+#define LLVM_CLANG_LIBCLANG_CURSORVISITOR_H
+
+#include "Index_Internal.h"
+#include "CXCursor.h"
+#include "CXTranslationUnit.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 };
+protected:
+ void *data[3];
+ CXCursor parent;
+ Kind K;
+ VisitorJob(CXCursor C, Kind k, void *d1, void *d2 = 0, void *d3 = 0)
+ : 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; }
+ static bool classof(VisitorJob *VJ) { return true; }
+};
+
+typedef SmallVector<VisitorJob, 10> VisitorWorkList;
+
+// Cursor visitor.
+class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
+ public TypeLocVisitor<CursorVisitor, bool>
+{
+ /// \brief The translation unit we are traversing.
+ CXTranslationUnit TU;
+ ASTUnit *AU;
+
+ /// \brief The parent cursor whose children we are traversing.
+ CXCursor Parent;
+
+ /// \brief The declaration that serves at the parent of any statement or
+ /// expression nodes.
+ Decl *StmtParent;
+
+ /// \brief The visitor function.
+ CXCursorVisitor Visitor;
+
+ /// \brief The opaque client data, to be passed along to the visitor.
+ CXClientData ClientData;
+
+ /// \brief Whether we should visit the preprocessing record entries last,
+ /// after visiting other declarations.
+ bool VisitPreprocessorLast;
+
+ /// \brief Whether we should visit declarations or preprocessing record
+ /// entries that are #included inside the \arg RegionOfInterest.
+ bool VisitIncludedEntities;
+
+ /// \brief When valid, a source range to which the cursor should restrict
+ /// its search.
+ SourceRange RegionOfInterest;
+
+ /// \brief 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;
+
+ /// \brief 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);
+
+ void visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length);
+
+ class SetParentRAII {
+ CXCursor &Parent;
+ Decl *&StmtParent;
+ CXCursor OldParent;
+
+ public:
+ SetParentRAII(CXCursor &Parent, 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)
+ : TU(TU), AU(static_cast<ASTUnit*>(TU->TUData)),
+ Visitor(Visitor), ClientData(ClientData),
+ VisitPreprocessorLast(VisitPreprocessorLast),
+ VisitIncludedEntities(VisitIncludedPreprocessingEntries),
+ RegionOfInterest(RegionOfInterest),
+ VisitDeclsOnly(VisitDeclsOnly),
+ DI_current(0), FileDI_current(0)
+ {
+ Parent.kind = CXCursor_NoDeclFound;
+ Parent.data[0] = 0;
+ Parent.data[1] = 0;
+ Parent.data[2] = 0;
+ StmtParent = 0;
+ }
+
+ ~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 static_cast<ASTUnit*>(TU->TUData); }
+ CXTranslationUnit getTU() const { return TU; }
+
+ bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
+
+ /// \brief Visit declarations and preprocessed entities for the file region
+ /// designated by \see RegionOfInterest.
+ void 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 VisitTypeAliasDecl(TypeAliasDecl *D);
+ bool VisitAttributes(Decl *D);
+ bool VisitBlockDecl(BlockDecl *B);
+ bool VisitCXXRecordDecl(CXXRecordDecl *D);
+ llvm::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 VisitObjCMethodDecl(ObjCMethodDecl *ND);
+ bool VisitObjCContainerDecl(ObjCContainerDecl *D);
+ bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
+ bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
+ bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
+ 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);
+
+ // 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, Stmt *S);
+ LLVM_ATTRIBUTE_NOINLINE bool Visit(Stmt *S);
+};
+
+}
+}
+
+#endif
+