12ce598a4SAaron Ballman #include "clang/AST/JSONNodeDumper.h"
286565c13SReid Kleckner #include "clang/Basic/SourceManager.h"
36407aa9dSDaniel Martín #include "clang/Basic/Specifiers.h"
4a612e34cSAaron Ballman #include "clang/Lex/Lexer.h"
52ce598a4SAaron Ballman #include "llvm/ADT/StringSwitch.h"
62ce598a4SAaron Ballman
72ce598a4SAaron Ballman using namespace clang;
82ce598a4SAaron Ballman
addPreviousDeclaration(const Decl * D)92ce598a4SAaron Ballman void JSONNodeDumper::addPreviousDeclaration(const Decl *D) {
102ce598a4SAaron Ballman switch (D->getKind()) {
112ce598a4SAaron Ballman #define DECL(DERIVED, BASE) \
122ce598a4SAaron Ballman case Decl::DERIVED: \
132ce598a4SAaron Ballman return writePreviousDeclImpl(cast<DERIVED##Decl>(D));
142ce598a4SAaron Ballman #define ABSTRACT_DECL(DECL)
152ce598a4SAaron Ballman #include "clang/AST/DeclNodes.inc"
162ce598a4SAaron Ballman #undef ABSTRACT_DECL
172ce598a4SAaron Ballman #undef DECL
182ce598a4SAaron Ballman }
192ce598a4SAaron Ballman llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
202ce598a4SAaron Ballman }
212ce598a4SAaron Ballman
Visit(const Attr * A)222ce598a4SAaron Ballman void JSONNodeDumper::Visit(const Attr *A) {
232ce598a4SAaron Ballman const char *AttrName = nullptr;
242ce598a4SAaron Ballman switch (A->getKind()) {
252ce598a4SAaron Ballman #define ATTR(X) \
262ce598a4SAaron Ballman case attr::X: \
272ce598a4SAaron Ballman AttrName = #X"Attr"; \
282ce598a4SAaron Ballman break;
292ce598a4SAaron Ballman #include "clang/Basic/AttrList.inc"
302ce598a4SAaron Ballman #undef ATTR
312ce598a4SAaron Ballman }
322ce598a4SAaron Ballman JOS.attribute("id", createPointerRepresentation(A));
332ce598a4SAaron Ballman JOS.attribute("kind", AttrName);
34a612e34cSAaron Ballman JOS.attributeObject("range", [A, this] { writeSourceRange(A->getRange()); });
352ce598a4SAaron Ballman attributeOnlyIfTrue("inherited", A->isInherited());
362ce598a4SAaron Ballman attributeOnlyIfTrue("implicit", A->isImplicit());
372ce598a4SAaron Ballman
382ce598a4SAaron Ballman // FIXME: it would be useful for us to output the spelling kind as well as
392ce598a4SAaron Ballman // the actual spelling. This would allow us to distinguish between the
402ce598a4SAaron Ballman // various attribute syntaxes, but we don't currently track that information
412ce598a4SAaron Ballman // within the AST.
422ce598a4SAaron Ballman //JOS.attribute("spelling", A->getSpelling());
432ce598a4SAaron Ballman
442ce598a4SAaron Ballman InnerAttrVisitor::Visit(A);
452ce598a4SAaron Ballman }
462ce598a4SAaron Ballman
Visit(const Stmt * S)472ce598a4SAaron Ballman void JSONNodeDumper::Visit(const Stmt *S) {
482ce598a4SAaron Ballman if (!S)
492ce598a4SAaron Ballman return;
502ce598a4SAaron Ballman
512ce598a4SAaron Ballman JOS.attribute("id", createPointerRepresentation(S));
522ce598a4SAaron Ballman JOS.attribute("kind", S->getStmtClassName());
53a612e34cSAaron Ballman JOS.attributeObject("range",
54a612e34cSAaron Ballman [S, this] { writeSourceRange(S->getSourceRange()); });
552ce598a4SAaron Ballman
562ce598a4SAaron Ballman if (const auto *E = dyn_cast<Expr>(S)) {
572ce598a4SAaron Ballman JOS.attribute("type", createQualType(E->getType()));
582ce598a4SAaron Ballman const char *Category = nullptr;
592ce598a4SAaron Ballman switch (E->getValueKind()) {
602ce598a4SAaron Ballman case VK_LValue: Category = "lvalue"; break;
612ce598a4SAaron Ballman case VK_XValue: Category = "xvalue"; break;
62aef5d8fdSMatheus Izvekov case VK_PRValue:
63aef5d8fdSMatheus Izvekov Category = "prvalue";
64aef5d8fdSMatheus Izvekov break;
652ce598a4SAaron Ballman }
662ce598a4SAaron Ballman JOS.attribute("valueCategory", Category);
672ce598a4SAaron Ballman }
682ce598a4SAaron Ballman InnerStmtVisitor::Visit(S);
692ce598a4SAaron Ballman }
702ce598a4SAaron Ballman
Visit(const Type * T)712ce598a4SAaron Ballman void JSONNodeDumper::Visit(const Type *T) {
722ce598a4SAaron Ballman JOS.attribute("id", createPointerRepresentation(T));
7317556172SAaron Ballman
7417556172SAaron Ballman if (!T)
7517556172SAaron Ballman return;
7617556172SAaron Ballman
772ce598a4SAaron Ballman JOS.attribute("kind", (llvm::Twine(T->getTypeClassName()) + "Type").str());
782ce598a4SAaron Ballman JOS.attribute("type", createQualType(QualType(T, 0), /*Desugar*/ false));
79493d8059SHaojian Wu attributeOnlyIfTrue("containsErrors", T->containsErrors());
802ce598a4SAaron Ballman attributeOnlyIfTrue("isDependent", T->isDependentType());
812ce598a4SAaron Ballman attributeOnlyIfTrue("isInstantiationDependent",
822ce598a4SAaron Ballman T->isInstantiationDependentType());
832ce598a4SAaron Ballman attributeOnlyIfTrue("isVariablyModified", T->isVariablyModifiedType());
842ce598a4SAaron Ballman attributeOnlyIfTrue("containsUnexpandedPack",
852ce598a4SAaron Ballman T->containsUnexpandedParameterPack());
862ce598a4SAaron Ballman attributeOnlyIfTrue("isImported", T->isFromAST());
872ce598a4SAaron Ballman InnerTypeVisitor::Visit(T);
882ce598a4SAaron Ballman }
892ce598a4SAaron Ballman
Visit(QualType T)902ce598a4SAaron Ballman void JSONNodeDumper::Visit(QualType T) {
912ce598a4SAaron Ballman JOS.attribute("id", createPointerRepresentation(T.getAsOpaquePtr()));
924c9def4aSAaron Ballman JOS.attribute("kind", "QualType");
932ce598a4SAaron Ballman JOS.attribute("type", createQualType(T));
942ce598a4SAaron Ballman JOS.attribute("qualifiers", T.split().Quals.getAsString());
952ce598a4SAaron Ballman }
962ce598a4SAaron Ballman
Visit(const Decl * D)972ce598a4SAaron Ballman void JSONNodeDumper::Visit(const Decl *D) {
982ce598a4SAaron Ballman JOS.attribute("id", createPointerRepresentation(D));
992ce598a4SAaron Ballman
1002ce598a4SAaron Ballman if (!D)
1012ce598a4SAaron Ballman return;
1022ce598a4SAaron Ballman
1032ce598a4SAaron Ballman JOS.attribute("kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str());
104a612e34cSAaron Ballman JOS.attributeObject("loc",
105a612e34cSAaron Ballman [D, this] { writeSourceLocation(D->getLocation()); });
106a612e34cSAaron Ballman JOS.attributeObject("range",
107a612e34cSAaron Ballman [D, this] { writeSourceRange(D->getSourceRange()); });
1082ce598a4SAaron Ballman attributeOnlyIfTrue("isImplicit", D->isImplicit());
1092ce598a4SAaron Ballman attributeOnlyIfTrue("isInvalid", D->isInvalidDecl());
1102ce598a4SAaron Ballman
1112ce598a4SAaron Ballman if (D->isUsed())
1122ce598a4SAaron Ballman JOS.attribute("isUsed", true);
1132ce598a4SAaron Ballman else if (D->isThisDeclarationReferenced())
1142ce598a4SAaron Ballman JOS.attribute("isReferenced", true);
1152ce598a4SAaron Ballman
1162ce598a4SAaron Ballman if (const auto *ND = dyn_cast<NamedDecl>(D))
1172e92b397SMartin Boehme attributeOnlyIfTrue("isHidden", !ND->isUnconditionallyVisible());
1182ce598a4SAaron Ballman
11940e37604SAaron Ballman if (D->getLexicalDeclContext() != D->getDeclContext()) {
12040e37604SAaron Ballman // Because of multiple inheritance, a DeclContext pointer does not produce
12140e37604SAaron Ballman // the same pointer representation as a Decl pointer that references the
12240e37604SAaron Ballman // same AST Node.
12340e37604SAaron Ballman const auto *ParentDeclContextDecl = dyn_cast<Decl>(D->getDeclContext());
12440e37604SAaron Ballman JOS.attribute("parentDeclContextId",
12540e37604SAaron Ballman createPointerRepresentation(ParentDeclContextDecl));
12640e37604SAaron Ballman }
1272ce598a4SAaron Ballman
1282ce598a4SAaron Ballman addPreviousDeclaration(D);
1292ce598a4SAaron Ballman InnerDeclVisitor::Visit(D);
1302ce598a4SAaron Ballman }
1312ce598a4SAaron Ballman
Visit(const comments::Comment * C,const comments::FullComment * FC)1322ce598a4SAaron Ballman void JSONNodeDumper::Visit(const comments::Comment *C,
13386abee81SAaron Ballman const comments::FullComment *FC) {
13486abee81SAaron Ballman if (!C)
13586abee81SAaron Ballman return;
13686abee81SAaron Ballman
13786abee81SAaron Ballman JOS.attribute("id", createPointerRepresentation(C));
13886abee81SAaron Ballman JOS.attribute("kind", C->getCommentKindName());
139a612e34cSAaron Ballman JOS.attributeObject("loc",
140a612e34cSAaron Ballman [C, this] { writeSourceLocation(C->getLocation()); });
141a612e34cSAaron Ballman JOS.attributeObject("range",
142a612e34cSAaron Ballman [C, this] { writeSourceRange(C->getSourceRange()); });
14386abee81SAaron Ballman
14486abee81SAaron Ballman InnerCommentVisitor::visit(C, FC);
14586abee81SAaron Ballman }
1462ce598a4SAaron Ballman
Visit(const TemplateArgument & TA,SourceRange R,const Decl * From,StringRef Label)1472ce598a4SAaron Ballman void JSONNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
1482ce598a4SAaron Ballman const Decl *From, StringRef Label) {
1492ce598a4SAaron Ballman JOS.attribute("kind", "TemplateArgument");
1502ce598a4SAaron Ballman if (R.isValid())
151a612e34cSAaron Ballman JOS.attributeObject("range", [R, this] { writeSourceRange(R); });
1522ce598a4SAaron Ballman
1532ce598a4SAaron Ballman if (From)
1542ce598a4SAaron Ballman JOS.attribute(Label.empty() ? "fromDecl" : Label, createBareDeclRef(From));
1552ce598a4SAaron Ballman
1562ce598a4SAaron Ballman InnerTemplateArgVisitor::Visit(TA);
1572ce598a4SAaron Ballman }
1582ce598a4SAaron Ballman
Visit(const CXXCtorInitializer * Init)1592ce598a4SAaron Ballman void JSONNodeDumper::Visit(const CXXCtorInitializer *Init) {
1602ce598a4SAaron Ballman JOS.attribute("kind", "CXXCtorInitializer");
1612ce598a4SAaron Ballman if (Init->isAnyMemberInitializer())
1622ce598a4SAaron Ballman JOS.attribute("anyInit", createBareDeclRef(Init->getAnyMember()));
1632ce598a4SAaron Ballman else if (Init->isBaseInitializer())
1642ce598a4SAaron Ballman JOS.attribute("baseInit",
1652ce598a4SAaron Ballman createQualType(QualType(Init->getBaseClass(), 0)));
1662ce598a4SAaron Ballman else if (Init->isDelegatingInitializer())
1672ce598a4SAaron Ballman JOS.attribute("delegatingInit",
1682ce598a4SAaron Ballman createQualType(Init->getTypeSourceInfo()->getType()));
1692ce598a4SAaron Ballman else
1702ce598a4SAaron Ballman llvm_unreachable("Unknown initializer type");
1712ce598a4SAaron Ballman }
1722ce598a4SAaron Ballman
Visit(const OMPClause * C)1732ce598a4SAaron Ballman void JSONNodeDumper::Visit(const OMPClause *C) {}
1744105882bSAaron Ballman
Visit(const BlockDecl::Capture & C)1754105882bSAaron Ballman void JSONNodeDumper::Visit(const BlockDecl::Capture &C) {
1764105882bSAaron Ballman JOS.attribute("kind", "Capture");
1774105882bSAaron Ballman attributeOnlyIfTrue("byref", C.isByRef());
1784105882bSAaron Ballman attributeOnlyIfTrue("nested", C.isNested());
1794105882bSAaron Ballman if (C.getVariable())
1804105882bSAaron Ballman JOS.attribute("var", createBareDeclRef(C.getVariable()));
1814105882bSAaron Ballman }
1824105882bSAaron Ballman
Visit(const GenericSelectionExpr::ConstAssociation & A)1832ce598a4SAaron Ballman void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
1842ce598a4SAaron Ballman JOS.attribute("associationKind", A.getTypeSourceInfo() ? "case" : "default");
1852ce598a4SAaron Ballman attributeOnlyIfTrue("selected", A.isSelected());
1862ce598a4SAaron Ballman }
1872ce598a4SAaron Ballman
Visit(const concepts::Requirement * R)188ef227b32SRichard Smith void JSONNodeDumper::Visit(const concepts::Requirement *R) {
189ef227b32SRichard Smith if (!R)
190ef227b32SRichard Smith return;
191ef227b32SRichard Smith
192ef227b32SRichard Smith switch (R->getKind()) {
193ef227b32SRichard Smith case concepts::Requirement::RK_Type:
194ef227b32SRichard Smith JOS.attribute("kind", "TypeRequirement");
195ef227b32SRichard Smith break;
196ef227b32SRichard Smith case concepts::Requirement::RK_Simple:
197ef227b32SRichard Smith JOS.attribute("kind", "SimpleRequirement");
198ef227b32SRichard Smith break;
199ef227b32SRichard Smith case concepts::Requirement::RK_Compound:
200ef227b32SRichard Smith JOS.attribute("kind", "CompoundRequirement");
201ef227b32SRichard Smith break;
202ef227b32SRichard Smith case concepts::Requirement::RK_Nested:
203ef227b32SRichard Smith JOS.attribute("kind", "NestedRequirement");
204ef227b32SRichard Smith break;
205ef227b32SRichard Smith }
206ef227b32SRichard Smith
207ef227b32SRichard Smith if (auto *ER = dyn_cast<concepts::ExprRequirement>(R))
208ef227b32SRichard Smith attributeOnlyIfTrue("noexcept", ER->hasNoexceptRequirement());
209ef227b32SRichard Smith
210ef227b32SRichard Smith attributeOnlyIfTrue("isDependent", R->isDependent());
211ef227b32SRichard Smith if (!R->isDependent())
212ef227b32SRichard Smith JOS.attribute("satisfied", R->isSatisfied());
213ef227b32SRichard Smith attributeOnlyIfTrue("containsUnexpandedPack",
214ef227b32SRichard Smith R->containsUnexpandedParameterPack());
215ef227b32SRichard Smith }
216ef227b32SRichard Smith
Visit(const APValue & Value,QualType Ty)217f63e3ea5SBruno Ricci void JSONNodeDumper::Visit(const APValue &Value, QualType Ty) {
218f63e3ea5SBruno Ricci std::string Str;
219f63e3ea5SBruno Ricci llvm::raw_string_ostream OS(Str);
220f63e3ea5SBruno Ricci Value.printPretty(OS, Ctx, Ty);
221f63e3ea5SBruno Ricci JOS.attribute("value", OS.str());
222f63e3ea5SBruno Ricci }
223f63e3ea5SBruno Ricci
writeIncludeStack(PresumedLoc Loc,bool JustFirst)22427c7a9b1SAaron Ballman void JSONNodeDumper::writeIncludeStack(PresumedLoc Loc, bool JustFirst) {
22527c7a9b1SAaron Ballman if (Loc.isInvalid())
22627c7a9b1SAaron Ballman return;
22727c7a9b1SAaron Ballman
22827c7a9b1SAaron Ballman JOS.attributeBegin("includedFrom");
22927c7a9b1SAaron Ballman JOS.objectBegin();
23027c7a9b1SAaron Ballman
23127c7a9b1SAaron Ballman if (!JustFirst) {
23227c7a9b1SAaron Ballman // Walk the stack recursively, then print out the presumed location.
23327c7a9b1SAaron Ballman writeIncludeStack(SM.getPresumedLoc(Loc.getIncludeLoc()));
23427c7a9b1SAaron Ballman }
23527c7a9b1SAaron Ballman
23627c7a9b1SAaron Ballman JOS.attribute("file", Loc.getFilename());
23727c7a9b1SAaron Ballman JOS.objectEnd();
23827c7a9b1SAaron Ballman JOS.attributeEnd();
23927c7a9b1SAaron Ballman }
24027c7a9b1SAaron Ballman
writeBareSourceLocation(SourceLocation Loc,bool IsSpelling)241352f0a22SAaron Ballman void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc,
242352f0a22SAaron Ballman bool IsSpelling) {
2434d05a974SAaron Ballman PresumedLoc Presumed = SM.getPresumedLoc(Loc);
244352f0a22SAaron Ballman unsigned ActualLine = IsSpelling ? SM.getSpellingLineNumber(Loc)
245352f0a22SAaron Ballman : SM.getExpansionLineNumber(Loc);
246fa6c157eSAaron Ballman StringRef ActualFile = SM.getBufferName(Loc);
247fa6c157eSAaron Ballman
248a612e34cSAaron Ballman if (Presumed.isValid()) {
24927c7a9b1SAaron Ballman JOS.attribute("offset", SM.getDecomposedLoc(Loc).second);
250fa6c157eSAaron Ballman if (LastLocFilename != ActualFile) {
251fa6c157eSAaron Ballman JOS.attribute("file", ActualFile);
252352f0a22SAaron Ballman JOS.attribute("line", ActualLine);
253352f0a22SAaron Ballman } else if (LastLocLine != ActualLine)
254352f0a22SAaron Ballman JOS.attribute("line", ActualLine);
255352f0a22SAaron Ballman
256fa6c157eSAaron Ballman StringRef PresumedFile = Presumed.getFilename();
257fa6c157eSAaron Ballman if (PresumedFile != ActualFile && LastLocPresumedFilename != PresumedFile)
258fa6c157eSAaron Ballman JOS.attribute("presumedFile", PresumedFile);
259fa6c157eSAaron Ballman
260352f0a22SAaron Ballman unsigned PresumedLine = Presumed.getLine();
261352f0a22SAaron Ballman if (ActualLine != PresumedLine && LastLocPresumedLine != PresumedLine)
262352f0a22SAaron Ballman JOS.attribute("presumedLine", PresumedLine);
263352f0a22SAaron Ballman
264a612e34cSAaron Ballman JOS.attribute("col", Presumed.getColumn());
265a612e34cSAaron Ballman JOS.attribute("tokLen",
266a612e34cSAaron Ballman Lexer::MeasureTokenLength(Loc, SM, Ctx.getLangOpts()));
267fa6c157eSAaron Ballman LastLocFilename = ActualFile;
268fa6c157eSAaron Ballman LastLocPresumedFilename = PresumedFile;
269352f0a22SAaron Ballman LastLocPresumedLine = PresumedLine;
270352f0a22SAaron Ballman LastLocLine = ActualLine;
27127c7a9b1SAaron Ballman
27227c7a9b1SAaron Ballman // Orthogonal to the file, line, and column de-duplication is whether the
27327c7a9b1SAaron Ballman // given location was a result of an include. If so, print where the
27427c7a9b1SAaron Ballman // include location came from.
27527c7a9b1SAaron Ballman writeIncludeStack(SM.getPresumedLoc(Presumed.getIncludeLoc()),
27627c7a9b1SAaron Ballman /*JustFirst*/ true);
277a612e34cSAaron Ballman }
2782ce598a4SAaron Ballman }
2792ce598a4SAaron Ballman
writeSourceLocation(SourceLocation Loc)280a612e34cSAaron Ballman void JSONNodeDumper::writeSourceLocation(SourceLocation Loc) {
2814d05a974SAaron Ballman SourceLocation Spelling = SM.getSpellingLoc(Loc);
2824d05a974SAaron Ballman SourceLocation Expansion = SM.getExpansionLoc(Loc);
2834d05a974SAaron Ballman
2844d05a974SAaron Ballman if (Expansion != Spelling) {
2854d05a974SAaron Ballman // If the expansion and the spelling are different, output subobjects
2864d05a974SAaron Ballman // describing both locations.
287352f0a22SAaron Ballman JOS.attributeObject("spellingLoc", [Spelling, this] {
288352f0a22SAaron Ballman writeBareSourceLocation(Spelling, /*IsSpelling*/ true);
289352f0a22SAaron Ballman });
290a612e34cSAaron Ballman JOS.attributeObject("expansionLoc", [Expansion, Loc, this] {
291352f0a22SAaron Ballman writeBareSourceLocation(Expansion, /*IsSpelling*/ false);
2924d05a974SAaron Ballman // If there is a macro expansion, add extra information if the interesting
2934d05a974SAaron Ballman // bit is the macro arg expansion.
2944d05a974SAaron Ballman if (SM.isMacroArgExpansion(Loc))
295a612e34cSAaron Ballman JOS.attribute("isMacroArgExpansion", true);
296a612e34cSAaron Ballman });
297a612e34cSAaron Ballman } else
298352f0a22SAaron Ballman writeBareSourceLocation(Spelling, /*IsSpelling*/ true);
2994d05a974SAaron Ballman }
3004d05a974SAaron Ballman
writeSourceRange(SourceRange R)301a612e34cSAaron Ballman void JSONNodeDumper::writeSourceRange(SourceRange R) {
302a612e34cSAaron Ballman JOS.attributeObject("begin",
303a612e34cSAaron Ballman [R, this] { writeSourceLocation(R.getBegin()); });
304a612e34cSAaron Ballman JOS.attributeObject("end", [R, this] { writeSourceLocation(R.getEnd()); });
3052ce598a4SAaron Ballman }
3062ce598a4SAaron Ballman
createPointerRepresentation(const void * Ptr)3072ce598a4SAaron Ballman std::string JSONNodeDumper::createPointerRepresentation(const void *Ptr) {
3082ce598a4SAaron Ballman // Because JSON stores integer values as signed 64-bit integers, trying to
3092ce598a4SAaron Ballman // represent them as such makes for very ugly pointer values in the resulting
3102ce598a4SAaron Ballman // output. Instead, we convert the value to hex and treat it as a string.
3112ce598a4SAaron Ballman return "0x" + llvm::utohexstr(reinterpret_cast<uint64_t>(Ptr), true);
3122ce598a4SAaron Ballman }
3132ce598a4SAaron Ballman
createQualType(QualType QT,bool Desugar)3142ce598a4SAaron Ballman llvm::json::Object JSONNodeDumper::createQualType(QualType QT, bool Desugar) {
3152ce598a4SAaron Ballman SplitQualType SQT = QT.split();
3162ce598a4SAaron Ballman llvm::json::Object Ret{{"qualType", QualType::getAsString(SQT, PrintPolicy)}};
3172ce598a4SAaron Ballman
3182ce598a4SAaron Ballman if (Desugar && !QT.isNull()) {
3192ce598a4SAaron Ballman SplitQualType DSQT = QT.getSplitDesugaredType();
3202ce598a4SAaron Ballman if (DSQT != SQT)
3212ce598a4SAaron Ballman Ret["desugaredQualType"] = QualType::getAsString(DSQT, PrintPolicy);
322d5e206eeSAaron Ballman if (const auto *TT = QT->getAs<TypedefType>())
323d5e206eeSAaron Ballman Ret["typeAliasDeclId"] = createPointerRepresentation(TT->getDecl());
3242ce598a4SAaron Ballman }
3252ce598a4SAaron Ballman return Ret;
3262ce598a4SAaron Ballman }
3272ce598a4SAaron Ballman
writeBareDeclRef(const Decl * D)3287556615aSAaron Ballman void JSONNodeDumper::writeBareDeclRef(const Decl *D) {
3297556615aSAaron Ballman JOS.attribute("id", createPointerRepresentation(D));
3307556615aSAaron Ballman if (!D)
3317556615aSAaron Ballman return;
3327556615aSAaron Ballman
3337556615aSAaron Ballman JOS.attribute("kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str());
3347556615aSAaron Ballman if (const auto *ND = dyn_cast<NamedDecl>(D))
3357556615aSAaron Ballman JOS.attribute("name", ND->getDeclName().getAsString());
3367556615aSAaron Ballman if (const auto *VD = dyn_cast<ValueDecl>(D))
3377556615aSAaron Ballman JOS.attribute("type", createQualType(VD->getType()));
3387556615aSAaron Ballman }
3397556615aSAaron Ballman
createBareDeclRef(const Decl * D)3402ce598a4SAaron Ballman llvm::json::Object JSONNodeDumper::createBareDeclRef(const Decl *D) {
3414105882bSAaron Ballman llvm::json::Object Ret{{"id", createPointerRepresentation(D)}};
3424105882bSAaron Ballman if (!D)
3434105882bSAaron Ballman return Ret;
3444105882bSAaron Ballman
3454105882bSAaron Ballman Ret["kind"] = (llvm::Twine(D->getDeclKindName()) + "Decl").str();
3462ce598a4SAaron Ballman if (const auto *ND = dyn_cast<NamedDecl>(D))
3472ce598a4SAaron Ballman Ret["name"] = ND->getDeclName().getAsString();
3482ce598a4SAaron Ballman if (const auto *VD = dyn_cast<ValueDecl>(D))
3492ce598a4SAaron Ballman Ret["type"] = createQualType(VD->getType());
3502ce598a4SAaron Ballman return Ret;
3512ce598a4SAaron Ballman }
3522ce598a4SAaron Ballman
createCastPath(const CastExpr * C)3532ce598a4SAaron Ballman llvm::json::Array JSONNodeDumper::createCastPath(const CastExpr *C) {
3542ce598a4SAaron Ballman llvm::json::Array Ret;
3552ce598a4SAaron Ballman if (C->path_empty())
3562ce598a4SAaron Ballman return Ret;
3572ce598a4SAaron Ballman
3582ce598a4SAaron Ballman for (auto I = C->path_begin(), E = C->path_end(); I != E; ++I) {
3592ce598a4SAaron Ballman const CXXBaseSpecifier *Base = *I;
3602ce598a4SAaron Ballman const auto *RD =
3611cd399c9SSimon Pilgrim cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
3622ce598a4SAaron Ballman
3632ce598a4SAaron Ballman llvm::json::Object Val{{"name", RD->getName()}};
3642ce598a4SAaron Ballman if (Base->isVirtual())
3652ce598a4SAaron Ballman Val["isVirtual"] = true;
3662ce598a4SAaron Ballman Ret.push_back(std::move(Val));
3672ce598a4SAaron Ballman }
3682ce598a4SAaron Ballman return Ret;
3692ce598a4SAaron Ballman }
3702ce598a4SAaron Ballman
3712ce598a4SAaron Ballman #define FIELD2(Name, Flag) if (RD->Flag()) Ret[Name] = true
3722ce598a4SAaron Ballman #define FIELD1(Flag) FIELD2(#Flag, Flag)
3732ce598a4SAaron Ballman
3742ce598a4SAaron Ballman static llvm::json::Object
createDefaultConstructorDefinitionData(const CXXRecordDecl * RD)3752ce598a4SAaron Ballman createDefaultConstructorDefinitionData(const CXXRecordDecl *RD) {
3762ce598a4SAaron Ballman llvm::json::Object Ret;
3772ce598a4SAaron Ballman
3782ce598a4SAaron Ballman FIELD2("exists", hasDefaultConstructor);
3792ce598a4SAaron Ballman FIELD2("trivial", hasTrivialDefaultConstructor);
3802ce598a4SAaron Ballman FIELD2("nonTrivial", hasNonTrivialDefaultConstructor);
3812ce598a4SAaron Ballman FIELD2("userProvided", hasUserProvidedDefaultConstructor);
3822ce598a4SAaron Ballman FIELD2("isConstexpr", hasConstexprDefaultConstructor);
3832ce598a4SAaron Ballman FIELD2("needsImplicit", needsImplicitDefaultConstructor);
3842ce598a4SAaron Ballman FIELD2("defaultedIsConstexpr", defaultedDefaultConstructorIsConstexpr);
3852ce598a4SAaron Ballman
3862ce598a4SAaron Ballman return Ret;
3872ce598a4SAaron Ballman }
3882ce598a4SAaron Ballman
3892ce598a4SAaron Ballman static llvm::json::Object
createCopyConstructorDefinitionData(const CXXRecordDecl * RD)3902ce598a4SAaron Ballman createCopyConstructorDefinitionData(const CXXRecordDecl *RD) {
3912ce598a4SAaron Ballman llvm::json::Object Ret;
3922ce598a4SAaron Ballman
3932ce598a4SAaron Ballman FIELD2("simple", hasSimpleCopyConstructor);
3942ce598a4SAaron Ballman FIELD2("trivial", hasTrivialCopyConstructor);
3952ce598a4SAaron Ballman FIELD2("nonTrivial", hasNonTrivialCopyConstructor);
3962ce598a4SAaron Ballman FIELD2("userDeclared", hasUserDeclaredCopyConstructor);
3972ce598a4SAaron Ballman FIELD2("hasConstParam", hasCopyConstructorWithConstParam);
3982ce598a4SAaron Ballman FIELD2("implicitHasConstParam", implicitCopyConstructorHasConstParam);
3992ce598a4SAaron Ballman FIELD2("needsImplicit", needsImplicitCopyConstructor);
4002ce598a4SAaron Ballman FIELD2("needsOverloadResolution", needsOverloadResolutionForCopyConstructor);
4012ce598a4SAaron Ballman if (!RD->needsOverloadResolutionForCopyConstructor())
4022ce598a4SAaron Ballman FIELD2("defaultedIsDeleted", defaultedCopyConstructorIsDeleted);
4032ce598a4SAaron Ballman
4042ce598a4SAaron Ballman return Ret;
4052ce598a4SAaron Ballman }
4062ce598a4SAaron Ballman
4072ce598a4SAaron Ballman static llvm::json::Object
createMoveConstructorDefinitionData(const CXXRecordDecl * RD)4082ce598a4SAaron Ballman createMoveConstructorDefinitionData(const CXXRecordDecl *RD) {
4092ce598a4SAaron Ballman llvm::json::Object Ret;
4102ce598a4SAaron Ballman
4112ce598a4SAaron Ballman FIELD2("exists", hasMoveConstructor);
4122ce598a4SAaron Ballman FIELD2("simple", hasSimpleMoveConstructor);
4132ce598a4SAaron Ballman FIELD2("trivial", hasTrivialMoveConstructor);
4142ce598a4SAaron Ballman FIELD2("nonTrivial", hasNonTrivialMoveConstructor);
4152ce598a4SAaron Ballman FIELD2("userDeclared", hasUserDeclaredMoveConstructor);
4162ce598a4SAaron Ballman FIELD2("needsImplicit", needsImplicitMoveConstructor);
4172ce598a4SAaron Ballman FIELD2("needsOverloadResolution", needsOverloadResolutionForMoveConstructor);
4182ce598a4SAaron Ballman if (!RD->needsOverloadResolutionForMoveConstructor())
4192ce598a4SAaron Ballman FIELD2("defaultedIsDeleted", defaultedMoveConstructorIsDeleted);
4202ce598a4SAaron Ballman
4212ce598a4SAaron Ballman return Ret;
4222ce598a4SAaron Ballman }
4232ce598a4SAaron Ballman
4242ce598a4SAaron Ballman static llvm::json::Object
createCopyAssignmentDefinitionData(const CXXRecordDecl * RD)4252ce598a4SAaron Ballman createCopyAssignmentDefinitionData(const CXXRecordDecl *RD) {
4262ce598a4SAaron Ballman llvm::json::Object Ret;
4272ce598a4SAaron Ballman
428825e3bb5SRichard Smith FIELD2("simple", hasSimpleCopyAssignment);
4292ce598a4SAaron Ballman FIELD2("trivial", hasTrivialCopyAssignment);
4302ce598a4SAaron Ballman FIELD2("nonTrivial", hasNonTrivialCopyAssignment);
4312ce598a4SAaron Ballman FIELD2("hasConstParam", hasCopyAssignmentWithConstParam);
4322ce598a4SAaron Ballman FIELD2("implicitHasConstParam", implicitCopyAssignmentHasConstParam);
4332ce598a4SAaron Ballman FIELD2("userDeclared", hasUserDeclaredCopyAssignment);
4342ce598a4SAaron Ballman FIELD2("needsImplicit", needsImplicitCopyAssignment);
4352ce598a4SAaron Ballman FIELD2("needsOverloadResolution", needsOverloadResolutionForCopyAssignment);
4362ce598a4SAaron Ballman
4372ce598a4SAaron Ballman return Ret;
4382ce598a4SAaron Ballman }
4392ce598a4SAaron Ballman
4402ce598a4SAaron Ballman static llvm::json::Object
createMoveAssignmentDefinitionData(const CXXRecordDecl * RD)4412ce598a4SAaron Ballman createMoveAssignmentDefinitionData(const CXXRecordDecl *RD) {
4422ce598a4SAaron Ballman llvm::json::Object Ret;
4432ce598a4SAaron Ballman
4442ce598a4SAaron Ballman FIELD2("exists", hasMoveAssignment);
4452ce598a4SAaron Ballman FIELD2("simple", hasSimpleMoveAssignment);
4462ce598a4SAaron Ballman FIELD2("trivial", hasTrivialMoveAssignment);
4472ce598a4SAaron Ballman FIELD2("nonTrivial", hasNonTrivialMoveAssignment);
4482ce598a4SAaron Ballman FIELD2("userDeclared", hasUserDeclaredMoveAssignment);
4492ce598a4SAaron Ballman FIELD2("needsImplicit", needsImplicitMoveAssignment);
4502ce598a4SAaron Ballman FIELD2("needsOverloadResolution", needsOverloadResolutionForMoveAssignment);
4512ce598a4SAaron Ballman
4522ce598a4SAaron Ballman return Ret;
4532ce598a4SAaron Ballman }
4542ce598a4SAaron Ballman
4552ce598a4SAaron Ballman static llvm::json::Object
createDestructorDefinitionData(const CXXRecordDecl * RD)4562ce598a4SAaron Ballman createDestructorDefinitionData(const CXXRecordDecl *RD) {
4572ce598a4SAaron Ballman llvm::json::Object Ret;
4582ce598a4SAaron Ballman
4592ce598a4SAaron Ballman FIELD2("simple", hasSimpleDestructor);
4602ce598a4SAaron Ballman FIELD2("irrelevant", hasIrrelevantDestructor);
4612ce598a4SAaron Ballman FIELD2("trivial", hasTrivialDestructor);
4622ce598a4SAaron Ballman FIELD2("nonTrivial", hasNonTrivialDestructor);
4632ce598a4SAaron Ballman FIELD2("userDeclared", hasUserDeclaredDestructor);
4642ce598a4SAaron Ballman FIELD2("needsImplicit", needsImplicitDestructor);
4652ce598a4SAaron Ballman FIELD2("needsOverloadResolution", needsOverloadResolutionForDestructor);
4662ce598a4SAaron Ballman if (!RD->needsOverloadResolutionForDestructor())
4672ce598a4SAaron Ballman FIELD2("defaultedIsDeleted", defaultedDestructorIsDeleted);
4682ce598a4SAaron Ballman
4692ce598a4SAaron Ballman return Ret;
4702ce598a4SAaron Ballman }
4712ce598a4SAaron Ballman
4722ce598a4SAaron Ballman llvm::json::Object
createCXXRecordDefinitionData(const CXXRecordDecl * RD)4732ce598a4SAaron Ballman JSONNodeDumper::createCXXRecordDefinitionData(const CXXRecordDecl *RD) {
4742ce598a4SAaron Ballman llvm::json::Object Ret;
4752ce598a4SAaron Ballman
4762ce598a4SAaron Ballman // This data is common to all C++ classes.
4772ce598a4SAaron Ballman FIELD1(isGenericLambda);
4782ce598a4SAaron Ballman FIELD1(isLambda);
4792ce598a4SAaron Ballman FIELD1(isEmpty);
4802ce598a4SAaron Ballman FIELD1(isAggregate);
4812ce598a4SAaron Ballman FIELD1(isStandardLayout);
4822ce598a4SAaron Ballman FIELD1(isTriviallyCopyable);
4832ce598a4SAaron Ballman FIELD1(isPOD);
4842ce598a4SAaron Ballman FIELD1(isTrivial);
4852ce598a4SAaron Ballman FIELD1(isPolymorphic);
4862ce598a4SAaron Ballman FIELD1(isAbstract);
4872ce598a4SAaron Ballman FIELD1(isLiteral);
4882ce598a4SAaron Ballman FIELD1(canPassInRegisters);
4892ce598a4SAaron Ballman FIELD1(hasUserDeclaredConstructor);
4902ce598a4SAaron Ballman FIELD1(hasConstexprNonCopyMoveConstructor);
4912ce598a4SAaron Ballman FIELD1(hasMutableFields);
4922ce598a4SAaron Ballman FIELD1(hasVariantMembers);
4932ce598a4SAaron Ballman FIELD2("canConstDefaultInit", allowConstDefaultInit);
4942ce598a4SAaron Ballman
4952ce598a4SAaron Ballman Ret["defaultCtor"] = createDefaultConstructorDefinitionData(RD);
4962ce598a4SAaron Ballman Ret["copyCtor"] = createCopyConstructorDefinitionData(RD);
4972ce598a4SAaron Ballman Ret["moveCtor"] = createMoveConstructorDefinitionData(RD);
4982ce598a4SAaron Ballman Ret["copyAssign"] = createCopyAssignmentDefinitionData(RD);
4992ce598a4SAaron Ballman Ret["moveAssign"] = createMoveAssignmentDefinitionData(RD);
5002ce598a4SAaron Ballman Ret["dtor"] = createDestructorDefinitionData(RD);
5012ce598a4SAaron Ballman
5022ce598a4SAaron Ballman return Ret;
5032ce598a4SAaron Ballman }
5042ce598a4SAaron Ballman
5052ce598a4SAaron Ballman #undef FIELD1
5062ce598a4SAaron Ballman #undef FIELD2
5072ce598a4SAaron Ballman
createAccessSpecifier(AccessSpecifier AS)5082ce598a4SAaron Ballman std::string JSONNodeDumper::createAccessSpecifier(AccessSpecifier AS) {
5096407aa9dSDaniel Martín const auto AccessSpelling = getAccessSpelling(AS);
5106407aa9dSDaniel Martín if (AccessSpelling.empty())
5116407aa9dSDaniel Martín return "none";
5126407aa9dSDaniel Martín return AccessSpelling.str();
5132ce598a4SAaron Ballman }
5142ce598a4SAaron Ballman
5152ce598a4SAaron Ballman llvm::json::Object
createCXXBaseSpecifier(const CXXBaseSpecifier & BS)5162ce598a4SAaron Ballman JSONNodeDumper::createCXXBaseSpecifier(const CXXBaseSpecifier &BS) {
5172ce598a4SAaron Ballman llvm::json::Object Ret;
5182ce598a4SAaron Ballman
5192ce598a4SAaron Ballman Ret["type"] = createQualType(BS.getType());
5202ce598a4SAaron Ballman Ret["access"] = createAccessSpecifier(BS.getAccessSpecifier());
5212ce598a4SAaron Ballman Ret["writtenAccess"] =
5222ce598a4SAaron Ballman createAccessSpecifier(BS.getAccessSpecifierAsWritten());
5232ce598a4SAaron Ballman if (BS.isVirtual())
5242ce598a4SAaron Ballman Ret["isVirtual"] = true;
5252ce598a4SAaron Ballman if (BS.isPackExpansion())
5262ce598a4SAaron Ballman Ret["isPackExpansion"] = true;
5272ce598a4SAaron Ballman
5282ce598a4SAaron Ballman return Ret;
5292ce598a4SAaron Ballman }
5302ce598a4SAaron Ballman
VisitTypedefType(const TypedefType * TT)5312ce598a4SAaron Ballman void JSONNodeDumper::VisitTypedefType(const TypedefType *TT) {
5322ce598a4SAaron Ballman JOS.attribute("decl", createBareDeclRef(TT->getDecl()));
5332ce598a4SAaron Ballman }
5342ce598a4SAaron Ballman
VisitFunctionType(const FunctionType * T)5352ce598a4SAaron Ballman void JSONNodeDumper::VisitFunctionType(const FunctionType *T) {
5362ce598a4SAaron Ballman FunctionType::ExtInfo E = T->getExtInfo();
5372ce598a4SAaron Ballman attributeOnlyIfTrue("noreturn", E.getNoReturn());
5382ce598a4SAaron Ballman attributeOnlyIfTrue("producesResult", E.getProducesResult());
5392ce598a4SAaron Ballman if (E.getHasRegParm())
5402ce598a4SAaron Ballman JOS.attribute("regParm", E.getRegParm());
5412ce598a4SAaron Ballman JOS.attribute("cc", FunctionType::getNameForCallConv(E.getCC()));
5422ce598a4SAaron Ballman }
5432ce598a4SAaron Ballman
VisitFunctionProtoType(const FunctionProtoType * T)5442ce598a4SAaron Ballman void JSONNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
5452ce598a4SAaron Ballman FunctionProtoType::ExtProtoInfo E = T->getExtProtoInfo();
5462ce598a4SAaron Ballman attributeOnlyIfTrue("trailingReturn", E.HasTrailingReturn);
5472ce598a4SAaron Ballman attributeOnlyIfTrue("const", T->isConst());
5482ce598a4SAaron Ballman attributeOnlyIfTrue("volatile", T->isVolatile());
5492ce598a4SAaron Ballman attributeOnlyIfTrue("restrict", T->isRestrict());
5502ce598a4SAaron Ballman attributeOnlyIfTrue("variadic", E.Variadic);
5512ce598a4SAaron Ballman switch (E.RefQualifier) {
5522ce598a4SAaron Ballman case RQ_LValue: JOS.attribute("refQualifier", "&"); break;
5532ce598a4SAaron Ballman case RQ_RValue: JOS.attribute("refQualifier", "&&"); break;
5542ce598a4SAaron Ballman case RQ_None: break;
5552ce598a4SAaron Ballman }
5562ce598a4SAaron Ballman switch (E.ExceptionSpec.Type) {
5572ce598a4SAaron Ballman case EST_DynamicNone:
5582ce598a4SAaron Ballman case EST_Dynamic: {
5592ce598a4SAaron Ballman JOS.attribute("exceptionSpec", "throw");
5602ce598a4SAaron Ballman llvm::json::Array Types;
5612ce598a4SAaron Ballman for (QualType QT : E.ExceptionSpec.Exceptions)
5622ce598a4SAaron Ballman Types.push_back(createQualType(QT));
5632ce598a4SAaron Ballman JOS.attribute("exceptionTypes", std::move(Types));
5642ce598a4SAaron Ballman } break;
5652ce598a4SAaron Ballman case EST_MSAny:
5662ce598a4SAaron Ballman JOS.attribute("exceptionSpec", "throw");
5672ce598a4SAaron Ballman JOS.attribute("throwsAny", true);
5682ce598a4SAaron Ballman break;
5692ce598a4SAaron Ballman case EST_BasicNoexcept:
5702ce598a4SAaron Ballman JOS.attribute("exceptionSpec", "noexcept");
5712ce598a4SAaron Ballman break;
5722ce598a4SAaron Ballman case EST_NoexceptTrue:
5732ce598a4SAaron Ballman case EST_NoexceptFalse:
5742ce598a4SAaron Ballman JOS.attribute("exceptionSpec", "noexcept");
5752ce598a4SAaron Ballman JOS.attribute("conditionEvaluatesTo",
5762ce598a4SAaron Ballman E.ExceptionSpec.Type == EST_NoexceptTrue);
5772ce598a4SAaron Ballman //JOS.attributeWithCall("exceptionSpecExpr",
5782ce598a4SAaron Ballman // [this, E]() { Visit(E.ExceptionSpec.NoexceptExpr); });
5792ce598a4SAaron Ballman break;
580d02f4a10SErich Keane case EST_NoThrow:
581d02f4a10SErich Keane JOS.attribute("exceptionSpec", "nothrow");
582d02f4a10SErich Keane break;
5832ce598a4SAaron Ballman // FIXME: I cannot find a way to trigger these cases while dumping the AST. I
5842ce598a4SAaron Ballman // suspect you can only run into them when executing an AST dump from within
5852ce598a4SAaron Ballman // the debugger, which is not a use case we worry about for the JSON dumping
5862ce598a4SAaron Ballman // feature.
5872ce598a4SAaron Ballman case EST_DependentNoexcept:
5882ce598a4SAaron Ballman case EST_Unevaluated:
5892ce598a4SAaron Ballman case EST_Uninstantiated:
5902ce598a4SAaron Ballman case EST_Unparsed:
5912ce598a4SAaron Ballman case EST_None: break;
5922ce598a4SAaron Ballman }
5932ce598a4SAaron Ballman VisitFunctionType(T);
5942ce598a4SAaron Ballman }
5952ce598a4SAaron Ballman
VisitRValueReferenceType(const ReferenceType * RT)596c07cfce2SAaron Ballman void JSONNodeDumper::VisitRValueReferenceType(const ReferenceType *RT) {
597c07cfce2SAaron Ballman attributeOnlyIfTrue("spelledAsLValue", RT->isSpelledAsLValue());
598c07cfce2SAaron Ballman }
599c07cfce2SAaron Ballman
VisitArrayType(const ArrayType * AT)600c07cfce2SAaron Ballman void JSONNodeDumper::VisitArrayType(const ArrayType *AT) {
601c07cfce2SAaron Ballman switch (AT->getSizeModifier()) {
602c07cfce2SAaron Ballman case ArrayType::Star:
603c07cfce2SAaron Ballman JOS.attribute("sizeModifier", "*");
604c07cfce2SAaron Ballman break;
605c07cfce2SAaron Ballman case ArrayType::Static:
606c07cfce2SAaron Ballman JOS.attribute("sizeModifier", "static");
607c07cfce2SAaron Ballman break;
608c07cfce2SAaron Ballman case ArrayType::Normal:
609c07cfce2SAaron Ballman break;
610c07cfce2SAaron Ballman }
611c07cfce2SAaron Ballman
612c07cfce2SAaron Ballman std::string Str = AT->getIndexTypeQualifiers().getAsString();
613c07cfce2SAaron Ballman if (!Str.empty())
614c07cfce2SAaron Ballman JOS.attribute("indexTypeQualifiers", Str);
615c07cfce2SAaron Ballman }
616c07cfce2SAaron Ballman
VisitConstantArrayType(const ConstantArrayType * CAT)617c07cfce2SAaron Ballman void JSONNodeDumper::VisitConstantArrayType(const ConstantArrayType *CAT) {
618c07cfce2SAaron Ballman // FIXME: this should use ZExt instead of SExt, but JSON doesn't allow a
619c07cfce2SAaron Ballman // narrowing conversion to int64_t so it cannot be expressed.
620c07cfce2SAaron Ballman JOS.attribute("size", CAT->getSize().getSExtValue());
621c07cfce2SAaron Ballman VisitArrayType(CAT);
622c07cfce2SAaron Ballman }
623c07cfce2SAaron Ballman
VisitDependentSizedExtVectorType(const DependentSizedExtVectorType * VT)624c07cfce2SAaron Ballman void JSONNodeDumper::VisitDependentSizedExtVectorType(
625c07cfce2SAaron Ballman const DependentSizedExtVectorType *VT) {
626a612e34cSAaron Ballman JOS.attributeObject(
627a612e34cSAaron Ballman "attrLoc", [VT, this] { writeSourceLocation(VT->getAttributeLoc()); });
628c07cfce2SAaron Ballman }
629c07cfce2SAaron Ballman
VisitVectorType(const VectorType * VT)630c07cfce2SAaron Ballman void JSONNodeDumper::VisitVectorType(const VectorType *VT) {
631c07cfce2SAaron Ballman JOS.attribute("numElements", VT->getNumElements());
632c07cfce2SAaron Ballman switch (VT->getVectorKind()) {
633c07cfce2SAaron Ballman case VectorType::GenericVector:
634c07cfce2SAaron Ballman break;
635c07cfce2SAaron Ballman case VectorType::AltiVecVector:
636c07cfce2SAaron Ballman JOS.attribute("vectorKind", "altivec");
637c07cfce2SAaron Ballman break;
638c07cfce2SAaron Ballman case VectorType::AltiVecPixel:
639c07cfce2SAaron Ballman JOS.attribute("vectorKind", "altivec pixel");
640c07cfce2SAaron Ballman break;
641c07cfce2SAaron Ballman case VectorType::AltiVecBool:
642c07cfce2SAaron Ballman JOS.attribute("vectorKind", "altivec bool");
643c07cfce2SAaron Ballman break;
644c07cfce2SAaron Ballman case VectorType::NeonVector:
645c07cfce2SAaron Ballman JOS.attribute("vectorKind", "neon");
646c07cfce2SAaron Ballman break;
647c07cfce2SAaron Ballman case VectorType::NeonPolyVector:
648c07cfce2SAaron Ballman JOS.attribute("vectorKind", "neon poly");
649c07cfce2SAaron Ballman break;
650feed5a72SCullen Rhodes case VectorType::SveFixedLengthDataVector:
651feed5a72SCullen Rhodes JOS.attribute("vectorKind", "fixed-length sve data vector");
652feed5a72SCullen Rhodes break;
653feed5a72SCullen Rhodes case VectorType::SveFixedLengthPredicateVector:
654feed5a72SCullen Rhodes JOS.attribute("vectorKind", "fixed-length sve predicate vector");
655feed5a72SCullen Rhodes break;
656c07cfce2SAaron Ballman }
657c07cfce2SAaron Ballman }
658c07cfce2SAaron Ballman
VisitUnresolvedUsingType(const UnresolvedUsingType * UUT)659c07cfce2SAaron Ballman void JSONNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *UUT) {
660c07cfce2SAaron Ballman JOS.attribute("decl", createBareDeclRef(UUT->getDecl()));
661c07cfce2SAaron Ballman }
662c07cfce2SAaron Ballman
VisitUnaryTransformType(const UnaryTransformType * UTT)663c07cfce2SAaron Ballman void JSONNodeDumper::VisitUnaryTransformType(const UnaryTransformType *UTT) {
664c07cfce2SAaron Ballman switch (UTT->getUTTKind()) {
665c07cfce2SAaron Ballman case UnaryTransformType::EnumUnderlyingType:
666c07cfce2SAaron Ballman JOS.attribute("transformKind", "underlying_type");
667c07cfce2SAaron Ballman break;
668c07cfce2SAaron Ballman }
669c07cfce2SAaron Ballman }
670c07cfce2SAaron Ballman
VisitTagType(const TagType * TT)671c07cfce2SAaron Ballman void JSONNodeDumper::VisitTagType(const TagType *TT) {
672c07cfce2SAaron Ballman JOS.attribute("decl", createBareDeclRef(TT->getDecl()));
673c07cfce2SAaron Ballman }
674c07cfce2SAaron Ballman
VisitTemplateTypeParmType(const TemplateTypeParmType * TTPT)675c07cfce2SAaron Ballman void JSONNodeDumper::VisitTemplateTypeParmType(
676c07cfce2SAaron Ballman const TemplateTypeParmType *TTPT) {
677c07cfce2SAaron Ballman JOS.attribute("depth", TTPT->getDepth());
678c07cfce2SAaron Ballman JOS.attribute("index", TTPT->getIndex());
679c07cfce2SAaron Ballman attributeOnlyIfTrue("isPack", TTPT->isParameterPack());
680c07cfce2SAaron Ballman JOS.attribute("decl", createBareDeclRef(TTPT->getDecl()));
681c07cfce2SAaron Ballman }
682c07cfce2SAaron Ballman
VisitAutoType(const AutoType * AT)683c07cfce2SAaron Ballman void JSONNodeDumper::VisitAutoType(const AutoType *AT) {
684c07cfce2SAaron Ballman JOS.attribute("undeduced", !AT->isDeduced());
685c07cfce2SAaron Ballman switch (AT->getKeyword()) {
686c07cfce2SAaron Ballman case AutoTypeKeyword::Auto:
687c07cfce2SAaron Ballman JOS.attribute("typeKeyword", "auto");
688c07cfce2SAaron Ballman break;
689c07cfce2SAaron Ballman case AutoTypeKeyword::DecltypeAuto:
690c07cfce2SAaron Ballman JOS.attribute("typeKeyword", "decltype(auto)");
691c07cfce2SAaron Ballman break;
692c07cfce2SAaron Ballman case AutoTypeKeyword::GNUAutoType:
693c07cfce2SAaron Ballman JOS.attribute("typeKeyword", "__auto_type");
694c07cfce2SAaron Ballman break;
695c07cfce2SAaron Ballman }
696c07cfce2SAaron Ballman }
697c07cfce2SAaron Ballman
VisitTemplateSpecializationType(const TemplateSpecializationType * TST)698c07cfce2SAaron Ballman void JSONNodeDumper::VisitTemplateSpecializationType(
699c07cfce2SAaron Ballman const TemplateSpecializationType *TST) {
700c07cfce2SAaron Ballman attributeOnlyIfTrue("isAlias", TST->isTypeAlias());
701c07cfce2SAaron Ballman
702c07cfce2SAaron Ballman std::string Str;
703c07cfce2SAaron Ballman llvm::raw_string_ostream OS(Str);
704c07cfce2SAaron Ballman TST->getTemplateName().print(OS, PrintPolicy);
705c07cfce2SAaron Ballman JOS.attribute("templateName", OS.str());
706c07cfce2SAaron Ballman }
707c07cfce2SAaron Ballman
VisitInjectedClassNameType(const InjectedClassNameType * ICNT)708c07cfce2SAaron Ballman void JSONNodeDumper::VisitInjectedClassNameType(
709c07cfce2SAaron Ballman const InjectedClassNameType *ICNT) {
710c07cfce2SAaron Ballman JOS.attribute("decl", createBareDeclRef(ICNT->getDecl()));
711c07cfce2SAaron Ballman }
712c07cfce2SAaron Ballman
VisitObjCInterfaceType(const ObjCInterfaceType * OIT)713c07cfce2SAaron Ballman void JSONNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *OIT) {
714c07cfce2SAaron Ballman JOS.attribute("decl", createBareDeclRef(OIT->getDecl()));
715c07cfce2SAaron Ballman }
716c07cfce2SAaron Ballman
VisitPackExpansionType(const PackExpansionType * PET)717c07cfce2SAaron Ballman void JSONNodeDumper::VisitPackExpansionType(const PackExpansionType *PET) {
718c07cfce2SAaron Ballman if (llvm::Optional<unsigned> N = PET->getNumExpansions())
719c07cfce2SAaron Ballman JOS.attribute("numExpansions", *N);
720c07cfce2SAaron Ballman }
721c07cfce2SAaron Ballman
VisitElaboratedType(const ElaboratedType * ET)722104b1298SAaron Ballman void JSONNodeDumper::VisitElaboratedType(const ElaboratedType *ET) {
723104b1298SAaron Ballman if (const NestedNameSpecifier *NNS = ET->getQualifier()) {
724104b1298SAaron Ballman std::string Str;
725104b1298SAaron Ballman llvm::raw_string_ostream OS(Str);
726104b1298SAaron Ballman NNS->print(OS, PrintPolicy, /*ResolveTemplateArgs*/ true);
727104b1298SAaron Ballman JOS.attribute("qualifier", OS.str());
728104b1298SAaron Ballman }
729104b1298SAaron Ballman if (const TagDecl *TD = ET->getOwnedTagDecl())
730104b1298SAaron Ballman JOS.attribute("ownedTagDecl", createBareDeclRef(TD));
731104b1298SAaron Ballman }
732104b1298SAaron Ballman
VisitMacroQualifiedType(const MacroQualifiedType * MQT)733104b1298SAaron Ballman void JSONNodeDumper::VisitMacroQualifiedType(const MacroQualifiedType *MQT) {
734104b1298SAaron Ballman JOS.attribute("macroName", MQT->getMacroIdentifier()->getName());
735104b1298SAaron Ballman }
736104b1298SAaron Ballman
VisitMemberPointerType(const MemberPointerType * MPT)737104b1298SAaron Ballman void JSONNodeDumper::VisitMemberPointerType(const MemberPointerType *MPT) {
738104b1298SAaron Ballman attributeOnlyIfTrue("isData", MPT->isMemberDataPointer());
739104b1298SAaron Ballman attributeOnlyIfTrue("isFunction", MPT->isMemberFunctionPointer());
740104b1298SAaron Ballman }
741104b1298SAaron Ballman
VisitNamedDecl(const NamedDecl * ND)7422ce598a4SAaron Ballman void JSONNodeDumper::VisitNamedDecl(const NamedDecl *ND) {
7433c3048c1SAlex Richardson if (ND && ND->getDeclName()) {
7442ce598a4SAaron Ballman JOS.attribute("name", ND->getNameAsString());
745ef227b32SRichard Smith // FIXME: There are likely other contexts in which it makes no sense to ask
746ef227b32SRichard Smith // for a mangled name.
7478043beb8SNikita Popov if (isa<RequiresExprBodyDecl>(ND->getDeclContext()))
7488043beb8SNikita Popov return;
7498043beb8SNikita Popov
7508043beb8SNikita Popov // Mangled names are not meaningful for locals, and may not be well-defined
7518043beb8SNikita Popov // in the case of VLAs.
7528043beb8SNikita Popov auto *VD = dyn_cast<VarDecl>(ND);
7538043beb8SNikita Popov if (VD && VD->hasLocalStorage())
7548043beb8SNikita Popov return;
7558043beb8SNikita Popov
7563c3048c1SAlex Richardson std::string MangledName = ASTNameGen.getName(ND);
7573c3048c1SAlex Richardson if (!MangledName.empty())
7583c3048c1SAlex Richardson JOS.attribute("mangledName", MangledName);
7593c3048c1SAlex Richardson }
7602ce598a4SAaron Ballman }
7612ce598a4SAaron Ballman
VisitTypedefDecl(const TypedefDecl * TD)7622ce598a4SAaron Ballman void JSONNodeDumper::VisitTypedefDecl(const TypedefDecl *TD) {
7632ce598a4SAaron Ballman VisitNamedDecl(TD);
7642ce598a4SAaron Ballman JOS.attribute("type", createQualType(TD->getUnderlyingType()));
7652ce598a4SAaron Ballman }
7662ce598a4SAaron Ballman
VisitTypeAliasDecl(const TypeAliasDecl * TAD)7672ce598a4SAaron Ballman void JSONNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *TAD) {
7682ce598a4SAaron Ballman VisitNamedDecl(TAD);
7692ce598a4SAaron Ballman JOS.attribute("type", createQualType(TAD->getUnderlyingType()));
7702ce598a4SAaron Ballman }
7712ce598a4SAaron Ballman
VisitNamespaceDecl(const NamespaceDecl * ND)7722ce598a4SAaron Ballman void JSONNodeDumper::VisitNamespaceDecl(const NamespaceDecl *ND) {
7732ce598a4SAaron Ballman VisitNamedDecl(ND);
7742ce598a4SAaron Ballman attributeOnlyIfTrue("isInline", ND->isInline());
7752ce598a4SAaron Ballman if (!ND->isOriginalNamespace())
7762ce598a4SAaron Ballman JOS.attribute("originalNamespace",
7772ce598a4SAaron Ballman createBareDeclRef(ND->getOriginalNamespace()));
7782ce598a4SAaron Ballman }
7792ce598a4SAaron Ballman
VisitUsingDirectiveDecl(const UsingDirectiveDecl * UDD)7802ce598a4SAaron Ballman void JSONNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *UDD) {
7812ce598a4SAaron Ballman JOS.attribute("nominatedNamespace",
7822ce598a4SAaron Ballman createBareDeclRef(UDD->getNominatedNamespace()));
7832ce598a4SAaron Ballman }
7842ce598a4SAaron Ballman
VisitNamespaceAliasDecl(const NamespaceAliasDecl * NAD)7852ce598a4SAaron Ballman void JSONNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *NAD) {
7862ce598a4SAaron Ballman VisitNamedDecl(NAD);
7872ce598a4SAaron Ballman JOS.attribute("aliasedNamespace",
7882ce598a4SAaron Ballman createBareDeclRef(NAD->getAliasedNamespace()));
7892ce598a4SAaron Ballman }
7902ce598a4SAaron Ballman
VisitUsingDecl(const UsingDecl * UD)7912ce598a4SAaron Ballman void JSONNodeDumper::VisitUsingDecl(const UsingDecl *UD) {
7922ce598a4SAaron Ballman std::string Name;
7932ce598a4SAaron Ballman if (const NestedNameSpecifier *NNS = UD->getQualifier()) {
7942ce598a4SAaron Ballman llvm::raw_string_ostream SOS(Name);
7952ce598a4SAaron Ballman NNS->print(SOS, UD->getASTContext().getPrintingPolicy());
7962ce598a4SAaron Ballman }
7972ce598a4SAaron Ballman Name += UD->getNameAsString();
7982ce598a4SAaron Ballman JOS.attribute("name", Name);
7992ce598a4SAaron Ballman }
8002ce598a4SAaron Ballman
VisitUsingEnumDecl(const UsingEnumDecl * UED)801b2d0c16eSNathan Sidwell void JSONNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *UED) {
802b2d0c16eSNathan Sidwell JOS.attribute("target", createBareDeclRef(UED->getEnumDecl()));
803b2d0c16eSNathan Sidwell }
804b2d0c16eSNathan Sidwell
VisitUsingShadowDecl(const UsingShadowDecl * USD)8052ce598a4SAaron Ballman void JSONNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *USD) {
8062ce598a4SAaron Ballman JOS.attribute("target", createBareDeclRef(USD->getTargetDecl()));
8072ce598a4SAaron Ballman }
8082ce598a4SAaron Ballman
VisitVarDecl(const VarDecl * VD)8092ce598a4SAaron Ballman void JSONNodeDumper::VisitVarDecl(const VarDecl *VD) {
8102ce598a4SAaron Ballman VisitNamedDecl(VD);
8112ce598a4SAaron Ballman JOS.attribute("type", createQualType(VD->getType()));
8122ce598a4SAaron Ballman
8132ce598a4SAaron Ballman StorageClass SC = VD->getStorageClass();
8142fd11e0bSThorsten Schütt if (SC != SC_None)
8152ce598a4SAaron Ballman JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));
8162ce598a4SAaron Ballman switch (VD->getTLSKind()) {
8172ce598a4SAaron Ballman case VarDecl::TLS_Dynamic: JOS.attribute("tls", "dynamic"); break;
8182ce598a4SAaron Ballman case VarDecl::TLS_Static: JOS.attribute("tls", "static"); break;
8192ce598a4SAaron Ballman case VarDecl::TLS_None: break;
8202ce598a4SAaron Ballman }
8212ce598a4SAaron Ballman attributeOnlyIfTrue("nrvo", VD->isNRVOVariable());
8222ce598a4SAaron Ballman attributeOnlyIfTrue("inline", VD->isInline());
8232ce598a4SAaron Ballman attributeOnlyIfTrue("constexpr", VD->isConstexpr());
8242ce598a4SAaron Ballman attributeOnlyIfTrue("modulePrivate", VD->isModulePrivate());
8252ce598a4SAaron Ballman if (VD->hasInit()) {
8262ce598a4SAaron Ballman switch (VD->getInitStyle()) {
8272ce598a4SAaron Ballman case VarDecl::CInit: JOS.attribute("init", "c"); break;
8282ce598a4SAaron Ballman case VarDecl::CallInit: JOS.attribute("init", "call"); break;
8292ce598a4SAaron Ballman case VarDecl::ListInit: JOS.attribute("init", "list"); break;
8302ce598a4SAaron Ballman }
8312ce598a4SAaron Ballman }
832b2997f57SRichard Smith attributeOnlyIfTrue("isParameterPack", VD->isParameterPack());
8332ce598a4SAaron Ballman }
8342ce598a4SAaron Ballman
VisitFieldDecl(const FieldDecl * FD)8352ce598a4SAaron Ballman void JSONNodeDumper::VisitFieldDecl(const FieldDecl *FD) {
8362ce598a4SAaron Ballman VisitNamedDecl(FD);
8372ce598a4SAaron Ballman JOS.attribute("type", createQualType(FD->getType()));
8382ce598a4SAaron Ballman attributeOnlyIfTrue("mutable", FD->isMutable());
8392ce598a4SAaron Ballman attributeOnlyIfTrue("modulePrivate", FD->isModulePrivate());
8402ce598a4SAaron Ballman attributeOnlyIfTrue("isBitfield", FD->isBitField());
8412ce598a4SAaron Ballman attributeOnlyIfTrue("hasInClassInitializer", FD->hasInClassInitializer());
8422ce598a4SAaron Ballman }
8432ce598a4SAaron Ballman
VisitFunctionDecl(const FunctionDecl * FD)8442ce598a4SAaron Ballman void JSONNodeDumper::VisitFunctionDecl(const FunctionDecl *FD) {
8452ce598a4SAaron Ballman VisitNamedDecl(FD);
8462ce598a4SAaron Ballman JOS.attribute("type", createQualType(FD->getType()));
8472ce598a4SAaron Ballman StorageClass SC = FD->getStorageClass();
8482fd11e0bSThorsten Schütt if (SC != SC_None)
8492ce598a4SAaron Ballman JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));
8502ce598a4SAaron Ballman attributeOnlyIfTrue("inline", FD->isInlineSpecified());
8512ce598a4SAaron Ballman attributeOnlyIfTrue("virtual", FD->isVirtualAsWritten());
8522ce598a4SAaron Ballman attributeOnlyIfTrue("pure", FD->isPure());
8532ce598a4SAaron Ballman attributeOnlyIfTrue("explicitlyDeleted", FD->isDeletedAsWritten());
8542ce598a4SAaron Ballman attributeOnlyIfTrue("constexpr", FD->isConstexpr());
8551b0ae8f0SAaron Ballman attributeOnlyIfTrue("variadic", FD->isVariadic());
8561b0ae8f0SAaron Ballman
8572ce598a4SAaron Ballman if (FD->isDefaulted())
8582ce598a4SAaron Ballman JOS.attribute("explicitlyDefaulted",
8592ce598a4SAaron Ballman FD->isDeleted() ? "deleted" : "default");
8602ce598a4SAaron Ballman }
8612ce598a4SAaron Ballman
VisitEnumDecl(const EnumDecl * ED)8622ce598a4SAaron Ballman void JSONNodeDumper::VisitEnumDecl(const EnumDecl *ED) {
8632ce598a4SAaron Ballman VisitNamedDecl(ED);
8642ce598a4SAaron Ballman if (ED->isFixed())
8652ce598a4SAaron Ballman JOS.attribute("fixedUnderlyingType", createQualType(ED->getIntegerType()));
8662ce598a4SAaron Ballman if (ED->isScoped())
8672ce598a4SAaron Ballman JOS.attribute("scopedEnumTag",
8682ce598a4SAaron Ballman ED->isScopedUsingClassTag() ? "class" : "struct");
8692ce598a4SAaron Ballman }
VisitEnumConstantDecl(const EnumConstantDecl * ECD)8702ce598a4SAaron Ballman void JSONNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *ECD) {
8712ce598a4SAaron Ballman VisitNamedDecl(ECD);
8722ce598a4SAaron Ballman JOS.attribute("type", createQualType(ECD->getType()));
8732ce598a4SAaron Ballman }
8742ce598a4SAaron Ballman
VisitRecordDecl(const RecordDecl * RD)8752ce598a4SAaron Ballman void JSONNodeDumper::VisitRecordDecl(const RecordDecl *RD) {
8762ce598a4SAaron Ballman VisitNamedDecl(RD);
8772ce598a4SAaron Ballman JOS.attribute("tagUsed", RD->getKindName());
8782ce598a4SAaron Ballman attributeOnlyIfTrue("completeDefinition", RD->isCompleteDefinition());
8792ce598a4SAaron Ballman }
VisitCXXRecordDecl(const CXXRecordDecl * RD)8802ce598a4SAaron Ballman void JSONNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *RD) {
8812ce598a4SAaron Ballman VisitRecordDecl(RD);
8822ce598a4SAaron Ballman
8832ce598a4SAaron Ballman // All other information requires a complete definition.
8842ce598a4SAaron Ballman if (!RD->isCompleteDefinition())
8852ce598a4SAaron Ballman return;
8862ce598a4SAaron Ballman
8872ce598a4SAaron Ballman JOS.attribute("definitionData", createCXXRecordDefinitionData(RD));
8882ce598a4SAaron Ballman if (RD->getNumBases()) {
8892ce598a4SAaron Ballman JOS.attributeArray("bases", [this, RD] {
8902ce598a4SAaron Ballman for (const auto &Spec : RD->bases())
8912ce598a4SAaron Ballman JOS.value(createCXXBaseSpecifier(Spec));
8922ce598a4SAaron Ballman });
8932ce598a4SAaron Ballman }
8942ce598a4SAaron Ballman }
8952ce598a4SAaron Ballman
VisitTemplateTypeParmDecl(const TemplateTypeParmDecl * D)8962ce598a4SAaron Ballman void JSONNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
8972ce598a4SAaron Ballman VisitNamedDecl(D);
8982ce598a4SAaron Ballman JOS.attribute("tagUsed", D->wasDeclaredWithTypename() ? "typename" : "class");
8992ce598a4SAaron Ballman JOS.attribute("depth", D->getDepth());
9002ce598a4SAaron Ballman JOS.attribute("index", D->getIndex());
9012ce598a4SAaron Ballman attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
9027556615aSAaron Ballman
9037556615aSAaron Ballman if (D->hasDefaultArgument())
9047556615aSAaron Ballman JOS.attributeObject("defaultArg", [=] {
9057556615aSAaron Ballman Visit(D->getDefaultArgument(), SourceRange(),
9067556615aSAaron Ballman D->getDefaultArgStorage().getInheritedFrom(),
9077556615aSAaron Ballman D->defaultArgumentWasInherited() ? "inherited from" : "previous");
9087556615aSAaron Ballman });
9092ce598a4SAaron Ballman }
9102ce598a4SAaron Ballman
VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl * D)9112ce598a4SAaron Ballman void JSONNodeDumper::VisitNonTypeTemplateParmDecl(
9122ce598a4SAaron Ballman const NonTypeTemplateParmDecl *D) {
9132ce598a4SAaron Ballman VisitNamedDecl(D);
9142ce598a4SAaron Ballman JOS.attribute("type", createQualType(D->getType()));
9152ce598a4SAaron Ballman JOS.attribute("depth", D->getDepth());
9162ce598a4SAaron Ballman JOS.attribute("index", D->getIndex());
9172ce598a4SAaron Ballman attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
9187556615aSAaron Ballman
9197556615aSAaron Ballman if (D->hasDefaultArgument())
9207556615aSAaron Ballman JOS.attributeObject("defaultArg", [=] {
9217556615aSAaron Ballman Visit(D->getDefaultArgument(), SourceRange(),
9227556615aSAaron Ballman D->getDefaultArgStorage().getInheritedFrom(),
9237556615aSAaron Ballman D->defaultArgumentWasInherited() ? "inherited from" : "previous");
9247556615aSAaron Ballman });
9252ce598a4SAaron Ballman }
9262ce598a4SAaron Ballman
VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl * D)9272ce598a4SAaron Ballman void JSONNodeDumper::VisitTemplateTemplateParmDecl(
9282ce598a4SAaron Ballman const TemplateTemplateParmDecl *D) {
9292ce598a4SAaron Ballman VisitNamedDecl(D);
9302ce598a4SAaron Ballman JOS.attribute("depth", D->getDepth());
9312ce598a4SAaron Ballman JOS.attribute("index", D->getIndex());
9322ce598a4SAaron Ballman attributeOnlyIfTrue("isParameterPack", D->isParameterPack());
9337556615aSAaron Ballman
9347556615aSAaron Ballman if (D->hasDefaultArgument())
9357556615aSAaron Ballman JOS.attributeObject("defaultArg", [=] {
936967ebad1SDavid Tolnay const auto *InheritedFrom = D->getDefaultArgStorage().getInheritedFrom();
9377556615aSAaron Ballman Visit(D->getDefaultArgument().getArgument(),
938967ebad1SDavid Tolnay InheritedFrom ? InheritedFrom->getSourceRange() : SourceLocation{},
939967ebad1SDavid Tolnay InheritedFrom,
9407556615aSAaron Ballman D->defaultArgumentWasInherited() ? "inherited from" : "previous");
9417556615aSAaron Ballman });
9422ce598a4SAaron Ballman }
9432ce598a4SAaron Ballman
VisitLinkageSpecDecl(const LinkageSpecDecl * LSD)9442ce598a4SAaron Ballman void JSONNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *LSD) {
9452ce598a4SAaron Ballman StringRef Lang;
9462ce598a4SAaron Ballman switch (LSD->getLanguage()) {
9472ce598a4SAaron Ballman case LinkageSpecDecl::lang_c: Lang = "C"; break;
9482ce598a4SAaron Ballman case LinkageSpecDecl::lang_cxx: Lang = "C++"; break;
9492ce598a4SAaron Ballman }
9502ce598a4SAaron Ballman JOS.attribute("language", Lang);
9512ce598a4SAaron Ballman attributeOnlyIfTrue("hasBraces", LSD->hasBraces());
9522ce598a4SAaron Ballman }
9532ce598a4SAaron Ballman
VisitAccessSpecDecl(const AccessSpecDecl * ASD)9542ce598a4SAaron Ballman void JSONNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *ASD) {
9552ce598a4SAaron Ballman JOS.attribute("access", createAccessSpecifier(ASD->getAccess()));
9562ce598a4SAaron Ballman }
9572ce598a4SAaron Ballman
VisitFriendDecl(const FriendDecl * FD)9582ce598a4SAaron Ballman void JSONNodeDumper::VisitFriendDecl(const FriendDecl *FD) {
9592ce598a4SAaron Ballman if (const TypeSourceInfo *T = FD->getFriendType())
9602ce598a4SAaron Ballman JOS.attribute("type", createQualType(T->getType()));
9612ce598a4SAaron Ballman }
9622ce598a4SAaron Ballman
VisitObjCIvarDecl(const ObjCIvarDecl * D)9634105882bSAaron Ballman void JSONNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
9644105882bSAaron Ballman VisitNamedDecl(D);
9654105882bSAaron Ballman JOS.attribute("type", createQualType(D->getType()));
9664105882bSAaron Ballman attributeOnlyIfTrue("synthesized", D->getSynthesize());
9674105882bSAaron Ballman switch (D->getAccessControl()) {
9684105882bSAaron Ballman case ObjCIvarDecl::None: JOS.attribute("access", "none"); break;
9694105882bSAaron Ballman case ObjCIvarDecl::Private: JOS.attribute("access", "private"); break;
9704105882bSAaron Ballman case ObjCIvarDecl::Protected: JOS.attribute("access", "protected"); break;
9714105882bSAaron Ballman case ObjCIvarDecl::Public: JOS.attribute("access", "public"); break;
9724105882bSAaron Ballman case ObjCIvarDecl::Package: JOS.attribute("access", "package"); break;
9734105882bSAaron Ballman }
9744105882bSAaron Ballman }
9754105882bSAaron Ballman
VisitObjCMethodDecl(const ObjCMethodDecl * D)9764105882bSAaron Ballman void JSONNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
9774105882bSAaron Ballman VisitNamedDecl(D);
9784105882bSAaron Ballman JOS.attribute("returnType", createQualType(D->getReturnType()));
9794105882bSAaron Ballman JOS.attribute("instance", D->isInstanceMethod());
9804105882bSAaron Ballman attributeOnlyIfTrue("variadic", D->isVariadic());
9814105882bSAaron Ballman }
9824105882bSAaron Ballman
VisitObjCTypeParamDecl(const ObjCTypeParamDecl * D)9834105882bSAaron Ballman void JSONNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
9844105882bSAaron Ballman VisitNamedDecl(D);
9854105882bSAaron Ballman JOS.attribute("type", createQualType(D->getUnderlyingType()));
9864105882bSAaron Ballman attributeOnlyIfTrue("bounded", D->hasExplicitBound());
9874105882bSAaron Ballman switch (D->getVariance()) {
9884105882bSAaron Ballman case ObjCTypeParamVariance::Invariant:
9894105882bSAaron Ballman break;
9904105882bSAaron Ballman case ObjCTypeParamVariance::Covariant:
9914105882bSAaron Ballman JOS.attribute("variance", "covariant");
9924105882bSAaron Ballman break;
9934105882bSAaron Ballman case ObjCTypeParamVariance::Contravariant:
9944105882bSAaron Ballman JOS.attribute("variance", "contravariant");
9954105882bSAaron Ballman break;
9964105882bSAaron Ballman }
9974105882bSAaron Ballman }
9984105882bSAaron Ballman
VisitObjCCategoryDecl(const ObjCCategoryDecl * D)9994105882bSAaron Ballman void JSONNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
10004105882bSAaron Ballman VisitNamedDecl(D);
10014105882bSAaron Ballman JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
10024105882bSAaron Ballman JOS.attribute("implementation", createBareDeclRef(D->getImplementation()));
10034105882bSAaron Ballman
10044105882bSAaron Ballman llvm::json::Array Protocols;
10054105882bSAaron Ballman for (const auto* P : D->protocols())
10064105882bSAaron Ballman Protocols.push_back(createBareDeclRef(P));
10074105882bSAaron Ballman if (!Protocols.empty())
10084105882bSAaron Ballman JOS.attribute("protocols", std::move(Protocols));
10094105882bSAaron Ballman }
10104105882bSAaron Ballman
VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl * D)10114105882bSAaron Ballman void JSONNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
10124105882bSAaron Ballman VisitNamedDecl(D);
10134105882bSAaron Ballman JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
10144105882bSAaron Ballman JOS.attribute("categoryDecl", createBareDeclRef(D->getCategoryDecl()));
10154105882bSAaron Ballman }
10164105882bSAaron Ballman
VisitObjCProtocolDecl(const ObjCProtocolDecl * D)10174105882bSAaron Ballman void JSONNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
10184105882bSAaron Ballman VisitNamedDecl(D);
10194105882bSAaron Ballman
10204105882bSAaron Ballman llvm::json::Array Protocols;
10214105882bSAaron Ballman for (const auto *P : D->protocols())
10224105882bSAaron Ballman Protocols.push_back(createBareDeclRef(P));
10234105882bSAaron Ballman if (!Protocols.empty())
10244105882bSAaron Ballman JOS.attribute("protocols", std::move(Protocols));
10254105882bSAaron Ballman }
10264105882bSAaron Ballman
VisitObjCInterfaceDecl(const ObjCInterfaceDecl * D)10274105882bSAaron Ballman void JSONNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
10284105882bSAaron Ballman VisitNamedDecl(D);
10294105882bSAaron Ballman JOS.attribute("super", createBareDeclRef(D->getSuperClass()));
10304105882bSAaron Ballman JOS.attribute("implementation", createBareDeclRef(D->getImplementation()));
10314105882bSAaron Ballman
10324105882bSAaron Ballman llvm::json::Array Protocols;
10334105882bSAaron Ballman for (const auto* P : D->protocols())
10344105882bSAaron Ballman Protocols.push_back(createBareDeclRef(P));
10354105882bSAaron Ballman if (!Protocols.empty())
10364105882bSAaron Ballman JOS.attribute("protocols", std::move(Protocols));
10374105882bSAaron Ballman }
10384105882bSAaron Ballman
VisitObjCImplementationDecl(const ObjCImplementationDecl * D)10394105882bSAaron Ballman void JSONNodeDumper::VisitObjCImplementationDecl(
10404105882bSAaron Ballman const ObjCImplementationDecl *D) {
10414105882bSAaron Ballman VisitNamedDecl(D);
10424105882bSAaron Ballman JOS.attribute("super", createBareDeclRef(D->getSuperClass()));
10434105882bSAaron Ballman JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
10444105882bSAaron Ballman }
10454105882bSAaron Ballman
VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl * D)10464105882bSAaron Ballman void JSONNodeDumper::VisitObjCCompatibleAliasDecl(
10474105882bSAaron Ballman const ObjCCompatibleAliasDecl *D) {
10484105882bSAaron Ballman VisitNamedDecl(D);
10494105882bSAaron Ballman JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));
10504105882bSAaron Ballman }
10514105882bSAaron Ballman
VisitObjCPropertyDecl(const ObjCPropertyDecl * D)10524105882bSAaron Ballman void JSONNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
10534105882bSAaron Ballman VisitNamedDecl(D);
10544105882bSAaron Ballman JOS.attribute("type", createQualType(D->getType()));
10554105882bSAaron Ballman
10564105882bSAaron Ballman switch (D->getPropertyImplementation()) {
10574105882bSAaron Ballman case ObjCPropertyDecl::None: break;
10584105882bSAaron Ballman case ObjCPropertyDecl::Required: JOS.attribute("control", "required"); break;
10594105882bSAaron Ballman case ObjCPropertyDecl::Optional: JOS.attribute("control", "optional"); break;
10604105882bSAaron Ballman }
10614105882bSAaron Ballman
10629721fbf8SPuyan Lotfi ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();
10639721fbf8SPuyan Lotfi if (Attrs != ObjCPropertyAttribute::kind_noattr) {
10649721fbf8SPuyan Lotfi if (Attrs & ObjCPropertyAttribute::kind_getter)
10654105882bSAaron Ballman JOS.attribute("getter", createBareDeclRef(D->getGetterMethodDecl()));
10669721fbf8SPuyan Lotfi if (Attrs & ObjCPropertyAttribute::kind_setter)
10674105882bSAaron Ballman JOS.attribute("setter", createBareDeclRef(D->getSetterMethodDecl()));
10689721fbf8SPuyan Lotfi attributeOnlyIfTrue("readonly",
10699721fbf8SPuyan Lotfi Attrs & ObjCPropertyAttribute::kind_readonly);
10709721fbf8SPuyan Lotfi attributeOnlyIfTrue("assign", Attrs & ObjCPropertyAttribute::kind_assign);
10714105882bSAaron Ballman attributeOnlyIfTrue("readwrite",
10729721fbf8SPuyan Lotfi Attrs & ObjCPropertyAttribute::kind_readwrite);
10739721fbf8SPuyan Lotfi attributeOnlyIfTrue("retain", Attrs & ObjCPropertyAttribute::kind_retain);
10749721fbf8SPuyan Lotfi attributeOnlyIfTrue("copy", Attrs & ObjCPropertyAttribute::kind_copy);
10754105882bSAaron Ballman attributeOnlyIfTrue("nonatomic",
10769721fbf8SPuyan Lotfi Attrs & ObjCPropertyAttribute::kind_nonatomic);
10779721fbf8SPuyan Lotfi attributeOnlyIfTrue("atomic", Attrs & ObjCPropertyAttribute::kind_atomic);
10789721fbf8SPuyan Lotfi attributeOnlyIfTrue("weak", Attrs & ObjCPropertyAttribute::kind_weak);
10799721fbf8SPuyan Lotfi attributeOnlyIfTrue("strong", Attrs & ObjCPropertyAttribute::kind_strong);
10804105882bSAaron Ballman attributeOnlyIfTrue("unsafe_unretained",
10819721fbf8SPuyan Lotfi Attrs & ObjCPropertyAttribute::kind_unsafe_unretained);
10829721fbf8SPuyan Lotfi attributeOnlyIfTrue("class", Attrs & ObjCPropertyAttribute::kind_class);
10839721fbf8SPuyan Lotfi attributeOnlyIfTrue("direct", Attrs & ObjCPropertyAttribute::kind_direct);
10844105882bSAaron Ballman attributeOnlyIfTrue("nullability",
10859721fbf8SPuyan Lotfi Attrs & ObjCPropertyAttribute::kind_nullability);
10864105882bSAaron Ballman attributeOnlyIfTrue("null_resettable",
10879721fbf8SPuyan Lotfi Attrs & ObjCPropertyAttribute::kind_null_resettable);
10884105882bSAaron Ballman }
10894105882bSAaron Ballman }
10904105882bSAaron Ballman
VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl * D)10914105882bSAaron Ballman void JSONNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
10924105882bSAaron Ballman VisitNamedDecl(D->getPropertyDecl());
10934105882bSAaron Ballman JOS.attribute("implKind", D->getPropertyImplementation() ==
10944105882bSAaron Ballman ObjCPropertyImplDecl::Synthesize
10954105882bSAaron Ballman ? "synthesize"
10964105882bSAaron Ballman : "dynamic");
10974105882bSAaron Ballman JOS.attribute("propertyDecl", createBareDeclRef(D->getPropertyDecl()));
10984105882bSAaron Ballman JOS.attribute("ivarDecl", createBareDeclRef(D->getPropertyIvarDecl()));
10994105882bSAaron Ballman }
11004105882bSAaron Ballman
VisitBlockDecl(const BlockDecl * D)11014105882bSAaron Ballman void JSONNodeDumper::VisitBlockDecl(const BlockDecl *D) {
11024105882bSAaron Ballman attributeOnlyIfTrue("variadic", D->isVariadic());
11034105882bSAaron Ballman attributeOnlyIfTrue("capturesThis", D->capturesCXXThis());
11044105882bSAaron Ballman }
11054105882bSAaron Ballman
VisitObjCEncodeExpr(const ObjCEncodeExpr * OEE)11067f1b223aSAaron Ballman void JSONNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE) {
11077f1b223aSAaron Ballman JOS.attribute("encodedType", createQualType(OEE->getEncodedType()));
11087f1b223aSAaron Ballman }
11097f1b223aSAaron Ballman
VisitObjCMessageExpr(const ObjCMessageExpr * OME)111075e23f85SAaron Ballman void JSONNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *OME) {
111175e23f85SAaron Ballman std::string Str;
111275e23f85SAaron Ballman llvm::raw_string_ostream OS(Str);
111375e23f85SAaron Ballman
111475e23f85SAaron Ballman OME->getSelector().print(OS);
111575e23f85SAaron Ballman JOS.attribute("selector", OS.str());
111675e23f85SAaron Ballman
111775e23f85SAaron Ballman switch (OME->getReceiverKind()) {
111875e23f85SAaron Ballman case ObjCMessageExpr::Instance:
111975e23f85SAaron Ballman JOS.attribute("receiverKind", "instance");
112075e23f85SAaron Ballman break;
112175e23f85SAaron Ballman case ObjCMessageExpr::Class:
112275e23f85SAaron Ballman JOS.attribute("receiverKind", "class");
112375e23f85SAaron Ballman JOS.attribute("classType", createQualType(OME->getClassReceiver()));
112475e23f85SAaron Ballman break;
112575e23f85SAaron Ballman case ObjCMessageExpr::SuperInstance:
112675e23f85SAaron Ballman JOS.attribute("receiverKind", "super (instance)");
112775e23f85SAaron Ballman JOS.attribute("superType", createQualType(OME->getSuperType()));
112875e23f85SAaron Ballman break;
112975e23f85SAaron Ballman case ObjCMessageExpr::SuperClass:
113075e23f85SAaron Ballman JOS.attribute("receiverKind", "super (class)");
113175e23f85SAaron Ballman JOS.attribute("superType", createQualType(OME->getSuperType()));
113275e23f85SAaron Ballman break;
113375e23f85SAaron Ballman }
113475e23f85SAaron Ballman
113575e23f85SAaron Ballman QualType CallReturnTy = OME->getCallReturnType(Ctx);
113675e23f85SAaron Ballman if (OME->getType() != CallReturnTy)
113775e23f85SAaron Ballman JOS.attribute("callReturnType", createQualType(CallReturnTy));
113875e23f85SAaron Ballman }
113975e23f85SAaron Ballman
VisitObjCBoxedExpr(const ObjCBoxedExpr * OBE)114075e23f85SAaron Ballman void JSONNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *OBE) {
114175e23f85SAaron Ballman if (const ObjCMethodDecl *MD = OBE->getBoxingMethod()) {
114275e23f85SAaron Ballman std::string Str;
114375e23f85SAaron Ballman llvm::raw_string_ostream OS(Str);
114475e23f85SAaron Ballman
114575e23f85SAaron Ballman MD->getSelector().print(OS);
114675e23f85SAaron Ballman JOS.attribute("selector", OS.str());
114775e23f85SAaron Ballman }
114875e23f85SAaron Ballman }
114975e23f85SAaron Ballman
VisitObjCSelectorExpr(const ObjCSelectorExpr * OSE)115075e23f85SAaron Ballman void JSONNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *OSE) {
115175e23f85SAaron Ballman std::string Str;
115275e23f85SAaron Ballman llvm::raw_string_ostream OS(Str);
115375e23f85SAaron Ballman
115475e23f85SAaron Ballman OSE->getSelector().print(OS);
115575e23f85SAaron Ballman JOS.attribute("selector", OS.str());
115675e23f85SAaron Ballman }
115775e23f85SAaron Ballman
VisitObjCProtocolExpr(const ObjCProtocolExpr * OPE)115875e23f85SAaron Ballman void JSONNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE) {
115975e23f85SAaron Ballman JOS.attribute("protocol", createBareDeclRef(OPE->getProtocol()));
116075e23f85SAaron Ballman }
116175e23f85SAaron Ballman
VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr * OPRE)116275e23f85SAaron Ballman void JSONNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE) {
116375e23f85SAaron Ballman if (OPRE->isImplicitProperty()) {
116475e23f85SAaron Ballman JOS.attribute("propertyKind", "implicit");
116575e23f85SAaron Ballman if (const ObjCMethodDecl *MD = OPRE->getImplicitPropertyGetter())
116675e23f85SAaron Ballman JOS.attribute("getter", createBareDeclRef(MD));
116775e23f85SAaron Ballman if (const ObjCMethodDecl *MD = OPRE->getImplicitPropertySetter())
116875e23f85SAaron Ballman JOS.attribute("setter", createBareDeclRef(MD));
116975e23f85SAaron Ballman } else {
117075e23f85SAaron Ballman JOS.attribute("propertyKind", "explicit");
117175e23f85SAaron Ballman JOS.attribute("property", createBareDeclRef(OPRE->getExplicitProperty()));
117275e23f85SAaron Ballman }
117375e23f85SAaron Ballman
117475e23f85SAaron Ballman attributeOnlyIfTrue("isSuperReceiver", OPRE->isSuperReceiver());
117575e23f85SAaron Ballman attributeOnlyIfTrue("isMessagingGetter", OPRE->isMessagingGetter());
117675e23f85SAaron Ballman attributeOnlyIfTrue("isMessagingSetter", OPRE->isMessagingSetter());
117775e23f85SAaron Ballman }
117875e23f85SAaron Ballman
VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr * OSRE)117975e23f85SAaron Ballman void JSONNodeDumper::VisitObjCSubscriptRefExpr(
118075e23f85SAaron Ballman const ObjCSubscriptRefExpr *OSRE) {
118175e23f85SAaron Ballman JOS.attribute("subscriptKind",
118275e23f85SAaron Ballman OSRE->isArraySubscriptRefExpr() ? "array" : "dictionary");
118375e23f85SAaron Ballman
118475e23f85SAaron Ballman if (const ObjCMethodDecl *MD = OSRE->getAtIndexMethodDecl())
118575e23f85SAaron Ballman JOS.attribute("getter", createBareDeclRef(MD));
118675e23f85SAaron Ballman if (const ObjCMethodDecl *MD = OSRE->setAtIndexMethodDecl())
118775e23f85SAaron Ballman JOS.attribute("setter", createBareDeclRef(MD));
118875e23f85SAaron Ballman }
118975e23f85SAaron Ballman
VisitObjCIvarRefExpr(const ObjCIvarRefExpr * OIRE)119075e23f85SAaron Ballman void JSONNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {
119175e23f85SAaron Ballman JOS.attribute("decl", createBareDeclRef(OIRE->getDecl()));
119275e23f85SAaron Ballman attributeOnlyIfTrue("isFreeIvar", OIRE->isFreeIvar());
119375e23f85SAaron Ballman JOS.attribute("isArrow", OIRE->isArrow());
119475e23f85SAaron Ballman }
119575e23f85SAaron Ballman
VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr * OBLE)119675e23f85SAaron Ballman void JSONNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *OBLE) {
119775e23f85SAaron Ballman JOS.attribute("value", OBLE->getValue() ? "__objc_yes" : "__objc_no");
119875e23f85SAaron Ballman }
119975e23f85SAaron Ballman
VisitDeclRefExpr(const DeclRefExpr * DRE)12002ce598a4SAaron Ballman void JSONNodeDumper::VisitDeclRefExpr(const DeclRefExpr *DRE) {
12012ce598a4SAaron Ballman JOS.attribute("referencedDecl", createBareDeclRef(DRE->getDecl()));
12022ce598a4SAaron Ballman if (DRE->getDecl() != DRE->getFoundDecl())
12032ce598a4SAaron Ballman JOS.attribute("foundReferencedDecl",
12042ce598a4SAaron Ballman createBareDeclRef(DRE->getFoundDecl()));
1205715f7a1bSRichard Smith switch (DRE->isNonOdrUse()) {
1206715f7a1bSRichard Smith case NOUR_None: break;
1207715f7a1bSRichard Smith case NOUR_Unevaluated: JOS.attribute("nonOdrUseReason", "unevaluated"); break;
1208715f7a1bSRichard Smith case NOUR_Constant: JOS.attribute("nonOdrUseReason", "constant"); break;
1209715f7a1bSRichard Smith case NOUR_Discarded: JOS.attribute("nonOdrUseReason", "discarded"); break;
1210715f7a1bSRichard Smith }
12112ce598a4SAaron Ballman }
12122ce598a4SAaron Ballman
VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr * E)1213eba69b59SErich Keane void JSONNodeDumper::VisitSYCLUniqueStableNameExpr(
1214eba69b59SErich Keane const SYCLUniqueStableNameExpr *E) {
1215eba69b59SErich Keane JOS.attribute("typeSourceInfo",
1216eba69b59SErich Keane createQualType(E->getTypeSourceInfo()->getType()));
1217eba69b59SErich Keane }
1218eba69b59SErich Keane
VisitPredefinedExpr(const PredefinedExpr * PE)12192ce598a4SAaron Ballman void JSONNodeDumper::VisitPredefinedExpr(const PredefinedExpr *PE) {
12202ce598a4SAaron Ballman JOS.attribute("name", PredefinedExpr::getIdentKindName(PE->getIdentKind()));
12212ce598a4SAaron Ballman }
12222ce598a4SAaron Ballman
VisitUnaryOperator(const UnaryOperator * UO)12232ce598a4SAaron Ballman void JSONNodeDumper::VisitUnaryOperator(const UnaryOperator *UO) {
12242ce598a4SAaron Ballman JOS.attribute("isPostfix", UO->isPostfix());
12252ce598a4SAaron Ballman JOS.attribute("opcode", UnaryOperator::getOpcodeStr(UO->getOpcode()));
12262ce598a4SAaron Ballman if (!UO->canOverflow())
12272ce598a4SAaron Ballman JOS.attribute("canOverflow", false);
12282ce598a4SAaron Ballman }
12292ce598a4SAaron Ballman
VisitBinaryOperator(const BinaryOperator * BO)12302ce598a4SAaron Ballman void JSONNodeDumper::VisitBinaryOperator(const BinaryOperator *BO) {
12312ce598a4SAaron Ballman JOS.attribute("opcode", BinaryOperator::getOpcodeStr(BO->getOpcode()));
12322ce598a4SAaron Ballman }
12332ce598a4SAaron Ballman
VisitCompoundAssignOperator(const CompoundAssignOperator * CAO)12342ce598a4SAaron Ballman void JSONNodeDumper::VisitCompoundAssignOperator(
12352ce598a4SAaron Ballman const CompoundAssignOperator *CAO) {
12362ce598a4SAaron Ballman VisitBinaryOperator(CAO);
12372ce598a4SAaron Ballman JOS.attribute("computeLHSType", createQualType(CAO->getComputationLHSType()));
12382ce598a4SAaron Ballman JOS.attribute("computeResultType",
12392ce598a4SAaron Ballman createQualType(CAO->getComputationResultType()));
12402ce598a4SAaron Ballman }
12412ce598a4SAaron Ballman
VisitMemberExpr(const MemberExpr * ME)12422ce598a4SAaron Ballman void JSONNodeDumper::VisitMemberExpr(const MemberExpr *ME) {
12432ce598a4SAaron Ballman // Note, we always write this Boolean field because the information it conveys
12442ce598a4SAaron Ballman // is critical to understanding the AST node.
1245e7b3b80fSAaron Ballman ValueDecl *VD = ME->getMemberDecl();
1246e7b3b80fSAaron Ballman JOS.attribute("name", VD && VD->getDeclName() ? VD->getNameAsString() : "");
12472ce598a4SAaron Ballman JOS.attribute("isArrow", ME->isArrow());
1248e7b3b80fSAaron Ballman JOS.attribute("referencedMemberDecl", createPointerRepresentation(VD));
12491bbad593SRichard Smith switch (ME->isNonOdrUse()) {
12501bbad593SRichard Smith case NOUR_None: break;
12511bbad593SRichard Smith case NOUR_Unevaluated: JOS.attribute("nonOdrUseReason", "unevaluated"); break;
12521bbad593SRichard Smith case NOUR_Constant: JOS.attribute("nonOdrUseReason", "constant"); break;
12531bbad593SRichard Smith case NOUR_Discarded: JOS.attribute("nonOdrUseReason", "discarded"); break;
12541bbad593SRichard Smith }
12552ce598a4SAaron Ballman }
12562ce598a4SAaron Ballman
VisitCXXNewExpr(const CXXNewExpr * NE)12572ce598a4SAaron Ballman void JSONNodeDumper::VisitCXXNewExpr(const CXXNewExpr *NE) {
12582ce598a4SAaron Ballman attributeOnlyIfTrue("isGlobal", NE->isGlobalNew());
12592ce598a4SAaron Ballman attributeOnlyIfTrue("isArray", NE->isArray());
12602ce598a4SAaron Ballman attributeOnlyIfTrue("isPlacement", NE->getNumPlacementArgs() != 0);
12612ce598a4SAaron Ballman switch (NE->getInitializationStyle()) {
12622ce598a4SAaron Ballman case CXXNewExpr::NoInit: break;
12632ce598a4SAaron Ballman case CXXNewExpr::CallInit: JOS.attribute("initStyle", "call"); break;
12642ce598a4SAaron Ballman case CXXNewExpr::ListInit: JOS.attribute("initStyle", "list"); break;
12652ce598a4SAaron Ballman }
12662ce598a4SAaron Ballman if (const FunctionDecl *FD = NE->getOperatorNew())
12672ce598a4SAaron Ballman JOS.attribute("operatorNewDecl", createBareDeclRef(FD));
12682ce598a4SAaron Ballman if (const FunctionDecl *FD = NE->getOperatorDelete())
12692ce598a4SAaron Ballman JOS.attribute("operatorDeleteDecl", createBareDeclRef(FD));
12702ce598a4SAaron Ballman }
VisitCXXDeleteExpr(const CXXDeleteExpr * DE)12712ce598a4SAaron Ballman void JSONNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *DE) {
12722ce598a4SAaron Ballman attributeOnlyIfTrue("isGlobal", DE->isGlobalDelete());
12732ce598a4SAaron Ballman attributeOnlyIfTrue("isArray", DE->isArrayForm());
12742ce598a4SAaron Ballman attributeOnlyIfTrue("isArrayAsWritten", DE->isArrayFormAsWritten());
12752ce598a4SAaron Ballman if (const FunctionDecl *FD = DE->getOperatorDelete())
12762ce598a4SAaron Ballman JOS.attribute("operatorDeleteDecl", createBareDeclRef(FD));
12772ce598a4SAaron Ballman }
12782ce598a4SAaron Ballman
VisitCXXThisExpr(const CXXThisExpr * TE)12792ce598a4SAaron Ballman void JSONNodeDumper::VisitCXXThisExpr(const CXXThisExpr *TE) {
12802ce598a4SAaron Ballman attributeOnlyIfTrue("implicit", TE->isImplicit());
12812ce598a4SAaron Ballman }
12822ce598a4SAaron Ballman
VisitCastExpr(const CastExpr * CE)12832ce598a4SAaron Ballman void JSONNodeDumper::VisitCastExpr(const CastExpr *CE) {
12842ce598a4SAaron Ballman JOS.attribute("castKind", CE->getCastKindName());
12852ce598a4SAaron Ballman llvm::json::Array Path = createCastPath(CE);
12862ce598a4SAaron Ballman if (!Path.empty())
12872ce598a4SAaron Ballman JOS.attribute("path", std::move(Path));
12882ce598a4SAaron Ballman // FIXME: This may not be useful information as it can be obtusely gleaned
12892ce598a4SAaron Ballman // from the inner[] array.
12902ce598a4SAaron Ballman if (const NamedDecl *ND = CE->getConversionFunction())
12912ce598a4SAaron Ballman JOS.attribute("conversionFunc", createBareDeclRef(ND));
12922ce598a4SAaron Ballman }
12932ce598a4SAaron Ballman
VisitImplicitCastExpr(const ImplicitCastExpr * ICE)12942ce598a4SAaron Ballman void JSONNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *ICE) {
12952ce598a4SAaron Ballman VisitCastExpr(ICE);
12962ce598a4SAaron Ballman attributeOnlyIfTrue("isPartOfExplicitCast", ICE->isPartOfExplicitCast());
12972ce598a4SAaron Ballman }
12982ce598a4SAaron Ballman
VisitCallExpr(const CallExpr * CE)12992ce598a4SAaron Ballman void JSONNodeDumper::VisitCallExpr(const CallExpr *CE) {
13002ce598a4SAaron Ballman attributeOnlyIfTrue("adl", CE->usesADL());
13012ce598a4SAaron Ballman }
13022ce598a4SAaron Ballman
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * TTE)13032ce598a4SAaron Ballman void JSONNodeDumper::VisitUnaryExprOrTypeTraitExpr(
13042ce598a4SAaron Ballman const UnaryExprOrTypeTraitExpr *TTE) {
130578e636b3SBruno Ricci JOS.attribute("name", getTraitSpelling(TTE->getKind()));
13062ce598a4SAaron Ballman if (TTE->isArgumentType())
13072ce598a4SAaron Ballman JOS.attribute("argType", createQualType(TTE->getArgumentType()));
13082ce598a4SAaron Ballman }
13092ce598a4SAaron Ballman
VisitSizeOfPackExpr(const SizeOfPackExpr * SOPE)1310bcc0cedfSAaron Ballman void JSONNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *SOPE) {
1311bcc0cedfSAaron Ballman VisitNamedDecl(SOPE->getPack());
1312bcc0cedfSAaron Ballman }
1313bcc0cedfSAaron Ballman
VisitUnresolvedLookupExpr(const UnresolvedLookupExpr * ULE)13142ce598a4SAaron Ballman void JSONNodeDumper::VisitUnresolvedLookupExpr(
13152ce598a4SAaron Ballman const UnresolvedLookupExpr *ULE) {
13162ce598a4SAaron Ballman JOS.attribute("usesADL", ULE->requiresADL());
13172ce598a4SAaron Ballman JOS.attribute("name", ULE->getName().getAsString());
13182ce598a4SAaron Ballman
13192ce598a4SAaron Ballman JOS.attributeArray("lookups", [this, ULE] {
13202ce598a4SAaron Ballman for (const NamedDecl *D : ULE->decls())
13212ce598a4SAaron Ballman JOS.value(createBareDeclRef(D));
13222ce598a4SAaron Ballman });
13232ce598a4SAaron Ballman }
13242ce598a4SAaron Ballman
VisitAddrLabelExpr(const AddrLabelExpr * ALE)13252ce598a4SAaron Ballman void JSONNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *ALE) {
13262ce598a4SAaron Ballman JOS.attribute("name", ALE->getLabel()->getName());
13272ce598a4SAaron Ballman JOS.attribute("labelDeclId", createPointerRepresentation(ALE->getLabel()));
13282ce598a4SAaron Ballman }
13292ce598a4SAaron Ballman
VisitCXXTypeidExpr(const CXXTypeidExpr * CTE)1330e091ab1bSAaron Ballman void JSONNodeDumper::VisitCXXTypeidExpr(const CXXTypeidExpr *CTE) {
1331e091ab1bSAaron Ballman if (CTE->isTypeOperand()) {
1332e091ab1bSAaron Ballman QualType Adjusted = CTE->getTypeOperand(Ctx);
1333e091ab1bSAaron Ballman QualType Unadjusted = CTE->getTypeOperandSourceInfo()->getType();
1334e091ab1bSAaron Ballman JOS.attribute("typeArg", createQualType(Unadjusted));
1335e091ab1bSAaron Ballman if (Adjusted != Unadjusted)
1336e091ab1bSAaron Ballman JOS.attribute("adjustedTypeArg", createQualType(Adjusted));
1337e091ab1bSAaron Ballman }
1338e091ab1bSAaron Ballman }
1339e091ab1bSAaron Ballman
VisitConstantExpr(const ConstantExpr * CE)134091f72657SAaron Ballman void JSONNodeDumper::VisitConstantExpr(const ConstantExpr *CE) {
1341f63e3ea5SBruno Ricci if (CE->getResultAPValueKind() != APValue::None)
1342f63e3ea5SBruno Ricci Visit(CE->getAPValueResult(), CE->getType());
134391f72657SAaron Ballman }
134491f72657SAaron Ballman
VisitInitListExpr(const InitListExpr * ILE)1345709a769cSAaron Ballman void JSONNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {
1346709a769cSAaron Ballman if (const FieldDecl *FD = ILE->getInitializedFieldInUnion())
1347709a769cSAaron Ballman JOS.attribute("field", createBareDeclRef(FD));
1348709a769cSAaron Ballman }
1349709a769cSAaron Ballman
VisitGenericSelectionExpr(const GenericSelectionExpr * GSE)135007e6da93SAaron Ballman void JSONNodeDumper::VisitGenericSelectionExpr(
135107e6da93SAaron Ballman const GenericSelectionExpr *GSE) {
135207e6da93SAaron Ballman attributeOnlyIfTrue("resultDependent", GSE->isResultDependent());
135307e6da93SAaron Ballman }
135407e6da93SAaron Ballman
VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr * UCE)1355d91b1edfSAaron Ballman void JSONNodeDumper::VisitCXXUnresolvedConstructExpr(
1356d91b1edfSAaron Ballman const CXXUnresolvedConstructExpr *UCE) {
1357d91b1edfSAaron Ballman if (UCE->getType() != UCE->getTypeAsWritten())
1358d91b1edfSAaron Ballman JOS.attribute("typeAsWritten", createQualType(UCE->getTypeAsWritten()));
1359d91b1edfSAaron Ballman attributeOnlyIfTrue("list", UCE->isListInitialization());
1360d91b1edfSAaron Ballman }
1361d91b1edfSAaron Ballman
VisitCXXConstructExpr(const CXXConstructExpr * CE)1362d91b1edfSAaron Ballman void JSONNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *CE) {
1363d91b1edfSAaron Ballman CXXConstructorDecl *Ctor = CE->getConstructor();
1364d91b1edfSAaron Ballman JOS.attribute("ctorType", createQualType(Ctor->getType()));
1365d91b1edfSAaron Ballman attributeOnlyIfTrue("elidable", CE->isElidable());
1366d91b1edfSAaron Ballman attributeOnlyIfTrue("list", CE->isListInitialization());
1367d91b1edfSAaron Ballman attributeOnlyIfTrue("initializer_list", CE->isStdInitListInitialization());
1368d91b1edfSAaron Ballman attributeOnlyIfTrue("zeroing", CE->requiresZeroInitialization());
1369d91b1edfSAaron Ballman attributeOnlyIfTrue("hadMultipleCandidates", CE->hadMultipleCandidates());
1370d91b1edfSAaron Ballman
1371d91b1edfSAaron Ballman switch (CE->getConstructionKind()) {
1372d91b1edfSAaron Ballman case CXXConstructExpr::CK_Complete:
1373d91b1edfSAaron Ballman JOS.attribute("constructionKind", "complete");
1374d91b1edfSAaron Ballman break;
1375d91b1edfSAaron Ballman case CXXConstructExpr::CK_Delegating:
1376d91b1edfSAaron Ballman JOS.attribute("constructionKind", "delegating");
1377d91b1edfSAaron Ballman break;
1378d91b1edfSAaron Ballman case CXXConstructExpr::CK_NonVirtualBase:
1379d91b1edfSAaron Ballman JOS.attribute("constructionKind", "non-virtual base");
1380d91b1edfSAaron Ballman break;
1381d91b1edfSAaron Ballman case CXXConstructExpr::CK_VirtualBase:
1382d91b1edfSAaron Ballman JOS.attribute("constructionKind", "virtual base");
1383d91b1edfSAaron Ballman break;
1384d91b1edfSAaron Ballman }
1385d91b1edfSAaron Ballman }
1386d91b1edfSAaron Ballman
VisitExprWithCleanups(const ExprWithCleanups * EWC)13871fffe8d6SAaron Ballman void JSONNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *EWC) {
13881fffe8d6SAaron Ballman attributeOnlyIfTrue("cleanupsHaveSideEffects",
13891fffe8d6SAaron Ballman EWC->cleanupsHaveSideEffects());
13901fffe8d6SAaron Ballman if (EWC->getNumObjects()) {
13911fffe8d6SAaron Ballman JOS.attributeArray("cleanups", [this, EWC] {
13921fffe8d6SAaron Ballman for (const ExprWithCleanups::CleanupObject &CO : EWC->getObjects())
139340568fecSAkira Hatanaka if (auto *BD = CO.dyn_cast<BlockDecl *>()) {
139440568fecSAkira Hatanaka JOS.value(createBareDeclRef(BD));
139540568fecSAkira Hatanaka } else if (auto *CLE = CO.dyn_cast<CompoundLiteralExpr *>()) {
139640568fecSAkira Hatanaka llvm::json::Object Obj;
139740568fecSAkira Hatanaka Obj["id"] = createPointerRepresentation(CLE);
139840568fecSAkira Hatanaka Obj["kind"] = CLE->getStmtClassName();
139940568fecSAkira Hatanaka JOS.value(std::move(Obj));
140040568fecSAkira Hatanaka } else {
140140568fecSAkira Hatanaka llvm_unreachable("unexpected cleanup object type");
140240568fecSAkira Hatanaka }
14031fffe8d6SAaron Ballman });
14041fffe8d6SAaron Ballman }
14051fffe8d6SAaron Ballman }
14061fffe8d6SAaron Ballman
VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr * BTE)14071fffe8d6SAaron Ballman void JSONNodeDumper::VisitCXXBindTemporaryExpr(
14081fffe8d6SAaron Ballman const CXXBindTemporaryExpr *BTE) {
14091fffe8d6SAaron Ballman const CXXTemporary *Temp = BTE->getTemporary();
14101fffe8d6SAaron Ballman JOS.attribute("temp", createPointerRepresentation(Temp));
14111fffe8d6SAaron Ballman if (const CXXDestructorDecl *Dtor = Temp->getDestructor())
14121fffe8d6SAaron Ballman JOS.attribute("dtor", createBareDeclRef(Dtor));
14131fffe8d6SAaron Ballman }
14141fffe8d6SAaron Ballman
VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr * MTE)14151fffe8d6SAaron Ballman void JSONNodeDumper::VisitMaterializeTemporaryExpr(
14161fffe8d6SAaron Ballman const MaterializeTemporaryExpr *MTE) {
14171fffe8d6SAaron Ballman if (const ValueDecl *VD = MTE->getExtendingDecl())
14181fffe8d6SAaron Ballman JOS.attribute("extendingDecl", createBareDeclRef(VD));
14191fffe8d6SAaron Ballman
14201fffe8d6SAaron Ballman switch (MTE->getStorageDuration()) {
14211fffe8d6SAaron Ballman case SD_Automatic:
14221fffe8d6SAaron Ballman JOS.attribute("storageDuration", "automatic");
14231fffe8d6SAaron Ballman break;
14241fffe8d6SAaron Ballman case SD_Dynamic:
14251fffe8d6SAaron Ballman JOS.attribute("storageDuration", "dynamic");
14261fffe8d6SAaron Ballman break;
14271fffe8d6SAaron Ballman case SD_FullExpression:
14281fffe8d6SAaron Ballman JOS.attribute("storageDuration", "full expression");
14291fffe8d6SAaron Ballman break;
14301fffe8d6SAaron Ballman case SD_Static:
14311fffe8d6SAaron Ballman JOS.attribute("storageDuration", "static");
14321fffe8d6SAaron Ballman break;
14331fffe8d6SAaron Ballman case SD_Thread:
14341fffe8d6SAaron Ballman JOS.attribute("storageDuration", "thread");
14351fffe8d6SAaron Ballman break;
14361fffe8d6SAaron Ballman }
14371fffe8d6SAaron Ballman
14381fffe8d6SAaron Ballman attributeOnlyIfTrue("boundToLValueRef", MTE->isBoundToLvalueReference());
14391fffe8d6SAaron Ballman }
14401fffe8d6SAaron Ballman
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr * DSME)14417dbb3a8fSAaron Ballman void JSONNodeDumper::VisitCXXDependentScopeMemberExpr(
14427dbb3a8fSAaron Ballman const CXXDependentScopeMemberExpr *DSME) {
14437dbb3a8fSAaron Ballman JOS.attribute("isArrow", DSME->isArrow());
14447dbb3a8fSAaron Ballman JOS.attribute("member", DSME->getMember().getAsString());
14457dbb3a8fSAaron Ballman attributeOnlyIfTrue("hasTemplateKeyword", DSME->hasTemplateKeyword());
14467dbb3a8fSAaron Ballman attributeOnlyIfTrue("hasExplicitTemplateArgs",
14477dbb3a8fSAaron Ballman DSME->hasExplicitTemplateArgs());
14487dbb3a8fSAaron Ballman
14497dbb3a8fSAaron Ballman if (DSME->getNumTemplateArgs()) {
14507dbb3a8fSAaron Ballman JOS.attributeArray("explicitTemplateArgs", [DSME, this] {
14517dbb3a8fSAaron Ballman for (const TemplateArgumentLoc &TAL : DSME->template_arguments())
14527dbb3a8fSAaron Ballman JOS.object(
14537dbb3a8fSAaron Ballman [&TAL, this] { Visit(TAL.getArgument(), TAL.getSourceRange()); });
14547dbb3a8fSAaron Ballman });
14557dbb3a8fSAaron Ballman }
14567dbb3a8fSAaron Ballman }
14577dbb3a8fSAaron Ballman
VisitRequiresExpr(const RequiresExpr * RE)1458ef227b32SRichard Smith void JSONNodeDumper::VisitRequiresExpr(const RequiresExpr *RE) {
1459ef227b32SRichard Smith if (!RE->isValueDependent())
1460ef227b32SRichard Smith JOS.attribute("satisfied", RE->isSatisfied());
1461ef227b32SRichard Smith }
1462ef227b32SRichard Smith
VisitIntegerLiteral(const IntegerLiteral * IL)14632ce598a4SAaron Ballman void JSONNodeDumper::VisitIntegerLiteral(const IntegerLiteral *IL) {
1464f3fd36e5SSimon Pilgrim llvm::SmallString<16> Buffer;
1465f3fd36e5SSimon Pilgrim IL->getValue().toString(Buffer,
1466f3fd36e5SSimon Pilgrim /*Radix=*/10, IL->getType()->isSignedIntegerType());
1467f3fd36e5SSimon Pilgrim JOS.attribute("value", Buffer);
14682ce598a4SAaron Ballman }
VisitCharacterLiteral(const CharacterLiteral * CL)14692ce598a4SAaron Ballman void JSONNodeDumper::VisitCharacterLiteral(const CharacterLiteral *CL) {
14702ce598a4SAaron Ballman // FIXME: This should probably print the character literal as a string,
14714aee1b5bSAaron Ballman // rather than as a numerical value. It would be nice if the behavior matched
14724aee1b5bSAaron Ballman // what we do to print a string literal; right now, it is impossible to tell
14734aee1b5bSAaron Ballman // the difference between 'a' and L'a' in C from the JSON output.
14742ce598a4SAaron Ballman JOS.attribute("value", CL->getValue());
14752ce598a4SAaron Ballman }
VisitFixedPointLiteral(const FixedPointLiteral * FPL)14762ce598a4SAaron Ballman void JSONNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *FPL) {
14772ce598a4SAaron Ballman JOS.attribute("value", FPL->getValueAsString(/*Radix=*/10));
14782ce598a4SAaron Ballman }
VisitFloatingLiteral(const FloatingLiteral * FL)14792ce598a4SAaron Ballman void JSONNodeDumper::VisitFloatingLiteral(const FloatingLiteral *FL) {
1480d44edfc1SNathan James llvm::SmallString<16> Buffer;
14814d08f899SAaron Ballman FL->getValue().toString(Buffer);
14824d08f899SAaron Ballman JOS.attribute("value", Buffer);
14832ce598a4SAaron Ballman }
VisitStringLiteral(const StringLiteral * SL)14842ce598a4SAaron Ballman void JSONNodeDumper::VisitStringLiteral(const StringLiteral *SL) {
14852ce598a4SAaron Ballman std::string Buffer;
14862ce598a4SAaron Ballman llvm::raw_string_ostream SS(Buffer);
14872ce598a4SAaron Ballman SL->outputString(SS);
14882ce598a4SAaron Ballman JOS.attribute("value", SS.str());
14892ce598a4SAaron Ballman }
VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr * BLE)14902ce598a4SAaron Ballman void JSONNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *BLE) {
14912ce598a4SAaron Ballman JOS.attribute("value", BLE->getValue());
14922ce598a4SAaron Ballman }
14932ce598a4SAaron Ballman
VisitIfStmt(const IfStmt * IS)14942ce598a4SAaron Ballman void JSONNodeDumper::VisitIfStmt(const IfStmt *IS) {
14952ce598a4SAaron Ballman attributeOnlyIfTrue("hasInit", IS->hasInitStorage());
14962ce598a4SAaron Ballman attributeOnlyIfTrue("hasVar", IS->hasVarStorage());
14972ce598a4SAaron Ballman attributeOnlyIfTrue("hasElse", IS->hasElseStorage());
14982ce598a4SAaron Ballman attributeOnlyIfTrue("isConstexpr", IS->isConstexpr());
1499424733c1SCorentin Jabot attributeOnlyIfTrue("isConsteval", IS->isConsteval());
1500424733c1SCorentin Jabot attributeOnlyIfTrue("constevalIsNegated", IS->isNegatedConsteval());
15012ce598a4SAaron Ballman }
15022ce598a4SAaron Ballman
VisitSwitchStmt(const SwitchStmt * SS)15032ce598a4SAaron Ballman void JSONNodeDumper::VisitSwitchStmt(const SwitchStmt *SS) {
15042ce598a4SAaron Ballman attributeOnlyIfTrue("hasInit", SS->hasInitStorage());
15052ce598a4SAaron Ballman attributeOnlyIfTrue("hasVar", SS->hasVarStorage());
15062ce598a4SAaron Ballman }
VisitCaseStmt(const CaseStmt * CS)15072ce598a4SAaron Ballman void JSONNodeDumper::VisitCaseStmt(const CaseStmt *CS) {
15082ce598a4SAaron Ballman attributeOnlyIfTrue("isGNURange", CS->caseStmtIsGNURange());
15092ce598a4SAaron Ballman }
15102ce598a4SAaron Ballman
VisitLabelStmt(const LabelStmt * LS)15112ce598a4SAaron Ballman void JSONNodeDumper::VisitLabelStmt(const LabelStmt *LS) {
15122ce598a4SAaron Ballman JOS.attribute("name", LS->getName());
15132ce598a4SAaron Ballman JOS.attribute("declId", createPointerRepresentation(LS->getDecl()));
1514797ad701STen Tzen attributeOnlyIfTrue("sideEntry", LS->isSideEntry());
15152ce598a4SAaron Ballman }
VisitGotoStmt(const GotoStmt * GS)15162ce598a4SAaron Ballman void JSONNodeDumper::VisitGotoStmt(const GotoStmt *GS) {
15172ce598a4SAaron Ballman JOS.attribute("targetLabelDeclId",
15182ce598a4SAaron Ballman createPointerRepresentation(GS->getLabel()));
15192ce598a4SAaron Ballman }
15202ce598a4SAaron Ballman
VisitWhileStmt(const WhileStmt * WS)15212ce598a4SAaron Ballman void JSONNodeDumper::VisitWhileStmt(const WhileStmt *WS) {
15222ce598a4SAaron Ballman attributeOnlyIfTrue("hasVar", WS->hasVarStorage());
15232ce598a4SAaron Ballman }
152486abee81SAaron Ballman
VisitObjCAtCatchStmt(const ObjCAtCatchStmt * OACS)1525fa643d70SAaron Ballman void JSONNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt* OACS) {
1526fa643d70SAaron Ballman // FIXME: it would be nice for the ASTNodeTraverser would handle the catch
1527fa643d70SAaron Ballman // parameter the same way for C++ and ObjC rather. In this case, C++ gets a
1528fa643d70SAaron Ballman // null child node and ObjC gets no child node.
1529fa643d70SAaron Ballman attributeOnlyIfTrue("isCatchAll", OACS->getCatchParamDecl() == nullptr);
1530fa643d70SAaron Ballman }
1531fa643d70SAaron Ballman
VisitNullTemplateArgument(const TemplateArgument & TA)15327556615aSAaron Ballman void JSONNodeDumper::VisitNullTemplateArgument(const TemplateArgument &TA) {
15337556615aSAaron Ballman JOS.attribute("isNull", true);
15347556615aSAaron Ballman }
VisitTypeTemplateArgument(const TemplateArgument & TA)15357556615aSAaron Ballman void JSONNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {
15367556615aSAaron Ballman JOS.attribute("type", createQualType(TA.getAsType()));
15377556615aSAaron Ballman }
VisitDeclarationTemplateArgument(const TemplateArgument & TA)15387556615aSAaron Ballman void JSONNodeDumper::VisitDeclarationTemplateArgument(
15397556615aSAaron Ballman const TemplateArgument &TA) {
15407556615aSAaron Ballman JOS.attribute("decl", createBareDeclRef(TA.getAsDecl()));
15417556615aSAaron Ballman }
VisitNullPtrTemplateArgument(const TemplateArgument & TA)15427556615aSAaron Ballman void JSONNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA) {
15437556615aSAaron Ballman JOS.attribute("isNullptr", true);
15447556615aSAaron Ballman }
VisitIntegralTemplateArgument(const TemplateArgument & TA)15457556615aSAaron Ballman void JSONNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {
15467556615aSAaron Ballman JOS.attribute("value", TA.getAsIntegral().getSExtValue());
15477556615aSAaron Ballman }
VisitTemplateTemplateArgument(const TemplateArgument & TA)15487556615aSAaron Ballman void JSONNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {
15497556615aSAaron Ballman // FIXME: cannot just call dump() on the argument, as that doesn't specify
15507556615aSAaron Ballman // the output format.
15517556615aSAaron Ballman }
VisitTemplateExpansionTemplateArgument(const TemplateArgument & TA)15527556615aSAaron Ballman void JSONNodeDumper::VisitTemplateExpansionTemplateArgument(
15537556615aSAaron Ballman const TemplateArgument &TA) {
15547556615aSAaron Ballman // FIXME: cannot just call dump() on the argument, as that doesn't specify
15557556615aSAaron Ballman // the output format.
15567556615aSAaron Ballman }
VisitExpressionTemplateArgument(const TemplateArgument & TA)15577556615aSAaron Ballman void JSONNodeDumper::VisitExpressionTemplateArgument(
15587556615aSAaron Ballman const TemplateArgument &TA) {
15597556615aSAaron Ballman JOS.attribute("isExpr", true);
15607556615aSAaron Ballman }
VisitPackTemplateArgument(const TemplateArgument & TA)15617556615aSAaron Ballman void JSONNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) {
15627556615aSAaron Ballman JOS.attribute("isPack", true);
15637556615aSAaron Ballman }
15647556615aSAaron Ballman
getCommentCommandName(unsigned CommandID) const156586abee81SAaron Ballman StringRef JSONNodeDumper::getCommentCommandName(unsigned CommandID) const {
156686abee81SAaron Ballman if (Traits)
156786abee81SAaron Ballman return Traits->getCommandInfo(CommandID)->Name;
156886abee81SAaron Ballman if (const comments::CommandInfo *Info =
156986abee81SAaron Ballman comments::CommandTraits::getBuiltinCommandInfo(CommandID))
157086abee81SAaron Ballman return Info->Name;
157186abee81SAaron Ballman return "<invalid>";
157286abee81SAaron Ballman }
157386abee81SAaron Ballman
visitTextComment(const comments::TextComment * C,const comments::FullComment *)157486abee81SAaron Ballman void JSONNodeDumper::visitTextComment(const comments::TextComment *C,
157586abee81SAaron Ballman const comments::FullComment *) {
157686abee81SAaron Ballman JOS.attribute("text", C->getText());
157786abee81SAaron Ballman }
157886abee81SAaron Ballman
visitInlineCommandComment(const comments::InlineCommandComment * C,const comments::FullComment *)157986abee81SAaron Ballman void JSONNodeDumper::visitInlineCommandComment(
158086abee81SAaron Ballman const comments::InlineCommandComment *C, const comments::FullComment *) {
158186abee81SAaron Ballman JOS.attribute("name", getCommentCommandName(C->getCommandID()));
158286abee81SAaron Ballman
158386abee81SAaron Ballman switch (C->getRenderKind()) {
158486abee81SAaron Ballman case comments::InlineCommandComment::RenderNormal:
158586abee81SAaron Ballman JOS.attribute("renderKind", "normal");
158686abee81SAaron Ballman break;
158786abee81SAaron Ballman case comments::InlineCommandComment::RenderBold:
158886abee81SAaron Ballman JOS.attribute("renderKind", "bold");
158986abee81SAaron Ballman break;
159086abee81SAaron Ballman case comments::InlineCommandComment::RenderEmphasized:
159186abee81SAaron Ballman JOS.attribute("renderKind", "emphasized");
159286abee81SAaron Ballman break;
159386abee81SAaron Ballman case comments::InlineCommandComment::RenderMonospaced:
159486abee81SAaron Ballman JOS.attribute("renderKind", "monospaced");
159586abee81SAaron Ballman break;
1596be1a9b38SMark de Wever case comments::InlineCommandComment::RenderAnchor:
1597be1a9b38SMark de Wever JOS.attribute("renderKind", "anchor");
1598be1a9b38SMark de Wever break;
159986abee81SAaron Ballman }
160086abee81SAaron Ballman
160186abee81SAaron Ballman llvm::json::Array Args;
160286abee81SAaron Ballman for (unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
160386abee81SAaron Ballman Args.push_back(C->getArgText(I));
160486abee81SAaron Ballman
160586abee81SAaron Ballman if (!Args.empty())
160686abee81SAaron Ballman JOS.attribute("args", std::move(Args));
160786abee81SAaron Ballman }
160886abee81SAaron Ballman
visitHTMLStartTagComment(const comments::HTMLStartTagComment * C,const comments::FullComment *)160986abee81SAaron Ballman void JSONNodeDumper::visitHTMLStartTagComment(
161086abee81SAaron Ballman const comments::HTMLStartTagComment *C, const comments::FullComment *) {
161186abee81SAaron Ballman JOS.attribute("name", C->getTagName());
161286abee81SAaron Ballman attributeOnlyIfTrue("selfClosing", C->isSelfClosing());
161386abee81SAaron Ballman attributeOnlyIfTrue("malformed", C->isMalformed());
161486abee81SAaron Ballman
161586abee81SAaron Ballman llvm::json::Array Attrs;
161686abee81SAaron Ballman for (unsigned I = 0, E = C->getNumAttrs(); I < E; ++I)
161786abee81SAaron Ballman Attrs.push_back(
161886abee81SAaron Ballman {{"name", C->getAttr(I).Name}, {"value", C->getAttr(I).Value}});
161986abee81SAaron Ballman
162086abee81SAaron Ballman if (!Attrs.empty())
162186abee81SAaron Ballman JOS.attribute("attrs", std::move(Attrs));
162286abee81SAaron Ballman }
162386abee81SAaron Ballman
visitHTMLEndTagComment(const comments::HTMLEndTagComment * C,const comments::FullComment *)162486abee81SAaron Ballman void JSONNodeDumper::visitHTMLEndTagComment(
162586abee81SAaron Ballman const comments::HTMLEndTagComment *C, const comments::FullComment *) {
162686abee81SAaron Ballman JOS.attribute("name", C->getTagName());
162786abee81SAaron Ballman }
162886abee81SAaron Ballman
visitBlockCommandComment(const comments::BlockCommandComment * C,const comments::FullComment *)162986abee81SAaron Ballman void JSONNodeDumper::visitBlockCommandComment(
163086abee81SAaron Ballman const comments::BlockCommandComment *C, const comments::FullComment *) {
163186abee81SAaron Ballman JOS.attribute("name", getCommentCommandName(C->getCommandID()));
163286abee81SAaron Ballman
163386abee81SAaron Ballman llvm::json::Array Args;
163486abee81SAaron Ballman for (unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
163586abee81SAaron Ballman Args.push_back(C->getArgText(I));
163686abee81SAaron Ballman
163786abee81SAaron Ballman if (!Args.empty())
163886abee81SAaron Ballman JOS.attribute("args", std::move(Args));
163986abee81SAaron Ballman }
164086abee81SAaron Ballman
visitParamCommandComment(const comments::ParamCommandComment * C,const comments::FullComment * FC)164186abee81SAaron Ballman void JSONNodeDumper::visitParamCommandComment(
164286abee81SAaron Ballman const comments::ParamCommandComment *C, const comments::FullComment *FC) {
164386abee81SAaron Ballman switch (C->getDirection()) {
164486abee81SAaron Ballman case comments::ParamCommandComment::In:
164586abee81SAaron Ballman JOS.attribute("direction", "in");
164686abee81SAaron Ballman break;
164786abee81SAaron Ballman case comments::ParamCommandComment::Out:
164886abee81SAaron Ballman JOS.attribute("direction", "out");
164986abee81SAaron Ballman break;
165086abee81SAaron Ballman case comments::ParamCommandComment::InOut:
165186abee81SAaron Ballman JOS.attribute("direction", "in,out");
165286abee81SAaron Ballman break;
165386abee81SAaron Ballman }
165486abee81SAaron Ballman attributeOnlyIfTrue("explicit", C->isDirectionExplicit());
165586abee81SAaron Ballman
165686abee81SAaron Ballman if (C->hasParamName())
165786abee81SAaron Ballman JOS.attribute("param", C->isParamIndexValid() ? C->getParamName(FC)
165886abee81SAaron Ballman : C->getParamNameAsWritten());
165986abee81SAaron Ballman
166086abee81SAaron Ballman if (C->isParamIndexValid() && !C->isVarArgParam())
166186abee81SAaron Ballman JOS.attribute("paramIdx", C->getParamIndex());
166286abee81SAaron Ballman }
166386abee81SAaron Ballman
visitTParamCommandComment(const comments::TParamCommandComment * C,const comments::FullComment * FC)166486abee81SAaron Ballman void JSONNodeDumper::visitTParamCommandComment(
166586abee81SAaron Ballman const comments::TParamCommandComment *C, const comments::FullComment *FC) {
166686abee81SAaron Ballman if (C->hasParamName())
166786abee81SAaron Ballman JOS.attribute("param", C->isPositionValid() ? C->getParamName(FC)
166886abee81SAaron Ballman : C->getParamNameAsWritten());
166986abee81SAaron Ballman if (C->isPositionValid()) {
167086abee81SAaron Ballman llvm::json::Array Positions;
167186abee81SAaron Ballman for (unsigned I = 0, E = C->getDepth(); I < E; ++I)
167286abee81SAaron Ballman Positions.push_back(C->getIndex(I));
167386abee81SAaron Ballman
167486abee81SAaron Ballman if (!Positions.empty())
167586abee81SAaron Ballman JOS.attribute("positions", std::move(Positions));
167686abee81SAaron Ballman }
167786abee81SAaron Ballman }
167886abee81SAaron Ballman
visitVerbatimBlockComment(const comments::VerbatimBlockComment * C,const comments::FullComment *)167986abee81SAaron Ballman void JSONNodeDumper::visitVerbatimBlockComment(
168086abee81SAaron Ballman const comments::VerbatimBlockComment *C, const comments::FullComment *) {
168186abee81SAaron Ballman JOS.attribute("name", getCommentCommandName(C->getCommandID()));
168286abee81SAaron Ballman JOS.attribute("closeName", C->getCloseName());
168386abee81SAaron Ballman }
168486abee81SAaron Ballman
visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment * C,const comments::FullComment *)168586abee81SAaron Ballman void JSONNodeDumper::visitVerbatimBlockLineComment(
168686abee81SAaron Ballman const comments::VerbatimBlockLineComment *C,
168786abee81SAaron Ballman const comments::FullComment *) {
168886abee81SAaron Ballman JOS.attribute("text", C->getText());
168986abee81SAaron Ballman }
169086abee81SAaron Ballman
visitVerbatimLineComment(const comments::VerbatimLineComment * C,const comments::FullComment *)169186abee81SAaron Ballman void JSONNodeDumper::visitVerbatimLineComment(
169286abee81SAaron Ballman const comments::VerbatimLineComment *C, const comments::FullComment *) {
169386abee81SAaron Ballman JOS.attribute("text", C->getText());
169486abee81SAaron Ballman }
1695*f7819ce1SSerge Pavlov
createFPOptions(FPOptionsOverride FPO)1696*f7819ce1SSerge Pavlov llvm::json::Object JSONNodeDumper::createFPOptions(FPOptionsOverride FPO) {
1697*f7819ce1SSerge Pavlov llvm::json::Object Ret;
1698*f7819ce1SSerge Pavlov #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
1699*f7819ce1SSerge Pavlov if (FPO.has##NAME##Override()) \
1700*f7819ce1SSerge Pavlov Ret.try_emplace(#NAME, static_cast<unsigned>(FPO.get##NAME##Override()));
1701*f7819ce1SSerge Pavlov #include "clang/Basic/FPOptions.def"
1702*f7819ce1SSerge Pavlov return Ret;
1703*f7819ce1SSerge Pavlov }
1704*f7819ce1SSerge Pavlov
VisitCompoundStmt(const CompoundStmt * S)1705*f7819ce1SSerge Pavlov void JSONNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {
1706*f7819ce1SSerge Pavlov VisitStmt(S);
1707*f7819ce1SSerge Pavlov if (S->hasStoredFPFeatures())
1708*f7819ce1SSerge Pavlov JOS.attribute("fpoptions", createFPOptions(S->getStoredFPFeatures()));
1709*f7819ce1SSerge Pavlov }
1710