clang  10.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 namespace clang {
22 namespace ast_type_traits {
23 
24 const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = {
25  { NKI_None, "<None>" },
26  { NKI_None, "TemplateArgument" },
27  { NKI_None, "TemplateName" },
28  { NKI_None, "NestedNameSpecifierLoc" },
29  { NKI_None, "QualType" },
30  { NKI_None, "TypeLoc" },
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 OPENMP_CLAUSE(TextualSpelling, Class) {NKI_OMPClause, #Class},
44 #include "clang/Basic/OpenMPKinds.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 OPENMP_CLAUSE(Name, Class) \
116  case OMPC_##Name: return ASTNodeKind(NKI_##Class);
117 #include "clang/Basic/OpenMPKinds.def"
118  case OMPC_threadprivate:
119  case OMPC_uniform:
120  case OMPC_device_type:
121  case OMPC_match:
122  case OMPC_unknown:
123  llvm_unreachable("unexpected OpenMP clause kind");
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, SourceManager &SM) const {
156  if (const Decl *D = get<Decl>())
157  D->dump(OS);
158  else if (const Stmt *S = get<Stmt>())
159  S->dump(OS, SM);
160  else if (const Type *T = get<Type>())
161  T->dump(OS);
162  else
163  OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
164 }
165 
167  if (const CXXCtorInitializer *CCI = get<CXXCtorInitializer>())
168  return CCI->getSourceRange();
169  if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
170  return NNSL->getSourceRange();
171  if (const TypeLoc *TL = get<TypeLoc>())
172  return TL->getSourceRange();
173  if (const Decl *D = get<Decl>())
174  return D->getSourceRange();
175  if (const Stmt *S = get<Stmt>())
176  return S->getSourceRange();
177  if (const auto *C = get<OMPClause>())
178  return SourceRange(C->getBeginLoc(), C->getEndLoc());
179  return SourceRange();
180 }
181 
182 } // end namespace ast_type_traits
183 } // end namespace clang
Defines the clang::ASTContext interface.
A (possibly-)qualified type.
Definition: Type.h:654
static ASTNodeKind getFromNode(const Decl &D)
Stmt - This represents one statement.
Definition: Stmt.h:66
StringRef asStringRef() const
String representation of the kind.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
The base class of the type hierarchy.
Definition: Type.h:1450
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:47
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:58
A C++ nested-name-specifier augmented with source location information.
ASTNodeKind()
Empty identifier. It matches nothing.
Definition: ASTTypeTraits.h:60
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void dump(llvm::raw_ostream &OS, SourceManager &SM) const
Dumps the node to the given output stream.
NodeId Parent
Definition: ASTDiff.cpp:191
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
Definition: OpenMPClause.h:79
Represents a C++ template name within the type system.
Definition: TemplateName.h:191
static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived type between Kind1 and Kind2.
SourceRange getSourceRange() const
For nodes which represent textual entities in the source code, return their SourceRange.
const SourceManager & SM
Definition: Format.cpp:1685
This file defines OpenMP AST classes for clauses.
NodeKind
A kind of a syntax node, used for implementing casts.
Definition: Nodes.h:37
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:51
TypeClass getTypeClass() const
Definition: Type.h:1876
bool isBaseOf(ASTNodeKind Other, unsigned *Distance=nullptr) const
Returns true if this is a base kind of (or same as) Other.
Represents a template argument.
Definition: TemplateBase.h:50
static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived common ancestor between Kind1 and Kind2.
Dataflow Directional Tag Classes.
StmtClass getStmtClass() const
Definition: Stmt.h:1109
Kind getKind() const
Definition: DeclBase.h:432
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2155
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
A trivial tuple used to represent a source range.
This class handles loading and caching of source files into memory.
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const
Prints the node to the given output stream.