giulianobelinassi created this revision.
Herald added a project: All.
giulianobelinassi requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added subscribers: cfe-commits, sstefan1.
Herald added a project: clang.

GCC rejects the following kind of dumps:

int f(void) __attribute__((unused))
{

  return 0;

}

because of the following reason: Assume the function is K&R declared:

int f(i) __attribute__((unused))

  int i;

{

  return 0;

}

Now, to which symbol should the __attribute__((unused)) be applied?
Depending of the parsing strategy, this will be either applied to
f or i, but likely this will be applied to f as the compiler parses
from left-to-right.

GCC, therefore, rejects this kind of declarations altogether. Clang
even warns that such declarations won't be accepted by GCC. Since
an user may be using clang dumps as a library to do static analysis
and outputing code that will be fed into GCC, then instead of dumping:

int f(void) __attribute__((unused));

this patch modifies such cases to output to:

int __attribute__((unused)) f(void);

causing GCC to also accept such dumps.

Signed-off-by: Giuliano Belinassi <gbelina...@suse.de>

Depends on: D141714 <https://reviews.llvm.org/D141714>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145269

Files:
  clang/lib/AST/DeclPrinter.cpp
  clang/test/AST/ast-print-attr-knr.c
  clang/test/AST/ast-print-attr.c
  clang/test/AST/ast-print-no-sanitize.cpp
  clang/test/AST/attr-print-emit.cpp
  clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
  clang/test/OpenMP/assumes_codegen.cpp
  clang/test/OpenMP/assumes_print.cpp
  clang/test/OpenMP/assumes_template_print.cpp
  clang/test/OpenMP/declare_simd_ast_print.c
  clang/test/OpenMP/declare_simd_ast_print.cpp
  clang/test/Sema/attr-print.c
  clang/test/SemaCXX/attr-no-sanitize.cpp
  clang/test/SemaCXX/attr-print.cpp
  clang/test/SemaCXX/cxx11-attr-print.cpp

Index: clang/test/SemaCXX/cxx11-attr-print.cpp
===================================================================
--- clang/test/SemaCXX/cxx11-attr-print.cpp
+++ clang/test/SemaCXX/cxx11-attr-print.cpp
@@ -30,16 +30,16 @@
 // CHECK: int c11_alignas _Alignas(alignof(int));
 _Alignas(int) int c11_alignas;
 
-// CHECK: void foo() __attribute__((const));
+// CHECK: void __attribute__((const)) foo();
 void foo() __attribute__((const));
 
-// CHECK: void bar() __attribute__((__const));
-void bar() __attribute__((__const));
+// CHECK: void __attribute__((__const)) bar();
+void __attribute__((__const)) bar();
 
 // FIXME: It's unfortunate that the string literal prints with the below three
 // cases given that the string is only exposed via the [[nodiscard]] spelling.
-// CHECK: int f1() __attribute__((warn_unused_result("")));
-int f1() __attribute__((warn_unused_result));
+// CHECK: int __attribute__((warn_unused_result(""))) f1();
+int __attribute__((warn_unused_result)) f1();
 
 // CHECK: {{\[}}[clang::warn_unused_result("")]];
 int f2 [[clang::warn_unused_result]] ();
@@ -52,24 +52,24 @@
 // CHECK: {{\[}}[noreturn]];
 void f4 [[noreturn]] ();
 
-// CHECK: __attribute__((gnu_inline));
-inline void f6() __attribute__((gnu_inline));
+// CHECK: void __attribute__((gnu_inline))
+inline void __attribute__((gnu_inline)) f6();
 
 // CHECK: {{\[}}[gnu::gnu_inline]];
 inline void f7 [[gnu::gnu_inline]] ();
 
 // arguments printing
-// CHECK: __attribute__((format(printf, 2, 3)));
-void f8 (void *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
+// CHECK: void __attribute__((format(printf, 2, 3)))
+void __attribute__ ((format (printf, 2, 3))) f8 (void *, const char *, ...);
 
 // CHECK: int m __attribute__((aligned(4)))
 // CHECK: int n alignas(4
-// CHECK: static int f() __attribute__((pure))
+// CHECK: static int __attribute__((pure)) f()
 // CHECK: static int g() {{\[}}[gnu::pure]]
 template <typename T> struct S {
   int __attribute__((aligned(4))) m;
   alignas(4) int n;
-  __attribute__((pure)) static int f() {
+  static int __attribute__((pure)) f() {
     return 0;
   }
   [[gnu::pure]] static int g() {
@@ -79,7 +79,7 @@
 
 // CHECK: int m __attribute__((aligned(4)))
 // CHECK: int n alignas(4
-// CHECK: static int f() __attribute__((pure))
+// CHECK: static int __attribute__((pure)) f()
 // CHECK: static int g() {{\[}}[gnu::pure]]
 template struct S<int>;
 
Index: clang/test/SemaCXX/attr-print.cpp
===================================================================
--- clang/test/SemaCXX/attr-print.cpp
+++ clang/test/SemaCXX/attr-print.cpp
@@ -7,14 +7,14 @@
 // CHECK: int __declspec(align(4)) y;
 int __declspec(align(4)) y;
 
-// CHECK: void foo() __attribute__((const));
+// CHECK: void __attribute__((const)) foo();
 void foo() __attribute__((const));
 
-// CHECK: void bar() __attribute__((__const));
+// CHECK: void __attribute__((__const)) bar();
 void bar() __attribute__((__const));
 
 // FIXME: Print this with correct format.
-// CHECK: void foo1() __attribute__((noinline)) __attribute__((pure));
+// CHECK: void __attribute__((noinline)) __attribute__((pure)) foo1();
 void foo1() __attribute__((noinline, pure));
 
 // CHECK: typedef int Small1 __attribute__((mode(byte)));
@@ -26,12 +26,12 @@
 // CHECK: int __attribute__((visibility("hidden"))) v;
 int __attribute__((visibility("hidden"))) v;
 
-// CHECK: char *PR24565() __attribute__((malloc))
+// CHECK: char *__attribute__((malloc)) PR24565()
 char *PR24565() __attribute__((__malloc__));
 
 // CHECK: class __attribute__((consumable("unknown"))) AttrTester1
 class __attribute__((consumable(unknown))) AttrTester1 {
-  // CHECK: void callableWhen() __attribute__((callable_when("unconsumed", "consumed")));
+  // CHECK: void __attribute__((callable_when("unconsumed", "consumed"))) callableWhen();
   void callableWhen()  __attribute__((callable_when("unconsumed", "consumed")));
 };
 
Index: clang/test/SemaCXX/attr-no-sanitize.cpp
===================================================================
--- clang/test/SemaCXX/attr-no-sanitize.cpp
+++ clang/test/SemaCXX/attr-no-sanitize.cpp
@@ -11,7 +11,7 @@
 
 // DUMP-LABEL: FunctionDecl {{.*}} f3
 // DUMP: NoSanitizeAttr {{.*}} address
-// PRINT: int f3() __attribute__((no_sanitize("address")))
+// PRINT: int __attribute__((no_sanitize("address"))) f3()
 int f3() __attribute__((no_sanitize("address")));
 
 // DUMP-LABEL: FunctionDecl {{.*}} f4
@@ -26,12 +26,12 @@
 
 // DUMP-LABEL: FunctionDecl {{.*}} f5
 // DUMP: NoSanitizeAttr {{.*}} address thread hwaddress
-// PRINT: int f5() __attribute__((no_sanitize("address", "thread", "hwaddress")))
+// PRINT: int __attribute__((no_sanitize("address", "thread", "hwaddress"))) f5()
 int f5() __attribute__((no_sanitize("address", "thread", "hwaddress")));
 
 // DUMP-LABEL: FunctionDecl {{.*}} f6
 // DUMP: NoSanitizeAttr {{.*}} unknown
-// PRINT: int f6() __attribute__((no_sanitize("unknown")))
+// PRINT: int __attribute__((no_sanitize("unknown"))) f6()
 int f6() __attribute__((no_sanitize("unknown"))); // expected-warning{{unknown sanitizer 'unknown' ignored}}
 
 // DUMP-LABEL: FunctionDecl {{.*}} f7
Index: clang/test/Sema/attr-print.c
===================================================================
--- clang/test/Sema/attr-print.c
+++ clang/test/Sema/attr-print.c
@@ -10,10 +10,10 @@
 // CHECK: short __attribute__((aligned)) arr[3];
 short __attribute__((aligned)) arr[3];
 
-// CHECK: void foo(void) __attribute__((const));
+// CHECK: void __attribute__((const)) foo(void);
 void foo(void) __attribute__((const));
 
-// CHECK: void bar(void) __attribute__((__const));
+// CHECK: void __attribute__((__const)) bar(void);
 void bar(void) __attribute__((__const));
 
 // CHECK: int * __ptr32 p32;
@@ -34,5 +34,5 @@
 // CHECK: int * __sptr * __ptr32 ppsp32;
 int * __sptr * __ptr32 ppsp32;
 
-// CHECK: __attribute__((availability(macos, strict, introduced=10.6)));
+// CHECK: void __attribute__((availability(macos, strict, introduced=10.6))) f6(int);
 void f6(int) __attribute__((availability(macosx,strict,introduced=10.6)));
Index: clang/test/OpenMP/declare_simd_ast_print.cpp
===================================================================
--- clang/test/OpenMP/declare_simd_ast_print.cpp
+++ clang/test/OpenMP/declare_simd_ast_print.cpp
@@ -13,12 +13,12 @@
 #pragma omp declare simd linear(d: 8)
 #pragma omp declare simd inbranch simdlen(32)
 #pragma omp declare simd notinbranch
-void add_1(float *d) __attribute__((cold));
+void __attribute__((cold)) add_1(float *d);
 
 // CHECK: #pragma omp declare simd notinbranch
 // CHECK-NEXT: #pragma omp declare simd inbranch simdlen(32)
 // CHECK-NEXT: #pragma omp declare simd linear(val(d): 8)
-// CHECK-NEXT: void add_1(float *d) __attribute__((cold));
+// CHECK-NEXT: void __attribute__((cold)) add_1(float *d);
 //
 
 #pragma omp declare simd aligned(hp, hp2:V)
@@ -60,7 +60,7 @@
 
 class VV {
   // CHECK: #pragma omp declare simd uniform(this, a) linear(val(b): a)
-  // CHECK-NEXT: int add(int a, int b) __attribute__((cold))    {
+  // CHECK-NEXT: int __attribute__((cold)) add(int a, int b)     {
   // CHECK-NEXT: return a + b;
   // CHECK-NEXT: }
   #pragma omp declare simd uniform(this, a) linear(val(b): a)
Index: clang/test/OpenMP/declare_simd_ast_print.c
===================================================================
--- clang/test/OpenMP/declare_simd_ast_print.c
+++ clang/test/OpenMP/declare_simd_ast_print.c
@@ -14,12 +14,12 @@
 #pragma omp declare simd simdlen(32) aligned(d, b)
 #pragma omp declare simd inbranch, uniform(d) linear(val(s1, s2) : 32)
 #pragma omp declare simd notinbranch simdlen(2), uniform(s1, s2) linear(d: s1)
-void add_1(float *d, int s1, float *s2, double b[]) __attribute__((cold));
+void __attribute__((cold)) add_1(float *d, int s1, float *s2, double b[]);
 
 // CHECK: #pragma omp declare simd notinbranch simdlen(2) uniform(s1, s2) linear(val(d): s1){{$}}
 // CHECK-NEXT: #pragma omp declare simd inbranch uniform(d) linear(val(s1): 32) linear(val(s2): 32){{$}}
 // CHECK-NEXT: #pragma omp declare simd simdlen(32) aligned(d) aligned(b){{$}}
 // CHECK-NEXT: #pragma omp declare simd aligned(b: 64){{$}}
-// CHECK-NEXT: void add_1(float *d, int s1, float *s2, double b[]) __attribute__((cold))
+// CHECK-NEXT: void __attribute__((cold)) add_1(float *d, int s1, float *s2, double b[])
 
 #endif
Index: clang/test/OpenMP/assumes_template_print.cpp
===================================================================
--- clang/test/OpenMP/assumes_template_print.cpp
+++ clang/test/OpenMP/assumes_template_print.cpp
@@ -17,7 +17,7 @@
 struct S {
   int a;
 // CHECK: template <typename T> struct S {
-// CHECK:     void foo() __attribute__((assume("ompx_global_assumption")))     {
+// CHECK:     void __attribute__((assume("ompx_global_assumption"))) foo()     {
   void foo() {
     #pragma omp parallel
     {}
@@ -25,15 +25,15 @@
 };
 
 // CHECK: template<> struct S<int> {
-// CHECK:     void foo() __attribute__((assume("ompx_global_assumption")))     {
+// CHECK:     void __attribute__((assume("ompx_global_assumption"))) foo()     {
 
 #pragma omp begin assumes no_openmp
-// CHECK: void S_with_assumes_no_call() __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) {
+// CHECK: void __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) S_with_assumes_no_call() {
 void S_with_assumes_no_call() {
   S<int> s;
   s.a = 0;
 }
-// CHECK: void S_with_assumes_call() __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) {
+// CHECK: void __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) S_with_assumes_call() {
 void S_with_assumes_call() {
   S<int> s;
   s.a = 0;
@@ -42,7 +42,7 @@
 }
 #pragma omp end assumes
 
-// CHECK: void S_without_assumes() __attribute__((assume("ompx_global_assumption"))) {
+// CHECK: void __attribute__((assume("ompx_global_assumption"))) S_without_assumes() {
 void S_without_assumes() {
   S<int> s;
   s.foo();
@@ -54,7 +54,7 @@
 template <typename T>
 struct P {
 // CHECK: template <typename T> struct P {
-// CHECK:     void foo() __attribute__((assume("ompx_global_assumption")))     {
+// CHECK:     void __attribute__((assume("ompx_global_assumption"))) foo()      {
   int a;
   void foo() {
     #pragma omp parallel
@@ -65,21 +65,21 @@
 // TODO: Avoid the duplication here:
 
 // CHECK: template<> struct P<int> {
-// CHECK:     void foo() __attribute__((assume("ompx_global_assumption"))) __attribute__((assume("ompx_global_assumption")))     {
+// CHECK:     void __attribute__((assume("ompx_global_assumption"))) __attribute__((assume("ompx_global_assumption"))) foo()   {
 
-// CHECK: void P_without_assumes() __attribute__((assume("ompx_global_assumption"))) {
+// CHECK: void  __attribute__((assume("ompx_global_assumption"))) P_without_assumes() {
 void P_without_assumes() {
   P<int> p;
   p.foo();
 }
 
 #pragma omp begin assumes no_openmp
-// CHECK: void P_with_assumes_no_call() __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) {
+// CHECK: void __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) P_with_assumes_no_call() {
 void P_with_assumes_no_call() {
   P<int> p;
   p.a = 0;
 }
-// CHECK: void P_with_assumes_call() __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) {
+// CHECK: void __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) P_with_assumes_call() {
 void P_with_assumes_call() {
   P<int> p;
   p.a = 0;
Index: clang/test/OpenMP/assumes_print.cpp
===================================================================
--- clang/test/OpenMP/assumes_print.cpp
+++ clang/test/OpenMP/assumes_print.cpp
@@ -37,8 +37,8 @@
 }
 #pragma omp end assumes
 
-// CHECK: void foo() __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp")))
-// CHECK: void bar() __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp")))
-// CHECK: void baz() __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp")))
+// CHECK: void __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) foo()
+// CHECK: void __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) bar()
+// CHECK: void __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) baz()
 
 #endif
Index: clang/test/OpenMP/assumes_codegen.cpp
===================================================================
--- clang/test/OpenMP/assumes_codegen.cpp
+++ clang/test/OpenMP/assumes_codegen.cpp
@@ -67,41 +67,41 @@
 }
 #pragma omp end assumes
 
-// AST:      void foo() __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) {
+// AST:      void __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) foo() {
 // AST-NEXT: }
 // AST-NEXT: class BAR {
 // AST-NEXT: public:
-// AST-NEXT:     BAR() __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")))     {
+// AST-NEXT:     __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) BAR()      {
 // AST-NEXT:     }
-// AST-NEXT:     void bar1() __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")))     {
+// AST-NEXT:     void __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) bar1()     {
 // AST-NEXT:     }
-// AST-NEXT:     static void bar2() __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")))     {
+// AST-NEXT:     static void __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) bar2()      {
 // AST-NEXT:     }
 // AST-NEXT: };
-// AST-NEXT: void bar() __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) {
+// AST-NEXT: void __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) bar() {
 // AST-NEXT:     BAR b;
 // AST-NEXT: }
-// AST-NEXT: void baz() __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")));
+// AST-NEXT: void __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) baz();
 // AST-NEXT: template <typename T> class BAZ {
 // AST-NEXT: public:
-// AST-NEXT:     BAZ<T>() __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")))     {
+// AST-NEXT:     __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) BAZ<T>()      {
 // AST-NEXT:     }
-// AST-NEXT:     void baz1() __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")))     {
+// AST-NEXT:     void __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")))  baz1()     {
 // AST-NEXT:     }
-// AST-NEXT:     static void baz2() __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")))     {
+// AST-NEXT:     static void __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) baz2()      {
 // AST-NEXT:     }
 // AST-NEXT: };
 // AST-NEXT: template<> class BAZ<float> {
 // AST-NEXT: public:
-// AST-NEXT:     BAZ() __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")))    {
+// AST-NEXT:     __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")))  BAZ()    {
 // AST-NEXT:     }
-// AST-NEXT:     void baz1() __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")));
-// AST-NEXT:     static void baz2() __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp")));
+// AST-NEXT:     void __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) baz1();
+// AST-NEXT:     static void __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) baz2();
 // AST-NEXT: };
-// AST-NEXT: void baz() __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) {
+// AST-NEXT: void __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) baz() {
 // AST-NEXT:     BAZ<float> b;
 // AST-NEXT: }
-// AST-NEXT: int lambda_outer() __attribute__((assume("ompx_lambda_assumption"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) {
+// AST-NEXT: int __attribute__((assume("ompx_lambda_assumption"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) lambda_outer() {
 // AST-NEXT:     auto lambda_inner = []() {
 // AST-NEXT:         return 42;
 // AST-NEXT:     };
Index: clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
===================================================================
--- clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
+++ clang/test/Analysis/std-c-library-functions-arg-weakdeps.c
@@ -21,7 +21,7 @@
 // RUN:   -triple x86_64-unknown-linux 2>&1 | FileCheck %s
 
 // CHECK: Loaded summary for: int isalnum(int)
-// CHECK: Loaded summary for: unsigned long fread(void *restrict, size_t, size_t, FILE *restrict) __attribute__((nonnull(1)))
+// CHECK: Loaded summary for: unsigned long __attribute__((nonnull(1))) fread(void *restrict, size_t, size_t, FILE *restrict)
 // CHECK: Loaded summary for: int fileno(FILE *stream)
 
 void initializeSummaryMap(void);
@@ -40,7 +40,7 @@
 typedef struct FILE FILE;
 
 int isalnum(int);
-size_t fread(void *restrict, size_t, size_t, FILE *restrict) __attribute__((nonnull(1)));
+size_t __attribute__((nonnull(1))) fread(void *restrict, size_t, size_t, FILE *restrict);
 int fileno(FILE *stream);
 
 void test_uninit_arg(void) {
Index: clang/test/AST/attr-print-emit.cpp
===================================================================
--- clang/test/AST/attr-print-emit.cpp
+++ clang/test/AST/attr-print-emit.cpp
@@ -2,68 +2,68 @@
 // RUN: %clang -emit-ast -o %t.ast %s
 // RUN: %clang_cc1 %t.ast -ast-print | FileCheck %s
 
-// CHECK: void xla(int a) __attribute__((xray_log_args(1)));
+// CHECK: void __attribute__((xray_log_args(1))) xla(int a);
 void xla(int a) __attribute__((xray_log_args(1)));
 
-// CHECK: void *as2(int, int) __attribute__((alloc_size(1, 2)));
+// CHECK: void *__attribute__((alloc_size(1, 2))) as2(int, int);
 void *as2(int, int) __attribute__((alloc_size(1, 2)));
-// CHECK: void *as1(void *, int) __attribute__((alloc_size(2)));
+// CHECK: void *__attribute__((alloc_size(2))) as1(void *, int);
 void *as1(void *, int) __attribute__((alloc_size(2)));
 
-// CHECK: void fmt(int, const char *, ...) __attribute__((format(printf, 2, 3)));
+// CHECK: void __attribute__((format(printf, 2, 3))) fmt(int, const char *, ...);
 void fmt(int, const char *, ...) __attribute__((format(printf, 2, 3)));
 
-// CHECK: char *fmta(int, const char *) __attribute__((format_arg(2)));
+// CHECK: char *__attribute__((format_arg(2))) fmta(int, const char *);
 char *fmta(int, const char *) __attribute__((format_arg(2)));
 
-// CHECK: void nn(int *, int *) __attribute__((nonnull(1, 2)));
+// CHECK: void __attribute__((nonnull(1, 2))) nn(int *, int *);
 void nn(int *, int *) __attribute__((nonnull(1, 2)));
 
-// CHECK: int *aa(int i) __attribute__((alloc_align(1)));
+// CHECK: int *__attribute__((alloc_align(1))) aa(int i);
 int *aa(int i) __attribute__((alloc_align(1)));
 
-// CHECK: void ownt(int *, int *) __attribute__((ownership_takes(foo, 1, 2)));
+// CHECK: void __attribute__((ownership_takes(foo, 1, 2))) ownt(int *, int *);
 void ownt(int *, int *) __attribute__((ownership_takes(foo, 1, 2)));
-// CHECK: void ownh(int *, int *) __attribute__((ownership_holds(foo, 1, 2)));
+// CHECK: void __attribute__((ownership_holds(foo, 1, 2))) ownh(int *, int *);
 void ownh(int *, int *) __attribute__((ownership_holds(foo, 1, 2)));
-// CHECK: void ownr(int) __attribute__((ownership_returns(foo, 1)));
+// CHECK: void __attribute__((ownership_returns(foo, 1))) ownr(int);
 void ownr(int) __attribute__((ownership_returns(foo, 1)));
 
-// CHECK: void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 3, 2)));
+// CHECK: void __attribute__((argument_with_type_tag(foo, 3, 2))) awtt(int, int, ...);
 void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 3, 2)));
-// CHECK: void pwtt(void *, int) __attribute__((pointer_with_type_tag(foo, 1, 2)));
+// CHECK: void __attribute__((pointer_with_type_tag(foo, 1, 2))) pwtt(void *, int);
 void pwtt(void *, int) __attribute__((pointer_with_type_tag(foo, 1, 2)));
 
 class C {
-  // CHECK: void xla(int a) __attribute__((xray_log_args(2)));
+  // CHECK: void __attribute__((xray_log_args(2))) xla(int a);
   void xla(int a) __attribute__((xray_log_args(2)));
 
-  // CHECK: void *as2(int, int) __attribute__((alloc_size(2, 3)));
+  // CHECK: void *__attribute__((alloc_size(2, 3))) as2(int, int);
   void *as2(int, int) __attribute__((alloc_size(2, 3)));
-  // CHECK: void *as1(void *, int) __attribute__((alloc_size(3)));
+  // CHECK: void *__attribute__((alloc_size(3))) as1(void *, int);
   void *as1(void *, int) __attribute__((alloc_size(3)));
 
-  // CHECK: void fmt(int, const char *, ...) __attribute__((format(printf, 3, 4)));
+  // CHECK: void __attribute__((format(printf, 3, 4))) fmt(int, const char *, ...);
   void fmt(int, const char *, ...) __attribute__((format(printf, 3, 4)));
 
-  // CHECK: char *fmta(int, const char *) __attribute__((format_arg(3)));
+  // CHECK: char *__attribute__((format_arg(3))) fmta(int, const char *);
   char *fmta(int, const char *) __attribute__((format_arg(3)));
 
-  // CHECK: void nn(int *, int *) __attribute__((nonnull(2, 3)));
+  // CHECK: void __attribute__((nonnull(2, 3))) nn(int *, int *);
   void nn(int *, int *) __attribute__((nonnull(2, 3)));
 
-  // CHECK: int *aa(int i) __attribute__((alloc_align(2)));
+  // CHECK: int *__attribute__((alloc_align(2))) aa(int i);
   int *aa(int i) __attribute__((alloc_align(2)));
 
-  // CHECK: void ownt(int *, int *) __attribute__((ownership_takes(foo, 2, 3)));
+  // CHECK: void __attribute__((ownership_takes(foo, 2, 3))) ownt(int *, int *);
   void ownt(int *, int *) __attribute__((ownership_takes(foo, 2, 3)));
-  // CHECK: void ownh(int *, int *) __attribute__((ownership_holds(foo, 2, 3)));
+  // CHECK: void __attribute__((ownership_holds(foo, 2, 3))) ownh(int *, int *);
   void ownh(int *, int *) __attribute__((ownership_holds(foo, 2, 3)));
-  // CHECK: void ownr(int) __attribute__((ownership_returns(foo, 2)));
+  // CHECK: void __attribute__((ownership_returns(foo, 2))) ownr(int);
   void ownr(int) __attribute__((ownership_returns(foo, 2)));
 
-  // CHECK: void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 4, 3)));
+  // CHECK: void __attribute__((argument_with_type_tag(foo, 4, 3))) awtt(int, int, ...);
   void awtt(int, int, ...) __attribute__((argument_with_type_tag(foo, 4, 3)));
-  // CHECK: void pwtt(void *, int) __attribute__((pointer_with_type_tag(foo, 2, 3)));
+  // CHECK: void __attribute__((pointer_with_type_tag(foo, 2, 3))) pwtt(void *, int);
   void pwtt(void *, int) __attribute__((pointer_with_type_tag(foo, 2, 3)));
 };
Index: clang/test/AST/ast-print-no-sanitize.cpp
===================================================================
--- clang/test/AST/ast-print-no-sanitize.cpp
+++ clang/test/AST/ast-print-no-sanitize.cpp
@@ -3,5 +3,5 @@
 void should_not_crash_1() __attribute__((no_sanitize_memory));
 [[clang::no_sanitize_memory]] void should_not_crash_2();
 
-// CHECK: void should_not_crash_1() __attribute__((no_sanitize("memory")));
+// CHECK: void __attribute__((no_sanitize("memory"))) should_not_crash_1();
 // CHECK: void should_not_crash_2() {{\[\[}}clang::no_sanitize("memory"){{\]\]}};
Index: clang/test/AST/ast-print-attr.c
===================================================================
--- clang/test/AST/ast-print-attr.c
+++ clang/test/AST/ast-print-attr.c
@@ -27,11 +27,11 @@
   MyErrSecond,
 };
 
-// CHECK: int *fun_returns() __attribute__((ownership_returns(fun_returns)));
-int *fun_returns() __attribute__((ownership_returns(fun_returns)));
+// CHECK: int *__attribute__((ownership_returns(fun_returns))) fun_returns();
+int *__attribute__((ownership_returns(fun_returns))) fun_returns();
 
-// CHECK: void fun_holds(int *a) __attribute__((ownership_holds(fun_holds, 1)));
-void fun_holds(int *a) __attribute__((ownership_holds(fun_holds, 1)));
+// CHECK: void __attribute__((ownership_holds(fun_holds, 1))) fun_holds(int *a);
+void __attribute__((ownership_holds(fun_holds, 1))) fun_holds(int *a);
 
 // CHECK: int fun_var_unused() {
 // CHECK-NEXT: int __attribute__((unused)) x = 0;
Index: clang/test/AST/ast-print-attr-knr.c
===================================================================
--- clang/test/AST/ast-print-attr-knr.c
+++ clang/test/AST/ast-print-attr-knr.c
@@ -8,3 +8,10 @@
 // CHECK-NEXT: return 0;
 // CHECK-NEXT: }
 int knr(i) int __attribute__((unused)) i; { return 0; }
+
+// CHECK: int __attribute__((unused)) knr2(i)
+// CHECK-NEXT: int i;
+// CHECK-NEXT: {
+// CHECK-NEXT: return 0;
+// CHECK-NEXT: }
+int __attribute__((unused)) knr2(i) int i; { return 0; }
Index: clang/lib/AST/DeclPrinter.cpp
===================================================================
--- clang/lib/AST/DeclPrinter.cpp
+++ clang/lib/AST/DeclPrinter.cpp
@@ -661,10 +661,21 @@
   SubPolicy.SuppressSpecifiers = false;
   std::string Proto;
 
+  llvm::raw_string_ostream OS(Proto);
+  prettyPrintAttributes(D, OS, SIDE_MIDDLE);
+
+  // prettyPrintAttributes print a space on left side of the attribute.
+  if (Proto[0] == ' ') {
+    // Skip the space prettyPrintAttributes generated.
+    Proto.erase(0, Proto.find_first_not_of(' '));
+
+    // Add a single space between the attribute and the Decl name.
+    OS << ' ';
+  }
+
   if (Policy.FullyQualifiedName) {
     Proto += D->getQualifiedNameAsString();
   } else {
-    llvm::raw_string_ostream OS(Proto);
     if (!Policy.SuppressScope) {
       if (const NestedNameSpecifier *NS = D->getQualifier()) {
         NS->print(OS, Policy);
@@ -792,7 +803,7 @@
     Ty.print(Out, Policy, Proto);
   }
 
-  prettyPrintAttributes(D);
+  prettyPrintAttributes(D, Out, SIDE_RIGHT);
 
   if (D->isPure())
     Out << " = 0";
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to