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