[PATCH] D45456: [Attr] Print enum attributes at correct position

2018-04-24 Thread Joel E. Denny via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC330722: [Attr] Print enum attributes at correct position 
(authored by jdenny, committed by ).

Repository:
  rL LLVM

https://reviews.llvm.org/D45456

Files:
  lib/AST/DeclPrinter.cpp
  test/Sema/ast-print.c


Index: test/Sema/ast-print.c
===
--- test/Sema/ast-print.c
+++ test/Sema/ast-print.c
@@ -1,5 +1,12 @@
-// RUN: %clang_cc1 %s -ast-print | FileCheck %s
-// RUN: %clang_cc1 %s -ast-print | %clang_cc1 -fsyntax-only -
+// RUN: %clang_cc1 %s -ast-print -verify > %t.c
+// RUN: FileCheck %s --input-file %t.c
+//
+// RUN: echo >> %t.c "// expected""-warning@* {{use of GNU old-style field 
designator extension}}"
+// RUN: echo >> %t.c "// expected""-warning@* {{'EnumWithAttributes' is 
deprecated}}"
+// RUN: echo >> %t.c "// expected""-note@* {{'EnumWithAttributes' has been 
explicitly marked deprecated here}}"
+// RUN: echo >> %t.c "// expected""-warning@* {{'EnumWithAttributes3' is 
deprecated}}"
+// RUN: echo >> %t.c "// expected""-note@* {{'EnumWithAttributes3' has been 
explicitly marked deprecated here}}"
+// RUN: %clang_cc1 -fsyntax-only %t.c -verify
 
 typedef void func_typedef();
 func_typedef xxx;
@@ -58,7 +65,7 @@
 };
 
 // CHECK: struct pair_t p = {a: 3, .b = 4};
-struct pair_t p = {a: 3, .b = 4};
+struct pair_t p = {a: 3, .b = 4}; // expected-warning {{use of GNU old-style 
field designator extension}}
 
 void initializers() {
   // CHECK: int *x = ((void *)0), *y = ((void *)0);
@@ -70,11 +77,30 @@
   } z = {(struct Z){}};
 }
 
-// CHECK-LABEL: enum EnumWithAttributes {
-enum EnumWithAttributes {
+// CHECK-LABEL: enum __attribute__((deprecated(""))) EnumWithAttributes {
+enum EnumWithAttributes { // expected-warning {{'EnumWithAttributes' is 
deprecated}}
   // CHECK-NEXT: EnumWithAttributesFoo __attribute__((deprecated(""))),
   EnumWithAttributesFoo __attribute__((deprecated)),
   // CHECK-NEXT: EnumWithAttributesBar __attribute__((unavailable(""))) = 50
   EnumWithAttributesBar __attribute__((unavailable)) = 50
-  // CHECK-NEXT: } __attribute__((deprecated("")))
-} __attribute__((deprecated));
+  // CHECK-NEXT: };
+  // CHECK-NEXT: enum EnumWithAttributes *EnumWithAttributesPtr;
+} __attribute__((deprecated)) *EnumWithAttributesPtr; // expected-note 
{{'EnumWithAttributes' has been explicitly marked deprecated here}}
+
+// FIXME: If enum is forward-declared at file scope, attributes are lost.
+// CHECK-LABEL: enum EnumWithAttributes2 *EnumWithAttributes2Ptr;
+// expected-warning@+2 {{'EnumWithAttributes2' is deprecated}}
+// expected-note@+1 {{'EnumWithAttributes2' has been explicitly marked 
deprecated here}}
+enum __attribute__((deprecated)) EnumWithAttributes2 *EnumWithAttributes2Ptr;
+
+// CHECK-LABEL: EnumWithAttributes3Fn
+void EnumWithAttributes3Fn() {
+  // CHECK-NEXT: enum __attribute__((deprecated(""))) EnumWithAttributes3 
*EnumWithAttributes3Ptr;
+  // expected-warning@+2 {{'EnumWithAttributes3' is deprecated}}
+  // expected-note@+1 {{'EnumWithAttributes3' has been explicitly marked 
deprecated here}}
+  enum __attribute__((deprecated)) EnumWithAttributes3 *EnumWithAttributes3Ptr;
+  // Printing must not put the attribute after the tag where it would apply to
+  // the variable instead of the type, and then our deprecation warning would
+  // move to this use of the variable.
+  void *p = EnumWithAttributes3Ptr;
+}
Index: lib/AST/DeclPrinter.cpp
===
--- lib/AST/DeclPrinter.cpp
+++ lib/AST/DeclPrinter.cpp
@@ -496,14 +496,17 @@
 void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
   if (!Policy.SuppressSpecifiers && D->isModulePrivate())
 Out << "__module_private__ ";
-  Out << "enum ";
+  Out << "enum";
   if (D->isScoped()) {
 if (D->isScopedUsingClassTag())
-  Out << "class ";
+  Out << " class";
 else
-  Out << "struct ";
+  Out << " struct";
   }
-  Out << *D;
+
+  prettyPrintAttributes(D);
+
+  Out << ' ' << *D;
 
   if (D->isFixed() && D->getASTContext().getLangOpts().CPlusPlus11)
 Out << " : " << D->getIntegerType().stream(Policy);
@@ -513,7 +516,6 @@
 VisitDeclContext(D);
 Indent() << "}";
   }
-  prettyPrintAttributes(D);
 }
 
 void DeclPrinter::VisitRecordDecl(RecordDecl *D) {


Index: test/Sema/ast-print.c
===
--- test/Sema/ast-print.c
+++ test/Sema/ast-print.c
@@ -1,5 +1,12 @@
-// RUN: %clang_cc1 %s -ast-print | FileCheck %s
-// RUN: %clang_cc1 %s -ast-print | %clang_cc1 -fsyntax-only -
+// RUN: %clang_cc1 %s -ast-print -verify > %t.c
+// RUN: FileCheck %s --input-file %t.c
+//
+// RUN: echo >> %t.c "// expected""-warning@* {{use of GNU old-style field designator extension}}"
+// RUN: echo >> %t.c "// expected""-warning@* {{'EnumWithAttributes' is deprecated}}"
+// RUN: echo >> %t.c "// expected""-note@* {{'EnumWithAttributes' has been explicitly marked 

[PATCH] D45456: [Attr] Print enum attributes at correct position

2018-04-24 Thread Joel E. Denny via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL330722: [Attr] Print enum attributes at correct position 
(authored by jdenny, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D45456?vs=142672=143745#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D45456

Files:
  cfe/trunk/lib/AST/DeclPrinter.cpp
  cfe/trunk/test/Sema/ast-print.c


Index: cfe/trunk/lib/AST/DeclPrinter.cpp
===
--- cfe/trunk/lib/AST/DeclPrinter.cpp
+++ cfe/trunk/lib/AST/DeclPrinter.cpp
@@ -496,14 +496,17 @@
 void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
   if (!Policy.SuppressSpecifiers && D->isModulePrivate())
 Out << "__module_private__ ";
-  Out << "enum ";
+  Out << "enum";
   if (D->isScoped()) {
 if (D->isScopedUsingClassTag())
-  Out << "class ";
+  Out << " class";
 else
-  Out << "struct ";
+  Out << " struct";
   }
-  Out << *D;
+
+  prettyPrintAttributes(D);
+
+  Out << ' ' << *D;
 
   if (D->isFixed() && D->getASTContext().getLangOpts().CPlusPlus11)
 Out << " : " << D->getIntegerType().stream(Policy);
@@ -513,7 +516,6 @@
 VisitDeclContext(D);
 Indent() << "}";
   }
-  prettyPrintAttributes(D);
 }
 
 void DeclPrinter::VisitRecordDecl(RecordDecl *D) {
Index: cfe/trunk/test/Sema/ast-print.c
===
--- cfe/trunk/test/Sema/ast-print.c
+++ cfe/trunk/test/Sema/ast-print.c
@@ -1,5 +1,12 @@
-// RUN: %clang_cc1 %s -ast-print | FileCheck %s
-// RUN: %clang_cc1 %s -ast-print | %clang_cc1 -fsyntax-only -
+// RUN: %clang_cc1 %s -ast-print -verify > %t.c
+// RUN: FileCheck %s --input-file %t.c
+//
+// RUN: echo >> %t.c "// expected""-warning@* {{use of GNU old-style field 
designator extension}}"
+// RUN: echo >> %t.c "// expected""-warning@* {{'EnumWithAttributes' is 
deprecated}}"
+// RUN: echo >> %t.c "// expected""-note@* {{'EnumWithAttributes' has been 
explicitly marked deprecated here}}"
+// RUN: echo >> %t.c "// expected""-warning@* {{'EnumWithAttributes3' is 
deprecated}}"
+// RUN: echo >> %t.c "// expected""-note@* {{'EnumWithAttributes3' has been 
explicitly marked deprecated here}}"
+// RUN: %clang_cc1 -fsyntax-only %t.c -verify
 
 typedef void func_typedef();
 func_typedef xxx;
@@ -58,7 +65,7 @@
 };
 
 // CHECK: struct pair_t p = {a: 3, .b = 4};
-struct pair_t p = {a: 3, .b = 4};
+struct pair_t p = {a: 3, .b = 4}; // expected-warning {{use of GNU old-style 
field designator extension}}
 
 void initializers() {
   // CHECK: int *x = ((void *)0), *y = ((void *)0);
@@ -70,11 +77,30 @@
   } z = {(struct Z){}};
 }
 
-// CHECK-LABEL: enum EnumWithAttributes {
-enum EnumWithAttributes {
+// CHECK-LABEL: enum __attribute__((deprecated(""))) EnumWithAttributes {
+enum EnumWithAttributes { // expected-warning {{'EnumWithAttributes' is 
deprecated}}
   // CHECK-NEXT: EnumWithAttributesFoo __attribute__((deprecated(""))),
   EnumWithAttributesFoo __attribute__((deprecated)),
   // CHECK-NEXT: EnumWithAttributesBar __attribute__((unavailable(""))) = 50
   EnumWithAttributesBar __attribute__((unavailable)) = 50
-  // CHECK-NEXT: } __attribute__((deprecated("")))
-} __attribute__((deprecated));
+  // CHECK-NEXT: };
+  // CHECK-NEXT: enum EnumWithAttributes *EnumWithAttributesPtr;
+} __attribute__((deprecated)) *EnumWithAttributesPtr; // expected-note 
{{'EnumWithAttributes' has been explicitly marked deprecated here}}
+
+// FIXME: If enum is forward-declared at file scope, attributes are lost.
+// CHECK-LABEL: enum EnumWithAttributes2 *EnumWithAttributes2Ptr;
+// expected-warning@+2 {{'EnumWithAttributes2' is deprecated}}
+// expected-note@+1 {{'EnumWithAttributes2' has been explicitly marked 
deprecated here}}
+enum __attribute__((deprecated)) EnumWithAttributes2 *EnumWithAttributes2Ptr;
+
+// CHECK-LABEL: EnumWithAttributes3Fn
+void EnumWithAttributes3Fn() {
+  // CHECK-NEXT: enum __attribute__((deprecated(""))) EnumWithAttributes3 
*EnumWithAttributes3Ptr;
+  // expected-warning@+2 {{'EnumWithAttributes3' is deprecated}}
+  // expected-note@+1 {{'EnumWithAttributes3' has been explicitly marked 
deprecated here}}
+  enum __attribute__((deprecated)) EnumWithAttributes3 *EnumWithAttributes3Ptr;
+  // Printing must not put the attribute after the tag where it would apply to
+  // the variable instead of the type, and then our deprecation warning would
+  // move to this use of the variable.
+  void *p = EnumWithAttributes3Ptr;
+}


Index: cfe/trunk/lib/AST/DeclPrinter.cpp
===
--- cfe/trunk/lib/AST/DeclPrinter.cpp
+++ cfe/trunk/lib/AST/DeclPrinter.cpp
@@ -496,14 +496,17 @@
 void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
   if (!Policy.SuppressSpecifiers && D->isModulePrivate())
 Out << "__module_private__ ";
-  Out << "enum ";
+  Out << "enum";
   if (D->isScoped()) {
 if (D->isScopedUsingClassTag())
-   

[PATCH] D45456: [Attr] Print enum attributes at correct position

2018-04-24 Thread Joel E. Denny via Phabricator via cfe-commits
jdenny added a comment.

Thanks.


https://reviews.llvm.org/D45456



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45456: [Attr] Print enum attributes at correct position

2018-04-23 Thread Joel E. Denny via Phabricator via cfe-commits
jdenny added a comment.

Ping.

In case it's not clear: this patch doesn't depend on other patches, but others 
depend on it.


https://reviews.llvm.org/D45456



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45456: [Attr] Print enum attributes at correct position

2018-04-16 Thread Joel E. Denny via Phabricator via cfe-commits
jdenny updated this revision to Diff 142672.
jdenny edited the summary of this revision.
jdenny added a comment.

Rebased onto a more recent master.

Added example to summary.


https://reviews.llvm.org/D45456

Files:
  lib/AST/DeclPrinter.cpp
  test/Sema/ast-print.c


Index: test/Sema/ast-print.c
===
--- test/Sema/ast-print.c
+++ test/Sema/ast-print.c
@@ -1,5 +1,12 @@
-// RUN: %clang_cc1 %s -ast-print | FileCheck %s
-// RUN: %clang_cc1 %s -ast-print | %clang_cc1 -fsyntax-only -
+// RUN: %clang_cc1 %s -ast-print -verify > %t.c
+// RUN: FileCheck %s --input-file %t.c
+//
+// RUN: echo >> %t.c "// expected""-warning@* {{use of GNU old-style field 
designator extension}}"
+// RUN: echo >> %t.c "// expected""-warning@* {{'EnumWithAttributes' is 
deprecated}}"
+// RUN: echo >> %t.c "// expected""-note@* {{'EnumWithAttributes' has been 
explicitly marked deprecated here}}"
+// RUN: echo >> %t.c "// expected""-warning@* {{'EnumWithAttributes3' is 
deprecated}}"
+// RUN: echo >> %t.c "// expected""-note@* {{'EnumWithAttributes3' has been 
explicitly marked deprecated here}}"
+// RUN: %clang_cc1 -fsyntax-only %t.c -verify
 
 typedef void func_typedef();
 func_typedef xxx;
@@ -58,7 +65,7 @@
 };
 
 // CHECK: struct pair_t p = {a: 3, .b = 4};
-struct pair_t p = {a: 3, .b = 4};
+struct pair_t p = {a: 3, .b = 4}; // expected-warning {{use of GNU old-style 
field designator extension}}
 
 void initializers() {
   // CHECK: int *x = ((void *)0), *y = ((void *)0);
@@ -70,11 +77,30 @@
   } z = {(struct Z){}};
 }
 
-// CHECK-LABEL: enum EnumWithAttributes {
-enum EnumWithAttributes {
+// CHECK-LABEL: enum __attribute__((deprecated(""))) EnumWithAttributes {
+enum EnumWithAttributes { // expected-warning {{'EnumWithAttributes' is 
deprecated}}
   // CHECK-NEXT: EnumWithAttributesFoo __attribute__((deprecated(""))),
   EnumWithAttributesFoo __attribute__((deprecated)),
   // CHECK-NEXT: EnumWithAttributesBar __attribute__((unavailable(""))) = 50
   EnumWithAttributesBar __attribute__((unavailable)) = 50
-  // CHECK-NEXT: } __attribute__((deprecated("")))
-} __attribute__((deprecated));
+  // CHECK-NEXT: };
+  // CHECK-NEXT: enum EnumWithAttributes *EnumWithAttributesPtr;
+} __attribute__((deprecated)) *EnumWithAttributesPtr; // expected-note 
{{'EnumWithAttributes' has been explicitly marked deprecated here}}
+
+// FIXME: If enum is forward-declared at file scope, attributes are lost.
+// CHECK-LABEL: enum EnumWithAttributes2 *EnumWithAttributes2Ptr;
+// expected-warning@+2 {{'EnumWithAttributes2' is deprecated}}
+// expected-note@+1 {{'EnumWithAttributes2' has been explicitly marked 
deprecated here}}
+enum __attribute__((deprecated)) EnumWithAttributes2 *EnumWithAttributes2Ptr;
+
+// CHECK-LABEL: EnumWithAttributes3Fn
+void EnumWithAttributes3Fn() {
+  // CHECK-NEXT: enum __attribute__((deprecated(""))) EnumWithAttributes3 
*EnumWithAttributes3Ptr;
+  // expected-warning@+2 {{'EnumWithAttributes3' is deprecated}}
+  // expected-note@+1 {{'EnumWithAttributes3' has been explicitly marked 
deprecated here}}
+  enum __attribute__((deprecated)) EnumWithAttributes3 *EnumWithAttributes3Ptr;
+  // Printing must not put the attribute after the tag where it would apply to
+  // the variable instead of the type, and then our deprecation warning would
+  // move to this use of the variable.
+  void *p = EnumWithAttributes3Ptr;
+}
Index: lib/AST/DeclPrinter.cpp
===
--- lib/AST/DeclPrinter.cpp
+++ lib/AST/DeclPrinter.cpp
@@ -496,14 +496,17 @@
 void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
   if (!Policy.SuppressSpecifiers && D->isModulePrivate())
 Out << "__module_private__ ";
-  Out << "enum ";
+  Out << "enum";
   if (D->isScoped()) {
 if (D->isScopedUsingClassTag())
-  Out << "class ";
+  Out << " class";
 else
-  Out << "struct ";
+  Out << " struct";
   }
-  Out << *D;
+
+  prettyPrintAttributes(D);
+
+  Out << ' ' << *D;
 
   if (D->isFixed() && D->getASTContext().getLangOpts().CPlusPlus11)
 Out << " : " << D->getIntegerType().stream(Policy);
@@ -513,7 +516,6 @@
 VisitDeclContext(D);
 Indent() << "}";
   }
-  prettyPrintAttributes(D);
 }
 
 void DeclPrinter::VisitRecordDecl(RecordDecl *D) {


Index: test/Sema/ast-print.c
===
--- test/Sema/ast-print.c
+++ test/Sema/ast-print.c
@@ -1,5 +1,12 @@
-// RUN: %clang_cc1 %s -ast-print | FileCheck %s
-// RUN: %clang_cc1 %s -ast-print | %clang_cc1 -fsyntax-only -
+// RUN: %clang_cc1 %s -ast-print -verify > %t.c
+// RUN: FileCheck %s --input-file %t.c
+//
+// RUN: echo >> %t.c "// expected""-warning@* {{use of GNU old-style field designator extension}}"
+// RUN: echo >> %t.c "// expected""-warning@* {{'EnumWithAttributes' is deprecated}}"
+// RUN: echo >> %t.c "// expected""-note@* {{'EnumWithAttributes' has been explicitly marked deprecated here}}"
+// RUN: echo 

[PATCH] D45456: [Attr] Print enum attributes at correct position

2018-04-09 Thread Joel E. Denny via Phabricator via cfe-commits
jdenny created this revision.
jdenny added reviewers: aaron.ballman, hfinkel.

In enum declarations, enum attributes were always printed after the
tag and any member list.  When no member list was present but the enum
was a type specifier in a variable declaration, the attribute then
applied to the variable not the enum, changing the semantics.

This patch fixes that by always printing attributes between the enum's
keyword and tag, as clang already does for structs, unions, and
classes.


https://reviews.llvm.org/D45456

Files:
  lib/AST/DeclPrinter.cpp
  test/Sema/ast-print.c


Index: test/Sema/ast-print.c
===
--- test/Sema/ast-print.c
+++ test/Sema/ast-print.c
@@ -1,5 +1,12 @@
-// RUN: %clang_cc1 %s -ast-print | FileCheck %s
-// RUN: %clang_cc1 %s -ast-print | %clang_cc1 -fsyntax-only -
+// RUN: %clang_cc1 %s -ast-print -verify > %t.c
+// RUN: FileCheck %s --input-file %t.c
+//
+// RUN: echo >> %t.c "// expected""-warning@* {{use of GNU old-style field 
designator extension}}"
+// RUN: echo >> %t.c "// expected""-warning@* {{'EnumWithAttributes' is 
deprecated}}"
+// RUN: echo >> %t.c "// expected""-note@* {{'EnumWithAttributes' has been 
explicitly marked deprecated here}}"
+// RUN: echo >> %t.c "// expected""-warning@* {{'EnumWithAttributes3' is 
deprecated}}"
+// RUN: echo >> %t.c "// expected""-note@* {{'EnumWithAttributes3' has been 
explicitly marked deprecated here}}"
+// RUN: %clang_cc1 -fsyntax-only %t.c -verify
 
 typedef void func_typedef();
 func_typedef xxx;
@@ -58,7 +65,7 @@
 };
 
 // CHECK: struct pair_t p = {a: 3, .b = 4};
-struct pair_t p = {a: 3, .b = 4};
+struct pair_t p = {a: 3, .b = 4}; // expected-warning {{use of GNU old-style 
field designator extension}}
 
 void initializers() {
   // CHECK: int *x = ((void *)0), *y = ((void *)0);
@@ -70,11 +77,30 @@
   } z = {(struct Z){}};
 }
 
-// CHECK-LABEL: enum EnumWithAttributes {
-enum EnumWithAttributes {
+// CHECK-LABEL: enum __attribute__((deprecated(""))) EnumWithAttributes {
+enum EnumWithAttributes { // expected-warning {{'EnumWithAttributes' is 
deprecated}}
   // CHECK-NEXT: EnumWithAttributesFoo __attribute__((deprecated(""))),
   EnumWithAttributesFoo __attribute__((deprecated)),
   // CHECK-NEXT: EnumWithAttributesBar __attribute__((unavailable(""))) = 50
   EnumWithAttributesBar __attribute__((unavailable)) = 50
-  // CHECK-NEXT: } __attribute__((deprecated("")))
-} __attribute__((deprecated));
+  // CHECK-NEXT: };
+  // CHECK-NEXT: enum EnumWithAttributes *EnumWithAttributesPtr;
+} __attribute__((deprecated)) *EnumWithAttributesPtr; // expected-note 
{{'EnumWithAttributes' has been explicitly marked deprecated here}}
+
+// FIXME: If enum is forward-declared at file scope, attributes are lost.
+// CHECK-LABEL: enum EnumWithAttributes2 *EnumWithAttributes2Ptr;
+// expected-warning@+2 {{'EnumWithAttributes2' is deprecated}}
+// expected-note@+1 {{'EnumWithAttributes2' has been explicitly marked 
deprecated here}}
+enum __attribute__((deprecated)) EnumWithAttributes2 *EnumWithAttributes2Ptr;
+
+// CHECK-LABEL: EnumWithAttributes3Fn
+void EnumWithAttributes3Fn() {
+  // CHECK-NEXT: enum __attribute__((deprecated(""))) EnumWithAttributes3 
*EnumWithAttributes3Ptr;
+  // expected-warning@+2 {{'EnumWithAttributes3' is deprecated}}
+  // expected-note@+1 {{'EnumWithAttributes3' has been explicitly marked 
deprecated here}}
+  enum __attribute__((deprecated)) EnumWithAttributes3 *EnumWithAttributes3Ptr;
+  // Printing must not put the attribute after the tag where it would apply to
+  // the variable instead of the type, and then our deprecation warning would
+  // move to this use of the variable.
+  void *p = EnumWithAttributes3Ptr;
+}
Index: lib/AST/DeclPrinter.cpp
===
--- lib/AST/DeclPrinter.cpp
+++ lib/AST/DeclPrinter.cpp
@@ -496,14 +496,17 @@
 void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
   if (!Policy.SuppressSpecifiers && D->isModulePrivate())
 Out << "__module_private__ ";
-  Out << "enum ";
+  Out << "enum";
   if (D->isScoped()) {
 if (D->isScopedUsingClassTag())
-  Out << "class ";
+  Out << " class";
 else
-  Out << "struct ";
+  Out << " struct";
   }
-  Out << *D;
+
+  prettyPrintAttributes(D);
+
+  Out << ' ' << *D;
 
   if (D->isFixed() && D->getASTContext().getLangOpts().CPlusPlus11)
 Out << " : " << D->getIntegerType().stream(Policy);
@@ -513,7 +516,6 @@
 VisitDeclContext(D);
 Indent() << "}";
   }
-  prettyPrintAttributes(D);
 }
 
 void DeclPrinter::VisitRecordDecl(RecordDecl *D) {


Index: test/Sema/ast-print.c
===
--- test/Sema/ast-print.c
+++ test/Sema/ast-print.c
@@ -1,5 +1,12 @@
-// RUN: %clang_cc1 %s -ast-print | FileCheck %s
-// RUN: %clang_cc1 %s -ast-print | %clang_cc1 -fsyntax-only -
+// RUN: %clang_cc1 %s -ast-print -verify > %t.c
+// RUN: FileCheck %s --input-file %t.c
+//