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