<div dir="ltr"><div class="gmail_default" style>Does r171808 fix the issue?</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jan 7, 2013 at 11:38 PM, David Dean <span dir="ltr"><<a href="mailto:david_dean@apple.com" target="_blank">david_dean@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I'm seeing the following test failure on darwin:<br>
<br>
******************** TEST 'Clang :: Misc/ast-dump-attr.cpp' FAILED ********************Script:<br>
--<br>
/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-nobootstrap-RA/clang-build/Release+Asserts/bin/clang -cc1 -internal-isystem /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-nobootstrap-RA/clang-build/Release+Asserts/bin/../lib/clang/3.3/include -std=c++11 -ast-dump -ast-dump-filter Test /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-nobootstrap-RA/clang.src/test/Misc/ast-dump-attr.cpp | FileCheck --strict-whitespace /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-nobootstrap-RA/clang.src/test/Misc/ast-dump-attr.cpp<br>
--<br>
Exit Code: 1<br>
Command Output (stderr):<br>
--<br>
/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-nobootstrap-RA/clang.src/test/Misc/ast-dump-attr.cpp:82:31: error: only weak aliases are supported on darwin<br>
<div class="im">int TestString __attribute__((alias("alias1")));<br>
^<br>
1 error generated.<br>
</div>/Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-nobootstrap-RA/clang.src/test/Misc/ast-dump-attr.cpp:84:18: error: expected string not found in input<br>
<div class="im">// CHECK-NEXT: AliasAttr{{.*}} "alias1"<br>
^<br>
</div><stdin>:84:180: note: scanning from here<br>
(VarDecl 0x10285abf0 </Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-nobootstrap-RA/clang.src/test/Misc/ast-dump-attr.cpp:82:1, col:5> TestString 'int')<br>
^<br>
<stdin>:93:7: note: possible intended match here<br>
(AllocSizeAttr 0x10285afd0 <col:49, col:61> 0))<br>
^<br>
--<br>
<br>
********************<br>
<div class="HOEnZb"><div class="h5">On 7 Jan 2013, at 9:53 AM, Alexander Kornienko <<a href="mailto:alexfh@google.com">alexfh@google.com</a>> wrote:<br>
<br>
> Author: alexfh<br>
> Date: Mon Jan 7 11:53:08 2013<br>
> New Revision: 171760<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=171760&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=171760&view=rev</a><br>
> Log:<br>
> Implement Attr dumping for -ast-dump.<br>
> <a href="http://llvm-reviews.chandlerc.com/D234" target="_blank">http://llvm-reviews.chandlerc.com/D234</a><br>
><br>
> Patch by Philip Craig!<br>
><br>
> Added:<br>
> cfe/trunk/test/Misc/ast-dump-attr.cpp<br>
> Modified:<br>
> cfe/trunk/include/clang/AST/CMakeLists.txt<br>
> cfe/trunk/include/clang/AST/Makefile<br>
> cfe/trunk/lib/AST/ASTDumper.cpp<br>
> cfe/trunk/lib/AST/CMakeLists.txt<br>
> cfe/trunk/test/Tooling/clang-check-ast-dump.cpp<br>
> cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp<br>
> cfe/trunk/utils/TableGen/TableGen.cpp<br>
> cfe/trunk/utils/TableGen/TableGenBackends.h<br>
><br>
> Modified: cfe/trunk/include/clang/AST/CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CMakeLists.txt?rev=171760&r1=171759&r2=171760&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CMakeLists.txt?rev=171760&r1=171759&r2=171760&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/AST/CMakeLists.txt (original)<br>
> +++ cfe/trunk/include/clang/AST/CMakeLists.txt Mon Jan 7 11:53:08 2013<br>
> @@ -8,6 +8,11 @@<br>
> SOURCE ../Basic/Attr.td<br>
> TARGET ClangAttrImpl)<br>
><br>
> +clang_tablegen(AttrDump.inc -gen-clang-attr-dump<br>
> + -I ${CMAKE_CURRENT_SOURCE_DIR}/../../<br>
> + SOURCE ../Basic/Attr.td<br>
> + TARGET ClangAttrDump)<br>
> +<br>
> clang_tablegen(StmtNodes.inc -gen-clang-stmt-nodes<br>
> SOURCE ../Basic/StmtNodes.td<br>
> TARGET ClangStmtNodes)<br>
><br>
> Modified: cfe/trunk/include/clang/AST/Makefile<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Makefile?rev=171760&r1=171759&r2=171760&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Makefile?rev=171760&r1=171759&r2=171760&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/AST/Makefile (original)<br>
> +++ cfe/trunk/include/clang/AST/Makefile Mon Jan 7 11:53:08 2013<br>
> @@ -1,6 +1,7 @@<br>
> CLANG_LEVEL := ../../..<br>
> TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic<br>
> -BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc \<br>
> +BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc \<br>
> + StmtNodes.inc DeclNodes.inc \<br>
> CommentNodes.inc CommentHTMLTags.inc \<br>
> CommentHTMLTagsProperties.inc CommentCommandInfo.inc<br>
><br>
> @@ -20,6 +21,12 @@<br>
> $(Verb) $(ClangTableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \<br>
> -I $(PROJ_SRC_DIR)/../../ $<<br>
><br>
> +$(ObjDir)/AttrDump.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \<br>
> + $(ObjDir)/.dir<br>
> + $(Echo) "Building Clang attribute dumper with tblgen"<br>
> + $(Verb) $(ClangTableGen) -gen-clang-attr-dump -o $(call SYSPATH, $@) \<br>
> + -I $(PROJ_SRC_DIR)/../../ $<<br>
> +<br>
> $(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(CLANG_TBLGEN) \<br>
> $(ObjDir)/.dir<br>
> $(Echo) "Building Clang statement node tables with tblgen"<br>
><br>
> Modified: cfe/trunk/lib/AST/ASTDumper.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=171760&r1=171759&r2=171760&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=171760&r1=171759&r2=171760&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/AST/ASTDumper.cpp (original)<br>
> +++ cfe/trunk/lib/AST/ASTDumper.cpp Mon Jan 7 11:53:08 2013<br>
> @@ -13,6 +13,7 @@<br>
> //===----------------------------------------------------------------------===//<br>
><br>
> #include "clang/AST/ASTContext.h"<br>
> +#include "clang/AST/Attr.h"<br>
> #include "clang/AST/DeclCXX.h"<br>
> #include "clang/AST/DeclObjC.h"<br>
> #include "clang/AST/DeclVisitor.h"<br>
> @@ -74,6 +75,7 @@<br>
> void dumpDeclRef(const Decl *Node, const char *Label = 0);<br>
> void dumpName(const NamedDecl *D);<br>
> void dumpDeclContext(const DeclContext *DC);<br>
> + void dumpAttr(const Attr *A);<br>
><br>
> // C++ Utilities<br>
> void dumpAccessSpecifier(AccessSpecifier AS);<br>
> @@ -141,6 +143,7 @@<br>
> // Stmts.<br>
> void VisitStmt(Stmt *Node);<br>
> void VisitDeclStmt(DeclStmt *Node);<br>
> + void VisitAttributedStmt(AttributedStmt *Node);<br>
> void VisitLabelStmt(LabelStmt *Node);<br>
> void VisitGotoStmt(GotoStmt *Node);<br>
><br>
> @@ -308,6 +311,19 @@<br>
> dumpDecl(*I);<br>
> }<br>
><br>
> +void ASTDumper::dumpAttr(const Attr *A) {<br>
> + IndentScope Indent(*this);<br>
> + switch (A->getKind()) {<br>
> +#define ATTR(X) case attr::X: OS << #X; break;<br>
> +#include "clang/Basic/AttrList.inc"<br>
> + default: llvm_unreachable("unexpected attribute kind");<br>
> + }<br>
> + OS << "Attr";<br>
> + dumpPointer(A);<br>
> + dumpSourceRange(A->getRange());<br>
> +#include "clang/AST/AttrDump.inc"<br>
> +}<br>
> +<br>
> //===----------------------------------------------------------------------===//<br>
> // C++ Utilities<br>
> //===----------------------------------------------------------------------===//<br>
> @@ -425,6 +441,11 @@<br>
> dumpPointer(D);<br>
> dumpSourceRange(D->getSourceRange());<br>
> DeclVisitor<ASTDumper>::Visit(D);<br>
> + if (D->hasAttrs()) {<br>
> + for (AttrVec::const_iterator I = D->getAttrs().begin(),<br>
> + E = D->getAttrs().end(); I != E; ++I)<br>
> + dumpAttr(*I);<br>
> + }<br>
> // Decls within functions are visited by the body<br>
> if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D))<br>
> dumpDeclContext(dyn_cast<DeclContext>(D));<br>
> @@ -959,6 +980,13 @@<br>
> dumpDecl(*I);<br>
> }<br>
><br>
> +void ASTDumper::VisitAttributedStmt(AttributedStmt *Node) {<br>
> + VisitStmt(Node);<br>
> + for (ArrayRef<const Attr*>::iterator I = Node->getAttrs().begin(),<br>
> + E = Node->getAttrs().end(); I != E; ++I)<br>
> + dumpAttr(*I);<br>
> +}<br>
> +<br>
> void ASTDumper::VisitLabelStmt(LabelStmt *Node) {<br>
> VisitStmt(Node);<br>
> OS << " '" << Node->getName() << "'";<br>
><br>
> Modified: cfe/trunk/lib/AST/CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CMakeLists.txt?rev=171760&r1=171759&r2=171760&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CMakeLists.txt?rev=171760&r1=171759&r2=171760&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/AST/CMakeLists.txt (original)<br>
> +++ cfe/trunk/lib/AST/CMakeLists.txt Mon Jan 7 11:53:08 2013<br>
> @@ -64,6 +64,7 @@<br>
> ClangAttrClasses<br>
> ClangAttrList<br>
> ClangAttrImpl<br>
> + ClangAttrDump<br>
> ClangCommentCommandInfo<br>
> ClangCommentNodes<br>
> ClangCommentHTMLTags<br>
><br>
> Added: cfe/trunk/test/Misc/ast-dump-attr.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-attr.cpp?rev=171760&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/ast-dump-attr.cpp?rev=171760&view=auto</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/Misc/ast-dump-attr.cpp (added)<br>
> +++ cfe/trunk/test/Misc/ast-dump-attr.cpp Mon Jan 7 11:53:08 2013<br>
> @@ -0,0 +1,97 @@<br>
> +// RUN: %clang_cc1 -std=c++11 -ast-dump -ast-dump-filter Test %s | FileCheck --strict-whitespace %s<br>
> +<br>
> +int TestLocation<br>
> +__attribute__((unused));<br>
> +// CHECK: VarDecl{{.*}}TestLocation<br>
> +// CHECK-NEXT: UnusedAttr 0x{{[^ ]*}} <line:[[@LINE-2]]:16><br>
> +<br>
> +int TestIndent<br>
> +__attribute__((unused));<br>
> +// CHECK: {{^\(VarDecl.*TestIndent[^()]*$}}<br>
> +// CHECK-NEXT: {{^ \(UnusedAttr[^()]*\)\)$}}<br>
> +<br>
> +void TestAttributedStmt() {<br>
> + switch (1) {<br>
> + case 1:<br>
> + [[clang::fallthrough]];<br>
> + case 2:<br>
> + ;<br>
> + }<br>
> +}<br>
> +// CHECK: FunctionDecl{{.*}}TestAttributedStmt<br>
> +// CHECK: AttributedStmt<br>
> +// CHECK-NEXT: FallThroughAttr<br>
> +// CHECK-NEXT: NullStmt<br>
> +<br>
> +[[clang::warn_unused_result]] int TestCXX11DeclAttr();<br>
> +// CHECK: FunctionDecl{{.*}}TestCXX11DeclAttr<br>
> +// CHECK-NEXT: WarnUnusedResultAttr<br>
> +<br>
> +int TestAlignedNull __attribute__((aligned));<br>
> +// CHECK: VarDecl{{.*}}TestAlignedNull<br>
> +// CHECK-NEXT: AlignedAttr<br>
> +// CHECK-NEXT: <<<NULL>>><br>
> +<br>
> +int TestAlignedExpr __attribute__((aligned(4)));<br>
> +// CHECK: VarDecl{{.*}}TestAlignedExpr<br>
> +// CHECK-NEXT: AlignedAttr<br>
> +// CHECK-NEXT: IntegerLiteral<br>
> +<br>
> +int TestEnum __attribute__((visibility("default")));<br>
> +// CHECK: VarDecl{{.*}}TestEnum<br>
> +// CHECK-NEXT: VisibilityAttr{{.*}} Default<br>
> +<br>
> +class __attribute__((lockable)) Mutex {<br>
> +} mu1, mu2;<br>
> +int TestExpr __attribute__((guarded_by(mu1)));<br>
> +// CHECK: VarDecl{{.*}}TestExpr<br>
> +// CHECK-NEXT: GuardedByAttr<br>
> +// CHECK-NEXT: DeclRefExpr{{.*}}mu1<br>
> +<br>
> +class Mutex TestVariadicExpr __attribute__((acquired_after(mu1, mu2)));<br>
> +// CHECK: VarDecl{{.*}}TestVariadicExpr<br>
> +// CHECK: AcquiredAfterAttr<br>
> +// CHECK-NEXT: DeclRefExpr{{.*}}mu1<br>
> +// CHECK-NEXT: DeclRefExpr{{.*}}mu2<br>
> +<br>
> +void function1(void *) {<br>
> + int TestFunction __attribute__((cleanup(function1)));<br>
> +}<br>
> +// CHECK: VarDecl{{.*}}TestFunction<br>
> +// CHECK-NEXT: CleanupAttr{{.*}} Function{{.*}}function1<br>
> +<br>
> +void TestIdentifier(void *, int)<br>
> +__attribute__((pointer_with_type_tag(ident1,1,2)));<br>
> +// CHECK: FunctionDecl{{.*}}TestIdentifier<br>
> +// CHECK: ArgumentWithTypeTagAttr{{.*}} ident1<br>
> +<br>
> +void TestBool(void *, int)<br>
> +__attribute__((pointer_with_type_tag(bool1,1,2)));<br>
> +// CHECK: FunctionDecl{{.*}}TestBool<br>
> +// CHECK: ArgumentWithTypeTagAttr{{.*}} IsPointer<br>
> +<br>
> +void TestUnsigned(void *, int)<br>
> +__attribute__((pointer_with_type_tag(unsigned1,1,2)));<br>
> +// CHECK: FunctionDecl{{.*}}TestUnsigned<br>
> +// CHECK: ArgumentWithTypeTagAttr{{.*}} 0 1<br>
> +<br>
> +void TestInt(void) __attribute__((constructor(123)));<br>
> +// CHECK: FunctionDecl{{.*}}TestInt<br>
> +// CHECK-NEXT: ConstructorAttr{{.*}} 123<br>
> +<br>
> +int TestString __attribute__((alias("alias1")));<br>
> +// CHECK: VarDecl{{.*}}TestString<br>
> +// CHECK-NEXT: AliasAttr{{.*}} "alias1"<br>
> +<br>
> +extern struct s1 TestType<br>
> +__attribute__((type_tag_for_datatype(ident1,int)));<br>
> +// CHECK: VarDecl{{.*}}TestType<br>
> +// CHECK-NEXT: TypeTagForDatatypeAttr{{.*}} int<br>
> +<br>
> +void *TestVariadicUnsigned1(int) __attribute__((alloc_size(1)));<br>
> +// CHECK: FunctionDecl{{.*}}TestVariadicUnsigned1<br>
> +// CHECK: AllocSizeAttr{{.*}} 0<br>
> +<br>
> +void *TestVariadicUnsigned2(int, int) __attribute__((alloc_size(1,2)));<br>
> +// CHECK: FunctionDecl{{.*}}TestVariadicUnsigned2<br>
> +// CHECK: AllocSizeAttr{{.*}} 0 1<br>
><br>
> Modified: cfe/trunk/test/Tooling/clang-check-ast-dump.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-check-ast-dump.cpp?rev=171760&r1=171759&r2=171760&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Tooling/clang-check-ast-dump.cpp?rev=171760&r1=171759&r2=171760&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/Tooling/clang-check-ast-dump.cpp (original)<br>
> +++ cfe/trunk/test/Tooling/clang-check-ast-dump.cpp Mon Jan 7 11:53:08 2013<br>
> @@ -31,7 +31,8 @@<br>
> // RUN: clang-check -ast-dump -ast-dump-filter test_namespace::TheClass::n "%s" -- 2>&1 | FileCheck -check-prefix CHECK-ATTR %s<br>
> // CHECK-ATTR: test_namespace<br>
> // CHECK-ATTR-NEXT: (FieldDecl{{.*}}n<br>
> -// FIXME: attribute dumping not implemented yet<br>
> +// CHECK-ATTR-NEXT: (AlignedAttr<br>
> +// CHECK-ATTR-NEXT: (BinaryOperator<br>
> //<br>
> // RUN: clang-check -ast-dump -ast-dump-filter test_namespace::AfterNullNode "%s" -- 2>&1 | FileCheck -check-prefix CHECK-AFTER-NULL %s<br>
> // CHECK-AFTER-NULL: class AfterNullNode<br>
><br>
> Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=171760&r1=171759&r2=171760&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=171760&r1=171759&r2=171760&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)<br>
> +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Mon Jan 7 11:53:08 2013<br>
> @@ -125,6 +125,8 @@<br>
> virtual void writePCHReadDecls(raw_ostream &OS) const = 0;<br>
> virtual void writePCHWrite(raw_ostream &OS) const = 0;<br>
> virtual void writeValue(raw_ostream &OS) const = 0;<br>
> + virtual void writeDump(raw_ostream &OS) const = 0;<br>
> + virtual void writeDumpChildren(raw_ostream &OS) const {}<br>
> };<br>
><br>
> class SimpleArgument : public Argument {<br>
> @@ -181,6 +183,28 @@<br>
> OS << "\" << get" << getUpperName() << "() << \"";<br>
> }<br>
> }<br>
> + void writeDump(raw_ostream &OS) const {<br>
> + if (type == "FunctionDecl *") {<br>
> + OS << " OS << \" \";\n";<br>
> + OS << " dumpBareDeclRef(SA->get" << getUpperName() << "());\n";<br>
> + } else if (type == "IdentifierInfo *") {<br>
> + OS << " OS << \" \" << SA->get" << getUpperName()<br>
> + << "()->getName();\n";<br>
> + } else if (type == "QualType") {<br>
> + OS << " OS << \" \" << SA->get" << getUpperName()<br>
> + << "().getAsString();\n";<br>
> + } else if (type == "SourceLocation") {<br>
> + OS << " OS << \" \";\n";<br>
> + OS << " SA->get" << getUpperName() << "().print(OS, *SM);\n";<br>
> + } else if (type == "bool") {<br>
> + OS << " if (SA->get" << getUpperName() << "()) OS << \" "<br>
> + << getUpperName() << "\";\n";<br>
> + } else if (type == "int" || type == "unsigned") {<br>
> + OS << " OS << \" \" << SA->get" << getUpperName() << "();\n";<br>
> + } else {<br>
> + llvm_unreachable("Unknown SimpleArgument type!");<br>
> + }<br>
> + }<br>
> };<br>
><br>
> class StringArgument : public Argument {<br>
> @@ -241,6 +265,10 @@<br>
> void writeValue(raw_ostream &OS) const {<br>
> OS << "\\\"\" << get" << getUpperName() << "() << \"\\\"";<br>
> }<br>
> + void writeDump(raw_ostream &OS) const {<br>
> + OS << " OS << \" \\\"\" << SA->get" << getUpperName()<br>
> + << "() << \"\\\"\";\n";<br>
> + }<br>
> };<br>
><br>
> class AlignedArgument : public Argument {<br>
> @@ -353,6 +381,15 @@<br>
> << " " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n"<br>
> << " OS << \"";<br>
> }<br>
> + void writeDump(raw_ostream &OS) const {<br>
> + }<br>
> + void writeDumpChildren(raw_ostream &OS) const {<br>
> + OS << " if (SA->is" << getUpperName() << "Expr())\n";<br>
> + OS << " dumpStmt(SA->get" << getUpperName() << "Expr());\n";<br>
> + OS << " else\n";<br>
> + OS << " dumpType(SA->get" << getUpperName()<br>
> + << "Type()->getType());\n";<br>
> + }<br>
> };<br>
><br>
> class VariadicArgument : public Argument {<br>
> @@ -439,17 +476,30 @@<br>
> << " }\n";<br>
> OS << " OS << \"";<br>
> }<br>
> + void writeDump(raw_ostream &OS) const {<br>
> + OS << " for (" << getAttrName() << "Attr::" << getLowerName()<br>
> + << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"<br>
> + << getLowerName() << "_end(); I != E; ++I)\n";<br>
> + OS << " OS << \" \" << *I;\n";<br>
> + }<br>
> };<br>
><br>
> class EnumArgument : public Argument {<br>
> std::string type;<br>
> - std::vector<StringRef> values, enums;<br>
> + std::vector<StringRef> values, enums, uniques;<br>
> public:<br>
> EnumArgument(Record &Arg, StringRef Attr)<br>
> : Argument(Arg, Attr), type(Arg.getValueAsString("Type")),<br>
> values(getValueAsListOfStrings(Arg, "Values")),<br>
> - enums(getValueAsListOfStrings(Arg, "Enums"))<br>
> - {}<br>
> + enums(getValueAsListOfStrings(Arg, "Enums")),<br>
> + uniques(enums)<br>
> + {<br>
> + // Calculate the various enum values<br>
> + std::sort(uniques.begin(), uniques.end());<br>
> + uniques.erase(std::unique(uniques.begin(), uniques.end()), uniques.end());<br>
> + // FIXME: Emit a proper error<br>
> + assert(!uniques.empty());<br>
> + }<br>
><br>
> void writeAccessors(raw_ostream &OS) const {<br>
> OS << " " << type << " get" << getUpperName() << "() const {\n";<br>
> @@ -469,16 +519,8 @@<br>
> OS << type << " " << getUpperName();<br>
> }<br>
> void writeDeclarations(raw_ostream &OS) const {<br>
> - // Calculate the various enum values<br>
> - std::vector<StringRef> uniques(enums);<br>
> - std::sort(uniques.begin(), uniques.end());<br>
> - uniques.erase(std::unique(uniques.begin(), uniques.end()),<br>
> - uniques.end());<br>
> - // FIXME: Emit a proper error<br>
> - assert(!uniques.empty());<br>
> -<br>
> - std::vector<StringRef>::iterator i = uniques.begin(),<br>
> - e = uniques.end();<br>
> + std::vector<StringRef>::const_iterator i = uniques.begin(),<br>
> + e = uniques.end();<br>
> // The last one needs to not have a comma.<br>
> --e;<br>
><br>
> @@ -505,6 +547,21 @@<br>
> void writeValue(raw_ostream &OS) const {<br>
> OS << "\" << get" << getUpperName() << "() << \"";<br>
> }<br>
> + void writeDump(raw_ostream &OS) const {<br>
> + OS << " switch(SA->get" << getUpperName() << "()) {\n";<br>
> + OS << " default:\n";<br>
> + OS << " llvm_unreachable(\"Unknown " << getAttrName() << "Attr::"<br>
> + << type << "!\");\n";<br>
> + OS << " break;\n";<br>
> +<br>
> + for (std::vector<StringRef>::const_iterator I = uniques.begin(),<br>
> + E = uniques.end(); I != E; ++I) {<br>
> + OS << " case " << getAttrName() << "Attr::" << *I << ":\n";<br>
> + OS << " OS << \" " << *I << "\";\n";<br>
> + OS << " break;\n";<br>
> + }<br>
> + OS << " }\n";<br>
> + }<br>
> };<br>
><br>
> class VersionArgument : public Argument {<br>
> @@ -552,6 +609,9 @@<br>
> void writeValue(raw_ostream &OS) const {<br>
> OS << getLowerName() << "=\" << get" << getUpperName() << "() << \"";<br>
> }<br>
> + void writeDump(raw_ostream &OS) const {<br>
> + OS << " OS << \" \" << SA->get" << getUpperName() << "();\n";<br>
> + }<br>
> };<br>
><br>
> class ExprArgument : public SimpleArgument {<br>
> @@ -575,6 +635,13 @@<br>
> << "Result.takeAs<Expr>();\n";<br>
> OS << " }\n";<br>
> }<br>
> +<br>
> + void writeDump(raw_ostream &OS) const {<br>
> + }<br>
> +<br>
> + void writeDumpChildren(raw_ostream &OS) const {<br>
> + OS << " dumpStmt(SA->get" << getUpperName() << "());\n";<br>
> + }<br>
> };<br>
><br>
> class VariadicExprArgument : public VariadicArgument {<br>
> @@ -607,6 +674,16 @@<br>
> OS << " }\n";<br>
> OS << " }\n";<br>
> }<br>
> +<br>
> + void writeDump(raw_ostream &OS) const {<br>
> + }<br>
> +<br>
> + void writeDumpChildren(raw_ostream &OS) const {<br>
> + OS << " for (" << getAttrName() << "Attr::" << getLowerName()<br>
> + << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->"<br>
> + << getLowerName() << "_end(); I != E; ++I)\n";<br>
> + OS << " dumpStmt(*I);\n";<br>
> + }<br>
> };<br>
> }<br>
><br>
> @@ -1163,4 +1240,36 @@<br>
> << "}\n";<br>
> }<br>
><br>
> +// Emits the code to dump an attribute.<br>
> +void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) {<br>
> + OS <<<br>
> + " switch (A->getKind()) {\n"<br>
> + " default:\n"<br>
> + " llvm_unreachable(\"Unknown attribute kind!\");\n"<br>
> + " break;\n";<br>
> + std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr"), Args;<br>
> + for (std::vector<Record*>::iterator I = Attrs.begin(), E = Attrs.end();<br>
> + I != E; ++I) {<br>
> + Record &R = **I;<br>
> + if (!R.getValueAsBit("ASTNode"))<br>
> + continue;<br>
> + OS << " case attr::" << R.getName() << ": {\n";<br>
> + Args = R.getValueAsListOfDefs("Args");<br>
> + if (!Args.empty()) {<br>
> + OS << " const " << R.getName() << "Attr *SA = cast<" << R.getName()<br>
> + << "Attr>(A);\n";<br>
> + for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end();<br>
> + I != E; ++I)<br>
> + createArgument(**I, R.getName())->writeDump(OS);<br>
> + for (std::vector<Record*>::iterator I = Args.begin(), E = Args.end();<br>
> + I != E; ++I)<br>
> + createArgument(**I, R.getName())->writeDumpChildren(OS);<br>
> + }<br>
> + OS <<<br>
> + " break;\n"<br>
> + " }\n";<br>
> + }<br>
> + OS << " }\n";<br>
> +}<br>
> +<br>
> } // end namespace clang<br>
><br>
> Modified: cfe/trunk/utils/TableGen/TableGen.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGen.cpp?rev=171760&r1=171759&r2=171760&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGen.cpp?rev=171760&r1=171759&r2=171760&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/utils/TableGen/TableGen.cpp (original)<br>
> +++ cfe/trunk/utils/TableGen/TableGen.cpp Mon Jan 7 11:53:08 2013<br>
> @@ -33,6 +33,7 @@<br>
> GenClangAttrTemplateInstantiate,<br>
> GenClangAttrParsedAttrList,<br>
> GenClangAttrParsedAttrKinds,<br>
> + GenClangAttrDump,<br>
> GenClangDiagsDefs,<br>
> GenClangDiagGroups,<br>
> GenClangDiagsIndexName,<br>
> @@ -81,6 +82,8 @@<br>
> clEnumValN(GenClangAttrParsedAttrKinds,<br>
> "gen-clang-attr-parsed-attr-kinds",<br>
> "Generate a clang parsed attribute kinds"),<br>
> + clEnumValN(GenClangAttrDump, "gen-clang-attr-dump",<br>
> + "Generate clang attribute dumper"),<br>
> clEnumValN(GenClangDiagsDefs, "gen-clang-diags-defs",<br>
> "Generate Clang diagnostics definitions"),<br>
> clEnumValN(GenClangDiagGroups, "gen-clang-diag-groups",<br>
> @@ -153,6 +156,9 @@<br>
> case GenClangAttrParsedAttrKinds:<br>
> EmitClangAttrParsedAttrKinds(Records, OS);<br>
> break;<br>
> + case GenClangAttrDump:<br>
> + EmitClangAttrDump(Records, OS);<br>
> + break;<br>
> case GenClangDiagsDefs:<br>
> EmitClangDiagsDefs(Records, OS, ClangComponent);<br>
> break;<br>
><br>
> Modified: cfe/trunk/utils/TableGen/TableGenBackends.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGenBackends.h?rev=171760&r1=171759&r2=171760&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGenBackends.h?rev=171760&r1=171759&r2=171760&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/utils/TableGen/TableGenBackends.h (original)<br>
> +++ cfe/trunk/utils/TableGen/TableGenBackends.h Mon Jan 7 11:53:08 2013<br>
> @@ -39,6 +39,7 @@<br>
> void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS);<br>
> void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS);<br>
> void EmitClangAttrParsedAttrKinds(RecordKeeper &Records, raw_ostream &OS);<br>
> +void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS);<br>
><br>
> void EmitClangDiagsDefs(RecordKeeper &Records, raw_ostream &OS,<br>
> const std::string &Component);<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">-David<br></font></span></blockquote></div>
</div></div>