clang  6.0.0svn
ASTTypeTraits.cpp
Go to the documentation of this file.
1 //===--- ASTTypeTraits.cpp --------------------------------------*- C++ -*-===//
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 // Provides a dynamic type identifier and a dynamically typed node container
11 // that can be used to store an AST base node at runtime in the same storage in
12 // a type safe way.
13 //
14 //===----------------------------------------------------------------------===//
15 
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/DeclCXX.h"
19 
20 namespace clang {
21 namespace ast_type_traits {
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, "CXXCtorInitializer" },
31  { NKI_None, "NestedNameSpecifier" },
32  { NKI_None, "Decl" },
33 #define DECL(DERIVED, BASE) { NKI_##BASE, #DERIVED "Decl" },
34 #include "clang/AST/DeclNodes.inc"
35  { NKI_None, "Stmt" },
36 #define STMT(DERIVED, BASE) { NKI_##BASE, #DERIVED },
37 #include "clang/AST/StmtNodes.inc"
38  { NKI_None, "Type" },
39 #define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" },
40 #include "clang/AST/TypeNodes.def"
41 };
42 
43 bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
44  return isBaseOf(KindId, Other.KindId, Distance);
45 }
46 
47 bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived,
48  unsigned *Distance) {
49  if (Base == NKI_None || Derived == NKI_None) return false;
50  unsigned Dist = 0;
51  while (Derived != Base && Derived != NKI_None) {
52  Derived = AllKindInfo[Derived].ParentId;
53  ++Dist;
54  }
55  if (Distance)
56  *Distance = Dist;
57  return Derived == Base;
58 }
59 
60 StringRef ASTNodeKind::asStringRef() const { return AllKindInfo[KindId].Name; }
61 
63  ASTNodeKind Kind2) {
64  if (Kind1.isBaseOf(Kind2)) return Kind2;
65  if (Kind2.isBaseOf(Kind1)) return Kind1;
66  return ASTNodeKind();
67 }
68 
70  ASTNodeKind Kind2) {
71  NodeKindId Parent = Kind1.KindId;
72  while (!isBaseOf(Parent, Kind2.KindId, nullptr) && Parent != NKI_None) {
73  Parent = AllKindInfo[Parent].ParentId;
74  }
75  return ASTNodeKind(Parent);
76 }
77 
79  switch (D.getKind()) {
80 #define DECL(DERIVED, BASE) \
81  case Decl::DERIVED: return ASTNodeKind(NKI_##DERIVED##Decl);
82 #define ABSTRACT_DECL(D)
83 #include "clang/AST/DeclNodes.inc"
84  };
85  llvm_unreachable("invalid decl kind");
86 }
87 
89  switch (S.getStmtClass()) {
90  case Stmt::NoStmtClass: return NKI_None;
91 #define STMT(CLASS, PARENT) \
92  case Stmt::CLASS##Class: return ASTNodeKind(NKI_##CLASS);
93 #define ABSTRACT_STMT(S)
94 #include "clang/AST/StmtNodes.inc"
95  }
96  llvm_unreachable("invalid stmt kind");
97 }
98 
100  switch (T.getTypeClass()) {
101 #define TYPE(Class, Base) \
102  case Type::Class: return ASTNodeKind(NKI_##Class##Type);
103 #define ABSTRACT_TYPE(Class, Base)
104 #include "clang/AST/TypeNodes.def"
105  }
106  llvm_unreachable("invalid type kind");
107 }
108 
109 void DynTypedNode::print(llvm::raw_ostream &OS,
110  const PrintingPolicy &PP) const {
111  if (const TemplateArgument *TA = get<TemplateArgument>())
112  TA->print(PP, OS);
113  else if (const TemplateName *TN = get<TemplateName>())
114  TN->print(OS, PP);
115  else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>())
116  NNS->print(OS, PP);
117  else if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
118  NNSL->getNestedNameSpecifier()->print(OS, PP);
119  else if (const QualType *QT = get<QualType>())
120  QT->print(OS, PP);
121  else if (const TypeLoc *TL = get<TypeLoc>())
122  TL->getType().print(OS, PP);
123  else if (const Decl *D = get<Decl>())
124  D->print(OS, PP);
125  else if (const Stmt *S = get<Stmt>())
126  S->printPretty(OS, nullptr, PP);
127  else if (const Type *T = get<Type>())
128  QualType(T, 0).print(OS, PP);
129  else
130  OS << "Unable to print values of type " << NodeKind.asStringRef() << "\n";
131 }
132 
133 void DynTypedNode::dump(llvm::raw_ostream &OS, SourceManager &SM) const {
134  if (const Decl *D = get<Decl>())
135  D->dump(OS);
136  else if (const Stmt *S = get<Stmt>())
137  S->dump(OS, SM);
138  else if (const Type *T = get<Type>())
139  T->dump(OS);
140  else
141  OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
142 }
143 
145  if (const CXXCtorInitializer *CCI = get<CXXCtorInitializer>())
146  return CCI->getSourceRange();
147  if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
148  return NNSL->getSourceRange();
149  if (const TypeLoc *TL = get<TypeLoc>())
150  return TL->getSourceRange();
151  if (const Decl *D = get<Decl>())
152  return D->getSourceRange();
153  if (const Stmt *S = get<Stmt>())
154  return S->getSourceRange();
155  return SourceRange();
156 }
157 
158 } // end namespace ast_type_traits
159 } // end namespace clang
void dump() const
Definition: ASTDumper.cpp:2673
Defines the clang::ASTContext interface.
A (possibly-)qualified type.
Definition: Type.h:653
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:991
static ASTNodeKind getFromNode(const Decl &D)
Construct an identifier for the dynamic type of the node.
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:86
The base class of the type hierarchy.
Definition: Type.h:1353
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:38
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:56
A C++ nested-name-specifier augmented with source location information.
ASTNodeKind()
Empty identifier. It matches nothing.
Definition: ASTTypeTraits.h:49
void dump(llvm::raw_ostream &OS, SourceManager &SM) const
Dumps the node to the given output stream.
NodeId Parent
Definition: ASTDiff.cpp:192
const FunctionProtoType * T
Represents a C++ template name within the type system.
Definition: TemplateName.h:178
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:1337
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
TypeClass getTypeClass() const
Definition: Type.h:1615
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:51
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:378
Kind getKind() const
Definition: DeclBase.h:419
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2172
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.