aronsky created this revision.
aronsky added reviewers: aaron.ballman, steveire.
aronsky created this object with visibility "All Users".
Herald added subscribers: cfe-commits, mgorny.
Herald added a project: clang.
aronsky requested review of this revision.

AST dumps in JSON format were missing attribute nodes, compared to the textual 
dumps. This commit fixes the issue.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D90221

Files:
  clang/include/clang/AST/CMakeLists.txt
  clang/include/clang/AST/JSONNodeDumper.h
  clang/lib/AST/JSONNodeDumper.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/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

Reply via email to