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 {
GoNextMarkerAction()23 
24 class ASTContext;
25 class ASTUnit;
26 class Attr;
execute(TypedEvent e)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 /// Create an Objective-C superclass reference at the given location.
62 CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
63                                      SourceLocation Loc,
64                                      CXTranslationUnit TU);
65 
66 /// 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 /// Create an Objective-C protocol reference at the given location.
72 CXCursor MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
73                                    SourceLocation Loc,
74                                    CXTranslationUnit TU);
75 
76 /// 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 /// Create an Objective-C class reference at the given location.
82 CXCursor MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
83                                 SourceLocation Loc,
84                                 CXTranslationUnit TU);
85 
86 /// 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 /// Create a type reference at the given location.
92 CXCursor MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
93                            CXTranslationUnit TU);
94 
95 /// 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 /// Create a reference to a template at the given location.
100 CXCursor MakeCursorTemplateRef(const TemplateDecl *Template, SourceLocation Loc,
101                                CXTranslationUnit TU);
102 
103 /// 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 /// 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 /// 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 /// Create a reference to a variable at the given location.
118 CXCursor MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
119                                CXTranslationUnit TU);
120 
121 /// 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 /// Create a reference to a field at the given location.
126 CXCursor MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
127                              CXTranslationUnit TU);
128 
129 /// 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 /// Create a CXX base specifier cursor.
134 CXCursor MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
135                                     CXTranslationUnit TU);
136 
137 /// Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier.
138 const CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C);
139 
140 /// Create a preprocessing directive cursor.
141 CXCursor MakePreprocessingDirectiveCursor(SourceRange Range,
142                                           CXTranslationUnit TU);
143 
144 /// Unpack a given preprocessing directive to retrieve its source range.
145 SourceRange getCursorPreprocessingDirective(CXCursor C);
146 
147 /// Create a macro definition cursor.
148 CXCursor MakeMacroDefinitionCursor(const MacroDefinitionRecord *,
149                                    CXTranslationUnit TU);
150 
151 /// Unpack a given macro definition cursor to retrieve its
152 /// source range.
153 const MacroDefinitionRecord *getCursorMacroDefinition(CXCursor C);
154 
155 /// Create a macro expansion cursor.
156 CXCursor MakeMacroExpansionCursor(MacroExpansion *, CXTranslationUnit TU);
157 
158 /// 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 /// 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 /// Unpack a given macro expansion cursor to retrieve its info.
198 static inline MacroExpansionCursor getCursorMacroExpansion(CXCursor C) {
199   return C;
200 }
201 
202 /// Create an inclusion directive cursor.
203 CXCursor MakeInclusionDirectiveCursor(InclusionDirective *,
204                                       CXTranslationUnit TU);
205 
206 /// Unpack a given inclusion directive cursor to retrieve its
207 /// source range.
208 const InclusionDirective *getCursorInclusionDirective(CXCursor C);
209 
210 /// Create a label reference at the given location.
211 CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
212                             CXTranslationUnit TU);
213 
214 /// 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 /// Create a overloaded declaration reference cursor for an expression.
219 CXCursor MakeCursorOverloadedDeclRef(const OverloadExpr *E,
220                                      CXTranslationUnit TU);
221 
222 /// Create a overloaded declaration reference cursor for a declaration.
223 CXCursor MakeCursorOverloadedDeclRef(const Decl *D, SourceLocation Location,
224                                      CXTranslationUnit TU);
225 
226 /// Create a overloaded declaration reference cursor for a template name.
227 CXCursor MakeCursorOverloadedDeclRef(TemplateName Template,
228                                      SourceLocation Location,
229                                      CXTranslationUnit TU);
230 
231 /// Internal storage for an overloaded declaration reference cursor;
232 typedef llvm::PointerUnion3<const OverloadExpr *, const Decl *,
233                             OverloadedTemplateStorage *>
234   OverloadedDeclRefStorage;
235 
236 /// 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 /// Create an opaque pool used for fast generation of overridden
255 /// CXCursor arrays.
256 void *createOverridenCXCursorsPool();
257 
258 /// Dispose of the overridden CXCursors pool.
259 void disposeOverridenCXCursorsPool(void *pool);
260 
261 /// 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 /// 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 /// 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