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 
isPseudo()169   bool isPseudo() const { return C.data[1] != nullptr; }
getAsMacroDefinition()170   const MacroDefinitionRecord *getAsMacroDefinition() const {
171     assert(isPseudo());
172     return static_cast<const MacroDefinitionRecord *>(C.data[0]);
173   }
getAsMacroExpansion()174   const MacroExpansion *getAsMacroExpansion() const {
175     assert(!isPseudo());
176     return static_cast<const MacroExpansion *>(C.data[0]);
177   }
getPseudoLoc()178   SourceLocation getPseudoLoc() const {
179     assert(isPseudo());
180     return SourceLocation::getFromPtrEncoding(C.data[1]);
181   }
182 
183 public:
MacroExpansionCursor(CXCursor C)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.
getCursorMacroExpansion(CXCursor C)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);
getSelectorIdentifierIndex(CXCursor cursor)259 static inline int getSelectorIdentifierIndex(CXCursor cursor) {
260   return getSelectorIdentifierIndexAndLoc(cursor).first;
261 }
getSelectorIdentifierLoc(CXCursor cursor)262 static inline SourceLocation getSelectorIdentifierLoc(CXCursor cursor) {
263   return getSelectorIdentifierIndexAndLoc(cursor).second;
264 }
265 
266 CXCursor getSelectorIdentifierCursor(int SelIdx, CXCursor cursor);
267 
getTypeRefedCallExprCursor(CXCursor cursor)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