//===- CXCursor.h - Routines for manipulating CXCursors -------------------===// // // 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 // //===----------------------------------------------------------------------===// // // This file defines routines for manipulating CXCursors. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXCURSOR_H #define LLVM_CLANG_TOOLS_LIBCLANG_CXCURSOR_H #include "clang-c/Index.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/PointerUnion.h" #include namespace clang { class ASTContext; class ASTUnit; class Attr; class CXXBaseSpecifier; class Decl; class Expr; class FieldDecl; class InclusionDirective; class LabelStmt; class MacroDefinitionRecord; class MacroExpansion; class NamedDecl; class ObjCInterfaceDecl; class ObjCProtocolDecl; class OverloadedTemplateStorage; class OverloadExpr; class Stmt; class TemplateDecl; class TemplateName; class TypeDecl; class VarDecl; class IdentifierInfo; namespace cxcursor { CXCursor getCursor(CXTranslationUnit, SourceLocation); CXCursor MakeCXCursor(const clang::Attr *A, const clang::Decl *Parent, CXTranslationUnit TU); CXCursor MakeCXCursor(const clang::Decl *D, CXTranslationUnit TU, SourceRange RegionOfInterest = SourceRange(), bool FirstInDeclGroup = true); CXCursor MakeCXCursor(const clang::Stmt *S, const clang::Decl *Parent, CXTranslationUnit TU, SourceRange RegionOfInterest = SourceRange()); CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = nullptr); /// Create an Objective-C superclass reference at the given location. CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, SourceLocation Loc, CXTranslationUnit TU); /// Unpack an ObjCSuperClassRef cursor into the interface it references /// and optionally the location where the reference occurred. std::pair getCursorObjCSuperClassRef(CXCursor C); /// Create an Objective-C protocol reference at the given location. CXCursor MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto, SourceLocation Loc, CXTranslationUnit TU); /// Unpack an ObjCProtocolRef cursor into the protocol it references /// and optionally the location where the reference occurred. std::pair getCursorObjCProtocolRef(CXCursor C); /// Create an Objective-C class reference at the given location. CXCursor MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class, SourceLocation Loc, CXTranslationUnit TU); /// Unpack an ObjCClassRef cursor into the class it references /// and optionally the location where the reference occurred. std::pair getCursorObjCClassRef(CXCursor C); /// Create a type reference at the given location. CXCursor MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc, CXTranslationUnit TU); /// Unpack a TypeRef cursor into the class it references /// and optionally the location where the reference occurred. std::pair getCursorTypeRef(CXCursor C); /// Create a reference to a template at the given location. CXCursor MakeCursorTemplateRef(const TemplateDecl *Template, SourceLocation Loc, CXTranslationUnit TU); /// Unpack a TemplateRef cursor into the template it references and /// the location where the reference occurred. std::pair getCursorTemplateRef(CXCursor C); /// Create a reference to a namespace or namespace alias at the given /// location. CXCursor MakeCursorNamespaceRef(const NamedDecl *NS, SourceLocation Loc, CXTranslationUnit TU); /// Unpack a NamespaceRef cursor into the namespace or namespace alias /// it references and the location where the reference occurred. std::pair getCursorNamespaceRef(CXCursor C); /// Create a reference to a variable at the given location. CXCursor MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc, CXTranslationUnit TU); /// Unpack a VariableRef cursor into the variable it references and the /// location where the where the reference occurred. std::pair getCursorVariableRef(CXCursor C); /// Create a reference to a field at the given location. CXCursor MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc, CXTranslationUnit TU); /// Unpack a MemberRef cursor into the field it references and the /// location where the reference occurred. std::pair getCursorMemberRef(CXCursor C); /// Create a CXX base specifier cursor. CXCursor MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B, CXTranslationUnit TU); /// Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier. const CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C); /// Create a preprocessing directive cursor. CXCursor MakePreprocessingDirectiveCursor(SourceRange Range, CXTranslationUnit TU); /// Unpack a given preprocessing directive to retrieve its source range. SourceRange getCursorPreprocessingDirective(CXCursor C); /// Create a macro definition cursor. CXCursor MakeMacroDefinitionCursor(const MacroDefinitionRecord *, CXTranslationUnit TU); /// Unpack a given macro definition cursor to retrieve its /// source range. const MacroDefinitionRecord *getCursorMacroDefinition(CXCursor C); /// Create a macro expansion cursor. CXCursor MakeMacroExpansionCursor(MacroExpansion *, CXTranslationUnit TU); /// Create a "pseudo" macro expansion cursor, using a macro definition /// and a source location. CXCursor MakeMacroExpansionCursor(MacroDefinitionRecord *, SourceLocation Loc, CXTranslationUnit TU); /// Wraps a macro expansion cursor and provides a common interface /// for a normal macro expansion cursor or a "pseudo" one. /// /// "Pseudo" macro expansion cursors (essentially a macro definition along with /// a source location) are created in special cases, for example they can be /// created for identifiers inside macro definitions, if these identifiers are /// macro names. class MacroExpansionCursor { CXCursor C; bool isPseudo() const { return C.data[1] != nullptr; } const MacroDefinitionRecord *getAsMacroDefinition() const { assert(isPseudo()); return static_cast(C.data[0]); } const MacroExpansion *getAsMacroExpansion() const { assert(!isPseudo()); return static_cast(C.data[0]); } SourceLocation getPseudoLoc() const { assert(isPseudo()); return SourceLocation::getFromPtrEncoding(C.data[1]); } public: MacroExpansionCursor(CXCursor C) : C(C) { assert(C.kind == CXCursor_MacroExpansion); } const IdentifierInfo *getName() const; const MacroDefinitionRecord *getDefinition() const; SourceRange getSourceRange() const; }; /// Unpack a given macro expansion cursor to retrieve its info. static inline MacroExpansionCursor getCursorMacroExpansion(CXCursor C) { return C; } /// Create an inclusion directive cursor. CXCursor MakeInclusionDirectiveCursor(InclusionDirective *, CXTranslationUnit TU); /// Unpack a given inclusion directive cursor to retrieve its /// source range. const InclusionDirective *getCursorInclusionDirective(CXCursor C); /// Create a label reference at the given location. CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc, CXTranslationUnit TU); /// Unpack a label reference into the label statement it refers to and /// the location of the reference. std::pair getCursorLabelRef(CXCursor C); /// Create a overloaded declaration reference cursor for an expression. CXCursor MakeCursorOverloadedDeclRef(const OverloadExpr *E, CXTranslationUnit TU); /// Create a overloaded declaration reference cursor for a declaration. CXCursor MakeCursorOverloadedDeclRef(const Decl *D, SourceLocation Location, CXTranslationUnit TU); /// Create a overloaded declaration reference cursor for a template name. CXCursor MakeCursorOverloadedDeclRef(TemplateName Template, SourceLocation Location, CXTranslationUnit TU); /// Internal storage for an overloaded declaration reference cursor; typedef llvm::PointerUnion OverloadedDeclRefStorage; /// Unpack an overloaded declaration reference into an expression, /// declaration, or template name along with the source location. std::pair getCursorOverloadedDeclRef(CXCursor C); const Decl *getCursorDecl(CXCursor Cursor); const Expr *getCursorExpr(CXCursor Cursor); const Stmt *getCursorStmt(CXCursor Cursor); const Attr *getCursorAttr(CXCursor Cursor); ASTContext &getCursorContext(CXCursor Cursor); ASTUnit *getCursorASTUnit(CXCursor Cursor); CXTranslationUnit getCursorTU(CXCursor Cursor); void getOverriddenCursors(CXCursor cursor, SmallVectorImpl &overridden); /// Create an opaque pool used for fast generation of overridden /// CXCursor arrays. void *createOverridenCXCursorsPool(); /// Dispose of the overridden CXCursors pool. void disposeOverridenCXCursorsPool(void *pool); /// Returns a index/location pair for a selector identifier if the cursor /// points to one. std::pair getSelectorIdentifierIndexAndLoc(CXCursor); static inline int getSelectorIdentifierIndex(CXCursor cursor) { return getSelectorIdentifierIndexAndLoc(cursor).first; } static inline SourceLocation getSelectorIdentifierLoc(CXCursor cursor) { return getSelectorIdentifierIndexAndLoc(cursor).second; } CXCursor getSelectorIdentifierCursor(int SelIdx, CXCursor cursor); static inline CXCursor getTypeRefedCallExprCursor(CXCursor cursor) { CXCursor newCursor = cursor; if (cursor.kind == CXCursor_CallExpr) newCursor.xdata = 1; return newCursor; } CXCursor getTypeRefCursor(CXCursor cursor); /// Generate a USR for \arg D and put it in \arg Buf. /// \returns true if no USR was computed or the result should be ignored, /// false otherwise. bool getDeclCursorUSR(const Decl *D, SmallVectorImpl &Buf); bool operator==(CXCursor X, CXCursor Y); inline bool operator!=(CXCursor X, CXCursor Y) { return !(X == Y); } /// Return true if the cursor represents a declaration that is the /// first in a declaration group. bool isFirstInDeclGroup(CXCursor C); } // namespace cxcursor } // namespace clang #endif