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