xref: /freebsd/contrib/llvm-project/clang/lib/AST/JSONNodeDumper.cpp (revision e6bfd18d21b225af6a0ed67ceeaf1293b7b9eba5)
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       return;
749 
750     // Mangled names are not meaningful for locals, and may not be well-defined
751     // in the case of VLAs.
752     auto *VD = dyn_cast<VarDecl>(ND);
753     if (VD && VD->hasLocalStorage())
754       return;
755 
756     std::string MangledName = ASTNameGen.getName(ND);
757     if (!MangledName.empty())
758       JOS.attribute("mangledName", MangledName);
759   }
760 }
761 
762 void JSONNodeDumper::VisitTypedefDecl(const TypedefDecl *TD) {
763   VisitNamedDecl(TD);
764   JOS.attribute("type", createQualType(TD->getUnderlyingType()));
765 }
766 
767 void JSONNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *TAD) {
768   VisitNamedDecl(TAD);
769   JOS.attribute("type", createQualType(TAD->getUnderlyingType()));
770 }
771 
772 void JSONNodeDumper::VisitNamespaceDecl(const NamespaceDecl *ND) {
773   VisitNamedDecl(ND);
774   attributeOnlyIfTrue("isInline", ND->isInline());
775   if (!ND->isOriginalNamespace())
776     JOS.attribute("originalNamespace",
777                   createBareDeclRef(ND->getOriginalNamespace()));
778 }
779 
780 void JSONNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *UDD) {
781   JOS.attribute("nominatedNamespace",
782                 createBareDeclRef(UDD->getNominatedNamespace()));
783 }
784 
785 void JSONNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *NAD) {
786   VisitNamedDecl(NAD);
787   JOS.attribute("aliasedNamespace",
788                 createBareDeclRef(NAD->getAliasedNamespace()));
789 }
790 
791 void JSONNodeDumper::VisitUsingDecl(const UsingDecl *UD) {
792   std::string Name;
793   if (const NestedNameSpecifier *NNS = UD->getQualifier()) {
794     llvm::raw_string_ostream SOS(Name);
795     NNS->print(SOS, UD->getASTContext().getPrintingPolicy());
796   }
797   Name += UD->getNameAsString();
798   JOS.attribute("name", Name);
799 }
800 
801 void JSONNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *UED) {
802   JOS.attribute("target", createBareDeclRef(UED->getEnumDecl()));
803 }
804 
805 void JSONNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *USD) {
806   JOS.attribute("target", createBareDeclRef(USD->getTargetDecl()));
807 }
808 
809 void JSONNodeDumper::VisitVarDecl(const VarDecl *VD) {
810   VisitNamedDecl(VD);
811   JOS.attribute("type", createQualType(VD->getType()));
812 
813   StorageClass SC = VD->getStorageClass();
814   if (SC != SC_None)
815     JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));
816   switch (VD->getTLSKind()) {
817   case VarDecl::TLS_Dynamic: JOS.attribute("tls", "dynamic"); break;
818   case VarDecl::TLS_Static: JOS.attribute("tls", "static"); break;
819   case VarDecl::TLS_None: break;
820   }
821   attributeOnlyIfTrue("nrvo", VD->isNRVOVariable());
822   attributeOnlyIfTrue("inline", VD->isInline());
823   attributeOnlyIfTrue("constexpr", VD->isConstexpr());
824   attributeOnlyIfTrue("modulePrivate", VD->isModulePrivate());
825   if (VD->hasInit()) {
826     switch (VD->getInitStyle()) {
827     case VarDecl::CInit: JOS.attribute("init", "c");  break;
828     case VarDecl::CallInit: JOS.attribute("init", "call"); break;
829     case VarDecl::ListInit: JOS.attribute("init", "list"); break;
830     }
831   }
832   attributeOnlyIfTrue("isParameterPack", VD->isParameterPack());
833 }
834 
835 void JSONNodeDumper::VisitFieldDecl(const FieldDecl *FD) {
836   VisitNamedDecl(FD);
837   JOS.attribute("type", createQualType(FD->getType()));
838   attributeOnlyIfTrue("mutable", FD->isMutable());
839   attributeOnlyIfTrue("modulePrivate", FD->isModulePrivate());
840   attributeOnlyIfTrue("isBitfield", FD->isBitField());
841   attributeOnlyIfTrue("hasInClassInitializer", FD->hasInClassInitializer());
842 }
843 
844 void JSONNodeDumper::VisitFunctionDecl(const FunctionDecl *FD) {
845   VisitNamedDecl(FD);
846   JOS.attribute("type", createQualType(FD->getType()));
847   StorageClass SC = FD->getStorageClass();
848   if (SC != SC_None)
849     JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));
850   attributeOnlyIfTrue("inline", FD->isInlineSpecified());
851   attributeOnlyIfTrue("virtual", FD->isVirtualAsWritten());
852   attributeOnlyIfTrue("pure", FD->isPure());
853   attributeOnlyIfTrue("explicitlyDeleted", FD->isDeletedAsWritten());
854   attributeOnlyIfTrue("constexpr", FD->isConstexpr());
855   attributeOnlyIfTrue("variadic", FD->isVariadic());
856 
857   if (FD->isDefaulted())
858     JOS.attribute("explicitlyDefaulted",
859                   FD->isDeleted() ? "deleted" : "default");
860 }
861 
862 void JSONNodeDumper::VisitEnumDecl(const EnumDecl *ED) {
863   VisitNamedDecl(ED);
864   if (ED->isFixed())
865     JOS.attribute("fixedUnderlyingType", createQualType(ED->getIntegerType()));
866   if (ED->isScoped())
867     JOS.attribute("scopedEnumTag",
868                   ED->isScopedUsingClassTag() ? "class" : "struct");
869 }
870 void JSONNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *ECD) {
871   VisitNamedDecl(ECD);
872   JOS.attribute("type", createQualType(ECD->getType()));
873 }
874 
875 void JSONNodeDumper::VisitRecordDecl(const RecordDecl *RD) {
876   VisitNamedDecl(RD);
877   JOS.attribute("tagUsed", RD->getKindName());
878   attributeOnlyIfTrue("completeDefinition", RD->isCompleteDefinition());
879 }
880 void JSONNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *RD) {
881   VisitRecordDecl(RD);
882 
883   // All other information requires a complete definition.
884   if (!RD->isCompleteDefinition())
885     return;
886 
887   JOS.attribute("definitionData", createCXXRecordDefinitionData(RD));
888   if (RD->getNumBases()) {
889     JOS.attributeArray("bases", [this, RD] {
890       for (const auto &Spec : RD->bases())
891         JOS.value(createCXXBaseSpecifier(Spec));
892     });
893   }
894 }
895 
896 void JSONNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
897   VisitNamedDecl(D);
898   JOS.attribute("tagUsed", D->wasDeclaredWithTypename() ? "typename" : "class");
899   JOS.attribute("depth", D->getDepth());
900   JOS.attribute("index", D->getIndex());
901   attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
902 
903   if (D->hasDefaultArgument())
904     JOS.attributeObject("defaultArg", [=] {
905       Visit(D->getDefaultArgument(), SourceRange(),
906             D->getDefaultArgStorage().getInheritedFrom(),
907             D->defaultArgumentWasInherited() ? "inherited from" : "previous");
908     });
909 }
910 
911 void JSONNodeDumper::VisitNonTypeTemplateParmDecl(
912     const NonTypeTemplateParmDecl *D) {
913   VisitNamedDecl(D);
914   JOS.attribute("type", createQualType(D->getType()));
915   JOS.attribute("depth", D->getDepth());
916   JOS.attribute("index", D->getIndex());
917   attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
918 
919   if (D->hasDefaultArgument())
920     JOS.attributeObject("defaultArg", [=] {
921       Visit(D->getDefaultArgument(), SourceRange(),
922             D->getDefaultArgStorage().getInheritedFrom(),
923             D->defaultArgumentWasInherited() ? "inherited from" : "previous");
924     });
925 }
926 
927 void JSONNodeDumper::VisitTemplateTemplateParmDecl(
928     const TemplateTemplateParmDecl *D) {
929   VisitNamedDecl(D);
930   JOS.attribute("depth", D->getDepth());
931   JOS.attribute("index", D->getIndex());
932   attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
933 
934   if (D->hasDefaultArgument())
935     JOS.attributeObject("defaultArg", [=] {
936       const auto *InheritedFrom = D->getDefaultArgStorage().getInheritedFrom();
937       Visit(D->getDefaultArgument().getArgument(),
938             InheritedFrom ? InheritedFrom->getSourceRange() : SourceLocation{},
939             InheritedFrom,
940             D->defaultArgumentWasInherited() ? "inherited from" : "previous");
941     });
942 }
943 
944 void JSONNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *LSD) {
945   StringRef Lang;
946   switch (LSD->getLanguage()) {
947   case LinkageSpecDecl::lang_c: Lang = "C"; break;
948   case LinkageSpecDecl::lang_cxx: Lang = "C++"; break;
949   }
950   JOS.attribute("language", Lang);
951   attributeOnlyIfTrue("hasBraces", LSD->hasBraces());
952 }
953 
954 void JSONNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *ASD) {
955   JOS.attribute("access", createAccessSpecifier(ASD->getAccess()));
956 }
957 
958 void JSONNodeDumper::VisitFriendDecl(const FriendDecl *FD) {
959   if (const TypeSourceInfo *T = FD->getFriendType())
960     JOS.attribute("type", createQualType(T->getType()));
961 }
962 
963 void JSONNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
964   VisitNamedDecl(D);
965   JOS.attribute("type", createQualType(D->getType()));
966   attributeOnlyIfTrue("synthesized", D->getSynthesize());
967   switch (D->getAccessControl()) {
968   case ObjCIvarDecl::None: JOS.attribute("access", "none"); break;
969   case ObjCIvarDecl::Private: JOS.attribute("access", "private"); break;
970   case ObjCIvarDecl::Protected: JOS.attribute("access", "protected"); break;
971   case ObjCIvarDecl::Public: JOS.attribute("access", "public"); break;
972   case ObjCIvarDecl::Package: JOS.attribute("access", "package"); break;
973   }
974 }
975 
976 void JSONNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
977   VisitNamedDecl(D);
978   JOS.attribute("returnType", createQualType(D->getReturnType()));
979   JOS.attribute("instance", D->isInstanceMethod());
980   attributeOnlyIfTrue("variadic", D->isVariadic());
981 }
982 
983 void JSONNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
984   VisitNamedDecl(D);
985   JOS.attribute("type", createQualType(D->getUnderlyingType()));
986   attributeOnlyIfTrue("bounded", D->hasExplicitBound());
987   switch (D->getVariance()) {
988   case ObjCTypeParamVariance::Invariant:
989     break;
990   case ObjCTypeParamVariance::Covariant:
991     JOS.attribute("variance", "covariant");
992     break;
993   case ObjCTypeParamVariance::Contravariant:
994     JOS.attribute("variance", "contravariant");
995     break;
996   }
997 }
998 
999 void JSONNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
1000   VisitNamedDecl(D);
1001   JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
1002   JOS.attribute("implementation", createBareDeclRef(D->getImplementation()));
1003 
1004   llvm::json::Array Protocols;
1005   for (const auto* P : D->protocols())
1006     Protocols.push_back(createBareDeclRef(P));
1007   if (!Protocols.empty())
1008     JOS.attribute("protocols", std::move(Protocols));
1009 }
1010 
1011 void JSONNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
1012   VisitNamedDecl(D);
1013   JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
1014   JOS.attribute("categoryDecl", createBareDeclRef(D->getCategoryDecl()));
1015 }
1016 
1017 void JSONNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
1018   VisitNamedDecl(D);
1019 
1020   llvm::json::Array Protocols;
1021   for (const auto *P : D->protocols())
1022     Protocols.push_back(createBareDeclRef(P));
1023   if (!Protocols.empty())
1024     JOS.attribute("protocols", std::move(Protocols));
1025 }
1026 
1027 void JSONNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
1028   VisitNamedDecl(D);
1029   JOS.attribute("super", createBareDeclRef(D->getSuperClass()));
1030   JOS.attribute("implementation", createBareDeclRef(D->getImplementation()));
1031 
1032   llvm::json::Array Protocols;
1033   for (const auto* P : D->protocols())
1034     Protocols.push_back(createBareDeclRef(P));
1035   if (!Protocols.empty())
1036     JOS.attribute("protocols", std::move(Protocols));
1037 }
1038 
1039 void JSONNodeDumper::VisitObjCImplementationDecl(
1040     const ObjCImplementationDecl *D) {
1041   VisitNamedDecl(D);
1042   JOS.attribute("super", createBareDeclRef(D->getSuperClass()));
1043   JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
1044 }
1045 
1046 void JSONNodeDumper::VisitObjCCompatibleAliasDecl(
1047     const ObjCCompatibleAliasDecl *D) {
1048   VisitNamedDecl(D);
1049   JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
1050 }
1051 
1052 void JSONNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
1053   VisitNamedDecl(D);
1054   JOS.attribute("type", createQualType(D->getType()));
1055 
1056   switch (D->getPropertyImplementation()) {
1057   case ObjCPropertyDecl::None: break;
1058   case ObjCPropertyDecl::Required: JOS.attribute("control", "required"); break;
1059   case ObjCPropertyDecl::Optional: JOS.attribute("control", "optional"); break;
1060   }
1061 
1062   ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
1063   if (Attrs != ObjCPropertyAttribute::kind_noattr) {
1064     if (Attrs & ObjCPropertyAttribute::kind_getter)
1065       JOS.attribute("getter", createBareDeclRef(D->getGetterMethodDecl()));
1066     if (Attrs & ObjCPropertyAttribute::kind_setter)
1067       JOS.attribute("setter", createBareDeclRef(D->getSetterMethodDecl()));
1068     attributeOnlyIfTrue("readonly",
1069                         Attrs & ObjCPropertyAttribute::kind_readonly);
1070     attributeOnlyIfTrue("assign", Attrs & ObjCPropertyAttribute::kind_assign);
1071     attributeOnlyIfTrue("readwrite",
1072                         Attrs & ObjCPropertyAttribute::kind_readwrite);
1073     attributeOnlyIfTrue("retain", Attrs & ObjCPropertyAttribute::kind_retain);
1074     attributeOnlyIfTrue("copy", Attrs & ObjCPropertyAttribute::kind_copy);
1075     attributeOnlyIfTrue("nonatomic",
1076                         Attrs & ObjCPropertyAttribute::kind_nonatomic);
1077     attributeOnlyIfTrue("atomic", Attrs & ObjCPropertyAttribute::kind_atomic);
1078     attributeOnlyIfTrue("weak", Attrs & ObjCPropertyAttribute::kind_weak);
1079     attributeOnlyIfTrue("strong", Attrs & ObjCPropertyAttribute::kind_strong);
1080     attributeOnlyIfTrue("unsafe_unretained",
1081                         Attrs & ObjCPropertyAttribute::kind_unsafe_unretained);
1082     attributeOnlyIfTrue("class", Attrs & ObjCPropertyAttribute::kind_class);
1083     attributeOnlyIfTrue("direct", Attrs & ObjCPropertyAttribute::kind_direct);
1084     attributeOnlyIfTrue("nullability",
1085                         Attrs & ObjCPropertyAttribute::kind_nullability);
1086     attributeOnlyIfTrue("null_resettable",
1087                         Attrs & ObjCPropertyAttribute::kind_null_resettable);
1088   }
1089 }
1090 
1091 void JSONNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
1092   VisitNamedDecl(D->getPropertyDecl());
1093   JOS.attribute("implKind", D->getPropertyImplementation() ==
1094                                     ObjCPropertyImplDecl::Synthesize
1095                                 ? "synthesize"
1096                                 : "dynamic");
1097   JOS.attribute("propertyDecl", createBareDeclRef(D->getPropertyDecl()));
1098   JOS.attribute("ivarDecl", createBareDeclRef(D->getPropertyIvarDecl()));
1099 }
1100 
1101 void JSONNodeDumper::VisitBlockDecl(const BlockDecl *D) {
1102   attributeOnlyIfTrue("variadic", D->isVariadic());
1103   attributeOnlyIfTrue("capturesThis", D->capturesCXXThis());
1104 }
1105 
1106 void JSONNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE) {
1107   JOS.attribute("encodedType", createQualType(OEE->getEncodedType()));
1108 }
1109 
1110 void JSONNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *OME) {
1111   std::string Str;
1112   llvm::raw_string_ostream OS(Str);
1113 
1114   OME->getSelector().print(OS);
1115   JOS.attribute("selector", OS.str());
1116 
1117   switch (OME->getReceiverKind()) {
1118   case ObjCMessageExpr::Instance:
1119     JOS.attribute("receiverKind", "instance");
1120     break;
1121   case ObjCMessageExpr::Class:
1122     JOS.attribute("receiverKind", "class");
1123     JOS.attribute("classType", createQualType(OME->getClassReceiver()));
1124     break;
1125   case ObjCMessageExpr::SuperInstance:
1126     JOS.attribute("receiverKind", "super (instance)");
1127     JOS.attribute("superType", createQualType(OME->getSuperType()));
1128     break;
1129   case ObjCMessageExpr::SuperClass:
1130     JOS.attribute("receiverKind", "super (class)");
1131     JOS.attribute("superType", createQualType(OME->getSuperType()));
1132     break;
1133   }
1134 
1135   QualType CallReturnTy = OME->getCallReturnType(Ctx);
1136   if (OME->getType() != CallReturnTy)
1137     JOS.attribute("callReturnType", createQualType(CallReturnTy));
1138 }
1139 
1140 void JSONNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *OBE) {
1141   if (const ObjCMethodDecl *MD = OBE->getBoxingMethod()) {
1142     std::string Str;
1143     llvm::raw_string_ostream OS(Str);
1144 
1145     MD->getSelector().print(OS);
1146     JOS.attribute("selector", OS.str());
1147   }
1148 }
1149 
1150 void JSONNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *OSE) {
1151   std::string Str;
1152   llvm::raw_string_ostream OS(Str);
1153 
1154   OSE->getSelector().print(OS);
1155   JOS.attribute("selector", OS.str());
1156 }
1157 
1158 void JSONNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE) {
1159   JOS.attribute("protocol", createBareDeclRef(OPE->getProtocol()));
1160 }
1161 
1162 void JSONNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE) {
1163   if (OPRE->isImplicitProperty()) {
1164     JOS.attribute("propertyKind", "implicit");
1165     if (const ObjCMethodDecl *MD = OPRE->getImplicitPropertyGetter())
1166       JOS.attribute("getter", createBareDeclRef(MD));
1167     if (const ObjCMethodDecl *MD = OPRE->getImplicitPropertySetter())
1168       JOS.attribute("setter", createBareDeclRef(MD));
1169   } else {
1170     JOS.attribute("propertyKind", "explicit");
1171     JOS.attribute("property", createBareDeclRef(OPRE->getExplicitProperty()));
1172   }
1173 
1174   attributeOnlyIfTrue("isSuperReceiver", OPRE->isSuperReceiver());
1175   attributeOnlyIfTrue("isMessagingGetter", OPRE->isMessagingGetter());
1176   attributeOnlyIfTrue("isMessagingSetter", OPRE->isMessagingSetter());
1177 }
1178 
1179 void JSONNodeDumper::VisitObjCSubscriptRefExpr(
1180     const ObjCSubscriptRefExpr *OSRE) {
1181   JOS.attribute("subscriptKind",
1182                 OSRE->isArraySubscriptRefExpr() ? "array" : "dictionary");
1183 
1184   if (const ObjCMethodDecl *MD = OSRE->getAtIndexMethodDecl())
1185     JOS.attribute("getter", createBareDeclRef(MD));
1186   if (const ObjCMethodDecl *MD = OSRE->setAtIndexMethodDecl())
1187     JOS.attribute("setter", createBareDeclRef(MD));
1188 }
1189 
1190 void JSONNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {
1191   JOS.attribute("decl", createBareDeclRef(OIRE->getDecl()));
1192   attributeOnlyIfTrue("isFreeIvar", OIRE->isFreeIvar());
1193   JOS.attribute("isArrow", OIRE->isArrow());
1194 }
1195 
1196 void JSONNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *OBLE) {
1197   JOS.attribute("value", OBLE->getValue() ? "__objc_yes" : "__objc_no");
1198 }
1199 
1200 void JSONNodeDumper::VisitDeclRefExpr(const DeclRefExpr *DRE) {
1201   JOS.attribute("referencedDecl", createBareDeclRef(DRE->getDecl()));
1202   if (DRE->getDecl() != DRE->getFoundDecl())
1203     JOS.attribute("foundReferencedDecl",
1204                   createBareDeclRef(DRE->getFoundDecl()));
1205   switch (DRE->isNonOdrUse()) {
1206   case NOUR_None: break;
1207   case NOUR_Unevaluated: JOS.attribute("nonOdrUseReason", "unevaluated"); break;
1208   case NOUR_Constant: JOS.attribute("nonOdrUseReason", "constant"); break;
1209   case NOUR_Discarded: JOS.attribute("nonOdrUseReason", "discarded"); break;
1210   }
1211 }
1212 
1213 void JSONNodeDumper::VisitSYCLUniqueStableNameExpr(
1214     const SYCLUniqueStableNameExpr *E) {
1215   JOS.attribute("typeSourceInfo",
1216                 createQualType(E->getTypeSourceInfo()->getType()));
1217 }
1218 
1219 void JSONNodeDumper::VisitPredefinedExpr(const PredefinedExpr *PE) {
1220   JOS.attribute("name", PredefinedExpr::getIdentKindName(PE->getIdentKind()));
1221 }
1222 
1223 void JSONNodeDumper::VisitUnaryOperator(const UnaryOperator *UO) {
1224   JOS.attribute("isPostfix", UO->isPostfix());
1225   JOS.attribute("opcode", UnaryOperator::getOpcodeStr(UO->getOpcode()));
1226   if (!UO->canOverflow())
1227     JOS.attribute("canOverflow", false);
1228 }
1229 
1230 void JSONNodeDumper::VisitBinaryOperator(const BinaryOperator *BO) {
1231   JOS.attribute("opcode", BinaryOperator::getOpcodeStr(BO->getOpcode()));
1232 }
1233 
1234 void JSONNodeDumper::VisitCompoundAssignOperator(
1235     const CompoundAssignOperator *CAO) {
1236   VisitBinaryOperator(CAO);
1237   JOS.attribute("computeLHSType", createQualType(CAO->getComputationLHSType()));
1238   JOS.attribute("computeResultType",
1239                 createQualType(CAO->getComputationResultType()));
1240 }
1241 
1242 void JSONNodeDumper::VisitMemberExpr(const MemberExpr *ME) {
1243   // Note, we always write this Boolean field because the information it conveys
1244   // is critical to understanding the AST node.
1245   ValueDecl *VD = ME->getMemberDecl();
1246   JOS.attribute("name", VD && VD->getDeclName() ? VD->getNameAsString() : "");
1247   JOS.attribute("isArrow", ME->isArrow());
1248   JOS.attribute("referencedMemberDecl", createPointerRepresentation(VD));
1249   switch (ME->isNonOdrUse()) {
1250   case NOUR_None: break;
1251   case NOUR_Unevaluated: JOS.attribute("nonOdrUseReason", "unevaluated"); break;
1252   case NOUR_Constant: JOS.attribute("nonOdrUseReason", "constant"); break;
1253   case NOUR_Discarded: JOS.attribute("nonOdrUseReason", "discarded"); break;
1254   }
1255 }
1256 
1257 void JSONNodeDumper::VisitCXXNewExpr(const CXXNewExpr *NE) {
1258   attributeOnlyIfTrue("isGlobal", NE->isGlobalNew());
1259   attributeOnlyIfTrue("isArray", NE->isArray());
1260   attributeOnlyIfTrue("isPlacement", NE->getNumPlacementArgs() != 0);
1261   switch (NE->getInitializationStyle()) {
1262   case CXXNewExpr::NoInit: break;
1263   case CXXNewExpr::CallInit: JOS.attribute("initStyle", "call"); break;
1264   case CXXNewExpr::ListInit: JOS.attribute("initStyle", "list"); break;
1265   }
1266   if (const FunctionDecl *FD = NE->getOperatorNew())
1267     JOS.attribute("operatorNewDecl", createBareDeclRef(FD));
1268   if (const FunctionDecl *FD = NE->getOperatorDelete())
1269     JOS.attribute("operatorDeleteDecl", createBareDeclRef(FD));
1270 }
1271 void JSONNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *DE) {
1272   attributeOnlyIfTrue("isGlobal", DE->isGlobalDelete());
1273   attributeOnlyIfTrue("isArray", DE->isArrayForm());
1274   attributeOnlyIfTrue("isArrayAsWritten", DE->isArrayFormAsWritten());
1275   if (const FunctionDecl *FD = DE->getOperatorDelete())
1276     JOS.attribute("operatorDeleteDecl", createBareDeclRef(FD));
1277 }
1278 
1279 void JSONNodeDumper::VisitCXXThisExpr(const CXXThisExpr *TE) {
1280   attributeOnlyIfTrue("implicit", TE->isImplicit());
1281 }
1282 
1283 void JSONNodeDumper::VisitCastExpr(const CastExpr *CE) {
1284   JOS.attribute("castKind", CE->getCastKindName());
1285   llvm::json::Array Path = createCastPath(CE);
1286   if (!Path.empty())
1287     JOS.attribute("path", std::move(Path));
1288   // FIXME: This may not be useful information as it can be obtusely gleaned
1289   // from the inner[] array.
1290   if (const NamedDecl *ND = CE->getConversionFunction())
1291     JOS.attribute("conversionFunc", createBareDeclRef(ND));
1292 }
1293 
1294 void JSONNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *ICE) {
1295   VisitCastExpr(ICE);
1296   attributeOnlyIfTrue("isPartOfExplicitCast", ICE->isPartOfExplicitCast());
1297 }
1298 
1299 void JSONNodeDumper::VisitCallExpr(const CallExpr *CE) {
1300   attributeOnlyIfTrue("adl", CE->usesADL());
1301 }
1302 
1303 void JSONNodeDumper::VisitUnaryExprOrTypeTraitExpr(
1304     const UnaryExprOrTypeTraitExpr *TTE) {
1305   JOS.attribute("name", getTraitSpelling(TTE->getKind()));
1306   if (TTE->isArgumentType())
1307     JOS.attribute("argType", createQualType(TTE->getArgumentType()));
1308 }
1309 
1310 void JSONNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *SOPE) {
1311   VisitNamedDecl(SOPE->getPack());
1312 }
1313 
1314 void JSONNodeDumper::VisitUnresolvedLookupExpr(
1315     const UnresolvedLookupExpr *ULE) {
1316   JOS.attribute("usesADL", ULE->requiresADL());
1317   JOS.attribute("name", ULE->getName().getAsString());
1318 
1319   JOS.attributeArray("lookups", [this, ULE] {
1320     for (const NamedDecl *D : ULE->decls())
1321       JOS.value(createBareDeclRef(D));
1322   });
1323 }
1324 
1325 void JSONNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *ALE) {
1326   JOS.attribute("name", ALE->getLabel()->getName());
1327   JOS.attribute("labelDeclId", createPointerRepresentation(ALE->getLabel()));
1328 }
1329 
1330 void JSONNodeDumper::VisitCXXTypeidExpr(const CXXTypeidExpr *CTE) {
1331   if (CTE->isTypeOperand()) {
1332     QualType Adjusted = CTE->getTypeOperand(Ctx);
1333     QualType Unadjusted = CTE->getTypeOperandSourceInfo()->getType();
1334     JOS.attribute("typeArg", createQualType(Unadjusted));
1335     if (Adjusted != Unadjusted)
1336       JOS.attribute("adjustedTypeArg", createQualType(Adjusted));
1337   }
1338 }
1339 
1340 void JSONNodeDumper::VisitConstantExpr(const ConstantExpr *CE) {
1341   if (CE->getResultAPValueKind() != APValue::None)
1342     Visit(CE->getAPValueResult(), CE->getType());
1343 }
1344 
1345 void JSONNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
1346   if (const FieldDecl *FD = ILE->getInitializedFieldInUnion())
1347     JOS.attribute("field", createBareDeclRef(FD));
1348 }
1349 
1350 void JSONNodeDumper::VisitGenericSelectionExpr(
1351     const GenericSelectionExpr *GSE) {
1352   attributeOnlyIfTrue("resultDependent", GSE->isResultDependent());
1353 }
1354 
1355 void JSONNodeDumper::VisitCXXUnresolvedConstructExpr(
1356     const CXXUnresolvedConstructExpr *UCE) {
1357   if (UCE->getType() != UCE->getTypeAsWritten())
1358     JOS.attribute("typeAsWritten", createQualType(UCE->getTypeAsWritten()));
1359   attributeOnlyIfTrue("list", UCE->isListInitialization());
1360 }
1361 
1362 void JSONNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *CE) {
1363   CXXConstructorDecl *Ctor = CE->getConstructor();
1364   JOS.attribute("ctorType", createQualType(Ctor->getType()));
1365   attributeOnlyIfTrue("elidable", CE->isElidable());
1366   attributeOnlyIfTrue("list", CE->isListInitialization());
1367   attributeOnlyIfTrue("initializer_list", CE->isStdInitListInitialization());
1368   attributeOnlyIfTrue("zeroing", CE->requiresZeroInitialization());
1369   attributeOnlyIfTrue("hadMultipleCandidates", CE->hadMultipleCandidates());
1370 
1371   switch (CE->getConstructionKind()) {
1372   case CXXConstructExpr::CK_Complete:
1373     JOS.attribute("constructionKind", "complete");
1374     break;
1375   case CXXConstructExpr::CK_Delegating:
1376     JOS.attribute("constructionKind", "delegating");
1377     break;
1378   case CXXConstructExpr::CK_NonVirtualBase:
1379     JOS.attribute("constructionKind", "non-virtual base");
1380     break;
1381   case CXXConstructExpr::CK_VirtualBase:
1382     JOS.attribute("constructionKind", "virtual base");
1383     break;
1384   }
1385 }
1386 
1387 void JSONNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *EWC) {
1388   attributeOnlyIfTrue("cleanupsHaveSideEffects",
1389                       EWC->cleanupsHaveSideEffects());
1390   if (EWC->getNumObjects()) {
1391     JOS.attributeArray("cleanups", [this, EWC] {
1392       for (const ExprWithCleanups::CleanupObject &CO : EWC->getObjects())
1393         if (auto *BD = CO.dyn_cast<BlockDecl *>()) {
1394           JOS.value(createBareDeclRef(BD));
1395         } else if (auto *CLE = CO.dyn_cast<CompoundLiteralExpr *>()) {
1396           llvm::json::Object Obj;
1397           Obj["id"] = createPointerRepresentation(CLE);
1398           Obj["kind"] = CLE->getStmtClassName();
1399           JOS.value(std::move(Obj));
1400         } else {
1401           llvm_unreachable("unexpected cleanup object type");
1402         }
1403     });
1404   }
1405 }
1406 
1407 void JSONNodeDumper::VisitCXXBindTemporaryExpr(
1408     const CXXBindTemporaryExpr *BTE) {
1409   const CXXTemporary *Temp = BTE->getTemporary();
1410   JOS.attribute("temp", createPointerRepresentation(Temp));
1411   if (const CXXDestructorDecl *Dtor = Temp->getDestructor())
1412     JOS.attribute("dtor", createBareDeclRef(Dtor));
1413 }
1414 
1415 void JSONNodeDumper::VisitMaterializeTemporaryExpr(
1416     const MaterializeTemporaryExpr *MTE) {
1417   if (const ValueDecl *VD = MTE->getExtendingDecl())
1418     JOS.attribute("extendingDecl", createBareDeclRef(VD));
1419 
1420   switch (MTE->getStorageDuration()) {
1421   case SD_Automatic:
1422     JOS.attribute("storageDuration", "automatic");
1423     break;
1424   case SD_Dynamic:
1425     JOS.attribute("storageDuration", "dynamic");
1426     break;
1427   case SD_FullExpression:
1428     JOS.attribute("storageDuration", "full expression");
1429     break;
1430   case SD_Static:
1431     JOS.attribute("storageDuration", "static");
1432     break;
1433   case SD_Thread:
1434     JOS.attribute("storageDuration", "thread");
1435     break;
1436   }
1437 
1438   attributeOnlyIfTrue("boundToLValueRef", MTE->isBoundToLvalueReference());
1439 }
1440 
1441 void JSONNodeDumper::VisitCXXDependentScopeMemberExpr(
1442     const CXXDependentScopeMemberExpr *DSME) {
1443   JOS.attribute("isArrow", DSME->isArrow());
1444   JOS.attribute("member", DSME->getMember().getAsString());
1445   attributeOnlyIfTrue("hasTemplateKeyword", DSME->hasTemplateKeyword());
1446   attributeOnlyIfTrue("hasExplicitTemplateArgs",
1447                       DSME->hasExplicitTemplateArgs());
1448 
1449   if (DSME->getNumTemplateArgs()) {
1450     JOS.attributeArray("explicitTemplateArgs", [DSME, this] {
1451       for (const TemplateArgumentLoc &TAL : DSME->template_arguments())
1452         JOS.object(
1453             [&TAL, this] { Visit(TAL.getArgument(), TAL.getSourceRange()); });
1454     });
1455   }
1456 }
1457 
1458 void JSONNodeDumper::VisitRequiresExpr(const RequiresExpr *RE) {
1459   if (!RE->isValueDependent())
1460     JOS.attribute("satisfied", RE->isSatisfied());
1461 }
1462 
1463 void JSONNodeDumper::VisitIntegerLiteral(const IntegerLiteral *IL) {
1464   llvm::SmallString<16> Buffer;
1465   IL->getValue().toString(Buffer,
1466                           /*Radix=*/10, IL->getType()->isSignedIntegerType());
1467   JOS.attribute("value", Buffer);
1468 }
1469 void JSONNodeDumper::VisitCharacterLiteral(const CharacterLiteral *CL) {
1470   // FIXME: This should probably print the character literal as a string,
1471   // rather than as a numerical value. It would be nice if the behavior matched
1472   // what we do to print a string literal; right now, it is impossible to tell
1473   // the difference between 'a' and L'a' in C from the JSON output.
1474   JOS.attribute("value", CL->getValue());
1475 }
1476 void JSONNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *FPL) {
1477   JOS.attribute("value", FPL->getValueAsString(/*Radix=*/10));
1478 }
1479 void JSONNodeDumper::VisitFloatingLiteral(const FloatingLiteral *FL) {
1480   llvm::SmallString<16> Buffer;
1481   FL->getValue().toString(Buffer);
1482   JOS.attribute("value", Buffer);
1483 }
1484 void JSONNodeDumper::VisitStringLiteral(const StringLiteral *SL) {
1485   std::string Buffer;
1486   llvm::raw_string_ostream SS(Buffer);
1487   SL->outputString(SS);
1488   JOS.attribute("value", SS.str());
1489 }
1490 void JSONNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *BLE) {
1491   JOS.attribute("value", BLE->getValue());
1492 }
1493 
1494 void JSONNodeDumper::VisitIfStmt(const IfStmt *IS) {
1495   attributeOnlyIfTrue("hasInit", IS->hasInitStorage());
1496   attributeOnlyIfTrue("hasVar", IS->hasVarStorage());
1497   attributeOnlyIfTrue("hasElse", IS->hasElseStorage());
1498   attributeOnlyIfTrue("isConstexpr", IS->isConstexpr());
1499   attributeOnlyIfTrue("isConsteval", IS->isConsteval());
1500   attributeOnlyIfTrue("constevalIsNegated", IS->isNegatedConsteval());
1501 }
1502 
1503 void JSONNodeDumper::VisitSwitchStmt(const SwitchStmt *SS) {
1504   attributeOnlyIfTrue("hasInit", SS->hasInitStorage());
1505   attributeOnlyIfTrue("hasVar", SS->hasVarStorage());
1506 }
1507 void JSONNodeDumper::VisitCaseStmt(const CaseStmt *CS) {
1508   attributeOnlyIfTrue("isGNURange", CS->caseStmtIsGNURange());
1509 }
1510 
1511 void JSONNodeDumper::VisitLabelStmt(const LabelStmt *LS) {
1512   JOS.attribute("name", LS->getName());
1513   JOS.attribute("declId", createPointerRepresentation(LS->getDecl()));
1514   attributeOnlyIfTrue("sideEntry", LS->isSideEntry());
1515 }
1516 void JSONNodeDumper::VisitGotoStmt(const GotoStmt *GS) {
1517   JOS.attribute("targetLabelDeclId",
1518                 createPointerRepresentation(GS->getLabel()));
1519 }
1520 
1521 void JSONNodeDumper::VisitWhileStmt(const WhileStmt *WS) {
1522   attributeOnlyIfTrue("hasVar", WS->hasVarStorage());
1523 }
1524 
1525 void JSONNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt* OACS) {
1526   // FIXME: it would be nice for the ASTNodeTraverser would handle the catch
1527   // parameter the same way for C++ and ObjC rather. In this case, C++ gets a
1528   // null child node and ObjC gets no child node.
1529   attributeOnlyIfTrue("isCatchAll", OACS->getCatchParamDecl() == nullptr);
1530 }
1531 
1532 void JSONNodeDumper::VisitNullTemplateArgument(const TemplateArgument &TA) {
1533   JOS.attribute("isNull", true);
1534 }
1535 void JSONNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
1536   JOS.attribute("type", createQualType(TA.getAsType()));
1537 }
1538 void JSONNodeDumper::VisitDeclarationTemplateArgument(
1539     const TemplateArgument &TA) {
1540   JOS.attribute("decl", createBareDeclRef(TA.getAsDecl()));
1541 }
1542 void JSONNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA) {
1543   JOS.attribute("isNullptr", true);
1544 }
1545 void JSONNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
1546   JOS.attribute("value", TA.getAsIntegral().getSExtValue());
1547 }
1548 void JSONNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
1549   // FIXME: cannot just call dump() on the argument, as that doesn't specify
1550   // the output format.
1551 }
1552 void JSONNodeDumper::VisitTemplateExpansionTemplateArgument(
1553     const TemplateArgument &TA) {
1554   // FIXME: cannot just call dump() on the argument, as that doesn't specify
1555   // the output format.
1556 }
1557 void JSONNodeDumper::VisitExpressionTemplateArgument(
1558     const TemplateArgument &TA) {
1559   JOS.attribute("isExpr", true);
1560 }
1561 void JSONNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) {
1562   JOS.attribute("isPack", true);
1563 }
1564 
1565 StringRef JSONNodeDumper::getCommentCommandName(unsigned CommandID) const {
1566   if (Traits)
1567     return Traits->getCommandInfo(CommandID)->Name;
1568   if (const comments::CommandInfo *Info =
1569           comments::CommandTraits::getBuiltinCommandInfo(CommandID))
1570     return Info->Name;
1571   return "<invalid>";
1572 }
1573 
1574 void JSONNodeDumper::visitTextComment(const comments::TextComment *C,
1575                                       const comments::FullComment *) {
1576   JOS.attribute("text", C->getText());
1577 }
1578 
1579 void JSONNodeDumper::visitInlineCommandComment(
1580     const comments::InlineCommandComment *C, const comments::FullComment *) {
1581   JOS.attribute("name", getCommentCommandName(C->getCommandID()));
1582 
1583   switch (C->getRenderKind()) {
1584   case comments::InlineCommandComment::RenderNormal:
1585     JOS.attribute("renderKind", "normal");
1586     break;
1587   case comments::InlineCommandComment::RenderBold:
1588     JOS.attribute("renderKind", "bold");
1589     break;
1590   case comments::InlineCommandComment::RenderEmphasized:
1591     JOS.attribute("renderKind", "emphasized");
1592     break;
1593   case comments::InlineCommandComment::RenderMonospaced:
1594     JOS.attribute("renderKind", "monospaced");
1595     break;
1596   case comments::InlineCommandComment::RenderAnchor:
1597     JOS.attribute("renderKind", "anchor");
1598     break;
1599   }
1600 
1601   llvm::json::Array Args;
1602   for (unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
1603     Args.push_back(C->getArgText(I));
1604 
1605   if (!Args.empty())
1606     JOS.attribute("args", std::move(Args));
1607 }
1608 
1609 void JSONNodeDumper::visitHTMLStartTagComment(
1610     const comments::HTMLStartTagComment *C, const comments::FullComment *) {
1611   JOS.attribute("name", C->getTagName());
1612   attributeOnlyIfTrue("selfClosing", C->isSelfClosing());
1613   attributeOnlyIfTrue("malformed", C->isMalformed());
1614 
1615   llvm::json::Array Attrs;
1616   for (unsigned I = 0, E = C->getNumAttrs(); I < E; ++I)
1617     Attrs.push_back(
1618         {{"name", C->getAttr(I).Name}, {"value", C->getAttr(I).Value}});
1619 
1620   if (!Attrs.empty())
1621     JOS.attribute("attrs", std::move(Attrs));
1622 }
1623 
1624 void JSONNodeDumper::visitHTMLEndTagComment(
1625     const comments::HTMLEndTagComment *C, const comments::FullComment *) {
1626   JOS.attribute("name", C->getTagName());
1627 }
1628 
1629 void JSONNodeDumper::visitBlockCommandComment(
1630     const comments::BlockCommandComment *C, const comments::FullComment *) {
1631   JOS.attribute("name", getCommentCommandName(C->getCommandID()));
1632 
1633   llvm::json::Array Args;
1634   for (unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
1635     Args.push_back(C->getArgText(I));
1636 
1637   if (!Args.empty())
1638     JOS.attribute("args", std::move(Args));
1639 }
1640 
1641 void JSONNodeDumper::visitParamCommandComment(
1642     const comments::ParamCommandComment *C, const comments::FullComment *FC) {
1643   switch (C->getDirection()) {
1644   case comments::ParamCommandComment::In:
1645     JOS.attribute("direction", "in");
1646     break;
1647   case comments::ParamCommandComment::Out:
1648     JOS.attribute("direction", "out");
1649     break;
1650   case comments::ParamCommandComment::InOut:
1651     JOS.attribute("direction", "in,out");
1652     break;
1653   }
1654   attributeOnlyIfTrue("explicit", C->isDirectionExplicit());
1655 
1656   if (C->hasParamName())
1657     JOS.attribute("param", C->isParamIndexValid() ? C->getParamName(FC)
1658                                                   : C->getParamNameAsWritten());
1659 
1660   if (C->isParamIndexValid() && !C->isVarArgParam())
1661     JOS.attribute("paramIdx", C->getParamIndex());
1662 }
1663 
1664 void JSONNodeDumper::visitTParamCommandComment(
1665     const comments::TParamCommandComment *C, const comments::FullComment *FC) {
1666   if (C->hasParamName())
1667     JOS.attribute("param", C->isPositionValid() ? C->getParamName(FC)
1668                                                 : C->getParamNameAsWritten());
1669   if (C->isPositionValid()) {
1670     llvm::json::Array Positions;
1671     for (unsigned I = 0, E = C->getDepth(); I < E; ++I)
1672       Positions.push_back(C->getIndex(I));
1673 
1674     if (!Positions.empty())
1675       JOS.attribute("positions", std::move(Positions));
1676   }
1677 }
1678 
1679 void JSONNodeDumper::visitVerbatimBlockComment(
1680     const comments::VerbatimBlockComment *C, const comments::FullComment *) {
1681   JOS.attribute("name", getCommentCommandName(C->getCommandID()));
1682   JOS.attribute("closeName", C->getCloseName());
1683 }
1684 
1685 void JSONNodeDumper::visitVerbatimBlockLineComment(
1686     const comments::VerbatimBlockLineComment *C,
1687     const comments::FullComment *) {
1688   JOS.attribute("text", C->getText());
1689 }
1690 
1691 void JSONNodeDumper::visitVerbatimLineComment(
1692     const comments::VerbatimLineComment *C, const comments::FullComment *) {
1693   JOS.attribute("text", C->getText());
1694 }
1695 
1696 llvm::json::Object JSONNodeDumper::createFPOptions(FPOptionsOverride FPO) {
1697   llvm::json::Object Ret;
1698 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS)                                    \
1699   if (FPO.has##NAME##Override())                                               \
1700     Ret.try_emplace(#NAME, static_cast<unsigned>(FPO.get##NAME##Override()));
1701 #include "clang/Basic/FPOptions.def"
1702   return Ret;
1703 }
1704 
1705 void JSONNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
1706   VisitStmt(S);
1707   if (S->hasStoredFPFeatures())
1708     JOS.attribute("fpoptions", createFPOptions(S->getStoredFPFeatures()));
1709 }
1710