File indexing completed on 2026-05-10 08:36:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_AST_JSONNODEDUMPER_H
0015 #define LLVM_CLANG_AST_JSONNODEDUMPER_H
0016
0017 #include "clang/AST/ASTContext.h"
0018 #include "clang/AST/ASTDumperUtils.h"
0019 #include "clang/AST/ASTNodeTraverser.h"
0020 #include "clang/AST/AttrVisitor.h"
0021 #include "clang/AST/CommentCommandTraits.h"
0022 #include "clang/AST/CommentVisitor.h"
0023 #include "clang/AST/ExprConcepts.h"
0024 #include "clang/AST/ExprCXX.h"
0025 #include "clang/AST/Mangle.h"
0026 #include "clang/AST/Type.h"
0027 #include "llvm/Support/JSON.h"
0028
0029 namespace clang {
0030
0031 class APValue;
0032
0033 class NodeStreamer {
0034 bool FirstChild = true;
0035 bool TopLevel = true;
0036 llvm::SmallVector<std::function<void(bool IsLastChild)>, 32> Pending;
0037
0038 protected:
0039 llvm::json::OStream JOS;
0040
0041 public:
0042
0043 template <typename Fn> void AddChild(Fn DoAddChild) {
0044 return AddChild("", DoAddChild);
0045 }
0046
0047
0048
0049 template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
0050
0051
0052 if (TopLevel) {
0053 TopLevel = false;
0054 JOS.objectBegin();
0055
0056 DoAddChild();
0057
0058 while (!Pending.empty()) {
0059 Pending.back()(true);
0060 Pending.pop_back();
0061 }
0062
0063 JOS.objectEnd();
0064 TopLevel = true;
0065 return;
0066 }
0067
0068
0069
0070 std::string LabelStr(!Label.empty() ? Label : "inner");
0071 bool WasFirstChild = FirstChild;
0072 auto DumpWithIndent = [=](bool IsLastChild) {
0073 if (WasFirstChild) {
0074 JOS.attributeBegin(LabelStr);
0075 JOS.arrayBegin();
0076 }
0077
0078 FirstChild = true;
0079 unsigned Depth = Pending.size();
0080 JOS.objectBegin();
0081
0082 DoAddChild();
0083
0084
0085
0086 while (Depth < Pending.size()) {
0087 Pending.back()(true);
0088 this->Pending.pop_back();
0089 }
0090
0091 JOS.objectEnd();
0092
0093 if (IsLastChild) {
0094 JOS.arrayEnd();
0095 JOS.attributeEnd();
0096 }
0097 };
0098
0099 if (FirstChild) {
0100 Pending.push_back(std::move(DumpWithIndent));
0101 } else {
0102 Pending.back()(false);
0103 Pending.back() = std::move(DumpWithIndent);
0104 }
0105 FirstChild = false;
0106 }
0107
0108 NodeStreamer(raw_ostream &OS) : JOS(OS, 2) {}
0109 };
0110
0111
0112
0113
0114
0115
0116 class JSONNodeDumper
0117 : public ConstAttrVisitor<JSONNodeDumper>,
0118 public comments::ConstCommentVisitor<JSONNodeDumper, void,
0119 const comments::FullComment *>,
0120 public ConstTemplateArgumentVisitor<JSONNodeDumper>,
0121 public ConstStmtVisitor<JSONNodeDumper>,
0122 public TypeVisitor<JSONNodeDumper>,
0123 public ConstDeclVisitor<JSONNodeDumper>,
0124 public NodeStreamer {
0125 friend class JSONDumper;
0126
0127 const SourceManager &SM;
0128 ASTContext& Ctx;
0129 ASTNameGenerator ASTNameGen;
0130 PrintingPolicy PrintPolicy;
0131 const comments::CommandTraits *Traits;
0132 StringRef LastLocFilename, LastLocPresumedFilename;
0133 unsigned LastLocLine, LastLocPresumedLine;
0134
0135 using InnerAttrVisitor = ConstAttrVisitor<JSONNodeDumper>;
0136 using InnerCommentVisitor =
0137 comments::ConstCommentVisitor<JSONNodeDumper, void,
0138 const comments::FullComment *>;
0139 using InnerTemplateArgVisitor = ConstTemplateArgumentVisitor<JSONNodeDumper>;
0140 using InnerStmtVisitor = ConstStmtVisitor<JSONNodeDumper>;
0141 using InnerTypeVisitor = TypeVisitor<JSONNodeDumper>;
0142 using InnerDeclVisitor = ConstDeclVisitor<JSONNodeDumper>;
0143
0144 void attributeOnlyIfTrue(StringRef Key, bool Value) {
0145 if (Value)
0146 JOS.attribute(Key, Value);
0147 }
0148
0149 void writeIncludeStack(PresumedLoc Loc, bool JustFirst = false);
0150
0151
0152 void writeBareSourceLocation(SourceLocation Loc, bool IsSpelling);
0153
0154
0155
0156
0157
0158 void writeSourceLocation(SourceLocation Loc);
0159 void writeSourceRange(SourceRange R);
0160 std::string createPointerRepresentation(const void *Ptr);
0161 llvm::json::Object createQualType(QualType QT, bool Desugar = true);
0162 llvm::json::Object createBareDeclRef(const Decl *D);
0163 llvm::json::Object createFPOptions(FPOptionsOverride FPO);
0164 void writeBareDeclRef(const Decl *D);
0165 llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD);
0166 llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier &BS);
0167 std::string createAccessSpecifier(AccessSpecifier AS);
0168 llvm::json::Array createCastPath(const CastExpr *C);
0169
0170 void writePreviousDeclImpl(...) {}
0171
0172 template <typename T> void writePreviousDeclImpl(const Mergeable<T> *D) {
0173 const T *First = D->getFirstDecl();
0174 if (First != D)
0175 JOS.attribute("firstRedecl", createPointerRepresentation(First));
0176 }
0177
0178 template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) {
0179 const T *Prev = D->getPreviousDecl();
0180 if (Prev)
0181 JOS.attribute("previousDecl", createPointerRepresentation(Prev));
0182 }
0183 void addPreviousDeclaration(const Decl *D);
0184
0185 StringRef getCommentCommandName(unsigned CommandID) const;
0186
0187 public:
0188 JSONNodeDumper(raw_ostream &OS, const SourceManager &SrcMgr, ASTContext &Ctx,
0189 const PrintingPolicy &PrintPolicy,
0190 const comments::CommandTraits *Traits)
0191 : NodeStreamer(OS), SM(SrcMgr), Ctx(Ctx), ASTNameGen(Ctx),
0192 PrintPolicy(PrintPolicy), Traits(Traits), LastLocLine(0),
0193 LastLocPresumedLine(0) {}
0194
0195 void Visit(const Attr *A);
0196 void Visit(const Stmt *Node);
0197 void Visit(const Type *T);
0198 void Visit(QualType T);
0199 void Visit(const Decl *D);
0200 void Visit(TypeLoc TL);
0201
0202 void Visit(const comments::Comment *C, const comments::FullComment *FC);
0203 void Visit(const TemplateArgument &TA, SourceRange R = {},
0204 const Decl *From = nullptr, StringRef Label = {});
0205 void Visit(const CXXCtorInitializer *Init);
0206 void Visit(const OpenACCClause *C);
0207 void Visit(const OMPClause *C);
0208 void Visit(const BlockDecl::Capture &C);
0209 void Visit(const GenericSelectionExpr::ConstAssociation &A);
0210 void Visit(const concepts::Requirement *R);
0211 void Visit(const APValue &Value, QualType Ty);
0212 void Visit(const ConceptReference *);
0213
0214 void VisitAliasAttr(const AliasAttr *AA);
0215 void VisitCleanupAttr(const CleanupAttr *CA);
0216 void VisitDeprecatedAttr(const DeprecatedAttr *DA);
0217 void VisitUnavailableAttr(const UnavailableAttr *UA);
0218 void VisitSectionAttr(const SectionAttr *SA);
0219 void VisitVisibilityAttr(const VisibilityAttr *VA);
0220 void VisitTLSModelAttr(const TLSModelAttr *TA);
0221
0222 void VisitTypedefType(const TypedefType *TT);
0223 void VisitUsingType(const UsingType *TT);
0224 void VisitFunctionType(const FunctionType *T);
0225 void VisitFunctionProtoType(const FunctionProtoType *T);
0226 void VisitRValueReferenceType(const ReferenceType *RT);
0227 void VisitArrayType(const ArrayType *AT);
0228 void VisitConstantArrayType(const ConstantArrayType *CAT);
0229 void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *VT);
0230 void VisitVectorType(const VectorType *VT);
0231 void VisitUnresolvedUsingType(const UnresolvedUsingType *UUT);
0232 void VisitUnaryTransformType(const UnaryTransformType *UTT);
0233 void VisitTagType(const TagType *TT);
0234 void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT);
0235 void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *STTPT);
0236 void
0237 VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T);
0238 void VisitAutoType(const AutoType *AT);
0239 void VisitTemplateSpecializationType(const TemplateSpecializationType *TST);
0240 void VisitInjectedClassNameType(const InjectedClassNameType *ICNT);
0241 void VisitObjCInterfaceType(const ObjCInterfaceType *OIT);
0242 void VisitPackExpansionType(const PackExpansionType *PET);
0243 void VisitElaboratedType(const ElaboratedType *ET);
0244 void VisitMacroQualifiedType(const MacroQualifiedType *MQT);
0245 void VisitMemberPointerType(const MemberPointerType *MPT);
0246
0247 void VisitNamedDecl(const NamedDecl *ND);
0248 void VisitTypedefDecl(const TypedefDecl *TD);
0249 void VisitTypeAliasDecl(const TypeAliasDecl *TAD);
0250 void VisitNamespaceDecl(const NamespaceDecl *ND);
0251 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *UDD);
0252 void VisitNamespaceAliasDecl(const NamespaceAliasDecl *NAD);
0253 void VisitUsingDecl(const UsingDecl *UD);
0254 void VisitUsingEnumDecl(const UsingEnumDecl *UED);
0255 void VisitUsingShadowDecl(const UsingShadowDecl *USD);
0256 void VisitVarDecl(const VarDecl *VD);
0257 void VisitFieldDecl(const FieldDecl *FD);
0258 void VisitFunctionDecl(const FunctionDecl *FD);
0259 void VisitEnumDecl(const EnumDecl *ED);
0260 void VisitEnumConstantDecl(const EnumConstantDecl *ECD);
0261 void VisitRecordDecl(const RecordDecl *RD);
0262 void VisitCXXRecordDecl(const CXXRecordDecl *RD);
0263 void VisitHLSLBufferDecl(const HLSLBufferDecl *D);
0264 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
0265 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
0266 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
0267 void VisitLinkageSpecDecl(const LinkageSpecDecl *LSD);
0268 void VisitAccessSpecDecl(const AccessSpecDecl *ASD);
0269 void VisitFriendDecl(const FriendDecl *FD);
0270
0271 void VisitObjCIvarDecl(const ObjCIvarDecl *D);
0272 void VisitObjCMethodDecl(const ObjCMethodDecl *D);
0273 void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D);
0274 void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
0275 void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
0276 void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
0277 void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
0278 void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
0279 void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
0280 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
0281 void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
0282 void VisitBlockDecl(const BlockDecl *D);
0283
0284 void VisitDeclRefExpr(const DeclRefExpr *DRE);
0285 void VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E);
0286 void VisitOpenACCAsteriskSizeExpr(const OpenACCAsteriskSizeExpr *E);
0287 void VisitPredefinedExpr(const PredefinedExpr *PE);
0288 void VisitUnaryOperator(const UnaryOperator *UO);
0289 void VisitBinaryOperator(const BinaryOperator *BO);
0290 void VisitCompoundAssignOperator(const CompoundAssignOperator *CAO);
0291 void VisitMemberExpr(const MemberExpr *ME);
0292 void VisitAtomicExpr(const AtomicExpr *AE);
0293 void VisitCXXNewExpr(const CXXNewExpr *NE);
0294 void VisitCXXDeleteExpr(const CXXDeleteExpr *DE);
0295 void VisitCXXThisExpr(const CXXThisExpr *TE);
0296 void VisitCastExpr(const CastExpr *CE);
0297 void VisitImplicitCastExpr(const ImplicitCastExpr *ICE);
0298 void VisitCallExpr(const CallExpr *CE);
0299 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *TTE);
0300 void VisitSizeOfPackExpr(const SizeOfPackExpr *SOPE);
0301 void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *ULE);
0302 void VisitAddrLabelExpr(const AddrLabelExpr *ALE);
0303 void VisitCXXTypeidExpr(const CXXTypeidExpr *CTE);
0304 void VisitConstantExpr(const ConstantExpr *CE);
0305 void VisitInitListExpr(const InitListExpr *ILE);
0306 void VisitGenericSelectionExpr(const GenericSelectionExpr *GSE);
0307 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *UCE);
0308 void VisitCXXConstructExpr(const CXXConstructExpr *CE);
0309 void VisitExprWithCleanups(const ExprWithCleanups *EWC);
0310 void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE);
0311 void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *MTE);
0312 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *ME);
0313 void VisitRequiresExpr(const RequiresExpr *RE);
0314 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node);
0315 void VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node);
0316
0317 void VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE);
0318 void VisitObjCMessageExpr(const ObjCMessageExpr *OME);
0319 void VisitObjCBoxedExpr(const ObjCBoxedExpr *OBE);
0320 void VisitObjCSelectorExpr(const ObjCSelectorExpr *OSE);
0321 void VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE);
0322 void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE);
0323 void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *OSRE);
0324 void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE);
0325 void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *OBLE);
0326
0327 void VisitIntegerLiteral(const IntegerLiteral *IL);
0328 void VisitCharacterLiteral(const CharacterLiteral *CL);
0329 void VisitFixedPointLiteral(const FixedPointLiteral *FPL);
0330 void VisitFloatingLiteral(const FloatingLiteral *FL);
0331 void VisitStringLiteral(const StringLiteral *SL);
0332 void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *BLE);
0333
0334 void VisitIfStmt(const IfStmt *IS);
0335 void VisitSwitchStmt(const SwitchStmt *SS);
0336 void VisitCaseStmt(const CaseStmt *CS);
0337 void VisitLabelStmt(const LabelStmt *LS);
0338 void VisitGotoStmt(const GotoStmt *GS);
0339 void VisitWhileStmt(const WhileStmt *WS);
0340 void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS);
0341 void VisitCompoundStmt(const CompoundStmt *IS);
0342
0343 void VisitNullTemplateArgument(const TemplateArgument &TA);
0344 void VisitTypeTemplateArgument(const TemplateArgument &TA);
0345 void VisitDeclarationTemplateArgument(const TemplateArgument &TA);
0346 void VisitNullPtrTemplateArgument(const TemplateArgument &TA);
0347 void VisitIntegralTemplateArgument(const TemplateArgument &TA);
0348 void VisitTemplateTemplateArgument(const TemplateArgument &TA);
0349 void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA);
0350 void VisitExpressionTemplateArgument(const TemplateArgument &TA);
0351 void VisitPackTemplateArgument(const TemplateArgument &TA);
0352
0353 void visitTextComment(const comments::TextComment *C,
0354 const comments::FullComment *);
0355 void visitInlineCommandComment(const comments::InlineCommandComment *C,
0356 const comments::FullComment *);
0357 void visitHTMLStartTagComment(const comments::HTMLStartTagComment *C,
0358 const comments::FullComment *);
0359 void visitHTMLEndTagComment(const comments::HTMLEndTagComment *C,
0360 const comments::FullComment *);
0361 void visitBlockCommandComment(const comments::BlockCommandComment *C,
0362 const comments::FullComment *);
0363 void visitParamCommandComment(const comments::ParamCommandComment *C,
0364 const comments::FullComment *FC);
0365 void visitTParamCommandComment(const comments::TParamCommandComment *C,
0366 const comments::FullComment *FC);
0367 void visitVerbatimBlockComment(const comments::VerbatimBlockComment *C,
0368 const comments::FullComment *);
0369 void
0370 visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C,
0371 const comments::FullComment *);
0372 void visitVerbatimLineComment(const comments::VerbatimLineComment *C,
0373 const comments::FullComment *);
0374 };
0375
0376 class JSONDumper : public ASTNodeTraverser<JSONDumper, JSONNodeDumper> {
0377 JSONNodeDumper NodeDumper;
0378
0379 template <typename SpecializationDecl>
0380 void writeTemplateDeclSpecialization(const SpecializationDecl *SD,
0381 bool DumpExplicitInst,
0382 bool DumpRefOnly) {
0383 bool DumpedAny = false;
0384 for (const auto *RedeclWithBadType : SD->redecls()) {
0385
0386
0387
0388 const auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
0389 if (!Redecl) {
0390
0391
0392
0393 assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
0394 "expected an injected-class-name");
0395 continue;
0396 }
0397
0398 switch (Redecl->getTemplateSpecializationKind()) {
0399 case TSK_ExplicitInstantiationDeclaration:
0400 case TSK_ExplicitInstantiationDefinition:
0401 if (!DumpExplicitInst)
0402 break;
0403 [[fallthrough]];
0404 case TSK_Undeclared:
0405 case TSK_ImplicitInstantiation:
0406 if (DumpRefOnly)
0407 NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(Redecl); });
0408 else
0409 Visit(Redecl);
0410 DumpedAny = true;
0411 break;
0412 case TSK_ExplicitSpecialization:
0413 break;
0414 }
0415 }
0416
0417
0418 if (!DumpedAny)
0419 NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(SD); });
0420 }
0421
0422 template <typename TemplateDecl>
0423 void writeTemplateDecl(const TemplateDecl *TD, bool DumpExplicitInst) {
0424
0425
0426
0427
0428
0429
0430 dumpTemplateParameters(TD->getTemplateParameters());
0431
0432 Visit(TD->getTemplatedDecl());
0433
0434 for (const auto *Child : TD->specializations())
0435 writeTemplateDeclSpecialization(Child, DumpExplicitInst,
0436 !TD->isCanonicalDecl());
0437 }
0438
0439 public:
0440 JSONDumper(raw_ostream &OS, const SourceManager &SrcMgr, ASTContext &Ctx,
0441 const PrintingPolicy &PrintPolicy,
0442 const comments::CommandTraits *Traits)
0443 : NodeDumper(OS, SrcMgr, Ctx, PrintPolicy, Traits) {}
0444
0445 JSONNodeDumper &doGetNodeDelegate() { return NodeDumper; }
0446
0447 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *FTD) {
0448 writeTemplateDecl(FTD, true);
0449 }
0450 void VisitClassTemplateDecl(const ClassTemplateDecl *CTD) {
0451 writeTemplateDecl(CTD, false);
0452 }
0453 void VisitVarTemplateDecl(const VarTemplateDecl *VTD) {
0454 writeTemplateDecl(VTD, false);
0455 }
0456 };
0457
0458 }
0459
0460 #endif