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