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 21namespace clang { 22 23class ASTContext; 24class ASTUnit; 25class Attr; 26class CXXBaseSpecifier; 27class Decl; 28class Expr; 29class FieldDecl; 30class InclusionDirective; 31class LabelStmt; 32class MacroDefinitionRecord; 33class MacroExpansion; 34class NamedDecl; 35class ObjCInterfaceDecl; 36class ObjCProtocolDecl; 37class OverloadedTemplateStorage; 38class OverloadExpr; 39class Stmt; 40class TemplateDecl; 41class TemplateName; 42class TypeDecl; 43class VarDecl; 44class IdentifierInfo; 45 46namespace cxcursor { 47 48CXCursor getCursor(CXTranslationUnit, SourceLocation); 49 50CXCursor MakeCXCursor(const clang::Attr *A, const clang::Decl *Parent, 51 CXTranslationUnit TU); 52CXCursor MakeCXCursor(const clang::Decl *D, CXTranslationUnit TU, 53 SourceRange RegionOfInterest = SourceRange(), 54 bool FirstInDeclGroup = true); 55CXCursor MakeCXCursor(const clang::Stmt *S, const clang::Decl *Parent, 56 CXTranslationUnit TU, 57 SourceRange RegionOfInterest = SourceRange()); 58CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = nullptr); 59 60/// Create an Objective-C superclass reference at the given location. 61CXCursor 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. 66std::pair<const ObjCInterfaceDecl *, SourceLocation> 67getCursorObjCSuperClassRef(CXCursor C); 68 69/// Create an Objective-C protocol reference at the given location. 70CXCursor 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. 75std::pair<const ObjCProtocolDecl *, SourceLocation> 76getCursorObjCProtocolRef(CXCursor C); 77 78/// Create an Objective-C class reference at the given location. 79CXCursor 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. 84std::pair<const ObjCInterfaceDecl *, SourceLocation> 85getCursorObjCClassRef(CXCursor C); 86 87/// Create a type reference at the given location. 88CXCursor 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. 93std::pair<const TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C); 94 95/// Create a reference to a template at the given location. 96CXCursor 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. 101std::pair<const TemplateDecl *, SourceLocation> 102getCursorTemplateRef(CXCursor C); 103 104/// Create a reference to a namespace or namespace alias at the given 105/// location. 106CXCursor 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. 111std::pair<const NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C); 112 113/// Create a reference to a variable at the given location. 114CXCursor 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. 119std::pair<const VarDecl *, SourceLocation> getCursorVariableRef(CXCursor C); 120 121/// Create a reference to a field at the given location. 122CXCursor 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. 127std::pair<const FieldDecl *, SourceLocation> getCursorMemberRef(CXCursor C); 128 129/// Create a CXX base specifier cursor. 130CXCursor MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B, 131 CXTranslationUnit TU); 132 133/// Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier. 134const CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C); 135 136/// Create a preprocessing directive cursor. 137CXCursor MakePreprocessingDirectiveCursor(SourceRange Range, 138 CXTranslationUnit TU); 139 140/// Unpack a given preprocessing directive to retrieve its source range. 141SourceRange getCursorPreprocessingDirective(CXCursor C); 142 143/// Create a macro definition cursor. 144CXCursor MakeMacroDefinitionCursor(const MacroDefinitionRecord *, 145 CXTranslationUnit TU); 146 147/// Unpack a given macro definition cursor to retrieve its 148/// source range. 149const MacroDefinitionRecord *getCursorMacroDefinition(CXCursor C); 150 151/// Create a macro expansion cursor. 152CXCursor MakeMacroExpansionCursor(MacroExpansion *, CXTranslationUnit TU); 153 154/// Create a "pseudo" macro expansion cursor, using a macro definition 155/// and a source location. 156CXCursor 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. 166class 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 183public: 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. 194static inline MacroExpansionCursor getCursorMacroExpansion(CXCursor C) { 195 return C; 196} 197 198/// Create an inclusion directive cursor. 199CXCursor MakeInclusionDirectiveCursor(InclusionDirective *, 200 CXTranslationUnit TU); 201 202/// Unpack a given inclusion directive cursor to retrieve its 203/// source range. 204const InclusionDirective *getCursorInclusionDirective(CXCursor C); 205 206/// Create a label reference at the given location. 207CXCursor 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. 212std::pair<const LabelStmt *, SourceLocation> getCursorLabelRef(CXCursor C); 213 214/// Create a overloaded declaration reference cursor for an expression. 215CXCursor MakeCursorOverloadedDeclRef(const OverloadExpr *E, 216 CXTranslationUnit TU); 217 218/// Create a overloaded declaration reference cursor for a declaration. 219CXCursor MakeCursorOverloadedDeclRef(const Decl *D, SourceLocation Location, 220 CXTranslationUnit TU); 221 222/// Create a overloaded declaration reference cursor for a template name. 223CXCursor MakeCursorOverloadedDeclRef(TemplateName Template, 224 SourceLocation Location, 225 CXTranslationUnit TU); 226 227/// Internal storage for an overloaded declaration reference cursor; 228typedef 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. 234std::pair<OverloadedDeclRefStorage, SourceLocation> 235getCursorOverloadedDeclRef(CXCursor C); 236 237const Decl *getCursorDecl(CXCursor Cursor); 238const Expr *getCursorExpr(CXCursor Cursor); 239const Stmt *getCursorStmt(CXCursor Cursor); 240const Attr *getCursorAttr(CXCursor Cursor); 241 242ASTContext &getCursorContext(CXCursor Cursor); 243ASTUnit *getCursorASTUnit(CXCursor Cursor); 244CXTranslationUnit getCursorTU(CXCursor Cursor); 245 246void getOverriddenCursors(CXCursor cursor, 247 SmallVectorImpl<CXCursor> &overridden); 248 249/// Create an opaque pool used for fast generation of overridden 250/// CXCursor arrays. 251void *createOverridenCXCursorsPool(); 252 253/// Dispose of the overridden CXCursors pool. 254void disposeOverridenCXCursorsPool(void *pool); 255 256/// Returns a index/location pair for a selector identifier if the cursor 257/// points to one. 258std::pair<int, SourceLocation> getSelectorIdentifierIndexAndLoc(CXCursor); 259static inline int getSelectorIdentifierIndex(CXCursor cursor) { 260 return getSelectorIdentifierIndexAndLoc(cursor).first; 261} 262static inline SourceLocation getSelectorIdentifierLoc(CXCursor cursor) { 263 return getSelectorIdentifierIndexAndLoc(cursor).second; 264} 265 266CXCursor getSelectorIdentifierCursor(int SelIdx, CXCursor cursor); 267 268static inline CXCursor getTypeRefedCallExprCursor(CXCursor cursor) { 269 CXCursor newCursor = cursor; 270 if (cursor.kind == CXCursor_CallExpr) 271 newCursor.xdata = 1; 272 return newCursor; 273} 274 275CXCursor 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. 280bool getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf); 281 282bool operator==(CXCursor X, CXCursor Y); 283 284inline 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. 288bool isFirstInDeclGroup(CXCursor C); 289 290} // namespace cxcursor 291} // namespace clang 292 293#endif 294