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(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