1 #include "clang/AST/JSONNodeDumper.h"
2 #include "clang/AST/Type.h"
3 #include "clang/Basic/SourceManager.h"
4 #include "clang/Basic/Specifiers.h"
5 #include "clang/Lex/Lexer.h"
6 #include "llvm/ADT/StringExtras.h"
11 void JSONNodeDumper::addPreviousDeclaration(const Decl
*D
) {
12 switch (D
->getKind()) {
13 #define DECL(DERIVED, BASE) \
15 return writePreviousDeclImpl(cast<DERIVED##Decl>(D));
16 #define ABSTRACT_DECL(DECL)
17 #include "clang/AST/DeclNodes.inc"
21 llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
24 void JSONNodeDumper::Visit(const Attr
*A
) {
25 const char *AttrName
= nullptr;
26 switch (A
->getKind()) {
29 AttrName = #X"Attr"; \
31 #include "clang/Basic/AttrList.inc"
34 JOS
.attribute("id", createPointerRepresentation(A
));
35 JOS
.attribute("kind", AttrName
);
36 JOS
.attributeObject("range", [A
, this] { writeSourceRange(A
->getRange()); });
37 attributeOnlyIfTrue("inherited", A
->isInherited());
38 attributeOnlyIfTrue("implicit", A
->isImplicit());
40 // FIXME: it would be useful for us to output the spelling kind as well as
41 // the actual spelling. This would allow us to distinguish between the
42 // various attribute syntaxes, but we don't currently track that information
44 //JOS.attribute("spelling", A->getSpelling());
46 InnerAttrVisitor::Visit(A
);
49 void JSONNodeDumper::Visit(const Stmt
*S
) {
53 JOS
.attribute("id", createPointerRepresentation(S
));
54 JOS
.attribute("kind", S
->getStmtClassName());
55 JOS
.attributeObject("range",
56 [S
, this] { writeSourceRange(S
->getSourceRange()); });
58 if (const auto *E
= dyn_cast
<Expr
>(S
)) {
59 JOS
.attribute("type", createQualType(E
->getType()));
60 const char *Category
= nullptr;
61 switch (E
->getValueKind()) {
62 case VK_LValue
: Category
= "lvalue"; break;
63 case VK_XValue
: Category
= "xvalue"; break;
68 JOS
.attribute("valueCategory", Category
);
70 InnerStmtVisitor::Visit(S
);
73 void JSONNodeDumper::Visit(const Type
*T
) {
74 JOS
.attribute("id", createPointerRepresentation(T
));
79 JOS
.attribute("kind", (llvm::Twine(T
->getTypeClassName()) + "Type").str());
80 JOS
.attribute("type", createQualType(QualType(T
, 0), /*Desugar=*/false));
81 attributeOnlyIfTrue("containsErrors", T
->containsErrors());
82 attributeOnlyIfTrue("isDependent", T
->isDependentType());
83 attributeOnlyIfTrue("isInstantiationDependent",
84 T
->isInstantiationDependentType());
85 attributeOnlyIfTrue("isVariablyModified", T
->isVariablyModifiedType());
86 attributeOnlyIfTrue("containsUnexpandedPack",
87 T
->containsUnexpandedParameterPack());
88 attributeOnlyIfTrue("isImported", T
->isFromAST());
89 InnerTypeVisitor::Visit(T
);
92 void JSONNodeDumper::Visit(QualType T
) {
93 JOS
.attribute("id", createPointerRepresentation(T
.getAsOpaquePtr()));
94 JOS
.attribute("kind", "QualType");
95 JOS
.attribute("type", createQualType(T
));
96 JOS
.attribute("qualifiers", T
.split().Quals
.getAsString());
99 void JSONNodeDumper::Visit(TypeLoc TL
) {
102 JOS
.attribute("kind",
103 (llvm::Twine(TL
.getTypeLocClass() == TypeLoc::Qualified
105 : TL
.getTypePtr()->getTypeClassName()) +
108 JOS
.attribute("type",
109 createQualType(QualType(TL
.getType()), /*Desugar=*/false));
110 JOS
.attributeObject("range",
111 [TL
, this] { writeSourceRange(TL
.getSourceRange()); });
114 void JSONNodeDumper::Visit(const Decl
*D
) {
115 JOS
.attribute("id", createPointerRepresentation(D
));
120 JOS
.attribute("kind", (llvm::Twine(D
->getDeclKindName()) + "Decl").str());
121 JOS
.attributeObject("loc",
122 [D
, this] { writeSourceLocation(D
->getLocation()); });
123 JOS
.attributeObject("range",
124 [D
, this] { writeSourceRange(D
->getSourceRange()); });
125 attributeOnlyIfTrue("isImplicit", D
->isImplicit());
126 attributeOnlyIfTrue("isInvalid", D
->isInvalidDecl());
129 JOS
.attribute("isUsed", true);
130 else if (D
->isThisDeclarationReferenced())
131 JOS
.attribute("isReferenced", true);
133 if (const auto *ND
= dyn_cast
<NamedDecl
>(D
))
134 attributeOnlyIfTrue("isHidden", !ND
->isUnconditionallyVisible());
136 if (D
->getLexicalDeclContext() != D
->getDeclContext()) {
137 // Because of multiple inheritance, a DeclContext pointer does not produce
138 // the same pointer representation as a Decl pointer that references the
140 const auto *ParentDeclContextDecl
= dyn_cast
<Decl
>(D
->getDeclContext());
141 JOS
.attribute("parentDeclContextId",
142 createPointerRepresentation(ParentDeclContextDecl
));
145 addPreviousDeclaration(D
);
146 InnerDeclVisitor::Visit(D
);
149 void JSONNodeDumper::Visit(const comments::Comment
*C
,
150 const comments::FullComment
*FC
) {
154 JOS
.attribute("id", createPointerRepresentation(C
));
155 JOS
.attribute("kind", C
->getCommentKindName());
156 JOS
.attributeObject("loc",
157 [C
, this] { writeSourceLocation(C
->getLocation()); });
158 JOS
.attributeObject("range",
159 [C
, this] { writeSourceRange(C
->getSourceRange()); });
161 InnerCommentVisitor::visit(C
, FC
);
164 void JSONNodeDumper::Visit(const TemplateArgument
&TA
, SourceRange R
,
165 const Decl
*From
, StringRef Label
) {
166 JOS
.attribute("kind", "TemplateArgument");
168 JOS
.attributeObject("range", [R
, this] { writeSourceRange(R
); });
171 JOS
.attribute(Label
.empty() ? "fromDecl" : Label
, createBareDeclRef(From
));
173 InnerTemplateArgVisitor::Visit(TA
);
176 void JSONNodeDumper::Visit(const CXXCtorInitializer
*Init
) {
177 JOS
.attribute("kind", "CXXCtorInitializer");
178 if (Init
->isAnyMemberInitializer())
179 JOS
.attribute("anyInit", createBareDeclRef(Init
->getAnyMember()));
180 else if (Init
->isBaseInitializer())
181 JOS
.attribute("baseInit",
182 createQualType(QualType(Init
->getBaseClass(), 0)));
183 else if (Init
->isDelegatingInitializer())
184 JOS
.attribute("delegatingInit",
185 createQualType(Init
->getTypeSourceInfo()->getType()));
187 llvm_unreachable("Unknown initializer type");
190 void JSONNodeDumper::Visit(const OpenACCClause
*C
) {}
192 void JSONNodeDumper::Visit(const OMPClause
*C
) {}
194 void JSONNodeDumper::Visit(const BlockDecl::Capture
&C
) {
195 JOS
.attribute("kind", "Capture");
196 attributeOnlyIfTrue("byref", C
.isByRef());
197 attributeOnlyIfTrue("nested", C
.isNested());
199 JOS
.attribute("var", createBareDeclRef(C
.getVariable()));
202 void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation
&A
) {
203 JOS
.attribute("associationKind", A
.getTypeSourceInfo() ? "case" : "default");
204 attributeOnlyIfTrue("selected", A
.isSelected());
207 void JSONNodeDumper::Visit(const concepts::Requirement
*R
) {
211 switch (R
->getKind()) {
212 case concepts::Requirement::RK_Type
:
213 JOS
.attribute("kind", "TypeRequirement");
215 case concepts::Requirement::RK_Simple
:
216 JOS
.attribute("kind", "SimpleRequirement");
218 case concepts::Requirement::RK_Compound
:
219 JOS
.attribute("kind", "CompoundRequirement");
221 case concepts::Requirement::RK_Nested
:
222 JOS
.attribute("kind", "NestedRequirement");
226 if (auto *ER
= dyn_cast
<concepts::ExprRequirement
>(R
))
227 attributeOnlyIfTrue("noexcept", ER
->hasNoexceptRequirement());
229 attributeOnlyIfTrue("isDependent", R
->isDependent());
230 if (!R
->isDependent())
231 JOS
.attribute("satisfied", R
->isSatisfied());
232 attributeOnlyIfTrue("containsUnexpandedPack",
233 R
->containsUnexpandedParameterPack());
236 void JSONNodeDumper::Visit(const APValue
&Value
, QualType Ty
) {
238 llvm::raw_string_ostream
OS(Str
);
239 Value
.printPretty(OS
, Ctx
, Ty
);
240 JOS
.attribute("value", Str
);
243 void JSONNodeDumper::Visit(const ConceptReference
*CR
) {
244 JOS
.attribute("kind", "ConceptReference");
245 JOS
.attribute("id", createPointerRepresentation(CR
->getNamedConcept()));
246 if (const auto *Args
= CR
->getTemplateArgsAsWritten()) {
247 JOS
.attributeArray("templateArgsAsWritten", [Args
, this] {
248 for (const TemplateArgumentLoc
&TAL
: Args
->arguments())
250 [&TAL
, this] { Visit(TAL
.getArgument(), TAL
.getSourceRange()); });
253 JOS
.attributeObject("loc",
254 [CR
, this] { writeSourceLocation(CR
->getLocation()); });
255 JOS
.attributeObject("range",
256 [CR
, this] { writeSourceRange(CR
->getSourceRange()); });
259 void JSONNodeDumper::writeIncludeStack(PresumedLoc Loc
, bool JustFirst
) {
263 JOS
.attributeBegin("includedFrom");
267 // Walk the stack recursively, then print out the presumed location.
268 writeIncludeStack(SM
.getPresumedLoc(Loc
.getIncludeLoc()));
271 JOS
.attribute("file", Loc
.getFilename());
276 void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc
,
278 PresumedLoc Presumed
= SM
.getPresumedLoc(Loc
);
279 unsigned ActualLine
= IsSpelling
? SM
.getSpellingLineNumber(Loc
)
280 : SM
.getExpansionLineNumber(Loc
);
281 StringRef ActualFile
= SM
.getBufferName(Loc
);
283 if (Presumed
.isValid()) {
284 JOS
.attribute("offset", SM
.getDecomposedLoc(Loc
).second
);
285 if (LastLocFilename
!= ActualFile
) {
286 JOS
.attribute("file", ActualFile
);
287 JOS
.attribute("line", ActualLine
);
288 } else if (LastLocLine
!= ActualLine
)
289 JOS
.attribute("line", ActualLine
);
291 StringRef PresumedFile
= Presumed
.getFilename();
292 if (PresumedFile
!= ActualFile
&& LastLocPresumedFilename
!= PresumedFile
)
293 JOS
.attribute("presumedFile", PresumedFile
);
295 unsigned PresumedLine
= Presumed
.getLine();
296 if (ActualLine
!= PresumedLine
&& LastLocPresumedLine
!= PresumedLine
)
297 JOS
.attribute("presumedLine", PresumedLine
);
299 JOS
.attribute("col", Presumed
.getColumn());
300 JOS
.attribute("tokLen",
301 Lexer::MeasureTokenLength(Loc
, SM
, Ctx
.getLangOpts()));
302 LastLocFilename
= ActualFile
;
303 LastLocPresumedFilename
= PresumedFile
;
304 LastLocPresumedLine
= PresumedLine
;
305 LastLocLine
= ActualLine
;
307 // Orthogonal to the file, line, and column de-duplication is whether the
308 // given location was a result of an include. If so, print where the
309 // include location came from.
310 writeIncludeStack(SM
.getPresumedLoc(Presumed
.getIncludeLoc()),
315 void JSONNodeDumper::writeSourceLocation(SourceLocation Loc
) {
316 SourceLocation Spelling
= SM
.getSpellingLoc(Loc
);
317 SourceLocation Expansion
= SM
.getExpansionLoc(Loc
);
319 if (Expansion
!= Spelling
) {
320 // If the expansion and the spelling are different, output subobjects
321 // describing both locations.
322 JOS
.attributeObject("spellingLoc", [Spelling
, this] {
323 writeBareSourceLocation(Spelling
, /*IsSpelling*/ true);
325 JOS
.attributeObject("expansionLoc", [Expansion
, Loc
, this] {
326 writeBareSourceLocation(Expansion
, /*IsSpelling*/ false);
327 // If there is a macro expansion, add extra information if the interesting
328 // bit is the macro arg expansion.
329 if (SM
.isMacroArgExpansion(Loc
))
330 JOS
.attribute("isMacroArgExpansion", true);
333 writeBareSourceLocation(Spelling
, /*IsSpelling*/ true);
336 void JSONNodeDumper::writeSourceRange(SourceRange R
) {
337 JOS
.attributeObject("begin",
338 [R
, this] { writeSourceLocation(R
.getBegin()); });
339 JOS
.attributeObject("end", [R
, this] { writeSourceLocation(R
.getEnd()); });
342 std::string
JSONNodeDumper::createPointerRepresentation(const void *Ptr
) {
343 // Because JSON stores integer values as signed 64-bit integers, trying to
344 // represent them as such makes for very ugly pointer values in the resulting
345 // output. Instead, we convert the value to hex and treat it as a string.
346 return "0x" + llvm::utohexstr(reinterpret_cast<uint64_t>(Ptr
), true);
349 llvm::json::Object
JSONNodeDumper::createQualType(QualType QT
, bool Desugar
) {
350 SplitQualType SQT
= QT
.split();
351 std::string SQTS
= QualType::getAsString(SQT
, PrintPolicy
);
352 llvm::json::Object Ret
{{"qualType", SQTS
}};
354 if (Desugar
&& !QT
.isNull()) {
355 SplitQualType DSQT
= QT
.getSplitDesugaredType();
357 std::string DSQTS
= QualType::getAsString(DSQT
, PrintPolicy
);
359 Ret
["desugaredQualType"] = DSQTS
;
361 if (const auto *TT
= QT
->getAs
<TypedefType
>())
362 Ret
["typeAliasDeclId"] = createPointerRepresentation(TT
->getDecl());
367 void JSONNodeDumper::writeBareDeclRef(const Decl
*D
) {
368 JOS
.attribute("id", createPointerRepresentation(D
));
372 JOS
.attribute("kind", (llvm::Twine(D
->getDeclKindName()) + "Decl").str());
373 if (const auto *ND
= dyn_cast
<NamedDecl
>(D
))
374 JOS
.attribute("name", ND
->getDeclName().getAsString());
375 if (const auto *VD
= dyn_cast
<ValueDecl
>(D
))
376 JOS
.attribute("type", createQualType(VD
->getType()));
379 llvm::json::Object
JSONNodeDumper::createBareDeclRef(const Decl
*D
) {
380 llvm::json::Object Ret
{{"id", createPointerRepresentation(D
)}};
384 Ret
["kind"] = (llvm::Twine(D
->getDeclKindName()) + "Decl").str();
385 if (const auto *ND
= dyn_cast
<NamedDecl
>(D
))
386 Ret
["name"] = ND
->getDeclName().getAsString();
387 if (const auto *VD
= dyn_cast
<ValueDecl
>(D
))
388 Ret
["type"] = createQualType(VD
->getType());
392 llvm::json::Array
JSONNodeDumper::createCastPath(const CastExpr
*C
) {
393 llvm::json::Array Ret
;
397 for (auto I
= C
->path_begin(), E
= C
->path_end(); I
!= E
; ++I
) {
398 const CXXBaseSpecifier
*Base
= *I
;
400 cast
<CXXRecordDecl
>(Base
->getType()->castAs
<RecordType
>()->getDecl());
402 llvm::json::Object Val
{{"name", RD
->getName()}};
403 if (Base
->isVirtual())
404 Val
["isVirtual"] = true;
405 Ret
.push_back(std::move(Val
));
410 #define FIELD2(Name, Flag) if (RD->Flag()) Ret[Name] = true
411 #define FIELD1(Flag) FIELD2(#Flag, Flag)
413 static llvm::json::Object
414 createDefaultConstructorDefinitionData(const CXXRecordDecl
*RD
) {
415 llvm::json::Object Ret
;
417 FIELD2("exists", hasDefaultConstructor
);
418 FIELD2("trivial", hasTrivialDefaultConstructor
);
419 FIELD2("nonTrivial", hasNonTrivialDefaultConstructor
);
420 FIELD2("userProvided", hasUserProvidedDefaultConstructor
);
421 FIELD2("isConstexpr", hasConstexprDefaultConstructor
);
422 FIELD2("needsImplicit", needsImplicitDefaultConstructor
);
423 FIELD2("defaultedIsConstexpr", defaultedDefaultConstructorIsConstexpr
);
428 static llvm::json::Object
429 createCopyConstructorDefinitionData(const CXXRecordDecl
*RD
) {
430 llvm::json::Object Ret
;
432 FIELD2("simple", hasSimpleCopyConstructor
);
433 FIELD2("trivial", hasTrivialCopyConstructor
);
434 FIELD2("nonTrivial", hasNonTrivialCopyConstructor
);
435 FIELD2("userDeclared", hasUserDeclaredCopyConstructor
);
436 FIELD2("hasConstParam", hasCopyConstructorWithConstParam
);
437 FIELD2("implicitHasConstParam", implicitCopyConstructorHasConstParam
);
438 FIELD2("needsImplicit", needsImplicitCopyConstructor
);
439 FIELD2("needsOverloadResolution", needsOverloadResolutionForCopyConstructor
);
440 if (!RD
->needsOverloadResolutionForCopyConstructor())
441 FIELD2("defaultedIsDeleted", defaultedCopyConstructorIsDeleted
);
446 static llvm::json::Object
447 createMoveConstructorDefinitionData(const CXXRecordDecl
*RD
) {
448 llvm::json::Object Ret
;
450 FIELD2("exists", hasMoveConstructor
);
451 FIELD2("simple", hasSimpleMoveConstructor
);
452 FIELD2("trivial", hasTrivialMoveConstructor
);
453 FIELD2("nonTrivial", hasNonTrivialMoveConstructor
);
454 FIELD2("userDeclared", hasUserDeclaredMoveConstructor
);
455 FIELD2("needsImplicit", needsImplicitMoveConstructor
);
456 FIELD2("needsOverloadResolution", needsOverloadResolutionForMoveConstructor
);
457 if (!RD
->needsOverloadResolutionForMoveConstructor())
458 FIELD2("defaultedIsDeleted", defaultedMoveConstructorIsDeleted
);
463 static llvm::json::Object
464 createCopyAssignmentDefinitionData(const CXXRecordDecl
*RD
) {
465 llvm::json::Object Ret
;
467 FIELD2("simple", hasSimpleCopyAssignment
);
468 FIELD2("trivial", hasTrivialCopyAssignment
);
469 FIELD2("nonTrivial", hasNonTrivialCopyAssignment
);
470 FIELD2("hasConstParam", hasCopyAssignmentWithConstParam
);
471 FIELD2("implicitHasConstParam", implicitCopyAssignmentHasConstParam
);
472 FIELD2("userDeclared", hasUserDeclaredCopyAssignment
);
473 FIELD2("needsImplicit", needsImplicitCopyAssignment
);
474 FIELD2("needsOverloadResolution", needsOverloadResolutionForCopyAssignment
);
479 static llvm::json::Object
480 createMoveAssignmentDefinitionData(const CXXRecordDecl
*RD
) {
481 llvm::json::Object Ret
;
483 FIELD2("exists", hasMoveAssignment
);
484 FIELD2("simple", hasSimpleMoveAssignment
);
485 FIELD2("trivial", hasTrivialMoveAssignment
);
486 FIELD2("nonTrivial", hasNonTrivialMoveAssignment
);
487 FIELD2("userDeclared", hasUserDeclaredMoveAssignment
);
488 FIELD2("needsImplicit", needsImplicitMoveAssignment
);
489 FIELD2("needsOverloadResolution", needsOverloadResolutionForMoveAssignment
);
494 static llvm::json::Object
495 createDestructorDefinitionData(const CXXRecordDecl
*RD
) {
496 llvm::json::Object Ret
;
498 FIELD2("simple", hasSimpleDestructor
);
499 FIELD2("irrelevant", hasIrrelevantDestructor
);
500 FIELD2("trivial", hasTrivialDestructor
);
501 FIELD2("nonTrivial", hasNonTrivialDestructor
);
502 FIELD2("userDeclared", hasUserDeclaredDestructor
);
503 FIELD2("needsImplicit", needsImplicitDestructor
);
504 FIELD2("needsOverloadResolution", needsOverloadResolutionForDestructor
);
505 if (!RD
->needsOverloadResolutionForDestructor())
506 FIELD2("defaultedIsDeleted", defaultedDestructorIsDeleted
);
512 JSONNodeDumper::createCXXRecordDefinitionData(const CXXRecordDecl
*RD
) {
513 llvm::json::Object Ret
;
515 // This data is common to all C++ classes.
516 FIELD1(isGenericLambda
);
520 FIELD1(isStandardLayout
);
521 FIELD1(isTriviallyCopyable
);
524 FIELD1(isPolymorphic
);
527 FIELD1(canPassInRegisters
);
528 FIELD1(hasUserDeclaredConstructor
);
529 FIELD1(hasConstexprNonCopyMoveConstructor
);
530 FIELD1(hasMutableFields
);
531 FIELD1(hasVariantMembers
);
532 FIELD2("canConstDefaultInit", allowConstDefaultInit
);
534 Ret
["defaultCtor"] = createDefaultConstructorDefinitionData(RD
);
535 Ret
["copyCtor"] = createCopyConstructorDefinitionData(RD
);
536 Ret
["moveCtor"] = createMoveConstructorDefinitionData(RD
);
537 Ret
["copyAssign"] = createCopyAssignmentDefinitionData(RD
);
538 Ret
["moveAssign"] = createMoveAssignmentDefinitionData(RD
);
539 Ret
["dtor"] = createDestructorDefinitionData(RD
);
547 std::string
JSONNodeDumper::createAccessSpecifier(AccessSpecifier AS
) {
548 const auto AccessSpelling
= getAccessSpelling(AS
);
549 if (AccessSpelling
.empty())
551 return AccessSpelling
.str();
555 JSONNodeDumper::createCXXBaseSpecifier(const CXXBaseSpecifier
&BS
) {
556 llvm::json::Object Ret
;
558 Ret
["type"] = createQualType(BS
.getType());
559 Ret
["access"] = createAccessSpecifier(BS
.getAccessSpecifier());
560 Ret
["writtenAccess"] =
561 createAccessSpecifier(BS
.getAccessSpecifierAsWritten());
563 Ret
["isVirtual"] = true;
564 if (BS
.isPackExpansion())
565 Ret
["isPackExpansion"] = true;
570 void JSONNodeDumper::VisitAliasAttr(const AliasAttr
*AA
) {
571 JOS
.attribute("aliasee", AA
->getAliasee());
574 void JSONNodeDumper::VisitCleanupAttr(const CleanupAttr
*CA
) {
575 JOS
.attribute("cleanup_function", createBareDeclRef(CA
->getFunctionDecl()));
578 void JSONNodeDumper::VisitDeprecatedAttr(const DeprecatedAttr
*DA
) {
579 if (!DA
->getMessage().empty())
580 JOS
.attribute("message", DA
->getMessage());
581 if (!DA
->getReplacement().empty())
582 JOS
.attribute("replacement", DA
->getReplacement());
585 void JSONNodeDumper::VisitUnavailableAttr(const UnavailableAttr
*UA
) {
586 if (!UA
->getMessage().empty())
587 JOS
.attribute("message", UA
->getMessage());
590 void JSONNodeDumper::VisitSectionAttr(const SectionAttr
*SA
) {
591 JOS
.attribute("section_name", SA
->getName());
594 void JSONNodeDumper::VisitVisibilityAttr(const VisibilityAttr
*VA
) {
595 JOS
.attribute("visibility", VisibilityAttr::ConvertVisibilityTypeToStr(
596 VA
->getVisibility()));
599 void JSONNodeDumper::VisitTLSModelAttr(const TLSModelAttr
*TA
) {
600 JOS
.attribute("tls_model", TA
->getModel());
603 void JSONNodeDumper::VisitTypedefType(const TypedefType
*TT
) {
604 JOS
.attribute("decl", createBareDeclRef(TT
->getDecl()));
605 if (!TT
->typeMatchesDecl())
606 JOS
.attribute("type", createQualType(TT
->desugar()));
609 void JSONNodeDumper::VisitUsingType(const UsingType
*TT
) {
610 JOS
.attribute("decl", createBareDeclRef(TT
->getFoundDecl()));
611 if (!TT
->typeMatchesDecl())
612 JOS
.attribute("type", createQualType(TT
->desugar()));
615 void JSONNodeDumper::VisitFunctionType(const FunctionType
*T
) {
616 FunctionType::ExtInfo E
= T
->getExtInfo();
617 attributeOnlyIfTrue("noreturn", E
.getNoReturn());
618 attributeOnlyIfTrue("producesResult", E
.getProducesResult());
619 if (E
.getHasRegParm())
620 JOS
.attribute("regParm", E
.getRegParm());
621 JOS
.attribute("cc", FunctionType::getNameForCallConv(E
.getCC()));
624 void JSONNodeDumper::VisitFunctionProtoType(const FunctionProtoType
*T
) {
625 FunctionProtoType::ExtProtoInfo E
= T
->getExtProtoInfo();
626 attributeOnlyIfTrue("trailingReturn", E
.HasTrailingReturn
);
627 attributeOnlyIfTrue("const", T
->isConst());
628 attributeOnlyIfTrue("volatile", T
->isVolatile());
629 attributeOnlyIfTrue("restrict", T
->isRestrict());
630 attributeOnlyIfTrue("variadic", E
.Variadic
);
631 switch (E
.RefQualifier
) {
632 case RQ_LValue
: JOS
.attribute("refQualifier", "&"); break;
633 case RQ_RValue
: JOS
.attribute("refQualifier", "&&"); break;
636 switch (E
.ExceptionSpec
.Type
) {
637 case EST_DynamicNone
:
639 JOS
.attribute("exceptionSpec", "throw");
640 llvm::json::Array Types
;
641 for (QualType QT
: E
.ExceptionSpec
.Exceptions
)
642 Types
.push_back(createQualType(QT
));
643 JOS
.attribute("exceptionTypes", std::move(Types
));
646 JOS
.attribute("exceptionSpec", "throw");
647 JOS
.attribute("throwsAny", true);
649 case EST_BasicNoexcept
:
650 JOS
.attribute("exceptionSpec", "noexcept");
652 case EST_NoexceptTrue
:
653 case EST_NoexceptFalse
:
654 JOS
.attribute("exceptionSpec", "noexcept");
655 JOS
.attribute("conditionEvaluatesTo",
656 E
.ExceptionSpec
.Type
== EST_NoexceptTrue
);
657 //JOS.attributeWithCall("exceptionSpecExpr",
658 // [this, E]() { Visit(E.ExceptionSpec.NoexceptExpr); });
661 JOS
.attribute("exceptionSpec", "nothrow");
663 // FIXME: I cannot find a way to trigger these cases while dumping the AST. I
664 // suspect you can only run into them when executing an AST dump from within
665 // the debugger, which is not a use case we worry about for the JSON dumping
667 case EST_DependentNoexcept
:
668 case EST_Unevaluated
:
669 case EST_Uninstantiated
:
671 case EST_None
: break;
673 VisitFunctionType(T
);
676 void JSONNodeDumper::VisitRValueReferenceType(const ReferenceType
*RT
) {
677 attributeOnlyIfTrue("spelledAsLValue", RT
->isSpelledAsLValue());
680 void JSONNodeDumper::VisitArrayType(const ArrayType
*AT
) {
681 switch (AT
->getSizeModifier()) {
682 case ArraySizeModifier::Star
:
683 JOS
.attribute("sizeModifier", "*");
685 case ArraySizeModifier::Static
:
686 JOS
.attribute("sizeModifier", "static");
688 case ArraySizeModifier::Normal
:
692 std::string Str
= AT
->getIndexTypeQualifiers().getAsString();
694 JOS
.attribute("indexTypeQualifiers", Str
);
697 void JSONNodeDumper::VisitConstantArrayType(const ConstantArrayType
*CAT
) {
698 // FIXME: this should use ZExt instead of SExt, but JSON doesn't allow a
699 // narrowing conversion to int64_t so it cannot be expressed.
700 JOS
.attribute("size", CAT
->getSExtSize());
704 void JSONNodeDumper::VisitDependentSizedExtVectorType(
705 const DependentSizedExtVectorType
*VT
) {
707 "attrLoc", [VT
, this] { writeSourceLocation(VT
->getAttributeLoc()); });
710 void JSONNodeDumper::VisitVectorType(const VectorType
*VT
) {
711 JOS
.attribute("numElements", VT
->getNumElements());
712 switch (VT
->getVectorKind()) {
713 case VectorKind::Generic
:
715 case VectorKind::AltiVecVector
:
716 JOS
.attribute("vectorKind", "altivec");
718 case VectorKind::AltiVecPixel
:
719 JOS
.attribute("vectorKind", "altivec pixel");
721 case VectorKind::AltiVecBool
:
722 JOS
.attribute("vectorKind", "altivec bool");
724 case VectorKind::Neon
:
725 JOS
.attribute("vectorKind", "neon");
727 case VectorKind::NeonPoly
:
728 JOS
.attribute("vectorKind", "neon poly");
730 case VectorKind::SveFixedLengthData
:
731 JOS
.attribute("vectorKind", "fixed-length sve data vector");
733 case VectorKind::SveFixedLengthPredicate
:
734 JOS
.attribute("vectorKind", "fixed-length sve predicate vector");
736 case VectorKind::RVVFixedLengthData
:
737 JOS
.attribute("vectorKind", "fixed-length rvv data vector");
739 case VectorKind::RVVFixedLengthMask
:
740 case VectorKind::RVVFixedLengthMask_1
:
741 case VectorKind::RVVFixedLengthMask_2
:
742 case VectorKind::RVVFixedLengthMask_4
:
743 JOS
.attribute("vectorKind", "fixed-length rvv mask vector");
748 void JSONNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType
*UUT
) {
749 JOS
.attribute("decl", createBareDeclRef(UUT
->getDecl()));
752 void JSONNodeDumper::VisitUnaryTransformType(const UnaryTransformType
*UTT
) {
753 switch (UTT
->getUTTKind()) {
754 #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
755 case UnaryTransformType::Enum: \
756 JOS.attribute("transformKind", #Trait); \
758 #include "clang/Basic/TransformTypeTraits.def"
762 void JSONNodeDumper::VisitTagType(const TagType
*TT
) {
763 JOS
.attribute("decl", createBareDeclRef(TT
->getDecl()));
766 void JSONNodeDumper::VisitTemplateTypeParmType(
767 const TemplateTypeParmType
*TTPT
) {
768 JOS
.attribute("depth", TTPT
->getDepth());
769 JOS
.attribute("index", TTPT
->getIndex());
770 attributeOnlyIfTrue("isPack", TTPT
->isParameterPack());
771 JOS
.attribute("decl", createBareDeclRef(TTPT
->getDecl()));
774 void JSONNodeDumper::VisitSubstTemplateTypeParmType(
775 const SubstTemplateTypeParmType
*STTPT
) {
776 JOS
.attribute("index", STTPT
->getIndex());
777 if (auto PackIndex
= STTPT
->getPackIndex())
778 JOS
.attribute("pack_index", *PackIndex
);
781 void JSONNodeDumper::VisitSubstTemplateTypeParmPackType(
782 const SubstTemplateTypeParmPackType
*T
) {
783 JOS
.attribute("index", T
->getIndex());
786 void JSONNodeDumper::VisitAutoType(const AutoType
*AT
) {
787 JOS
.attribute("undeduced", !AT
->isDeduced());
788 switch (AT
->getKeyword()) {
789 case AutoTypeKeyword::Auto
:
790 JOS
.attribute("typeKeyword", "auto");
792 case AutoTypeKeyword::DecltypeAuto
:
793 JOS
.attribute("typeKeyword", "decltype(auto)");
795 case AutoTypeKeyword::GNUAutoType
:
796 JOS
.attribute("typeKeyword", "__auto_type");
801 void JSONNodeDumper::VisitTemplateSpecializationType(
802 const TemplateSpecializationType
*TST
) {
803 attributeOnlyIfTrue("isAlias", TST
->isTypeAlias());
806 llvm::raw_string_ostream
OS(Str
);
807 TST
->getTemplateName().print(OS
, PrintPolicy
);
808 JOS
.attribute("templateName", Str
);
811 void JSONNodeDumper::VisitInjectedClassNameType(
812 const InjectedClassNameType
*ICNT
) {
813 JOS
.attribute("decl", createBareDeclRef(ICNT
->getDecl()));
816 void JSONNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType
*OIT
) {
817 JOS
.attribute("decl", createBareDeclRef(OIT
->getDecl()));
820 void JSONNodeDumper::VisitPackExpansionType(const PackExpansionType
*PET
) {
821 if (std::optional
<unsigned> N
= PET
->getNumExpansions())
822 JOS
.attribute("numExpansions", *N
);
825 void JSONNodeDumper::VisitElaboratedType(const ElaboratedType
*ET
) {
826 if (const NestedNameSpecifier
*NNS
= ET
->getQualifier()) {
828 llvm::raw_string_ostream
OS(Str
);
829 NNS
->print(OS
, PrintPolicy
, /*ResolveTemplateArgs*/ true);
830 JOS
.attribute("qualifier", Str
);
832 if (const TagDecl
*TD
= ET
->getOwnedTagDecl())
833 JOS
.attribute("ownedTagDecl", createBareDeclRef(TD
));
836 void JSONNodeDumper::VisitMacroQualifiedType(const MacroQualifiedType
*MQT
) {
837 JOS
.attribute("macroName", MQT
->getMacroIdentifier()->getName());
840 void JSONNodeDumper::VisitMemberPointerType(const MemberPointerType
*MPT
) {
841 attributeOnlyIfTrue("isData", MPT
->isMemberDataPointer());
842 attributeOnlyIfTrue("isFunction", MPT
->isMemberFunctionPointer());
845 void JSONNodeDumper::VisitNamedDecl(const NamedDecl
*ND
) {
846 if (ND
&& ND
->getDeclName()) {
847 JOS
.attribute("name", ND
->getNameAsString());
848 // FIXME: There are likely other contexts in which it makes no sense to ask
849 // for a mangled name.
850 if (isa
<RequiresExprBodyDecl
>(ND
->getDeclContext()))
853 // If the declaration is dependent or is in a dependent context, then the
854 // mangling is unlikely to be meaningful (and in some cases may cause
855 // "don't know how to mangle this" assertion failures.
856 if (ND
->isTemplated())
859 // Mangled names are not meaningful for locals, and may not be well-defined
860 // in the case of VLAs.
861 auto *VD
= dyn_cast
<VarDecl
>(ND
);
862 if (VD
&& VD
->hasLocalStorage())
865 // Do not mangle template deduction guides.
866 if (isa
<CXXDeductionGuideDecl
>(ND
))
869 std::string MangledName
= ASTNameGen
.getName(ND
);
870 if (!MangledName
.empty())
871 JOS
.attribute("mangledName", MangledName
);
875 void JSONNodeDumper::VisitTypedefDecl(const TypedefDecl
*TD
) {
877 JOS
.attribute("type", createQualType(TD
->getUnderlyingType()));
880 void JSONNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl
*TAD
) {
882 JOS
.attribute("type", createQualType(TAD
->getUnderlyingType()));
885 void JSONNodeDumper::VisitNamespaceDecl(const NamespaceDecl
*ND
) {
887 attributeOnlyIfTrue("isInline", ND
->isInline());
888 attributeOnlyIfTrue("isNested", ND
->isNested());
889 if (!ND
->isFirstDecl())
890 JOS
.attribute("originalNamespace", createBareDeclRef(ND
->getFirstDecl()));
893 void JSONNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl
*UDD
) {
894 JOS
.attribute("nominatedNamespace",
895 createBareDeclRef(UDD
->getNominatedNamespace()));
898 void JSONNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl
*NAD
) {
900 JOS
.attribute("aliasedNamespace",
901 createBareDeclRef(NAD
->getAliasedNamespace()));
904 void JSONNodeDumper::VisitUsingDecl(const UsingDecl
*UD
) {
906 if (const NestedNameSpecifier
*NNS
= UD
->getQualifier()) {
907 llvm::raw_string_ostream
SOS(Name
);
908 NNS
->print(SOS
, UD
->getASTContext().getPrintingPolicy());
910 Name
+= UD
->getNameAsString();
911 JOS
.attribute("name", Name
);
914 void JSONNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl
*UED
) {
915 JOS
.attribute("target", createBareDeclRef(UED
->getEnumDecl()));
918 void JSONNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl
*USD
) {
919 JOS
.attribute("target", createBareDeclRef(USD
->getTargetDecl()));
922 void JSONNodeDumper::VisitVarDecl(const VarDecl
*VD
) {
924 JOS
.attribute("type", createQualType(VD
->getType()));
925 if (const auto *P
= dyn_cast
<ParmVarDecl
>(VD
))
926 attributeOnlyIfTrue("explicitObjectParameter",
927 P
->isExplicitObjectParameter());
929 StorageClass SC
= VD
->getStorageClass();
931 JOS
.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC
));
932 switch (VD
->getTLSKind()) {
933 case VarDecl::TLS_Dynamic
: JOS
.attribute("tls", "dynamic"); break;
934 case VarDecl::TLS_Static
: JOS
.attribute("tls", "static"); break;
935 case VarDecl::TLS_None
: break;
937 attributeOnlyIfTrue("nrvo", VD
->isNRVOVariable());
938 attributeOnlyIfTrue("inline", VD
->isInline());
939 attributeOnlyIfTrue("constexpr", VD
->isConstexpr());
940 attributeOnlyIfTrue("modulePrivate", VD
->isModulePrivate());
942 switch (VD
->getInitStyle()) {
943 case VarDecl::CInit
: JOS
.attribute("init", "c"); break;
944 case VarDecl::CallInit
: JOS
.attribute("init", "call"); break;
945 case VarDecl::ListInit
: JOS
.attribute("init", "list"); break;
946 case VarDecl::ParenListInit
:
947 JOS
.attribute("init", "paren-list");
951 attributeOnlyIfTrue("isParameterPack", VD
->isParameterPack());
954 void JSONNodeDumper::VisitFieldDecl(const FieldDecl
*FD
) {
956 JOS
.attribute("type", createQualType(FD
->getType()));
957 attributeOnlyIfTrue("mutable", FD
->isMutable());
958 attributeOnlyIfTrue("modulePrivate", FD
->isModulePrivate());
959 attributeOnlyIfTrue("isBitfield", FD
->isBitField());
960 attributeOnlyIfTrue("hasInClassInitializer", FD
->hasInClassInitializer());
963 void JSONNodeDumper::VisitFunctionDecl(const FunctionDecl
*FD
) {
965 JOS
.attribute("type", createQualType(FD
->getType()));
966 StorageClass SC
= FD
->getStorageClass();
968 JOS
.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC
));
969 attributeOnlyIfTrue("inline", FD
->isInlineSpecified());
970 attributeOnlyIfTrue("virtual", FD
->isVirtualAsWritten());
971 attributeOnlyIfTrue("pure", FD
->isPureVirtual());
972 attributeOnlyIfTrue("explicitlyDeleted", FD
->isDeletedAsWritten());
973 attributeOnlyIfTrue("constexpr", FD
->isConstexpr());
974 attributeOnlyIfTrue("variadic", FD
->isVariadic());
975 attributeOnlyIfTrue("immediate", FD
->isImmediateFunction());
977 if (FD
->isDefaulted())
978 JOS
.attribute("explicitlyDefaulted",
979 FD
->isDeleted() ? "deleted" : "default");
981 if (StringLiteral
*Msg
= FD
->getDeletedMessage())
982 JOS
.attribute("deletedMessage", Msg
->getString());
985 void JSONNodeDumper::VisitEnumDecl(const EnumDecl
*ED
) {
988 JOS
.attribute("fixedUnderlyingType", createQualType(ED
->getIntegerType()));
990 JOS
.attribute("scopedEnumTag",
991 ED
->isScopedUsingClassTag() ? "class" : "struct");
993 void JSONNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl
*ECD
) {
995 JOS
.attribute("type", createQualType(ECD
->getType()));
998 void JSONNodeDumper::VisitRecordDecl(const RecordDecl
*RD
) {
1000 JOS
.attribute("tagUsed", RD
->getKindName());
1001 attributeOnlyIfTrue("completeDefinition", RD
->isCompleteDefinition());
1003 void JSONNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl
*RD
) {
1004 VisitRecordDecl(RD
);
1006 // All other information requires a complete definition.
1007 if (!RD
->isCompleteDefinition())
1010 JOS
.attribute("definitionData", createCXXRecordDefinitionData(RD
));
1011 if (RD
->getNumBases()) {
1012 JOS
.attributeArray("bases", [this, RD
] {
1013 for (const auto &Spec
: RD
->bases())
1014 JOS
.value(createCXXBaseSpecifier(Spec
));
1019 void JSONNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl
*D
) {
1021 JOS
.attribute("bufferKind", D
->isCBuffer() ? "cbuffer" : "tbuffer");
1024 void JSONNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl
*D
) {
1026 JOS
.attribute("tagUsed", D
->wasDeclaredWithTypename() ? "typename" : "class");
1027 JOS
.attribute("depth", D
->getDepth());
1028 JOS
.attribute("index", D
->getIndex());
1029 attributeOnlyIfTrue("isParameterPack", D
->isParameterPack());
1031 if (D
->hasDefaultArgument())
1032 JOS
.attributeObject("defaultArg", [=] {
1033 Visit(D
->getDefaultArgument().getArgument(), SourceRange(),
1034 D
->getDefaultArgStorage().getInheritedFrom(),
1035 D
->defaultArgumentWasInherited() ? "inherited from" : "previous");
1039 void JSONNodeDumper::VisitNonTypeTemplateParmDecl(
1040 const NonTypeTemplateParmDecl
*D
) {
1042 JOS
.attribute("type", createQualType(D
->getType()));
1043 JOS
.attribute("depth", D
->getDepth());
1044 JOS
.attribute("index", D
->getIndex());
1045 attributeOnlyIfTrue("isParameterPack", D
->isParameterPack());
1047 if (D
->hasDefaultArgument())
1048 JOS
.attributeObject("defaultArg", [=] {
1049 Visit(D
->getDefaultArgument().getArgument(), SourceRange(),
1050 D
->getDefaultArgStorage().getInheritedFrom(),
1051 D
->defaultArgumentWasInherited() ? "inherited from" : "previous");
1055 void JSONNodeDumper::VisitTemplateTemplateParmDecl(
1056 const TemplateTemplateParmDecl
*D
) {
1058 JOS
.attribute("depth", D
->getDepth());
1059 JOS
.attribute("index", D
->getIndex());
1060 attributeOnlyIfTrue("isParameterPack", D
->isParameterPack());
1062 if (D
->hasDefaultArgument())
1063 JOS
.attributeObject("defaultArg", [=] {
1064 const auto *InheritedFrom
= D
->getDefaultArgStorage().getInheritedFrom();
1065 Visit(D
->getDefaultArgument().getArgument(),
1066 InheritedFrom
? InheritedFrom
->getSourceRange() : SourceLocation
{},
1068 D
->defaultArgumentWasInherited() ? "inherited from" : "previous");
1072 void JSONNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl
*LSD
) {
1074 switch (LSD
->getLanguage()) {
1075 case LinkageSpecLanguageIDs::C
:
1078 case LinkageSpecLanguageIDs::CXX
:
1082 JOS
.attribute("language", Lang
);
1083 attributeOnlyIfTrue("hasBraces", LSD
->hasBraces());
1086 void JSONNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl
*ASD
) {
1087 JOS
.attribute("access", createAccessSpecifier(ASD
->getAccess()));
1090 void JSONNodeDumper::VisitFriendDecl(const FriendDecl
*FD
) {
1091 if (const TypeSourceInfo
*T
= FD
->getFriendType())
1092 JOS
.attribute("type", createQualType(T
->getType()));
1093 attributeOnlyIfTrue("isPackExpansion", FD
->isPackExpansion());
1096 void JSONNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl
*D
) {
1098 JOS
.attribute("type", createQualType(D
->getType()));
1099 attributeOnlyIfTrue("synthesized", D
->getSynthesize());
1100 switch (D
->getAccessControl()) {
1101 case ObjCIvarDecl::None
: JOS
.attribute("access", "none"); break;
1102 case ObjCIvarDecl::Private
: JOS
.attribute("access", "private"); break;
1103 case ObjCIvarDecl::Protected
: JOS
.attribute("access", "protected"); break;
1104 case ObjCIvarDecl::Public
: JOS
.attribute("access", "public"); break;
1105 case ObjCIvarDecl::Package
: JOS
.attribute("access", "package"); break;
1109 void JSONNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl
*D
) {
1111 JOS
.attribute("returnType", createQualType(D
->getReturnType()));
1112 JOS
.attribute("instance", D
->isInstanceMethod());
1113 attributeOnlyIfTrue("variadic", D
->isVariadic());
1116 void JSONNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl
*D
) {
1118 JOS
.attribute("type", createQualType(D
->getUnderlyingType()));
1119 attributeOnlyIfTrue("bounded", D
->hasExplicitBound());
1120 switch (D
->getVariance()) {
1121 case ObjCTypeParamVariance::Invariant
:
1123 case ObjCTypeParamVariance::Covariant
:
1124 JOS
.attribute("variance", "covariant");
1126 case ObjCTypeParamVariance::Contravariant
:
1127 JOS
.attribute("variance", "contravariant");
1132 void JSONNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl
*D
) {
1134 JOS
.attribute("interface", createBareDeclRef(D
->getClassInterface()));
1135 JOS
.attribute("implementation", createBareDeclRef(D
->getImplementation()));
1137 llvm::json::Array Protocols
;
1138 for (const auto* P
: D
->protocols())
1139 Protocols
.push_back(createBareDeclRef(P
));
1140 if (!Protocols
.empty())
1141 JOS
.attribute("protocols", std::move(Protocols
));
1144 void JSONNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl
*D
) {
1146 JOS
.attribute("interface", createBareDeclRef(D
->getClassInterface()));
1147 JOS
.attribute("categoryDecl", createBareDeclRef(D
->getCategoryDecl()));
1150 void JSONNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl
*D
) {
1153 llvm::json::Array Protocols
;
1154 for (const auto *P
: D
->protocols())
1155 Protocols
.push_back(createBareDeclRef(P
));
1156 if (!Protocols
.empty())
1157 JOS
.attribute("protocols", std::move(Protocols
));
1160 void JSONNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl
*D
) {
1162 JOS
.attribute("super", createBareDeclRef(D
->getSuperClass()));
1163 JOS
.attribute("implementation", createBareDeclRef(D
->getImplementation()));
1165 llvm::json::Array Protocols
;
1166 for (const auto* P
: D
->protocols())
1167 Protocols
.push_back(createBareDeclRef(P
));
1168 if (!Protocols
.empty())
1169 JOS
.attribute("protocols", std::move(Protocols
));
1172 void JSONNodeDumper::VisitObjCImplementationDecl(
1173 const ObjCImplementationDecl
*D
) {
1175 JOS
.attribute("super", createBareDeclRef(D
->getSuperClass()));
1176 JOS
.attribute("interface", createBareDeclRef(D
->getClassInterface()));
1179 void JSONNodeDumper::VisitObjCCompatibleAliasDecl(
1180 const ObjCCompatibleAliasDecl
*D
) {
1182 JOS
.attribute("interface", createBareDeclRef(D
->getClassInterface()));
1185 void JSONNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl
*D
) {
1187 JOS
.attribute("type", createQualType(D
->getType()));
1189 switch (D
->getPropertyImplementation()) {
1190 case ObjCPropertyDecl::None
: break;
1191 case ObjCPropertyDecl::Required
: JOS
.attribute("control", "required"); break;
1192 case ObjCPropertyDecl::Optional
: JOS
.attribute("control", "optional"); break;
1195 ObjCPropertyAttribute::Kind Attrs
= D
->getPropertyAttributes();
1196 if (Attrs
!= ObjCPropertyAttribute::kind_noattr
) {
1197 if (Attrs
& ObjCPropertyAttribute::kind_getter
)
1198 JOS
.attribute("getter", createBareDeclRef(D
->getGetterMethodDecl()));
1199 if (Attrs
& ObjCPropertyAttribute::kind_setter
)
1200 JOS
.attribute("setter", createBareDeclRef(D
->getSetterMethodDecl()));
1201 attributeOnlyIfTrue("readonly",
1202 Attrs
& ObjCPropertyAttribute::kind_readonly
);
1203 attributeOnlyIfTrue("assign", Attrs
& ObjCPropertyAttribute::kind_assign
);
1204 attributeOnlyIfTrue("readwrite",
1205 Attrs
& ObjCPropertyAttribute::kind_readwrite
);
1206 attributeOnlyIfTrue("retain", Attrs
& ObjCPropertyAttribute::kind_retain
);
1207 attributeOnlyIfTrue("copy", Attrs
& ObjCPropertyAttribute::kind_copy
);
1208 attributeOnlyIfTrue("nonatomic",
1209 Attrs
& ObjCPropertyAttribute::kind_nonatomic
);
1210 attributeOnlyIfTrue("atomic", Attrs
& ObjCPropertyAttribute::kind_atomic
);
1211 attributeOnlyIfTrue("weak", Attrs
& ObjCPropertyAttribute::kind_weak
);
1212 attributeOnlyIfTrue("strong", Attrs
& ObjCPropertyAttribute::kind_strong
);
1213 attributeOnlyIfTrue("unsafe_unretained",
1214 Attrs
& ObjCPropertyAttribute::kind_unsafe_unretained
);
1215 attributeOnlyIfTrue("class", Attrs
& ObjCPropertyAttribute::kind_class
);
1216 attributeOnlyIfTrue("direct", Attrs
& ObjCPropertyAttribute::kind_direct
);
1217 attributeOnlyIfTrue("nullability",
1218 Attrs
& ObjCPropertyAttribute::kind_nullability
);
1219 attributeOnlyIfTrue("null_resettable",
1220 Attrs
& ObjCPropertyAttribute::kind_null_resettable
);
1224 void JSONNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl
*D
) {
1225 VisitNamedDecl(D
->getPropertyDecl());
1226 JOS
.attribute("implKind", D
->getPropertyImplementation() ==
1227 ObjCPropertyImplDecl::Synthesize
1230 JOS
.attribute("propertyDecl", createBareDeclRef(D
->getPropertyDecl()));
1231 JOS
.attribute("ivarDecl", createBareDeclRef(D
->getPropertyIvarDecl()));
1234 void JSONNodeDumper::VisitBlockDecl(const BlockDecl
*D
) {
1235 attributeOnlyIfTrue("variadic", D
->isVariadic());
1236 attributeOnlyIfTrue("capturesThis", D
->capturesCXXThis());
1239 void JSONNodeDumper::VisitAtomicExpr(const AtomicExpr
*AE
) {
1240 JOS
.attribute("name", AE
->getOpAsString());
1243 void JSONNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr
*OEE
) {
1244 JOS
.attribute("encodedType", createQualType(OEE
->getEncodedType()));
1247 void JSONNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr
*OME
) {
1249 llvm::raw_string_ostream
OS(Str
);
1251 OME
->getSelector().print(OS
);
1252 JOS
.attribute("selector", Str
);
1254 switch (OME
->getReceiverKind()) {
1255 case ObjCMessageExpr::Instance
:
1256 JOS
.attribute("receiverKind", "instance");
1258 case ObjCMessageExpr::Class
:
1259 JOS
.attribute("receiverKind", "class");
1260 JOS
.attribute("classType", createQualType(OME
->getClassReceiver()));
1262 case ObjCMessageExpr::SuperInstance
:
1263 JOS
.attribute("receiverKind", "super (instance)");
1264 JOS
.attribute("superType", createQualType(OME
->getSuperType()));
1266 case ObjCMessageExpr::SuperClass
:
1267 JOS
.attribute("receiverKind", "super (class)");
1268 JOS
.attribute("superType", createQualType(OME
->getSuperType()));
1272 QualType CallReturnTy
= OME
->getCallReturnType(Ctx
);
1273 if (OME
->getType() != CallReturnTy
)
1274 JOS
.attribute("callReturnType", createQualType(CallReturnTy
));
1277 void JSONNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr
*OBE
) {
1278 if (const ObjCMethodDecl
*MD
= OBE
->getBoxingMethod()) {
1280 llvm::raw_string_ostream
OS(Str
);
1282 MD
->getSelector().print(OS
);
1283 JOS
.attribute("selector", Str
);
1287 void JSONNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr
*OSE
) {
1289 llvm::raw_string_ostream
OS(Str
);
1291 OSE
->getSelector().print(OS
);
1292 JOS
.attribute("selector", Str
);
1295 void JSONNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr
*OPE
) {
1296 JOS
.attribute("protocol", createBareDeclRef(OPE
->getProtocol()));
1299 void JSONNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr
*OPRE
) {
1300 if (OPRE
->isImplicitProperty()) {
1301 JOS
.attribute("propertyKind", "implicit");
1302 if (const ObjCMethodDecl
*MD
= OPRE
->getImplicitPropertyGetter())
1303 JOS
.attribute("getter", createBareDeclRef(MD
));
1304 if (const ObjCMethodDecl
*MD
= OPRE
->getImplicitPropertySetter())
1305 JOS
.attribute("setter", createBareDeclRef(MD
));
1307 JOS
.attribute("propertyKind", "explicit");
1308 JOS
.attribute("property", createBareDeclRef(OPRE
->getExplicitProperty()));
1311 attributeOnlyIfTrue("isSuperReceiver", OPRE
->isSuperReceiver());
1312 attributeOnlyIfTrue("isMessagingGetter", OPRE
->isMessagingGetter());
1313 attributeOnlyIfTrue("isMessagingSetter", OPRE
->isMessagingSetter());
1316 void JSONNodeDumper::VisitObjCSubscriptRefExpr(
1317 const ObjCSubscriptRefExpr
*OSRE
) {
1318 JOS
.attribute("subscriptKind",
1319 OSRE
->isArraySubscriptRefExpr() ? "array" : "dictionary");
1321 if (const ObjCMethodDecl
*MD
= OSRE
->getAtIndexMethodDecl())
1322 JOS
.attribute("getter", createBareDeclRef(MD
));
1323 if (const ObjCMethodDecl
*MD
= OSRE
->setAtIndexMethodDecl())
1324 JOS
.attribute("setter", createBareDeclRef(MD
));
1327 void JSONNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr
*OIRE
) {
1328 JOS
.attribute("decl", createBareDeclRef(OIRE
->getDecl()));
1329 attributeOnlyIfTrue("isFreeIvar", OIRE
->isFreeIvar());
1330 JOS
.attribute("isArrow", OIRE
->isArrow());
1333 void JSONNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr
*OBLE
) {
1334 JOS
.attribute("value", OBLE
->getValue() ? "__objc_yes" : "__objc_no");
1337 void JSONNodeDumper::VisitDeclRefExpr(const DeclRefExpr
*DRE
) {
1338 JOS
.attribute("referencedDecl", createBareDeclRef(DRE
->getDecl()));
1339 if (DRE
->getDecl() != DRE
->getFoundDecl())
1340 JOS
.attribute("foundReferencedDecl",
1341 createBareDeclRef(DRE
->getFoundDecl()));
1342 switch (DRE
->isNonOdrUse()) {
1343 case NOUR_None
: break;
1344 case NOUR_Unevaluated
: JOS
.attribute("nonOdrUseReason", "unevaluated"); break;
1345 case NOUR_Constant
: JOS
.attribute("nonOdrUseReason", "constant"); break;
1346 case NOUR_Discarded
: JOS
.attribute("nonOdrUseReason", "discarded"); break;
1348 attributeOnlyIfTrue("isImmediateEscalating", DRE
->isImmediateEscalating());
1351 void JSONNodeDumper::VisitSYCLUniqueStableNameExpr(
1352 const SYCLUniqueStableNameExpr
*E
) {
1353 JOS
.attribute("typeSourceInfo",
1354 createQualType(E
->getTypeSourceInfo()->getType()));
1357 void JSONNodeDumper::VisitOpenACCAsteriskSizeExpr(
1358 const OpenACCAsteriskSizeExpr
*E
) {}
1360 void JSONNodeDumper::VisitPredefinedExpr(const PredefinedExpr
*PE
) {
1361 JOS
.attribute("name", PredefinedExpr::getIdentKindName(PE
->getIdentKind()));
1364 void JSONNodeDumper::VisitUnaryOperator(const UnaryOperator
*UO
) {
1365 JOS
.attribute("isPostfix", UO
->isPostfix());
1366 JOS
.attribute("opcode", UnaryOperator::getOpcodeStr(UO
->getOpcode()));
1367 if (!UO
->canOverflow())
1368 JOS
.attribute("canOverflow", false);
1371 void JSONNodeDumper::VisitBinaryOperator(const BinaryOperator
*BO
) {
1372 JOS
.attribute("opcode", BinaryOperator::getOpcodeStr(BO
->getOpcode()));
1375 void JSONNodeDumper::VisitCompoundAssignOperator(
1376 const CompoundAssignOperator
*CAO
) {
1377 VisitBinaryOperator(CAO
);
1378 JOS
.attribute("computeLHSType", createQualType(CAO
->getComputationLHSType()));
1379 JOS
.attribute("computeResultType",
1380 createQualType(CAO
->getComputationResultType()));
1383 void JSONNodeDumper::VisitMemberExpr(const MemberExpr
*ME
) {
1384 // Note, we always write this Boolean field because the information it conveys
1385 // is critical to understanding the AST node.
1386 ValueDecl
*VD
= ME
->getMemberDecl();
1387 JOS
.attribute("name", VD
&& VD
->getDeclName() ? VD
->getNameAsString() : "");
1388 JOS
.attribute("isArrow", ME
->isArrow());
1389 JOS
.attribute("referencedMemberDecl", createPointerRepresentation(VD
));
1390 switch (ME
->isNonOdrUse()) {
1391 case NOUR_None
: break;
1392 case NOUR_Unevaluated
: JOS
.attribute("nonOdrUseReason", "unevaluated"); break;
1393 case NOUR_Constant
: JOS
.attribute("nonOdrUseReason", "constant"); break;
1394 case NOUR_Discarded
: JOS
.attribute("nonOdrUseReason", "discarded"); break;
1398 void JSONNodeDumper::VisitCXXNewExpr(const CXXNewExpr
*NE
) {
1399 attributeOnlyIfTrue("isGlobal", NE
->isGlobalNew());
1400 attributeOnlyIfTrue("isArray", NE
->isArray());
1401 attributeOnlyIfTrue("isPlacement", NE
->getNumPlacementArgs() != 0);
1402 switch (NE
->getInitializationStyle()) {
1403 case CXXNewInitializationStyle::None
:
1405 case CXXNewInitializationStyle::Parens
:
1406 JOS
.attribute("initStyle", "call");
1408 case CXXNewInitializationStyle::Braces
:
1409 JOS
.attribute("initStyle", "list");
1412 if (const FunctionDecl
*FD
= NE
->getOperatorNew())
1413 JOS
.attribute("operatorNewDecl", createBareDeclRef(FD
));
1414 if (const FunctionDecl
*FD
= NE
->getOperatorDelete())
1415 JOS
.attribute("operatorDeleteDecl", createBareDeclRef(FD
));
1417 void JSONNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr
*DE
) {
1418 attributeOnlyIfTrue("isGlobal", DE
->isGlobalDelete());
1419 attributeOnlyIfTrue("isArray", DE
->isArrayForm());
1420 attributeOnlyIfTrue("isArrayAsWritten", DE
->isArrayFormAsWritten());
1421 if (const FunctionDecl
*FD
= DE
->getOperatorDelete())
1422 JOS
.attribute("operatorDeleteDecl", createBareDeclRef(FD
));
1425 void JSONNodeDumper::VisitCXXThisExpr(const CXXThisExpr
*TE
) {
1426 attributeOnlyIfTrue("implicit", TE
->isImplicit());
1429 void JSONNodeDumper::VisitCastExpr(const CastExpr
*CE
) {
1430 JOS
.attribute("castKind", CE
->getCastKindName());
1431 llvm::json::Array Path
= createCastPath(CE
);
1433 JOS
.attribute("path", std::move(Path
));
1434 // FIXME: This may not be useful information as it can be obtusely gleaned
1435 // from the inner[] array.
1436 if (const NamedDecl
*ND
= CE
->getConversionFunction())
1437 JOS
.attribute("conversionFunc", createBareDeclRef(ND
));
1440 void JSONNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr
*ICE
) {
1442 attributeOnlyIfTrue("isPartOfExplicitCast", ICE
->isPartOfExplicitCast());
1445 void JSONNodeDumper::VisitCallExpr(const CallExpr
*CE
) {
1446 attributeOnlyIfTrue("adl", CE
->usesADL());
1449 void JSONNodeDumper::VisitUnaryExprOrTypeTraitExpr(
1450 const UnaryExprOrTypeTraitExpr
*TTE
) {
1451 JOS
.attribute("name", getTraitSpelling(TTE
->getKind()));
1452 if (TTE
->isArgumentType())
1453 JOS
.attribute("argType", createQualType(TTE
->getArgumentType()));
1456 void JSONNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr
*SOPE
) {
1457 VisitNamedDecl(SOPE
->getPack());
1460 void JSONNodeDumper::VisitUnresolvedLookupExpr(
1461 const UnresolvedLookupExpr
*ULE
) {
1462 JOS
.attribute("usesADL", ULE
->requiresADL());
1463 JOS
.attribute("name", ULE
->getName().getAsString());
1465 JOS
.attributeArray("lookups", [this, ULE
] {
1466 for (const NamedDecl
*D
: ULE
->decls())
1467 JOS
.value(createBareDeclRef(D
));
1471 void JSONNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr
*ALE
) {
1472 JOS
.attribute("name", ALE
->getLabel()->getName());
1473 JOS
.attribute("labelDeclId", createPointerRepresentation(ALE
->getLabel()));
1476 void JSONNodeDumper::VisitCXXTypeidExpr(const CXXTypeidExpr
*CTE
) {
1477 if (CTE
->isTypeOperand()) {
1478 QualType Adjusted
= CTE
->getTypeOperand(Ctx
);
1479 QualType Unadjusted
= CTE
->getTypeOperandSourceInfo()->getType();
1480 JOS
.attribute("typeArg", createQualType(Unadjusted
));
1481 if (Adjusted
!= Unadjusted
)
1482 JOS
.attribute("adjustedTypeArg", createQualType(Adjusted
));
1486 void JSONNodeDumper::VisitConstantExpr(const ConstantExpr
*CE
) {
1487 if (CE
->getResultAPValueKind() != APValue::None
)
1488 Visit(CE
->getAPValueResult(), CE
->getType());
1491 void JSONNodeDumper::VisitInitListExpr(const InitListExpr
*ILE
) {
1492 if (const FieldDecl
*FD
= ILE
->getInitializedFieldInUnion())
1493 JOS
.attribute("field", createBareDeclRef(FD
));
1496 void JSONNodeDumper::VisitGenericSelectionExpr(
1497 const GenericSelectionExpr
*GSE
) {
1498 attributeOnlyIfTrue("resultDependent", GSE
->isResultDependent());
1501 void JSONNodeDumper::VisitCXXUnresolvedConstructExpr(
1502 const CXXUnresolvedConstructExpr
*UCE
) {
1503 if (UCE
->getType() != UCE
->getTypeAsWritten())
1504 JOS
.attribute("typeAsWritten", createQualType(UCE
->getTypeAsWritten()));
1505 attributeOnlyIfTrue("list", UCE
->isListInitialization());
1508 void JSONNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr
*CE
) {
1509 CXXConstructorDecl
*Ctor
= CE
->getConstructor();
1510 JOS
.attribute("ctorType", createQualType(Ctor
->getType()));
1511 attributeOnlyIfTrue("elidable", CE
->isElidable());
1512 attributeOnlyIfTrue("list", CE
->isListInitialization());
1513 attributeOnlyIfTrue("initializer_list", CE
->isStdInitListInitialization());
1514 attributeOnlyIfTrue("zeroing", CE
->requiresZeroInitialization());
1515 attributeOnlyIfTrue("hadMultipleCandidates", CE
->hadMultipleCandidates());
1516 attributeOnlyIfTrue("isImmediateEscalating", CE
->isImmediateEscalating());
1518 switch (CE
->getConstructionKind()) {
1519 case CXXConstructionKind::Complete
:
1520 JOS
.attribute("constructionKind", "complete");
1522 case CXXConstructionKind::Delegating
:
1523 JOS
.attribute("constructionKind", "delegating");
1525 case CXXConstructionKind::NonVirtualBase
:
1526 JOS
.attribute("constructionKind", "non-virtual base");
1528 case CXXConstructionKind::VirtualBase
:
1529 JOS
.attribute("constructionKind", "virtual base");
1534 void JSONNodeDumper::VisitExprWithCleanups(const ExprWithCleanups
*EWC
) {
1535 attributeOnlyIfTrue("cleanupsHaveSideEffects",
1536 EWC
->cleanupsHaveSideEffects());
1537 if (EWC
->getNumObjects()) {
1538 JOS
.attributeArray("cleanups", [this, EWC
] {
1539 for (const ExprWithCleanups::CleanupObject
&CO
: EWC
->getObjects())
1540 if (auto *BD
= CO
.dyn_cast
<BlockDecl
*>()) {
1541 JOS
.value(createBareDeclRef(BD
));
1542 } else if (auto *CLE
= CO
.dyn_cast
<CompoundLiteralExpr
*>()) {
1543 llvm::json::Object Obj
;
1544 Obj
["id"] = createPointerRepresentation(CLE
);
1545 Obj
["kind"] = CLE
->getStmtClassName();
1546 JOS
.value(std::move(Obj
));
1548 llvm_unreachable("unexpected cleanup object type");
1554 void JSONNodeDumper::VisitCXXBindTemporaryExpr(
1555 const CXXBindTemporaryExpr
*BTE
) {
1556 const CXXTemporary
*Temp
= BTE
->getTemporary();
1557 JOS
.attribute("temp", createPointerRepresentation(Temp
));
1558 if (const CXXDestructorDecl
*Dtor
= Temp
->getDestructor())
1559 JOS
.attribute("dtor", createBareDeclRef(Dtor
));
1562 void JSONNodeDumper::VisitMaterializeTemporaryExpr(
1563 const MaterializeTemporaryExpr
*MTE
) {
1564 if (const ValueDecl
*VD
= MTE
->getExtendingDecl())
1565 JOS
.attribute("extendingDecl", createBareDeclRef(VD
));
1567 switch (MTE
->getStorageDuration()) {
1569 JOS
.attribute("storageDuration", "automatic");
1572 JOS
.attribute("storageDuration", "dynamic");
1574 case SD_FullExpression
:
1575 JOS
.attribute("storageDuration", "full expression");
1578 JOS
.attribute("storageDuration", "static");
1581 JOS
.attribute("storageDuration", "thread");
1585 attributeOnlyIfTrue("boundToLValueRef", MTE
->isBoundToLvalueReference());
1588 void JSONNodeDumper::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr
*Node
) {
1589 attributeOnlyIfTrue("hasRewrittenInit", Node
->hasRewrittenInit());
1592 void JSONNodeDumper::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr
*Node
) {
1593 attributeOnlyIfTrue("hasRewrittenInit", Node
->hasRewrittenInit());
1596 void JSONNodeDumper::VisitCXXDependentScopeMemberExpr(
1597 const CXXDependentScopeMemberExpr
*DSME
) {
1598 JOS
.attribute("isArrow", DSME
->isArrow());
1599 JOS
.attribute("member", DSME
->getMember().getAsString());
1600 attributeOnlyIfTrue("hasTemplateKeyword", DSME
->hasTemplateKeyword());
1601 attributeOnlyIfTrue("hasExplicitTemplateArgs",
1602 DSME
->hasExplicitTemplateArgs());
1604 if (DSME
->getNumTemplateArgs()) {
1605 JOS
.attributeArray("explicitTemplateArgs", [DSME
, this] {
1606 for (const TemplateArgumentLoc
&TAL
: DSME
->template_arguments())
1608 [&TAL
, this] { Visit(TAL
.getArgument(), TAL
.getSourceRange()); });
1613 void JSONNodeDumper::VisitRequiresExpr(const RequiresExpr
*RE
) {
1614 if (!RE
->isValueDependent())
1615 JOS
.attribute("satisfied", RE
->isSatisfied());
1618 void JSONNodeDumper::VisitIntegerLiteral(const IntegerLiteral
*IL
) {
1619 llvm::SmallString
<16> Buffer
;
1620 IL
->getValue().toString(Buffer
,
1621 /*Radix=*/10, IL
->getType()->isSignedIntegerType());
1622 JOS
.attribute("value", Buffer
);
1624 void JSONNodeDumper::VisitCharacterLiteral(const CharacterLiteral
*CL
) {
1625 // FIXME: This should probably print the character literal as a string,
1626 // rather than as a numerical value. It would be nice if the behavior matched
1627 // what we do to print a string literal; right now, it is impossible to tell
1628 // the difference between 'a' and L'a' in C from the JSON output.
1629 JOS
.attribute("value", CL
->getValue());
1631 void JSONNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral
*FPL
) {
1632 JOS
.attribute("value", FPL
->getValueAsString(/*Radix=*/10));
1634 void JSONNodeDumper::VisitFloatingLiteral(const FloatingLiteral
*FL
) {
1635 llvm::SmallString
<16> Buffer
;
1636 FL
->getValue().toString(Buffer
);
1637 JOS
.attribute("value", Buffer
);
1639 void JSONNodeDumper::VisitStringLiteral(const StringLiteral
*SL
) {
1641 llvm::raw_string_ostream
SS(Buffer
);
1642 SL
->outputString(SS
);
1643 JOS
.attribute("value", Buffer
);
1645 void JSONNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr
*BLE
) {
1646 JOS
.attribute("value", BLE
->getValue());
1649 void JSONNodeDumper::VisitIfStmt(const IfStmt
*IS
) {
1650 attributeOnlyIfTrue("hasInit", IS
->hasInitStorage());
1651 attributeOnlyIfTrue("hasVar", IS
->hasVarStorage());
1652 attributeOnlyIfTrue("hasElse", IS
->hasElseStorage());
1653 attributeOnlyIfTrue("isConstexpr", IS
->isConstexpr());
1654 attributeOnlyIfTrue("isConsteval", IS
->isConsteval());
1655 attributeOnlyIfTrue("constevalIsNegated", IS
->isNegatedConsteval());
1658 void JSONNodeDumper::VisitSwitchStmt(const SwitchStmt
*SS
) {
1659 attributeOnlyIfTrue("hasInit", SS
->hasInitStorage());
1660 attributeOnlyIfTrue("hasVar", SS
->hasVarStorage());
1662 void JSONNodeDumper::VisitCaseStmt(const CaseStmt
*CS
) {
1663 attributeOnlyIfTrue("isGNURange", CS
->caseStmtIsGNURange());
1666 void JSONNodeDumper::VisitLabelStmt(const LabelStmt
*LS
) {
1667 JOS
.attribute("name", LS
->getName());
1668 JOS
.attribute("declId", createPointerRepresentation(LS
->getDecl()));
1669 attributeOnlyIfTrue("sideEntry", LS
->isSideEntry());
1671 void JSONNodeDumper::VisitGotoStmt(const GotoStmt
*GS
) {
1672 JOS
.attribute("targetLabelDeclId",
1673 createPointerRepresentation(GS
->getLabel()));
1676 void JSONNodeDumper::VisitWhileStmt(const WhileStmt
*WS
) {
1677 attributeOnlyIfTrue("hasVar", WS
->hasVarStorage());
1680 void JSONNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt
* OACS
) {
1681 // FIXME: it would be nice for the ASTNodeTraverser would handle the catch
1682 // parameter the same way for C++ and ObjC rather. In this case, C++ gets a
1683 // null child node and ObjC gets no child node.
1684 attributeOnlyIfTrue("isCatchAll", OACS
->getCatchParamDecl() == nullptr);
1687 void JSONNodeDumper::VisitNullTemplateArgument(const TemplateArgument
&TA
) {
1688 JOS
.attribute("isNull", true);
1690 void JSONNodeDumper::VisitTypeTemplateArgument(const TemplateArgument
&TA
) {
1691 JOS
.attribute("type", createQualType(TA
.getAsType()));
1693 void JSONNodeDumper::VisitDeclarationTemplateArgument(
1694 const TemplateArgument
&TA
) {
1695 JOS
.attribute("decl", createBareDeclRef(TA
.getAsDecl()));
1697 void JSONNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument
&TA
) {
1698 JOS
.attribute("isNullptr", true);
1700 void JSONNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument
&TA
) {
1701 JOS
.attribute("value", TA
.getAsIntegral().getSExtValue());
1703 void JSONNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument
&TA
) {
1704 // FIXME: cannot just call dump() on the argument, as that doesn't specify
1705 // the output format.
1707 void JSONNodeDumper::VisitTemplateExpansionTemplateArgument(
1708 const TemplateArgument
&TA
) {
1709 // FIXME: cannot just call dump() on the argument, as that doesn't specify
1710 // the output format.
1712 void JSONNodeDumper::VisitExpressionTemplateArgument(
1713 const TemplateArgument
&TA
) {
1714 JOS
.attribute("isExpr", true);
1716 void JSONNodeDumper::VisitPackTemplateArgument(const TemplateArgument
&TA
) {
1717 JOS
.attribute("isPack", true);
1720 StringRef
JSONNodeDumper::getCommentCommandName(unsigned CommandID
) const {
1722 return Traits
->getCommandInfo(CommandID
)->Name
;
1723 if (const comments::CommandInfo
*Info
=
1724 comments::CommandTraits::getBuiltinCommandInfo(CommandID
))
1729 void JSONNodeDumper::visitTextComment(const comments::TextComment
*C
,
1730 const comments::FullComment
*) {
1731 JOS
.attribute("text", C
->getText());
1734 void JSONNodeDumper::visitInlineCommandComment(
1735 const comments::InlineCommandComment
*C
, const comments::FullComment
*) {
1736 JOS
.attribute("name", getCommentCommandName(C
->getCommandID()));
1738 switch (C
->getRenderKind()) {
1739 case comments::InlineCommandRenderKind::Normal
:
1740 JOS
.attribute("renderKind", "normal");
1742 case comments::InlineCommandRenderKind::Bold
:
1743 JOS
.attribute("renderKind", "bold");
1745 case comments::InlineCommandRenderKind::Emphasized
:
1746 JOS
.attribute("renderKind", "emphasized");
1748 case comments::InlineCommandRenderKind::Monospaced
:
1749 JOS
.attribute("renderKind", "monospaced");
1751 case comments::InlineCommandRenderKind::Anchor
:
1752 JOS
.attribute("renderKind", "anchor");
1756 llvm::json::Array Args
;
1757 for (unsigned I
= 0, E
= C
->getNumArgs(); I
< E
; ++I
)
1758 Args
.push_back(C
->getArgText(I
));
1761 JOS
.attribute("args", std::move(Args
));
1764 void JSONNodeDumper::visitHTMLStartTagComment(
1765 const comments::HTMLStartTagComment
*C
, const comments::FullComment
*) {
1766 JOS
.attribute("name", C
->getTagName());
1767 attributeOnlyIfTrue("selfClosing", C
->isSelfClosing());
1768 attributeOnlyIfTrue("malformed", C
->isMalformed());
1770 llvm::json::Array Attrs
;
1771 for (unsigned I
= 0, E
= C
->getNumAttrs(); I
< E
; ++I
)
1773 {{"name", C
->getAttr(I
).Name
}, {"value", C
->getAttr(I
).Value
}});
1776 JOS
.attribute("attrs", std::move(Attrs
));
1779 void JSONNodeDumper::visitHTMLEndTagComment(
1780 const comments::HTMLEndTagComment
*C
, const comments::FullComment
*) {
1781 JOS
.attribute("name", C
->getTagName());
1784 void JSONNodeDumper::visitBlockCommandComment(
1785 const comments::BlockCommandComment
*C
, const comments::FullComment
*) {
1786 JOS
.attribute("name", getCommentCommandName(C
->getCommandID()));
1788 llvm::json::Array Args
;
1789 for (unsigned I
= 0, E
= C
->getNumArgs(); I
< E
; ++I
)
1790 Args
.push_back(C
->getArgText(I
));
1793 JOS
.attribute("args", std::move(Args
));
1796 void JSONNodeDumper::visitParamCommandComment(
1797 const comments::ParamCommandComment
*C
, const comments::FullComment
*FC
) {
1798 switch (C
->getDirection()) {
1799 case comments::ParamCommandPassDirection::In
:
1800 JOS
.attribute("direction", "in");
1802 case comments::ParamCommandPassDirection::Out
:
1803 JOS
.attribute("direction", "out");
1805 case comments::ParamCommandPassDirection::InOut
:
1806 JOS
.attribute("direction", "in,out");
1809 attributeOnlyIfTrue("explicit", C
->isDirectionExplicit());
1811 if (C
->hasParamName())
1812 JOS
.attribute("param", C
->isParamIndexValid() ? C
->getParamName(FC
)
1813 : C
->getParamNameAsWritten());
1815 if (C
->isParamIndexValid() && !C
->isVarArgParam())
1816 JOS
.attribute("paramIdx", C
->getParamIndex());
1819 void JSONNodeDumper::visitTParamCommandComment(
1820 const comments::TParamCommandComment
*C
, const comments::FullComment
*FC
) {
1821 if (C
->hasParamName())
1822 JOS
.attribute("param", C
->isPositionValid() ? C
->getParamName(FC
)
1823 : C
->getParamNameAsWritten());
1824 if (C
->isPositionValid()) {
1825 llvm::json::Array Positions
;
1826 for (unsigned I
= 0, E
= C
->getDepth(); I
< E
; ++I
)
1827 Positions
.push_back(C
->getIndex(I
));
1829 if (!Positions
.empty())
1830 JOS
.attribute("positions", std::move(Positions
));
1834 void JSONNodeDumper::visitVerbatimBlockComment(
1835 const comments::VerbatimBlockComment
*C
, const comments::FullComment
*) {
1836 JOS
.attribute("name", getCommentCommandName(C
->getCommandID()));
1837 JOS
.attribute("closeName", C
->getCloseName());
1840 void JSONNodeDumper::visitVerbatimBlockLineComment(
1841 const comments::VerbatimBlockLineComment
*C
,
1842 const comments::FullComment
*) {
1843 JOS
.attribute("text", C
->getText());
1846 void JSONNodeDumper::visitVerbatimLineComment(
1847 const comments::VerbatimLineComment
*C
, const comments::FullComment
*) {
1848 JOS
.attribute("text", C
->getText());
1851 llvm::json::Object
JSONNodeDumper::createFPOptions(FPOptionsOverride FPO
) {
1852 llvm::json::Object Ret
;
1853 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
1854 if (FPO.has##NAME##Override()) \
1855 Ret.try_emplace(#NAME, static_cast<unsigned>(FPO.get##NAME##Override()));
1856 #include "clang/Basic/FPOptions.def"
1860 void JSONNodeDumper::VisitCompoundStmt(const CompoundStmt
*S
) {
1862 if (S
->hasStoredFPFeatures())
1863 JOS
.attribute("fpoptions", createFPOptions(S
->getStoredFPFeatures()));