mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-20 03:55:48 -04:00

to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
278 lines
9.7 KiB
C++
278 lines
9.7 KiB
C++
//===- CursorVisitor.h - CursorVisitor interface ----------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H
|
|
#define LLVM_CLANG_TOOLS_LIBCLANG_CURSORVISITOR_H
|
|
|
|
#include "CXCursor.h"
|
|
#include "CXTranslationUnit.h"
|
|
#include "Index_Internal.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, PostChildrenVisitKind };
|
|
protected:
|
|
const void *data[3];
|
|
CXCursor parent;
|
|
Kind K;
|
|
VisitorJob(CXCursor C, Kind k, const void *d1, const void *d2 = nullptr,
|
|
const void *d3 = nullptr)
|
|
: 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; }
|
|
};
|
|
|
|
typedef SmallVector<VisitorJob, 10> VisitorWorkList;
|
|
|
|
// Cursor visitor.
|
|
class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
|
|
public TypeLocVisitor<CursorVisitor, bool>
|
|
{
|
|
public:
|
|
/// Callback called after child nodes of a cursor have been visited.
|
|
/// Return true to break visitation or false to continue.
|
|
typedef bool (*PostChildrenVisitorTy)(CXCursor cursor,
|
|
CXClientData client_data);
|
|
|
|
private:
|
|
/// The translation unit we are traversing.
|
|
CXTranslationUnit TU;
|
|
ASTUnit *AU;
|
|
|
|
/// The parent cursor whose children we are traversing.
|
|
CXCursor Parent;
|
|
|
|
/// The declaration that serves at the parent of any statement or
|
|
/// expression nodes.
|
|
const Decl *StmtParent;
|
|
|
|
/// The visitor function.
|
|
CXCursorVisitor Visitor;
|
|
|
|
PostChildrenVisitorTy PostChildrenVisitor;
|
|
|
|
/// The opaque client data, to be passed along to the visitor.
|
|
CXClientData ClientData;
|
|
|
|
/// Whether we should visit the preprocessing record entries last,
|
|
/// after visiting other declarations.
|
|
bool VisitPreprocessorLast;
|
|
|
|
/// Whether we should visit declarations or preprocessing record
|
|
/// entries that are #included inside the \arg RegionOfInterest.
|
|
bool VisitIncludedEntities;
|
|
|
|
/// When valid, a source range to which the cursor should restrict
|
|
/// its search.
|
|
SourceRange RegionOfInterest;
|
|
|
|
/// 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;
|
|
|
|
/// 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);
|
|
|
|
bool visitDeclsFromFileRegion(FileID File, unsigned Offset, unsigned Length);
|
|
|
|
class SetParentRAII {
|
|
CXCursor &Parent;
|
|
const Decl *&StmtParent;
|
|
CXCursor OldParent;
|
|
|
|
public:
|
|
SetParentRAII(CXCursor &Parent, const 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,
|
|
PostChildrenVisitorTy PostChildrenVisitor = nullptr)
|
|
: TU(TU), AU(cxtu::getASTUnit(TU)),
|
|
Visitor(Visitor), PostChildrenVisitor(PostChildrenVisitor),
|
|
ClientData(ClientData),
|
|
VisitPreprocessorLast(VisitPreprocessorLast),
|
|
VisitIncludedEntities(VisitIncludedPreprocessingEntries),
|
|
RegionOfInterest(RegionOfInterest),
|
|
VisitDeclsOnly(VisitDeclsOnly),
|
|
DI_current(nullptr), FileDI_current(nullptr)
|
|
{
|
|
Parent.kind = CXCursor_NoDeclFound;
|
|
Parent.data[0] = nullptr;
|
|
Parent.data[1] = nullptr;
|
|
Parent.data[2] = nullptr;
|
|
StmtParent = nullptr;
|
|
}
|
|
|
|
~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 AU; }
|
|
CXTranslationUnit getTU() const { return TU; }
|
|
|
|
bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false);
|
|
|
|
/// Visit declarations and preprocessed entities for the file region
|
|
/// designated by \see RegionOfInterest.
|
|
bool 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 VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
|
|
bool VisitTypeAliasDecl(TypeAliasDecl *D);
|
|
bool VisitAttributes(Decl *D);
|
|
bool VisitBlockDecl(BlockDecl *B);
|
|
bool VisitCXXRecordDecl(CXXRecordDecl *D);
|
|
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 VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
|
|
bool VisitObjCMethodDecl(ObjCMethodDecl *ND);
|
|
bool VisitObjCContainerDecl(ObjCContainerDecl *D);
|
|
bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND);
|
|
bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID);
|
|
bool VisitObjCPropertyDecl(ObjCPropertyDecl *PD);
|
|
bool VisitObjCTypeParamList(ObjCTypeParamList *typeParamList);
|
|
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);
|
|
bool VisitStaticAssertDecl(StaticAssertDecl *D);
|
|
bool VisitFriendDecl(FriendDecl *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, const Stmt *S);
|
|
LLVM_ATTRIBUTE_NOINLINE bool Visit(const Stmt *S);
|
|
|
|
private:
|
|
Optional<bool> handleDeclForVisitation(const Decl *D);
|
|
};
|
|
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|