17330f729Sjoerg //===- CXCursor.h - Routines for manipulating CXCursors -------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file defines routines for manipulating CXCursors.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg
137330f729Sjoerg #ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXCURSOR_H
147330f729Sjoerg #define LLVM_CLANG_TOOLS_LIBCLANG_CXCURSOR_H
157330f729Sjoerg
167330f729Sjoerg #include "clang-c/Index.h"
177330f729Sjoerg #include "clang/Basic/SourceLocation.h"
187330f729Sjoerg #include "llvm/ADT/PointerUnion.h"
197330f729Sjoerg #include <utility>
207330f729Sjoerg
217330f729Sjoerg namespace clang {
227330f729Sjoerg
237330f729Sjoerg class ASTContext;
247330f729Sjoerg class ASTUnit;
257330f729Sjoerg class Attr;
267330f729Sjoerg class CXXBaseSpecifier;
277330f729Sjoerg class Decl;
287330f729Sjoerg class Expr;
297330f729Sjoerg class FieldDecl;
307330f729Sjoerg class InclusionDirective;
317330f729Sjoerg class LabelStmt;
327330f729Sjoerg class MacroDefinitionRecord;
337330f729Sjoerg class MacroExpansion;
347330f729Sjoerg class NamedDecl;
357330f729Sjoerg class ObjCInterfaceDecl;
367330f729Sjoerg class ObjCProtocolDecl;
377330f729Sjoerg class OverloadedTemplateStorage;
387330f729Sjoerg class OverloadExpr;
397330f729Sjoerg class Stmt;
407330f729Sjoerg class TemplateDecl;
417330f729Sjoerg class TemplateName;
427330f729Sjoerg class TypeDecl;
437330f729Sjoerg class VarDecl;
447330f729Sjoerg class IdentifierInfo;
457330f729Sjoerg
467330f729Sjoerg namespace cxcursor {
477330f729Sjoerg
487330f729Sjoerg CXCursor getCursor(CXTranslationUnit, SourceLocation);
497330f729Sjoerg
507330f729Sjoerg CXCursor MakeCXCursor(const clang::Attr *A, const clang::Decl *Parent,
517330f729Sjoerg CXTranslationUnit TU);
527330f729Sjoerg CXCursor MakeCXCursor(const clang::Decl *D, CXTranslationUnit TU,
537330f729Sjoerg SourceRange RegionOfInterest = SourceRange(),
547330f729Sjoerg bool FirstInDeclGroup = true);
557330f729Sjoerg CXCursor MakeCXCursor(const clang::Stmt *S, const clang::Decl *Parent,
567330f729Sjoerg CXTranslationUnit TU,
577330f729Sjoerg SourceRange RegionOfInterest = SourceRange());
587330f729Sjoerg CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = nullptr);
597330f729Sjoerg
607330f729Sjoerg /// Create an Objective-C superclass reference at the given location.
617330f729Sjoerg CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
62*e038c9c4Sjoerg SourceLocation Loc, CXTranslationUnit TU);
637330f729Sjoerg
647330f729Sjoerg /// Unpack an ObjCSuperClassRef cursor into the interface it references
657330f729Sjoerg /// and optionally the location where the reference occurred.
667330f729Sjoerg std::pair<const ObjCInterfaceDecl *, SourceLocation>
677330f729Sjoerg getCursorObjCSuperClassRef(CXCursor C);
687330f729Sjoerg
697330f729Sjoerg /// Create an Objective-C protocol reference at the given location.
707330f729Sjoerg CXCursor MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
71*e038c9c4Sjoerg SourceLocation Loc, CXTranslationUnit TU);
727330f729Sjoerg
737330f729Sjoerg /// Unpack an ObjCProtocolRef cursor into the protocol it references
747330f729Sjoerg /// and optionally the location where the reference occurred.
757330f729Sjoerg std::pair<const ObjCProtocolDecl *, SourceLocation>
767330f729Sjoerg getCursorObjCProtocolRef(CXCursor C);
777330f729Sjoerg
787330f729Sjoerg /// Create an Objective-C class reference at the given location.
797330f729Sjoerg CXCursor MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
80*e038c9c4Sjoerg SourceLocation Loc, CXTranslationUnit TU);
817330f729Sjoerg
827330f729Sjoerg /// Unpack an ObjCClassRef cursor into the class it references
837330f729Sjoerg /// and optionally the location where the reference occurred.
847330f729Sjoerg std::pair<const ObjCInterfaceDecl *, SourceLocation>
857330f729Sjoerg getCursorObjCClassRef(CXCursor C);
867330f729Sjoerg
877330f729Sjoerg /// Create a type reference at the given location.
887330f729Sjoerg CXCursor MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
897330f729Sjoerg CXTranslationUnit TU);
907330f729Sjoerg
917330f729Sjoerg /// Unpack a TypeRef cursor into the class it references
927330f729Sjoerg /// and optionally the location where the reference occurred.
937330f729Sjoerg std::pair<const TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C);
947330f729Sjoerg
957330f729Sjoerg /// Create a reference to a template at the given location.
967330f729Sjoerg CXCursor MakeCursorTemplateRef(const TemplateDecl *Template, SourceLocation Loc,
977330f729Sjoerg CXTranslationUnit TU);
987330f729Sjoerg
997330f729Sjoerg /// Unpack a TemplateRef cursor into the template it references and
1007330f729Sjoerg /// the location where the reference occurred.
1017330f729Sjoerg std::pair<const TemplateDecl *, SourceLocation>
1027330f729Sjoerg getCursorTemplateRef(CXCursor C);
1037330f729Sjoerg
1047330f729Sjoerg /// Create a reference to a namespace or namespace alias at the given
1057330f729Sjoerg /// location.
1067330f729Sjoerg CXCursor MakeCursorNamespaceRef(const NamedDecl *NS, SourceLocation Loc,
1077330f729Sjoerg CXTranslationUnit TU);
1087330f729Sjoerg
1097330f729Sjoerg /// Unpack a NamespaceRef cursor into the namespace or namespace alias
1107330f729Sjoerg /// it references and the location where the reference occurred.
1117330f729Sjoerg std::pair<const NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C);
1127330f729Sjoerg
1137330f729Sjoerg /// Create a reference to a variable at the given location.
1147330f729Sjoerg CXCursor MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
1157330f729Sjoerg CXTranslationUnit TU);
1167330f729Sjoerg
1177330f729Sjoerg /// Unpack a VariableRef cursor into the variable it references and the
1187330f729Sjoerg /// location where the where the reference occurred.
1197330f729Sjoerg std::pair<const VarDecl *, SourceLocation> getCursorVariableRef(CXCursor C);
1207330f729Sjoerg
1217330f729Sjoerg /// Create a reference to a field at the given location.
1227330f729Sjoerg CXCursor MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
1237330f729Sjoerg CXTranslationUnit TU);
1247330f729Sjoerg
1257330f729Sjoerg /// Unpack a MemberRef cursor into the field it references and the
1267330f729Sjoerg /// location where the reference occurred.
1277330f729Sjoerg std::pair<const FieldDecl *, SourceLocation> getCursorMemberRef(CXCursor C);
1287330f729Sjoerg
1297330f729Sjoerg /// Create a CXX base specifier cursor.
1307330f729Sjoerg CXCursor MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
1317330f729Sjoerg CXTranslationUnit TU);
1327330f729Sjoerg
1337330f729Sjoerg /// Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier.
1347330f729Sjoerg const CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C);
1357330f729Sjoerg
1367330f729Sjoerg /// Create a preprocessing directive cursor.
1377330f729Sjoerg CXCursor MakePreprocessingDirectiveCursor(SourceRange Range,
1387330f729Sjoerg CXTranslationUnit TU);
1397330f729Sjoerg
1407330f729Sjoerg /// Unpack a given preprocessing directive to retrieve its source range.
1417330f729Sjoerg SourceRange getCursorPreprocessingDirective(CXCursor C);
1427330f729Sjoerg
1437330f729Sjoerg /// Create a macro definition cursor.
1447330f729Sjoerg CXCursor MakeMacroDefinitionCursor(const MacroDefinitionRecord *,
1457330f729Sjoerg CXTranslationUnit TU);
1467330f729Sjoerg
1477330f729Sjoerg /// Unpack a given macro definition cursor to retrieve its
1487330f729Sjoerg /// source range.
1497330f729Sjoerg const MacroDefinitionRecord *getCursorMacroDefinition(CXCursor C);
1507330f729Sjoerg
1517330f729Sjoerg /// Create a macro expansion cursor.
1527330f729Sjoerg CXCursor MakeMacroExpansionCursor(MacroExpansion *, CXTranslationUnit TU);
1537330f729Sjoerg
1547330f729Sjoerg /// Create a "pseudo" macro expansion cursor, using a macro definition
1557330f729Sjoerg /// and a source location.
1567330f729Sjoerg CXCursor MakeMacroExpansionCursor(MacroDefinitionRecord *, SourceLocation Loc,
1577330f729Sjoerg CXTranslationUnit TU);
1587330f729Sjoerg
1597330f729Sjoerg /// Wraps a macro expansion cursor and provides a common interface
1607330f729Sjoerg /// for a normal macro expansion cursor or a "pseudo" one.
1617330f729Sjoerg ///
1627330f729Sjoerg /// "Pseudo" macro expansion cursors (essentially a macro definition along with
1637330f729Sjoerg /// a source location) are created in special cases, for example they can be
1647330f729Sjoerg /// created for identifiers inside macro definitions, if these identifiers are
1657330f729Sjoerg /// macro names.
1667330f729Sjoerg class MacroExpansionCursor {
1677330f729Sjoerg CXCursor C;
1687330f729Sjoerg
isPseudo()1697330f729Sjoerg bool isPseudo() const { return C.data[1] != nullptr; }
getAsMacroDefinition()1707330f729Sjoerg const MacroDefinitionRecord *getAsMacroDefinition() const {
1717330f729Sjoerg assert(isPseudo());
1727330f729Sjoerg return static_cast<const MacroDefinitionRecord *>(C.data[0]);
1737330f729Sjoerg }
getAsMacroExpansion()1747330f729Sjoerg const MacroExpansion *getAsMacroExpansion() const {
1757330f729Sjoerg assert(!isPseudo());
1767330f729Sjoerg return static_cast<const MacroExpansion *>(C.data[0]);
1777330f729Sjoerg }
getPseudoLoc()1787330f729Sjoerg SourceLocation getPseudoLoc() const {
1797330f729Sjoerg assert(isPseudo());
1807330f729Sjoerg return SourceLocation::getFromPtrEncoding(C.data[1]);
1817330f729Sjoerg }
1827330f729Sjoerg
1837330f729Sjoerg public:
MacroExpansionCursor(CXCursor C)1847330f729Sjoerg MacroExpansionCursor(CXCursor C) : C(C) {
1857330f729Sjoerg assert(C.kind == CXCursor_MacroExpansion);
1867330f729Sjoerg }
1877330f729Sjoerg
1887330f729Sjoerg const IdentifierInfo *getName() const;
1897330f729Sjoerg const MacroDefinitionRecord *getDefinition() const;
1907330f729Sjoerg SourceRange getSourceRange() const;
1917330f729Sjoerg };
1927330f729Sjoerg
1937330f729Sjoerg /// Unpack a given macro expansion cursor to retrieve its info.
getCursorMacroExpansion(CXCursor C)1947330f729Sjoerg static inline MacroExpansionCursor getCursorMacroExpansion(CXCursor C) {
1957330f729Sjoerg return C;
1967330f729Sjoerg }
1977330f729Sjoerg
1987330f729Sjoerg /// Create an inclusion directive cursor.
1997330f729Sjoerg CXCursor MakeInclusionDirectiveCursor(InclusionDirective *,
2007330f729Sjoerg CXTranslationUnit TU);
2017330f729Sjoerg
2027330f729Sjoerg /// Unpack a given inclusion directive cursor to retrieve its
2037330f729Sjoerg /// source range.
2047330f729Sjoerg const InclusionDirective *getCursorInclusionDirective(CXCursor C);
2057330f729Sjoerg
2067330f729Sjoerg /// Create a label reference at the given location.
2077330f729Sjoerg CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
2087330f729Sjoerg CXTranslationUnit TU);
2097330f729Sjoerg
2107330f729Sjoerg /// Unpack a label reference into the label statement it refers to and
2117330f729Sjoerg /// the location of the reference.
2127330f729Sjoerg std::pair<const LabelStmt *, SourceLocation> getCursorLabelRef(CXCursor C);
2137330f729Sjoerg
2147330f729Sjoerg /// Create a overloaded declaration reference cursor for an expression.
2157330f729Sjoerg CXCursor MakeCursorOverloadedDeclRef(const OverloadExpr *E,
2167330f729Sjoerg CXTranslationUnit TU);
2177330f729Sjoerg
2187330f729Sjoerg /// Create a overloaded declaration reference cursor for a declaration.
2197330f729Sjoerg CXCursor MakeCursorOverloadedDeclRef(const Decl *D, SourceLocation Location,
2207330f729Sjoerg CXTranslationUnit TU);
2217330f729Sjoerg
2227330f729Sjoerg /// Create a overloaded declaration reference cursor for a template name.
2237330f729Sjoerg CXCursor MakeCursorOverloadedDeclRef(TemplateName Template,
2247330f729Sjoerg SourceLocation Location,
2257330f729Sjoerg CXTranslationUnit TU);
2267330f729Sjoerg
2277330f729Sjoerg /// Internal storage for an overloaded declaration reference cursor;
228*e038c9c4Sjoerg typedef llvm::PointerUnion<const OverloadExpr *, const Decl *,
2297330f729Sjoerg OverloadedTemplateStorage *>
2307330f729Sjoerg OverloadedDeclRefStorage;
2317330f729Sjoerg
2327330f729Sjoerg /// Unpack an overloaded declaration reference into an expression,
2337330f729Sjoerg /// declaration, or template name along with the source location.
2347330f729Sjoerg std::pair<OverloadedDeclRefStorage, SourceLocation>
2357330f729Sjoerg getCursorOverloadedDeclRef(CXCursor C);
2367330f729Sjoerg
2377330f729Sjoerg const Decl *getCursorDecl(CXCursor Cursor);
2387330f729Sjoerg const Expr *getCursorExpr(CXCursor Cursor);
2397330f729Sjoerg const Stmt *getCursorStmt(CXCursor Cursor);
2407330f729Sjoerg const Attr *getCursorAttr(CXCursor Cursor);
2417330f729Sjoerg
2427330f729Sjoerg ASTContext &getCursorContext(CXCursor Cursor);
2437330f729Sjoerg ASTUnit *getCursorASTUnit(CXCursor Cursor);
2447330f729Sjoerg CXTranslationUnit getCursorTU(CXCursor Cursor);
2457330f729Sjoerg
2467330f729Sjoerg void getOverriddenCursors(CXCursor cursor,
2477330f729Sjoerg SmallVectorImpl<CXCursor> &overridden);
2487330f729Sjoerg
2497330f729Sjoerg /// Create an opaque pool used for fast generation of overridden
2507330f729Sjoerg /// CXCursor arrays.
2517330f729Sjoerg void *createOverridenCXCursorsPool();
2527330f729Sjoerg
2537330f729Sjoerg /// Dispose of the overridden CXCursors pool.
2547330f729Sjoerg void disposeOverridenCXCursorsPool(void *pool);
2557330f729Sjoerg
2567330f729Sjoerg /// Returns a index/location pair for a selector identifier if the cursor
2577330f729Sjoerg /// points to one.
2587330f729Sjoerg std::pair<int, SourceLocation> getSelectorIdentifierIndexAndLoc(CXCursor);
getSelectorIdentifierIndex(CXCursor cursor)2597330f729Sjoerg static inline int getSelectorIdentifierIndex(CXCursor cursor) {
2607330f729Sjoerg return getSelectorIdentifierIndexAndLoc(cursor).first;
2617330f729Sjoerg }
getSelectorIdentifierLoc(CXCursor cursor)2627330f729Sjoerg static inline SourceLocation getSelectorIdentifierLoc(CXCursor cursor) {
2637330f729Sjoerg return getSelectorIdentifierIndexAndLoc(cursor).second;
2647330f729Sjoerg }
2657330f729Sjoerg
2667330f729Sjoerg CXCursor getSelectorIdentifierCursor(int SelIdx, CXCursor cursor);
2677330f729Sjoerg
getTypeRefedCallExprCursor(CXCursor cursor)2687330f729Sjoerg static inline CXCursor getTypeRefedCallExprCursor(CXCursor cursor) {
2697330f729Sjoerg CXCursor newCursor = cursor;
2707330f729Sjoerg if (cursor.kind == CXCursor_CallExpr)
2717330f729Sjoerg newCursor.xdata = 1;
2727330f729Sjoerg return newCursor;
2737330f729Sjoerg }
2747330f729Sjoerg
2757330f729Sjoerg CXCursor getTypeRefCursor(CXCursor cursor);
2767330f729Sjoerg
2777330f729Sjoerg /// Generate a USR for \arg D and put it in \arg Buf.
2787330f729Sjoerg /// \returns true if no USR was computed or the result should be ignored,
2797330f729Sjoerg /// false otherwise.
2807330f729Sjoerg bool getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf);
2817330f729Sjoerg
2827330f729Sjoerg bool operator==(CXCursor X, CXCursor Y);
2837330f729Sjoerg
284*e038c9c4Sjoerg inline bool operator!=(CXCursor X, CXCursor Y) { return !(X == Y); }
2857330f729Sjoerg
2867330f729Sjoerg /// Return true if the cursor represents a declaration that is the
2877330f729Sjoerg /// first in a declaration group.
2887330f729Sjoerg bool isFirstInDeclGroup(CXCursor C);
2897330f729Sjoerg
290*e038c9c4Sjoerg } // namespace cxcursor
291*e038c9c4Sjoerg } // namespace clang
2927330f729Sjoerg
2937330f729Sjoerg #endif
294