r350958 - Implement Attr dumping in terms of visitors
Stephen Kelly via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 11 11:16:02 PST 2019
Author: steveire
Date: Fri Jan 11 11:16:01 2019
New Revision: 350958
URL: http://llvm.org/viewvc/llvm-project?rev=350958&view=rev
Log:
Implement Attr dumping in terms of visitors
Remove now-vestigial dumpType and dumpBareDeclRef methods. The old
tablegen generated code used to expect them to be present, but the new
generated code has no such requirement.
Reviewers: aaron.ballman
Subscribers: mgorny, cfe-commits
Differential Revision: https://reviews.llvm.org/D55492
Added:
cfe/trunk/include/clang/AST/AttrVisitor.h
Modified:
cfe/trunk/include/clang/AST/CMakeLists.txt
cfe/trunk/include/clang/AST/TextNodeDumper.h
cfe/trunk/lib/AST/ASTDumper.cpp
cfe/trunk/lib/AST/TextNodeDumper.cpp
cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
cfe/trunk/utils/TableGen/TableGen.cpp
cfe/trunk/utils/TableGen/TableGenBackends.h
Added: cfe/trunk/include/clang/AST/AttrVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/AttrVisitor.h?rev=350958&view=auto
==============================================================================
--- cfe/trunk/include/clang/AST/AttrVisitor.h (added)
+++ cfe/trunk/include/clang/AST/AttrVisitor.h Fri Jan 11 11:16:01 2019
@@ -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
Modified: cfe/trunk/include/clang/AST/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CMakeLists.txt?rev=350958&r1=350957&r2=350958&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CMakeLists.txt (original)
+++ cfe/trunk/include/clang/AST/CMakeLists.txt Fri Jan 11 11:16:01 2019
@@ -8,10 +8,15 @@ clang_tablegen(AttrImpl.inc -gen-clang-a
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}/../../
Modified: cfe/trunk/include/clang/AST/TextNodeDumper.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TextNodeDumper.h?rev=350958&r1=350957&r2=350958&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TextNodeDumper.h (original)
+++ cfe/trunk/include/clang/AST/TextNodeDumper.h Fri Jan 11 11:16:01 2019
@@ -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 @@ public:
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 @@ public:
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 @@ public:
const comments::FullComment *);
void visitVerbatimLineComment(const comments::VerbatimLineComment *C,
const comments::FullComment *);
+
+// Implements Visit methods for Attrs.
+#include "clang/AST/AttrTextNodeDump.inc"
};
} // namespace clang
Modified: cfe/trunk/lib/AST/ASTDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=350958&r1=350957&r2=350958&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTDumper.cpp (original)
+++ cfe/trunk/lib/AST/ASTDumper.cpp Fri Jan 11 11:16:01 2019
@@ -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 @@ namespace {
: 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 @@ namespace {
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 @@ namespace {
// 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::dumpLookups(const DeclCo
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);
});
}
Modified: cfe/trunk/lib/AST/TextNodeDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TextNodeDumper.cpp?rev=350958&r1=350957&r2=350958&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TextNodeDumper.cpp (original)
+++ cfe/trunk/lib/AST/TextNodeDumper.cpp Fri Jan 11 11:16:01 2019
@@ -41,6 +41,29 @@ void TextNodeDumper::Visit(const comment
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;
Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=350958&r1=350957&r2=350958&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Fri Jan 11 11:16:01 2019
@@ -603,14 +603,15 @@ namespace {
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 @@ void EmitClangAttrHasAttrImpl(RecordKeep
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 @@ void EmitClangAttrParsedAttrKinds(Record
}
// 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);
- for (const auto *AI : Args)
- createArgument(*AI, R.getName())->writeDumpChildren(OS);
+ 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 traverser", OS);
+
+ std::vector<Record *> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;
+ for (const auto *Attr : Attrs) {
+ const Record &R = *Attr;
+ if (!R.getValueAsBit("ASTNode"))
+ continue;
+
+ 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,
Modified: cfe/trunk/utils/TableGen/TableGen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGen.cpp?rev=350958&r1=350957&r2=350958&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/TableGen.cpp (original)
+++ cfe/trunk/utils/TableGen/TableGen.cpp Fri Jan 11 11:16:01 2019
@@ -40,7 +40,8 @@ enum ActionType {
GenClangAttrParsedAttrList,
GenClangAttrParsedAttrImpl,
GenClangAttrParsedAttrKinds,
- GenClangAttrDump,
+ GenClangAttrTextNodeDump,
+ GenClangAttrNodeTraverse,
GenClangDiagsDefs,
GenClangDiagGroups,
GenClangDiagsIndexName,
@@ -112,8 +113,10 @@ cl::opt<ActionType> Action(
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 @@ bool ClangTableGenMain(raw_ostream &OS,
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);
Modified: cfe/trunk/utils/TableGen/TableGenBackends.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGenBackends.h?rev=350958&r1=350957&r2=350958&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/TableGenBackends.h (original)
+++ cfe/trunk/utils/TableGen/TableGenBackends.h Fri Jan 11 11:16:01 2019
@@ -45,7 +45,10 @@ void EmitClangAttrTemplateInstantiate(ll
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);
More information about the cfe-commits
mailing list