clang  12.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 
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/DeclCXX.h"
19 #include "clang/AST/OpenMPClause.h"
20 
21 using namespace clang;
22 
23 const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = {
24  { NKI_None, "<None>" },
25  { NKI_None, "TemplateArgument" },
26  { NKI_None, "TemplateName" },
27  { NKI_None, "NestedNameSpecifierLoc" },
28  { NKI_None, "QualType" },
29  { NKI_None, "TypeLoc" },
30  { NKI_None, "CXXBaseSpecifier" },
31  { NKI_None, "CXXCtorInitializer" },
32  { NKI_None, "NestedNameSpecifier" },
33  { NKI_None, "Decl" },
34 #define DECL(DERIVED, BASE) { NKI_##BASE, #DERIVED "Decl" },
35 #include "clang/AST/DeclNodes.inc"
36  { NKI_None, "Stmt" },
37 #define STMT(DERIVED, BASE) { NKI_##BASE, #DERIVED },
38 #include "clang/AST/StmtNodes.inc"
39  { NKI_None, "Type" },
40 #define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" },
41 #include "clang/AST/TypeNodes.inc"
42  { NKI_None, "OMPClause" },
43 #define OMP_CLAUSE_CLASS(Enum, Str, Class) {NKI_OMPClause, #Class},
44 #include "llvm/Frontend/OpenMP/OMPKinds.def"
45 };
46 
47 bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
48  return isBaseOf(KindId, Other.KindId, Distance);
49 }
50 
51 bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived,
52  unsigned *Distance) {
53  if (Base == NKI_None || Derived == NKI_None) return false;
54  unsigned Dist = 0;
55  while (Derived != Base && Derived != NKI_None) {
56  Derived = AllKindInfo[Derived].ParentId;
57  ++Dist;
58  }
59  if (Distance)
60  *Distance = Dist;
61  return Derived == Base;
62 }
63 
64 StringRef ASTNodeKind::asStringRef() const { return AllKindInfo[KindId].Name; }
65 
67  ASTNodeKind Kind2) {
68  if (Kind1.isBaseOf(Kind2)) return Kind2;
69  if (Kind2.isBaseOf(Kind1)) return Kind1;
70  return ASTNodeKind();
71 }
72 
74  ASTNodeKind Kind2) {
75  NodeKindId Parent = Kind1.KindId;
76  while (!isBaseOf(Parent, Kind2.KindId, nullptr) && Parent != NKI_None) {
77  Parent = AllKindInfo[Parent].ParentId;
78  }
79  return ASTNodeKind(Parent);
80 }
81 
83  switch (D.getKind()) {
84 #define DECL(DERIVED, BASE) \
85  case Decl::DERIVED: return ASTNodeKind(NKI_##DERIVED##Decl);
86 #define ABSTRACT_DECL(D)
87 #include "clang/AST/DeclNodes.inc"
88  };
89  llvm_unreachable("invalid decl kind");
90 }
91 
93  switch (S.getStmtClass()) {
94  case Stmt::NoStmtClass: return NKI_None;
95 #define STMT(CLASS, PARENT) \
96  case Stmt::CLASS##Class: return ASTNodeKind(NKI_##CLASS);
97 #define ABSTRACT_STMT(S)
98 #include "clang/AST/StmtNodes.inc"
99  }
100  llvm_unreachable("invalid stmt kind");
101 }
102 
104  switch (T.getTypeClass()) {
105 #define TYPE(Class, Base) \
106  case Type::Class: return ASTNodeKind(NKI_##Class##Type);
107 #define ABSTRACT_TYPE(Class, Base)
108 #include "clang/AST/TypeNodes.inc"
109  }
110  llvm_unreachable("invalid type kind");
111  }
112 
114  switch (C.getClauseKind()) {
115 #define OMP_CLAUSE_CLASS(Enum, Str, Class) \
116  case llvm::omp::Clause::Enum: \
117  return ASTNodeKind(NKI_##Class);
118 #define OMP_CLAUSE_NO_CLASS(Enum, Str) \
119  case llvm::omp::Clause::Enum: \
120  llvm_unreachable("unexpected OpenMP clause kind");
121  default:
122  break;
123 #include "llvm/Frontend/OpenMP/OMPKinds.def"
124  }
125  llvm_unreachable("invalid stmt kind");
126 }
127 
128 void DynTypedNode::print(llvm::raw_ostream &OS,
129  const PrintingPolicy &PP) const {
130  if (const TemplateArgument *TA = get<TemplateArgument>())
131  TA->print(PP, OS);
132  else if (const TemplateName *TN = get<TemplateName>())
133  TN->print(OS, PP);
134  else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>())
135  NNS->print(OS, PP);
136  else if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>()) {
137  if (const NestedNameSpecifier *NNS = NNSL->getNestedNameSpecifier())
138  NNS->print(OS, PP);
139  else
140  OS << "(empty NestedNameSpecifierLoc)";
141  } else if (const QualType *QT = get<QualType>())
142  QT->print(OS, PP);
143  else if (const TypeLoc *TL = get<TypeLoc>())
144  TL->getType().print(OS, PP);
145  else if (const Decl *D = get<Decl>())
146  D->print(OS, PP);
147  else if (const Stmt *S = get<Stmt>())
148  S->printPretty(OS, nullptr, PP);
149  else if (const Type *T = get<Type>())
150  QualType(T, 0).print(OS, PP);
151  else
152  OS << "Unable to print values of type " << NodeKind.asStringRef() << "\n";
153 }
154 
155 void DynTypedNode::dump(llvm::raw_ostream &OS,
156  const ASTContext &Context) const {
157  if (const Decl *D = get<Decl>())
158  D->dump(OS);
159  else if (const Stmt *S = get<Stmt>())
160  S->dump(OS, Context);
161  else if (const Type *T = get<Type>())
162  T->dump(OS, Context);
163  else
164  OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
165 }
166 
168  if (const CXXCtorInitializer *CCI = get<CXXCtorInitializer>())
169  return CCI->getSourceRange();
170  if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
171  return NNSL->getSourceRange();
172  if (const TypeLoc *TL = get<TypeLoc>())
173  return TL->getSourceRange();
174  if (const Decl *D = get<Decl>())
175  return D->getSourceRange();
176  if (const Stmt *S = get<Stmt>())
177  return S->getSourceRange();
178  if (const auto *C = get<OMPClause>())
179  return SourceRange(C->getBeginLoc(), C->getEndLoc());
180  return SourceRange();
181 }
Defines the clang::ASTContext interface.
A (possibly-)qualified type.
Definition: Type.h:655
Stmt - This represents one statement.
Definition: Stmt.h:68
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
The base class of the type hierarchy.
Definition: Type.h:1472
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:49
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:58
static ASTNodeKind getFromNode(const Decl &D)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:174
A C++ nested-name-specifier augmented with source location information.
void dump(llvm::raw_ostream &OS, const ASTContext &Context) const
Dumps the node to the given output stream.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived type between Kind1 and Kind2.
NodeId Parent
Definition: ASTDiff.cpp:192
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
Definition: OpenMPClause.h:80
static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived common ancestor between Kind1 and Kind2.
Represents a C++ template name within the type system.
Definition: TemplateName.h:192
This file defines OpenMP AST classes for clauses.
NodeKind
A kind of a syntax node, used for implementing casts.
Definition: Nodes.h:37
SourceRange getSourceRange() const
For nodes which represent textual entities in the source code, return their SourceRange.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:52
StringRef asStringRef() const
String representation of the kind.
TypeClass getTypeClass() const
Definition: Type.h:1884
Represents a template argument.
Definition: TemplateBase.h:51
Dataflow Directional Tag Classes.
Kind identifier.
Definition: ASTTypeTraits.h:56
StmtClass getStmtClass() const
Definition: Stmt.h:1148
Kind getKind() const
Definition: DeclBase.h:433
bool isBaseOf(ASTNodeKind Other, unsigned *Distance=nullptr) const
Returns true if this is a base kind of (or same as) Other.
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2185
ASTNodeKind()
Empty identifier. It matches nothing.
Definition: ASTTypeTraits.h:59
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const
Prints the node to the given output stream.
A trivial tuple used to represent a source range.