From 52d87a6f824ac6fd2ac2bc22b676b10d59e873a7 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Thu, 3 Nov 2011 19:02:34 +0000 Subject: [PATCH] [libclang] Move CursorVisitor to its own header. llvm-svn: 143639 --- clang/tools/libclang/CIndex.cpp | 240 +----------------------- clang/tools/libclang/CursorVisitor.h | 251 ++++++++++++++++++++++++++ clang/tools/libclang/Index_Internal.h | 12 ++ 3 files changed, 264 insertions(+), 239 deletions(-) create mode 100644 clang/tools/libclang/CursorVisitor.h diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 8deb85c99c21..bf5607b5300a 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -19,12 +19,11 @@ #include "CXType.h" #include "CXSourceLocation.h" #include "CIndexDiagnostic.h" +#include "CursorVisitor.h" #include "clang/Basic/Version.h" -#include "clang/AST/DeclVisitor.h" #include "clang/AST/StmtVisitor.h" -#include "clang/AST/TypeLocVisitor.h" #include "clang/Basic/Diagnostic.h" #include "clang/Frontend/ASTUnit.h" #include "clang/Frontend/CompilerInstance.h" @@ -67,18 +66,6 @@ cxtu::CXTUOwner::~CXTUOwner() { clang_disposeTranslationUnit(TU); } -/// \brief The result of comparing two source ranges. -enum RangeComparisonResult { - /// \brief Either the ranges overlap or one of the ranges is invalid. - RangeOverlap, - - /// \brief The first range ends before the second range starts. - RangeBefore, - - /// \brief The first range starts after the second range ends. - RangeAfter -}; - /// \brief Compare two source ranges to determine their relative position in /// the translation unit. static RangeComparisonResult RangeCompare(SourceManager &SM, @@ -139,231 +126,6 @@ CXSourceRange cxloc::translateSourceRange(const SourceManager &SM, // Cursor visitor. //===----------------------------------------------------------------------===// -namespace { - -class VisitorJob { -public: - enum Kind { DeclVisitKind, StmtVisitKind, MemberExprPartsKind, - TypeLocVisitKind, OverloadExprPartsKind, - DeclRefExprPartsKind, LabelRefVisitKind, - ExplicitTemplateArgsVisitKind, - NestedNameSpecifierLocVisitKind, - DeclarationNameInfoVisitKind, - MemberRefVisitKind, SizeOfPackExprPartsKind }; -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 VisitorWorkList; - -// Cursor visitor. -class CursorVisitor : public DeclVisitor, - public TypeLocVisitor -{ - /// \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; - - // 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; - - // Cache of pre-allocated worklists for data-recursion walk of Stmts. - SmallVector WorkListFreeList; - SmallVector WorkListCache; - - using DeclVisitor::Visit; - using TypeLocVisitor::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()) - : TU(TU), AU(static_cast(TU->TUData)), - Visitor(Visitor), ClientData(ClientData), - VisitPreprocessorLast(VisitPreprocessorLast), - VisitIncludedEntities(VisitIncludedPreprocessingEntries), - RegionOfInterest(RegionOfInterest), DI_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::iterator - I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) { - delete *I; - } - } - - ASTUnit *getASTUnit() const { return static_cast(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 - 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 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 VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); - bool VisitObjCClassDecl(ObjCClassDecl *D); - 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); -}; - -} // end anonymous namespace - static SourceRange getRawCursorExtent(CXCursor C); static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr); diff --git a/clang/tools/libclang/CursorVisitor.h b/clang/tools/libclang/CursorVisitor.h new file mode 100644 index 000000000000..eaefd83716d4 --- /dev/null +++ b/clang/tools/libclang/CursorVisitor.h @@ -0,0 +1,251 @@ +//===- 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 }; +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 VisitorWorkList; + +// Cursor visitor. +class CursorVisitor : public DeclVisitor, + public TypeLocVisitor +{ + /// \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; + + // 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; + + // Cache of pre-allocated worklists for data-recursion walk of Stmts. + SmallVector WorkListFreeList; + SmallVector WorkListCache; + + using DeclVisitor::Visit; + using TypeLocVisitor::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()) + : TU(TU), AU(static_cast(TU->TUData)), + Visitor(Visitor), ClientData(ClientData), + VisitPreprocessorLast(VisitPreprocessorLast), + VisitIncludedEntities(VisitIncludedPreprocessingEntries), + RegionOfInterest(RegionOfInterest), DI_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::iterator + I = WorkListCache.begin(), E = WorkListCache.end(); I != E; ++I) { + delete *I; + } + } + + ASTUnit *getASTUnit() const { return static_cast(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 + 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 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 VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); + bool VisitObjCClassDecl(ObjCClassDecl *D); + 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 + diff --git a/clang/tools/libclang/Index_Internal.h b/clang/tools/libclang/Index_Internal.h index df54d7c87965..2d42cb83c970 100644 --- a/clang/tools/libclang/Index_Internal.h +++ b/clang/tools/libclang/Index_Internal.h @@ -40,4 +40,16 @@ typedef struct _CXCursorAndRangeVisitorBlock { #endif // !__has_feature(blocks) +/// \brief The result of comparing two source ranges. +enum RangeComparisonResult { + /// \brief Either the ranges overlap or one of the ranges is invalid. + RangeOverlap, + + /// \brief The first range ends before the second range starts. + RangeBefore, + + /// \brief The first range starts after the second range ends. + RangeAfter +}; + #endif