aronsky updated this revision to Diff 302558. aronsky retitled this revision from "Include attribute details when dumping AST in JSON" to "Include more attribute details when dumping AST in JSON". aronsky edited the summary of this revision. aronsky added a comment.
Updated the relevant unit-test: it now passes, and also verifies the changes. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D90221/new/ https://reviews.llvm.org/D90221 Files: clang/include/clang/AST/CMakeLists.txt clang/include/clang/AST/JSONNodeDumper.h clang/lib/AST/JSONNodeDumper.cpp clang/test/AST/ast-dump-stmt-json.cpp clang/utils/TableGen/ClangAttrEmitter.cpp clang/utils/TableGen/TableGen.cpp clang/utils/TableGen/TableGenBackends.h
Index: clang/utils/TableGen/TableGenBackends.h =================================================================== --- clang/utils/TableGen/TableGenBackends.h +++ clang/utils/TableGen/TableGenBackends.h @@ -59,6 +59,8 @@ llvm::raw_ostream &OS); void EmitClangAttrTextNodeDump(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); +void EmitClangAttrJSONNodeDump(llvm::RecordKeeper &Records, + llvm::raw_ostream &OS); void EmitClangAttrNodeTraverse(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); Index: clang/utils/TableGen/TableGen.cpp =================================================================== --- clang/utils/TableGen/TableGen.cpp +++ clang/utils/TableGen/TableGen.cpp @@ -41,6 +41,7 @@ GenClangAttrParsedAttrImpl, GenClangAttrParsedAttrKinds, GenClangAttrTextNodeDump, + GenClangAttrJSONNodeDump, GenClangAttrNodeTraverse, GenClangBasicReader, GenClangBasicWriter, @@ -138,6 +139,8 @@ "Generate a clang parsed attribute kinds"), clEnumValN(GenClangAttrTextNodeDump, "gen-clang-attr-text-node-dump", "Generate clang attribute text node dumper"), + clEnumValN(GenClangAttrJSONNodeDump, "gen-clang-attr-json-node-dump", + "Generate clang attribute JSON node dumper"), clEnumValN(GenClangAttrNodeTraverse, "gen-clang-attr-node-traverse", "Generate clang attribute traverser"), clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs", @@ -295,6 +298,9 @@ case GenClangAttrTextNodeDump: EmitClangAttrTextNodeDump(Records, OS); break; + case GenClangAttrJSONNodeDump: + EmitClangAttrJSONNodeDump(Records, OS); + break; case GenClangAttrNodeTraverse: EmitClangAttrNodeTraverse(Records, OS); break; Index: clang/utils/TableGen/ClangAttrEmitter.cpp =================================================================== --- clang/utils/TableGen/ClangAttrEmitter.cpp +++ clang/utils/TableGen/ClangAttrEmitter.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/JSON.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" @@ -3895,7 +3896,7 @@ << "}\n"; } -// Emits the code to dump an attribute. +// Emits the code to dump an attribute as text. void EmitClangAttrTextNodeDump(RecordKeeper &Records, raw_ostream &OS) { emitSourceFileHeader("Attribute text node dumper", OS); @@ -3932,6 +3933,58 @@ } } +// Emits the code to dump an attribute as JSON. +void EmitClangAttrJSONNodeDump(RecordKeeper &Records, raw_ostream &OS) { + emitSourceFileHeader("Attribute text node dumper", OS); + + std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr"), Args; + for (const auto *Attr : Attrs) { + const Record &R = *Attr; + if (!R.getValueAsBit("ASTNode")) + continue; + + OS << " void Visit" << R.getName() << "Attr(const " << R.getName() + << "Attr *A) {\n"; + + // If the attribute has a semantically-meaningful name (which is determined + // by whether there is a Spelling enumeration for it), then write out the + // spelling used for the attribute. + + std::string FunctionContent; + llvm::raw_string_ostream SS(FunctionContent); + + Args = R.getValueAsListOfDefs("Args"); + + if (!Args.empty()) + OS << " const auto *SA = cast<" << R.getName() + << "Attr>(A); (void)SA;\n" + << " llvm::json::Array Args;\n"; + + std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R); + if (Spellings.size() > 1 && !SpellingNamesAreCommon(Spellings)) + OS << " JOS.attribute(\"spelling\", A->getSpelling());\n"; + + for (const auto *Arg : Args) { + std::string ArgContent; + llvm::raw_string_ostream SS(ArgContent); + + createArgument(*Arg, R.getName())->writeDump(SS); + + if (SS.tell()) + OS << " {\n" + << " std::string Str;\n" + << " llvm::raw_string_ostream OS(Str);\n" + << SS.str() << " Args.push_back(OS.str());\n" + << " }\n"; + } + + if (!Args.empty()) + OS << " JOS.attribute(\"args\", std::move(Args));\n"; + + OS << "}\n"; + } +} + void EmitClangAttrNodeTraverse(RecordKeeper &Records, raw_ostream &OS) { emitSourceFileHeader("Attribute text node traverser", OS); Index: clang/test/AST/ast-dump-stmt-json.cpp =================================================================== --- clang/test/AST/ast-dump-stmt-json.cpp +++ clang/test/AST/ast-dump-stmt-json.cpp @@ -1461,6 +1461,9 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " Default" +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", @@ -1479,6 +1482,10 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " 1", +// CHECK-NEXT: "" +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -1531,6 +1538,9 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " Default" +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", @@ -1549,6 +1559,10 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " 1", +// CHECK-NEXT: "" +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", @@ -1558,6 +1572,9 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " 2" +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -1598,6 +1615,9 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " Default" +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", @@ -1616,6 +1636,10 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " 1" +// CHECK-NEXT: "" +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -1668,6 +1692,9 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " Default" +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", @@ -1686,6 +1713,10 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " 1" +// CHECK-NEXT: "" +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", @@ -1695,6 +1726,9 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " 2" +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -1735,6 +1769,9 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " Default" +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -1787,6 +1824,9 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " Default" +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -1827,6 +1867,9 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " Default" +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -1879,6 +1922,9 @@ // CHECK-NEXT: "end": {} // CHECK-NEXT: }, // CHECK-NEXT: "implicit": true +// CHECK-NEXT: "args": [ +// CHECK-NEXT: " Default" +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } Index: clang/lib/AST/JSONNodeDumper.cpp =================================================================== --- clang/lib/AST/JSONNodeDumper.cpp +++ clang/lib/AST/JSONNodeDumper.cpp @@ -306,6 +306,12 @@ JOS.attribute("type", createQualType(VD->getType())); } +void JSONNodeDumper::dumpBareDeclRef(const Decl *D) { writeBareDeclRef(D); } + +void JSONNodeDumper::dumpType(QualType QT) { + JOS.attribute("type", createQualType(QT)); +} + llvm::json::Object JSONNodeDumper::createBareDeclRef(const Decl *D) { llvm::json::Object Ret{{"id", createPointerRepresentation(D)}}; if (!D) Index: clang/include/clang/AST/JSONNodeDumper.h =================================================================== --- clang/include/clang/AST/JSONNodeDumper.h +++ clang/include/clang/AST/JSONNodeDumper.h @@ -161,6 +161,8 @@ llvm::json::Object createQualType(QualType QT, bool Desugar = true); llvm::json::Object createBareDeclRef(const Decl *D); void writeBareDeclRef(const Decl *D); + void dumpBareDeclRef(const Decl *D); + void dumpType(QualType QT); llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD); llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier &BS); std::string createAccessSpecifier(AccessSpecifier AS); @@ -206,6 +208,9 @@ void Visit(const GenericSelectionExpr::ConstAssociation &A); void Visit(const APValue &Value, QualType Ty); +// Implements Visit methods for Attrs. +#include "clang/AST/AttrJSONNodeDump.inc" + void VisitTypedefType(const TypedefType *TT); void VisitFunctionType(const FunctionType *T); void VisitFunctionProtoType(const FunctionProtoType *T); Index: clang/include/clang/AST/CMakeLists.txt =================================================================== --- clang/include/clang/AST/CMakeLists.txt +++ clang/include/clang/AST/CMakeLists.txt @@ -10,6 +10,10 @@ SOURCE ../Basic/Attr.td TARGET ClangAttrTextDump) +clang_tablegen(AttrJSONNodeDump.inc -gen-clang-attr-json-node-dump + SOURCE ../Basic/Attr.td + TARGET ClangAttrJSONDump) + clang_tablegen(AttrNodeTraverse.inc -gen-clang-attr-node-traverse SOURCE ../Basic/Attr.td TARGET ClangAttrTraverse)
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits