diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -49,6 +49,17 @@ void PrintObjCTypeParams(ObjCTypeParamList *Params); + enum AttrPrintLoc { + None = 0, + Left = 1, + Middle = 2, + Right = 4, + Any = Left | Middle | Right, + }; + + void prettyPrintAttributes(Decl *D, raw_ostream &out, + AttrPrintLoc loc = AttrPrintLoc::Any); + public: DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy, const ASTContext &Context, unsigned Indentation = 0, @@ -117,7 +128,11 @@ const TemplateParameterList *Params); void printTemplateArguments(llvm::ArrayRef Args, const TemplateParameterList *Params); - void prettyPrintAttributes(Decl *D); + + inline void prettyPrintAttributes(Decl *D) { + prettyPrintAttributes(D, Out); + } + void prettyPrintPragmas(Decl *D); void printDeclType(QualType T, StringRef DeclName, bool Pack = false); }; @@ -234,7 +249,8 @@ return Out; } -void DeclPrinter::prettyPrintAttributes(Decl *D) { +void DeclPrinter::prettyPrintAttributes(Decl *D, llvm::raw_ostream &Out, + AttrPrintLoc Loc) { if (Policy.PolishForDeclaration) return; @@ -243,14 +259,43 @@ for (auto *A : Attrs) { if (A->isInherited() || A->isImplicit()) continue; - switch (A->getKind()) { -#define ATTR(X) -#define PRAGMA_SPELLING_ATTR(X) case attr::X: -#include "clang/Basic/AttrList.inc" - break; - default: + + // We will try to classify the attr::Kind into three disjoint sets: + // 1- should be print on the left side of a decl. + // 2- should be print on the middle of a decl right after the type. + // 3- should be print on the right side of a decl. + AttrPrintLoc attrloc = AttrPrintLoc::Right; // We default to right. + attr::Kind kind = A->getKind(); + + // FIXME: Find a way to use the AttrList.inc. We use if-else statements + // to classify each of them. + if (A->isStandardAttributeSyntax()) { + // C++11 onwards attributes can not be placed on left side. Output on + // right to mimic old clang behaviour. + attrloc = AttrPrintLoc::Right; + } else if (kind == attr::AsmLabel) { + // AsmLabels can not be placed on the middle nor left. + attrloc = AttrPrintLoc::Right; + } else if (kind == attr::DiagnoseIf || kind == attr::EnableIf) { + // DiagnoseIf should be print on the right side because it may refer to + // a variable that is declared as a parameter. + // FIXME: There are other attributes in which this is possible. + // Either parse the attribute to find if such variable is + // referenced or extend this to all these attributes. + attrloc = AttrPrintLoc::Right; + } else if (A->isDeclspecAttribute()) { + // Microsoft's __declspec should be print on the left side. + attrloc = AttrPrintLoc::Left; + } else if (const FunctionDecl *FD = dyn_cast(D); + FD && FD->isThisDeclarationADefinition()) { + // In case Decl is a function with a body, then attrs should be print + // on the left side. + attrloc = AttrPrintLoc::Left; + } + + // Only print the side matches the user requested. + if ((Loc & attrloc) != AttrPrintLoc::None) { A->printPretty(Out, Policy); - break; } } } @@ -603,6 +648,22 @@ printTemplateParameters(D->getTemplateParameterList(I)); } + std::string LeftsideAttrs; + llvm::raw_string_ostream LSAS(LeftsideAttrs); + + prettyPrintAttributes(D, LSAS, AttrPrintLoc::Left); + + // prettyPrintAttributes print a space on left side of the attribute. + if (LeftsideAttrs[0] == ' ') { + // Skip the space prettyPrintAttributes generated. + LeftsideAttrs.erase(0, LeftsideAttrs.find_first_not_of(' ')); + + // Add a single space between the attribute and the Decl name. + LSAS << ' '; + } + + Out << LeftsideAttrs; + CXXConstructorDecl *CDecl = dyn_cast(D); CXXConversionDecl *ConversionDecl = dyn_cast(D); CXXDeductionGuideDecl *GuideDecl = dyn_cast(D); @@ -762,7 +823,7 @@ Ty.print(Out, Policy, Proto); } - prettyPrintAttributes(D); + prettyPrintAttributes(D, Out, Right); if (D->isPure()) Out << " = 0"; @@ -855,6 +916,23 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) { prettyPrintPragmas(D); + std::string Declspec; + llvm::raw_string_ostream DeclspecStream(Declspec); + + // Print attributes that should be placed on the left, such as __declspec. + prettyPrintAttributes(D, DeclspecStream, AttrPrintLoc::Left); + + // prettyPrintAttributes print a space on left side of the attribute. + if (Declspec[0] == ' ') { + // Skip the space prettyPrintAttributes generated. + Declspec.erase(0, Declspec.find_first_not_of(' ')); + + // Add a single space between the attribute and the Decl name. + DeclspecStream << ' '; + } + + Out << Declspec; + QualType T = D->getTypeSourceInfo() ? D->getTypeSourceInfo()->getType() : D->getASTContext().getUnqualifiedObjCPointerType(D->getType()); @@ -887,10 +965,19 @@ } } - printDeclType(T, (isa(D) && Policy.CleanUglifiedParameters && - D->getIdentifier()) - ? D->getIdentifier()->deuglifiedName() - : D->getName()); + std::string Name; + + Name += (isa(D) && Policy.CleanUglifiedParameters && + D->getIdentifier()) + ? D->getIdentifier()->deuglifiedName().str() + : D->getName().str(); + + printDeclType(T, StringRef(Name)); + + // Print the attributes that should be placed right before the end of the + // decl. + prettyPrintAttributes(D, Out, Right); + Expr *Init = D->getInit(); if (!Policy.SuppressInitializers && Init) { bool ImplicitInit = false; @@ -919,7 +1006,6 @@ Out << ")"; } } - prettyPrintAttributes(D); } void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) { diff --git a/clang/test/AST/ast-print-attr-knr.c b/clang/test/AST/ast-print-attr-knr.c new file mode 100644 --- /dev/null +++ b/clang/test/AST/ast-print-attr-knr.c @@ -0,0 +1,17 @@ +// This file contain tests for attribute arguments on K&R functions. + +// RUN: %clang_cc1 -ast-print -x c -std=c89 -fms-extensions %s -o - | FileCheck %s + +// CHECK: int knr(i) +// CHECK-NEXT: int i __attribute__((unused)); +// CHECK-NEXT: { +// CHECK-NEXT: return 0; +// CHECK-NEXT: } +int knr(i) int i __attribute__((unused)); { return 0; } + +// CHECK: __attribute__((unused)) int knr2(i) +// CHECK-NEXT: int i; +// CHECK-NEXT: { +// CHECK-NEXT: return 0; +// CHECK-NEXT: } +__attribute__((unused)) int knr2(i) int i; { return 0; } diff --git a/clang/test/AST/ast-print-attr.c b/clang/test/AST/ast-print-attr.c --- a/clang/test/AST/ast-print-attr.c +++ b/clang/test/AST/ast-print-attr.c @@ -32,3 +32,9 @@ // CHECK: void fun_holds(int *a) __attribute__((ownership_holds(fun_holds, 1))); void fun_holds(int *a) __attribute__((ownership_holds(fun_holds, 1))); + +// CHECK: int fun_var_unused() { +// CHECK-NEXT: int x __attribute__((unused)) = 0; +// CHECK-NEXT: return x; +// CHECK-NEXT: } +int fun_var_unused() { int x __attribute__((unused)) = 0; return x; } diff --git a/clang/test/AST/ast-print-pragmas.cpp b/clang/test/AST/ast-print-pragmas.cpp --- a/clang/test/AST/ast-print-pragmas.cpp +++ b/clang/test/AST/ast-print-pragmas.cpp @@ -93,7 +93,7 @@ #ifdef MS_EXT #pragma init_seg(compiler) // MS-EXT: #pragma init_seg (.CRT$XCC){{$}} -// MS-EXT-NEXT: int x = 3 __declspec(thread); -int __declspec(thread) x = 3; +// MS-EXT-NEXT: __declspec(thread) int x = 3; +__declspec(thread) int x = 3; #endif //MS_EXT diff --git a/clang/test/Analysis/blocks.mm b/clang/test/Analysis/blocks.mm --- a/clang/test/Analysis/blocks.mm +++ b/clang/test/Analysis/blocks.mm @@ -78,7 +78,7 @@ // CHECK-NEXT: 1: 5 // WARNINGS-NEXT: 2: [B1.1] (CXXConstructExpr, StructWithCopyConstructor) // ANALYZER-NEXT: 2: [B1.1] (CXXConstructExpr, [B1.3], StructWithCopyConstructor) -// CHECK-NEXT: 3: StructWithCopyConstructor s(5) __attribute__((blocks("byref"))); +// CHECK-NEXT: 3: StructWithCopyConstructor s __attribute__((blocks("byref")))(5); // CHECK-NEXT: 4: ^{ } // CHECK-NEXT: 5: (void)([B1.4]) (CStyleCastExpr, ToVoid, void) // CHECK-NEXT: Preds (1): B2 diff --git a/clang/test/OpenMP/assumes_codegen.cpp b/clang/test/OpenMP/assumes_codegen.cpp --- a/clang/test/OpenMP/assumes_codegen.cpp +++ b/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: __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void 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: __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"))) void 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: __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"))) static void 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: __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"))) void 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: template class BAZ { // 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"))) { +// 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() { // 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: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void 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: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) static void baz2() { // AST-NEXT: } // AST-NEXT: }; // AST-NEXT: template<> class BAZ { // 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: }; -// 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: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void baz() { // AST-NEXT: BAZ 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: __attribute__((assume("ompx_lambda_assumption"))) __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) int lambda_outer() { // AST-NEXT: auto lambda_inner = []() { // AST-NEXT: return 42; // AST-NEXT: }; diff --git a/clang/test/OpenMP/assumes_print.cpp b/clang/test/OpenMP/assumes_print.cpp --- a/clang/test/OpenMP/assumes_print.cpp +++ b/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: __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) void foo() +// CHECK: __attribute__((assume("ompx_range_bar_only"))) __attribute__((assume("ompx_range_bar_only_2"))) __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) void bar() +// CHECK: __attribute__((assume("ompx_1234"))) __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) void baz() #endif diff --git a/clang/test/OpenMP/assumes_template_print.cpp b/clang/test/OpenMP/assumes_template_print.cpp --- a/clang/test/OpenMP/assumes_template_print.cpp +++ b/clang/test/OpenMP/assumes_template_print.cpp @@ -17,7 +17,7 @@ struct S { int a; // CHECK: template struct S { -// CHECK: void foo() __attribute__((assume("ompx_global_assumption"))) { +// CHECK: __attribute__((assume("ompx_global_assumption"))) void foo() { void foo() { #pragma omp parallel {} @@ -25,15 +25,15 @@ }; // CHECK: template<> struct S { -// CHECK: void foo() __attribute__((assume("ompx_global_assumption"))) { +// CHECK: __attribute__((assume("ompx_global_assumption"))) void 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: __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) void S_with_assumes_no_call() { void S_with_assumes_no_call() { S s; s.a = 0; } -// CHECK: void S_with_assumes_call() __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) { +// CHECK: __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) void S_with_assumes_call() { void S_with_assumes_call() { S s; s.a = 0; @@ -42,7 +42,7 @@ } #pragma omp end assumes -// CHECK: void S_without_assumes() __attribute__((assume("ompx_global_assumption"))) { +// CHECK: __attribute__((assume("ompx_global_assumption"))) void S_without_assumes() { void S_without_assumes() { S s; s.foo(); @@ -54,7 +54,7 @@ template struct P { // CHECK: template struct P { -// CHECK: void foo() __attribute__((assume("ompx_global_assumption"))) { +// CHECK: __attribute__((assume("ompx_global_assumption"))) void foo() { int a; void foo() { #pragma omp parallel @@ -65,21 +65,21 @@ // TODO: Avoid the duplication here: // CHECK: template<> struct P { -// CHECK: void foo() __attribute__((assume("ompx_global_assumption"))) __attribute__((assume("ompx_global_assumption"))) { +// CHECK: __attribute__((assume("ompx_global_assumption"))) __attribute__((assume("ompx_global_assumption"))) void foo() { -// CHECK: void P_without_assumes() __attribute__((assume("ompx_global_assumption"))) { +// CHECK: __attribute__((assume("ompx_global_assumption"))) void P_without_assumes() { void P_without_assumes() { P 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: __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) void P_with_assumes_no_call() { void P_with_assumes_no_call() { P p; p.a = 0; } -// CHECK: void P_with_assumes_call() __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) { +// CHECK: __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) void P_with_assumes_call() { void P_with_assumes_call() { P p; p.a = 0; diff --git a/clang/test/OpenMP/declare_simd_ast_print.cpp b/clang/test/OpenMP/declare_simd_ast_print.cpp --- a/clang/test/OpenMP/declare_simd_ast_print.cpp +++ b/clang/test/OpenMP/declare_simd_ast_print.cpp @@ -60,11 +60,11 @@ 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: __attribute__((cold)) int add(int a, int b) { // CHECK-NEXT: return a + b; // CHECK-NEXT: } #pragma omp declare simd uniform(this, a) linear(val(b): a) - int add(int a, int b) __attribute__((cold)) { return a + b; } + __attribute__((cold)) int add(int a, int b) { return a + b; } // CHECK: #pragma omp declare simd aligned(b: 4) aligned(a) linear(ref(b): 4) linear(val(this)) linear(val(a)) // CHECK-NEXT: float taddpf(float *a, float *&b) { diff --git a/clang/test/Sema/attr-print.c b/clang/test/Sema/attr-print.c --- a/clang/test/Sema/attr-print.c +++ b/clang/test/Sema/attr-print.c @@ -3,8 +3,7 @@ // CHECK: int x __attribute__((aligned(4))); int x __attribute__((aligned(4))); -// FIXME: Print this at a valid location for a __declspec attr. -// CHECK: int y __declspec(align(4)); +// CHECK: __declspec(align(4)) int y; __declspec(align(4)) int y; // CHECK: short arr[3] __attribute__((aligned)); diff --git a/clang/test/SemaCXX/attr-print.cpp b/clang/test/SemaCXX/attr-print.cpp --- a/clang/test/SemaCXX/attr-print.cpp +++ b/clang/test/SemaCXX/attr-print.cpp @@ -3,8 +3,7 @@ // CHECK: int x __attribute__((aligned(4))); int x __attribute__((aligned(4))); -// FIXME: Print this at a valid location for a __declspec attr. -// CHECK: int y __declspec(align(4)); +// CHECK: __declspec(align(4)) int y; __declspec(align(4)) int y; // CHECK: void foo() __attribute__((const)); diff --git a/clang/test/SemaCXX/cxx11-attr-print.cpp b/clang/test/SemaCXX/cxx11-attr-print.cpp --- a/clang/test/SemaCXX/cxx11-attr-print.cpp +++ b/clang/test/SemaCXX/cxx11-attr-print.cpp @@ -3,8 +3,7 @@ // CHECK: int x __attribute__((aligned(4))); int x __attribute__((aligned(4))); -// FIXME: Print this at a valid location for a __declspec attr. -// CHECK: int y __declspec(align(4)); +// CHECK: __declspec(align(4)) int y; __declspec(align(4)) int y; // CHECK: int z {{\[}}[gnu::aligned(4)]]; @@ -65,7 +64,7 @@ // CHECK: int m __attribute__((aligned(4 // CHECK: int n alignas(4 -// CHECK: static int f() __attribute__((pure)) +// CHECK: __attribute__((pure)) static int f() // CHECK: static int g() {{\[}}[gnu::pure]] template struct S { __attribute__((aligned(4))) int m; @@ -80,7 +79,7 @@ // CHECK: int m __attribute__((aligned(4 // CHECK: int n alignas(4 -// CHECK: static int f() __attribute__((pure)) +// CHECK: __attribute__((pure)) static int f() // CHECK: static int g() {{\[}}[gnu::pure]] template struct S;