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