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
21namespace clang {
22
23class ASTContext;
24class ASTUnit;
25class Attr;
26class CXXBaseSpecifier;
27class Decl;
28class Expr;
29class FieldDecl;
30class InclusionDirective;
31class LabelStmt;
32class MacroDefinitionRecord;
33class MacroExpansion;
34class NamedDecl;
35class ObjCInterfaceDecl;
36class ObjCProtocolDecl;
37class OverloadedTemplateStorage;
38class OverloadExpr;
39class Stmt;
40class TemplateDecl;
41class TemplateName;
42class TypeDecl;
43class VarDecl;
44class IdentifierInfo;
45
46namespace cxcursor {
47
48CXCursor getCursor(CXTranslationUnit, SourceLocation);
49
50CXCursor MakeCXCursor(const clang::Attr *A, const clang::Decl *Parent,
51                      CXTranslationUnit TU);
52CXCursor MakeCXCursor(const clang::Decl *D, CXTranslationUnit TU,
53                      SourceRange RegionOfInterest = SourceRange(),
54                      bool FirstInDeclGroup = true);
55CXCursor MakeCXCursor(const clang::Stmt *S, const clang::Decl *Parent,
56                      CXTranslationUnit TU,
57                      SourceRange RegionOfInterest = SourceRange());
58CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = nullptr);
59
60/// Create an Objective-C superclass reference at the given location.
61CXCursor 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.
66std::pair<const ObjCInterfaceDecl *, SourceLocation>
67getCursorObjCSuperClassRef(CXCursor C);
68
69/// Create an Objective-C protocol reference at the given location.
70CXCursor 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.
75std::pair<const ObjCProtocolDecl *, SourceLocation>
76getCursorObjCProtocolRef(CXCursor C);
77
78/// Create an Objective-C class reference at the given location.
79CXCursor 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.
84std::pair<const ObjCInterfaceDecl *, SourceLocation>
85getCursorObjCClassRef(CXCursor C);
86
87/// Create a type reference at the given location.
88CXCursor 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.
93std::pair<const TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C);
94
95/// Create a reference to a template at the given location.
96CXCursor 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.
101std::pair<const TemplateDecl *, SourceLocation>
102getCursorTemplateRef(CXCursor C);
103
104/// Create a reference to a namespace or namespace alias at the given
105/// location.
106CXCursor 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.
111std::pair<const NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C);
112
113/// Create a reference to a variable at the given location.
114CXCursor 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.
119std::pair<const VarDecl *, SourceLocation> getCursorVariableRef(CXCursor C);
120
121/// Create a reference to a field at the given location.
122CXCursor 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.
127std::pair<const FieldDecl *, SourceLocation> getCursorMemberRef(CXCursor C);
128
129/// Create a CXX base specifier cursor.
130CXCursor MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
131                                    CXTranslationUnit TU);
132
133/// Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier.
134const CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C);
135
136/// Create a preprocessing directive cursor.
137CXCursor MakePreprocessingDirectiveCursor(SourceRange Range,
138                                          CXTranslationUnit TU);
139
140/// Unpack a given preprocessing directive to retrieve its source range.
141SourceRange getCursorPreprocessingDirective(CXCursor C);
142
143/// Create a macro definition cursor.
144CXCursor MakeMacroDefinitionCursor(const MacroDefinitionRecord *,
145                                   CXTranslationUnit TU);
146
147/// Unpack a given macro definition cursor to retrieve its
148/// source range.
149const MacroDefinitionRecord *getCursorMacroDefinition(CXCursor C);
150
151/// Create a macro expansion cursor.
152CXCursor MakeMacroExpansionCursor(MacroExpansion *, CXTranslationUnit TU);
153
154/// Create a "pseudo" macro expansion cursor, using a macro definition
155/// and a source location.
156CXCursor 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.
166class 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
183public:
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.
194static inline MacroExpansionCursor getCursorMacroExpansion(CXCursor C) {
195  return C;
196}
197
198/// Create an inclusion directive cursor.
199CXCursor MakeInclusionDirectiveCursor(InclusionDirective *,
200                                      CXTranslationUnit TU);
201
202/// Unpack a given inclusion directive cursor to retrieve its
203/// source range.
204const InclusionDirective *getCursorInclusionDirective(CXCursor C);
205
206/// Create a label reference at the given location.
207CXCursor 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.
212std::pair<const LabelStmt *, SourceLocation> getCursorLabelRef(CXCursor C);
213
214/// Create a overloaded declaration reference cursor for an expression.
215CXCursor MakeCursorOverloadedDeclRef(const OverloadExpr *E,
216                                     CXTranslationUnit TU);
217
218/// Create a overloaded declaration reference cursor for a declaration.
219CXCursor MakeCursorOverloadedDeclRef(const Decl *D, SourceLocation Location,
220                                     CXTranslationUnit TU);
221
222/// Create a overloaded declaration reference cursor for a template name.
223CXCursor MakeCursorOverloadedDeclRef(TemplateName Template,
224                                     SourceLocation Location,
225                                     CXTranslationUnit TU);
226
227/// Internal storage for an overloaded declaration reference cursor;
228typedef 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.
234std::pair<OverloadedDeclRefStorage, SourceLocation>
235getCursorOverloadedDeclRef(CXCursor C);
236
237const Decl *getCursorDecl(CXCursor Cursor);
238const Expr *getCursorExpr(CXCursor Cursor);
239const Stmt *getCursorStmt(CXCursor Cursor);
240const Attr *getCursorAttr(CXCursor Cursor);
241
242ASTContext &getCursorContext(CXCursor Cursor);
243ASTUnit *getCursorASTUnit(CXCursor Cursor);
244CXTranslationUnit getCursorTU(CXCursor Cursor);
245
246void getOverriddenCursors(CXCursor cursor,
247                          SmallVectorImpl<CXCursor> &overridden);
248
249/// Create an opaque pool used for fast generation of overridden
250/// CXCursor arrays.
251void *createOverridenCXCursorsPool();
252
253/// Dispose of the overridden CXCursors pool.
254void disposeOverridenCXCursorsPool(void *pool);
255
256/// Returns a index/location pair for a selector identifier if the cursor
257/// points to one.
258std::pair<int, SourceLocation> getSelectorIdentifierIndexAndLoc(CXCursor);
259static inline int getSelectorIdentifierIndex(CXCursor cursor) {
260  return getSelectorIdentifierIndexAndLoc(cursor).first;
261}
262static inline SourceLocation getSelectorIdentifierLoc(CXCursor cursor) {
263  return getSelectorIdentifierIndexAndLoc(cursor).second;
264}
265
266CXCursor getSelectorIdentifierCursor(int SelIdx, CXCursor cursor);
267
268static inline CXCursor getTypeRefedCallExprCursor(CXCursor cursor) {
269  CXCursor newCursor = cursor;
270  if (cursor.kind == CXCursor_CallExpr)
271    newCursor.xdata = 1;
272  return newCursor;
273}
274
275CXCursor 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.
280bool getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf);
281
282bool operator==(CXCursor X, CXCursor Y);
283
284inline 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.
288bool isFirstInDeclGroup(CXCursor C);
289
290} // namespace cxcursor
291} // namespace clang
292
293#endif
294