annotate clang/lib/AST/JSONNodeDumper.cpp @ 176:de4ac79aef9d

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 17:13:11 +0900
parents 0572611fdcc8
children 2e18cbf3894f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 #include "clang/AST/JSONNodeDumper.h"
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
2 #include "clang/Basic/SourceManager.h"
150
anatofuz
parents:
diff changeset
3 #include "clang/Lex/Lexer.h"
anatofuz
parents:
diff changeset
4 #include "llvm/ADT/StringSwitch.h"
anatofuz
parents:
diff changeset
5
anatofuz
parents:
diff changeset
6 using namespace clang;
anatofuz
parents:
diff changeset
7
anatofuz
parents:
diff changeset
8 void JSONNodeDumper::addPreviousDeclaration(const Decl *D) {
anatofuz
parents:
diff changeset
9 switch (D->getKind()) {
anatofuz
parents:
diff changeset
10 #define DECL(DERIVED, BASE) \
anatofuz
parents:
diff changeset
11 case Decl::DERIVED: \
anatofuz
parents:
diff changeset
12 return writePreviousDeclImpl(cast<DERIVED##Decl>(D));
anatofuz
parents:
diff changeset
13 #define ABSTRACT_DECL(DECL)
anatofuz
parents:
diff changeset
14 #include "clang/AST/DeclNodes.inc"
anatofuz
parents:
diff changeset
15 #undef ABSTRACT_DECL
anatofuz
parents:
diff changeset
16 #undef DECL
anatofuz
parents:
diff changeset
17 }
anatofuz
parents:
diff changeset
18 llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
anatofuz
parents:
diff changeset
19 }
anatofuz
parents:
diff changeset
20
anatofuz
parents:
diff changeset
21 void JSONNodeDumper::Visit(const Attr *A) {
anatofuz
parents:
diff changeset
22 const char *AttrName = nullptr;
anatofuz
parents:
diff changeset
23 switch (A->getKind()) {
anatofuz
parents:
diff changeset
24 #define ATTR(X) \
anatofuz
parents:
diff changeset
25 case attr::X: \
anatofuz
parents:
diff changeset
26 AttrName = #X"Attr"; \
anatofuz
parents:
diff changeset
27 break;
anatofuz
parents:
diff changeset
28 #include "clang/Basic/AttrList.inc"
anatofuz
parents:
diff changeset
29 #undef ATTR
anatofuz
parents:
diff changeset
30 }
anatofuz
parents:
diff changeset
31 JOS.attribute("id", createPointerRepresentation(A));
anatofuz
parents:
diff changeset
32 JOS.attribute("kind", AttrName);
anatofuz
parents:
diff changeset
33 JOS.attributeObject("range", [A, this] { writeSourceRange(A->getRange()); });
anatofuz
parents:
diff changeset
34 attributeOnlyIfTrue("inherited", A->isInherited());
anatofuz
parents:
diff changeset
35 attributeOnlyIfTrue("implicit", A->isImplicit());
anatofuz
parents:
diff changeset
36
anatofuz
parents:
diff changeset
37 // FIXME: it would be useful for us to output the spelling kind as well as
anatofuz
parents:
diff changeset
38 // the actual spelling. This would allow us to distinguish between the
anatofuz
parents:
diff changeset
39 // various attribute syntaxes, but we don't currently track that information
anatofuz
parents:
diff changeset
40 // within the AST.
anatofuz
parents:
diff changeset
41 //JOS.attribute("spelling", A->getSpelling());
anatofuz
parents:
diff changeset
42
anatofuz
parents:
diff changeset
43 InnerAttrVisitor::Visit(A);
anatofuz
parents:
diff changeset
44 }
anatofuz
parents:
diff changeset
45
anatofuz
parents:
diff changeset
46 void JSONNodeDumper::Visit(const Stmt *S) {
anatofuz
parents:
diff changeset
47 if (!S)
anatofuz
parents:
diff changeset
48 return;
anatofuz
parents:
diff changeset
49
anatofuz
parents:
diff changeset
50 JOS.attribute("id", createPointerRepresentation(S));
anatofuz
parents:
diff changeset
51 JOS.attribute("kind", S->getStmtClassName());
anatofuz
parents:
diff changeset
52 JOS.attributeObject("range",
anatofuz
parents:
diff changeset
53 [S, this] { writeSourceRange(S->getSourceRange()); });
anatofuz
parents:
diff changeset
54
anatofuz
parents:
diff changeset
55 if (const auto *E = dyn_cast<Expr>(S)) {
anatofuz
parents:
diff changeset
56 JOS.attribute("type", createQualType(E->getType()));
anatofuz
parents:
diff changeset
57 const char *Category = nullptr;
anatofuz
parents:
diff changeset
58 switch (E->getValueKind()) {
anatofuz
parents:
diff changeset
59 case VK_LValue: Category = "lvalue"; break;
anatofuz
parents:
diff changeset
60 case VK_XValue: Category = "xvalue"; break;
anatofuz
parents:
diff changeset
61 case VK_RValue: Category = "rvalue"; break;
anatofuz
parents:
diff changeset
62 }
anatofuz
parents:
diff changeset
63 JOS.attribute("valueCategory", Category);
anatofuz
parents:
diff changeset
64 }
anatofuz
parents:
diff changeset
65 InnerStmtVisitor::Visit(S);
anatofuz
parents:
diff changeset
66 }
anatofuz
parents:
diff changeset
67
anatofuz
parents:
diff changeset
68 void JSONNodeDumper::Visit(const Type *T) {
anatofuz
parents:
diff changeset
69 JOS.attribute("id", createPointerRepresentation(T));
anatofuz
parents:
diff changeset
70
anatofuz
parents:
diff changeset
71 if (!T)
anatofuz
parents:
diff changeset
72 return;
anatofuz
parents:
diff changeset
73
anatofuz
parents:
diff changeset
74 JOS.attribute("kind", (llvm::Twine(T->getTypeClassName()) + "Type").str());
anatofuz
parents:
diff changeset
75 JOS.attribute("type", createQualType(QualType(T, 0), /*Desugar*/ false));
anatofuz
parents:
diff changeset
76 attributeOnlyIfTrue("isDependent", T->isDependentType());
anatofuz
parents:
diff changeset
77 attributeOnlyIfTrue("isInstantiationDependent",
anatofuz
parents:
diff changeset
78 T->isInstantiationDependentType());
anatofuz
parents:
diff changeset
79 attributeOnlyIfTrue("isVariablyModified", T->isVariablyModifiedType());
anatofuz
parents:
diff changeset
80 attributeOnlyIfTrue("containsUnexpandedPack",
anatofuz
parents:
diff changeset
81 T->containsUnexpandedParameterPack());
anatofuz
parents:
diff changeset
82 attributeOnlyIfTrue("isImported", T->isFromAST());
anatofuz
parents:
diff changeset
83 InnerTypeVisitor::Visit(T);
anatofuz
parents:
diff changeset
84 }
anatofuz
parents:
diff changeset
85
anatofuz
parents:
diff changeset
86 void JSONNodeDumper::Visit(QualType T) {
anatofuz
parents:
diff changeset
87 JOS.attribute("id", createPointerRepresentation(T.getAsOpaquePtr()));
anatofuz
parents:
diff changeset
88 JOS.attribute("kind", "QualType");
anatofuz
parents:
diff changeset
89 JOS.attribute("type", createQualType(T));
anatofuz
parents:
diff changeset
90 JOS.attribute("qualifiers", T.split().Quals.getAsString());
anatofuz
parents:
diff changeset
91 }
anatofuz
parents:
diff changeset
92
anatofuz
parents:
diff changeset
93 void JSONNodeDumper::Visit(const Decl *D) {
anatofuz
parents:
diff changeset
94 JOS.attribute("id", createPointerRepresentation(D));
anatofuz
parents:
diff changeset
95
anatofuz
parents:
diff changeset
96 if (!D)
anatofuz
parents:
diff changeset
97 return;
anatofuz
parents:
diff changeset
98
anatofuz
parents:
diff changeset
99 JOS.attribute("kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str());
anatofuz
parents:
diff changeset
100 JOS.attributeObject("loc",
anatofuz
parents:
diff changeset
101 [D, this] { writeSourceLocation(D->getLocation()); });
anatofuz
parents:
diff changeset
102 JOS.attributeObject("range",
anatofuz
parents:
diff changeset
103 [D, this] { writeSourceRange(D->getSourceRange()); });
anatofuz
parents:
diff changeset
104 attributeOnlyIfTrue("isImplicit", D->isImplicit());
anatofuz
parents:
diff changeset
105 attributeOnlyIfTrue("isInvalid", D->isInvalidDecl());
anatofuz
parents:
diff changeset
106
anatofuz
parents:
diff changeset
107 if (D->isUsed())
anatofuz
parents:
diff changeset
108 JOS.attribute("isUsed", true);
anatofuz
parents:
diff changeset
109 else if (D->isThisDeclarationReferenced())
anatofuz
parents:
diff changeset
110 JOS.attribute("isReferenced", true);
anatofuz
parents:
diff changeset
111
anatofuz
parents:
diff changeset
112 if (const auto *ND = dyn_cast<NamedDecl>(D))
anatofuz
parents:
diff changeset
113 attributeOnlyIfTrue("isHidden", ND->isHidden());
anatofuz
parents:
diff changeset
114
anatofuz
parents:
diff changeset
115 if (D->getLexicalDeclContext() != D->getDeclContext()) {
anatofuz
parents:
diff changeset
116 // Because of multiple inheritance, a DeclContext pointer does not produce
anatofuz
parents:
diff changeset
117 // the same pointer representation as a Decl pointer that references the
anatofuz
parents:
diff changeset
118 // same AST Node.
anatofuz
parents:
diff changeset
119 const auto *ParentDeclContextDecl = dyn_cast<Decl>(D->getDeclContext());
anatofuz
parents:
diff changeset
120 JOS.attribute("parentDeclContextId",
anatofuz
parents:
diff changeset
121 createPointerRepresentation(ParentDeclContextDecl));
anatofuz
parents:
diff changeset
122 }
anatofuz
parents:
diff changeset
123
anatofuz
parents:
diff changeset
124 addPreviousDeclaration(D);
anatofuz
parents:
diff changeset
125 InnerDeclVisitor::Visit(D);
anatofuz
parents:
diff changeset
126 }
anatofuz
parents:
diff changeset
127
anatofuz
parents:
diff changeset
128 void JSONNodeDumper::Visit(const comments::Comment *C,
anatofuz
parents:
diff changeset
129 const comments::FullComment *FC) {
anatofuz
parents:
diff changeset
130 if (!C)
anatofuz
parents:
diff changeset
131 return;
anatofuz
parents:
diff changeset
132
anatofuz
parents:
diff changeset
133 JOS.attribute("id", createPointerRepresentation(C));
anatofuz
parents:
diff changeset
134 JOS.attribute("kind", C->getCommentKindName());
anatofuz
parents:
diff changeset
135 JOS.attributeObject("loc",
anatofuz
parents:
diff changeset
136 [C, this] { writeSourceLocation(C->getLocation()); });
anatofuz
parents:
diff changeset
137 JOS.attributeObject("range",
anatofuz
parents:
diff changeset
138 [C, this] { writeSourceRange(C->getSourceRange()); });
anatofuz
parents:
diff changeset
139
anatofuz
parents:
diff changeset
140 InnerCommentVisitor::visit(C, FC);
anatofuz
parents:
diff changeset
141 }
anatofuz
parents:
diff changeset
142
anatofuz
parents:
diff changeset
143 void JSONNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
anatofuz
parents:
diff changeset
144 const Decl *From, StringRef Label) {
anatofuz
parents:
diff changeset
145 JOS.attribute("kind", "TemplateArgument");
anatofuz
parents:
diff changeset
146 if (R.isValid())
anatofuz
parents:
diff changeset
147 JOS.attributeObject("range", [R, this] { writeSourceRange(R); });
anatofuz
parents:
diff changeset
148
anatofuz
parents:
diff changeset
149 if (From)
anatofuz
parents:
diff changeset
150 JOS.attribute(Label.empty() ? "fromDecl" : Label, createBareDeclRef(From));
anatofuz
parents:
diff changeset
151
anatofuz
parents:
diff changeset
152 InnerTemplateArgVisitor::Visit(TA);
anatofuz
parents:
diff changeset
153 }
anatofuz
parents:
diff changeset
154
anatofuz
parents:
diff changeset
155 void JSONNodeDumper::Visit(const CXXCtorInitializer *Init) {
anatofuz
parents:
diff changeset
156 JOS.attribute("kind", "CXXCtorInitializer");
anatofuz
parents:
diff changeset
157 if (Init->isAnyMemberInitializer())
anatofuz
parents:
diff changeset
158 JOS.attribute("anyInit", createBareDeclRef(Init->getAnyMember()));
anatofuz
parents:
diff changeset
159 else if (Init->isBaseInitializer())
anatofuz
parents:
diff changeset
160 JOS.attribute("baseInit",
anatofuz
parents:
diff changeset
161 createQualType(QualType(Init->getBaseClass(), 0)));
anatofuz
parents:
diff changeset
162 else if (Init->isDelegatingInitializer())
anatofuz
parents:
diff changeset
163 JOS.attribute("delegatingInit",
anatofuz
parents:
diff changeset
164 createQualType(Init->getTypeSourceInfo()->getType()));
anatofuz
parents:
diff changeset
165 else
anatofuz
parents:
diff changeset
166 llvm_unreachable("Unknown initializer type");
anatofuz
parents:
diff changeset
167 }
anatofuz
parents:
diff changeset
168
anatofuz
parents:
diff changeset
169 void JSONNodeDumper::Visit(const OMPClause *C) {}
anatofuz
parents:
diff changeset
170
anatofuz
parents:
diff changeset
171 void JSONNodeDumper::Visit(const BlockDecl::Capture &C) {
anatofuz
parents:
diff changeset
172 JOS.attribute("kind", "Capture");
anatofuz
parents:
diff changeset
173 attributeOnlyIfTrue("byref", C.isByRef());
anatofuz
parents:
diff changeset
174 attributeOnlyIfTrue("nested", C.isNested());
anatofuz
parents:
diff changeset
175 if (C.getVariable())
anatofuz
parents:
diff changeset
176 JOS.attribute("var", createBareDeclRef(C.getVariable()));
anatofuz
parents:
diff changeset
177 }
anatofuz
parents:
diff changeset
178
anatofuz
parents:
diff changeset
179 void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
anatofuz
parents:
diff changeset
180 JOS.attribute("associationKind", A.getTypeSourceInfo() ? "case" : "default");
anatofuz
parents:
diff changeset
181 attributeOnlyIfTrue("selected", A.isSelected());
anatofuz
parents:
diff changeset
182 }
anatofuz
parents:
diff changeset
183
anatofuz
parents:
diff changeset
184 void JSONNodeDumper::writeIncludeStack(PresumedLoc Loc, bool JustFirst) {
anatofuz
parents:
diff changeset
185 if (Loc.isInvalid())
anatofuz
parents:
diff changeset
186 return;
anatofuz
parents:
diff changeset
187
anatofuz
parents:
diff changeset
188 JOS.attributeBegin("includedFrom");
anatofuz
parents:
diff changeset
189 JOS.objectBegin();
anatofuz
parents:
diff changeset
190
anatofuz
parents:
diff changeset
191 if (!JustFirst) {
anatofuz
parents:
diff changeset
192 // Walk the stack recursively, then print out the presumed location.
anatofuz
parents:
diff changeset
193 writeIncludeStack(SM.getPresumedLoc(Loc.getIncludeLoc()));
anatofuz
parents:
diff changeset
194 }
anatofuz
parents:
diff changeset
195
anatofuz
parents:
diff changeset
196 JOS.attribute("file", Loc.getFilename());
anatofuz
parents:
diff changeset
197 JOS.objectEnd();
anatofuz
parents:
diff changeset
198 JOS.attributeEnd();
anatofuz
parents:
diff changeset
199 }
anatofuz
parents:
diff changeset
200
anatofuz
parents:
diff changeset
201 void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc,
anatofuz
parents:
diff changeset
202 bool IsSpelling) {
anatofuz
parents:
diff changeset
203 PresumedLoc Presumed = SM.getPresumedLoc(Loc);
anatofuz
parents:
diff changeset
204 unsigned ActualLine = IsSpelling ? SM.getSpellingLineNumber(Loc)
anatofuz
parents:
diff changeset
205 : SM.getExpansionLineNumber(Loc);
anatofuz
parents:
diff changeset
206 StringRef ActualFile = SM.getBufferName(Loc);
anatofuz
parents:
diff changeset
207
anatofuz
parents:
diff changeset
208 if (Presumed.isValid()) {
anatofuz
parents:
diff changeset
209 JOS.attribute("offset", SM.getDecomposedLoc(Loc).second);
anatofuz
parents:
diff changeset
210 if (LastLocFilename != ActualFile) {
anatofuz
parents:
diff changeset
211 JOS.attribute("file", ActualFile);
anatofuz
parents:
diff changeset
212 JOS.attribute("line", ActualLine);
anatofuz
parents:
diff changeset
213 } else if (LastLocLine != ActualLine)
anatofuz
parents:
diff changeset
214 JOS.attribute("line", ActualLine);
anatofuz
parents:
diff changeset
215
anatofuz
parents:
diff changeset
216 StringRef PresumedFile = Presumed.getFilename();
anatofuz
parents:
diff changeset
217 if (PresumedFile != ActualFile && LastLocPresumedFilename != PresumedFile)
anatofuz
parents:
diff changeset
218 JOS.attribute("presumedFile", PresumedFile);
anatofuz
parents:
diff changeset
219
anatofuz
parents:
diff changeset
220 unsigned PresumedLine = Presumed.getLine();
anatofuz
parents:
diff changeset
221 if (ActualLine != PresumedLine && LastLocPresumedLine != PresumedLine)
anatofuz
parents:
diff changeset
222 JOS.attribute("presumedLine", PresumedLine);
anatofuz
parents:
diff changeset
223
anatofuz
parents:
diff changeset
224 JOS.attribute("col", Presumed.getColumn());
anatofuz
parents:
diff changeset
225 JOS.attribute("tokLen",
anatofuz
parents:
diff changeset
226 Lexer::MeasureTokenLength(Loc, SM, Ctx.getLangOpts()));
anatofuz
parents:
diff changeset
227 LastLocFilename = ActualFile;
anatofuz
parents:
diff changeset
228 LastLocPresumedFilename = PresumedFile;
anatofuz
parents:
diff changeset
229 LastLocPresumedLine = PresumedLine;
anatofuz
parents:
diff changeset
230 LastLocLine = ActualLine;
anatofuz
parents:
diff changeset
231
anatofuz
parents:
diff changeset
232 // Orthogonal to the file, line, and column de-duplication is whether the
anatofuz
parents:
diff changeset
233 // given location was a result of an include. If so, print where the
anatofuz
parents:
diff changeset
234 // include location came from.
anatofuz
parents:
diff changeset
235 writeIncludeStack(SM.getPresumedLoc(Presumed.getIncludeLoc()),
anatofuz
parents:
diff changeset
236 /*JustFirst*/ true);
anatofuz
parents:
diff changeset
237 }
anatofuz
parents:
diff changeset
238 }
anatofuz
parents:
diff changeset
239
anatofuz
parents:
diff changeset
240 void JSONNodeDumper::writeSourceLocation(SourceLocation Loc) {
anatofuz
parents:
diff changeset
241 SourceLocation Spelling = SM.getSpellingLoc(Loc);
anatofuz
parents:
diff changeset
242 SourceLocation Expansion = SM.getExpansionLoc(Loc);
anatofuz
parents:
diff changeset
243
anatofuz
parents:
diff changeset
244 if (Expansion != Spelling) {
anatofuz
parents:
diff changeset
245 // If the expansion and the spelling are different, output subobjects
anatofuz
parents:
diff changeset
246 // describing both locations.
anatofuz
parents:
diff changeset
247 JOS.attributeObject("spellingLoc", [Spelling, this] {
anatofuz
parents:
diff changeset
248 writeBareSourceLocation(Spelling, /*IsSpelling*/ true);
anatofuz
parents:
diff changeset
249 });
anatofuz
parents:
diff changeset
250 JOS.attributeObject("expansionLoc", [Expansion, Loc, this] {
anatofuz
parents:
diff changeset
251 writeBareSourceLocation(Expansion, /*IsSpelling*/ false);
anatofuz
parents:
diff changeset
252 // If there is a macro expansion, add extra information if the interesting
anatofuz
parents:
diff changeset
253 // bit is the macro arg expansion.
anatofuz
parents:
diff changeset
254 if (SM.isMacroArgExpansion(Loc))
anatofuz
parents:
diff changeset
255 JOS.attribute("isMacroArgExpansion", true);
anatofuz
parents:
diff changeset
256 });
anatofuz
parents:
diff changeset
257 } else
anatofuz
parents:
diff changeset
258 writeBareSourceLocation(Spelling, /*IsSpelling*/ true);
anatofuz
parents:
diff changeset
259 }
anatofuz
parents:
diff changeset
260
anatofuz
parents:
diff changeset
261 void JSONNodeDumper::writeSourceRange(SourceRange R) {
anatofuz
parents:
diff changeset
262 JOS.attributeObject("begin",
anatofuz
parents:
diff changeset
263 [R, this] { writeSourceLocation(R.getBegin()); });
anatofuz
parents:
diff changeset
264 JOS.attributeObject("end", [R, this] { writeSourceLocation(R.getEnd()); });
anatofuz
parents:
diff changeset
265 }
anatofuz
parents:
diff changeset
266
anatofuz
parents:
diff changeset
267 std::string JSONNodeDumper::createPointerRepresentation(const void *Ptr) {
anatofuz
parents:
diff changeset
268 // Because JSON stores integer values as signed 64-bit integers, trying to
anatofuz
parents:
diff changeset
269 // represent them as such makes for very ugly pointer values in the resulting
anatofuz
parents:
diff changeset
270 // output. Instead, we convert the value to hex and treat it as a string.
anatofuz
parents:
diff changeset
271 return "0x" + llvm::utohexstr(reinterpret_cast<uint64_t>(Ptr), true);
anatofuz
parents:
diff changeset
272 }
anatofuz
parents:
diff changeset
273
anatofuz
parents:
diff changeset
274 llvm::json::Object JSONNodeDumper::createQualType(QualType QT, bool Desugar) {
anatofuz
parents:
diff changeset
275 SplitQualType SQT = QT.split();
anatofuz
parents:
diff changeset
276 llvm::json::Object Ret{{"qualType", QualType::getAsString(SQT, PrintPolicy)}};
anatofuz
parents:
diff changeset
277
anatofuz
parents:
diff changeset
278 if (Desugar && !QT.isNull()) {
anatofuz
parents:
diff changeset
279 SplitQualType DSQT = QT.getSplitDesugaredType();
anatofuz
parents:
diff changeset
280 if (DSQT != SQT)
anatofuz
parents:
diff changeset
281 Ret["desugaredQualType"] = QualType::getAsString(DSQT, PrintPolicy);
anatofuz
parents:
diff changeset
282 if (const auto *TT = QT->getAs<TypedefType>())
anatofuz
parents:
diff changeset
283 Ret["typeAliasDeclId"] = createPointerRepresentation(TT->getDecl());
anatofuz
parents:
diff changeset
284 }
anatofuz
parents:
diff changeset
285 return Ret;
anatofuz
parents:
diff changeset
286 }
anatofuz
parents:
diff changeset
287
anatofuz
parents:
diff changeset
288 void JSONNodeDumper::writeBareDeclRef(const Decl *D) {
anatofuz
parents:
diff changeset
289 JOS.attribute("id", createPointerRepresentation(D));
anatofuz
parents:
diff changeset
290 if (!D)
anatofuz
parents:
diff changeset
291 return;
anatofuz
parents:
diff changeset
292
anatofuz
parents:
diff changeset
293 JOS.attribute("kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str());
anatofuz
parents:
diff changeset
294 if (const auto *ND = dyn_cast<NamedDecl>(D))
anatofuz
parents:
diff changeset
295 JOS.attribute("name", ND->getDeclName().getAsString());
anatofuz
parents:
diff changeset
296 if (const auto *VD = dyn_cast<ValueDecl>(D))
anatofuz
parents:
diff changeset
297 JOS.attribute("type", createQualType(VD->getType()));
anatofuz
parents:
diff changeset
298 }
anatofuz
parents:
diff changeset
299
anatofuz
parents:
diff changeset
300 llvm::json::Object JSONNodeDumper::createBareDeclRef(const Decl *D) {
anatofuz
parents:
diff changeset
301 llvm::json::Object Ret{{"id", createPointerRepresentation(D)}};
anatofuz
parents:
diff changeset
302 if (!D)
anatofuz
parents:
diff changeset
303 return Ret;
anatofuz
parents:
diff changeset
304
anatofuz
parents:
diff changeset
305 Ret["kind"] = (llvm::Twine(D->getDeclKindName()) + "Decl").str();
anatofuz
parents:
diff changeset
306 if (const auto *ND = dyn_cast<NamedDecl>(D))
anatofuz
parents:
diff changeset
307 Ret["name"] = ND->getDeclName().getAsString();
anatofuz
parents:
diff changeset
308 if (const auto *VD = dyn_cast<ValueDecl>(D))
anatofuz
parents:
diff changeset
309 Ret["type"] = createQualType(VD->getType());
anatofuz
parents:
diff changeset
310 return Ret;
anatofuz
parents:
diff changeset
311 }
anatofuz
parents:
diff changeset
312
anatofuz
parents:
diff changeset
313 llvm::json::Array JSONNodeDumper::createCastPath(const CastExpr *C) {
anatofuz
parents:
diff changeset
314 llvm::json::Array Ret;
anatofuz
parents:
diff changeset
315 if (C->path_empty())
anatofuz
parents:
diff changeset
316 return Ret;
anatofuz
parents:
diff changeset
317
anatofuz
parents:
diff changeset
318 for (auto I = C->path_begin(), E = C->path_end(); I != E; ++I) {
anatofuz
parents:
diff changeset
319 const CXXBaseSpecifier *Base = *I;
anatofuz
parents:
diff changeset
320 const auto *RD =
anatofuz
parents:
diff changeset
321 cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
anatofuz
parents:
diff changeset
322
anatofuz
parents:
diff changeset
323 llvm::json::Object Val{{"name", RD->getName()}};
anatofuz
parents:
diff changeset
324 if (Base->isVirtual())
anatofuz
parents:
diff changeset
325 Val["isVirtual"] = true;
anatofuz
parents:
diff changeset
326 Ret.push_back(std::move(Val));
anatofuz
parents:
diff changeset
327 }
anatofuz
parents:
diff changeset
328 return Ret;
anatofuz
parents:
diff changeset
329 }
anatofuz
parents:
diff changeset
330
anatofuz
parents:
diff changeset
331 #define FIELD2(Name, Flag) if (RD->Flag()) Ret[Name] = true
anatofuz
parents:
diff changeset
332 #define FIELD1(Flag) FIELD2(#Flag, Flag)
anatofuz
parents:
diff changeset
333
anatofuz
parents:
diff changeset
334 static llvm::json::Object
anatofuz
parents:
diff changeset
335 createDefaultConstructorDefinitionData(const CXXRecordDecl *RD) {
anatofuz
parents:
diff changeset
336 llvm::json::Object Ret;
anatofuz
parents:
diff changeset
337
anatofuz
parents:
diff changeset
338 FIELD2("exists", hasDefaultConstructor);
anatofuz
parents:
diff changeset
339 FIELD2("trivial", hasTrivialDefaultConstructor);
anatofuz
parents:
diff changeset
340 FIELD2("nonTrivial", hasNonTrivialDefaultConstructor);
anatofuz
parents:
diff changeset
341 FIELD2("userProvided", hasUserProvidedDefaultConstructor);
anatofuz
parents:
diff changeset
342 FIELD2("isConstexpr", hasConstexprDefaultConstructor);
anatofuz
parents:
diff changeset
343 FIELD2("needsImplicit", needsImplicitDefaultConstructor);
anatofuz
parents:
diff changeset
344 FIELD2("defaultedIsConstexpr", defaultedDefaultConstructorIsConstexpr);
anatofuz
parents:
diff changeset
345
anatofuz
parents:
diff changeset
346 return Ret;
anatofuz
parents:
diff changeset
347 }
anatofuz
parents:
diff changeset
348
anatofuz
parents:
diff changeset
349 static llvm::json::Object
anatofuz
parents:
diff changeset
350 createCopyConstructorDefinitionData(const CXXRecordDecl *RD) {
anatofuz
parents:
diff changeset
351 llvm::json::Object Ret;
anatofuz
parents:
diff changeset
352
anatofuz
parents:
diff changeset
353 FIELD2("simple", hasSimpleCopyConstructor);
anatofuz
parents:
diff changeset
354 FIELD2("trivial", hasTrivialCopyConstructor);
anatofuz
parents:
diff changeset
355 FIELD2("nonTrivial", hasNonTrivialCopyConstructor);
anatofuz
parents:
diff changeset
356 FIELD2("userDeclared", hasUserDeclaredCopyConstructor);
anatofuz
parents:
diff changeset
357 FIELD2("hasConstParam", hasCopyConstructorWithConstParam);
anatofuz
parents:
diff changeset
358 FIELD2("implicitHasConstParam", implicitCopyConstructorHasConstParam);
anatofuz
parents:
diff changeset
359 FIELD2("needsImplicit", needsImplicitCopyConstructor);
anatofuz
parents:
diff changeset
360 FIELD2("needsOverloadResolution", needsOverloadResolutionForCopyConstructor);
anatofuz
parents:
diff changeset
361 if (!RD->needsOverloadResolutionForCopyConstructor())
anatofuz
parents:
diff changeset
362 FIELD2("defaultedIsDeleted", defaultedCopyConstructorIsDeleted);
anatofuz
parents:
diff changeset
363
anatofuz
parents:
diff changeset
364 return Ret;
anatofuz
parents:
diff changeset
365 }
anatofuz
parents:
diff changeset
366
anatofuz
parents:
diff changeset
367 static llvm::json::Object
anatofuz
parents:
diff changeset
368 createMoveConstructorDefinitionData(const CXXRecordDecl *RD) {
anatofuz
parents:
diff changeset
369 llvm::json::Object Ret;
anatofuz
parents:
diff changeset
370
anatofuz
parents:
diff changeset
371 FIELD2("exists", hasMoveConstructor);
anatofuz
parents:
diff changeset
372 FIELD2("simple", hasSimpleMoveConstructor);
anatofuz
parents:
diff changeset
373 FIELD2("trivial", hasTrivialMoveConstructor);
anatofuz
parents:
diff changeset
374 FIELD2("nonTrivial", hasNonTrivialMoveConstructor);
anatofuz
parents:
diff changeset
375 FIELD2("userDeclared", hasUserDeclaredMoveConstructor);
anatofuz
parents:
diff changeset
376 FIELD2("needsImplicit", needsImplicitMoveConstructor);
anatofuz
parents:
diff changeset
377 FIELD2("needsOverloadResolution", needsOverloadResolutionForMoveConstructor);
anatofuz
parents:
diff changeset
378 if (!RD->needsOverloadResolutionForMoveConstructor())
anatofuz
parents:
diff changeset
379 FIELD2("defaultedIsDeleted", defaultedMoveConstructorIsDeleted);
anatofuz
parents:
diff changeset
380
anatofuz
parents:
diff changeset
381 return Ret;
anatofuz
parents:
diff changeset
382 }
anatofuz
parents:
diff changeset
383
anatofuz
parents:
diff changeset
384 static llvm::json::Object
anatofuz
parents:
diff changeset
385 createCopyAssignmentDefinitionData(const CXXRecordDecl *RD) {
anatofuz
parents:
diff changeset
386 llvm::json::Object Ret;
anatofuz
parents:
diff changeset
387
anatofuz
parents:
diff changeset
388 FIELD2("trivial", hasTrivialCopyAssignment);
anatofuz
parents:
diff changeset
389 FIELD2("nonTrivial", hasNonTrivialCopyAssignment);
anatofuz
parents:
diff changeset
390 FIELD2("hasConstParam", hasCopyAssignmentWithConstParam);
anatofuz
parents:
diff changeset
391 FIELD2("implicitHasConstParam", implicitCopyAssignmentHasConstParam);
anatofuz
parents:
diff changeset
392 FIELD2("userDeclared", hasUserDeclaredCopyAssignment);
anatofuz
parents:
diff changeset
393 FIELD2("needsImplicit", needsImplicitCopyAssignment);
anatofuz
parents:
diff changeset
394 FIELD2("needsOverloadResolution", needsOverloadResolutionForCopyAssignment);
anatofuz
parents:
diff changeset
395
anatofuz
parents:
diff changeset
396 return Ret;
anatofuz
parents:
diff changeset
397 }
anatofuz
parents:
diff changeset
398
anatofuz
parents:
diff changeset
399 static llvm::json::Object
anatofuz
parents:
diff changeset
400 createMoveAssignmentDefinitionData(const CXXRecordDecl *RD) {
anatofuz
parents:
diff changeset
401 llvm::json::Object Ret;
anatofuz
parents:
diff changeset
402
anatofuz
parents:
diff changeset
403 FIELD2("exists", hasMoveAssignment);
anatofuz
parents:
diff changeset
404 FIELD2("simple", hasSimpleMoveAssignment);
anatofuz
parents:
diff changeset
405 FIELD2("trivial", hasTrivialMoveAssignment);
anatofuz
parents:
diff changeset
406 FIELD2("nonTrivial", hasNonTrivialMoveAssignment);
anatofuz
parents:
diff changeset
407 FIELD2("userDeclared", hasUserDeclaredMoveAssignment);
anatofuz
parents:
diff changeset
408 FIELD2("needsImplicit", needsImplicitMoveAssignment);
anatofuz
parents:
diff changeset
409 FIELD2("needsOverloadResolution", needsOverloadResolutionForMoveAssignment);
anatofuz
parents:
diff changeset
410
anatofuz
parents:
diff changeset
411 return Ret;
anatofuz
parents:
diff changeset
412 }
anatofuz
parents:
diff changeset
413
anatofuz
parents:
diff changeset
414 static llvm::json::Object
anatofuz
parents:
diff changeset
415 createDestructorDefinitionData(const CXXRecordDecl *RD) {
anatofuz
parents:
diff changeset
416 llvm::json::Object Ret;
anatofuz
parents:
diff changeset
417
anatofuz
parents:
diff changeset
418 FIELD2("simple", hasSimpleDestructor);
anatofuz
parents:
diff changeset
419 FIELD2("irrelevant", hasIrrelevantDestructor);
anatofuz
parents:
diff changeset
420 FIELD2("trivial", hasTrivialDestructor);
anatofuz
parents:
diff changeset
421 FIELD2("nonTrivial", hasNonTrivialDestructor);
anatofuz
parents:
diff changeset
422 FIELD2("userDeclared", hasUserDeclaredDestructor);
anatofuz
parents:
diff changeset
423 FIELD2("needsImplicit", needsImplicitDestructor);
anatofuz
parents:
diff changeset
424 FIELD2("needsOverloadResolution", needsOverloadResolutionForDestructor);
anatofuz
parents:
diff changeset
425 if (!RD->needsOverloadResolutionForDestructor())
anatofuz
parents:
diff changeset
426 FIELD2("defaultedIsDeleted", defaultedDestructorIsDeleted);
anatofuz
parents:
diff changeset
427
anatofuz
parents:
diff changeset
428 return Ret;
anatofuz
parents:
diff changeset
429 }
anatofuz
parents:
diff changeset
430
anatofuz
parents:
diff changeset
431 llvm::json::Object
anatofuz
parents:
diff changeset
432 JSONNodeDumper::createCXXRecordDefinitionData(const CXXRecordDecl *RD) {
anatofuz
parents:
diff changeset
433 llvm::json::Object Ret;
anatofuz
parents:
diff changeset
434
anatofuz
parents:
diff changeset
435 // This data is common to all C++ classes.
anatofuz
parents:
diff changeset
436 FIELD1(isGenericLambda);
anatofuz
parents:
diff changeset
437 FIELD1(isLambda);
anatofuz
parents:
diff changeset
438 FIELD1(isEmpty);
anatofuz
parents:
diff changeset
439 FIELD1(isAggregate);
anatofuz
parents:
diff changeset
440 FIELD1(isStandardLayout);
anatofuz
parents:
diff changeset
441 FIELD1(isTriviallyCopyable);
anatofuz
parents:
diff changeset
442 FIELD1(isPOD);
anatofuz
parents:
diff changeset
443 FIELD1(isTrivial);
anatofuz
parents:
diff changeset
444 FIELD1(isPolymorphic);
anatofuz
parents:
diff changeset
445 FIELD1(isAbstract);
anatofuz
parents:
diff changeset
446 FIELD1(isLiteral);
anatofuz
parents:
diff changeset
447 FIELD1(canPassInRegisters);
anatofuz
parents:
diff changeset
448 FIELD1(hasUserDeclaredConstructor);
anatofuz
parents:
diff changeset
449 FIELD1(hasConstexprNonCopyMoveConstructor);
anatofuz
parents:
diff changeset
450 FIELD1(hasMutableFields);
anatofuz
parents:
diff changeset
451 FIELD1(hasVariantMembers);
anatofuz
parents:
diff changeset
452 FIELD2("canConstDefaultInit", allowConstDefaultInit);
anatofuz
parents:
diff changeset
453
anatofuz
parents:
diff changeset
454 Ret["defaultCtor"] = createDefaultConstructorDefinitionData(RD);
anatofuz
parents:
diff changeset
455 Ret["copyCtor"] = createCopyConstructorDefinitionData(RD);
anatofuz
parents:
diff changeset
456 Ret["moveCtor"] = createMoveConstructorDefinitionData(RD);
anatofuz
parents:
diff changeset
457 Ret["copyAssign"] = createCopyAssignmentDefinitionData(RD);
anatofuz
parents:
diff changeset
458 Ret["moveAssign"] = createMoveAssignmentDefinitionData(RD);
anatofuz
parents:
diff changeset
459 Ret["dtor"] = createDestructorDefinitionData(RD);
anatofuz
parents:
diff changeset
460
anatofuz
parents:
diff changeset
461 return Ret;
anatofuz
parents:
diff changeset
462 }
anatofuz
parents:
diff changeset
463
anatofuz
parents:
diff changeset
464 #undef FIELD1
anatofuz
parents:
diff changeset
465 #undef FIELD2
anatofuz
parents:
diff changeset
466
anatofuz
parents:
diff changeset
467 std::string JSONNodeDumper::createAccessSpecifier(AccessSpecifier AS) {
anatofuz
parents:
diff changeset
468 switch (AS) {
anatofuz
parents:
diff changeset
469 case AS_none: return "none";
anatofuz
parents:
diff changeset
470 case AS_private: return "private";
anatofuz
parents:
diff changeset
471 case AS_protected: return "protected";
anatofuz
parents:
diff changeset
472 case AS_public: return "public";
anatofuz
parents:
diff changeset
473 }
anatofuz
parents:
diff changeset
474 llvm_unreachable("Unknown access specifier");
anatofuz
parents:
diff changeset
475 }
anatofuz
parents:
diff changeset
476
anatofuz
parents:
diff changeset
477 llvm::json::Object
anatofuz
parents:
diff changeset
478 JSONNodeDumper::createCXXBaseSpecifier(const CXXBaseSpecifier &BS) {
anatofuz
parents:
diff changeset
479 llvm::json::Object Ret;
anatofuz
parents:
diff changeset
480
anatofuz
parents:
diff changeset
481 Ret["type"] = createQualType(BS.getType());
anatofuz
parents:
diff changeset
482 Ret["access"] = createAccessSpecifier(BS.getAccessSpecifier());
anatofuz
parents:
diff changeset
483 Ret["writtenAccess"] =
anatofuz
parents:
diff changeset
484 createAccessSpecifier(BS.getAccessSpecifierAsWritten());
anatofuz
parents:
diff changeset
485 if (BS.isVirtual())
anatofuz
parents:
diff changeset
486 Ret["isVirtual"] = true;
anatofuz
parents:
diff changeset
487 if (BS.isPackExpansion())
anatofuz
parents:
diff changeset
488 Ret["isPackExpansion"] = true;
anatofuz
parents:
diff changeset
489
anatofuz
parents:
diff changeset
490 return Ret;
anatofuz
parents:
diff changeset
491 }
anatofuz
parents:
diff changeset
492
anatofuz
parents:
diff changeset
493 void JSONNodeDumper::VisitTypedefType(const TypedefType *TT) {
anatofuz
parents:
diff changeset
494 JOS.attribute("decl", createBareDeclRef(TT->getDecl()));
anatofuz
parents:
diff changeset
495 }
anatofuz
parents:
diff changeset
496
anatofuz
parents:
diff changeset
497 void JSONNodeDumper::VisitFunctionType(const FunctionType *T) {
anatofuz
parents:
diff changeset
498 FunctionType::ExtInfo E = T->getExtInfo();
anatofuz
parents:
diff changeset
499 attributeOnlyIfTrue("noreturn", E.getNoReturn());
anatofuz
parents:
diff changeset
500 attributeOnlyIfTrue("producesResult", E.getProducesResult());
anatofuz
parents:
diff changeset
501 if (E.getHasRegParm())
anatofuz
parents:
diff changeset
502 JOS.attribute("regParm", E.getRegParm());
anatofuz
parents:
diff changeset
503 JOS.attribute("cc", FunctionType::getNameForCallConv(E.getCC()));
anatofuz
parents:
diff changeset
504 }
anatofuz
parents:
diff changeset
505
anatofuz
parents:
diff changeset
506 void JSONNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
anatofuz
parents:
diff changeset
507 FunctionProtoType::ExtProtoInfo E = T->getExtProtoInfo();
anatofuz
parents:
diff changeset
508 attributeOnlyIfTrue("trailingReturn", E.HasTrailingReturn);
anatofuz
parents:
diff changeset
509 attributeOnlyIfTrue("const", T->isConst());
anatofuz
parents:
diff changeset
510 attributeOnlyIfTrue("volatile", T->isVolatile());
anatofuz
parents:
diff changeset
511 attributeOnlyIfTrue("restrict", T->isRestrict());
anatofuz
parents:
diff changeset
512 attributeOnlyIfTrue("variadic", E.Variadic);
anatofuz
parents:
diff changeset
513 switch (E.RefQualifier) {
anatofuz
parents:
diff changeset
514 case RQ_LValue: JOS.attribute("refQualifier", "&"); break;
anatofuz
parents:
diff changeset
515 case RQ_RValue: JOS.attribute("refQualifier", "&&"); break;
anatofuz
parents:
diff changeset
516 case RQ_None: break;
anatofuz
parents:
diff changeset
517 }
anatofuz
parents:
diff changeset
518 switch (E.ExceptionSpec.Type) {
anatofuz
parents:
diff changeset
519 case EST_DynamicNone:
anatofuz
parents:
diff changeset
520 case EST_Dynamic: {
anatofuz
parents:
diff changeset
521 JOS.attribute("exceptionSpec", "throw");
anatofuz
parents:
diff changeset
522 llvm::json::Array Types;
anatofuz
parents:
diff changeset
523 for (QualType QT : E.ExceptionSpec.Exceptions)
anatofuz
parents:
diff changeset
524 Types.push_back(createQualType(QT));
anatofuz
parents:
diff changeset
525 JOS.attribute("exceptionTypes", std::move(Types));
anatofuz
parents:
diff changeset
526 } break;
anatofuz
parents:
diff changeset
527 case EST_MSAny:
anatofuz
parents:
diff changeset
528 JOS.attribute("exceptionSpec", "throw");
anatofuz
parents:
diff changeset
529 JOS.attribute("throwsAny", true);
anatofuz
parents:
diff changeset
530 break;
anatofuz
parents:
diff changeset
531 case EST_BasicNoexcept:
anatofuz
parents:
diff changeset
532 JOS.attribute("exceptionSpec", "noexcept");
anatofuz
parents:
diff changeset
533 break;
anatofuz
parents:
diff changeset
534 case EST_NoexceptTrue:
anatofuz
parents:
diff changeset
535 case EST_NoexceptFalse:
anatofuz
parents:
diff changeset
536 JOS.attribute("exceptionSpec", "noexcept");
anatofuz
parents:
diff changeset
537 JOS.attribute("conditionEvaluatesTo",
anatofuz
parents:
diff changeset
538 E.ExceptionSpec.Type == EST_NoexceptTrue);
anatofuz
parents:
diff changeset
539 //JOS.attributeWithCall("exceptionSpecExpr",
anatofuz
parents:
diff changeset
540 // [this, E]() { Visit(E.ExceptionSpec.NoexceptExpr); });
anatofuz
parents:
diff changeset
541 break;
anatofuz
parents:
diff changeset
542 case EST_NoThrow:
anatofuz
parents:
diff changeset
543 JOS.attribute("exceptionSpec", "nothrow");
anatofuz
parents:
diff changeset
544 break;
anatofuz
parents:
diff changeset
545 // FIXME: I cannot find a way to trigger these cases while dumping the AST. I
anatofuz
parents:
diff changeset
546 // suspect you can only run into them when executing an AST dump from within
anatofuz
parents:
diff changeset
547 // the debugger, which is not a use case we worry about for the JSON dumping
anatofuz
parents:
diff changeset
548 // feature.
anatofuz
parents:
diff changeset
549 case EST_DependentNoexcept:
anatofuz
parents:
diff changeset
550 case EST_Unevaluated:
anatofuz
parents:
diff changeset
551 case EST_Uninstantiated:
anatofuz
parents:
diff changeset
552 case EST_Unparsed:
anatofuz
parents:
diff changeset
553 case EST_None: break;
anatofuz
parents:
diff changeset
554 }
anatofuz
parents:
diff changeset
555 VisitFunctionType(T);
anatofuz
parents:
diff changeset
556 }
anatofuz
parents:
diff changeset
557
anatofuz
parents:
diff changeset
558 void JSONNodeDumper::VisitRValueReferenceType(const ReferenceType *RT) {
anatofuz
parents:
diff changeset
559 attributeOnlyIfTrue("spelledAsLValue", RT->isSpelledAsLValue());
anatofuz
parents:
diff changeset
560 }
anatofuz
parents:
diff changeset
561
anatofuz
parents:
diff changeset
562 void JSONNodeDumper::VisitArrayType(const ArrayType *AT) {
anatofuz
parents:
diff changeset
563 switch (AT->getSizeModifier()) {
anatofuz
parents:
diff changeset
564 case ArrayType::Star:
anatofuz
parents:
diff changeset
565 JOS.attribute("sizeModifier", "*");
anatofuz
parents:
diff changeset
566 break;
anatofuz
parents:
diff changeset
567 case ArrayType::Static:
anatofuz
parents:
diff changeset
568 JOS.attribute("sizeModifier", "static");
anatofuz
parents:
diff changeset
569 break;
anatofuz
parents:
diff changeset
570 case ArrayType::Normal:
anatofuz
parents:
diff changeset
571 break;
anatofuz
parents:
diff changeset
572 }
anatofuz
parents:
diff changeset
573
anatofuz
parents:
diff changeset
574 std::string Str = AT->getIndexTypeQualifiers().getAsString();
anatofuz
parents:
diff changeset
575 if (!Str.empty())
anatofuz
parents:
diff changeset
576 JOS.attribute("indexTypeQualifiers", Str);
anatofuz
parents:
diff changeset
577 }
anatofuz
parents:
diff changeset
578
anatofuz
parents:
diff changeset
579 void JSONNodeDumper::VisitConstantArrayType(const ConstantArrayType *CAT) {
anatofuz
parents:
diff changeset
580 // FIXME: this should use ZExt instead of SExt, but JSON doesn't allow a
anatofuz
parents:
diff changeset
581 // narrowing conversion to int64_t so it cannot be expressed.
anatofuz
parents:
diff changeset
582 JOS.attribute("size", CAT->getSize().getSExtValue());
anatofuz
parents:
diff changeset
583 VisitArrayType(CAT);
anatofuz
parents:
diff changeset
584 }
anatofuz
parents:
diff changeset
585
anatofuz
parents:
diff changeset
586 void JSONNodeDumper::VisitDependentSizedExtVectorType(
anatofuz
parents:
diff changeset
587 const DependentSizedExtVectorType *VT) {
anatofuz
parents:
diff changeset
588 JOS.attributeObject(
anatofuz
parents:
diff changeset
589 "attrLoc", [VT, this] { writeSourceLocation(VT->getAttributeLoc()); });
anatofuz
parents:
diff changeset
590 }
anatofuz
parents:
diff changeset
591
anatofuz
parents:
diff changeset
592 void JSONNodeDumper::VisitVectorType(const VectorType *VT) {
anatofuz
parents:
diff changeset
593 JOS.attribute("numElements", VT->getNumElements());
anatofuz
parents:
diff changeset
594 switch (VT->getVectorKind()) {
anatofuz
parents:
diff changeset
595 case VectorType::GenericVector:
anatofuz
parents:
diff changeset
596 break;
anatofuz
parents:
diff changeset
597 case VectorType::AltiVecVector:
anatofuz
parents:
diff changeset
598 JOS.attribute("vectorKind", "altivec");
anatofuz
parents:
diff changeset
599 break;
anatofuz
parents:
diff changeset
600 case VectorType::AltiVecPixel:
anatofuz
parents:
diff changeset
601 JOS.attribute("vectorKind", "altivec pixel");
anatofuz
parents:
diff changeset
602 break;
anatofuz
parents:
diff changeset
603 case VectorType::AltiVecBool:
anatofuz
parents:
diff changeset
604 JOS.attribute("vectorKind", "altivec bool");
anatofuz
parents:
diff changeset
605 break;
anatofuz
parents:
diff changeset
606 case VectorType::NeonVector:
anatofuz
parents:
diff changeset
607 JOS.attribute("vectorKind", "neon");
anatofuz
parents:
diff changeset
608 break;
anatofuz
parents:
diff changeset
609 case VectorType::NeonPolyVector:
anatofuz
parents:
diff changeset
610 JOS.attribute("vectorKind", "neon poly");
anatofuz
parents:
diff changeset
611 break;
anatofuz
parents:
diff changeset
612 }
anatofuz
parents:
diff changeset
613 }
anatofuz
parents:
diff changeset
614
anatofuz
parents:
diff changeset
615 void JSONNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *UUT) {
anatofuz
parents:
diff changeset
616 JOS.attribute("decl", createBareDeclRef(UUT->getDecl()));
anatofuz
parents:
diff changeset
617 }
anatofuz
parents:
diff changeset
618
anatofuz
parents:
diff changeset
619 void JSONNodeDumper::VisitUnaryTransformType(const UnaryTransformType *UTT) {
anatofuz
parents:
diff changeset
620 switch (UTT->getUTTKind()) {
anatofuz
parents:
diff changeset
621 case UnaryTransformType::EnumUnderlyingType:
anatofuz
parents:
diff changeset
622 JOS.attribute("transformKind", "underlying_type");
anatofuz
parents:
diff changeset
623 break;
anatofuz
parents:
diff changeset
624 }
anatofuz
parents:
diff changeset
625 }
anatofuz
parents:
diff changeset
626
anatofuz
parents:
diff changeset
627 void JSONNodeDumper::VisitTagType(const TagType *TT) {
anatofuz
parents:
diff changeset
628 JOS.attribute("decl", createBareDeclRef(TT->getDecl()));
anatofuz
parents:
diff changeset
629 }
anatofuz
parents:
diff changeset
630
anatofuz
parents:
diff changeset
631 void JSONNodeDumper::VisitTemplateTypeParmType(
anatofuz
parents:
diff changeset
632 const TemplateTypeParmType *TTPT) {
anatofuz
parents:
diff changeset
633 JOS.attribute("depth", TTPT->getDepth());
anatofuz
parents:
diff changeset
634 JOS.attribute("index", TTPT->getIndex());
anatofuz
parents:
diff changeset
635 attributeOnlyIfTrue("isPack", TTPT->isParameterPack());
anatofuz
parents:
diff changeset
636 JOS.attribute("decl", createBareDeclRef(TTPT->getDecl()));
anatofuz
parents:
diff changeset
637 }
anatofuz
parents:
diff changeset
638
anatofuz
parents:
diff changeset
639 void JSONNodeDumper::VisitAutoType(const AutoType *AT) {
anatofuz
parents:
diff changeset
640 JOS.attribute("undeduced", !AT->isDeduced());
anatofuz
parents:
diff changeset
641 switch (AT->getKeyword()) {
anatofuz
parents:
diff changeset
642 case AutoTypeKeyword::Auto:
anatofuz
parents:
diff changeset
643 JOS.attribute("typeKeyword", "auto");
anatofuz
parents:
diff changeset
644 break;
anatofuz
parents:
diff changeset
645 case AutoTypeKeyword::DecltypeAuto:
anatofuz
parents:
diff changeset
646 JOS.attribute("typeKeyword", "decltype(auto)");
anatofuz
parents:
diff changeset
647 break;
anatofuz
parents:
diff changeset
648 case AutoTypeKeyword::GNUAutoType:
anatofuz
parents:
diff changeset
649 JOS.attribute("typeKeyword", "__auto_type");
anatofuz
parents:
diff changeset
650 break;
anatofuz
parents:
diff changeset
651 }
anatofuz
parents:
diff changeset
652 }
anatofuz
parents:
diff changeset
653
anatofuz
parents:
diff changeset
654 void JSONNodeDumper::VisitTemplateSpecializationType(
anatofuz
parents:
diff changeset
655 const TemplateSpecializationType *TST) {
anatofuz
parents:
diff changeset
656 attributeOnlyIfTrue("isAlias", TST->isTypeAlias());
anatofuz
parents:
diff changeset
657
anatofuz
parents:
diff changeset
658 std::string Str;
anatofuz
parents:
diff changeset
659 llvm::raw_string_ostream OS(Str);
anatofuz
parents:
diff changeset
660 TST->getTemplateName().print(OS, PrintPolicy);
anatofuz
parents:
diff changeset
661 JOS.attribute("templateName", OS.str());
anatofuz
parents:
diff changeset
662 }
anatofuz
parents:
diff changeset
663
anatofuz
parents:
diff changeset
664 void JSONNodeDumper::VisitInjectedClassNameType(
anatofuz
parents:
diff changeset
665 const InjectedClassNameType *ICNT) {
anatofuz
parents:
diff changeset
666 JOS.attribute("decl", createBareDeclRef(ICNT->getDecl()));
anatofuz
parents:
diff changeset
667 }
anatofuz
parents:
diff changeset
668
anatofuz
parents:
diff changeset
669 void JSONNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *OIT) {
anatofuz
parents:
diff changeset
670 JOS.attribute("decl", createBareDeclRef(OIT->getDecl()));
anatofuz
parents:
diff changeset
671 }
anatofuz
parents:
diff changeset
672
anatofuz
parents:
diff changeset
673 void JSONNodeDumper::VisitPackExpansionType(const PackExpansionType *PET) {
anatofuz
parents:
diff changeset
674 if (llvm::Optional<unsigned> N = PET->getNumExpansions())
anatofuz
parents:
diff changeset
675 JOS.attribute("numExpansions", *N);
anatofuz
parents:
diff changeset
676 }
anatofuz
parents:
diff changeset
677
anatofuz
parents:
diff changeset
678 void JSONNodeDumper::VisitElaboratedType(const ElaboratedType *ET) {
anatofuz
parents:
diff changeset
679 if (const NestedNameSpecifier *NNS = ET->getQualifier()) {
anatofuz
parents:
diff changeset
680 std::string Str;
anatofuz
parents:
diff changeset
681 llvm::raw_string_ostream OS(Str);
anatofuz
parents:
diff changeset
682 NNS->print(OS, PrintPolicy, /*ResolveTemplateArgs*/ true);
anatofuz
parents:
diff changeset
683 JOS.attribute("qualifier", OS.str());
anatofuz
parents:
diff changeset
684 }
anatofuz
parents:
diff changeset
685 if (const TagDecl *TD = ET->getOwnedTagDecl())
anatofuz
parents:
diff changeset
686 JOS.attribute("ownedTagDecl", createBareDeclRef(TD));
anatofuz
parents:
diff changeset
687 }
anatofuz
parents:
diff changeset
688
anatofuz
parents:
diff changeset
689 void JSONNodeDumper::VisitMacroQualifiedType(const MacroQualifiedType *MQT) {
anatofuz
parents:
diff changeset
690 JOS.attribute("macroName", MQT->getMacroIdentifier()->getName());
anatofuz
parents:
diff changeset
691 }
anatofuz
parents:
diff changeset
692
anatofuz
parents:
diff changeset
693 void JSONNodeDumper::VisitMemberPointerType(const MemberPointerType *MPT) {
anatofuz
parents:
diff changeset
694 attributeOnlyIfTrue("isData", MPT->isMemberDataPointer());
anatofuz
parents:
diff changeset
695 attributeOnlyIfTrue("isFunction", MPT->isMemberFunctionPointer());
anatofuz
parents:
diff changeset
696 }
anatofuz
parents:
diff changeset
697
anatofuz
parents:
diff changeset
698 void JSONNodeDumper::VisitNamedDecl(const NamedDecl *ND) {
anatofuz
parents:
diff changeset
699 if (ND && ND->getDeclName()) {
anatofuz
parents:
diff changeset
700 JOS.attribute("name", ND->getNameAsString());
anatofuz
parents:
diff changeset
701 std::string MangledName = ASTNameGen.getName(ND);
anatofuz
parents:
diff changeset
702 if (!MangledName.empty())
anatofuz
parents:
diff changeset
703 JOS.attribute("mangledName", MangledName);
anatofuz
parents:
diff changeset
704 }
anatofuz
parents:
diff changeset
705 }
anatofuz
parents:
diff changeset
706
anatofuz
parents:
diff changeset
707 void JSONNodeDumper::VisitTypedefDecl(const TypedefDecl *TD) {
anatofuz
parents:
diff changeset
708 VisitNamedDecl(TD);
anatofuz
parents:
diff changeset
709 JOS.attribute("type", createQualType(TD->getUnderlyingType()));
anatofuz
parents:
diff changeset
710 }
anatofuz
parents:
diff changeset
711
anatofuz
parents:
diff changeset
712 void JSONNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *TAD) {
anatofuz
parents:
diff changeset
713 VisitNamedDecl(TAD);
anatofuz
parents:
diff changeset
714 JOS.attribute("type", createQualType(TAD->getUnderlyingType()));
anatofuz
parents:
diff changeset
715 }
anatofuz
parents:
diff changeset
716
anatofuz
parents:
diff changeset
717 void JSONNodeDumper::VisitNamespaceDecl(const NamespaceDecl *ND) {
anatofuz
parents:
diff changeset
718 VisitNamedDecl(ND);
anatofuz
parents:
diff changeset
719 attributeOnlyIfTrue("isInline", ND->isInline());
anatofuz
parents:
diff changeset
720 if (!ND->isOriginalNamespace())
anatofuz
parents:
diff changeset
721 JOS.attribute("originalNamespace",
anatofuz
parents:
diff changeset
722 createBareDeclRef(ND->getOriginalNamespace()));
anatofuz
parents:
diff changeset
723 }
anatofuz
parents:
diff changeset
724
anatofuz
parents:
diff changeset
725 void JSONNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *UDD) {
anatofuz
parents:
diff changeset
726 JOS.attribute("nominatedNamespace",
anatofuz
parents:
diff changeset
727 createBareDeclRef(UDD->getNominatedNamespace()));
anatofuz
parents:
diff changeset
728 }
anatofuz
parents:
diff changeset
729
anatofuz
parents:
diff changeset
730 void JSONNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *NAD) {
anatofuz
parents:
diff changeset
731 VisitNamedDecl(NAD);
anatofuz
parents:
diff changeset
732 JOS.attribute("aliasedNamespace",
anatofuz
parents:
diff changeset
733 createBareDeclRef(NAD->getAliasedNamespace()));
anatofuz
parents:
diff changeset
734 }
anatofuz
parents:
diff changeset
735
anatofuz
parents:
diff changeset
736 void JSONNodeDumper::VisitUsingDecl(const UsingDecl *UD) {
anatofuz
parents:
diff changeset
737 std::string Name;
anatofuz
parents:
diff changeset
738 if (const NestedNameSpecifier *NNS = UD->getQualifier()) {
anatofuz
parents:
diff changeset
739 llvm::raw_string_ostream SOS(Name);
anatofuz
parents:
diff changeset
740 NNS->print(SOS, UD->getASTContext().getPrintingPolicy());
anatofuz
parents:
diff changeset
741 }
anatofuz
parents:
diff changeset
742 Name += UD->getNameAsString();
anatofuz
parents:
diff changeset
743 JOS.attribute("name", Name);
anatofuz
parents:
diff changeset
744 }
anatofuz
parents:
diff changeset
745
anatofuz
parents:
diff changeset
746 void JSONNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *USD) {
anatofuz
parents:
diff changeset
747 JOS.attribute("target", createBareDeclRef(USD->getTargetDecl()));
anatofuz
parents:
diff changeset
748 }
anatofuz
parents:
diff changeset
749
anatofuz
parents:
diff changeset
750 void JSONNodeDumper::VisitVarDecl(const VarDecl *VD) {
anatofuz
parents:
diff changeset
751 VisitNamedDecl(VD);
anatofuz
parents:
diff changeset
752 JOS.attribute("type", createQualType(VD->getType()));
anatofuz
parents:
diff changeset
753
anatofuz
parents:
diff changeset
754 StorageClass SC = VD->getStorageClass();
anatofuz
parents:
diff changeset
755 if (SC != SC_None)
anatofuz
parents:
diff changeset
756 JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));
anatofuz
parents:
diff changeset
757 switch (VD->getTLSKind()) {
anatofuz
parents:
diff changeset
758 case VarDecl::TLS_Dynamic: JOS.attribute("tls", "dynamic"); break;
anatofuz
parents:
diff changeset
759 case VarDecl::TLS_Static: JOS.attribute("tls", "static"); break;
anatofuz
parents:
diff changeset
760 case VarDecl::TLS_None: break;
anatofuz
parents:
diff changeset
761 }
anatofuz
parents:
diff changeset
762 attributeOnlyIfTrue("nrvo", VD->isNRVOVariable());
anatofuz
parents:
diff changeset
763 attributeOnlyIfTrue("inline", VD->isInline());
anatofuz
parents:
diff changeset
764 attributeOnlyIfTrue("constexpr", VD->isConstexpr());
anatofuz
parents:
diff changeset
765 attributeOnlyIfTrue("modulePrivate", VD->isModulePrivate());
anatofuz
parents:
diff changeset
766 if (VD->hasInit()) {
anatofuz
parents:
diff changeset
767 switch (VD->getInitStyle()) {
anatofuz
parents:
diff changeset
768 case VarDecl::CInit: JOS.attribute("init", "c"); break;
anatofuz
parents:
diff changeset
769 case VarDecl::CallInit: JOS.attribute("init", "call"); break;
anatofuz
parents:
diff changeset
770 case VarDecl::ListInit: JOS.attribute("init", "list"); break;
anatofuz
parents:
diff changeset
771 }
anatofuz
parents:
diff changeset
772 }
anatofuz
parents:
diff changeset
773 attributeOnlyIfTrue("isParameterPack", VD->isParameterPack());
anatofuz
parents:
diff changeset
774 }
anatofuz
parents:
diff changeset
775
anatofuz
parents:
diff changeset
776 void JSONNodeDumper::VisitFieldDecl(const FieldDecl *FD) {
anatofuz
parents:
diff changeset
777 VisitNamedDecl(FD);
anatofuz
parents:
diff changeset
778 JOS.attribute("type", createQualType(FD->getType()));
anatofuz
parents:
diff changeset
779 attributeOnlyIfTrue("mutable", FD->isMutable());
anatofuz
parents:
diff changeset
780 attributeOnlyIfTrue("modulePrivate", FD->isModulePrivate());
anatofuz
parents:
diff changeset
781 attributeOnlyIfTrue("isBitfield", FD->isBitField());
anatofuz
parents:
diff changeset
782 attributeOnlyIfTrue("hasInClassInitializer", FD->hasInClassInitializer());
anatofuz
parents:
diff changeset
783 }
anatofuz
parents:
diff changeset
784
anatofuz
parents:
diff changeset
785 void JSONNodeDumper::VisitFunctionDecl(const FunctionDecl *FD) {
anatofuz
parents:
diff changeset
786 VisitNamedDecl(FD);
anatofuz
parents:
diff changeset
787 JOS.attribute("type", createQualType(FD->getType()));
anatofuz
parents:
diff changeset
788 StorageClass SC = FD->getStorageClass();
anatofuz
parents:
diff changeset
789 if (SC != SC_None)
anatofuz
parents:
diff changeset
790 JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));
anatofuz
parents:
diff changeset
791 attributeOnlyIfTrue("inline", FD->isInlineSpecified());
anatofuz
parents:
diff changeset
792 attributeOnlyIfTrue("virtual", FD->isVirtualAsWritten());
anatofuz
parents:
diff changeset
793 attributeOnlyIfTrue("pure", FD->isPure());
anatofuz
parents:
diff changeset
794 attributeOnlyIfTrue("explicitlyDeleted", FD->isDeletedAsWritten());
anatofuz
parents:
diff changeset
795 attributeOnlyIfTrue("constexpr", FD->isConstexpr());
anatofuz
parents:
diff changeset
796 attributeOnlyIfTrue("variadic", FD->isVariadic());
anatofuz
parents:
diff changeset
797
anatofuz
parents:
diff changeset
798 if (FD->isDefaulted())
anatofuz
parents:
diff changeset
799 JOS.attribute("explicitlyDefaulted",
anatofuz
parents:
diff changeset
800 FD->isDeleted() ? "deleted" : "default");
anatofuz
parents:
diff changeset
801 }
anatofuz
parents:
diff changeset
802
anatofuz
parents:
diff changeset
803 void JSONNodeDumper::VisitEnumDecl(const EnumDecl *ED) {
anatofuz
parents:
diff changeset
804 VisitNamedDecl(ED);
anatofuz
parents:
diff changeset
805 if (ED->isFixed())
anatofuz
parents:
diff changeset
806 JOS.attribute("fixedUnderlyingType", createQualType(ED->getIntegerType()));
anatofuz
parents:
diff changeset
807 if (ED->isScoped())
anatofuz
parents:
diff changeset
808 JOS.attribute("scopedEnumTag",
anatofuz
parents:
diff changeset
809 ED->isScopedUsingClassTag() ? "class" : "struct");
anatofuz
parents:
diff changeset
810 }
anatofuz
parents:
diff changeset
811 void JSONNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *ECD) {
anatofuz
parents:
diff changeset
812 VisitNamedDecl(ECD);
anatofuz
parents:
diff changeset
813 JOS.attribute("type", createQualType(ECD->getType()));
anatofuz
parents:
diff changeset
814 }
anatofuz
parents:
diff changeset
815
anatofuz
parents:
diff changeset
816 void JSONNodeDumper::VisitRecordDecl(const RecordDecl *RD) {
anatofuz
parents:
diff changeset
817 VisitNamedDecl(RD);
anatofuz
parents:
diff changeset
818 JOS.attribute("tagUsed", RD->getKindName());
anatofuz
parents:
diff changeset
819 attributeOnlyIfTrue("completeDefinition", RD->isCompleteDefinition());
anatofuz
parents:
diff changeset
820 }
anatofuz
parents:
diff changeset
821 void JSONNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *RD) {
anatofuz
parents:
diff changeset
822 VisitRecordDecl(RD);
anatofuz
parents:
diff changeset
823
anatofuz
parents:
diff changeset
824 // All other information requires a complete definition.
anatofuz
parents:
diff changeset
825 if (!RD->isCompleteDefinition())
anatofuz
parents:
diff changeset
826 return;
anatofuz
parents:
diff changeset
827
anatofuz
parents:
diff changeset
828 JOS.attribute("definitionData", createCXXRecordDefinitionData(RD));
anatofuz
parents:
diff changeset
829 if (RD->getNumBases()) {
anatofuz
parents:
diff changeset
830 JOS.attributeArray("bases", [this, RD] {
anatofuz
parents:
diff changeset
831 for (const auto &Spec : RD->bases())
anatofuz
parents:
diff changeset
832 JOS.value(createCXXBaseSpecifier(Spec));
anatofuz
parents:
diff changeset
833 });
anatofuz
parents:
diff changeset
834 }
anatofuz
parents:
diff changeset
835 }
anatofuz
parents:
diff changeset
836
anatofuz
parents:
diff changeset
837 void JSONNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
anatofuz
parents:
diff changeset
838 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
839 JOS.attribute("tagUsed", D->wasDeclaredWithTypename() ? "typename" : "class");
anatofuz
parents:
diff changeset
840 JOS.attribute("depth", D->getDepth());
anatofuz
parents:
diff changeset
841 JOS.attribute("index", D->getIndex());
anatofuz
parents:
diff changeset
842 attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
anatofuz
parents:
diff changeset
843
anatofuz
parents:
diff changeset
844 if (D->hasDefaultArgument())
anatofuz
parents:
diff changeset
845 JOS.attributeObject("defaultArg", [=] {
anatofuz
parents:
diff changeset
846 Visit(D->getDefaultArgument(), SourceRange(),
anatofuz
parents:
diff changeset
847 D->getDefaultArgStorage().getInheritedFrom(),
anatofuz
parents:
diff changeset
848 D->defaultArgumentWasInherited() ? "inherited from" : "previous");
anatofuz
parents:
diff changeset
849 });
anatofuz
parents:
diff changeset
850 }
anatofuz
parents:
diff changeset
851
anatofuz
parents:
diff changeset
852 void JSONNodeDumper::VisitNonTypeTemplateParmDecl(
anatofuz
parents:
diff changeset
853 const NonTypeTemplateParmDecl *D) {
anatofuz
parents:
diff changeset
854 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
855 JOS.attribute("type", createQualType(D->getType()));
anatofuz
parents:
diff changeset
856 JOS.attribute("depth", D->getDepth());
anatofuz
parents:
diff changeset
857 JOS.attribute("index", D->getIndex());
anatofuz
parents:
diff changeset
858 attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
anatofuz
parents:
diff changeset
859
anatofuz
parents:
diff changeset
860 if (D->hasDefaultArgument())
anatofuz
parents:
diff changeset
861 JOS.attributeObject("defaultArg", [=] {
anatofuz
parents:
diff changeset
862 Visit(D->getDefaultArgument(), SourceRange(),
anatofuz
parents:
diff changeset
863 D->getDefaultArgStorage().getInheritedFrom(),
anatofuz
parents:
diff changeset
864 D->defaultArgumentWasInherited() ? "inherited from" : "previous");
anatofuz
parents:
diff changeset
865 });
anatofuz
parents:
diff changeset
866 }
anatofuz
parents:
diff changeset
867
anatofuz
parents:
diff changeset
868 void JSONNodeDumper::VisitTemplateTemplateParmDecl(
anatofuz
parents:
diff changeset
869 const TemplateTemplateParmDecl *D) {
anatofuz
parents:
diff changeset
870 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
871 JOS.attribute("depth", D->getDepth());
anatofuz
parents:
diff changeset
872 JOS.attribute("index", D->getIndex());
anatofuz
parents:
diff changeset
873 attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
anatofuz
parents:
diff changeset
874
anatofuz
parents:
diff changeset
875 if (D->hasDefaultArgument())
anatofuz
parents:
diff changeset
876 JOS.attributeObject("defaultArg", [=] {
anatofuz
parents:
diff changeset
877 Visit(D->getDefaultArgument().getArgument(),
anatofuz
parents:
diff changeset
878 D->getDefaultArgStorage().getInheritedFrom()->getSourceRange(),
anatofuz
parents:
diff changeset
879 D->getDefaultArgStorage().getInheritedFrom(),
anatofuz
parents:
diff changeset
880 D->defaultArgumentWasInherited() ? "inherited from" : "previous");
anatofuz
parents:
diff changeset
881 });
anatofuz
parents:
diff changeset
882 }
anatofuz
parents:
diff changeset
883
anatofuz
parents:
diff changeset
884 void JSONNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *LSD) {
anatofuz
parents:
diff changeset
885 StringRef Lang;
anatofuz
parents:
diff changeset
886 switch (LSD->getLanguage()) {
anatofuz
parents:
diff changeset
887 case LinkageSpecDecl::lang_c: Lang = "C"; break;
anatofuz
parents:
diff changeset
888 case LinkageSpecDecl::lang_cxx: Lang = "C++"; break;
anatofuz
parents:
diff changeset
889 }
anatofuz
parents:
diff changeset
890 JOS.attribute("language", Lang);
anatofuz
parents:
diff changeset
891 attributeOnlyIfTrue("hasBraces", LSD->hasBraces());
anatofuz
parents:
diff changeset
892 }
anatofuz
parents:
diff changeset
893
anatofuz
parents:
diff changeset
894 void JSONNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *ASD) {
anatofuz
parents:
diff changeset
895 JOS.attribute("access", createAccessSpecifier(ASD->getAccess()));
anatofuz
parents:
diff changeset
896 }
anatofuz
parents:
diff changeset
897
anatofuz
parents:
diff changeset
898 void JSONNodeDumper::VisitFriendDecl(const FriendDecl *FD) {
anatofuz
parents:
diff changeset
899 if (const TypeSourceInfo *T = FD->getFriendType())
anatofuz
parents:
diff changeset
900 JOS.attribute("type", createQualType(T->getType()));
anatofuz
parents:
diff changeset
901 }
anatofuz
parents:
diff changeset
902
anatofuz
parents:
diff changeset
903 void JSONNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
anatofuz
parents:
diff changeset
904 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
905 JOS.attribute("type", createQualType(D->getType()));
anatofuz
parents:
diff changeset
906 attributeOnlyIfTrue("synthesized", D->getSynthesize());
anatofuz
parents:
diff changeset
907 switch (D->getAccessControl()) {
anatofuz
parents:
diff changeset
908 case ObjCIvarDecl::None: JOS.attribute("access", "none"); break;
anatofuz
parents:
diff changeset
909 case ObjCIvarDecl::Private: JOS.attribute("access", "private"); break;
anatofuz
parents:
diff changeset
910 case ObjCIvarDecl::Protected: JOS.attribute("access", "protected"); break;
anatofuz
parents:
diff changeset
911 case ObjCIvarDecl::Public: JOS.attribute("access", "public"); break;
anatofuz
parents:
diff changeset
912 case ObjCIvarDecl::Package: JOS.attribute("access", "package"); break;
anatofuz
parents:
diff changeset
913 }
anatofuz
parents:
diff changeset
914 }
anatofuz
parents:
diff changeset
915
anatofuz
parents:
diff changeset
916 void JSONNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
anatofuz
parents:
diff changeset
917 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
918 JOS.attribute("returnType", createQualType(D->getReturnType()));
anatofuz
parents:
diff changeset
919 JOS.attribute("instance", D->isInstanceMethod());
anatofuz
parents:
diff changeset
920 attributeOnlyIfTrue("variadic", D->isVariadic());
anatofuz
parents:
diff changeset
921 }
anatofuz
parents:
diff changeset
922
anatofuz
parents:
diff changeset
923 void JSONNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
anatofuz
parents:
diff changeset
924 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
925 JOS.attribute("type", createQualType(D->getUnderlyingType()));
anatofuz
parents:
diff changeset
926 attributeOnlyIfTrue("bounded", D->hasExplicitBound());
anatofuz
parents:
diff changeset
927 switch (D->getVariance()) {
anatofuz
parents:
diff changeset
928 case ObjCTypeParamVariance::Invariant:
anatofuz
parents:
diff changeset
929 break;
anatofuz
parents:
diff changeset
930 case ObjCTypeParamVariance::Covariant:
anatofuz
parents:
diff changeset
931 JOS.attribute("variance", "covariant");
anatofuz
parents:
diff changeset
932 break;
anatofuz
parents:
diff changeset
933 case ObjCTypeParamVariance::Contravariant:
anatofuz
parents:
diff changeset
934 JOS.attribute("variance", "contravariant");
anatofuz
parents:
diff changeset
935 break;
anatofuz
parents:
diff changeset
936 }
anatofuz
parents:
diff changeset
937 }
anatofuz
parents:
diff changeset
938
anatofuz
parents:
diff changeset
939 void JSONNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
anatofuz
parents:
diff changeset
940 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
941 JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
anatofuz
parents:
diff changeset
942 JOS.attribute("implementation", createBareDeclRef(D->getImplementation()));
anatofuz
parents:
diff changeset
943
anatofuz
parents:
diff changeset
944 llvm::json::Array Protocols;
anatofuz
parents:
diff changeset
945 for (const auto* P : D->protocols())
anatofuz
parents:
diff changeset
946 Protocols.push_back(createBareDeclRef(P));
anatofuz
parents:
diff changeset
947 if (!Protocols.empty())
anatofuz
parents:
diff changeset
948 JOS.attribute("protocols", std::move(Protocols));
anatofuz
parents:
diff changeset
949 }
anatofuz
parents:
diff changeset
950
anatofuz
parents:
diff changeset
951 void JSONNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
anatofuz
parents:
diff changeset
952 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
953 JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
anatofuz
parents:
diff changeset
954 JOS.attribute("categoryDecl", createBareDeclRef(D->getCategoryDecl()));
anatofuz
parents:
diff changeset
955 }
anatofuz
parents:
diff changeset
956
anatofuz
parents:
diff changeset
957 void JSONNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
anatofuz
parents:
diff changeset
958 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
959
anatofuz
parents:
diff changeset
960 llvm::json::Array Protocols;
anatofuz
parents:
diff changeset
961 for (const auto *P : D->protocols())
anatofuz
parents:
diff changeset
962 Protocols.push_back(createBareDeclRef(P));
anatofuz
parents:
diff changeset
963 if (!Protocols.empty())
anatofuz
parents:
diff changeset
964 JOS.attribute("protocols", std::move(Protocols));
anatofuz
parents:
diff changeset
965 }
anatofuz
parents:
diff changeset
966
anatofuz
parents:
diff changeset
967 void JSONNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
anatofuz
parents:
diff changeset
968 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
969 JOS.attribute("super", createBareDeclRef(D->getSuperClass()));
anatofuz
parents:
diff changeset
970 JOS.attribute("implementation", createBareDeclRef(D->getImplementation()));
anatofuz
parents:
diff changeset
971
anatofuz
parents:
diff changeset
972 llvm::json::Array Protocols;
anatofuz
parents:
diff changeset
973 for (const auto* P : D->protocols())
anatofuz
parents:
diff changeset
974 Protocols.push_back(createBareDeclRef(P));
anatofuz
parents:
diff changeset
975 if (!Protocols.empty())
anatofuz
parents:
diff changeset
976 JOS.attribute("protocols", std::move(Protocols));
anatofuz
parents:
diff changeset
977 }
anatofuz
parents:
diff changeset
978
anatofuz
parents:
diff changeset
979 void JSONNodeDumper::VisitObjCImplementationDecl(
anatofuz
parents:
diff changeset
980 const ObjCImplementationDecl *D) {
anatofuz
parents:
diff changeset
981 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
982 JOS.attribute("super", createBareDeclRef(D->getSuperClass()));
anatofuz
parents:
diff changeset
983 JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
anatofuz
parents:
diff changeset
984 }
anatofuz
parents:
diff changeset
985
anatofuz
parents:
diff changeset
986 void JSONNodeDumper::VisitObjCCompatibleAliasDecl(
anatofuz
parents:
diff changeset
987 const ObjCCompatibleAliasDecl *D) {
anatofuz
parents:
diff changeset
988 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
989 JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
anatofuz
parents:
diff changeset
990 }
anatofuz
parents:
diff changeset
991
anatofuz
parents:
diff changeset
992 void JSONNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
anatofuz
parents:
diff changeset
993 VisitNamedDecl(D);
anatofuz
parents:
diff changeset
994 JOS.attribute("type", createQualType(D->getType()));
anatofuz
parents:
diff changeset
995
anatofuz
parents:
diff changeset
996 switch (D->getPropertyImplementation()) {
anatofuz
parents:
diff changeset
997 case ObjCPropertyDecl::None: break;
anatofuz
parents:
diff changeset
998 case ObjCPropertyDecl::Required: JOS.attribute("control", "required"); break;
anatofuz
parents:
diff changeset
999 case ObjCPropertyDecl::Optional: JOS.attribute("control", "optional"); break;
anatofuz
parents:
diff changeset
1000 }
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1001
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1002 ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1003 if (Attrs != ObjCPropertyAttribute::kind_noattr) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1004 if (Attrs & ObjCPropertyAttribute::kind_getter)
150
anatofuz
parents:
diff changeset
1005 JOS.attribute("getter", createBareDeclRef(D->getGetterMethodDecl()));
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1006 if (Attrs & ObjCPropertyAttribute::kind_setter)
150
anatofuz
parents:
diff changeset
1007 JOS.attribute("setter", createBareDeclRef(D->getSetterMethodDecl()));
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1008 attributeOnlyIfTrue("readonly",
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1009 Attrs & ObjCPropertyAttribute::kind_readonly);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1010 attributeOnlyIfTrue("assign", Attrs & ObjCPropertyAttribute::kind_assign);
150
anatofuz
parents:
diff changeset
1011 attributeOnlyIfTrue("readwrite",
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1012 Attrs & ObjCPropertyAttribute::kind_readwrite);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1013 attributeOnlyIfTrue("retain", Attrs & ObjCPropertyAttribute::kind_retain);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1014 attributeOnlyIfTrue("copy", Attrs & ObjCPropertyAttribute::kind_copy);
150
anatofuz
parents:
diff changeset
1015 attributeOnlyIfTrue("nonatomic",
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1016 Attrs & ObjCPropertyAttribute::kind_nonatomic);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1017 attributeOnlyIfTrue("atomic", Attrs & ObjCPropertyAttribute::kind_atomic);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1018 attributeOnlyIfTrue("weak", Attrs & ObjCPropertyAttribute::kind_weak);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1019 attributeOnlyIfTrue("strong", Attrs & ObjCPropertyAttribute::kind_strong);
150
anatofuz
parents:
diff changeset
1020 attributeOnlyIfTrue("unsafe_unretained",
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1021 Attrs & ObjCPropertyAttribute::kind_unsafe_unretained);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1022 attributeOnlyIfTrue("class", Attrs & ObjCPropertyAttribute::kind_class);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1023 attributeOnlyIfTrue("direct", Attrs & ObjCPropertyAttribute::kind_direct);
150
anatofuz
parents:
diff changeset
1024 attributeOnlyIfTrue("nullability",
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1025 Attrs & ObjCPropertyAttribute::kind_nullability);
150
anatofuz
parents:
diff changeset
1026 attributeOnlyIfTrue("null_resettable",
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1027 Attrs & ObjCPropertyAttribute::kind_null_resettable);
150
anatofuz
parents:
diff changeset
1028 }
anatofuz
parents:
diff changeset
1029 }
anatofuz
parents:
diff changeset
1030
anatofuz
parents:
diff changeset
1031 void JSONNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
anatofuz
parents:
diff changeset
1032 VisitNamedDecl(D->getPropertyDecl());
anatofuz
parents:
diff changeset
1033 JOS.attribute("implKind", D->getPropertyImplementation() ==
anatofuz
parents:
diff changeset
1034 ObjCPropertyImplDecl::Synthesize
anatofuz
parents:
diff changeset
1035 ? "synthesize"
anatofuz
parents:
diff changeset
1036 : "dynamic");
anatofuz
parents:
diff changeset
1037 JOS.attribute("propertyDecl", createBareDeclRef(D->getPropertyDecl()));
anatofuz
parents:
diff changeset
1038 JOS.attribute("ivarDecl", createBareDeclRef(D->getPropertyIvarDecl()));
anatofuz
parents:
diff changeset
1039 }
anatofuz
parents:
diff changeset
1040
anatofuz
parents:
diff changeset
1041 void JSONNodeDumper::VisitBlockDecl(const BlockDecl *D) {
anatofuz
parents:
diff changeset
1042 attributeOnlyIfTrue("variadic", D->isVariadic());
anatofuz
parents:
diff changeset
1043 attributeOnlyIfTrue("capturesThis", D->capturesCXXThis());
anatofuz
parents:
diff changeset
1044 }
anatofuz
parents:
diff changeset
1045
anatofuz
parents:
diff changeset
1046 void JSONNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE) {
anatofuz
parents:
diff changeset
1047 JOS.attribute("encodedType", createQualType(OEE->getEncodedType()));
anatofuz
parents:
diff changeset
1048 }
anatofuz
parents:
diff changeset
1049
anatofuz
parents:
diff changeset
1050 void JSONNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *OME) {
anatofuz
parents:
diff changeset
1051 std::string Str;
anatofuz
parents:
diff changeset
1052 llvm::raw_string_ostream OS(Str);
anatofuz
parents:
diff changeset
1053
anatofuz
parents:
diff changeset
1054 OME->getSelector().print(OS);
anatofuz
parents:
diff changeset
1055 JOS.attribute("selector", OS.str());
anatofuz
parents:
diff changeset
1056
anatofuz
parents:
diff changeset
1057 switch (OME->getReceiverKind()) {
anatofuz
parents:
diff changeset
1058 case ObjCMessageExpr::Instance:
anatofuz
parents:
diff changeset
1059 JOS.attribute("receiverKind", "instance");
anatofuz
parents:
diff changeset
1060 break;
anatofuz
parents:
diff changeset
1061 case ObjCMessageExpr::Class:
anatofuz
parents:
diff changeset
1062 JOS.attribute("receiverKind", "class");
anatofuz
parents:
diff changeset
1063 JOS.attribute("classType", createQualType(OME->getClassReceiver()));
anatofuz
parents:
diff changeset
1064 break;
anatofuz
parents:
diff changeset
1065 case ObjCMessageExpr::SuperInstance:
anatofuz
parents:
diff changeset
1066 JOS.attribute("receiverKind", "super (instance)");
anatofuz
parents:
diff changeset
1067 JOS.attribute("superType", createQualType(OME->getSuperType()));
anatofuz
parents:
diff changeset
1068 break;
anatofuz
parents:
diff changeset
1069 case ObjCMessageExpr::SuperClass:
anatofuz
parents:
diff changeset
1070 JOS.attribute("receiverKind", "super (class)");
anatofuz
parents:
diff changeset
1071 JOS.attribute("superType", createQualType(OME->getSuperType()));
anatofuz
parents:
diff changeset
1072 break;
anatofuz
parents:
diff changeset
1073 }
anatofuz
parents:
diff changeset
1074
anatofuz
parents:
diff changeset
1075 QualType CallReturnTy = OME->getCallReturnType(Ctx);
anatofuz
parents:
diff changeset
1076 if (OME->getType() != CallReturnTy)
anatofuz
parents:
diff changeset
1077 JOS.attribute("callReturnType", createQualType(CallReturnTy));
anatofuz
parents:
diff changeset
1078 }
anatofuz
parents:
diff changeset
1079
anatofuz
parents:
diff changeset
1080 void JSONNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *OBE) {
anatofuz
parents:
diff changeset
1081 if (const ObjCMethodDecl *MD = OBE->getBoxingMethod()) {
anatofuz
parents:
diff changeset
1082 std::string Str;
anatofuz
parents:
diff changeset
1083 llvm::raw_string_ostream OS(Str);
anatofuz
parents:
diff changeset
1084
anatofuz
parents:
diff changeset
1085 MD->getSelector().print(OS);
anatofuz
parents:
diff changeset
1086 JOS.attribute("selector", OS.str());
anatofuz
parents:
diff changeset
1087 }
anatofuz
parents:
diff changeset
1088 }
anatofuz
parents:
diff changeset
1089
anatofuz
parents:
diff changeset
1090 void JSONNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *OSE) {
anatofuz
parents:
diff changeset
1091 std::string Str;
anatofuz
parents:
diff changeset
1092 llvm::raw_string_ostream OS(Str);
anatofuz
parents:
diff changeset
1093
anatofuz
parents:
diff changeset
1094 OSE->getSelector().print(OS);
anatofuz
parents:
diff changeset
1095 JOS.attribute("selector", OS.str());
anatofuz
parents:
diff changeset
1096 }
anatofuz
parents:
diff changeset
1097
anatofuz
parents:
diff changeset
1098 void JSONNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE) {
anatofuz
parents:
diff changeset
1099 JOS.attribute("protocol", createBareDeclRef(OPE->getProtocol()));
anatofuz
parents:
diff changeset
1100 }
anatofuz
parents:
diff changeset
1101
anatofuz
parents:
diff changeset
1102 void JSONNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE) {
anatofuz
parents:
diff changeset
1103 if (OPRE->isImplicitProperty()) {
anatofuz
parents:
diff changeset
1104 JOS.attribute("propertyKind", "implicit");
anatofuz
parents:
diff changeset
1105 if (const ObjCMethodDecl *MD = OPRE->getImplicitPropertyGetter())
anatofuz
parents:
diff changeset
1106 JOS.attribute("getter", createBareDeclRef(MD));
anatofuz
parents:
diff changeset
1107 if (const ObjCMethodDecl *MD = OPRE->getImplicitPropertySetter())
anatofuz
parents:
diff changeset
1108 JOS.attribute("setter", createBareDeclRef(MD));
anatofuz
parents:
diff changeset
1109 } else {
anatofuz
parents:
diff changeset
1110 JOS.attribute("propertyKind", "explicit");
anatofuz
parents:
diff changeset
1111 JOS.attribute("property", createBareDeclRef(OPRE->getExplicitProperty()));
anatofuz
parents:
diff changeset
1112 }
anatofuz
parents:
diff changeset
1113
anatofuz
parents:
diff changeset
1114 attributeOnlyIfTrue("isSuperReceiver", OPRE->isSuperReceiver());
anatofuz
parents:
diff changeset
1115 attributeOnlyIfTrue("isMessagingGetter", OPRE->isMessagingGetter());
anatofuz
parents:
diff changeset
1116 attributeOnlyIfTrue("isMessagingSetter", OPRE->isMessagingSetter());
anatofuz
parents:
diff changeset
1117 }
anatofuz
parents:
diff changeset
1118
anatofuz
parents:
diff changeset
1119 void JSONNodeDumper::VisitObjCSubscriptRefExpr(
anatofuz
parents:
diff changeset
1120 const ObjCSubscriptRefExpr *OSRE) {
anatofuz
parents:
diff changeset
1121 JOS.attribute("subscriptKind",
anatofuz
parents:
diff changeset
1122 OSRE->isArraySubscriptRefExpr() ? "array" : "dictionary");
anatofuz
parents:
diff changeset
1123
anatofuz
parents:
diff changeset
1124 if (const ObjCMethodDecl *MD = OSRE->getAtIndexMethodDecl())
anatofuz
parents:
diff changeset
1125 JOS.attribute("getter", createBareDeclRef(MD));
anatofuz
parents:
diff changeset
1126 if (const ObjCMethodDecl *MD = OSRE->setAtIndexMethodDecl())
anatofuz
parents:
diff changeset
1127 JOS.attribute("setter", createBareDeclRef(MD));
anatofuz
parents:
diff changeset
1128 }
anatofuz
parents:
diff changeset
1129
anatofuz
parents:
diff changeset
1130 void JSONNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {
anatofuz
parents:
diff changeset
1131 JOS.attribute("decl", createBareDeclRef(OIRE->getDecl()));
anatofuz
parents:
diff changeset
1132 attributeOnlyIfTrue("isFreeIvar", OIRE->isFreeIvar());
anatofuz
parents:
diff changeset
1133 JOS.attribute("isArrow", OIRE->isArrow());
anatofuz
parents:
diff changeset
1134 }
anatofuz
parents:
diff changeset
1135
anatofuz
parents:
diff changeset
1136 void JSONNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *OBLE) {
anatofuz
parents:
diff changeset
1137 JOS.attribute("value", OBLE->getValue() ? "__objc_yes" : "__objc_no");
anatofuz
parents:
diff changeset
1138 }
anatofuz
parents:
diff changeset
1139
anatofuz
parents:
diff changeset
1140 void JSONNodeDumper::VisitDeclRefExpr(const DeclRefExpr *DRE) {
anatofuz
parents:
diff changeset
1141 JOS.attribute("referencedDecl", createBareDeclRef(DRE->getDecl()));
anatofuz
parents:
diff changeset
1142 if (DRE->getDecl() != DRE->getFoundDecl())
anatofuz
parents:
diff changeset
1143 JOS.attribute("foundReferencedDecl",
anatofuz
parents:
diff changeset
1144 createBareDeclRef(DRE->getFoundDecl()));
anatofuz
parents:
diff changeset
1145 switch (DRE->isNonOdrUse()) {
anatofuz
parents:
diff changeset
1146 case NOUR_None: break;
anatofuz
parents:
diff changeset
1147 case NOUR_Unevaluated: JOS.attribute("nonOdrUseReason", "unevaluated"); break;
anatofuz
parents:
diff changeset
1148 case NOUR_Constant: JOS.attribute("nonOdrUseReason", "constant"); break;
anatofuz
parents:
diff changeset
1149 case NOUR_Discarded: JOS.attribute("nonOdrUseReason", "discarded"); break;
anatofuz
parents:
diff changeset
1150 }
anatofuz
parents:
diff changeset
1151 }
anatofuz
parents:
diff changeset
1152
anatofuz
parents:
diff changeset
1153 void JSONNodeDumper::VisitPredefinedExpr(const PredefinedExpr *PE) {
anatofuz
parents:
diff changeset
1154 JOS.attribute("name", PredefinedExpr::getIdentKindName(PE->getIdentKind()));
anatofuz
parents:
diff changeset
1155 }
anatofuz
parents:
diff changeset
1156
anatofuz
parents:
diff changeset
1157 void JSONNodeDumper::VisitUnaryOperator(const UnaryOperator *UO) {
anatofuz
parents:
diff changeset
1158 JOS.attribute("isPostfix", UO->isPostfix());
anatofuz
parents:
diff changeset
1159 JOS.attribute("opcode", UnaryOperator::getOpcodeStr(UO->getOpcode()));
anatofuz
parents:
diff changeset
1160 if (!UO->canOverflow())
anatofuz
parents:
diff changeset
1161 JOS.attribute("canOverflow", false);
anatofuz
parents:
diff changeset
1162 }
anatofuz
parents:
diff changeset
1163
anatofuz
parents:
diff changeset
1164 void JSONNodeDumper::VisitBinaryOperator(const BinaryOperator *BO) {
anatofuz
parents:
diff changeset
1165 JOS.attribute("opcode", BinaryOperator::getOpcodeStr(BO->getOpcode()));
anatofuz
parents:
diff changeset
1166 }
anatofuz
parents:
diff changeset
1167
anatofuz
parents:
diff changeset
1168 void JSONNodeDumper::VisitCompoundAssignOperator(
anatofuz
parents:
diff changeset
1169 const CompoundAssignOperator *CAO) {
anatofuz
parents:
diff changeset
1170 VisitBinaryOperator(CAO);
anatofuz
parents:
diff changeset
1171 JOS.attribute("computeLHSType", createQualType(CAO->getComputationLHSType()));
anatofuz
parents:
diff changeset
1172 JOS.attribute("computeResultType",
anatofuz
parents:
diff changeset
1173 createQualType(CAO->getComputationResultType()));
anatofuz
parents:
diff changeset
1174 }
anatofuz
parents:
diff changeset
1175
anatofuz
parents:
diff changeset
1176 void JSONNodeDumper::VisitMemberExpr(const MemberExpr *ME) {
anatofuz
parents:
diff changeset
1177 // Note, we always write this Boolean field because the information it conveys
anatofuz
parents:
diff changeset
1178 // is critical to understanding the AST node.
anatofuz
parents:
diff changeset
1179 ValueDecl *VD = ME->getMemberDecl();
anatofuz
parents:
diff changeset
1180 JOS.attribute("name", VD && VD->getDeclName() ? VD->getNameAsString() : "");
anatofuz
parents:
diff changeset
1181 JOS.attribute("isArrow", ME->isArrow());
anatofuz
parents:
diff changeset
1182 JOS.attribute("referencedMemberDecl", createPointerRepresentation(VD));
anatofuz
parents:
diff changeset
1183 switch (ME->isNonOdrUse()) {
anatofuz
parents:
diff changeset
1184 case NOUR_None: break;
anatofuz
parents:
diff changeset
1185 case NOUR_Unevaluated: JOS.attribute("nonOdrUseReason", "unevaluated"); break;
anatofuz
parents:
diff changeset
1186 case NOUR_Constant: JOS.attribute("nonOdrUseReason", "constant"); break;
anatofuz
parents:
diff changeset
1187 case NOUR_Discarded: JOS.attribute("nonOdrUseReason", "discarded"); break;
anatofuz
parents:
diff changeset
1188 }
anatofuz
parents:
diff changeset
1189 }
anatofuz
parents:
diff changeset
1190
anatofuz
parents:
diff changeset
1191 void JSONNodeDumper::VisitCXXNewExpr(const CXXNewExpr *NE) {
anatofuz
parents:
diff changeset
1192 attributeOnlyIfTrue("isGlobal", NE->isGlobalNew());
anatofuz
parents:
diff changeset
1193 attributeOnlyIfTrue("isArray", NE->isArray());
anatofuz
parents:
diff changeset
1194 attributeOnlyIfTrue("isPlacement", NE->getNumPlacementArgs() != 0);
anatofuz
parents:
diff changeset
1195 switch (NE->getInitializationStyle()) {
anatofuz
parents:
diff changeset
1196 case CXXNewExpr::NoInit: break;
anatofuz
parents:
diff changeset
1197 case CXXNewExpr::CallInit: JOS.attribute("initStyle", "call"); break;
anatofuz
parents:
diff changeset
1198 case CXXNewExpr::ListInit: JOS.attribute("initStyle", "list"); break;
anatofuz
parents:
diff changeset
1199 }
anatofuz
parents:
diff changeset
1200 if (const FunctionDecl *FD = NE->getOperatorNew())
anatofuz
parents:
diff changeset
1201 JOS.attribute("operatorNewDecl", createBareDeclRef(FD));
anatofuz
parents:
diff changeset
1202 if (const FunctionDecl *FD = NE->getOperatorDelete())
anatofuz
parents:
diff changeset
1203 JOS.attribute("operatorDeleteDecl", createBareDeclRef(FD));
anatofuz
parents:
diff changeset
1204 }
anatofuz
parents:
diff changeset
1205 void JSONNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *DE) {
anatofuz
parents:
diff changeset
1206 attributeOnlyIfTrue("isGlobal", DE->isGlobalDelete());
anatofuz
parents:
diff changeset
1207 attributeOnlyIfTrue("isArray", DE->isArrayForm());
anatofuz
parents:
diff changeset
1208 attributeOnlyIfTrue("isArrayAsWritten", DE->isArrayFormAsWritten());
anatofuz
parents:
diff changeset
1209 if (const FunctionDecl *FD = DE->getOperatorDelete())
anatofuz
parents:
diff changeset
1210 JOS.attribute("operatorDeleteDecl", createBareDeclRef(FD));
anatofuz
parents:
diff changeset
1211 }
anatofuz
parents:
diff changeset
1212
anatofuz
parents:
diff changeset
1213 void JSONNodeDumper::VisitCXXThisExpr(const CXXThisExpr *TE) {
anatofuz
parents:
diff changeset
1214 attributeOnlyIfTrue("implicit", TE->isImplicit());
anatofuz
parents:
diff changeset
1215 }
anatofuz
parents:
diff changeset
1216
anatofuz
parents:
diff changeset
1217 void JSONNodeDumper::VisitCastExpr(const CastExpr *CE) {
anatofuz
parents:
diff changeset
1218 JOS.attribute("castKind", CE->getCastKindName());
anatofuz
parents:
diff changeset
1219 llvm::json::Array Path = createCastPath(CE);
anatofuz
parents:
diff changeset
1220 if (!Path.empty())
anatofuz
parents:
diff changeset
1221 JOS.attribute("path", std::move(Path));
anatofuz
parents:
diff changeset
1222 // FIXME: This may not be useful information as it can be obtusely gleaned
anatofuz
parents:
diff changeset
1223 // from the inner[] array.
anatofuz
parents:
diff changeset
1224 if (const NamedDecl *ND = CE->getConversionFunction())
anatofuz
parents:
diff changeset
1225 JOS.attribute("conversionFunc", createBareDeclRef(ND));
anatofuz
parents:
diff changeset
1226 }
anatofuz
parents:
diff changeset
1227
anatofuz
parents:
diff changeset
1228 void JSONNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *ICE) {
anatofuz
parents:
diff changeset
1229 VisitCastExpr(ICE);
anatofuz
parents:
diff changeset
1230 attributeOnlyIfTrue("isPartOfExplicitCast", ICE->isPartOfExplicitCast());
anatofuz
parents:
diff changeset
1231 }
anatofuz
parents:
diff changeset
1232
anatofuz
parents:
diff changeset
1233 void JSONNodeDumper::VisitCallExpr(const CallExpr *CE) {
anatofuz
parents:
diff changeset
1234 attributeOnlyIfTrue("adl", CE->usesADL());
anatofuz
parents:
diff changeset
1235 }
anatofuz
parents:
diff changeset
1236
anatofuz
parents:
diff changeset
1237 void JSONNodeDumper::VisitUnaryExprOrTypeTraitExpr(
anatofuz
parents:
diff changeset
1238 const UnaryExprOrTypeTraitExpr *TTE) {
anatofuz
parents:
diff changeset
1239 switch (TTE->getKind()) {
anatofuz
parents:
diff changeset
1240 case UETT_SizeOf: JOS.attribute("name", "sizeof"); break;
anatofuz
parents:
diff changeset
1241 case UETT_AlignOf: JOS.attribute("name", "alignof"); break;
anatofuz
parents:
diff changeset
1242 case UETT_VecStep: JOS.attribute("name", "vec_step"); break;
anatofuz
parents:
diff changeset
1243 case UETT_PreferredAlignOf: JOS.attribute("name", "__alignof"); break;
anatofuz
parents:
diff changeset
1244 case UETT_OpenMPRequiredSimdAlign:
anatofuz
parents:
diff changeset
1245 JOS.attribute("name", "__builtin_omp_required_simd_align"); break;
anatofuz
parents:
diff changeset
1246 }
anatofuz
parents:
diff changeset
1247 if (TTE->isArgumentType())
anatofuz
parents:
diff changeset
1248 JOS.attribute("argType", createQualType(TTE->getArgumentType()));
anatofuz
parents:
diff changeset
1249 }
anatofuz
parents:
diff changeset
1250
anatofuz
parents:
diff changeset
1251 void JSONNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *SOPE) {
anatofuz
parents:
diff changeset
1252 VisitNamedDecl(SOPE->getPack());
anatofuz
parents:
diff changeset
1253 }
anatofuz
parents:
diff changeset
1254
anatofuz
parents:
diff changeset
1255 void JSONNodeDumper::VisitUnresolvedLookupExpr(
anatofuz
parents:
diff changeset
1256 const UnresolvedLookupExpr *ULE) {
anatofuz
parents:
diff changeset
1257 JOS.attribute("usesADL", ULE->requiresADL());
anatofuz
parents:
diff changeset
1258 JOS.attribute("name", ULE->getName().getAsString());
anatofuz
parents:
diff changeset
1259
anatofuz
parents:
diff changeset
1260 JOS.attributeArray("lookups", [this, ULE] {
anatofuz
parents:
diff changeset
1261 for (const NamedDecl *D : ULE->decls())
anatofuz
parents:
diff changeset
1262 JOS.value(createBareDeclRef(D));
anatofuz
parents:
diff changeset
1263 });
anatofuz
parents:
diff changeset
1264 }
anatofuz
parents:
diff changeset
1265
anatofuz
parents:
diff changeset
1266 void JSONNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *ALE) {
anatofuz
parents:
diff changeset
1267 JOS.attribute("name", ALE->getLabel()->getName());
anatofuz
parents:
diff changeset
1268 JOS.attribute("labelDeclId", createPointerRepresentation(ALE->getLabel()));
anatofuz
parents:
diff changeset
1269 }
anatofuz
parents:
diff changeset
1270
anatofuz
parents:
diff changeset
1271 void JSONNodeDumper::VisitCXXTypeidExpr(const CXXTypeidExpr *CTE) {
anatofuz
parents:
diff changeset
1272 if (CTE->isTypeOperand()) {
anatofuz
parents:
diff changeset
1273 QualType Adjusted = CTE->getTypeOperand(Ctx);
anatofuz
parents:
diff changeset
1274 QualType Unadjusted = CTE->getTypeOperandSourceInfo()->getType();
anatofuz
parents:
diff changeset
1275 JOS.attribute("typeArg", createQualType(Unadjusted));
anatofuz
parents:
diff changeset
1276 if (Adjusted != Unadjusted)
anatofuz
parents:
diff changeset
1277 JOS.attribute("adjustedTypeArg", createQualType(Adjusted));
anatofuz
parents:
diff changeset
1278 }
anatofuz
parents:
diff changeset
1279 }
anatofuz
parents:
diff changeset
1280
anatofuz
parents:
diff changeset
1281 void JSONNodeDumper::VisitConstantExpr(const ConstantExpr *CE) {
anatofuz
parents:
diff changeset
1282 if (CE->getResultAPValueKind() != APValue::None) {
anatofuz
parents:
diff changeset
1283 std::string Str;
anatofuz
parents:
diff changeset
1284 llvm::raw_string_ostream OS(Str);
anatofuz
parents:
diff changeset
1285 CE->getAPValueResult().printPretty(OS, Ctx, CE->getType());
anatofuz
parents:
diff changeset
1286 JOS.attribute("value", OS.str());
anatofuz
parents:
diff changeset
1287 }
anatofuz
parents:
diff changeset
1288 }
anatofuz
parents:
diff changeset
1289
anatofuz
parents:
diff changeset
1290 void JSONNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
anatofuz
parents:
diff changeset
1291 if (const FieldDecl *FD = ILE->getInitializedFieldInUnion())
anatofuz
parents:
diff changeset
1292 JOS.attribute("field", createBareDeclRef(FD));
anatofuz
parents:
diff changeset
1293 }
anatofuz
parents:
diff changeset
1294
anatofuz
parents:
diff changeset
1295 void JSONNodeDumper::VisitGenericSelectionExpr(
anatofuz
parents:
diff changeset
1296 const GenericSelectionExpr *GSE) {
anatofuz
parents:
diff changeset
1297 attributeOnlyIfTrue("resultDependent", GSE->isResultDependent());
anatofuz
parents:
diff changeset
1298 }
anatofuz
parents:
diff changeset
1299
anatofuz
parents:
diff changeset
1300 void JSONNodeDumper::VisitCXXUnresolvedConstructExpr(
anatofuz
parents:
diff changeset
1301 const CXXUnresolvedConstructExpr *UCE) {
anatofuz
parents:
diff changeset
1302 if (UCE->getType() != UCE->getTypeAsWritten())
anatofuz
parents:
diff changeset
1303 JOS.attribute("typeAsWritten", createQualType(UCE->getTypeAsWritten()));
anatofuz
parents:
diff changeset
1304 attributeOnlyIfTrue("list", UCE->isListInitialization());
anatofuz
parents:
diff changeset
1305 }
anatofuz
parents:
diff changeset
1306
anatofuz
parents:
diff changeset
1307 void JSONNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *CE) {
anatofuz
parents:
diff changeset
1308 CXXConstructorDecl *Ctor = CE->getConstructor();
anatofuz
parents:
diff changeset
1309 JOS.attribute("ctorType", createQualType(Ctor->getType()));
anatofuz
parents:
diff changeset
1310 attributeOnlyIfTrue("elidable", CE->isElidable());
anatofuz
parents:
diff changeset
1311 attributeOnlyIfTrue("list", CE->isListInitialization());
anatofuz
parents:
diff changeset
1312 attributeOnlyIfTrue("initializer_list", CE->isStdInitListInitialization());
anatofuz
parents:
diff changeset
1313 attributeOnlyIfTrue("zeroing", CE->requiresZeroInitialization());
anatofuz
parents:
diff changeset
1314 attributeOnlyIfTrue("hadMultipleCandidates", CE->hadMultipleCandidates());
anatofuz
parents:
diff changeset
1315
anatofuz
parents:
diff changeset
1316 switch (CE->getConstructionKind()) {
anatofuz
parents:
diff changeset
1317 case CXXConstructExpr::CK_Complete:
anatofuz
parents:
diff changeset
1318 JOS.attribute("constructionKind", "complete");
anatofuz
parents:
diff changeset
1319 break;
anatofuz
parents:
diff changeset
1320 case CXXConstructExpr::CK_Delegating:
anatofuz
parents:
diff changeset
1321 JOS.attribute("constructionKind", "delegating");
anatofuz
parents:
diff changeset
1322 break;
anatofuz
parents:
diff changeset
1323 case CXXConstructExpr::CK_NonVirtualBase:
anatofuz
parents:
diff changeset
1324 JOS.attribute("constructionKind", "non-virtual base");
anatofuz
parents:
diff changeset
1325 break;
anatofuz
parents:
diff changeset
1326 case CXXConstructExpr::CK_VirtualBase:
anatofuz
parents:
diff changeset
1327 JOS.attribute("constructionKind", "virtual base");
anatofuz
parents:
diff changeset
1328 break;
anatofuz
parents:
diff changeset
1329 }
anatofuz
parents:
diff changeset
1330 }
anatofuz
parents:
diff changeset
1331
anatofuz
parents:
diff changeset
1332 void JSONNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *EWC) {
anatofuz
parents:
diff changeset
1333 attributeOnlyIfTrue("cleanupsHaveSideEffects",
anatofuz
parents:
diff changeset
1334 EWC->cleanupsHaveSideEffects());
anatofuz
parents:
diff changeset
1335 if (EWC->getNumObjects()) {
anatofuz
parents:
diff changeset
1336 JOS.attributeArray("cleanups", [this, EWC] {
anatofuz
parents:
diff changeset
1337 for (const ExprWithCleanups::CleanupObject &CO : EWC->getObjects())
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1338 if (auto *BD = CO.dyn_cast<BlockDecl *>()) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1339 JOS.value(createBareDeclRef(BD));
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1340 } else if (auto *CLE = CO.dyn_cast<CompoundLiteralExpr *>()) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1341 llvm::json::Object Obj;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1342 Obj["id"] = createPointerRepresentation(CLE);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1343 Obj["kind"] = CLE->getStmtClassName();
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1344 JOS.value(std::move(Obj));
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1345 } else {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1346 llvm_unreachable("unexpected cleanup object type");
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1347 }
150
anatofuz
parents:
diff changeset
1348 });
anatofuz
parents:
diff changeset
1349 }
anatofuz
parents:
diff changeset
1350 }
anatofuz
parents:
diff changeset
1351
anatofuz
parents:
diff changeset
1352 void JSONNodeDumper::VisitCXXBindTemporaryExpr(
anatofuz
parents:
diff changeset
1353 const CXXBindTemporaryExpr *BTE) {
anatofuz
parents:
diff changeset
1354 const CXXTemporary *Temp = BTE->getTemporary();
anatofuz
parents:
diff changeset
1355 JOS.attribute("temp", createPointerRepresentation(Temp));
anatofuz
parents:
diff changeset
1356 if (const CXXDestructorDecl *Dtor = Temp->getDestructor())
anatofuz
parents:
diff changeset
1357 JOS.attribute("dtor", createBareDeclRef(Dtor));
anatofuz
parents:
diff changeset
1358 }
anatofuz
parents:
diff changeset
1359
anatofuz
parents:
diff changeset
1360 void JSONNodeDumper::VisitMaterializeTemporaryExpr(
anatofuz
parents:
diff changeset
1361 const MaterializeTemporaryExpr *MTE) {
anatofuz
parents:
diff changeset
1362 if (const ValueDecl *VD = MTE->getExtendingDecl())
anatofuz
parents:
diff changeset
1363 JOS.attribute("extendingDecl", createBareDeclRef(VD));
anatofuz
parents:
diff changeset
1364
anatofuz
parents:
diff changeset
1365 switch (MTE->getStorageDuration()) {
anatofuz
parents:
diff changeset
1366 case SD_Automatic:
anatofuz
parents:
diff changeset
1367 JOS.attribute("storageDuration", "automatic");
anatofuz
parents:
diff changeset
1368 break;
anatofuz
parents:
diff changeset
1369 case SD_Dynamic:
anatofuz
parents:
diff changeset
1370 JOS.attribute("storageDuration", "dynamic");
anatofuz
parents:
diff changeset
1371 break;
anatofuz
parents:
diff changeset
1372 case SD_FullExpression:
anatofuz
parents:
diff changeset
1373 JOS.attribute("storageDuration", "full expression");
anatofuz
parents:
diff changeset
1374 break;
anatofuz
parents:
diff changeset
1375 case SD_Static:
anatofuz
parents:
diff changeset
1376 JOS.attribute("storageDuration", "static");
anatofuz
parents:
diff changeset
1377 break;
anatofuz
parents:
diff changeset
1378 case SD_Thread:
anatofuz
parents:
diff changeset
1379 JOS.attribute("storageDuration", "thread");
anatofuz
parents:
diff changeset
1380 break;
anatofuz
parents:
diff changeset
1381 }
anatofuz
parents:
diff changeset
1382
anatofuz
parents:
diff changeset
1383 attributeOnlyIfTrue("boundToLValueRef", MTE->isBoundToLvalueReference());
anatofuz
parents:
diff changeset
1384 }
anatofuz
parents:
diff changeset
1385
anatofuz
parents:
diff changeset
1386 void JSONNodeDumper::VisitCXXDependentScopeMemberExpr(
anatofuz
parents:
diff changeset
1387 const CXXDependentScopeMemberExpr *DSME) {
anatofuz
parents:
diff changeset
1388 JOS.attribute("isArrow", DSME->isArrow());
anatofuz
parents:
diff changeset
1389 JOS.attribute("member", DSME->getMember().getAsString());
anatofuz
parents:
diff changeset
1390 attributeOnlyIfTrue("hasTemplateKeyword", DSME->hasTemplateKeyword());
anatofuz
parents:
diff changeset
1391 attributeOnlyIfTrue("hasExplicitTemplateArgs",
anatofuz
parents:
diff changeset
1392 DSME->hasExplicitTemplateArgs());
anatofuz
parents:
diff changeset
1393
anatofuz
parents:
diff changeset
1394 if (DSME->getNumTemplateArgs()) {
anatofuz
parents:
diff changeset
1395 JOS.attributeArray("explicitTemplateArgs", [DSME, this] {
anatofuz
parents:
diff changeset
1396 for (const TemplateArgumentLoc &TAL : DSME->template_arguments())
anatofuz
parents:
diff changeset
1397 JOS.object(
anatofuz
parents:
diff changeset
1398 [&TAL, this] { Visit(TAL.getArgument(), TAL.getSourceRange()); });
anatofuz
parents:
diff changeset
1399 });
anatofuz
parents:
diff changeset
1400 }
anatofuz
parents:
diff changeset
1401 }
anatofuz
parents:
diff changeset
1402
anatofuz
parents:
diff changeset
1403 void JSONNodeDumper::VisitIntegerLiteral(const IntegerLiteral *IL) {
anatofuz
parents:
diff changeset
1404 JOS.attribute("value",
anatofuz
parents:
diff changeset
1405 IL->getValue().toString(
anatofuz
parents:
diff changeset
1406 /*Radix=*/10, IL->getType()->isSignedIntegerType()));
anatofuz
parents:
diff changeset
1407 }
anatofuz
parents:
diff changeset
1408 void JSONNodeDumper::VisitCharacterLiteral(const CharacterLiteral *CL) {
anatofuz
parents:
diff changeset
1409 // FIXME: This should probably print the character literal as a string,
anatofuz
parents:
diff changeset
1410 // rather than as a numerical value. It would be nice if the behavior matched
anatofuz
parents:
diff changeset
1411 // what we do to print a string literal; right now, it is impossible to tell
anatofuz
parents:
diff changeset
1412 // the difference between 'a' and L'a' in C from the JSON output.
anatofuz
parents:
diff changeset
1413 JOS.attribute("value", CL->getValue());
anatofuz
parents:
diff changeset
1414 }
anatofuz
parents:
diff changeset
1415 void JSONNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *FPL) {
anatofuz
parents:
diff changeset
1416 JOS.attribute("value", FPL->getValueAsString(/*Radix=*/10));
anatofuz
parents:
diff changeset
1417 }
anatofuz
parents:
diff changeset
1418 void JSONNodeDumper::VisitFloatingLiteral(const FloatingLiteral *FL) {
anatofuz
parents:
diff changeset
1419 llvm::SmallVector<char, 16> Buffer;
anatofuz
parents:
diff changeset
1420 FL->getValue().toString(Buffer);
anatofuz
parents:
diff changeset
1421 JOS.attribute("value", Buffer);
anatofuz
parents:
diff changeset
1422 }
anatofuz
parents:
diff changeset
1423 void JSONNodeDumper::VisitStringLiteral(const StringLiteral *SL) {
anatofuz
parents:
diff changeset
1424 std::string Buffer;
anatofuz
parents:
diff changeset
1425 llvm::raw_string_ostream SS(Buffer);
anatofuz
parents:
diff changeset
1426 SL->outputString(SS);
anatofuz
parents:
diff changeset
1427 JOS.attribute("value", SS.str());
anatofuz
parents:
diff changeset
1428 }
anatofuz
parents:
diff changeset
1429 void JSONNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *BLE) {
anatofuz
parents:
diff changeset
1430 JOS.attribute("value", BLE->getValue());
anatofuz
parents:
diff changeset
1431 }
anatofuz
parents:
diff changeset
1432
anatofuz
parents:
diff changeset
1433 void JSONNodeDumper::VisitIfStmt(const IfStmt *IS) {
anatofuz
parents:
diff changeset
1434 attributeOnlyIfTrue("hasInit", IS->hasInitStorage());
anatofuz
parents:
diff changeset
1435 attributeOnlyIfTrue("hasVar", IS->hasVarStorage());
anatofuz
parents:
diff changeset
1436 attributeOnlyIfTrue("hasElse", IS->hasElseStorage());
anatofuz
parents:
diff changeset
1437 attributeOnlyIfTrue("isConstexpr", IS->isConstexpr());
anatofuz
parents:
diff changeset
1438 }
anatofuz
parents:
diff changeset
1439
anatofuz
parents:
diff changeset
1440 void JSONNodeDumper::VisitSwitchStmt(const SwitchStmt *SS) {
anatofuz
parents:
diff changeset
1441 attributeOnlyIfTrue("hasInit", SS->hasInitStorage());
anatofuz
parents:
diff changeset
1442 attributeOnlyIfTrue("hasVar", SS->hasVarStorage());
anatofuz
parents:
diff changeset
1443 }
anatofuz
parents:
diff changeset
1444 void JSONNodeDumper::VisitCaseStmt(const CaseStmt *CS) {
anatofuz
parents:
diff changeset
1445 attributeOnlyIfTrue("isGNURange", CS->caseStmtIsGNURange());
anatofuz
parents:
diff changeset
1446 }
anatofuz
parents:
diff changeset
1447
anatofuz
parents:
diff changeset
1448 void JSONNodeDumper::VisitLabelStmt(const LabelStmt *LS) {
anatofuz
parents:
diff changeset
1449 JOS.attribute("name", LS->getName());
anatofuz
parents:
diff changeset
1450 JOS.attribute("declId", createPointerRepresentation(LS->getDecl()));
anatofuz
parents:
diff changeset
1451 }
anatofuz
parents:
diff changeset
1452 void JSONNodeDumper::VisitGotoStmt(const GotoStmt *GS) {
anatofuz
parents:
diff changeset
1453 JOS.attribute("targetLabelDeclId",
anatofuz
parents:
diff changeset
1454 createPointerRepresentation(GS->getLabel()));
anatofuz
parents:
diff changeset
1455 }
anatofuz
parents:
diff changeset
1456
anatofuz
parents:
diff changeset
1457 void JSONNodeDumper::VisitWhileStmt(const WhileStmt *WS) {
anatofuz
parents:
diff changeset
1458 attributeOnlyIfTrue("hasVar", WS->hasVarStorage());
anatofuz
parents:
diff changeset
1459 }
anatofuz
parents:
diff changeset
1460
anatofuz
parents:
diff changeset
1461 void JSONNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt* OACS) {
anatofuz
parents:
diff changeset
1462 // FIXME: it would be nice for the ASTNodeTraverser would handle the catch
anatofuz
parents:
diff changeset
1463 // parameter the same way for C++ and ObjC rather. In this case, C++ gets a
anatofuz
parents:
diff changeset
1464 // null child node and ObjC gets no child node.
anatofuz
parents:
diff changeset
1465 attributeOnlyIfTrue("isCatchAll", OACS->getCatchParamDecl() == nullptr);
anatofuz
parents:
diff changeset
1466 }
anatofuz
parents:
diff changeset
1467
anatofuz
parents:
diff changeset
1468 void JSONNodeDumper::VisitNullTemplateArgument(const TemplateArgument &TA) {
anatofuz
parents:
diff changeset
1469 JOS.attribute("isNull", true);
anatofuz
parents:
diff changeset
1470 }
anatofuz
parents:
diff changeset
1471 void JSONNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
anatofuz
parents:
diff changeset
1472 JOS.attribute("type", createQualType(TA.getAsType()));
anatofuz
parents:
diff changeset
1473 }
anatofuz
parents:
diff changeset
1474 void JSONNodeDumper::VisitDeclarationTemplateArgument(
anatofuz
parents:
diff changeset
1475 const TemplateArgument &TA) {
anatofuz
parents:
diff changeset
1476 JOS.attribute("decl", createBareDeclRef(TA.getAsDecl()));
anatofuz
parents:
diff changeset
1477 }
anatofuz
parents:
diff changeset
1478 void JSONNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA) {
anatofuz
parents:
diff changeset
1479 JOS.attribute("isNullptr", true);
anatofuz
parents:
diff changeset
1480 }
anatofuz
parents:
diff changeset
1481 void JSONNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
anatofuz
parents:
diff changeset
1482 JOS.attribute("value", TA.getAsIntegral().getSExtValue());
anatofuz
parents:
diff changeset
1483 }
anatofuz
parents:
diff changeset
1484 void JSONNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
anatofuz
parents:
diff changeset
1485 // FIXME: cannot just call dump() on the argument, as that doesn't specify
anatofuz
parents:
diff changeset
1486 // the output format.
anatofuz
parents:
diff changeset
1487 }
anatofuz
parents:
diff changeset
1488 void JSONNodeDumper::VisitTemplateExpansionTemplateArgument(
anatofuz
parents:
diff changeset
1489 const TemplateArgument &TA) {
anatofuz
parents:
diff changeset
1490 // FIXME: cannot just call dump() on the argument, as that doesn't specify
anatofuz
parents:
diff changeset
1491 // the output format.
anatofuz
parents:
diff changeset
1492 }
anatofuz
parents:
diff changeset
1493 void JSONNodeDumper::VisitExpressionTemplateArgument(
anatofuz
parents:
diff changeset
1494 const TemplateArgument &TA) {
anatofuz
parents:
diff changeset
1495 JOS.attribute("isExpr", true);
anatofuz
parents:
diff changeset
1496 }
anatofuz
parents:
diff changeset
1497 void JSONNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) {
anatofuz
parents:
diff changeset
1498 JOS.attribute("isPack", true);
anatofuz
parents:
diff changeset
1499 }
anatofuz
parents:
diff changeset
1500
anatofuz
parents:
diff changeset
1501 StringRef JSONNodeDumper::getCommentCommandName(unsigned CommandID) const {
anatofuz
parents:
diff changeset
1502 if (Traits)
anatofuz
parents:
diff changeset
1503 return Traits->getCommandInfo(CommandID)->Name;
anatofuz
parents:
diff changeset
1504 if (const comments::CommandInfo *Info =
anatofuz
parents:
diff changeset
1505 comments::CommandTraits::getBuiltinCommandInfo(CommandID))
anatofuz
parents:
diff changeset
1506 return Info->Name;
anatofuz
parents:
diff changeset
1507 return "<invalid>";
anatofuz
parents:
diff changeset
1508 }
anatofuz
parents:
diff changeset
1509
anatofuz
parents:
diff changeset
1510 void JSONNodeDumper::visitTextComment(const comments::TextComment *C,
anatofuz
parents:
diff changeset
1511 const comments::FullComment *) {
anatofuz
parents:
diff changeset
1512 JOS.attribute("text", C->getText());
anatofuz
parents:
diff changeset
1513 }
anatofuz
parents:
diff changeset
1514
anatofuz
parents:
diff changeset
1515 void JSONNodeDumper::visitInlineCommandComment(
anatofuz
parents:
diff changeset
1516 const comments::InlineCommandComment *C, const comments::FullComment *) {
anatofuz
parents:
diff changeset
1517 JOS.attribute("name", getCommentCommandName(C->getCommandID()));
anatofuz
parents:
diff changeset
1518
anatofuz
parents:
diff changeset
1519 switch (C->getRenderKind()) {
anatofuz
parents:
diff changeset
1520 case comments::InlineCommandComment::RenderNormal:
anatofuz
parents:
diff changeset
1521 JOS.attribute("renderKind", "normal");
anatofuz
parents:
diff changeset
1522 break;
anatofuz
parents:
diff changeset
1523 case comments::InlineCommandComment::RenderBold:
anatofuz
parents:
diff changeset
1524 JOS.attribute("renderKind", "bold");
anatofuz
parents:
diff changeset
1525 break;
anatofuz
parents:
diff changeset
1526 case comments::InlineCommandComment::RenderEmphasized:
anatofuz
parents:
diff changeset
1527 JOS.attribute("renderKind", "emphasized");
anatofuz
parents:
diff changeset
1528 break;
anatofuz
parents:
diff changeset
1529 case comments::InlineCommandComment::RenderMonospaced:
anatofuz
parents:
diff changeset
1530 JOS.attribute("renderKind", "monospaced");
anatofuz
parents:
diff changeset
1531 break;
anatofuz
parents:
diff changeset
1532 case comments::InlineCommandComment::RenderAnchor:
anatofuz
parents:
diff changeset
1533 JOS.attribute("renderKind", "anchor");
anatofuz
parents:
diff changeset
1534 break;
anatofuz
parents:
diff changeset
1535 }
anatofuz
parents:
diff changeset
1536
anatofuz
parents:
diff changeset
1537 llvm::json::Array Args;
anatofuz
parents:
diff changeset
1538 for (unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
anatofuz
parents:
diff changeset
1539 Args.push_back(C->getArgText(I));
anatofuz
parents:
diff changeset
1540
anatofuz
parents:
diff changeset
1541 if (!Args.empty())
anatofuz
parents:
diff changeset
1542 JOS.attribute("args", std::move(Args));
anatofuz
parents:
diff changeset
1543 }
anatofuz
parents:
diff changeset
1544
anatofuz
parents:
diff changeset
1545 void JSONNodeDumper::visitHTMLStartTagComment(
anatofuz
parents:
diff changeset
1546 const comments::HTMLStartTagComment *C, const comments::FullComment *) {
anatofuz
parents:
diff changeset
1547 JOS.attribute("name", C->getTagName());
anatofuz
parents:
diff changeset
1548 attributeOnlyIfTrue("selfClosing", C->isSelfClosing());
anatofuz
parents:
diff changeset
1549 attributeOnlyIfTrue("malformed", C->isMalformed());
anatofuz
parents:
diff changeset
1550
anatofuz
parents:
diff changeset
1551 llvm::json::Array Attrs;
anatofuz
parents:
diff changeset
1552 for (unsigned I = 0, E = C->getNumAttrs(); I < E; ++I)
anatofuz
parents:
diff changeset
1553 Attrs.push_back(
anatofuz
parents:
diff changeset
1554 {{"name", C->getAttr(I).Name}, {"value", C->getAttr(I).Value}});
anatofuz
parents:
diff changeset
1555
anatofuz
parents:
diff changeset
1556 if (!Attrs.empty())
anatofuz
parents:
diff changeset
1557 JOS.attribute("attrs", std::move(Attrs));
anatofuz
parents:
diff changeset
1558 }
anatofuz
parents:
diff changeset
1559
anatofuz
parents:
diff changeset
1560 void JSONNodeDumper::visitHTMLEndTagComment(
anatofuz
parents:
diff changeset
1561 const comments::HTMLEndTagComment *C, const comments::FullComment *) {
anatofuz
parents:
diff changeset
1562 JOS.attribute("name", C->getTagName());
anatofuz
parents:
diff changeset
1563 }
anatofuz
parents:
diff changeset
1564
anatofuz
parents:
diff changeset
1565 void JSONNodeDumper::visitBlockCommandComment(
anatofuz
parents:
diff changeset
1566 const comments::BlockCommandComment *C, const comments::FullComment *) {
anatofuz
parents:
diff changeset
1567 JOS.attribute("name", getCommentCommandName(C->getCommandID()));
anatofuz
parents:
diff changeset
1568
anatofuz
parents:
diff changeset
1569 llvm::json::Array Args;
anatofuz
parents:
diff changeset
1570 for (unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
anatofuz
parents:
diff changeset
1571 Args.push_back(C->getArgText(I));
anatofuz
parents:
diff changeset
1572
anatofuz
parents:
diff changeset
1573 if (!Args.empty())
anatofuz
parents:
diff changeset
1574 JOS.attribute("args", std::move(Args));
anatofuz
parents:
diff changeset
1575 }
anatofuz
parents:
diff changeset
1576
anatofuz
parents:
diff changeset
1577 void JSONNodeDumper::visitParamCommandComment(
anatofuz
parents:
diff changeset
1578 const comments::ParamCommandComment *C, const comments::FullComment *FC) {
anatofuz
parents:
diff changeset
1579 switch (C->getDirection()) {
anatofuz
parents:
diff changeset
1580 case comments::ParamCommandComment::In:
anatofuz
parents:
diff changeset
1581 JOS.attribute("direction", "in");
anatofuz
parents:
diff changeset
1582 break;
anatofuz
parents:
diff changeset
1583 case comments::ParamCommandComment::Out:
anatofuz
parents:
diff changeset
1584 JOS.attribute("direction", "out");
anatofuz
parents:
diff changeset
1585 break;
anatofuz
parents:
diff changeset
1586 case comments::ParamCommandComment::InOut:
anatofuz
parents:
diff changeset
1587 JOS.attribute("direction", "in,out");
anatofuz
parents:
diff changeset
1588 break;
anatofuz
parents:
diff changeset
1589 }
anatofuz
parents:
diff changeset
1590 attributeOnlyIfTrue("explicit", C->isDirectionExplicit());
anatofuz
parents:
diff changeset
1591
anatofuz
parents:
diff changeset
1592 if (C->hasParamName())
anatofuz
parents:
diff changeset
1593 JOS.attribute("param", C->isParamIndexValid() ? C->getParamName(FC)
anatofuz
parents:
diff changeset
1594 : C->getParamNameAsWritten());
anatofuz
parents:
diff changeset
1595
anatofuz
parents:
diff changeset
1596 if (C->isParamIndexValid() && !C->isVarArgParam())
anatofuz
parents:
diff changeset
1597 JOS.attribute("paramIdx", C->getParamIndex());
anatofuz
parents:
diff changeset
1598 }
anatofuz
parents:
diff changeset
1599
anatofuz
parents:
diff changeset
1600 void JSONNodeDumper::visitTParamCommandComment(
anatofuz
parents:
diff changeset
1601 const comments::TParamCommandComment *C, const comments::FullComment *FC) {
anatofuz
parents:
diff changeset
1602 if (C->hasParamName())
anatofuz
parents:
diff changeset
1603 JOS.attribute("param", C->isPositionValid() ? C->getParamName(FC)
anatofuz
parents:
diff changeset
1604 : C->getParamNameAsWritten());
anatofuz
parents:
diff changeset
1605 if (C->isPositionValid()) {
anatofuz
parents:
diff changeset
1606 llvm::json::Array Positions;
anatofuz
parents:
diff changeset
1607 for (unsigned I = 0, E = C->getDepth(); I < E; ++I)
anatofuz
parents:
diff changeset
1608 Positions.push_back(C->getIndex(I));
anatofuz
parents:
diff changeset
1609
anatofuz
parents:
diff changeset
1610 if (!Positions.empty())
anatofuz
parents:
diff changeset
1611 JOS.attribute("positions", std::move(Positions));
anatofuz
parents:
diff changeset
1612 }
anatofuz
parents:
diff changeset
1613 }
anatofuz
parents:
diff changeset
1614
anatofuz
parents:
diff changeset
1615 void JSONNodeDumper::visitVerbatimBlockComment(
anatofuz
parents:
diff changeset
1616 const comments::VerbatimBlockComment *C, const comments::FullComment *) {
anatofuz
parents:
diff changeset
1617 JOS.attribute("name", getCommentCommandName(C->getCommandID()));
anatofuz
parents:
diff changeset
1618 JOS.attribute("closeName", C->getCloseName());
anatofuz
parents:
diff changeset
1619 }
anatofuz
parents:
diff changeset
1620
anatofuz
parents:
diff changeset
1621 void JSONNodeDumper::visitVerbatimBlockLineComment(
anatofuz
parents:
diff changeset
1622 const comments::VerbatimBlockLineComment *C,
anatofuz
parents:
diff changeset
1623 const comments::FullComment *) {
anatofuz
parents:
diff changeset
1624 JOS.attribute("text", C->getText());
anatofuz
parents:
diff changeset
1625 }
anatofuz
parents:
diff changeset
1626
anatofuz
parents:
diff changeset
1627 void JSONNodeDumper::visitVerbatimLineComment(
anatofuz
parents:
diff changeset
1628 const comments::VerbatimLineComment *C, const comments::FullComment *) {
anatofuz
parents:
diff changeset
1629 JOS.attribute("text", C->getText());
anatofuz
parents:
diff changeset
1630 }