[cfe-commits] r171760 - in /cfe/trunk: include/clang/AST/CMakeLists.txt include/clang/AST/Makefile lib/AST/ASTDumper.cpp lib/AST/CMakeLists.txt test/Misc/ast-dump-attr.cpp test/Tooling/clang-check-ast-dump.cpp utils/TableGen/ClangAttrEmitter.cpp utils/TableGen/TableGen.cpp utils/TableGen/TableGenBackends.h

David Dean david_dean at apple.com
Mon Jan 7 14:38:07 PST 2013


I'm seeing the following test failure on darwin:

******************** TEST 'Clang :: Misc/ast-dump-attr.cpp' FAILED ********************Script:
--
/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
--
Exit Code: 1
Command Output (stderr):
--
/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
int TestString __attribute__((alias("alias1")));
                              ^
1 error generated.
/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
// CHECK-NEXT:   AliasAttr{{.*}} "alias1"
                 ^
<stdin>:84:180: note: scanning from here
(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')
                                                                                                                                                                                   ^
<stdin>:93:7: note: possible intended match here
  (AllocSizeAttr 0x10285afd0 <col:49, col:61> 0))
      ^
--

********************
On 7 Jan 2013, at 9:53 AM, Alexander Kornienko <alexfh at google.com> wrote:

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

-David





More information about the cfe-commits mailing list