steveire updated this revision to Diff 180943.
steveire added a comment.

Updates


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55492/new/

https://reviews.llvm.org/D55492

Files:
  include/clang/AST/AttrVisitor.h
  include/clang/AST/CMakeLists.txt
  include/clang/AST/TextNodeDumper.h
  lib/AST/ASTDumper.cpp
  lib/AST/TextNodeDumper.cpp
  utils/TableGen/ClangAttrEmitter.cpp
  utils/TableGen/TableGen.cpp
  utils/TableGen/TableGenBackends.h

Index: utils/TableGen/TableGenBackends.h
===================================================================
--- utils/TableGen/TableGenBackends.h
+++ utils/TableGen/TableGenBackends.h
@@ -45,7 +45,10 @@
 void EmitClangAttrParsedAttrList(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
 void EmitClangAttrParsedAttrImpl(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
 void EmitClangAttrParsedAttrKinds(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
-void EmitClangAttrDump(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);
+void EmitClangAttrTextNodeDump(llvm::RecordKeeper &Records,
+                               llvm::raw_ostream &OS);
+void EmitClangAttrNodeTraverse(llvm::RecordKeeper &Records,
+                               llvm::raw_ostream &OS);
 
 void EmitClangDiagsDefs(llvm::RecordKeeper &Records, llvm::raw_ostream &OS,
                         const std::string &Component);
Index: utils/TableGen/TableGen.cpp
===================================================================
--- utils/TableGen/TableGen.cpp
+++ utils/TableGen/TableGen.cpp
@@ -40,7 +40,8 @@
   GenClangAttrParsedAttrList,
   GenClangAttrParsedAttrImpl,
   GenClangAttrParsedAttrKinds,
-  GenClangAttrDump,
+  GenClangAttrTextNodeDump,
+  GenClangAttrNodeTraverse,
   GenClangDiagsDefs,
   GenClangDiagGroups,
   GenClangDiagsIndexName,
@@ -112,8 +113,10 @@
         clEnumValN(GenClangAttrParsedAttrKinds,
                    "gen-clang-attr-parsed-attr-kinds",
                    "Generate a clang parsed attribute kinds"),
-        clEnumValN(GenClangAttrDump, "gen-clang-attr-dump",
-                   "Generate clang attribute dumper"),
+        clEnumValN(GenClangAttrTextNodeDump, "gen-clang-attr-text-node-dump",
+                   "Generate clang attribute text node dumper"),
+        clEnumValN(GenClangAttrNodeTraverse, "gen-clang-attr-node-traverse",
+                   "Generate clang attribute traverser"),
         clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs",
                    "Generate Clang diagnostics definitions"),
         clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups",
@@ -221,8 +224,11 @@
   case GenClangAttrParsedAttrKinds:
     EmitClangAttrParsedAttrKinds(Records, OS);
     break;
-  case GenClangAttrDump:
-    EmitClangAttrDump(Records, OS);
+  case GenClangAttrTextNodeDump:
+    EmitClangAttrTextNodeDump(Records, OS);
+    break;
+  case GenClangAttrNodeTraverse:
+    EmitClangAttrNodeTraverse(Records, OS);
     break;
   case GenClangDiagsDefs:
     EmitClangDiagsDefs(Records, OS, ClangComponent);
Index: utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -603,14 +603,15 @@
       OS << "    OS << \"";
     }
 
-    void writeDump(raw_ostream &OS) const override {}
+    void writeDump(raw_ostream &OS) const override {
+      OS << "    if (!SA->is" << getUpperName() << "Expr())\n";
+      OS << "      dumpType(SA->get" << getUpperName()
+         << "Type()->getType());\n";
+    }
 
     void writeDumpChildren(raw_ostream &OS) const override {
       OS << "    if (SA->is" << getUpperName() << "Expr())\n";
       OS << "      dumpStmt(SA->get" << getUpperName() << "Expr());\n";
-      OS << "    else\n";
-      OS << "      dumpType(SA->get" << getUpperName()
-         << "Type()->getType());\n";
     }
 
     void writeHasChildren(raw_ostream &OS) const override {
@@ -2932,15 +2933,15 @@
     OS << "case AttrSyntax::" << Variety << ": {\n";
     // C++11-style attributes are further split out based on the Scope.
     for (auto I = List.cbegin(), E = List.cend(); I != E; ++I) {
-      if (I != List.cbegin())
-        OS << " else ";
-      if (I->first.empty())
-        OS << "if (ScopeName == \"\") {\n";
-      else
-        OS << "if (ScopeName == \"" << I->first << "\") {\n";
-      OS << "  return llvm::StringSwitch<int>(Name)\n";
-      GenerateHasAttrSpellingStringSwitch(I->second, OS, Spelling, I->first);
-      OS << "}";
+      if (I != List.cbegin())
+        OS << " else ";
+      if (I->first.empty())
+        OS << "if (ScopeName == \"\") {\n";
+      else
+        OS << "if (ScopeName == \"" << I->first << "\") {\n";
+      OS << "  return llvm::StringSwitch<int>(Name)\n";
+      GenerateHasAttrSpellingStringSwitch(I->second, OS, Spelling, I->first);
+      OS << "}";
     }
     OS << "\n} break;\n";
   };
@@ -3697,39 +3698,67 @@
 }
 
 // Emits the code to dump an attribute.
-void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) {
-  emitSourceFileHeader("Attribute dumper", OS);
+void EmitClangAttrTextNodeDump(RecordKeeper &Records, raw_ostream &OS) {
+  emitSourceFileHeader("Attribute text node dumper", OS);
 
-  OS << "  switch (A->getKind()) {\n";
   std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
   for (const auto *Attr : Attrs) {
     const Record &R = *Attr;
     if (!R.getValueAsBit("ASTNode"))
       continue;
-    OS << "  case attr::" << R.getName() << ": {\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);
+
     std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(R);
     if (Spellings.size() > 1 && !SpellingNamesAreCommon(Spellings))
-      OS << "    OS << \" \" << A->getSpelling();\n";
+      SS << "    OS << \" \" << A->getSpelling();\n";
 
     Args = R.getValueAsListOfDefs("Args");
-    if (!Args.empty()) {
-      OS << "    const auto *SA = cast<" << R.getName()
-         << "Attr>(A);\n";
-      for (const auto *Arg : Args)
-        createArgument(*Arg, R.getName())->writeDump(OS);
+    for (const auto *Arg : Args)
+      createArgument(*Arg, R.getName())->writeDump(SS);
+
+    if (SS.tell()) {
+      OS << "  void Visit" << R.getName() << "Attr(const " << R.getName()
+         << "Attr *A) {\n";
+      if (!Args.empty())
+        OS << "    const auto *SA = cast<" << R.getName()
+           << "Attr>(A); (void)SA;\n";
+      OS << SS.str();
+      OS << "  }\n";
+    }
+  }
+}
+
+void EmitClangAttrNodeTraverse(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;
 
-      for (const auto *AI : Args)
-        createArgument(*AI, R.getName())->writeDumpChildren(OS);
+    std::string FunctionContent;
+    llvm::raw_string_ostream SS(FunctionContent);
+
+    Args = R.getValueAsListOfDefs("Args");
+    for (const auto *Arg : Args)
+      createArgument(*Arg, R.getName())->writeDumpChildren(SS);
+    if (SS.tell()) {
+      OS << "  void Visit" << R.getName() << "Attr(const " << R.getName()
+         << "Attr *A) {\n";
+      if (!Args.empty())
+        OS << "    const auto *SA = cast<" << R.getName()
+           << "Attr>(A); (void)SA;\n";
+      OS << SS.str();
+      OS << "  }\n";
     }
-    OS <<
-      "    break;\n"
-      "  }\n";
   }
-  OS << "  }\n";
 }
 
 void EmitClangAttrParserStringSwitches(RecordKeeper &Records,
Index: lib/AST/TextNodeDumper.cpp
===================================================================
--- lib/AST/TextNodeDumper.cpp
+++ lib/AST/TextNodeDumper.cpp
@@ -41,6 +41,29 @@
                       const comments::FullComment *>::visit(C, FC);
 }
 
+void TextNodeDumper::Visit(const Attr *A) {
+  {
+    ColorScope Color(OS, ShowColors, AttrColor);
+
+    switch (A->getKind()) {
+#define ATTR(X)                                                                \
+  case attr::X:                                                                \
+    OS << #X;                                                                  \
+    break;
+#include "clang/Basic/AttrList.inc"
+    }
+    OS << "Attr";
+  }
+  dumpPointer(A);
+  dumpSourceRange(A->getRange());
+  if (A->isInherited())
+    OS << " Inherited";
+  if (A->isImplicit())
+    OS << " Implicit";
+
+  ConstAttrVisitor<TextNodeDumper>::Visit(A);
+}
+
 void TextNodeDumper::dumpPointer(const void *Ptr) {
   ColorScope Color(OS, ShowColors, AddressColor);
   OS << ' ' << Ptr;
Index: lib/AST/ASTDumper.cpp
===================================================================
--- lib/AST/ASTDumper.cpp
+++ lib/AST/ASTDumper.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDumperUtils.h"
 #include "clang/AST/Attr.h"
+#include "clang/AST/AttrVisitor.h"
 #include "clang/AST/CommentVisitor.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclLookups.h"
@@ -42,7 +43,8 @@
       : public ConstDeclVisitor<ASTDumper>,
         public ConstStmtVisitor<ASTDumper>,
         public ConstCommentVisitor<ASTDumper, void, const FullComment *>,
-        public TypeVisitor<ASTDumper> {
+        public TypeVisitor<ASTDumper>,
+        public ConstAttrVisitor<ASTDumper> {
 
     TextNodeDumper NodeDumper;
 
@@ -86,10 +88,8 @@
     void dumpStmt(const Stmt *S, StringRef Label = {});
 
     // Utilities
-    void dumpType(QualType T) { NodeDumper.dumpType(T); }
     void dumpTypeAsChild(QualType T);
     void dumpTypeAsChild(const Type *T);
-    void dumpBareDeclRef(const Decl *Node) { NodeDumper.dumpBareDeclRef(Node); }
     void dumpDeclContext(const DeclContext *DC);
     void dumpLookups(const DeclContext *DC, bool DumpDecls);
     void dumpAttr(const Attr *A);
@@ -439,6 +439,9 @@
 
     // Comments.
     void dumpComment(const Comment *C, const FullComment *FC);
+
+// Implements Visit methods for Attrs
+#include "clang/AST/AttrNodeTraverse.inc"
   };
 }
 
@@ -584,22 +587,8 @@
 
 void ASTDumper::dumpAttr(const Attr *A) {
   dumpChild([=] {
-    {
-      ColorScope Color(OS, ShowColors, AttrColor);
-
-      switch (A->getKind()) {
-#define ATTR(X) case attr::X: OS << #X; break;
-#include "clang/Basic/AttrList.inc"
-      }
-      OS << "Attr";
-    }
-    NodeDumper.dumpPointer(A);
-    NodeDumper.dumpSourceRange(A->getRange());
-    if (A->isInherited())
-      OS << " Inherited";
-    if (A->isImplicit())
-      OS << " Implicit";
-#include "clang/AST/AttrDump.inc"
+    NodeDumper.Visit(A);
+    ConstAttrVisitor<ASTDumper>::Visit(A);
   });
 }
 
Index: include/clang/AST/TextNodeDumper.h
===================================================================
--- include/clang/AST/TextNodeDumper.h
+++ include/clang/AST/TextNodeDumper.h
@@ -16,6 +16,7 @@
 
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDumperUtils.h"
+#include "clang/AST/AttrVisitor.h"
 #include "clang/AST/CommentCommandTraits.h"
 #include "clang/AST/CommentVisitor.h"
 #include "clang/AST/ExprCXX.h"
@@ -121,7 +122,8 @@
 class TextNodeDumper
     : public TextTreeStructure,
       public comments::ConstCommentVisitor<TextNodeDumper, void,
-                                           const comments::FullComment *> {
+                                           const comments::FullComment *>,
+      public ConstAttrVisitor<TextNodeDumper> {
   raw_ostream &OS;
   const bool ShowColors;
 
@@ -146,6 +148,8 @@
 
   void Visit(const comments::Comment *C, const comments::FullComment *FC);
 
+  void Visit(const Attr *A);
+
   void dumpPointer(const void *Ptr);
   void dumpLocation(SourceLocation Loc);
   void dumpSourceRange(SourceRange R);
@@ -179,6 +183,9 @@
                                 const comments::FullComment *);
   void visitVerbatimLineComment(const comments::VerbatimLineComment *C,
                                 const comments::FullComment *);
+
+// Implements Visit methods for Attrs
+#include "clang/AST/AttrTextNodeDump.inc"
 };
 
 } // namespace clang
Index: include/clang/AST/CMakeLists.txt
===================================================================
--- include/clang/AST/CMakeLists.txt
+++ include/clang/AST/CMakeLists.txt
@@ -8,10 +8,15 @@
   SOURCE ../Basic/Attr.td
   TARGET ClangAttrImpl)
 
-clang_tablegen(AttrDump.inc -gen-clang-attr-dump
+clang_tablegen(AttrTextNodeDump.inc -gen-clang-attr-text-node-dump
   -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
   SOURCE ../Basic/Attr.td
-  TARGET ClangAttrDump)
+  TARGET ClangAttrTextDump)
+
+clang_tablegen(AttrNodeTraverse.inc -gen-clang-attr-node-traverse
+  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  SOURCE ../Basic/Attr.td
+  TARGET ClangAttrTraverse)
 
 clang_tablegen(AttrVisitor.inc -gen-clang-attr-ast-visitor
   -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
Index: include/clang/AST/AttrVisitor.h
===================================================================
--- /dev/null
+++ include/clang/AST/AttrVisitor.h
@@ -0,0 +1,76 @@
+//===- AttrVisitor.h - Visitor for Attr subclasses --------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the AttrVisitor interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ATTRVISITOR_H
+#define LLVM_CLANG_AST_ATTRVISITOR_H
+
+#include "clang/AST/Attr.h"
+
+namespace clang {
+
+namespace attrvisitor {
+
+/// A simple visitor class that helps create attribute visitors.
+template <template <typename> class Ptr, typename ImplClass,
+          typename RetTy = void, class... ParamTys>
+class Base {
+public:
+#define PTR(CLASS) typename Ptr<CLASS>::type
+#define DISPATCH(NAME)                                                         \
+  return static_cast<ImplClass *>(this)->Visit##NAME(static_cast<PTR(NAME)>(A))
+
+  RetTy Visit(PTR(Attr) A) {
+    switch (A->getKind()) {
+
+#define ATTR(NAME)                                                             \
+  case attr::NAME:                                                             \
+    DISPATCH(NAME##Attr);
+#include "clang/Basic/AttrList.inc"
+    }
+    llvm_unreachable("Attr that isn't part of AttrList.inc!");
+  }
+
+  // If the implementation chooses not to implement a certain visit
+  // method, fall back to the parent.
+#define ATTR(NAME)                                                             \
+  RetTy Visit##NAME##Attr(PTR(NAME##Attr) A) { DISPATCH(Attr); }
+#include "clang/Basic/AttrList.inc"
+
+  RetTy VisitAttr(PTR(Attr)) { return RetTy(); }
+
+#undef PTR
+#undef DISPATCH
+};
+
+} // namespace attrvisitor
+
+/// A simple visitor class that helps create attribute visitors.
+///
+/// This class does not preserve constness of Attr pointers (see
+/// also ConstAttrVisitor).
+template <typename ImplClass, typename RetTy = void, typename... ParamTys>
+class AttrVisitor : public attrvisitor::Base<std::add_pointer, ImplClass, RetTy,
+                                             ParamTys...> {};
+
+/// A simple visitor class that helps create attribute visitors.
+///
+/// This class preserves constness of Attr pointers (see also
+/// AttrVisitor).
+template <typename ImplClass, typename RetTy = void, typename... ParamTys>
+class ConstAttrVisitor
+    : public attrvisitor::Base<llvm::make_const_ptr, ImplClass, RetTy,
+                               ParamTys...> {};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ATTRVISITOR_H
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to