Home | History | Annotate | Line # | Download | only in libclang
      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