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