1896 lines · cpp
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"7 8using namespace clang;9 10void JSONNodeDumper::addPreviousDeclaration(const Decl *D) {11 switch (D->getKind()) {12#define DECL(DERIVED, BASE) \13 case Decl::DERIVED: \14 return writePreviousDeclImpl(cast<DERIVED##Decl>(D));15#define ABSTRACT_DECL(DECL)16#include "clang/AST/DeclNodes.inc"17#undef ABSTRACT_DECL18#undef DECL19 }20 llvm_unreachable("Decl that isn't part of DeclNodes.inc!");21}22 23void JSONNodeDumper::Visit(const Attr *A) {24 const char *AttrName = nullptr;25 switch (A->getKind()) {26#define ATTR(X) \27 case attr::X: \28 AttrName = #X"Attr"; \29 break;30#include "clang/Basic/AttrList.inc"31#undef ATTR32 }33 JOS.attribute("id", createPointerRepresentation(A));34 JOS.attribute("kind", AttrName);35 JOS.attributeObject("range", [A, this] { writeSourceRange(A->getRange()); });36 attributeOnlyIfTrue("inherited", A->isInherited());37 attributeOnlyIfTrue("implicit", A->isImplicit());38 39 // FIXME: it would be useful for us to output the spelling kind as well as40 // the actual spelling. This would allow us to distinguish between the41 // various attribute syntaxes, but we don't currently track that information42 // within the AST.43 //JOS.attribute("spelling", A->getSpelling());44 45 InnerAttrVisitor::Visit(A);46}47 48void JSONNodeDumper::Visit(const Stmt *S) {49 if (!S)50 return;51 52 JOS.attribute("id", createPointerRepresentation(S));53 JOS.attribute("kind", S->getStmtClassName());54 JOS.attributeObject("range",55 [S, this] { writeSourceRange(S->getSourceRange()); });56 57 if (const auto *E = dyn_cast<Expr>(S)) {58 JOS.attribute("type", createQualType(E->getType()));59 const char *Category = nullptr;60 switch (E->getValueKind()) {61 case VK_LValue: Category = "lvalue"; break;62 case VK_XValue: Category = "xvalue"; break;63 case VK_PRValue:64 Category = "prvalue";65 break;66 }67 JOS.attribute("valueCategory", Category);68 }69 InnerStmtVisitor::Visit(S);70}71 72void JSONNodeDumper::Visit(const Type *T) {73 JOS.attribute("id", createPointerRepresentation(T));74 75 if (!T)76 return;77 78 JOS.attribute("kind", (llvm::Twine(T->getTypeClassName()) + "Type").str());79 JOS.attribute("type", createQualType(QualType(T, 0), /*Desugar=*/false));80 attributeOnlyIfTrue("containsErrors", T->containsErrors());81 attributeOnlyIfTrue("isDependent", T->isDependentType());82 attributeOnlyIfTrue("isInstantiationDependent",83 T->isInstantiationDependentType());84 attributeOnlyIfTrue("isVariablyModified", T->isVariablyModifiedType());85 attributeOnlyIfTrue("containsUnexpandedPack",86 T->containsUnexpandedParameterPack());87 attributeOnlyIfTrue("isImported", T->isFromAST());88 InnerTypeVisitor::Visit(T);89}90 91void JSONNodeDumper::Visit(QualType T) {92 JOS.attribute("id", createPointerRepresentation(T.getAsOpaquePtr()));93 JOS.attribute("kind", "QualType");94 JOS.attribute("type", createQualType(T));95 JOS.attribute("qualifiers", T.split().Quals.getAsString());96}97 98void JSONNodeDumper::Visit(TypeLoc TL) {99 if (TL.isNull())100 return;101 JOS.attribute("kind",102 (llvm::Twine(TL.getTypeLocClass() == TypeLoc::Qualified103 ? "Qualified"104 : TL.getTypePtr()->getTypeClassName()) +105 "TypeLoc")106 .str());107 JOS.attribute("type",108 createQualType(QualType(TL.getType()), /*Desugar=*/false));109 JOS.attributeObject("range",110 [TL, this] { writeSourceRange(TL.getSourceRange()); });111}112 113void JSONNodeDumper::Visit(const Decl *D) {114 JOS.attribute("id", createPointerRepresentation(D));115 116 if (!D)117 return;118 119 JOS.attribute("kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str());120 JOS.attributeObject("loc",121 [D, this] { writeSourceLocation(D->getLocation()); });122 JOS.attributeObject("range",123 [D, this] { writeSourceRange(D->getSourceRange()); });124 attributeOnlyIfTrue("isImplicit", D->isImplicit());125 attributeOnlyIfTrue("isInvalid", D->isInvalidDecl());126 127 if (D->isUsed())128 JOS.attribute("isUsed", true);129 else if (D->isThisDeclarationReferenced())130 JOS.attribute("isReferenced", true);131 132 if (const auto *ND = dyn_cast<NamedDecl>(D))133 attributeOnlyIfTrue("isHidden", !ND->isUnconditionallyVisible());134 135 if (D->getLexicalDeclContext() != D->getDeclContext()) {136 // Because of multiple inheritance, a DeclContext pointer does not produce137 // the same pointer representation as a Decl pointer that references the138 // same AST Node.139 const auto *ParentDeclContextDecl = dyn_cast<Decl>(D->getDeclContext());140 JOS.attribute("parentDeclContextId",141 createPointerRepresentation(ParentDeclContextDecl));142 }143 144 addPreviousDeclaration(D);145 InnerDeclVisitor::Visit(D);146}147 148void JSONNodeDumper::Visit(const comments::Comment *C,149 const comments::FullComment *FC) {150 if (!C)151 return;152 153 JOS.attribute("id", createPointerRepresentation(C));154 JOS.attribute("kind", C->getCommentKindName());155 JOS.attributeObject("loc",156 [C, this] { writeSourceLocation(C->getLocation()); });157 JOS.attributeObject("range",158 [C, this] { writeSourceRange(C->getSourceRange()); });159 160 InnerCommentVisitor::visit(C, FC);161}162 163void JSONNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,164 const Decl *From, StringRef Label) {165 JOS.attribute("kind", "TemplateArgument");166 if (R.isValid())167 JOS.attributeObject("range", [R, this] { writeSourceRange(R); });168 169 if (From)170 JOS.attribute(Label.empty() ? "fromDecl" : Label, createBareDeclRef(From));171 172 InnerTemplateArgVisitor::Visit(TA);173}174 175void JSONNodeDumper::Visit(const CXXCtorInitializer *Init) {176 JOS.attribute("kind", "CXXCtorInitializer");177 if (Init->isAnyMemberInitializer())178 JOS.attribute("anyInit", createBareDeclRef(Init->getAnyMember()));179 else if (Init->isBaseInitializer())180 JOS.attribute("baseInit",181 createQualType(QualType(Init->getBaseClass(), 0)));182 else if (Init->isDelegatingInitializer())183 JOS.attribute("delegatingInit",184 createQualType(Init->getTypeSourceInfo()->getType()));185 else186 llvm_unreachable("Unknown initializer type");187}188 189void JSONNodeDumper::Visit(const OpenACCClause *C) {}190 191void JSONNodeDumper::Visit(const OMPClause *C) {}192 193void JSONNodeDumper::Visit(const BlockDecl::Capture &C) {194 JOS.attribute("kind", "Capture");195 attributeOnlyIfTrue("byref", C.isByRef());196 attributeOnlyIfTrue("nested", C.isNested());197 if (C.getVariable())198 JOS.attribute("var", createBareDeclRef(C.getVariable()));199}200 201void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {202 JOS.attribute("associationKind", A.getTypeSourceInfo() ? "case" : "default");203 attributeOnlyIfTrue("selected", A.isSelected());204}205 206void JSONNodeDumper::Visit(const concepts::Requirement *R) {207 if (!R)208 return;209 210 switch (R->getKind()) {211 case concepts::Requirement::RK_Type:212 JOS.attribute("kind", "TypeRequirement");213 break;214 case concepts::Requirement::RK_Simple:215 JOS.attribute("kind", "SimpleRequirement");216 break;217 case concepts::Requirement::RK_Compound:218 JOS.attribute("kind", "CompoundRequirement");219 break;220 case concepts::Requirement::RK_Nested:221 JOS.attribute("kind", "NestedRequirement");222 break;223 }224 225 if (auto *ER = dyn_cast<concepts::ExprRequirement>(R))226 attributeOnlyIfTrue("noexcept", ER->hasNoexceptRequirement());227 228 attributeOnlyIfTrue("isDependent", R->isDependent());229 if (!R->isDependent())230 JOS.attribute("satisfied", R->isSatisfied());231 attributeOnlyIfTrue("containsUnexpandedPack",232 R->containsUnexpandedParameterPack());233}234 235void JSONNodeDumper::Visit(const APValue &Value, QualType Ty) {236 std::string Str;237 llvm::raw_string_ostream OS(Str);238 Value.printPretty(OS, Ctx, Ty);239 JOS.attribute("value", Str);240}241 242void JSONNodeDumper::Visit(const ConceptReference *CR) {243 JOS.attribute("kind", "ConceptReference");244 JOS.attribute("id", createPointerRepresentation(CR->getNamedConcept()));245 if (const auto *Args = CR->getTemplateArgsAsWritten()) {246 JOS.attributeArray("templateArgsAsWritten", [Args, this] {247 for (const TemplateArgumentLoc &TAL : Args->arguments())248 JOS.object(249 [&TAL, this] { Visit(TAL.getArgument(), TAL.getSourceRange()); });250 });251 }252 JOS.attributeObject("loc",253 [CR, this] { writeSourceLocation(CR->getLocation()); });254 JOS.attributeObject("range",255 [CR, this] { writeSourceRange(CR->getSourceRange()); });256}257 258void JSONNodeDumper::writeIncludeStack(PresumedLoc Loc, bool JustFirst) {259 if (Loc.isInvalid())260 return;261 262 JOS.attributeBegin("includedFrom");263 JOS.objectBegin();264 265 if (!JustFirst) {266 // Walk the stack recursively, then print out the presumed location.267 writeIncludeStack(SM.getPresumedLoc(Loc.getIncludeLoc()));268 }269 270 JOS.attribute("file", Loc.getFilename());271 JOS.objectEnd();272 JOS.attributeEnd();273}274 275void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc) {276 PresumedLoc Presumed = SM.getPresumedLoc(Loc);277 if (Presumed.isValid()) {278 StringRef ActualFile = SM.getBufferName(Loc);279 auto [FID, FilePos] = SM.getDecomposedLoc(Loc);280 unsigned ActualLine = SM.getLineNumber(FID, FilePos);281 JOS.attribute("offset", FilePos);282 if (LastLocFilename != ActualFile) {283 JOS.attribute("file", ActualFile);284 JOS.attribute("line", ActualLine);285 } else if (LastLocLine != ActualLine)286 JOS.attribute("line", ActualLine);287 288 StringRef PresumedFile = Presumed.getFilename();289 if (PresumedFile != ActualFile && LastLocPresumedFilename != PresumedFile)290 JOS.attribute("presumedFile", PresumedFile);291 292 unsigned PresumedLine = Presumed.getLine();293 if (ActualLine != PresumedLine && LastLocPresumedLine != PresumedLine)294 JOS.attribute("presumedLine", PresumedLine);295 296 JOS.attribute("col", Presumed.getColumn());297 JOS.attribute("tokLen",298 Lexer::MeasureTokenLength(Loc, SM, Ctx.getLangOpts()));299 LastLocFilename = ActualFile;300 LastLocPresumedFilename = PresumedFile;301 LastLocPresumedLine = PresumedLine;302 LastLocLine = ActualLine;303 304 // Orthogonal to the file, line, and column de-duplication is whether the305 // given location was a result of an include. If so, print where the306 // include location came from.307 writeIncludeStack(SM.getPresumedLoc(Presumed.getIncludeLoc()),308 /*JustFirst*/ true);309 }310}311 312void JSONNodeDumper::writeSourceLocation(SourceLocation Loc) {313 SourceLocation Spelling = SM.getSpellingLoc(Loc);314 SourceLocation Expansion = SM.getExpansionLoc(Loc);315 316 if (Expansion != Spelling) {317 // If the expansion and the spelling are different, output subobjects318 // describing both locations.319 JOS.attributeObject(320 "spellingLoc", [Spelling, this] { writeBareSourceLocation(Spelling); });321 JOS.attributeObject("expansionLoc", [Expansion, Loc, this] {322 writeBareSourceLocation(Expansion);323 // If there is a macro expansion, add extra information if the interesting324 // bit is the macro arg expansion.325 if (SM.isMacroArgExpansion(Loc))326 JOS.attribute("isMacroArgExpansion", true);327 });328 } else329 writeBareSourceLocation(Spelling);330}331 332void JSONNodeDumper::writeSourceRange(SourceRange R) {333 JOS.attributeObject("begin",334 [R, this] { writeSourceLocation(R.getBegin()); });335 JOS.attributeObject("end", [R, this] { writeSourceLocation(R.getEnd()); });336}337 338std::string JSONNodeDumper::createPointerRepresentation(const void *Ptr) {339 // Because JSON stores integer values as signed 64-bit integers, trying to340 // represent them as such makes for very ugly pointer values in the resulting341 // output. Instead, we convert the value to hex and treat it as a string.342 return "0x" + llvm::utohexstr(reinterpret_cast<uint64_t>(Ptr), true);343}344 345llvm::json::Object JSONNodeDumper::createQualType(QualType QT, bool Desugar) {346 SplitQualType SQT = QT.split();347 std::string SQTS = QualType::getAsString(SQT, PrintPolicy);348 llvm::json::Object Ret{{"qualType", SQTS}};349 350 if (Desugar && !QT.isNull()) {351 SplitQualType DSQT = QT.getSplitDesugaredType();352 if (DSQT != SQT) {353 std::string DSQTS = QualType::getAsString(DSQT, PrintPolicy);354 if (DSQTS != SQTS)355 Ret["desugaredQualType"] = DSQTS;356 }357 if (const auto *TT = QT->getAs<TypedefType>())358 Ret["typeAliasDeclId"] = createPointerRepresentation(TT->getDecl());359 }360 return Ret;361}362 363void JSONNodeDumper::writeBareDeclRef(const Decl *D) {364 JOS.attribute("id", createPointerRepresentation(D));365 if (!D)366 return;367 368 JOS.attribute("kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str());369 if (const auto *ND = dyn_cast<NamedDecl>(D))370 JOS.attribute("name", ND->getDeclName().getAsString());371 if (const auto *VD = dyn_cast<ValueDecl>(D))372 JOS.attribute("type", createQualType(VD->getType()));373}374 375llvm::json::Object JSONNodeDumper::createBareDeclRef(const Decl *D) {376 llvm::json::Object Ret{{"id", createPointerRepresentation(D)}};377 if (!D)378 return Ret;379 380 Ret["kind"] = (llvm::Twine(D->getDeclKindName()) + "Decl").str();381 if (const auto *ND = dyn_cast<NamedDecl>(D))382 Ret["name"] = ND->getDeclName().getAsString();383 if (const auto *VD = dyn_cast<ValueDecl>(D))384 Ret["type"] = createQualType(VD->getType());385 return Ret;386}387 388llvm::json::Array JSONNodeDumper::createCastPath(const CastExpr *C) {389 llvm::json::Array Ret;390 if (C->path_empty())391 return Ret;392 393 for (auto I = C->path_begin(), E = C->path_end(); I != E; ++I) {394 const CXXBaseSpecifier *Base = *I;395 const auto *RD = cast<CXXRecordDecl>(396 Base->getType()->castAsCanonical<RecordType>()->getDecl());397 398 llvm::json::Object Val{{"name", RD->getName()}};399 if (Base->isVirtual())400 Val["isVirtual"] = true;401 Ret.push_back(std::move(Val));402 }403 return Ret;404}405 406#define FIELD2(Name, Flag) if (RD->Flag()) Ret[Name] = true407#define FIELD1(Flag) FIELD2(#Flag, Flag)408 409static llvm::json::Object410createDefaultConstructorDefinitionData(const CXXRecordDecl *RD) {411 llvm::json::Object Ret;412 413 FIELD2("exists", hasDefaultConstructor);414 FIELD2("trivial", hasTrivialDefaultConstructor);415 FIELD2("nonTrivial", hasNonTrivialDefaultConstructor);416 FIELD2("userProvided", hasUserProvidedDefaultConstructor);417 FIELD2("isConstexpr", hasConstexprDefaultConstructor);418 FIELD2("needsImplicit", needsImplicitDefaultConstructor);419 FIELD2("defaultedIsConstexpr", defaultedDefaultConstructorIsConstexpr);420 421 return Ret;422}423 424static llvm::json::Object425createCopyConstructorDefinitionData(const CXXRecordDecl *RD) {426 llvm::json::Object Ret;427 428 FIELD2("simple", hasSimpleCopyConstructor);429 FIELD2("trivial", hasTrivialCopyConstructor);430 FIELD2("nonTrivial", hasNonTrivialCopyConstructor);431 FIELD2("userDeclared", hasUserDeclaredCopyConstructor);432 FIELD2("hasConstParam", hasCopyConstructorWithConstParam);433 FIELD2("implicitHasConstParam", implicitCopyConstructorHasConstParam);434 FIELD2("needsImplicit", needsImplicitCopyConstructor);435 FIELD2("needsOverloadResolution", needsOverloadResolutionForCopyConstructor);436 if (!RD->needsOverloadResolutionForCopyConstructor())437 FIELD2("defaultedIsDeleted", defaultedCopyConstructorIsDeleted);438 439 return Ret;440}441 442static llvm::json::Object443createMoveConstructorDefinitionData(const CXXRecordDecl *RD) {444 llvm::json::Object Ret;445 446 FIELD2("exists", hasMoveConstructor);447 FIELD2("simple", hasSimpleMoveConstructor);448 FIELD2("trivial", hasTrivialMoveConstructor);449 FIELD2("nonTrivial", hasNonTrivialMoveConstructor);450 FIELD2("userDeclared", hasUserDeclaredMoveConstructor);451 FIELD2("needsImplicit", needsImplicitMoveConstructor);452 FIELD2("needsOverloadResolution", needsOverloadResolutionForMoveConstructor);453 if (!RD->needsOverloadResolutionForMoveConstructor())454 FIELD2("defaultedIsDeleted", defaultedMoveConstructorIsDeleted);455 456 return Ret;457}458 459static llvm::json::Object460createCopyAssignmentDefinitionData(const CXXRecordDecl *RD) {461 llvm::json::Object Ret;462 463 FIELD2("simple", hasSimpleCopyAssignment);464 FIELD2("trivial", hasTrivialCopyAssignment);465 FIELD2("nonTrivial", hasNonTrivialCopyAssignment);466 FIELD2("hasConstParam", hasCopyAssignmentWithConstParam);467 FIELD2("implicitHasConstParam", implicitCopyAssignmentHasConstParam);468 FIELD2("userDeclared", hasUserDeclaredCopyAssignment);469 FIELD2("needsImplicit", needsImplicitCopyAssignment);470 FIELD2("needsOverloadResolution", needsOverloadResolutionForCopyAssignment);471 472 return Ret;473}474 475static llvm::json::Object476createMoveAssignmentDefinitionData(const CXXRecordDecl *RD) {477 llvm::json::Object Ret;478 479 FIELD2("exists", hasMoveAssignment);480 FIELD2("simple", hasSimpleMoveAssignment);481 FIELD2("trivial", hasTrivialMoveAssignment);482 FIELD2("nonTrivial", hasNonTrivialMoveAssignment);483 FIELD2("userDeclared", hasUserDeclaredMoveAssignment);484 FIELD2("needsImplicit", needsImplicitMoveAssignment);485 FIELD2("needsOverloadResolution", needsOverloadResolutionForMoveAssignment);486 487 return Ret;488}489 490static llvm::json::Object491createDestructorDefinitionData(const CXXRecordDecl *RD) {492 llvm::json::Object Ret;493 494 FIELD2("simple", hasSimpleDestructor);495 FIELD2("irrelevant", hasIrrelevantDestructor);496 FIELD2("trivial", hasTrivialDestructor);497 FIELD2("nonTrivial", hasNonTrivialDestructor);498 FIELD2("userDeclared", hasUserDeclaredDestructor);499 FIELD2("needsImplicit", needsImplicitDestructor);500 FIELD2("needsOverloadResolution", needsOverloadResolutionForDestructor);501 if (!RD->needsOverloadResolutionForDestructor())502 FIELD2("defaultedIsDeleted", defaultedDestructorIsDeleted);503 504 return Ret;505}506 507llvm::json::Object508JSONNodeDumper::createCXXRecordDefinitionData(const CXXRecordDecl *RD) {509 llvm::json::Object Ret;510 511 // This data is common to all C++ classes.512 FIELD1(isGenericLambda);513 FIELD1(isLambda);514 FIELD1(isEmpty);515 FIELD1(isAggregate);516 FIELD1(isStandardLayout);517 FIELD1(isTriviallyCopyable);518 FIELD1(isPOD);519 FIELD1(isTrivial);520 FIELD1(isPolymorphic);521 FIELD1(isAbstract);522 FIELD1(isLiteral);523 FIELD1(canPassInRegisters);524 FIELD1(hasUserDeclaredConstructor);525 FIELD1(hasConstexprNonCopyMoveConstructor);526 FIELD1(hasMutableFields);527 FIELD1(hasVariantMembers);528 FIELD2("canConstDefaultInit", allowConstDefaultInit);529 530 Ret["defaultCtor"] = createDefaultConstructorDefinitionData(RD);531 Ret["copyCtor"] = createCopyConstructorDefinitionData(RD);532 Ret["moveCtor"] = createMoveConstructorDefinitionData(RD);533 Ret["copyAssign"] = createCopyAssignmentDefinitionData(RD);534 Ret["moveAssign"] = createMoveAssignmentDefinitionData(RD);535 Ret["dtor"] = createDestructorDefinitionData(RD);536 537 return Ret;538}539 540#undef FIELD1541#undef FIELD2542 543std::string JSONNodeDumper::createAccessSpecifier(AccessSpecifier AS) {544 const auto AccessSpelling = getAccessSpelling(AS);545 if (AccessSpelling.empty())546 return "none";547 return AccessSpelling.str();548}549 550llvm::json::Object551JSONNodeDumper::createCXXBaseSpecifier(const CXXBaseSpecifier &BS) {552 llvm::json::Object Ret;553 554 Ret["type"] = createQualType(BS.getType());555 Ret["access"] = createAccessSpecifier(BS.getAccessSpecifier());556 Ret["writtenAccess"] =557 createAccessSpecifier(BS.getAccessSpecifierAsWritten());558 if (BS.isVirtual())559 Ret["isVirtual"] = true;560 if (BS.isPackExpansion())561 Ret["isPackExpansion"] = true;562 563 return Ret;564}565 566void JSONNodeDumper::VisitAliasAttr(const AliasAttr *AA) {567 JOS.attribute("aliasee", AA->getAliasee());568}569 570void JSONNodeDumper::VisitCleanupAttr(const CleanupAttr *CA) {571 JOS.attribute("cleanup_function", createBareDeclRef(CA->getFunctionDecl()));572}573 574void JSONNodeDumper::VisitDeprecatedAttr(const DeprecatedAttr *DA) {575 if (!DA->getMessage().empty())576 JOS.attribute("message", DA->getMessage());577 if (!DA->getReplacement().empty())578 JOS.attribute("replacement", DA->getReplacement());579}580 581void JSONNodeDumper::VisitUnavailableAttr(const UnavailableAttr *UA) {582 if (!UA->getMessage().empty())583 JOS.attribute("message", UA->getMessage());584}585 586void JSONNodeDumper::VisitSectionAttr(const SectionAttr *SA) {587 JOS.attribute("section_name", SA->getName());588}589 590void JSONNodeDumper::VisitVisibilityAttr(const VisibilityAttr *VA) {591 JOS.attribute("visibility", VisibilityAttr::ConvertVisibilityTypeToStr(592 VA->getVisibility()));593}594 595void JSONNodeDumper::VisitTLSModelAttr(const TLSModelAttr *TA) {596 JOS.attribute("tls_model", TA->getModel());597}598 599void JSONNodeDumper::VisitTypedefType(const TypedefType *TT) {600 JOS.attribute("decl", createBareDeclRef(TT->getDecl()));601 if (!TT->typeMatchesDecl())602 JOS.attribute("type", createQualType(TT->desugar()));603}604 605void JSONNodeDumper::VisitUsingType(const UsingType *TT) {606 JOS.attribute("decl", createBareDeclRef(TT->getDecl()));607 JOS.attribute("type", createQualType(TT->desugar()));608}609 610void JSONNodeDumper::VisitFunctionType(const FunctionType *T) {611 FunctionType::ExtInfo E = T->getExtInfo();612 attributeOnlyIfTrue("noreturn", E.getNoReturn());613 attributeOnlyIfTrue("producesResult", E.getProducesResult());614 if (E.getHasRegParm())615 JOS.attribute("regParm", E.getRegParm());616 JOS.attribute("cc", FunctionType::getNameForCallConv(E.getCC()));617}618 619void JSONNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {620 FunctionProtoType::ExtProtoInfo E = T->getExtProtoInfo();621 attributeOnlyIfTrue("trailingReturn", E.HasTrailingReturn);622 attributeOnlyIfTrue("const", T->isConst());623 attributeOnlyIfTrue("volatile", T->isVolatile());624 attributeOnlyIfTrue("restrict", T->isRestrict());625 attributeOnlyIfTrue("variadic", E.Variadic);626 switch (E.RefQualifier) {627 case RQ_LValue: JOS.attribute("refQualifier", "&"); break;628 case RQ_RValue: JOS.attribute("refQualifier", "&&"); break;629 case RQ_None: break;630 }631 switch (E.ExceptionSpec.Type) {632 case EST_DynamicNone:633 case EST_Dynamic: {634 JOS.attribute("exceptionSpec", "throw");635 llvm::json::Array Types;636 for (QualType QT : E.ExceptionSpec.Exceptions)637 Types.push_back(createQualType(QT));638 JOS.attribute("exceptionTypes", std::move(Types));639 } break;640 case EST_MSAny:641 JOS.attribute("exceptionSpec", "throw");642 JOS.attribute("throwsAny", true);643 break;644 case EST_BasicNoexcept:645 JOS.attribute("exceptionSpec", "noexcept");646 break;647 case EST_NoexceptTrue:648 case EST_NoexceptFalse:649 JOS.attribute("exceptionSpec", "noexcept");650 JOS.attribute("conditionEvaluatesTo",651 E.ExceptionSpec.Type == EST_NoexceptTrue);652 //JOS.attributeWithCall("exceptionSpecExpr",653 // [this, E]() { Visit(E.ExceptionSpec.NoexceptExpr); });654 break;655 case EST_NoThrow:656 JOS.attribute("exceptionSpec", "nothrow");657 break;658 // FIXME: I cannot find a way to trigger these cases while dumping the AST. I659 // suspect you can only run into them when executing an AST dump from within660 // the debugger, which is not a use case we worry about for the JSON dumping661 // feature.662 case EST_DependentNoexcept:663 case EST_Unevaluated:664 case EST_Uninstantiated:665 case EST_Unparsed:666 case EST_None: break;667 }668 VisitFunctionType(T);669}670 671void JSONNodeDumper::VisitRValueReferenceType(const ReferenceType *RT) {672 attributeOnlyIfTrue("spelledAsLValue", RT->isSpelledAsLValue());673}674 675void JSONNodeDumper::VisitArrayType(const ArrayType *AT) {676 switch (AT->getSizeModifier()) {677 case ArraySizeModifier::Star:678 JOS.attribute("sizeModifier", "*");679 break;680 case ArraySizeModifier::Static:681 JOS.attribute("sizeModifier", "static");682 break;683 case ArraySizeModifier::Normal:684 break;685 }686 687 std::string Str = AT->getIndexTypeQualifiers().getAsString();688 if (!Str.empty())689 JOS.attribute("indexTypeQualifiers", Str);690}691 692void JSONNodeDumper::VisitConstantArrayType(const ConstantArrayType *CAT) {693 // FIXME: this should use ZExt instead of SExt, but JSON doesn't allow a694 // narrowing conversion to int64_t so it cannot be expressed.695 JOS.attribute("size", CAT->getSExtSize());696 VisitArrayType(CAT);697}698 699void JSONNodeDumper::VisitDependentSizedExtVectorType(700 const DependentSizedExtVectorType *VT) {701 JOS.attributeObject(702 "attrLoc", [VT, this] { writeSourceLocation(VT->getAttributeLoc()); });703}704 705void JSONNodeDumper::VisitVectorType(const VectorType *VT) {706 JOS.attribute("numElements", VT->getNumElements());707 switch (VT->getVectorKind()) {708 case VectorKind::Generic:709 break;710 case VectorKind::AltiVecVector:711 JOS.attribute("vectorKind", "altivec");712 break;713 case VectorKind::AltiVecPixel:714 JOS.attribute("vectorKind", "altivec pixel");715 break;716 case VectorKind::AltiVecBool:717 JOS.attribute("vectorKind", "altivec bool");718 break;719 case VectorKind::Neon:720 JOS.attribute("vectorKind", "neon");721 break;722 case VectorKind::NeonPoly:723 JOS.attribute("vectorKind", "neon poly");724 break;725 case VectorKind::SveFixedLengthData:726 JOS.attribute("vectorKind", "fixed-length sve data vector");727 break;728 case VectorKind::SveFixedLengthPredicate:729 JOS.attribute("vectorKind", "fixed-length sve predicate vector");730 break;731 case VectorKind::RVVFixedLengthData:732 JOS.attribute("vectorKind", "fixed-length rvv data vector");733 break;734 case VectorKind::RVVFixedLengthMask:735 case VectorKind::RVVFixedLengthMask_1:736 case VectorKind::RVVFixedLengthMask_2:737 case VectorKind::RVVFixedLengthMask_4:738 JOS.attribute("vectorKind", "fixed-length rvv mask vector");739 break;740 }741}742 743void JSONNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *UUT) {744 JOS.attribute("decl", createBareDeclRef(UUT->getDecl()));745}746 747void JSONNodeDumper::VisitUnaryTransformType(const UnaryTransformType *UTT) {748 switch (UTT->getUTTKind()) {749#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \750 case UnaryTransformType::Enum: \751 JOS.attribute("transformKind", #Trait); \752 break;753#include "clang/Basic/TransformTypeTraits.def"754 }755}756 757void JSONNodeDumper::VisitTagType(const TagType *TT) {758 if (NestedNameSpecifier Qualifier = TT->getQualifier()) {759 std::string Str;760 llvm::raw_string_ostream OS(Str);761 Qualifier.print(OS, PrintPolicy, /*ResolveTemplateArguments=*/true);762 JOS.attribute("qualifier", Str);763 }764 JOS.attribute("decl", createBareDeclRef(TT->getDecl()));765 if (TT->isTagOwned())766 JOS.attribute("isTagOwned", true);767}768 769void JSONNodeDumper::VisitTemplateTypeParmType(770 const TemplateTypeParmType *TTPT) {771 JOS.attribute("depth", TTPT->getDepth());772 JOS.attribute("index", TTPT->getIndex());773 attributeOnlyIfTrue("isPack", TTPT->isParameterPack());774 JOS.attribute("decl", createBareDeclRef(TTPT->getDecl()));775}776 777void JSONNodeDumper::VisitSubstTemplateTypeParmType(778 const SubstTemplateTypeParmType *STTPT) {779 JOS.attribute("index", STTPT->getIndex());780 if (auto PackIndex = STTPT->getPackIndex())781 JOS.attribute("pack_index", *PackIndex);782}783 784void JSONNodeDumper::VisitSubstTemplateTypeParmPackType(785 const SubstTemplateTypeParmPackType *T) {786 JOS.attribute("index", T->getIndex());787}788 789void JSONNodeDumper::VisitAutoType(const AutoType *AT) {790 JOS.attribute("undeduced", !AT->isDeduced());791 switch (AT->getKeyword()) {792 case AutoTypeKeyword::Auto:793 JOS.attribute("typeKeyword", "auto");794 break;795 case AutoTypeKeyword::DecltypeAuto:796 JOS.attribute("typeKeyword", "decltype(auto)");797 break;798 case AutoTypeKeyword::GNUAutoType:799 JOS.attribute("typeKeyword", "__auto_type");800 break;801 }802}803 804void JSONNodeDumper::VisitTemplateSpecializationType(805 const TemplateSpecializationType *TST) {806 attributeOnlyIfTrue("isAlias", TST->isTypeAlias());807 808 std::string Str;809 llvm::raw_string_ostream OS(Str);810 TST->getTemplateName().print(OS, PrintPolicy);811 JOS.attribute("templateName", Str);812}813 814void JSONNodeDumper::VisitInjectedClassNameType(815 const InjectedClassNameType *ICNT) {816 JOS.attribute("decl", createBareDeclRef(ICNT->getDecl()));817}818 819void JSONNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *OIT) {820 JOS.attribute("decl", createBareDeclRef(OIT->getDecl()));821}822 823void JSONNodeDumper::VisitPackExpansionType(const PackExpansionType *PET) {824 if (UnsignedOrNone N = PET->getNumExpansions())825 JOS.attribute("numExpansions", *N);826}827 828void JSONNodeDumper::VisitMacroQualifiedType(const MacroQualifiedType *MQT) {829 JOS.attribute("macroName", MQT->getMacroIdentifier()->getName());830}831 832void JSONNodeDumper::VisitMemberPointerType(const MemberPointerType *MPT) {833 attributeOnlyIfTrue("isData", MPT->isMemberDataPointer());834 attributeOnlyIfTrue("isFunction", MPT->isMemberFunctionPointer());835}836 837void JSONNodeDumper::VisitNamedDecl(const NamedDecl *ND) {838 if (ND && ND->getDeclName()) {839 JOS.attribute("name", ND->getNameAsString());840 // FIXME: There are likely other contexts in which it makes no sense to ask841 // for a mangled name.842 if (isa<RequiresExprBodyDecl>(ND->getDeclContext()))843 return;844 845 // If the declaration is dependent or is in a dependent context, then the846 // mangling is unlikely to be meaningful (and in some cases may cause847 // "don't know how to mangle this" assertion failures.848 if (ND->isTemplated())849 return;850 851 // Mangled names are not meaningful for locals, and may not be well-defined852 // in the case of VLAs.853 auto *VD = dyn_cast<VarDecl>(ND);854 if (VD && VD->hasLocalStorage())855 return;856 857 // Do not mangle template deduction guides.858 if (isa<CXXDeductionGuideDecl>(ND))859 return;860 861 std::string MangledName = ASTNameGen.getName(ND);862 if (!MangledName.empty())863 JOS.attribute("mangledName", MangledName);864 }865}866 867void JSONNodeDumper::VisitTypedefDecl(const TypedefDecl *TD) {868 VisitNamedDecl(TD);869 JOS.attribute("type", createQualType(TD->getUnderlyingType()));870}871 872void JSONNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *TAD) {873 VisitNamedDecl(TAD);874 JOS.attribute("type", createQualType(TAD->getUnderlyingType()));875}876 877void JSONNodeDumper::VisitNamespaceDecl(const NamespaceDecl *ND) {878 VisitNamedDecl(ND);879 attributeOnlyIfTrue("isInline", ND->isInline());880 attributeOnlyIfTrue("isNested", ND->isNested());881 if (!ND->isFirstDecl())882 JOS.attribute("originalNamespace", createBareDeclRef(ND->getFirstDecl()));883}884 885void JSONNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *UDD) {886 JOS.attribute("nominatedNamespace",887 createBareDeclRef(UDD->getNominatedNamespace()));888}889 890void JSONNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *NAD) {891 VisitNamedDecl(NAD);892 JOS.attribute("aliasedNamespace",893 createBareDeclRef(NAD->getAliasedNamespace()));894}895 896void JSONNodeDumper::VisitUsingDecl(const UsingDecl *UD) {897 std::string Name;898 if (NestedNameSpecifier Qualifier = UD->getQualifier()) {899 llvm::raw_string_ostream SOS(Name);900 Qualifier.print(SOS, UD->getASTContext().getPrintingPolicy());901 }902 Name += UD->getNameAsString();903 JOS.attribute("name", Name);904}905 906void JSONNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *UED) {907 JOS.attribute("target", createBareDeclRef(UED->getEnumDecl()));908}909 910void JSONNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *USD) {911 JOS.attribute("target", createBareDeclRef(USD->getTargetDecl()));912}913 914void JSONNodeDumper::VisitVarDecl(const VarDecl *VD) {915 VisitNamedDecl(VD);916 JOS.attribute("type", createQualType(VD->getType()));917 if (const auto *P = dyn_cast<ParmVarDecl>(VD))918 attributeOnlyIfTrue("explicitObjectParameter",919 P->isExplicitObjectParameter());920 921 StorageClass SC = VD->getStorageClass();922 if (SC != SC_None)923 JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));924 switch (VD->getTLSKind()) {925 case VarDecl::TLS_Dynamic: JOS.attribute("tls", "dynamic"); break;926 case VarDecl::TLS_Static: JOS.attribute("tls", "static"); break;927 case VarDecl::TLS_None: break;928 }929 attributeOnlyIfTrue("nrvo", VD->isNRVOVariable());930 attributeOnlyIfTrue("inline", VD->isInline());931 attributeOnlyIfTrue("constexpr", VD->isConstexpr());932 attributeOnlyIfTrue("modulePrivate", VD->isModulePrivate());933 if (VD->hasInit()) {934 switch (VD->getInitStyle()) {935 case VarDecl::CInit: JOS.attribute("init", "c"); break;936 case VarDecl::CallInit: JOS.attribute("init", "call"); break;937 case VarDecl::ListInit: JOS.attribute("init", "list"); break;938 case VarDecl::ParenListInit:939 JOS.attribute("init", "paren-list");940 break;941 }942 }943 attributeOnlyIfTrue("isParameterPack", VD->isParameterPack());944 if (const auto *Instance = VD->getTemplateInstantiationPattern())945 JOS.attribute("TemplateInstantiationPattern",946 createPointerRepresentation(Instance));947}948 949void JSONNodeDumper::VisitFieldDecl(const FieldDecl *FD) {950 VisitNamedDecl(FD);951 JOS.attribute("type", createQualType(FD->getType()));952 attributeOnlyIfTrue("mutable", FD->isMutable());953 attributeOnlyIfTrue("modulePrivate", FD->isModulePrivate());954 attributeOnlyIfTrue("isBitfield", FD->isBitField());955 attributeOnlyIfTrue("hasInClassInitializer", FD->hasInClassInitializer());956}957 958void JSONNodeDumper::VisitFunctionDecl(const FunctionDecl *FD) {959 VisitNamedDecl(FD);960 JOS.attribute("type", createQualType(FD->getType()));961 StorageClass SC = FD->getStorageClass();962 if (SC != SC_None)963 JOS.attribute("storageClass", VarDecl::getStorageClassSpecifierString(SC));964 attributeOnlyIfTrue("inline", FD->isInlineSpecified());965 attributeOnlyIfTrue("virtual", FD->isVirtualAsWritten());966 attributeOnlyIfTrue("pure", FD->isPureVirtual());967 attributeOnlyIfTrue("explicitlyDeleted", FD->isDeletedAsWritten());968 attributeOnlyIfTrue("constexpr", FD->isConstexpr());969 attributeOnlyIfTrue("variadic", FD->isVariadic());970 attributeOnlyIfTrue("immediate", FD->isImmediateFunction());971 972 if (FD->isDefaulted())973 JOS.attribute("explicitlyDefaulted",974 FD->isDeleted() ? "deleted" : "default");975 976 if (StringLiteral *Msg = FD->getDeletedMessage())977 JOS.attribute("deletedMessage", Msg->getString());978 979 if (const auto *Instance = FD->getTemplateInstantiationPattern())980 JOS.attribute("TemplateInstantiationPattern",981 createPointerRepresentation(Instance));982}983 984void JSONNodeDumper::VisitEnumDecl(const EnumDecl *ED) {985 VisitNamedDecl(ED);986 if (ED->isFixed())987 JOS.attribute("fixedUnderlyingType", createQualType(ED->getIntegerType()));988 if (ED->isScoped())989 JOS.attribute("scopedEnumTag",990 ED->isScopedUsingClassTag() ? "class" : "struct");991 if (const auto *Instance = ED->getTemplateInstantiationPattern())992 JOS.attribute("TemplateInstantiationPattern",993 createPointerRepresentation(Instance));994}995void JSONNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *ECD) {996 VisitNamedDecl(ECD);997 JOS.attribute("type", createQualType(ECD->getType()));998}999 1000void JSONNodeDumper::VisitRecordDecl(const RecordDecl *RD) {1001 VisitNamedDecl(RD);1002 JOS.attribute("tagUsed", RD->getKindName());1003 attributeOnlyIfTrue("completeDefinition", RD->isCompleteDefinition());1004}1005void JSONNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *RD) {1006 VisitRecordDecl(RD);1007 1008 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {1009 if (CTSD->hasStrictPackMatch())1010 JOS.attribute("strict-pack-match", true);1011 }1012 1013 if (const auto *Instance = RD->getTemplateInstantiationPattern())1014 JOS.attribute("TemplateInstantiationPattern",1015 createPointerRepresentation(Instance));1016 1017 // All other information requires a complete definition.1018 if (!RD->isCompleteDefinition())1019 return;1020 1021 JOS.attribute("definitionData", createCXXRecordDefinitionData(RD));1022 if (RD->getNumBases()) {1023 JOS.attributeArray("bases", [this, RD] {1024 for (const auto &Spec : RD->bases())1025 JOS.value(createCXXBaseSpecifier(Spec));1026 });1027 }1028}1029 1030void JSONNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) {1031 VisitNamedDecl(D);1032 JOS.attribute("bufferKind", D->isCBuffer() ? "cbuffer" : "tbuffer");1033}1034 1035void JSONNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {1036 VisitNamedDecl(D);1037 JOS.attribute("tagUsed", D->wasDeclaredWithTypename() ? "typename" : "class");1038 JOS.attribute("depth", D->getDepth());1039 JOS.attribute("index", D->getIndex());1040 attributeOnlyIfTrue("isParameterPack", D->isParameterPack());1041 1042 if (D->hasDefaultArgument())1043 JOS.attributeObject("defaultArg", [=] {1044 Visit(D->getDefaultArgument().getArgument(), SourceRange(),1045 D->getDefaultArgStorage().getInheritedFrom(),1046 D->defaultArgumentWasInherited() ? "inherited from" : "previous");1047 });1048}1049 1050void JSONNodeDumper::VisitNonTypeTemplateParmDecl(1051 const NonTypeTemplateParmDecl *D) {1052 VisitNamedDecl(D);1053 JOS.attribute("type", createQualType(D->getType()));1054 JOS.attribute("depth", D->getDepth());1055 JOS.attribute("index", D->getIndex());1056 attributeOnlyIfTrue("isParameterPack", D->isParameterPack());1057 1058 if (D->hasDefaultArgument())1059 JOS.attributeObject("defaultArg", [=] {1060 Visit(D->getDefaultArgument().getArgument(), SourceRange(),1061 D->getDefaultArgStorage().getInheritedFrom(),1062 D->defaultArgumentWasInherited() ? "inherited from" : "previous");1063 });1064}1065 1066void JSONNodeDumper::VisitTemplateTemplateParmDecl(1067 const TemplateTemplateParmDecl *D) {1068 VisitNamedDecl(D);1069 JOS.attribute("depth", D->getDepth());1070 JOS.attribute("index", D->getIndex());1071 attributeOnlyIfTrue("isParameterPack", D->isParameterPack());1072 1073 if (D->hasDefaultArgument())1074 JOS.attributeObject("defaultArg", [=] {1075 const auto *InheritedFrom = D->getDefaultArgStorage().getInheritedFrom();1076 Visit(D->getDefaultArgument().getArgument(),1077 InheritedFrom ? InheritedFrom->getSourceRange() : SourceLocation{},1078 InheritedFrom,1079 D->defaultArgumentWasInherited() ? "inherited from" : "previous");1080 });1081}1082 1083void JSONNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *LSD) {1084 StringRef Lang;1085 switch (LSD->getLanguage()) {1086 case LinkageSpecLanguageIDs::C:1087 Lang = "C";1088 break;1089 case LinkageSpecLanguageIDs::CXX:1090 Lang = "C++";1091 break;1092 }1093 JOS.attribute("language", Lang);1094 attributeOnlyIfTrue("hasBraces", LSD->hasBraces());1095}1096 1097void JSONNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *ASD) {1098 JOS.attribute("access", createAccessSpecifier(ASD->getAccess()));1099}1100 1101void JSONNodeDumper::VisitFriendDecl(const FriendDecl *FD) {1102 if (const TypeSourceInfo *T = FD->getFriendType())1103 JOS.attribute("type", createQualType(T->getType()));1104 attributeOnlyIfTrue("isPackExpansion", FD->isPackExpansion());1105}1106 1107void JSONNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {1108 VisitNamedDecl(D);1109 JOS.attribute("type", createQualType(D->getType()));1110 attributeOnlyIfTrue("synthesized", D->getSynthesize());1111 switch (D->getAccessControl()) {1112 case ObjCIvarDecl::None: JOS.attribute("access", "none"); break;1113 case ObjCIvarDecl::Private: JOS.attribute("access", "private"); break;1114 case ObjCIvarDecl::Protected: JOS.attribute("access", "protected"); break;1115 case ObjCIvarDecl::Public: JOS.attribute("access", "public"); break;1116 case ObjCIvarDecl::Package: JOS.attribute("access", "package"); break;1117 }1118}1119 1120void JSONNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {1121 VisitNamedDecl(D);1122 JOS.attribute("returnType", createQualType(D->getReturnType()));1123 JOS.attribute("instance", D->isInstanceMethod());1124 attributeOnlyIfTrue("variadic", D->isVariadic());1125}1126 1127void JSONNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {1128 VisitNamedDecl(D);1129 JOS.attribute("type", createQualType(D->getUnderlyingType()));1130 attributeOnlyIfTrue("bounded", D->hasExplicitBound());1131 switch (D->getVariance()) {1132 case ObjCTypeParamVariance::Invariant:1133 break;1134 case ObjCTypeParamVariance::Covariant:1135 JOS.attribute("variance", "covariant");1136 break;1137 case ObjCTypeParamVariance::Contravariant:1138 JOS.attribute("variance", "contravariant");1139 break;1140 }1141}1142 1143void JSONNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {1144 VisitNamedDecl(D);1145 JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));1146 JOS.attribute("implementation", createBareDeclRef(D->getImplementation()));1147 1148 llvm::json::Array Protocols;1149 for (const auto* P : D->protocols())1150 Protocols.push_back(createBareDeclRef(P));1151 if (!Protocols.empty())1152 JOS.attribute("protocols", std::move(Protocols));1153}1154 1155void JSONNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {1156 VisitNamedDecl(D);1157 JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));1158 JOS.attribute("categoryDecl", createBareDeclRef(D->getCategoryDecl()));1159}1160 1161void JSONNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {1162 VisitNamedDecl(D);1163 1164 llvm::json::Array Protocols;1165 for (const auto *P : D->protocols())1166 Protocols.push_back(createBareDeclRef(P));1167 if (!Protocols.empty())1168 JOS.attribute("protocols", std::move(Protocols));1169}1170 1171void JSONNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {1172 VisitNamedDecl(D);1173 JOS.attribute("super", createBareDeclRef(D->getSuperClass()));1174 JOS.attribute("implementation", createBareDeclRef(D->getImplementation()));1175 1176 llvm::json::Array Protocols;1177 for (const auto* P : D->protocols())1178 Protocols.push_back(createBareDeclRef(P));1179 if (!Protocols.empty())1180 JOS.attribute("protocols", std::move(Protocols));1181}1182 1183void JSONNodeDumper::VisitObjCImplementationDecl(1184 const ObjCImplementationDecl *D) {1185 VisitNamedDecl(D);1186 JOS.attribute("super", createBareDeclRef(D->getSuperClass()));1187 JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));1188}1189 1190void JSONNodeDumper::VisitObjCCompatibleAliasDecl(1191 const ObjCCompatibleAliasDecl *D) {1192 VisitNamedDecl(D);1193 JOS.attribute("interface", createBareDeclRef(D->getClassInterface()));1194}1195 1196void JSONNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {1197 VisitNamedDecl(D);1198 JOS.attribute("type", createQualType(D->getType()));1199 1200 switch (D->getPropertyImplementation()) {1201 case ObjCPropertyDecl::None: break;1202 case ObjCPropertyDecl::Required: JOS.attribute("control", "required"); break;1203 case ObjCPropertyDecl::Optional: JOS.attribute("control", "optional"); break;1204 }1205 1206 ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes();1207 if (Attrs != ObjCPropertyAttribute::kind_noattr) {1208 if (Attrs & ObjCPropertyAttribute::kind_getter)1209 JOS.attribute("getter", createBareDeclRef(D->getGetterMethodDecl()));1210 if (Attrs & ObjCPropertyAttribute::kind_setter)1211 JOS.attribute("setter", createBareDeclRef(D->getSetterMethodDecl()));1212 attributeOnlyIfTrue("readonly",1213 Attrs & ObjCPropertyAttribute::kind_readonly);1214 attributeOnlyIfTrue("assign", Attrs & ObjCPropertyAttribute::kind_assign);1215 attributeOnlyIfTrue("readwrite",1216 Attrs & ObjCPropertyAttribute::kind_readwrite);1217 attributeOnlyIfTrue("retain", Attrs & ObjCPropertyAttribute::kind_retain);1218 attributeOnlyIfTrue("copy", Attrs & ObjCPropertyAttribute::kind_copy);1219 attributeOnlyIfTrue("nonatomic",1220 Attrs & ObjCPropertyAttribute::kind_nonatomic);1221 attributeOnlyIfTrue("atomic", Attrs & ObjCPropertyAttribute::kind_atomic);1222 attributeOnlyIfTrue("weak", Attrs & ObjCPropertyAttribute::kind_weak);1223 attributeOnlyIfTrue("strong", Attrs & ObjCPropertyAttribute::kind_strong);1224 attributeOnlyIfTrue("unsafe_unretained",1225 Attrs & ObjCPropertyAttribute::kind_unsafe_unretained);1226 attributeOnlyIfTrue("class", Attrs & ObjCPropertyAttribute::kind_class);1227 attributeOnlyIfTrue("direct", Attrs & ObjCPropertyAttribute::kind_direct);1228 attributeOnlyIfTrue("nullability",1229 Attrs & ObjCPropertyAttribute::kind_nullability);1230 attributeOnlyIfTrue("null_resettable",1231 Attrs & ObjCPropertyAttribute::kind_null_resettable);1232 }1233}1234 1235void JSONNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {1236 VisitNamedDecl(D->getPropertyDecl());1237 JOS.attribute("implKind", D->getPropertyImplementation() ==1238 ObjCPropertyImplDecl::Synthesize1239 ? "synthesize"1240 : "dynamic");1241 JOS.attribute("propertyDecl", createBareDeclRef(D->getPropertyDecl()));1242 JOS.attribute("ivarDecl", createBareDeclRef(D->getPropertyIvarDecl()));1243}1244 1245void JSONNodeDumper::VisitBlockDecl(const BlockDecl *D) {1246 attributeOnlyIfTrue("variadic", D->isVariadic());1247 attributeOnlyIfTrue("capturesThis", D->capturesCXXThis());1248}1249 1250void JSONNodeDumper::VisitAtomicExpr(const AtomicExpr *AE) {1251 JOS.attribute("name", AE->getOpAsString());1252}1253 1254void JSONNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE) {1255 JOS.attribute("encodedType", createQualType(OEE->getEncodedType()));1256}1257 1258void JSONNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *OME) {1259 std::string Str;1260 llvm::raw_string_ostream OS(Str);1261 1262 OME->getSelector().print(OS);1263 JOS.attribute("selector", Str);1264 1265 switch (OME->getReceiverKind()) {1266 case ObjCMessageExpr::Instance:1267 JOS.attribute("receiverKind", "instance");1268 break;1269 case ObjCMessageExpr::Class:1270 JOS.attribute("receiverKind", "class");1271 JOS.attribute("classType", createQualType(OME->getClassReceiver()));1272 break;1273 case ObjCMessageExpr::SuperInstance:1274 JOS.attribute("receiverKind", "super (instance)");1275 JOS.attribute("superType", createQualType(OME->getSuperType()));1276 break;1277 case ObjCMessageExpr::SuperClass:1278 JOS.attribute("receiverKind", "super (class)");1279 JOS.attribute("superType", createQualType(OME->getSuperType()));1280 break;1281 }1282 1283 QualType CallReturnTy = OME->getCallReturnType(Ctx);1284 if (OME->getType() != CallReturnTy)1285 JOS.attribute("callReturnType", createQualType(CallReturnTy));1286}1287 1288void JSONNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *OBE) {1289 if (const ObjCMethodDecl *MD = OBE->getBoxingMethod()) {1290 std::string Str;1291 llvm::raw_string_ostream OS(Str);1292 1293 MD->getSelector().print(OS);1294 JOS.attribute("selector", Str);1295 }1296}1297 1298void JSONNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *OSE) {1299 std::string Str;1300 llvm::raw_string_ostream OS(Str);1301 1302 OSE->getSelector().print(OS);1303 JOS.attribute("selector", Str);1304}1305 1306void JSONNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE) {1307 JOS.attribute("protocol", createBareDeclRef(OPE->getProtocol()));1308}1309 1310void JSONNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE) {1311 if (OPRE->isImplicitProperty()) {1312 JOS.attribute("propertyKind", "implicit");1313 if (const ObjCMethodDecl *MD = OPRE->getImplicitPropertyGetter())1314 JOS.attribute("getter", createBareDeclRef(MD));1315 if (const ObjCMethodDecl *MD = OPRE->getImplicitPropertySetter())1316 JOS.attribute("setter", createBareDeclRef(MD));1317 } else {1318 JOS.attribute("propertyKind", "explicit");1319 JOS.attribute("property", createBareDeclRef(OPRE->getExplicitProperty()));1320 }1321 1322 attributeOnlyIfTrue("isSuperReceiver", OPRE->isSuperReceiver());1323 attributeOnlyIfTrue("isMessagingGetter", OPRE->isMessagingGetter());1324 attributeOnlyIfTrue("isMessagingSetter", OPRE->isMessagingSetter());1325}1326 1327void JSONNodeDumper::VisitObjCSubscriptRefExpr(1328 const ObjCSubscriptRefExpr *OSRE) {1329 JOS.attribute("subscriptKind",1330 OSRE->isArraySubscriptRefExpr() ? "array" : "dictionary");1331 1332 if (const ObjCMethodDecl *MD = OSRE->getAtIndexMethodDecl())1333 JOS.attribute("getter", createBareDeclRef(MD));1334 if (const ObjCMethodDecl *MD = OSRE->setAtIndexMethodDecl())1335 JOS.attribute("setter", createBareDeclRef(MD));1336}1337 1338void JSONNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE) {1339 JOS.attribute("decl", createBareDeclRef(OIRE->getDecl()));1340 attributeOnlyIfTrue("isFreeIvar", OIRE->isFreeIvar());1341 JOS.attribute("isArrow", OIRE->isArrow());1342}1343 1344void JSONNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *OBLE) {1345 JOS.attribute("value", OBLE->getValue() ? "__objc_yes" : "__objc_no");1346}1347 1348void JSONNodeDumper::VisitDeclRefExpr(const DeclRefExpr *DRE) {1349 JOS.attribute("referencedDecl", createBareDeclRef(DRE->getDecl()));1350 if (DRE->getDecl() != DRE->getFoundDecl())1351 JOS.attribute("foundReferencedDecl",1352 createBareDeclRef(DRE->getFoundDecl()));1353 switch (DRE->isNonOdrUse()) {1354 case NOUR_None: break;1355 case NOUR_Unevaluated: JOS.attribute("nonOdrUseReason", "unevaluated"); break;1356 case NOUR_Constant: JOS.attribute("nonOdrUseReason", "constant"); break;1357 case NOUR_Discarded: JOS.attribute("nonOdrUseReason", "discarded"); break;1358 }1359 attributeOnlyIfTrue("isImmediateEscalating", DRE->isImmediateEscalating());1360}1361 1362void JSONNodeDumper::VisitSYCLUniqueStableNameExpr(1363 const SYCLUniqueStableNameExpr *E) {1364 JOS.attribute("typeSourceInfo",1365 createQualType(E->getTypeSourceInfo()->getType()));1366}1367 1368void JSONNodeDumper::VisitOpenACCAsteriskSizeExpr(1369 const OpenACCAsteriskSizeExpr *E) {}1370 1371void JSONNodeDumper::VisitOpenACCDeclareDecl(const OpenACCDeclareDecl *D) {}1372void JSONNodeDumper::VisitOpenACCRoutineDecl(const OpenACCRoutineDecl *D) {}1373 1374void JSONNodeDumper::VisitPredefinedExpr(const PredefinedExpr *PE) {1375 JOS.attribute("name", PredefinedExpr::getIdentKindName(PE->getIdentKind()));1376}1377 1378void JSONNodeDumper::VisitUnaryOperator(const UnaryOperator *UO) {1379 JOS.attribute("isPostfix", UO->isPostfix());1380 JOS.attribute("opcode", UnaryOperator::getOpcodeStr(UO->getOpcode()));1381 if (!UO->canOverflow())1382 JOS.attribute("canOverflow", false);1383}1384 1385void JSONNodeDumper::VisitBinaryOperator(const BinaryOperator *BO) {1386 JOS.attribute("opcode", BinaryOperator::getOpcodeStr(BO->getOpcode()));1387}1388 1389void JSONNodeDumper::VisitCompoundAssignOperator(1390 const CompoundAssignOperator *CAO) {1391 VisitBinaryOperator(CAO);1392 JOS.attribute("computeLHSType", createQualType(CAO->getComputationLHSType()));1393 JOS.attribute("computeResultType",1394 createQualType(CAO->getComputationResultType()));1395}1396 1397void JSONNodeDumper::VisitMemberExpr(const MemberExpr *ME) {1398 // Note, we always write this Boolean field because the information it conveys1399 // is critical to understanding the AST node.1400 ValueDecl *VD = ME->getMemberDecl();1401 JOS.attribute("name", VD && VD->getDeclName() ? VD->getNameAsString() : "");1402 JOS.attribute("isArrow", ME->isArrow());1403 JOS.attribute("referencedMemberDecl", createPointerRepresentation(VD));1404 switch (ME->isNonOdrUse()) {1405 case NOUR_None: break;1406 case NOUR_Unevaluated: JOS.attribute("nonOdrUseReason", "unevaluated"); break;1407 case NOUR_Constant: JOS.attribute("nonOdrUseReason", "constant"); break;1408 case NOUR_Discarded: JOS.attribute("nonOdrUseReason", "discarded"); break;1409 }1410}1411 1412void JSONNodeDumper::VisitCXXNewExpr(const CXXNewExpr *NE) {1413 attributeOnlyIfTrue("isGlobal", NE->isGlobalNew());1414 attributeOnlyIfTrue("isArray", NE->isArray());1415 attributeOnlyIfTrue("isPlacement", NE->getNumPlacementArgs() != 0);1416 switch (NE->getInitializationStyle()) {1417 case CXXNewInitializationStyle::None:1418 break;1419 case CXXNewInitializationStyle::Parens:1420 JOS.attribute("initStyle", "call");1421 break;1422 case CXXNewInitializationStyle::Braces:1423 JOS.attribute("initStyle", "list");1424 break;1425 }1426 if (const FunctionDecl *FD = NE->getOperatorNew())1427 JOS.attribute("operatorNewDecl", createBareDeclRef(FD));1428 if (const FunctionDecl *FD = NE->getOperatorDelete())1429 JOS.attribute("operatorDeleteDecl", createBareDeclRef(FD));1430}1431void JSONNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *DE) {1432 attributeOnlyIfTrue("isGlobal", DE->isGlobalDelete());1433 attributeOnlyIfTrue("isArray", DE->isArrayForm());1434 attributeOnlyIfTrue("isArrayAsWritten", DE->isArrayFormAsWritten());1435 if (const FunctionDecl *FD = DE->getOperatorDelete())1436 JOS.attribute("operatorDeleteDecl", createBareDeclRef(FD));1437}1438 1439void JSONNodeDumper::VisitCXXThisExpr(const CXXThisExpr *TE) {1440 attributeOnlyIfTrue("implicit", TE->isImplicit());1441}1442 1443void JSONNodeDumper::VisitCastExpr(const CastExpr *CE) {1444 JOS.attribute("castKind", CE->getCastKindName());1445 llvm::json::Array Path = createCastPath(CE);1446 if (!Path.empty())1447 JOS.attribute("path", std::move(Path));1448 // FIXME: This may not be useful information as it can be obtusely gleaned1449 // from the inner[] array.1450 if (const NamedDecl *ND = CE->getConversionFunction())1451 JOS.attribute("conversionFunc", createBareDeclRef(ND));1452}1453 1454void JSONNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *ICE) {1455 VisitCastExpr(ICE);1456 attributeOnlyIfTrue("isPartOfExplicitCast", ICE->isPartOfExplicitCast());1457}1458 1459void JSONNodeDumper::VisitCallExpr(const CallExpr *CE) {1460 attributeOnlyIfTrue("adl", CE->usesADL());1461}1462 1463void JSONNodeDumper::VisitUnaryExprOrTypeTraitExpr(1464 const UnaryExprOrTypeTraitExpr *TTE) {1465 JOS.attribute("name", getTraitSpelling(TTE->getKind()));1466 if (TTE->isArgumentType())1467 JOS.attribute("argType", createQualType(TTE->getArgumentType()));1468}1469 1470void JSONNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *SOPE) {1471 VisitNamedDecl(SOPE->getPack());1472}1473 1474void JSONNodeDumper::VisitUnresolvedLookupExpr(1475 const UnresolvedLookupExpr *ULE) {1476 JOS.attribute("usesADL", ULE->requiresADL());1477 JOS.attribute("name", ULE->getName().getAsString());1478 1479 JOS.attributeArray("lookups", [this, ULE] {1480 for (const NamedDecl *D : ULE->decls())1481 JOS.value(createBareDeclRef(D));1482 });1483}1484 1485void JSONNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *ALE) {1486 JOS.attribute("name", ALE->getLabel()->getName());1487 JOS.attribute("labelDeclId", createPointerRepresentation(ALE->getLabel()));1488}1489 1490void JSONNodeDumper::VisitCXXTypeidExpr(const CXXTypeidExpr *CTE) {1491 if (CTE->isTypeOperand()) {1492 QualType Adjusted = CTE->getTypeOperand(Ctx);1493 QualType Unadjusted = CTE->getTypeOperandSourceInfo()->getType();1494 JOS.attribute("typeArg", createQualType(Unadjusted));1495 if (Adjusted != Unadjusted)1496 JOS.attribute("adjustedTypeArg", createQualType(Adjusted));1497 }1498}1499 1500void JSONNodeDumper::VisitConstantExpr(const ConstantExpr *CE) {1501 if (CE->getResultAPValueKind() != APValue::None)1502 Visit(CE->getAPValueResult(), CE->getType());1503}1504 1505void JSONNodeDumper::VisitInitListExpr(const InitListExpr *ILE) {1506 if (const FieldDecl *FD = ILE->getInitializedFieldInUnion())1507 JOS.attribute("field", createBareDeclRef(FD));1508}1509 1510void JSONNodeDumper::VisitGenericSelectionExpr(1511 const GenericSelectionExpr *GSE) {1512 attributeOnlyIfTrue("resultDependent", GSE->isResultDependent());1513}1514 1515void JSONNodeDumper::VisitCXXUnresolvedConstructExpr(1516 const CXXUnresolvedConstructExpr *UCE) {1517 if (UCE->getType() != UCE->getTypeAsWritten())1518 JOS.attribute("typeAsWritten", createQualType(UCE->getTypeAsWritten()));1519 attributeOnlyIfTrue("list", UCE->isListInitialization());1520}1521 1522void JSONNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *CE) {1523 CXXConstructorDecl *Ctor = CE->getConstructor();1524 JOS.attribute("ctorType", createQualType(Ctor->getType()));1525 attributeOnlyIfTrue("elidable", CE->isElidable());1526 attributeOnlyIfTrue("list", CE->isListInitialization());1527 attributeOnlyIfTrue("initializer_list", CE->isStdInitListInitialization());1528 attributeOnlyIfTrue("zeroing", CE->requiresZeroInitialization());1529 attributeOnlyIfTrue("hadMultipleCandidates", CE->hadMultipleCandidates());1530 attributeOnlyIfTrue("isImmediateEscalating", CE->isImmediateEscalating());1531 1532 switch (CE->getConstructionKind()) {1533 case CXXConstructionKind::Complete:1534 JOS.attribute("constructionKind", "complete");1535 break;1536 case CXXConstructionKind::Delegating:1537 JOS.attribute("constructionKind", "delegating");1538 break;1539 case CXXConstructionKind::NonVirtualBase:1540 JOS.attribute("constructionKind", "non-virtual base");1541 break;1542 case CXXConstructionKind::VirtualBase:1543 JOS.attribute("constructionKind", "virtual base");1544 break;1545 }1546}1547 1548void JSONNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *EWC) {1549 attributeOnlyIfTrue("cleanupsHaveSideEffects",1550 EWC->cleanupsHaveSideEffects());1551 if (EWC->getNumObjects()) {1552 JOS.attributeArray("cleanups", [this, EWC] {1553 for (const ExprWithCleanups::CleanupObject &CO : EWC->getObjects())1554 if (auto *BD = dyn_cast<BlockDecl *>(CO)) {1555 JOS.value(createBareDeclRef(BD));1556 } else if (auto *CLE = dyn_cast<CompoundLiteralExpr *>(CO)) {1557 llvm::json::Object Obj;1558 Obj["id"] = createPointerRepresentation(CLE);1559 Obj["kind"] = CLE->getStmtClassName();1560 JOS.value(std::move(Obj));1561 } else {1562 llvm_unreachable("unexpected cleanup object type");1563 }1564 });1565 }1566}1567 1568void JSONNodeDumper::VisitCXXBindTemporaryExpr(1569 const CXXBindTemporaryExpr *BTE) {1570 const CXXTemporary *Temp = BTE->getTemporary();1571 JOS.attribute("temp", createPointerRepresentation(Temp));1572 if (const CXXDestructorDecl *Dtor = Temp->getDestructor())1573 JOS.attribute("dtor", createBareDeclRef(Dtor));1574}1575 1576void JSONNodeDumper::VisitMaterializeTemporaryExpr(1577 const MaterializeTemporaryExpr *MTE) {1578 if (const ValueDecl *VD = MTE->getExtendingDecl())1579 JOS.attribute("extendingDecl", createBareDeclRef(VD));1580 1581 switch (MTE->getStorageDuration()) {1582 case SD_Automatic:1583 JOS.attribute("storageDuration", "automatic");1584 break;1585 case SD_Dynamic:1586 JOS.attribute("storageDuration", "dynamic");1587 break;1588 case SD_FullExpression:1589 JOS.attribute("storageDuration", "full expression");1590 break;1591 case SD_Static:1592 JOS.attribute("storageDuration", "static");1593 break;1594 case SD_Thread:1595 JOS.attribute("storageDuration", "thread");1596 break;1597 }1598 1599 attributeOnlyIfTrue("boundToLValueRef", MTE->isBoundToLvalueReference());1600}1601 1602void JSONNodeDumper::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) {1603 attributeOnlyIfTrue("hasRewrittenInit", Node->hasRewrittenInit());1604}1605 1606void JSONNodeDumper::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) {1607 attributeOnlyIfTrue("hasRewrittenInit", Node->hasRewrittenInit());1608}1609 1610void JSONNodeDumper::VisitLambdaExpr(const LambdaExpr *LE) {1611 JOS.attribute("hasExplicitParameters", LE->hasExplicitParameters());1612}1613 1614void JSONNodeDumper::VisitCXXDependentScopeMemberExpr(1615 const CXXDependentScopeMemberExpr *DSME) {1616 JOS.attribute("isArrow", DSME->isArrow());1617 JOS.attribute("member", DSME->getMember().getAsString());1618 attributeOnlyIfTrue("hasTemplateKeyword", DSME->hasTemplateKeyword());1619 attributeOnlyIfTrue("hasExplicitTemplateArgs",1620 DSME->hasExplicitTemplateArgs());1621 1622 if (DSME->getNumTemplateArgs()) {1623 JOS.attributeArray("explicitTemplateArgs", [DSME, this] {1624 for (const TemplateArgumentLoc &TAL : DSME->template_arguments())1625 JOS.object(1626 [&TAL, this] { Visit(TAL.getArgument(), TAL.getSourceRange()); });1627 });1628 }1629}1630 1631void JSONNodeDumper::VisitRequiresExpr(const RequiresExpr *RE) {1632 if (!RE->isValueDependent())1633 JOS.attribute("satisfied", RE->isSatisfied());1634}1635 1636void JSONNodeDumper::VisitIntegerLiteral(const IntegerLiteral *IL) {1637 llvm::SmallString<16> Buffer;1638 IL->getValue().toString(Buffer,1639 /*Radix=*/10, IL->getType()->isSignedIntegerType());1640 JOS.attribute("value", Buffer);1641}1642void JSONNodeDumper::VisitCharacterLiteral(const CharacterLiteral *CL) {1643 // FIXME: This should probably print the character literal as a string,1644 // rather than as a numerical value. It would be nice if the behavior matched1645 // what we do to print a string literal; right now, it is impossible to tell1646 // the difference between 'a' and L'a' in C from the JSON output.1647 JOS.attribute("value", CL->getValue());1648}1649void JSONNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *FPL) {1650 JOS.attribute("value", FPL->getValueAsString(/*Radix=*/10));1651}1652void JSONNodeDumper::VisitFloatingLiteral(const FloatingLiteral *FL) {1653 llvm::SmallString<16> Buffer;1654 FL->getValue().toString(Buffer);1655 JOS.attribute("value", Buffer);1656}1657void JSONNodeDumper::VisitStringLiteral(const StringLiteral *SL) {1658 std::string Buffer;1659 llvm::raw_string_ostream SS(Buffer);1660 SL->outputString(SS);1661 JOS.attribute("value", Buffer);1662}1663void JSONNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *BLE) {1664 JOS.attribute("value", BLE->getValue());1665}1666 1667void JSONNodeDumper::VisitIfStmt(const IfStmt *IS) {1668 attributeOnlyIfTrue("hasInit", IS->hasInitStorage());1669 attributeOnlyIfTrue("hasVar", IS->hasVarStorage());1670 attributeOnlyIfTrue("hasElse", IS->hasElseStorage());1671 attributeOnlyIfTrue("isConstexpr", IS->isConstexpr());1672 attributeOnlyIfTrue("isConsteval", IS->isConsteval());1673 attributeOnlyIfTrue("constevalIsNegated", IS->isNegatedConsteval());1674}1675 1676void JSONNodeDumper::VisitSwitchStmt(const SwitchStmt *SS) {1677 attributeOnlyIfTrue("hasInit", SS->hasInitStorage());1678 attributeOnlyIfTrue("hasVar", SS->hasVarStorage());1679}1680void JSONNodeDumper::VisitCaseStmt(const CaseStmt *CS) {1681 attributeOnlyIfTrue("isGNURange", CS->caseStmtIsGNURange());1682}1683 1684void JSONNodeDumper::VisitLabelStmt(const LabelStmt *LS) {1685 JOS.attribute("name", LS->getName());1686 JOS.attribute("declId", createPointerRepresentation(LS->getDecl()));1687 attributeOnlyIfTrue("sideEntry", LS->isSideEntry());1688}1689 1690void JSONNodeDumper::VisitLoopControlStmt(const LoopControlStmt *LS) {1691 if (LS->hasLabelTarget())1692 JOS.attribute("targetLabelDeclId",1693 createPointerRepresentation(LS->getLabelDecl()));1694}1695 1696void JSONNodeDumper::VisitGotoStmt(const GotoStmt *GS) {1697 JOS.attribute("targetLabelDeclId",1698 createPointerRepresentation(GS->getLabel()));1699}1700 1701void JSONNodeDumper::VisitWhileStmt(const WhileStmt *WS) {1702 attributeOnlyIfTrue("hasVar", WS->hasVarStorage());1703}1704 1705void JSONNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt* OACS) {1706 // FIXME: it would be nice for the ASTNodeTraverser would handle the catch1707 // parameter the same way for C++ and ObjC rather. In this case, C++ gets a1708 // null child node and ObjC gets no child node.1709 attributeOnlyIfTrue("isCatchAll", OACS->getCatchParamDecl() == nullptr);1710}1711 1712void JSONNodeDumper::VisitNullTemplateArgument(const TemplateArgument &TA) {1713 JOS.attribute("isNull", true);1714}1715void JSONNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) {1716 JOS.attribute("type", createQualType(TA.getAsType()));1717}1718void JSONNodeDumper::VisitDeclarationTemplateArgument(1719 const TemplateArgument &TA) {1720 JOS.attribute("decl", createBareDeclRef(TA.getAsDecl()));1721}1722void JSONNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA) {1723 JOS.attribute("isNullptr", true);1724}1725void JSONNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) {1726 JOS.attribute("value", TA.getAsIntegral().getSExtValue());1727}1728void JSONNodeDumper::VisitStructuralValueTemplateArgument(1729 const TemplateArgument &TA) {1730 Visit(TA.getAsStructuralValue(), TA.getStructuralValueType());1731}1732void JSONNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) {1733 // FIXME: cannot just call dump() on the argument, as that doesn't specify1734 // the output format.1735}1736void JSONNodeDumper::VisitTemplateExpansionTemplateArgument(1737 const TemplateArgument &TA) {1738 // FIXME: cannot just call dump() on the argument, as that doesn't specify1739 // the output format.1740}1741void JSONNodeDumper::VisitExpressionTemplateArgument(1742 const TemplateArgument &TA) {1743 JOS.attribute("isExpr", true);1744 if (TA.isCanonicalExpr())1745 JOS.attribute("isCanonical", true);1746}1747void JSONNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) {1748 JOS.attribute("isPack", true);1749}1750 1751StringRef JSONNodeDumper::getCommentCommandName(unsigned CommandID) const {1752 if (Traits)1753 return Traits->getCommandInfo(CommandID)->Name;1754 if (const comments::CommandInfo *Info =1755 comments::CommandTraits::getBuiltinCommandInfo(CommandID))1756 return Info->Name;1757 return "<invalid>";1758}1759 1760void JSONNodeDumper::visitTextComment(const comments::TextComment *C,1761 const comments::FullComment *) {1762 JOS.attribute("text", C->getText());1763}1764 1765void JSONNodeDumper::visitInlineCommandComment(1766 const comments::InlineCommandComment *C, const comments::FullComment *) {1767 JOS.attribute("name", getCommentCommandName(C->getCommandID()));1768 1769 switch (C->getRenderKind()) {1770 case comments::InlineCommandRenderKind::Normal:1771 JOS.attribute("renderKind", "normal");1772 break;1773 case comments::InlineCommandRenderKind::Bold:1774 JOS.attribute("renderKind", "bold");1775 break;1776 case comments::InlineCommandRenderKind::Emphasized:1777 JOS.attribute("renderKind", "emphasized");1778 break;1779 case comments::InlineCommandRenderKind::Monospaced:1780 JOS.attribute("renderKind", "monospaced");1781 break;1782 case comments::InlineCommandRenderKind::Anchor:1783 JOS.attribute("renderKind", "anchor");1784 break;1785 }1786 1787 llvm::json::Array Args;1788 for (unsigned I = 0, E = C->getNumArgs(); I < E; ++I)1789 Args.push_back(C->getArgText(I));1790 1791 if (!Args.empty())1792 JOS.attribute("args", std::move(Args));1793}1794 1795void JSONNodeDumper::visitHTMLStartTagComment(1796 const comments::HTMLStartTagComment *C, const comments::FullComment *) {1797 JOS.attribute("name", C->getTagName());1798 attributeOnlyIfTrue("selfClosing", C->isSelfClosing());1799 attributeOnlyIfTrue("malformed", C->isMalformed());1800 1801 llvm::json::Array Attrs;1802 for (unsigned I = 0, E = C->getNumAttrs(); I < E; ++I)1803 Attrs.push_back(1804 {{"name", C->getAttr(I).Name}, {"value", C->getAttr(I).Value}});1805 1806 if (!Attrs.empty())1807 JOS.attribute("attrs", std::move(Attrs));1808}1809 1810void JSONNodeDumper::visitHTMLEndTagComment(1811 const comments::HTMLEndTagComment *C, const comments::FullComment *) {1812 JOS.attribute("name", C->getTagName());1813}1814 1815void JSONNodeDumper::visitBlockCommandComment(1816 const comments::BlockCommandComment *C, const comments::FullComment *) {1817 JOS.attribute("name", getCommentCommandName(C->getCommandID()));1818 1819 llvm::json::Array Args;1820 for (unsigned I = 0, E = C->getNumArgs(); I < E; ++I)1821 Args.push_back(C->getArgText(I));1822 1823 if (!Args.empty())1824 JOS.attribute("args", std::move(Args));1825}1826 1827void JSONNodeDumper::visitParamCommandComment(1828 const comments::ParamCommandComment *C, const comments::FullComment *FC) {1829 switch (C->getDirection()) {1830 case comments::ParamCommandPassDirection::In:1831 JOS.attribute("direction", "in");1832 break;1833 case comments::ParamCommandPassDirection::Out:1834 JOS.attribute("direction", "out");1835 break;1836 case comments::ParamCommandPassDirection::InOut:1837 JOS.attribute("direction", "in,out");1838 break;1839 }1840 attributeOnlyIfTrue("explicit", C->isDirectionExplicit());1841 1842 if (C->hasParamName())1843 JOS.attribute("param", C->isParamIndexValid() ? C->getParamName(FC)1844 : C->getParamNameAsWritten());1845 1846 if (C->isParamIndexValid() && !C->isVarArgParam())1847 JOS.attribute("paramIdx", C->getParamIndex());1848}1849 1850void JSONNodeDumper::visitTParamCommandComment(1851 const comments::TParamCommandComment *C, const comments::FullComment *FC) {1852 if (C->hasParamName())1853 JOS.attribute("param", C->isPositionValid() ? C->getParamName(FC)1854 : C->getParamNameAsWritten());1855 if (C->isPositionValid()) {1856 llvm::json::Array Positions;1857 for (unsigned I = 0, E = C->getDepth(); I < E; ++I)1858 Positions.push_back(C->getIndex(I));1859 1860 if (!Positions.empty())1861 JOS.attribute("positions", std::move(Positions));1862 }1863}1864 1865void JSONNodeDumper::visitVerbatimBlockComment(1866 const comments::VerbatimBlockComment *C, const comments::FullComment *) {1867 JOS.attribute("name", getCommentCommandName(C->getCommandID()));1868 JOS.attribute("closeName", C->getCloseName());1869}1870 1871void JSONNodeDumper::visitVerbatimBlockLineComment(1872 const comments::VerbatimBlockLineComment *C,1873 const comments::FullComment *) {1874 JOS.attribute("text", C->getText());1875}1876 1877void JSONNodeDumper::visitVerbatimLineComment(1878 const comments::VerbatimLineComment *C, const comments::FullComment *) {1879 JOS.attribute("text", C->getText());1880}1881 1882llvm::json::Object JSONNodeDumper::createFPOptions(FPOptionsOverride FPO) {1883 llvm::json::Object Ret;1884#define FP_OPTION(NAME, TYPE, WIDTH, PREVIOUS) \1885 if (FPO.has##NAME##Override()) \1886 Ret.try_emplace(#NAME, static_cast<unsigned>(FPO.get##NAME##Override()));1887#include "clang/Basic/FPOptions.def"1888 return Ret;1889}1890 1891void JSONNodeDumper::VisitCompoundStmt(const CompoundStmt *S) {1892 VisitStmt(S);1893 if (S->hasStoredFPFeatures())1894 JOS.attribute("fpoptions", createFPOptions(S->getStoredFPFeatures()));1895}1896