| 1 | //===- CXCursor.h - Routines for manipulating CXCursors -------------------===// | 
|---|
| 2 | // | 
|---|
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|---|
| 4 | // See https://llvm.org/LICENSE.txt for license information. | 
|---|
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|---|
| 6 | // | 
|---|
| 7 | //===----------------------------------------------------------------------===// | 
|---|
| 8 | // | 
|---|
| 9 | // This file defines routines for manipulating CXCursors. | 
|---|
| 10 | // | 
|---|
| 11 | //===----------------------------------------------------------------------===// | 
|---|
| 12 |  | 
|---|
| 13 | #ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXCURSOR_H | 
|---|
| 14 | #define LLVM_CLANG_TOOLS_LIBCLANG_CXCURSOR_H | 
|---|
| 15 |  | 
|---|
| 16 | #include "clang-c/Index.h" | 
|---|
| 17 | #include "clang/Basic/SourceLocation.h" | 
|---|
| 18 | #include "llvm/ADT/PointerUnion.h" | 
|---|
| 19 | #include <utility> | 
|---|
| 20 |  | 
|---|
| 21 | namespace clang { | 
|---|
| 22 |  | 
|---|
| 23 | class ASTContext; | 
|---|
| 24 | class ASTUnit; | 
|---|
| 25 | class Attr; | 
|---|
| 26 | class CXXBaseSpecifier; | 
|---|
| 27 | class Decl; | 
|---|
| 28 | class Expr; | 
|---|
| 29 | class FieldDecl; | 
|---|
| 30 | class InclusionDirective; | 
|---|
| 31 | class LabelStmt; | 
|---|
| 32 | class MacroDefinitionRecord; | 
|---|
| 33 | class MacroExpansion; | 
|---|
| 34 | class NamedDecl; | 
|---|
| 35 | class ObjCInterfaceDecl; | 
|---|
| 36 | class ObjCProtocolDecl; | 
|---|
| 37 | class OverloadedTemplateStorage; | 
|---|
| 38 | class OverloadExpr; | 
|---|
| 39 | class Stmt; | 
|---|
| 40 | class TemplateDecl; | 
|---|
| 41 | class TemplateName; | 
|---|
| 42 | class TypeDecl; | 
|---|
| 43 | class VarDecl; | 
|---|
| 44 | class IdentifierInfo; | 
|---|
| 45 |  | 
|---|
| 46 | namespace cxcursor { | 
|---|
| 47 |  | 
|---|
| 48 | CXCursor getCursor(CXTranslationUnit, SourceLocation); | 
|---|
| 49 |  | 
|---|
| 50 | CXCursor MakeCXCursor(const clang::Attr *A, const clang::Decl *Parent, | 
|---|
| 51 | CXTranslationUnit TU); | 
|---|
| 52 | CXCursor MakeCXCursor(const clang::Decl *D, CXTranslationUnit TU, | 
|---|
| 53 | SourceRange RegionOfInterest = SourceRange(), | 
|---|
| 54 | bool FirstInDeclGroup = true); | 
|---|
| 55 | CXCursor MakeCXCursor(const clang::Stmt *S, const clang::Decl *Parent, | 
|---|
| 56 | CXTranslationUnit TU, | 
|---|
| 57 | SourceRange RegionOfInterest = SourceRange()); | 
|---|
| 58 | CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = nullptr); | 
|---|
| 59 |  | 
|---|
| 60 | /// Create an Objective-C superclass reference at the given location. | 
|---|
| 61 | CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, | 
|---|
| 62 | SourceLocation Loc, CXTranslationUnit TU); | 
|---|
| 63 |  | 
|---|
| 64 | /// Unpack an ObjCSuperClassRef cursor into the interface it references | 
|---|
| 65 | /// and optionally the location where the reference occurred. | 
|---|
| 66 | std::pair<const ObjCInterfaceDecl *, SourceLocation> | 
|---|
| 67 | getCursorObjCSuperClassRef(CXCursor C); | 
|---|
| 68 |  | 
|---|
| 69 | /// Create an Objective-C protocol reference at the given location. | 
|---|
| 70 | CXCursor MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto, | 
|---|
| 71 | SourceLocation Loc, CXTranslationUnit TU); | 
|---|
| 72 |  | 
|---|
| 73 | /// Unpack an ObjCProtocolRef cursor into the protocol it references | 
|---|
| 74 | /// and optionally the location where the reference occurred. | 
|---|
| 75 | std::pair<const ObjCProtocolDecl *, SourceLocation> | 
|---|
| 76 | getCursorObjCProtocolRef(CXCursor C); | 
|---|
| 77 |  | 
|---|
| 78 | /// Create an Objective-C class reference at the given location. | 
|---|
| 79 | CXCursor MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class, | 
|---|
| 80 | SourceLocation Loc, CXTranslationUnit TU); | 
|---|
| 81 |  | 
|---|
| 82 | /// Unpack an ObjCClassRef cursor into the class it references | 
|---|
| 83 | /// and optionally the location where the reference occurred. | 
|---|
| 84 | std::pair<const ObjCInterfaceDecl *, SourceLocation> | 
|---|
| 85 | getCursorObjCClassRef(CXCursor C); | 
|---|
| 86 |  | 
|---|
| 87 | /// Create a type reference at the given location. | 
|---|
| 88 | CXCursor MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc, | 
|---|
| 89 | CXTranslationUnit TU); | 
|---|
| 90 |  | 
|---|
| 91 | /// Unpack a TypeRef cursor into the class it references | 
|---|
| 92 | /// and optionally the location where the reference occurred. | 
|---|
| 93 | std::pair<const TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C); | 
|---|
| 94 |  | 
|---|
| 95 | /// Create a reference to a template at the given location. | 
|---|
| 96 | CXCursor MakeCursorTemplateRef(const TemplateDecl *Template, SourceLocation Loc, | 
|---|
| 97 | CXTranslationUnit TU); | 
|---|
| 98 |  | 
|---|
| 99 | /// Unpack a TemplateRef cursor into the template it references and | 
|---|
| 100 | /// the location where the reference occurred. | 
|---|
| 101 | std::pair<const TemplateDecl *, SourceLocation> | 
|---|
| 102 | getCursorTemplateRef(CXCursor C); | 
|---|
| 103 |  | 
|---|
| 104 | /// Create a reference to a namespace or namespace alias at the given | 
|---|
| 105 | /// location. | 
|---|
| 106 | CXCursor MakeCursorNamespaceRef(const NamedDecl *NS, SourceLocation Loc, | 
|---|
| 107 | CXTranslationUnit TU); | 
|---|
| 108 |  | 
|---|
| 109 | /// Unpack a NamespaceRef cursor into the namespace or namespace alias | 
|---|
| 110 | /// it references and the location where the reference occurred. | 
|---|
| 111 | std::pair<const NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C); | 
|---|
| 112 |  | 
|---|
| 113 | /// Create a reference to a variable at the given location. | 
|---|
| 114 | CXCursor MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc, | 
|---|
| 115 | CXTranslationUnit TU); | 
|---|
| 116 |  | 
|---|
| 117 | /// Unpack a VariableRef cursor into the variable it references and the | 
|---|
| 118 | /// location where the where the reference occurred. | 
|---|
| 119 | std::pair<const VarDecl *, SourceLocation> getCursorVariableRef(CXCursor C); | 
|---|
| 120 |  | 
|---|
| 121 | /// Create a reference to a field at the given location. | 
|---|
| 122 | CXCursor MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc, | 
|---|
| 123 | CXTranslationUnit TU); | 
|---|
| 124 |  | 
|---|
| 125 | /// Unpack a MemberRef cursor into the field it references and the | 
|---|
| 126 | /// location where the reference occurred. | 
|---|
| 127 | std::pair<const FieldDecl *, SourceLocation> getCursorMemberRef(CXCursor C); | 
|---|
| 128 |  | 
|---|
| 129 | /// Create a CXX base specifier cursor. | 
|---|
| 130 | CXCursor MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B, | 
|---|
| 131 | CXTranslationUnit TU); | 
|---|
| 132 |  | 
|---|
| 133 | /// Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier. | 
|---|
| 134 | const CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C); | 
|---|
| 135 |  | 
|---|
| 136 | /// Create a preprocessing directive cursor. | 
|---|
| 137 | CXCursor MakePreprocessingDirectiveCursor(SourceRange Range, | 
|---|
| 138 | CXTranslationUnit TU); | 
|---|
| 139 |  | 
|---|
| 140 | /// Unpack a given preprocessing directive to retrieve its source range. | 
|---|
| 141 | SourceRange getCursorPreprocessingDirective(CXCursor C); | 
|---|
| 142 |  | 
|---|
| 143 | /// Create a macro definition cursor. | 
|---|
| 144 | CXCursor MakeMacroDefinitionCursor(const MacroDefinitionRecord *, | 
|---|
| 145 | CXTranslationUnit TU); | 
|---|
| 146 |  | 
|---|
| 147 | /// Unpack a given macro definition cursor to retrieve its | 
|---|
| 148 | /// source range. | 
|---|
| 149 | const MacroDefinitionRecord *getCursorMacroDefinition(CXCursor C); | 
|---|
| 150 |  | 
|---|
| 151 | /// Create a macro expansion cursor. | 
|---|
| 152 | CXCursor MakeMacroExpansionCursor(MacroExpansion *, CXTranslationUnit TU); | 
|---|
| 153 |  | 
|---|
| 154 | /// Create a "pseudo" macro expansion cursor, using a macro definition | 
|---|
| 155 | /// and a source location. | 
|---|
| 156 | CXCursor MakeMacroExpansionCursor(MacroDefinitionRecord *, SourceLocation Loc, | 
|---|
| 157 | CXTranslationUnit TU); | 
|---|
| 158 |  | 
|---|
| 159 | /// Wraps a macro expansion cursor and provides a common interface | 
|---|
| 160 | /// for a normal macro expansion cursor or a "pseudo" one. | 
|---|
| 161 | /// | 
|---|
| 162 | /// "Pseudo" macro expansion cursors (essentially a macro definition along with | 
|---|
| 163 | /// a source location) are created in special cases, for example they can be | 
|---|
| 164 | /// created for identifiers inside macro definitions, if these identifiers are | 
|---|
| 165 | /// macro names. | 
|---|
| 166 | class MacroExpansionCursor { | 
|---|
| 167 | CXCursor C; | 
|---|
| 168 |  | 
|---|
| 169 | bool isPseudo() const { return C.data[1] != nullptr; } | 
|---|
| 170 | const MacroDefinitionRecord *getAsMacroDefinition() const { | 
|---|
| 171 | assert(isPseudo()); | 
|---|
| 172 | return static_cast<const MacroDefinitionRecord *>(C.data[0]); | 
|---|
| 173 | } | 
|---|
| 174 | const MacroExpansion *getAsMacroExpansion() const { | 
|---|
| 175 | assert(!isPseudo()); | 
|---|
| 176 | return static_cast<const MacroExpansion *>(C.data[0]); | 
|---|
| 177 | } | 
|---|
| 178 | SourceLocation getPseudoLoc() const { | 
|---|
| 179 | assert(isPseudo()); | 
|---|
| 180 | return SourceLocation::getFromPtrEncoding(Encoding: C.data[1]); | 
|---|
| 181 | } | 
|---|
| 182 |  | 
|---|
| 183 | public: | 
|---|
| 184 | MacroExpansionCursor(CXCursor C) : C(C) { | 
|---|
| 185 | assert(C.kind == CXCursor_MacroExpansion); | 
|---|
| 186 | } | 
|---|
| 187 |  | 
|---|
| 188 | const IdentifierInfo *getName() const; | 
|---|
| 189 | const MacroDefinitionRecord *getDefinition() const; | 
|---|
| 190 | SourceRange getSourceRange() const; | 
|---|
| 191 | }; | 
|---|
| 192 |  | 
|---|
| 193 | /// Unpack a given macro expansion cursor to retrieve its info. | 
|---|
| 194 | static inline MacroExpansionCursor getCursorMacroExpansion(CXCursor C) { | 
|---|
| 195 | return C; | 
|---|
| 196 | } | 
|---|
| 197 |  | 
|---|
| 198 | /// Create an inclusion directive cursor. | 
|---|
| 199 | CXCursor MakeInclusionDirectiveCursor(InclusionDirective *, | 
|---|
| 200 | CXTranslationUnit TU); | 
|---|
| 201 |  | 
|---|
| 202 | /// Unpack a given inclusion directive cursor to retrieve its | 
|---|
| 203 | /// source range. | 
|---|
| 204 | const InclusionDirective *getCursorInclusionDirective(CXCursor C); | 
|---|
| 205 |  | 
|---|
| 206 | /// Create a label reference at the given location. | 
|---|
| 207 | CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc, | 
|---|
| 208 | CXTranslationUnit TU); | 
|---|
| 209 |  | 
|---|
| 210 | /// Unpack a label reference into the label statement it refers to and | 
|---|
| 211 | /// the location of the reference. | 
|---|
| 212 | std::pair<const LabelStmt *, SourceLocation> getCursorLabelRef(CXCursor C); | 
|---|
| 213 |  | 
|---|
| 214 | /// Create a overloaded declaration reference cursor for an expression. | 
|---|
| 215 | CXCursor MakeCursorOverloadedDeclRef(const OverloadExpr *E, | 
|---|
| 216 | CXTranslationUnit TU); | 
|---|
| 217 |  | 
|---|
| 218 | /// Create a overloaded declaration reference cursor for a declaration. | 
|---|
| 219 | CXCursor MakeCursorOverloadedDeclRef(const Decl *D, SourceLocation Location, | 
|---|
| 220 | CXTranslationUnit TU); | 
|---|
| 221 |  | 
|---|
| 222 | /// Create a overloaded declaration reference cursor for a template name. | 
|---|
| 223 | CXCursor MakeCursorOverloadedDeclRef(TemplateName Template, | 
|---|
| 224 | SourceLocation Location, | 
|---|
| 225 | CXTranslationUnit TU); | 
|---|
| 226 |  | 
|---|
| 227 | /// Internal storage for an overloaded declaration reference cursor; | 
|---|
| 228 | typedef llvm::PointerUnion<const OverloadExpr *, const Decl *, | 
|---|
| 229 | OverloadedTemplateStorage *> | 
|---|
| 230 | OverloadedDeclRefStorage; | 
|---|
| 231 |  | 
|---|
| 232 | /// Unpack an overloaded declaration reference into an expression, | 
|---|
| 233 | /// declaration, or template name along with the source location. | 
|---|
| 234 | std::pair<OverloadedDeclRefStorage, SourceLocation> | 
|---|
| 235 | getCursorOverloadedDeclRef(CXCursor C); | 
|---|
| 236 |  | 
|---|
| 237 | const Decl *getCursorDecl(CXCursor Cursor); | 
|---|
| 238 | const Expr *getCursorExpr(CXCursor Cursor); | 
|---|
| 239 | const Stmt *getCursorStmt(CXCursor Cursor); | 
|---|
| 240 | const Attr *getCursorAttr(CXCursor Cursor); | 
|---|
| 241 |  | 
|---|
| 242 | ASTContext &getCursorContext(CXCursor Cursor); | 
|---|
| 243 | ASTUnit *getCursorASTUnit(CXCursor Cursor); | 
|---|
| 244 | CXTranslationUnit getCursorTU(CXCursor Cursor); | 
|---|
| 245 |  | 
|---|
| 246 | void getOverriddenCursors(CXCursor cursor, | 
|---|
| 247 | SmallVectorImpl<CXCursor> &overridden); | 
|---|
| 248 |  | 
|---|
| 249 | /// Create an opaque pool used for fast generation of overridden | 
|---|
| 250 | /// CXCursor arrays. | 
|---|
| 251 | void *createOverridenCXCursorsPool(); | 
|---|
| 252 |  | 
|---|
| 253 | /// Dispose of the overridden CXCursors pool. | 
|---|
| 254 | void disposeOverridenCXCursorsPool(void *pool); | 
|---|
| 255 |  | 
|---|
| 256 | /// Returns a index/location pair for a selector identifier if the cursor | 
|---|
| 257 | /// points to one. | 
|---|
| 258 | std::pair<int, SourceLocation> getSelectorIdentifierIndexAndLoc(CXCursor); | 
|---|
| 259 | static inline int getSelectorIdentifierIndex(CXCursor cursor) { | 
|---|
| 260 | return getSelectorIdentifierIndexAndLoc(cursor).first; | 
|---|
| 261 | } | 
|---|
| 262 | static inline SourceLocation getSelectorIdentifierLoc(CXCursor cursor) { | 
|---|
| 263 | return getSelectorIdentifierIndexAndLoc(cursor).second; | 
|---|
| 264 | } | 
|---|
| 265 |  | 
|---|
| 266 | CXCursor getSelectorIdentifierCursor(int SelIdx, CXCursor cursor); | 
|---|
| 267 |  | 
|---|
| 268 | static inline CXCursor getTypeRefedCallExprCursor(CXCursor cursor) { | 
|---|
| 269 | CXCursor newCursor = cursor; | 
|---|
| 270 | if (cursor.kind == CXCursor_CallExpr) | 
|---|
| 271 | newCursor.xdata = 1; | 
|---|
| 272 | return newCursor; | 
|---|
| 273 | } | 
|---|
| 274 |  | 
|---|
| 275 | CXCursor getTypeRefCursor(CXCursor cursor); | 
|---|
| 276 |  | 
|---|
| 277 | /// Generate a USR for \arg D and put it in \arg Buf. | 
|---|
| 278 | /// \returns true if no USR was computed or the result should be ignored, | 
|---|
| 279 | /// false otherwise. | 
|---|
| 280 | bool getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf); | 
|---|
| 281 |  | 
|---|
| 282 | bool operator==(CXCursor X, CXCursor Y); | 
|---|
| 283 |  | 
|---|
| 284 | inline bool operator!=(CXCursor X, CXCursor Y) { return !(X == Y); } | 
|---|
| 285 |  | 
|---|
| 286 | /// Return true if the cursor represents a declaration that is the | 
|---|
| 287 | /// first in a declaration group. | 
|---|
| 288 | bool isFirstInDeclGroup(CXCursor C); | 
|---|
| 289 |  | 
|---|
| 290 | } // namespace cxcursor | 
|---|
| 291 | } // namespace clang | 
|---|
| 292 |  | 
|---|
| 293 | #endif | 
|---|
| 294 |  | 
|---|