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