diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 6584460cf5685..dc87a8c6f022d 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -324,13 +324,10 @@ class Spelling { } class GNU : Spelling; -class Declspec : Spelling { - bit PrintOnLeft = 1; -} +class Declspec : Spelling; class Microsoft : Spelling; class CXX11 : Spelling { - bit CanPrintOnLeft = 0; string Namespace = namespace; } class C23 @@ -596,12 +593,6 @@ class AttrSubjectMatcherAggregateRule { def SubjectMatcherForNamed : AttrSubjectMatcherAggregateRule; class Attr { - // Specifies that when printed, this attribute is meaningful on the - // 'left side' of the declaration. - bit CanPrintOnLeft = 1; - // Specifies that when printed, this attribute is required to be printed on - // the 'left side' of the declaration. - bit PrintOnLeft = 0; // The various ways in which an attribute can be spelled in source list Spellings; // The things to which an attribute can appertain @@ -937,7 +928,6 @@ def AVRSignal : InheritableAttr, TargetSpecificAttr { } def AsmLabel : InheritableAttr { - let CanPrintOnLeft = 0; let Spellings = [CustomKeyword<"asm">, CustomKeyword<"__asm__">]; let Args = [ // Label specifies the mangled name for the decl. @@ -1534,7 +1524,6 @@ def AllocSize : InheritableAttr { } def EnableIf : InheritableAttr { - let CanPrintOnLeft = 0; // Does not have a [[]] spelling because this attribute requires the ability // to parse function arguments but the attribute is not written in the type // position. @@ -3171,7 +3160,6 @@ def Unavailable : InheritableAttr { } def DiagnoseIf : InheritableAttr { - let CanPrintOnLeft = 0; // Does not have a [[]] spelling because this attribute requires the ability // to parse function arguments but the attribute is not written in the type // position. diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 7d53c751c13ac..2ef6ddc68f4bf 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -31,16 +31,6 @@ clang_tablegen(AttrList.inc -gen-clang-attr-list SOURCE Attr.td TARGET ClangAttrList) -clang_tablegen(AttrLeftSideCanPrintList.inc -gen-clang-attr-can-print-left-list - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ - SOURCE Attr.td - TARGET ClangAttrCanPrintLeftList) - -clang_tablegen(AttrLeftSideMustPrintList.inc -gen-clang-attr-must-print-left-list - -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ - SOURCE Attr.td - TARGET ClangAttrMustPrintLeftList) - clang_tablegen(AttrSubMatchRulesList.inc -gen-clang-attr-subject-match-rule-list -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ SOURCE Attr.td diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index edbcdfe4d55bc..0d03288a491ab 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -21,6 +21,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/PrettyPrinter.h" #include "clang/Basic/Module.h" +#include "clang/Basic/SourceManager.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -49,18 +50,6 @@ namespace { void PrintObjCTypeParams(ObjCTypeParamList *Params); - enum class AttrPrintLoc { - None = 0, - Left = 1, - Right = 2, - Any = Left | Right, - - LLVM_MARK_AS_BITMASK_ENUM(/*DefaultValue=*/Any) - }; - - 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, @@ -129,11 +118,10 @@ namespace { const TemplateParameterList *Params); void printTemplateArguments(llvm::ArrayRef Args, const TemplateParameterList *Params); - - inline void prettyPrintAttributes(Decl *D) { - prettyPrintAttributes(D, Out); - } - + enum class AttrPosAsWritten { Unknown = 0, Default, Left, Right }; + void + prettyPrintAttributes(const Decl *D, + AttrPosAsWritten Pos = AttrPosAsWritten::Default); void prettyPrintPragmas(Decl *D); void printDeclType(QualType T, StringRef DeclName, bool Pack = false); }; @@ -250,87 +238,53 @@ raw_ostream& DeclPrinter::Indent(unsigned Indentation) { return Out; } -// For CLANG_ATTR_LIST_CanPrintOnLeft macro. -#include "clang/Basic/AttrLeftSideCanPrintList.inc" +static DeclPrinter::AttrPosAsWritten getPosAsWritten(const Attr *A, + const Decl *D) { + SourceLocation ALoc = A->getLoc(); + SourceLocation DLoc = D->getLocation(); + const ASTContext &C = D->getASTContext(); + if (ALoc.isInvalid() || DLoc.isInvalid()) + return DeclPrinter::AttrPosAsWritten::Unknown; -// For CLANG_ATTR_LIST_PrintOnLeft macro. -#include "clang/Basic/AttrLeftSideMustPrintList.inc" + if (C.getSourceManager().isBeforeInTranslationUnit(ALoc, DLoc)) + return DeclPrinter::AttrPosAsWritten::Left; -static bool canPrintOnLeftSide(attr::Kind kind) { -#ifdef CLANG_ATTR_LIST_CanPrintOnLeft - switch (kind) { - CLANG_ATTR_LIST_CanPrintOnLeft - return true; - default: - return false; - } -#else - return false; -#endif -} - -static bool canPrintOnLeftSide(const Attr *A) { - if (A->isStandardAttributeSyntax()) - return false; - - return canPrintOnLeftSide(A->getKind()); + return DeclPrinter::AttrPosAsWritten::Right; } -static bool mustPrintOnLeftSide(attr::Kind kind) { -#ifdef CLANG_ATTR_LIST_PrintOnLeft - switch (kind) { - CLANG_ATTR_LIST_PrintOnLeft - return true; - default: - return false; - } -#else - return false; -#endif -} - -static bool mustPrintOnLeftSide(const Attr *A) { - if (A->isDeclspecAttribute()) - return true; - - return mustPrintOnLeftSide(A->getKind()); -} - -void DeclPrinter::prettyPrintAttributes(Decl *D, llvm::raw_ostream &Out, - AttrPrintLoc Loc) { +void DeclPrinter::prettyPrintAttributes(const Decl *D, + AttrPosAsWritten Pos /*=Default*/) { if (Policy.PolishForDeclaration) return; if (D->hasAttrs()) { - AttrVec &Attrs = D->getAttrs(); + assert(Pos != AttrPosAsWritten::Unknown && "Use Default"); + const AttrVec &Attrs = D->getAttrs(); for (auto *A : Attrs) { if (A->isInherited() || A->isImplicit()) continue; - - AttrPrintLoc AttrLoc = AttrPrintLoc::Right; - if (mustPrintOnLeftSide(A)) { - // If we must always print on left side (e.g. declspec), then mark as - // so. - AttrLoc = AttrPrintLoc::Left; - } else if (canPrintOnLeftSide(A)) { - // For functions with body defined we print the attributes on the left - // side so that GCC accept our dumps as well. - 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; - - // In case it is a variable declaration with a ctor, then allow - // printing on the left side for readbility. - else if (const VarDecl *VD = dyn_cast(D); - VD && VD->getInit() && - VD->getInitStyle() == VarDecl::CallInit) - AttrLoc = AttrPrintLoc::Left; + switch (A->getKind()) { +#define ATTR(X) +#define PRAGMA_SPELLING_ATTR(X) case attr::X: +#include "clang/Basic/AttrList.inc" + break; + default: + AttrPosAsWritten APos = getPosAsWritten(A, D); + // Might trigger on programatically created attributes or declarations + // with no source locations. + assert(APos != AttrPosAsWritten::Unknown && + "Invalid source location for attribute or decl."); + assert(APos != AttrPosAsWritten::Default && + "Default not a valid for an attribute location"); + if (Pos == AttrPosAsWritten::Default || Pos == APos) { + if (Pos != AttrPosAsWritten::Left) + Out << ' '; + A->printPretty(Out, Policy); + if (Pos == AttrPosAsWritten::Left) + Out << ' '; + } + break; } - // Only print the side matches the user requested. - if ((Loc & AttrLoc) != AttrPrintLoc::None) - A->printPretty(Out, Policy); } } } @@ -691,8 +645,10 @@ static void MaybePrintTagKeywordIfSupressingScopes(PrintingPolicy &Policy, void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { if (!D->getDescribedFunctionTemplate() && - !D->isFunctionTemplateSpecialization()) + !D->isFunctionTemplateSpecialization()) { prettyPrintPragmas(D); + prettyPrintAttributes(D, AttrPosAsWritten::Left); + } if (D->isFunctionTemplateSpecialization()) Out << "template<> "; @@ -702,22 +658,6 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { 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); @@ -883,7 +823,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { Ty.print(Out, Policy, Proto); } - prettyPrintAttributes(D, Out, AttrPrintLoc::Right); + prettyPrintAttributes(D, AttrPosAsWritten::Right); if (D->isPureVirtual()) Out << " = 0"; @@ -976,27 +916,12 @@ void DeclPrinter::VisitLabelDecl(LabelDecl *D) { void DeclPrinter::VisitVarDecl(VarDecl *D) { prettyPrintPragmas(D); + prettyPrintAttributes(D, AttrPosAsWritten::Left); + if (const auto *Param = dyn_cast(D); Param && Param->isExplicitObjectParameter()) Out << "this "; - std::string LeftSide; - llvm::raw_string_ostream LeftSideStream(LeftSide); - - // Print attributes that should be placed on the left, such as __declspec. - prettyPrintAttributes(D, LeftSideStream, AttrPrintLoc::Left); - - // prettyPrintAttributes print a space on left side of the attribute. - if (LeftSide[0] == ' ') { - // Skip the space prettyPrintAttributes generated. - LeftSide.erase(0, LeftSide.find_first_not_of(' ')); - - // Add a single space between the attribute and the Decl name. - LeftSideStream << ' '; - } - - Out << LeftSide; - QualType T = D->getTypeSourceInfo() ? D->getTypeSourceInfo()->getType() : D->getASTContext().getUnqualifiedObjCPointerType(D->getType()); @@ -1029,21 +954,16 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) { } } - StringRef Name; - - Name = (isa(D) && Policy.CleanUglifiedParameters && - D->getIdentifier()) - ? D->getIdentifier()->deuglifiedName() - : D->getName(); - if (!Policy.SuppressTagKeyword && Policy.SuppressScope && !Policy.SuppressUnwrittenScope) MaybePrintTagKeywordIfSupressingScopes(Policy, T, Out); - printDeclType(T, Name); - // Print the attributes that should be placed right before the end of the - // decl. - prettyPrintAttributes(D, Out, AttrPrintLoc::Right); + printDeclType(T, (isa(D) && Policy.CleanUglifiedParameters && + D->getIdentifier()) + ? D->getIdentifier()->deuglifiedName() + : D->getName()); + + prettyPrintAttributes(D, AttrPosAsWritten::Right); Expr *Init = D->getInit(); if (!Policy.SuppressInitializers && Init) { diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 74b18e50bf1f4..2ba93d17f2675 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -292,8 +292,11 @@ void StmtPrinter::VisitLabelStmt(LabelStmt *Node) { } void StmtPrinter::VisitAttributedStmt(AttributedStmt *Node) { - for (const auto *Attr : Node->getAttrs()) { + llvm::ArrayRef Attrs = Node->getAttrs(); + for (const auto *Attr : Attrs) { Attr->printPretty(OS, Policy); + if (Attr != Attrs.back()) + OS << ' '; } PrintStmt(Node->getSubStmt(), 0); diff --git a/clang/test/AST/ast-print-method-decl.cpp b/clang/test/AST/ast-print-method-decl.cpp index 75dea0cac16be..cb5d10096381a 100644 --- a/clang/test/AST/ast-print-method-decl.cpp +++ b/clang/test/AST/ast-print-method-decl.cpp @@ -94,7 +94,7 @@ struct DefMethodsWithoutBody { // CHECK-NEXT: DefMethodsWithoutBody() = default; ~DefMethodsWithoutBody() = default; - // CHECK-NEXT: __attribute__((alias("X"))) void m1(); + // CHECK-NEXT: void m1() __attribute__((alias("X"))); void m1() __attribute__((alias("X"))); // CHECK-NEXT: }; diff --git a/clang/test/AST/ast-print-no-sanitize.cpp b/clang/test/AST/ast-print-no-sanitize.cpp index 4ff97190955ad..a5ada8246f0c0 100644 --- a/clang/test/AST/ast-print-no-sanitize.cpp +++ b/clang/test/AST/ast-print-no-sanitize.cpp @@ -4,4 +4,4 @@ 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 should_not_crash_2() {{\[\[}}clang::no_sanitize("memory"){{\]\]}}; +// CHECK: {{\[\[}}clang::no_sanitize("memory"){{\]\]}} void should_not_crash_2(); diff --git a/clang/test/AST/attr-print-emit.cpp b/clang/test/AST/attr-print-emit.cpp index 8c48eb92daba5..8c8a2b2080599 100644 --- a/clang/test/AST/attr-print-emit.cpp +++ b/clang/test/AST/attr-print-emit.cpp @@ -73,3 +73,18 @@ class C { // CHECK: void pwtt(void *, int) __attribute__((pointer_with_type_tag(foo, 2, 3))); void pwtt(void *, int) __attribute__((pointer_with_type_tag(foo, 2, 3))); }; + +#define ANNOTATE_ATTR __attribute__((annotate("Annotated"))) +ANNOTATE_ATTR int annotated_attr ANNOTATE_ATTR = 0; +// CHECK: __attribute__((annotate("Annotated"))) int annotated_attr __attribute__((annotate("Annotated"))) = 0; + +// FIXME: We do not print the attribute as written after the type specifier. +int ANNOTATE_ATTR annotated_attr_fixme = 0; +// CHECK: __attribute__((annotate("Annotated"))) int annotated_attr_fixme = 0; + +#define NONNULL_ATTR __attribute__((nonnull(1))) +ANNOTATE_ATTR NONNULL_ATTR void fn_non_null_annotated_attr(int *) __attribute__((annotate("AnnotatedRHS"))); +// CHECK:__attribute__((annotate("Annotated"))) __attribute__((nonnull(1))) void fn_non_null_annotated_attr(int *) __attribute__((annotate("AnnotatedRHS"))); + +[[gnu::nonnull(1)]] [[gnu::always_inline]] void cxx11_attr(int*) ANNOTATE_ATTR; +// CHECK: {{\[\[}}gnu::nonnull(1)]] {{\[\[}}gnu::always_inline]] void cxx11_attr(int *) __attribute__((annotate("Annotated"))); diff --git a/clang/test/Analysis/scopes-cfg-output.cpp b/clang/test/Analysis/scopes-cfg-output.cpp index 4eb8967e37351..5e6706602d456 100644 --- a/clang/test/Analysis/scopes-cfg-output.cpp +++ b/clang/test/Analysis/scopes-cfg-output.cpp @@ -1469,7 +1469,7 @@ void test_cleanup_functions2(int m) { // CHECK: [B1] // CHECK-NEXT: 1: CFGScopeBegin(f) // CHECK-NEXT: 2: (CXXConstructExpr, [B1.3], F) -// CHECK-NEXT: 3: __attribute__((cleanup(cleanup_F))) F f; +// CHECK-NEXT: 3: F f __attribute__((cleanup(cleanup_F))); // CHECK-NEXT: 4: CleanupFunction (cleanup_F) // CHECK-NEXT: 5: [B1.3].~F() (Implicit destructor) // CHECK-NEXT: 6: CFGScopeEnd(f) diff --git a/clang/test/OpenMP/assumes_codegen.cpp b/clang/test/OpenMP/assumes_codegen.cpp index 6a5871c303aad..4a2518a51ec34 100644 --- a/clang/test/OpenMP/assumes_codegen.cpp +++ b/clang/test/OpenMP/assumes_codegen.cpp @@ -67,7 +67,7 @@ int lambda_outer() { } #pragma omp end assumes -// AST: __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) void foo() { +// AST: void foo() __attribute__((assume("omp_no_openmp_routines,ompx_another_warning,ompx_after_invalid_clauses"))) __attribute__((assume("omp_no_openmp"))) { // AST-NEXT: } // AST-NEXT: class BAR { // AST-NEXT: public: @@ -81,7 +81,7 @@ int lambda_outer() { // 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: __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: template class BAZ { // AST-NEXT: public: // 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() { @@ -95,8 +95,8 @@ int lambda_outer() { // AST-NEXT: public: // 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: __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"))) void baz1(); +// 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"))) static void baz2(); // AST-NEXT: }; // 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; diff --git a/clang/test/OpenMP/assumes_print.cpp b/clang/test/OpenMP/assumes_print.cpp index a7f04edb3b1af..da3629f70408d 100644 --- a/clang/test/OpenMP/assumes_print.cpp +++ b/clang/test/OpenMP/assumes_print.cpp @@ -37,7 +37,7 @@ void baz() { } #pragma omp end assumes -// CHECK: __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) void foo() +// CHECK: void foo() __attribute__((assume("omp_no_openmp_routines"))) __attribute__((assume("omp_no_openmp"))) // 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() diff --git a/clang/test/OpenMP/assumes_template_print.cpp b/clang/test/OpenMP/assumes_template_print.cpp index bd1100fbefffc..e0bc3e9884ca5 100644 --- a/clang/test/OpenMP/assumes_template_print.cpp +++ b/clang/test/OpenMP/assumes_template_print.cpp @@ -17,7 +17,7 @@ template struct S { int a; // CHECK: template struct S { -// CHECK: __attribute__((assume("ompx_global_assumption"))) void foo() { +// CHECK: void foo() __attribute__((assume("ompx_global_assumption"))) { void foo() { #pragma omp parallel {} @@ -25,15 +25,15 @@ struct S { }; // CHECK: template<> struct S { -// CHECK: __attribute__((assume("ompx_global_assumption"))) void foo() { +// CHECK: void foo() __attribute__((assume("ompx_global_assumption"))) { #pragma omp begin assumes no_openmp -// CHECK: __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) void S_with_assumes_no_call() { +// CHECK: __attribute__((assume("omp_no_openmp"))) void S_with_assumes_no_call() __attribute__((assume("ompx_global_assumption"))) { void S_with_assumes_no_call() { S s; s.a = 0; } -// CHECK: __attribute__((assume("omp_no_openmp"))) __attribute__((assume("ompx_global_assumption"))) void S_with_assumes_call() { +// CHECK: __attribute__((assume("omp_no_openmp"))) void S_with_assumes_call() __attribute__((assume("ompx_global_assumption"))) { void S_with_assumes_call() { S s; s.a = 0; @@ -42,7 +42,7 @@ void S_with_assumes_call() { } #pragma omp end assumes -// CHECK: __attribute__((assume("ompx_global_assumption"))) void S_without_assumes() { +// CHECK: void S_without_assumes() __attribute__((assume("ompx_global_assumption"))) { void S_without_assumes() { S s; s.foo(); diff --git a/clang/test/OpenMP/declare_simd_ast_print.cpp b/clang/test/OpenMP/declare_simd_ast_print.cpp index 1adf95226c8be..565dc2dfc04d1 100644 --- a/clang/test/OpenMP/declare_simd_ast_print.cpp +++ b/clang/test/OpenMP/declare_simd_ast_print.cpp @@ -60,11 +60,11 @@ void h(int *hp, int *hp2, int *hq, int *lin) class VV { // CHECK: #pragma omp declare simd uniform(this, a) linear(val(b): a) - // CHECK-NEXT: __attribute__((cold)) int add(int a, int b) { + // CHECK-NEXT: int add(int a, int b) __attribute__((cold)) { // CHECK-NEXT: return a + b; // CHECK-NEXT: } #pragma omp declare simd uniform(this, a) linear(val(b): a) - __attribute__((cold)) int add(int a, int b) { return a + b; } + int add(int a, int b) __attribute__((cold)) { 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/SemaCXX/attr-no-sanitize.cpp b/clang/test/SemaCXX/attr-no-sanitize.cpp index a464947fe5a34..8951f616ce0f0 100644 --- a/clang/test/SemaCXX/attr-no-sanitize.cpp +++ b/clang/test/SemaCXX/attr-no-sanitize.cpp @@ -16,12 +16,12 @@ int f3() __attribute__((no_sanitize("address"))); // DUMP-LABEL: FunctionDecl {{.*}} f4 // DUMP: NoSanitizeAttr {{.*}} thread -// PRINT: int f4() {{\[\[}}clang::no_sanitize("thread")]] +// PRINT: {{\[\[}}clang::no_sanitize("thread")]] int f4() [[clang::no_sanitize("thread")]] int f4(); // DUMP-LABEL: FunctionDecl {{.*}} f4 // DUMP: NoSanitizeAttr {{.*}} hwaddress -// PRINT: int f4() {{\[\[}}clang::no_sanitize("hwaddress")]] +// PRINT: {{\[\[}}clang::no_sanitize("hwaddress")]] int f4() [[clang::no_sanitize("hwaddress")]] int f4(); // DUMP-LABEL: FunctionDecl {{.*}} f5 @@ -36,5 +36,5 @@ int f6() __attribute__((no_sanitize("unknown"))); // expected-warning{{unknown s // DUMP-LABEL: FunctionDecl {{.*}} f7 // DUMP: NoSanitizeAttr {{.*}} memtag -// PRINT: int f7() {{\[\[}}clang::no_sanitize("memtag")]] +// PRINT: {{\[\[}}clang::no_sanitize("memtag")]] int f7() [[clang::no_sanitize("memtag")]] int f7(); diff --git a/clang/test/SemaCXX/cxx11-attr-print.cpp b/clang/test/SemaCXX/cxx11-attr-print.cpp index c988972aeb1a5..a169d1b4409b4 100644 --- a/clang/test/SemaCXX/cxx11-attr-print.cpp +++ b/clang/test/SemaCXX/cxx11-attr-print.cpp @@ -24,10 +24,10 @@ int d [[deprecated("warning")]]; // CHECK: __attribute__((deprecated("warning", "fixit"))); int e __attribute__((deprecated("warning", "fixit"))); -// CHECK: int cxx11_alignas alignas(4); +// CHECK: alignas(4) int cxx11_alignas; alignas(4) int cxx11_alignas; -// CHECK: int c11_alignas _Alignas(int); +// CHECK: _Alignas(int) int c11_alignas; _Alignas(int) int c11_alignas; // CHECK: int foo() __attribute__((const)); @@ -66,7 +66,7 @@ void f8 (void *, const char *, ...) __attribute__ ((format (printf, 2, 3))); // CHECK: int n alignas(4 // CHECK: int p alignas(int // CHECK: __attribute__((pure)) static int f() -// CHECK: static int g() {{\[}}[gnu::pure]] +// CHECK: {{\[}}[gnu::pure]] static int g() template struct S { __attribute__((aligned(4))) int m; alignas(4) int n; @@ -82,7 +82,7 @@ template struct S { // CHECK: int m __attribute__((aligned(4 // CHECK: int n alignas(4 // CHECK: __attribute__((pure)) static int f() -// CHECK: static int g() {{\[}}[gnu::pure]] +// CHECK: {{\[}}[gnu::pure]] static int g() template struct S; // CHECK: using Small2 {{\[}}[gnu::mode(byte)]] = int; diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index eb5c34d15693d..6c56f99f503df 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -1591,10 +1591,10 @@ writePrettyPrintFunction(const Record &R, std::string Variety = Spellings[I].variety(); if (Variety == "GNU") { - Prefix = " __attribute__(("; + Prefix = "__attribute__(("; Suffix = "))"; } else if (Variety == "CXX11" || Variety == "C23") { - Prefix = " [["; + Prefix = "[["; Suffix = "]]"; std::string Namespace = Spellings[I].nameSpace(); if (!Namespace.empty()) { @@ -1602,7 +1602,7 @@ writePrettyPrintFunction(const Record &R, Spelling += "::"; } } else if (Variety == "Declspec") { - Prefix = " __declspec("; + Prefix = "__declspec("; Suffix = ")"; } else if (Variety == "Microsoft") { Prefix = "["; @@ -3316,37 +3316,6 @@ void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS) { OS << "#undef PRAGMA_SPELLING_ATTR\n"; } -// Emits the enumeration list for attributes. -void EmitClangAttrPrintList(const std::string &FieldName, RecordKeeper &Records, - raw_ostream &OS) { - emitSourceFileHeader( - "List of attributes that can be print on the left side of a decl", OS, - Records); - - AttrClassHierarchy Hierarchy(Records); - - std::vector Attrs = Records.getAllDerivedDefinitions("Attr"); - std::vector PragmaAttrs; - bool first = false; - - for (auto *Attr : Attrs) { - if (!Attr->getValueAsBit("ASTNode")) - continue; - - if (!Attr->getValueAsBit(FieldName)) - continue; - - if (!first) { - first = true; - OS << "#define CLANG_ATTR_LIST_" << FieldName; - } - - OS << " \\\n case attr::" << Attr->getName() << ":"; - } - - OS << '\n'; -} - // Emits the enumeration list for attributes. void EmitClangAttrSubjectMatchRuleList(RecordKeeper &Records, raw_ostream &OS) { emitSourceFileHeader( diff --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp index 3f22e43b97ecd..42cc704543f18 100644 --- a/clang/utils/TableGen/TableGen.cpp +++ b/clang/utils/TableGen/TableGen.cpp @@ -31,8 +31,6 @@ enum ActionType { GenClangAttrSubjectMatchRulesParserStringSwitches, GenClangAttrImpl, GenClangAttrList, - GenClangAttrCanPrintLeftList, - GenClangAttrMustPrintLeftList, GenClangAttrDocTable, GenClangAttrSubjectMatchRuleList, GenClangAttrPCHRead, @@ -134,14 +132,6 @@ cl::opt Action( "Generate clang attribute implementations"), clEnumValN(GenClangAttrList, "gen-clang-attr-list", "Generate a clang attribute list"), - clEnumValN(GenClangAttrCanPrintLeftList, - "gen-clang-attr-can-print-left-list", - "Generate list of attributes that can be printed on left " - "side of a decl"), - clEnumValN(GenClangAttrMustPrintLeftList, - "gen-clang-attr-must-print-left-list", - "Generate list of attributes that must be printed on left " - "side of a decl"), clEnumValN(GenClangAttrDocTable, "gen-clang-attr-doc-table", "Generate a table of attribute documentation"), clEnumValN(GenClangAttrSubjectMatchRuleList, @@ -345,12 +335,6 @@ bool ClangTableGenMain(raw_ostream &OS, RecordKeeper &Records) { case GenClangAttrList: EmitClangAttrList(Records, OS); break; - case GenClangAttrCanPrintLeftList: - EmitClangAttrPrintList("CanPrintOnLeft", Records, OS); - break; - case GenClangAttrMustPrintLeftList: - EmitClangAttrPrintList("PrintOnLeft", Records, OS); - break; case GenClangAttrDocTable: EmitClangAttrDocTable(Records, OS); break; diff --git a/clang/utils/TableGen/TableGenBackends.h b/clang/utils/TableGen/TableGenBackends.h index ecd506b7b6b50..5f2dd257cb90a 100644 --- a/clang/utils/TableGen/TableGenBackends.h +++ b/clang/utils/TableGen/TableGenBackends.h @@ -47,8 +47,6 @@ void EmitClangAttrSubjectMatchRulesParserStringSwitches( void EmitClangAttrClass(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitClangAttrImpl(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitClangAttrList(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); -void EmitClangAttrPrintList(const std::string &FieldName, - llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitClangAttrSubjectMatchRuleList(llvm::RecordKeeper &Records, llvm::raw_ostream &OS); void EmitClangAttrPCHRead(llvm::RecordKeeper &Records, llvm::raw_ostream &OS);