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