#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"
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,
// 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<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;
-
- // 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<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())
- : TU(TU), AU(static_cast<ASTUnit*>(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<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 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);
--- /dev/null
+//===- 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<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;
+
+ // 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<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())
+ : TU(TU), AU(static_cast<ASTUnit*>(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<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 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
+