1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | #include "clang/AST/ASTTypeTraits.h" |
16 | #include "clang/AST/ASTContext.h" |
17 | #include "clang/AST/DeclCXX.h" |
18 | |
19 | namespace clang { |
20 | namespace ast_type_traits { |
21 | |
22 | const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = { |
23 | { NKI_None, "<None>" }, |
24 | { NKI_None, "TemplateArgument" }, |
25 | { NKI_None, "TemplateName" }, |
26 | { NKI_None, "NestedNameSpecifierLoc" }, |
27 | { NKI_None, "QualType" }, |
28 | { NKI_None, "TypeLoc" }, |
29 | { NKI_None, "CXXCtorInitializer" }, |
30 | { NKI_None, "NestedNameSpecifier" }, |
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 | { NKI_None, "OMPClause" }, |
41 | #define OPENMP_CLAUSE(TextualSpelling, Class) {NKI_OMPClause, #Class}, |
42 | #include "clang/Basic/OpenMPKinds.def" |
43 | }; |
44 | |
45 | bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const { |
46 | return isBaseOf(KindId, Other.KindId, Distance); |
47 | } |
48 | |
49 | bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived, |
50 | unsigned *Distance) { |
51 | if (Base == NKI_None || Derived == NKI_None) return false; |
52 | unsigned Dist = 0; |
53 | while (Derived != Base && Derived != NKI_None) { |
54 | Derived = AllKindInfo[Derived].ParentId; |
55 | ++Dist; |
56 | } |
57 | if (Distance) |
58 | *Distance = Dist; |
59 | return Derived == Base; |
60 | } |
61 | |
62 | StringRef ASTNodeKind::asStringRef() const { return AllKindInfo[KindId].Name; } |
63 | |
64 | ASTNodeKind ASTNodeKind::getMostDerivedType(ASTNodeKind Kind1, |
65 | ASTNodeKind Kind2) { |
66 | if (Kind1.isBaseOf(Kind2)) return Kind2; |
67 | if (Kind2.isBaseOf(Kind1)) return Kind1; |
68 | return ASTNodeKind(); |
69 | } |
70 | |
71 | ASTNodeKind ASTNodeKind::getMostDerivedCommonAncestor(ASTNodeKind Kind1, |
72 | ASTNodeKind Kind2) { |
73 | NodeKindId Parent = Kind1.KindId; |
74 | while (!isBaseOf(Parent, Kind2.KindId, nullptr) && Parent != NKI_None) { |
75 | Parent = AllKindInfo[Parent].ParentId; |
76 | } |
77 | return ASTNodeKind(Parent); |
78 | } |
79 | |
80 | ASTNodeKind ASTNodeKind::getFromNode(const Decl &D) { |
81 | switch (D.getKind()) { |
82 | #define DECL(DERIVED, BASE) \ |
83 | case Decl::DERIVED: return ASTNodeKind(NKI_##DERIVED##Decl); |
84 | #define ABSTRACT_DECL(D) |
85 | #include "clang/AST/DeclNodes.inc" |
86 | }; |
87 | llvm_unreachable("invalid decl kind"); |
88 | } |
89 | |
90 | ASTNodeKind ASTNodeKind::getFromNode(const Stmt &S) { |
91 | switch (S.getStmtClass()) { |
92 | case Stmt::NoStmtClass: return NKI_None; |
93 | #define STMT(CLASS, PARENT) \ |
94 | case Stmt::CLASS##Class: return ASTNodeKind(NKI_##CLASS); |
95 | #define ABSTRACT_STMT(S) |
96 | #include "clang/AST/StmtNodes.inc" |
97 | } |
98 | llvm_unreachable("invalid stmt kind"); |
99 | } |
100 | |
101 | ASTNodeKind ASTNodeKind::getFromNode(const Type &T) { |
102 | switch (T.getTypeClass()) { |
103 | #define TYPE(Class, Base) \ |
104 | case Type::Class: return ASTNodeKind(NKI_##Class##Type); |
105 | #define ABSTRACT_TYPE(Class, Base) |
106 | #include "clang/AST/TypeNodes.def" |
107 | } |
108 | llvm_unreachable("invalid type kind"); |
109 | } |
110 | |
111 | ASTNodeKind ASTNodeKind::getFromNode(const OMPClause &C) { |
112 | switch (C.getClauseKind()) { |
113 | #define OPENMP_CLAUSE(Name, Class) \ |
114 | case OMPC_##Name: return ASTNodeKind(NKI_##Class); |
115 | #include "clang/Basic/OpenMPKinds.def" |
116 | case OMPC_threadprivate: |
117 | case OMPC_uniform: |
118 | case OMPC_unknown: |
119 | llvm_unreachable("unexpected OpenMP clause kind"); |
120 | } |
121 | llvm_unreachable("invalid stmt kind"); |
122 | } |
123 | |
124 | void DynTypedNode::print(llvm::raw_ostream &OS, |
125 | const PrintingPolicy &PP) const { |
126 | if (const TemplateArgument *TA = get<TemplateArgument>()) |
127 | TA->print(PP, OS); |
128 | else if (const TemplateName *TN = get<TemplateName>()) |
129 | TN->print(OS, PP); |
130 | else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>()) |
131 | NNS->print(OS, PP); |
132 | else if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>()) |
133 | NNSL->getNestedNameSpecifier()->print(OS, PP); |
134 | else if (const QualType *QT = get<QualType>()) |
135 | QT->print(OS, PP); |
136 | else if (const TypeLoc *TL = get<TypeLoc>()) |
137 | TL->getType().print(OS, PP); |
138 | else if (const Decl *D = get<Decl>()) |
139 | D->print(OS, PP); |
140 | else if (const Stmt *S = get<Stmt>()) |
141 | S->printPretty(OS, nullptr, PP); |
142 | else if (const Type *T = get<Type>()) |
143 | QualType(T, 0).print(OS, PP); |
144 | else |
145 | OS << "Unable to print values of type " << NodeKind.asStringRef() << "\n"; |
146 | } |
147 | |
148 | void DynTypedNode::dump(llvm::raw_ostream &OS, SourceManager &SM) const { |
149 | if (const Decl *D = get<Decl>()) |
150 | D->dump(OS); |
151 | else if (const Stmt *S = get<Stmt>()) |
152 | S->dump(OS, SM); |
153 | else if (const Type *T = get<Type>()) |
154 | T->dump(OS); |
155 | else |
156 | OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n"; |
157 | } |
158 | |
159 | SourceRange DynTypedNode::getSourceRange() const { |
160 | if (const CXXCtorInitializer *CCI = get<CXXCtorInitializer>()) |
161 | return CCI->getSourceRange(); |
162 | if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>()) |
163 | return NNSL->getSourceRange(); |
164 | if (const TypeLoc *TL = get<TypeLoc>()) |
165 | return TL->getSourceRange(); |
166 | if (const Decl *D = get<Decl>()) |
167 | return D->getSourceRange(); |
168 | if (const Stmt *S = get<Stmt>()) |
169 | return S->getSourceRange(); |
170 | if (const auto *C = get<OMPClause>()) |
171 | return SourceRange(C->getBeginLoc(), C->getEndLoc()); |
172 | return SourceRange(); |
173 | } |
174 | |
175 | } |
176 | } |
177 | |