clang 17.0.0git
ASTTypeTraits.cpp
Go to the documentation of this file.
1//===--- ASTTypeTraits.cpp --------------------------------------*- C++ -*-===//
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// Provides a dynamic type identifier and a dynamically typed node container
10// that can be used to store an AST base node at runtime in the same storage in
11// a type safe way.
12//
13//===----------------------------------------------------------------------===//
14
17#include "clang/AST/Attr.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/DeclObjC.h"
22#include "clang/AST/TypeLoc.h"
23
24using namespace clang;
25
26const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = {
27 {NKI_None, "<None>"},
28 {NKI_None, "TemplateArgument"},
29 {NKI_None, "TemplateArgumentLoc"},
30 {NKI_None, "LambdaCapture"},
31 {NKI_None, "TemplateName"},
32 {NKI_None, "NestedNameSpecifierLoc"},
33 {NKI_None, "QualType"},
34#define TYPELOC(CLASS, PARENT) {NKI_##PARENT, #CLASS "TypeLoc"},
35#include "clang/AST/TypeLocNodes.def"
36 {NKI_None, "TypeLoc"},
37 {NKI_None, "CXXBaseSpecifier"},
38 {NKI_None, "CXXCtorInitializer"},
39 {NKI_None, "NestedNameSpecifier"},
40 {NKI_None, "Decl"},
41#define DECL(DERIVED, BASE) { NKI_##BASE, #DERIVED "Decl" },
42#include "clang/AST/DeclNodes.inc"
43 {NKI_None, "Stmt"},
44#define STMT(DERIVED, BASE) { NKI_##BASE, #DERIVED },
45#include "clang/AST/StmtNodes.inc"
46 {NKI_None, "Type"},
47#define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" },
48#include "clang/AST/TypeNodes.inc"
49 {NKI_None, "OMPClause"},
50#define GEN_CLANG_CLAUSE_CLASS
51#define CLAUSE_CLASS(Enum, Str, Class) {NKI_OMPClause, #Class},
52#include "llvm/Frontend/OpenMP/OMP.inc"
53 {NKI_None, "Attr"},
54#define ATTR(A) {NKI_Attr, #A "Attr"},
55#include "clang/Basic/AttrList.inc"
56 {NKI_None, "ObjCProtocolLoc"},
57};
58
60 return isBaseOf(KindId, Other.KindId);
61}
62
63bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
64 return isBaseOf(KindId, Other.KindId, Distance);
65}
66
67bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived) {
68 if (Base == NKI_None || Derived == NKI_None)
69 return false;
70 while (Derived != Base && Derived != NKI_None) {
71 Derived = AllKindInfo[Derived].ParentId;
72 }
73 return Derived == Base;
74}
75
76bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived,
77 unsigned *Distance) {
78 if (Base == NKI_None || Derived == NKI_None) return false;
79 unsigned Dist = 0;
80 while (Derived != Base && Derived != NKI_None) {
81 Derived = AllKindInfo[Derived].ParentId;
82 ++Dist;
83 }
84 if (Distance)
85 *Distance = Dist;
86 return Derived == Base;
87}
88
90 NodeKindId LastId = KindId;
91 while (LastId) {
92 NodeKindId ParentId = AllKindInfo[LastId].ParentId;
93 if (ParentId == NKI_None)
94 return LastId;
95 LastId = ParentId;
96 }
97 return NKI_None;
98}
99
100StringRef ASTNodeKind::asStringRef() const { return AllKindInfo[KindId].Name; }
101
103 ASTNodeKind Kind2) {
104 if (Kind1.isBaseOf(Kind2)) return Kind2;
105 if (Kind2.isBaseOf(Kind1)) return Kind1;
106 return ASTNodeKind();
107}
108
110 ASTNodeKind Kind2) {
111 NodeKindId Parent = Kind1.KindId;
112 while (!isBaseOf(Parent, Kind2.KindId) && Parent != NKI_None) {
113 Parent = AllKindInfo[Parent].ParentId;
114 }
115 return ASTNodeKind(Parent);
116}
117
119 switch (D.getKind()) {
120#define DECL(DERIVED, BASE) \
121 case Decl::DERIVED: return ASTNodeKind(NKI_##DERIVED##Decl);
122#define ABSTRACT_DECL(D)
123#include "clang/AST/DeclNodes.inc"
124 };
125 llvm_unreachable("invalid decl kind");
126}
127
129 switch (S.getStmtClass()) {
130 case Stmt::NoStmtClass: return NKI_None;
131#define STMT(CLASS, PARENT) \
132 case Stmt::CLASS##Class: return ASTNodeKind(NKI_##CLASS);
133#define ABSTRACT_STMT(S)
134#include "clang/AST/StmtNodes.inc"
135 }
136 llvm_unreachable("invalid stmt kind");
137}
138
140 switch (T.getTypeClass()) {
141#define TYPE(Class, Base) \
142 case Type::Class: return ASTNodeKind(NKI_##Class##Type);
143#define ABSTRACT_TYPE(Class, Base)
144#include "clang/AST/TypeNodes.inc"
145 }
146 llvm_unreachable("invalid type kind");
147 }
148
150 switch (T.getTypeLocClass()) {
151#define ABSTRACT_TYPELOC(CLASS, PARENT)
152#define TYPELOC(CLASS, PARENT) \
153 case TypeLoc::CLASS: \
154 return ASTNodeKind(NKI_##CLASS##TypeLoc);
155#include "clang/AST/TypeLocNodes.def"
156 }
157 llvm_unreachable("invalid typeloc kind");
158 }
159
161 switch (C.getClauseKind()) {
162#define GEN_CLANG_CLAUSE_CLASS
163#define CLAUSE_CLASS(Enum, Str, Class) \
164 case llvm::omp::Clause::Enum: \
165 return ASTNodeKind(NKI_##Class);
166#define CLAUSE_NO_CLASS(Enum, Str) \
167 case llvm::omp::Clause::Enum: \
168 llvm_unreachable("unexpected OpenMP clause kind");
169#include "llvm/Frontend/OpenMP/OMP.inc"
170 }
171 llvm_unreachable("invalid omp clause kind");
172}
173
175 switch (A.getKind()) {
176#define ATTR(A) \
177 case attr::A: \
178 return ASTNodeKind(NKI_##A##Attr);
179#include "clang/Basic/AttrList.inc"
180 }
181 llvm_unreachable("invalid attr kind");
182}
183
184void DynTypedNode::print(llvm::raw_ostream &OS,
185 const PrintingPolicy &PP) const {
186 if (const TemplateArgument *TA = get<TemplateArgument>())
187 TA->print(PP, OS, /*IncludeType*/ true);
188 else if (const TemplateArgumentLoc *TAL = get<TemplateArgumentLoc>())
189 TAL->getArgument().print(PP, OS, /*IncludeType*/ true);
190 else if (const TemplateName *TN = get<TemplateName>())
191 TN->print(OS, PP);
192 else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>())
193 NNS->print(OS, PP);
194 else if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>()) {
195 if (const NestedNameSpecifier *NNS = NNSL->getNestedNameSpecifier())
196 NNS->print(OS, PP);
197 else
198 OS << "(empty NestedNameSpecifierLoc)";
199 } else if (const QualType *QT = get<QualType>())
200 QT->print(OS, PP);
201 else if (const TypeLoc *TL = get<TypeLoc>())
202 TL->getType().print(OS, PP);
203 else if (const Decl *D = get<Decl>())
204 D->print(OS, PP);
205 else if (const Stmt *S = get<Stmt>())
206 S->printPretty(OS, nullptr, PP);
207 else if (const Type *T = get<Type>())
208 QualType(T, 0).print(OS, PP);
209 else if (const Attr *A = get<Attr>())
210 A->printPretty(OS, PP);
211 else if (const ObjCProtocolLoc *P = get<ObjCProtocolLoc>())
212 P->getProtocol()->print(OS, PP);
213 else
214 OS << "Unable to print values of type " << NodeKind.asStringRef() << "\n";
215}
216
217void DynTypedNode::dump(llvm::raw_ostream &OS,
218 const ASTContext &Context) const {
219 if (const Decl *D = get<Decl>())
220 D->dump(OS);
221 else if (const Stmt *S = get<Stmt>())
222 S->dump(OS, Context);
223 else if (const Type *T = get<Type>())
224 T->dump(OS, Context);
225 else
226 OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
227}
228
230 if (const CXXCtorInitializer *CCI = get<CXXCtorInitializer>())
231 return CCI->getSourceRange();
232 if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
233 return NNSL->getSourceRange();
234 if (const TypeLoc *TL = get<TypeLoc>())
235 return TL->getSourceRange();
236 if (const Decl *D = get<Decl>())
237 return D->getSourceRange();
238 if (const Stmt *S = get<Stmt>())
239 return S->getSourceRange();
240 if (const TemplateArgumentLoc *TAL = get<TemplateArgumentLoc>())
241 return TAL->getSourceRange();
242 if (const auto *C = get<OMPClause>())
243 return SourceRange(C->getBeginLoc(), C->getEndLoc());
244 if (const auto *CBS = get<CXXBaseSpecifier>())
245 return CBS->getSourceRange();
246 if (const auto *A = get<Attr>())
247 return A->getRange();
248 if (const ObjCProtocolLoc *P = get<ObjCProtocolLoc>())
249 return P->getSourceRange();
250 return SourceRange();
251}
Defines the clang::ASTContext interface.
NodeId Parent
Definition: ASTDiff.cpp:191
StringRef P
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenMP AST classes for clauses.
Defines the clang::TypeLoc interface and its subclasses.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
Kind identifier.
Definition: ASTTypeTraits.h:51
StringRef asStringRef() const
String representation of the kind.
bool isBaseOf(ASTNodeKind Other) const
Returns true if this is a base kind of (or same as) Other.
constexpr ASTNodeKind()
Empty identifier. It matches nothing.
Definition: ASTTypeTraits.h:54
ASTNodeKind getCladeKind() const
static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived common ancestor between Kind1 and Kind2.
static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived type between Kind1 and Kind2.
static ASTNodeKind getFromNode(const Decl &D)
Attr - This represents one attribute.
Definition: Attr.h:40
attr::Kind getKind() const
Definition: Attr.h:80
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2259
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
Kind getKind() const
Definition: DeclBase.h:435
SourceRange getSourceRange() const
For nodes which represent textual entities in the source code, return their SourceRange.
void dump(llvm::raw_ostream &OS, const ASTContext &Context) const
Dumps the node to the given output stream.
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const
Prints the node to the given output stream.
A C++ nested-name-specifier augmented with source location information.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:55
A (possibly-)qualified type.
Definition: Type.h:736
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition: Stmt.h:72
@ NoStmtClass
Definition: Stmt.h:75
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:484
Represents a template argument.
Definition: TemplateBase.h:60
Represents a C++ template name within the type system.
Definition: TemplateName.h:202
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:58
TypeLocClass getTypeLocClass() const
Definition: TypeLoc.h:115
The base class of the type hierarchy.
Definition: Type.h:1568
TypeClass getTypeClass() const
Definition: Type.h:1987
@ C
Languages that the frontend can parse and compile.
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57