1 #include "clang/AST/JSONNodeDumper.h"
2 #include "llvm/ADT/StringSwitch.h"
3 
4 using namespace clang;
5 
6 void JSONNodeDumper::addPreviousDeclaration(const Decl *D) {
7   switch (D->getKind()) {
8 #define DECL(DERIVED, BASE)                                                    \
9   case Decl::DERIVED:                                                          \
10     return writePreviousDeclImpl(cast<DERIVED##Decl>(D));
11 #define ABSTRACT_DECL(DECL)
12 #include "clang/AST/DeclNodes.inc"
13 #undef ABSTRACT_DECL
14 #undef DECL
15   }
16   llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
17 }
18 
19 void JSONNodeDumper::Visit(const Attr *A) {
20   const char *AttrName = nullptr;
21   switch (A->getKind()) {
22 #define ATTR(X)                                                                \
23   case attr::X:                                                                \
24     AttrName = #X"Attr";                                                       \
25     break;
26 #include "clang/Basic/AttrList.inc"
27 #undef ATTR
28   }
29   JOS.attribute("id", createPointerRepresentation(A));
30   JOS.attribute("kind", AttrName);
31   JOS.attribute("range", createSourceRange(A->getRange()));
32   attributeOnlyIfTrue("inherited", A->isInherited());
33   attributeOnlyIfTrue("implicit", A->isImplicit());
34 
35   // FIXME: it would be useful for us to output the spelling kind as well as
36   // the actual spelling. This would allow us to distinguish between the
37   // various attribute syntaxes, but we don't currently track that information
38   // within the AST.
39   //JOS.attribute("spelling", A->getSpelling());
40 
41   InnerAttrVisitor::Visit(A);
42 }
43 
44 void JSONNodeDumper::Visit(const Stmt *S) {
45   if (!S)
46     return;
47 
48   JOS.attribute("id", createPointerRepresentation(S));
49   JOS.attribute("kind", S->getStmtClassName());
50   JOS.attribute("range", createSourceRange(S->getSourceRange()));
51 
52   if (const auto *E = dyn_cast<Expr>(S)) {
53     JOS.attribute("type", createQualType(E->getType()));
54     const char *Category = nullptr;
55     switch (E->getValueKind()) {
56     case VK_LValue: Category = "lvalue"; break;
57     case VK_XValue: Category = "xvalue"; break;
58     case VK_RValue: Category = "rvalue"; break;
59     }
60     JOS.attribute("valueCategory", Category);
61   }
62   InnerStmtVisitor::Visit(S);
63 }
64 
65 void JSONNodeDumper::Visit(const Type *T) {
66   JOS.attribute("id", createPointerRepresentation(T));
67   JOS.attribute("kind", (llvm::Twine(T->getTypeClassName()) + "Type").str());
68   JOS.attribute("type", createQualType(QualType(T, 0), /*Desugar*/ false));
69   attributeOnlyIfTrue("isDependent", T->isDependentType());
70   attributeOnlyIfTrue("isInstantiationDependent",
71                       T->isInstantiationDependentType());
72   attributeOnlyIfTrue("isVariablyModified", T->isVariablyModifiedType());
73   attributeOnlyIfTrue("containsUnexpandedPack",
74                       T->containsUnexpandedParameterPack());
75   attributeOnlyIfTrue("isImported", T->isFromAST());
76   InnerTypeVisitor::Visit(T);
77 }
78 
79 void JSONNodeDumper::Visit(QualType T) {
80   JOS.attribute("id", createPointerRepresentation(T.getAsOpaquePtr()));
81   JOS.attribute("type", createQualType(T));
82   JOS.attribute("qualifiers", T.split().Quals.getAsString());
83 }
84 
85 void JSONNodeDumper::Visit(const Decl *D) {
86   JOS.attribute("id", createPointerRepresentation(D));
87 
88   if (!D)
89     return;
90 
91   JOS.attribute("kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str());
92   JOS.attribute("loc", createSourceLocation(D->getLocation()));
93   JOS.attribute("range", createSourceRange(D->getSourceRange()));
94   attributeOnlyIfTrue("isImplicit", D->isImplicit());
95   attributeOnlyIfTrue("isInvalid", D->isInvalidDecl());
96 
97   if (D->isUsed())
98     JOS.attribute("isUsed", true);
99   else if (D->isThisDeclarationReferenced())
100     JOS.attribute("isReferenced", true);
101 
102   if (const auto *ND = dyn_cast<NamedDecl>(D))
103     attributeOnlyIfTrue("isHidden", ND->isHidden());
104 
105   if (D->getLexicalDeclContext() != D->getDeclContext())
106     JOS.attribute("parentDeclContext",
107                   createPointerRepresentation(D->getDeclContext()));
108 
109   addPreviousDeclaration(D);
110   InnerDeclVisitor::Visit(D);
111 }
112 
113 void JSONNodeDumper::Visit(const comments::Comment *C,
114                            const comments::FullComment *FC) {}
115 
116 void JSONNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
117                            const Decl *From, StringRef Label) {
118   JOS.attribute("kind", "TemplateArgument");
119   if (R.isValid())
120     JOS.attribute("range", createSourceRange(R));
121 
122   if (From)
123     JOS.attribute(Label.empty() ? "fromDecl" : Label, createBareDeclRef(From));
124 
125   InnerTemplateArgVisitor::Visit(TA);
126 }
127 
128 void JSONNodeDumper::Visit(const CXXCtorInitializer *Init) {
129   JOS.attribute("kind", "CXXCtorInitializer");
130   if (Init->isAnyMemberInitializer())
131     JOS.attribute("anyInit", createBareDeclRef(Init->getAnyMember()));
132   else if (Init->isBaseInitializer())
133     JOS.attribute("baseInit",
134                   createQualType(QualType(Init->getBaseClass(), 0)));
135   else if (Init->isDelegatingInitializer())
136     JOS.attribute("delegatingInit",
137                   createQualType(Init->getTypeSourceInfo()->getType()));
138   else
139     llvm_unreachable("Unknown initializer type");
140 }
141 
142 void JSONNodeDumper::Visit(const OMPClause *C) {}
143 void JSONNodeDumper::Visit(const BlockDecl::Capture &C) {}
144 void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
145   JOS.attribute("associationKind", A.getTypeSourceInfo() ? "case" : "default");
146   attributeOnlyIfTrue("selected", A.isSelected());
147 }
148 
149 llvm::json::Object JSONNodeDumper::createSourceLocation(SourceLocation Loc) {
150   SourceLocation Spelling = SM.getSpellingLoc(Loc);
151   PresumedLoc Presumed = SM.getPresumedLoc(Spelling);
152 
153   if (Presumed.isInvalid())
154     return llvm::json::Object{};
155 
156   return llvm::json::Object{{"file", Presumed.getFilename()},
157                             {"line", Presumed.getLine()},
158                             {"col", Presumed.getColumn()}};
159 }
160 
161 llvm::json::Object JSONNodeDumper::createSourceRange(SourceRange R) {
162   return llvm::json::Object{{"begin", createSourceLocation(R.getBegin())},
163                             {"end", createSourceLocation(R.getEnd())}};
164 }
165 
166 std::string JSONNodeDumper::createPointerRepresentation(const void *Ptr) {
167   // Because JSON stores integer values as signed 64-bit integers, trying to
168   // represent them as such makes for very ugly pointer values in the resulting
169   // output. Instead, we convert the value to hex and treat it as a string.
170   return "0x" + llvm::utohexstr(reinterpret_cast<uint64_t>(Ptr), true);
171 }
172 
173 llvm::json::Object JSONNodeDumper::createQualType(QualType QT, bool Desugar) {
174   SplitQualType SQT = QT.split();
175   llvm::json::Object Ret{{"qualType", QualType::getAsString(SQT, PrintPolicy)}};
176 
177   if (Desugar && !QT.isNull()) {
178     SplitQualType DSQT = QT.getSplitDesugaredType();
179     if (DSQT != SQT)
180       Ret["desugaredQualType"] = QualType::getAsString(DSQT, PrintPolicy);
181   }
182   return Ret;
183 }
184 
185 llvm::json::Object JSONNodeDumper::createBareDeclRef(const Decl *D) {
186   llvm::json::Object Ret{
187       {"id", createPointerRepresentation(D)},
188       {"kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str()}};
189   if (const auto *ND = dyn_cast<NamedDecl>(D))
190     Ret["name"] = ND->getDeclName().getAsString();
191   if (const auto *VD = dyn_cast<ValueDecl>(D))
192     Ret["type"] = createQualType(VD->getType());
193   return Ret;
194 }
195 
196 llvm::json::Array JSONNodeDumper::createCastPath(const CastExpr *C) {
197   llvm::json::Array Ret;
198   if (C->path_empty())
199     return Ret;
200 
201   for (auto I = C->path_begin(), E = C->path_end(); I != E; ++I) {
202     const CXXBaseSpecifier *Base = *I;
203     const auto *RD =
204         cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
205 
206     llvm::json::Object Val{{"name", RD->getName()}};
207     if (Base->isVirtual())
208       Val["isVirtual"] = true;
209     Ret.push_back(std::move(Val));
210   }
211   return Ret;
212 }
213 
214 #define FIELD2(Name, Flag)  if (RD->Flag()) Ret[Name] = true
215 #define FIELD1(Flag)        FIELD2(#Flag, Flag)
216 
217 static llvm::json::Object
218 createDefaultConstructorDefinitionData(const CXXRecordDecl *RD) {
219   llvm::json::Object Ret;
220 
221   FIELD2("exists", hasDefaultConstructor);
222   FIELD2("trivial", hasTrivialDefaultConstructor);
223   FIELD2("nonTrivial", hasNonTrivialDefaultConstructor);
224   FIELD2("userProvided", hasUserProvidedDefaultConstructor);
225   FIELD2("isConstexpr", hasConstexprDefaultConstructor);
226   FIELD2("needsImplicit", needsImplicitDefaultConstructor);
227   FIELD2("defaultedIsConstexpr", defaultedDefaultConstructorIsConstexpr);
228 
229   return Ret;
230 }
231 
232 static llvm::json::Object
233 createCopyConstructorDefinitionData(const CXXRecordDecl *RD) {
234   llvm::json::Object Ret;
235 
236   FIELD2("simple", hasSimpleCopyConstructor);
237   FIELD2("trivial", hasTrivialCopyConstructor);
238   FIELD2("nonTrivial", hasNonTrivialCopyConstructor);
239   FIELD2("userDeclared", hasUserDeclaredCopyConstructor);
240   FIELD2("hasConstParam", hasCopyConstructorWithConstParam);
241   FIELD2("implicitHasConstParam", implicitCopyConstructorHasConstParam);
242   FIELD2("needsImplicit", needsImplicitCopyConstructor);
243   FIELD2("needsOverloadResolution", needsOverloadResolutionForCopyConstructor);
244   if (!RD->needsOverloadResolutionForCopyConstructor())
245     FIELD2("defaultedIsDeleted", defaultedCopyConstructorIsDeleted);
246 
247   return Ret;
248 }
249 
250 static llvm::json::Object
251 createMoveConstructorDefinitionData(const CXXRecordDecl *RD) {
252   llvm::json::Object Ret;
253 
254   FIELD2("exists", hasMoveConstructor);
255   FIELD2("simple", hasSimpleMoveConstructor);
256   FIELD2("trivial", hasTrivialMoveConstructor);
257   FIELD2("nonTrivial", hasNonTrivialMoveConstructor);
258   FIELD2("userDeclared", hasUserDeclaredMoveConstructor);
259   FIELD2("needsImplicit", needsImplicitMoveConstructor);
260   FIELD2("needsOverloadResolution", needsOverloadResolutionForMoveConstructor);
261   if (!RD->needsOverloadResolutionForMoveConstructor())
262     FIELD2("defaultedIsDeleted", defaultedMoveConstructorIsDeleted);
263 
264   return Ret;
265 }
266 
267 static llvm::json::Object
268 createCopyAssignmentDefinitionData(const CXXRecordDecl *RD) {
269   llvm::json::Object Ret;
270 
271   FIELD2("trivial", hasTrivialCopyAssignment);
272   FIELD2("nonTrivial", hasNonTrivialCopyAssignment);
273   FIELD2("hasConstParam", hasCopyAssignmentWithConstParam);
274   FIELD2("implicitHasConstParam", implicitCopyAssignmentHasConstParam);
275   FIELD2("userDeclared", hasUserDeclaredCopyAssignment);
276   FIELD2("needsImplicit", needsImplicitCopyAssignment);
277   FIELD2("needsOverloadResolution", needsOverloadResolutionForCopyAssignment);
278 
279   return Ret;
280 }
281 
282 static llvm::json::Object
283 createMoveAssignmentDefinitionData(const CXXRecordDecl *RD) {
284   llvm::json::Object Ret;
285 
286   FIELD2("exists", hasMoveAssignment);
287   FIELD2("simple", hasSimpleMoveAssignment);
288   FIELD2("trivial", hasTrivialMoveAssignment);
289   FIELD2("nonTrivial", hasNonTrivialMoveAssignment);
290   FIELD2("userDeclared", hasUserDeclaredMoveAssignment);
291   FIELD2("needsImplicit", needsImplicitMoveAssignment);
292   FIELD2("needsOverloadResolution", needsOverloadResolutionForMoveAssignment);
293 
294   return Ret;
295 }
296 
297 static llvm::json::Object
298 createDestructorDefinitionData(const CXXRecordDecl *RD) {
299   llvm::json::Object Ret;
300 
301   FIELD2("simple", hasSimpleDestructor);
302   FIELD2("irrelevant", hasIrrelevantDestructor);
303   FIELD2("trivial", hasTrivialDestructor);
304   FIELD2("nonTrivial", hasNonTrivialDestructor);
305   FIELD2("userDeclared", hasUserDeclaredDestructor);
306   FIELD2("needsImplicit", needsImplicitDestructor);
307   FIELD2("needsOverloadResolution", needsOverloadResolutionForDestructor);
308   if (!RD->needsOverloadResolutionForDestructor())
309     FIELD2("defaultedIsDeleted", defaultedDestructorIsDeleted);
310 
311   return Ret;
312 }
313 
314 llvm::json::Object
315 JSONNodeDumper::createCXXRecordDefinitionData(const CXXRecordDecl *RD) {
316   llvm::json::Object Ret;
317 
318   // This data is common to all C++ classes.
319   FIELD1(isGenericLambda);
320   FIELD1(isLambda);
321   FIELD1(isEmpty);
322   FIELD1(isAggregate);
323   FIELD1(isStandardLayout);
324   FIELD1(isTriviallyCopyable);
325   FIELD1(isPOD);
326   FIELD1(isTrivial);
327   FIELD1(isPolymorphic);
328   FIELD1(isAbstract);
329   FIELD1(isLiteral);
330   FIELD1(canPassInRegisters);
331   FIELD1(hasUserDeclaredConstructor);
332   FIELD1(hasConstexprNonCopyMoveConstructor);
333   FIELD1(hasMutableFields);
334   FIELD1(hasVariantMembers);
335   FIELD2("canConstDefaultInit", allowConstDefaultInit);
336 
337   Ret["defaultCtor"] = createDefaultConstructorDefinitionData(RD);
338   Ret["copyCtor"] = createCopyConstructorDefinitionData(RD);
339   Ret["moveCtor"] = createMoveConstructorDefinitionData(RD);
340   Ret["copyAssign"] = createCopyAssignmentDefinitionData(RD);
341   Ret["moveAssign"] = createMoveAssignmentDefinitionData(RD);
342   Ret["dtor"] = createDestructorDefinitionData(RD);
343 
344   return Ret;
345 }
346 
347 #undef FIELD1
348 #undef FIELD2
349 
350 std::string JSONNodeDumper::createAccessSpecifier(AccessSpecifier AS) {
351   switch (AS) {
352   case AS_none: return "none";
353   case AS_private: return "private";
354   case AS_protected: return "protected";
355   case AS_public: return "public";
356   }
357   llvm_unreachable("Unknown access specifier");
358 }
359 
360 llvm::json::Object
361 JSONNodeDumper::createCXXBaseSpecifier(const CXXBaseSpecifier &BS) {
362   llvm::json::Object Ret;
363 
364   Ret["type"] = createQualType(BS.getType());
365   Ret["access"] = createAccessSpecifier(BS.getAccessSpecifier());
366   Ret["writtenAccess"] =
367       createAccessSpecifier(BS.getAccessSpecifierAsWritten());
368   if (BS.isVirtual())
369     Ret["isVirtual"] = true;
370   if (BS.isPackExpansion())
371     Ret["isPackExpansion"] = true;
372 
373   return Ret;
374 }
375 
376 void JSONNodeDumper::VisitTypedefType(const TypedefType *TT) {
377   JOS.attribute("decl", createBareDeclRef(TT->getDecl()));
378 }
379 
380 void JSONNodeDumper::VisitFunctionType(const FunctionType *T) {
381   FunctionType::ExtInfo E = T->getExtInfo();
382   attributeOnlyIfTrue("noreturn", E.getNoReturn());
383   attributeOnlyIfTrue("producesResult", E.getProducesResult());
384   if (E.getHasRegParm())
385     JOS.attribute("regParm", E.getRegParm());
386   JOS.attribute("cc", FunctionType::getNameForCallConv(E.getCC()));
387 }
388 
389 void JSONNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
390   FunctionProtoType::ExtProtoInfo E = T->getExtProtoInfo();
391   attributeOnlyIfTrue("trailingReturn", E.HasTrailingReturn);
392   attributeOnlyIfTrue("const", T->isConst());
393   attributeOnlyIfTrue("volatile", T->isVolatile());
394   attributeOnlyIfTrue("restrict", T->isRestrict());
395   attributeOnlyIfTrue("variadic", E.Variadic);
396   switch (E.RefQualifier) {
397   case RQ_LValue: JOS.attribute("refQualifier", "&"); break;
398   case RQ_RValue: JOS.attribute("refQualifier", "&&"); break;
399   case RQ_None: break;
400   }
401   switch (E.ExceptionSpec.Type) {
402   case EST_DynamicNone:
403   case EST_Dynamic: {
404     JOS.attribute("exceptionSpec", "throw");
405     llvm::json::Array Types;
406     for (QualType QT : E.ExceptionSpec.Exceptions)
407       Types.push_back(createQualType(QT));
408     JOS.attribute("exceptionTypes", std::move(Types));
409   } break;
410   case EST_MSAny:
411     JOS.attribute("exceptionSpec", "throw");
412     JOS.attribute("throwsAny", true);
413     break;
414   case EST_BasicNoexcept:
415     JOS.attribute("exceptionSpec", "noexcept");
416     break;
417   case EST_NoexceptTrue:
418   case EST_NoexceptFalse:
419     JOS.attribute("exceptionSpec", "noexcept");
420     JOS.attribute("conditionEvaluatesTo",
421                 E.ExceptionSpec.Type == EST_NoexceptTrue);
422     //JOS.attributeWithCall("exceptionSpecExpr",
423     //                    [this, E]() { Visit(E.ExceptionSpec.NoexceptExpr); });
424     break;
425 
426   // FIXME: I cannot find a way to trigger these cases while dumping the AST. I
427   // suspect you can only run into them when executing an AST dump from within
428   // the debugger, which is not a use case we worry about for the JSON dumping
429   // feature.
430   case EST_DependentNoexcept:
431   case EST_Unevaluated:
432   case EST_Uninstantiated:
433   case EST_Unparsed:
434   case EST_None: break;
435   }
436   VisitFunctionType(T);
437 }
438 
439 void JSONNodeDumper::VisitNamedDecl(const NamedDecl *ND) {
440   if (ND && ND->getDeclName())
441     JOS.attribute("name", ND->getNameAsString());
442 }
443 
444 void JSONNodeDumper::VisitTypedefDecl(const TypedefDecl *TD) {
445   VisitNamedDecl(TD);
446   JOS.attribute("type", createQualType(TD->getUnderlyingType()));
447 }
448 
449 void JSONNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *TAD) {
450   VisitNamedDecl(TAD);
451   JOS.attribute("type", createQualType(TAD->getUnderlyingType()));
452 }
453 
454 void JSONNodeDumper::VisitNamespaceDecl(const NamespaceDecl *ND) {
455   VisitNamedDecl(ND);
456   attributeOnlyIfTrue("isInline", ND->isInline());
457   if (!ND->isOriginalNamespace())
458     JOS.attribute("originalNamespace",
459                   createBareDeclRef(ND->getOriginalNamespace()));
460 }
461 
462 void JSONNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *UDD) {
463   JOS.attribute("nominatedNamespace",
464                 createBareDeclRef(UDD->getNominatedNamespace()));
465 }
466 
467 void JSONNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *NAD) {
468   VisitNamedDecl(NAD);
469   JOS.attribute("aliasedNamespace",
470                 createBareDeclRef(NAD->getAliasedNamespace()));
471 }
472 
473 void JSONNodeDumper::VisitUsingDecl(const UsingDecl *UD) {
474   std::string Name;
475   if (const NestedNameSpecifier *NNS = UD->getQualifier()) {
476     llvm::raw_string_ostream SOS(Name);
477     NNS->print(SOS, UD->getASTContext().getPrintingPolicy());
478   }
479   Name += UD->getNameAsString();
480   JOS.attribute("name", Name);
481 }
482 
483 void JSONNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *USD) {
484   JOS.attribute("target", createBareDeclRef(USD->getTargetDecl()));
485 }
486 
487 void JSONNodeDumper::VisitVarDecl(const VarDecl *VD) {
488   VisitNamedDecl(VD);
489   JOS.attribute("type", createQualType(VD->getType()));
490 
491   StorageClass SC = VD->getStorageClass();
492   if (SC != SC_None)
493     JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));
494   switch (VD->getTLSKind()) {
495   case VarDecl::TLS_Dynamic: JOS.attribute("tls", "dynamic"); break;
496   case VarDecl::TLS_Static: JOS.attribute("tls", "static"); break;
497   case VarDecl::TLS_None: break;
498   }
499   attributeOnlyIfTrue("nrvo", VD->isNRVOVariable());
500   attributeOnlyIfTrue("inline", VD->isInline());
501   attributeOnlyIfTrue("constexpr", VD->isConstexpr());
502   attributeOnlyIfTrue("modulePrivate", VD->isModulePrivate());
503   if (VD->hasInit()) {
504     switch (VD->getInitStyle()) {
505     case VarDecl::CInit: JOS.attribute("init", "c");  break;
506     case VarDecl::CallInit: JOS.attribute("init", "call"); break;
507     case VarDecl::ListInit: JOS.attribute("init", "list"); break;
508     }
509   }
510 }
511 
512 void JSONNodeDumper::VisitFieldDecl(const FieldDecl *FD) {
513   VisitNamedDecl(FD);
514   JOS.attribute("type", createQualType(FD->getType()));
515   attributeOnlyIfTrue("mutable", FD->isMutable());
516   attributeOnlyIfTrue("modulePrivate", FD->isModulePrivate());
517   attributeOnlyIfTrue("isBitfield", FD->isBitField());
518   attributeOnlyIfTrue("hasInClassInitializer", FD->hasInClassInitializer());
519 }
520 
521 void JSONNodeDumper::VisitFunctionDecl(const FunctionDecl *FD) {
522   VisitNamedDecl(FD);
523   JOS.attribute("type", createQualType(FD->getType()));
524   StorageClass SC = FD->getStorageClass();
525   if (SC != SC_None)
526     JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));
527   attributeOnlyIfTrue("inline", FD->isInlineSpecified());
528   attributeOnlyIfTrue("virtual", FD->isVirtualAsWritten());
529   attributeOnlyIfTrue("pure", FD->isPure());
530   attributeOnlyIfTrue("explicitlyDeleted", FD->isDeletedAsWritten());
531   attributeOnlyIfTrue("constexpr", FD->isConstexpr());
532   if (FD->isDefaulted())
533     JOS.attribute("explicitlyDefaulted",
534                   FD->isDeleted() ? "deleted" : "default");
535 }
536 
537 void JSONNodeDumper::VisitEnumDecl(const EnumDecl *ED) {
538   VisitNamedDecl(ED);
539   if (ED->isFixed())
540     JOS.attribute("fixedUnderlyingType", createQualType(ED->getIntegerType()));
541   if (ED->isScoped())
542     JOS.attribute("scopedEnumTag",
543                   ED->isScopedUsingClassTag() ? "class" : "struct");
544 }
545 void JSONNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *ECD) {
546   VisitNamedDecl(ECD);
547   JOS.attribute("type", createQualType(ECD->getType()));
548 }
549 
550 void JSONNodeDumper::VisitRecordDecl(const RecordDecl *RD) {
551   VisitNamedDecl(RD);
552   JOS.attribute("tagUsed", RD->getKindName());
553   attributeOnlyIfTrue("completeDefinition", RD->isCompleteDefinition());
554 }
555 void JSONNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *RD) {
556   VisitRecordDecl(RD);
557 
558   // All other information requires a complete definition.
559   if (!RD->isCompleteDefinition())
560     return;
561 
562   JOS.attribute("definitionData", createCXXRecordDefinitionData(RD));
563   if (RD->getNumBases()) {
564     JOS.attributeArray("bases", [this, RD] {
565       for (const auto &Spec : RD->bases())
566         JOS.value(createCXXBaseSpecifier(Spec));
567     });
568   }
569 }
570 
571 void JSONNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
572   VisitNamedDecl(D);
573   JOS.attribute("tagUsed", D->wasDeclaredWithTypename() ? "typename" : "class");
574   JOS.attribute("depth", D->getDepth());
575   JOS.attribute("index", D->getIndex());
576   attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
577 }
578 
579 void JSONNodeDumper::VisitNonTypeTemplateParmDecl(
580     const NonTypeTemplateParmDecl *D) {
581   VisitNamedDecl(D);
582   JOS.attribute("type", createQualType(D->getType()));
583   JOS.attribute("depth", D->getDepth());
584   JOS.attribute("index", D->getIndex());
585   attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
586 }
587 
588 void JSONNodeDumper::VisitTemplateTemplateParmDecl(
589     const TemplateTemplateParmDecl *D) {
590   VisitNamedDecl(D);
591   JOS.attribute("depth", D->getDepth());
592   JOS.attribute("index", D->getIndex());
593   attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
594 }
595 
596 void JSONNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *LSD) {
597   StringRef Lang;
598   switch (LSD->getLanguage()) {
599   case LinkageSpecDecl::lang_c: Lang = "C"; break;
600   case LinkageSpecDecl::lang_cxx: Lang = "C++"; break;
601   }
602   JOS.attribute("language", Lang);
603   attributeOnlyIfTrue("hasBraces", LSD->hasBraces());
604 }
605 
606 void JSONNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *ASD) {
607   JOS.attribute("access", createAccessSpecifier(ASD->getAccess()));
608 }
609 
610 void JSONNodeDumper::VisitFriendDecl(const FriendDecl *FD) {
611   if (const TypeSourceInfo *T = FD->getFriendType())
612     JOS.attribute("type", createQualType(T->getType()));
613 }
614 
615 void JSONNodeDumper::VisitDeclRefExpr(const DeclRefExpr *DRE) {
616   JOS.attribute("referencedDecl", createBareDeclRef(DRE->getDecl()));
617   if (DRE->getDecl() != DRE->getFoundDecl())
618     JOS.attribute("foundReferencedDecl",
619                   createBareDeclRef(DRE->getFoundDecl()));
620 }
621 
622 void JSONNodeDumper::VisitPredefinedExpr(const PredefinedExpr *PE) {
623   JOS.attribute("name", PredefinedExpr::getIdentKindName(PE->getIdentKind()));
624 }
625 
626 void JSONNodeDumper::VisitUnaryOperator(const UnaryOperator *UO) {
627   JOS.attribute("isPostfix", UO->isPostfix());
628   JOS.attribute("opcode", UnaryOperator::getOpcodeStr(UO->getOpcode()));
629   if (!UO->canOverflow())
630     JOS.attribute("canOverflow", false);
631 }
632 
633 void JSONNodeDumper::VisitBinaryOperator(const BinaryOperator *BO) {
634   JOS.attribute("opcode", BinaryOperator::getOpcodeStr(BO->getOpcode()));
635 }
636 
637 void JSONNodeDumper::VisitCompoundAssignOperator(
638     const CompoundAssignOperator *CAO) {
639   VisitBinaryOperator(CAO);
640   JOS.attribute("computeLHSType", createQualType(CAO->getComputationLHSType()));
641   JOS.attribute("computeResultType",
642                 createQualType(CAO->getComputationResultType()));
643 }
644 
645 void JSONNodeDumper::VisitMemberExpr(const MemberExpr *ME) {
646   // Note, we always write this Boolean field because the information it conveys
647   // is critical to understanding the AST node.
648   JOS.attribute("isArrow", ME->isArrow());
649   JOS.attribute("referencedMemberDecl",
650                 createPointerRepresentation(ME->getMemberDecl()));
651 }
652 
653 void JSONNodeDumper::VisitCXXNewExpr(const CXXNewExpr *NE) {
654   attributeOnlyIfTrue("isGlobal", NE->isGlobalNew());
655   attributeOnlyIfTrue("isArray", NE->isArray());
656   attributeOnlyIfTrue("isPlacement", NE->getNumPlacementArgs() != 0);
657   switch (NE->getInitializationStyle()) {
658   case CXXNewExpr::NoInit: break;
659   case CXXNewExpr::CallInit: JOS.attribute("initStyle", "call"); break;
660   case CXXNewExpr::ListInit: JOS.attribute("initStyle", "list"); break;
661   }
662   if (const FunctionDecl *FD = NE->getOperatorNew())
663     JOS.attribute("operatorNewDecl", createBareDeclRef(FD));
664   if (const FunctionDecl *FD = NE->getOperatorDelete())
665     JOS.attribute("operatorDeleteDecl", createBareDeclRef(FD));
666 }
667 void JSONNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *DE) {
668   attributeOnlyIfTrue("isGlobal", DE->isGlobalDelete());
669   attributeOnlyIfTrue("isArray", DE->isArrayForm());
670   attributeOnlyIfTrue("isArrayAsWritten", DE->isArrayFormAsWritten());
671   if (const FunctionDecl *FD = DE->getOperatorDelete())
672     JOS.attribute("operatorDeleteDecl", createBareDeclRef(FD));
673 }
674 
675 void JSONNodeDumper::VisitCXXThisExpr(const CXXThisExpr *TE) {
676   attributeOnlyIfTrue("implicit", TE->isImplicit());
677 }
678 
679 void JSONNodeDumper::VisitCastExpr(const CastExpr *CE) {
680   JOS.attribute("castKind", CE->getCastKindName());
681   llvm::json::Array Path = createCastPath(CE);
682   if (!Path.empty())
683     JOS.attribute("path", std::move(Path));
684   // FIXME: This may not be useful information as it can be obtusely gleaned
685   // from the inner[] array.
686   if (const NamedDecl *ND = CE->getConversionFunction())
687     JOS.attribute("conversionFunc", createBareDeclRef(ND));
688 }
689 
690 void JSONNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *ICE) {
691   VisitCastExpr(ICE);
692   attributeOnlyIfTrue("isPartOfExplicitCast", ICE->isPartOfExplicitCast());
693 }
694 
695 void JSONNodeDumper::VisitCallExpr(const CallExpr *CE) {
696   attributeOnlyIfTrue("adl", CE->usesADL());
697 }
698 
699 void JSONNodeDumper::VisitUnaryExprOrTypeTraitExpr(
700     const UnaryExprOrTypeTraitExpr *TTE) {
701   switch (TTE->getKind()) {
702   case UETT_SizeOf: JOS.attribute("name", "sizeof"); break;
703   case UETT_AlignOf: JOS.attribute("name", "alignof"); break;
704   case UETT_VecStep:  JOS.attribute("name", "vec_step"); break;
705   case UETT_PreferredAlignOf:  JOS.attribute("name", "__alignof"); break;
706   case UETT_OpenMPRequiredSimdAlign:
707     JOS.attribute("name", "__builtin_omp_required_simd_align"); break;
708   }
709   if (TTE->isArgumentType())
710     JOS.attribute("argType", createQualType(TTE->getArgumentType()));
711 }
712 
713 void JSONNodeDumper::VisitUnresolvedLookupExpr(
714     const UnresolvedLookupExpr *ULE) {
715   JOS.attribute("usesADL", ULE->requiresADL());
716   JOS.attribute("name", ULE->getName().getAsString());
717 
718   JOS.attributeArray("lookups", [this, ULE] {
719     for (const NamedDecl *D : ULE->decls())
720       JOS.value(createBareDeclRef(D));
721   });
722 }
723 
724 void JSONNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *ALE) {
725   JOS.attribute("name", ALE->getLabel()->getName());
726   JOS.attribute("labelDeclId", createPointerRepresentation(ALE->getLabel()));
727 }
728 
729 void JSONNodeDumper::VisitIntegerLiteral(const IntegerLiteral *IL) {
730   JOS.attribute("value",
731                 IL->getValue().toString(
732                     /*Radix=*/10, IL->getType()->isSignedIntegerType()));
733 }
734 void JSONNodeDumper::VisitCharacterLiteral(const CharacterLiteral *CL) {
735   // FIXME: This should probably print the character literal as a string,
736   // rather than as a numerical value.
737   JOS.attribute("value", CL->getValue());
738 }
739 void JSONNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *FPL) {
740   JOS.attribute("value", FPL->getValueAsString(/*Radix=*/10));
741 }
742 void JSONNodeDumper::VisitFloatingLiteral(const FloatingLiteral *FL) {
743   JOS.attribute("value", FL->getValueAsApproximateDouble());
744 }
745 void JSONNodeDumper::VisitStringLiteral(const StringLiteral *SL) {
746   std::string Buffer;
747   llvm::raw_string_ostream SS(Buffer);
748   SL->outputString(SS);
749   JOS.attribute("value", SS.str());
750 }
751 void JSONNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *BLE) {
752   JOS.attribute("value", BLE->getValue());
753 }
754 
755 void JSONNodeDumper::VisitIfStmt(const IfStmt *IS) {
756   attributeOnlyIfTrue("hasInit", IS->hasInitStorage());
757   attributeOnlyIfTrue("hasVar", IS->hasVarStorage());
758   attributeOnlyIfTrue("hasElse", IS->hasElseStorage());
759   attributeOnlyIfTrue("isConstexpr", IS->isConstexpr());
760 }
761 
762 void JSONNodeDumper::VisitSwitchStmt(const SwitchStmt *SS) {
763   attributeOnlyIfTrue("hasInit", SS->hasInitStorage());
764   attributeOnlyIfTrue("hasVar", SS->hasVarStorage());
765 }
766 void JSONNodeDumper::VisitCaseStmt(const CaseStmt *CS) {
767   attributeOnlyIfTrue("isGNURange", CS->caseStmtIsGNURange());
768 }
769 
770 void JSONNodeDumper::VisitLabelStmt(const LabelStmt *LS) {
771   JOS.attribute("name", LS->getName());
772   JOS.attribute("declId", createPointerRepresentation(LS->getDecl()));
773 }
774 void JSONNodeDumper::VisitGotoStmt(const GotoStmt *GS) {
775   JOS.attribute("targetLabelDeclId",
776                 createPointerRepresentation(GS->getLabel()));
777 }
778 
779 void JSONNodeDumper::VisitWhileStmt(const WhileStmt *WS) {
780   attributeOnlyIfTrue("hasVar", WS->hasVarStorage());
781 }
782