clang  3.7.0
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, "CXXCtorInitializer" },
26  { NKI_None, "TemplateArgument" },
27  { NKI_None, "NestedNameSpecifier" },
28  { NKI_None, "NestedNameSpecifierLoc" },
29  { NKI_None, "QualType" },
30  { NKI_None, "TypeLoc" },
31  { NKI_None, "Decl" },
32 #define DECL(DERIVED, BASE) { NKI_##BASE, #DERIVED "Decl" },
33 #include "clang/AST/DeclNodes.inc"
34  { NKI_None, "Stmt" },
35 #define STMT(DERIVED, BASE) { NKI_##BASE, #DERIVED },
36 #include "clang/AST/StmtNodes.inc"
37  { NKI_None, "Type" },
38 #define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" },
39 #include "clang/AST/TypeNodes.def"
40 };
41 
42 bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
43  return isBaseOf(KindId, Other.KindId, Distance);
44 }
45 
46 bool ASTNodeKind::isSame(ASTNodeKind Other) const {
47  return KindId != NKI_None && KindId == Other.KindId;
48 }
49 
50 bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived,
51  unsigned *Distance) {
52  if (Base == NKI_None || Derived == NKI_None) return false;
53  unsigned Dist = 0;
54  while (Derived != Base && Derived != NKI_None) {
55  Derived = AllKindInfo[Derived].ParentId;
56  ++Dist;
57  }
58  if (Distance)
59  *Distance = Dist;
60  return Derived == Base;
61 }
62 
63 StringRef ASTNodeKind::asStringRef() const { return AllKindInfo[KindId].Name; }
64 
66  ASTNodeKind Kind2) {
67  if (Kind1.isBaseOf(Kind2)) return Kind2;
68  if (Kind2.isBaseOf(Kind1)) return Kind1;
69  return ASTNodeKind();
70 }
71 
73  ASTNodeKind Kind2) {
74  NodeKindId Parent = Kind1.KindId;
75  while (!isBaseOf(Parent, Kind2.KindId, nullptr) && Parent != NKI_None) {
76  Parent = AllKindInfo[Parent].ParentId;
77  }
78  return ASTNodeKind(Parent);
79 }
80 
82  switch (D.getKind()) {
83 #define DECL(DERIVED, BASE) \
84  case Decl::DERIVED: return ASTNodeKind(NKI_##DERIVED##Decl);
85 #define ABSTRACT_DECL(D)
86 #include "clang/AST/DeclNodes.inc"
87  };
88  llvm_unreachable("invalid decl kind");
89 }
90 
92  switch (S.getStmtClass()) {
93  case Stmt::NoStmtClass: return NKI_None;
94 #define STMT(CLASS, PARENT) \
95  case Stmt::CLASS##Class: return ASTNodeKind(NKI_##CLASS);
96 #define ABSTRACT_STMT(S)
97 #include "clang/AST/StmtNodes.inc"
98  }
99  llvm_unreachable("invalid stmt kind");
100 }
101 
103  switch (T.getTypeClass()) {
104 #define TYPE(Class, Base) \
105  case Type::Class: return ASTNodeKind(NKI_##Class##Type);
106 #define ABSTRACT_TYPE(Class, Base)
107 #include "clang/AST/TypeNodes.def"
108  }
109  llvm_unreachable("invalid type kind");
110 }
111 
112 void DynTypedNode::print(llvm::raw_ostream &OS,
113  const PrintingPolicy &PP) const {
114  if (const TemplateArgument *TA = get<TemplateArgument>())
115  TA->print(PP, OS);
116  else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>())
117  NNS->print(OS, PP);
118  else if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
119  NNSL->getNestedNameSpecifier()->print(OS, PP);
120  else if (const QualType *QT = get<QualType>())
121  QT->print(OS, PP);
122  else if (const TypeLoc *TL = get<TypeLoc>())
123  TL->getType().print(OS, PP);
124  else if (const Decl *D = get<Decl>())
125  D->print(OS, PP);
126  else if (const Stmt *S = get<Stmt>())
127  S->printPretty(OS, nullptr, PP);
128  else if (const Type *T = get<Type>())
129  QualType(T, 0).print(OS, PP);
130  else
131  OS << "Unable to print values of type " << NodeKind.asStringRef() << "\n";
132 }
133 
134 void DynTypedNode::dump(llvm::raw_ostream &OS, SourceManager &SM) const {
135  if (const Decl *D = get<Decl>())
136  D->dump(OS);
137  else if (const Stmt *S = get<Stmt>())
138  S->dump(OS, SM);
139  else
140  OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
141 }
142 
144  if (const CXXCtorInitializer *CCI = get<CXXCtorInitializer>())
145  return CCI->getSourceRange();
146  if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
147  return NNSL->getSourceRange();
148  if (const TypeLoc *TL = get<TypeLoc>())
149  return TL->getSourceRange();
150  if (const Decl *D = get<Decl>())
151  return D->getSourceRange();
152  if (const Stmt *S = get<Stmt>())
153  return S->getSourceRange();
154  return SourceRange();
155 }
156 
157 } // end namespace ast_type_traits
158 } // end namespace clang
Defines the clang::ASTContext interface.
static ASTNodeKind getFromNode(const Decl &D)
Construct an identifier for the dynamic type of the node.
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:35
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:40
A C++ nested-name-specifier augmented with source location information.
bool isBaseOf(ASTNodeKind Other, unsigned *Distance=nullptr) const
Returns true if this is a base kind of (or same as) Other.
ASTNodeKind()
Empty identifier. It matches nothing.
Definition: ASTTypeTraits.h:49
TypeClass getTypeClass() const
Definition: Type.h:1486
SourceManager & SM
void dump(llvm::raw_ostream &OS, SourceManager &SM) const
Dumps the node to the given output stream.
Kind getKind() const
Definition: DeclBase.h:375
static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived type between Kind1 and Kind2.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine()) const
Definition: Type.h:907
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
StringRef asStringRef() const
String representation of the kind.
Represents a template argument.
Definition: TemplateBase.h:39
static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived common ancestor between Kind1 and Kind2.
bool isSame(ASTNodeKind Other) const
Returns true if this and Other represent the same kind.
Represents a C++ base or member initializer.
Definition: DeclCXX.h:1901
SourceRange getSourceRange() const
For nodes which represent textual entities in the source code, return their SourceRange. For all other nodes, return SourceRange().
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.
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const
Prints the node to the given output stream.
This class handles loading and caching of source files into memory.