diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -416,6 +416,9 @@ } def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>; def TargetAArch64 : TargetArch<["aarch64"]>; +def TargetAArch64SME : TargetArch<["aarch64"]> { + let CustomCode = [{ Target.hasFeature("sme") }]; +} def TargetAnyArm : TargetArch; def TargetAVR : TargetArch<["avr"]>; def TargetBPF : TargetArch<["bpfel", "bpfeb"]>; @@ -2434,9 +2437,10 @@ let Documentation = [AArch64SVEPcsDocs]; } -def ArmStreaming : TypeAttr, TargetSpecificAttr { +def ArmStreaming : TypeAttr, TargetSpecificAttr { let Spellings = [RegularKeyword<"__arm_streaming">]; - let Documentation = [ArmStreamingDocs]; + let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>; + let Documentation = [ArmSmeStreamingDocs]; } def Pure : InheritableAttr { diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -6551,7 +6551,7 @@ }]; } -def ArmStreamingDocs : Documentation { +def ArmSmeStreamingDocs : Documentation { let Category = DocCatType; let Content = [{ .. Note:: This attribute has not been implemented yet, but once it is @@ -6568,6 +6568,8 @@ * the function must return in streaming mode +* the function does not have a K&R-style unprototyped function type. + See `Procedure Call Standard for the ArmĀ® 64-bit Architecture (AArch64) `_ for more details about streaming-interface functions. diff --git a/clang/test/Parser/aarch64-sme-attrs-no-sme.c b/clang/test/Parser/aarch64-sme-attrs-no-sme.c new file mode 100644 --- /dev/null +++ b/clang/test/Parser/aarch64-sme-attrs-no-sme.c @@ -0,0 +1,31 @@ +// Test that the attribute is ignored if we don't compile for both AArch64 with +sme. +// +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple x86_64-none-linux-gnu -target-feature +sme -fsyntax-only -verify %s + +extern int normal_callee(void); + +// expected-error@+1 {{'__arm_streaming' is not supported on this target}} +int streaming_caller(void) __arm_streaming { + return normal_callee(); +} + +// expected-error@+1 {{'__arm_locally_streaming' is not supported on this target}} +__arm_locally_streaming int locally_streaming_caller(void) { + return normal_callee(); +} + +// expected-error@+1 {{'__arm_shared_za' is not supported on this target}} +int shared_za_caller(void) __arm_shared_za { + return normal_callee(); +} + +// expected-error@+1 {{'__arm_preserves_za' is not supported on this target}} +int preserves_za_caller(void) __arm_preserves_za { + return normal_callee(); +} + +// expected-error@+1 {{'__arm_new_za' is not supported on this target}} +__arm_new_za int new_za_caller(void) { + return normal_callee(); +} diff --git a/clang/test/Parser/c2x-attribute-keywords.c b/clang/test/Parser/c2x-attribute-keywords.c --- a/clang/test/Parser/c2x-attribute-keywords.c +++ b/clang/test/Parser/c2x-attribute-keywords.c @@ -1,13 +1,13 @@ // RUN: %clang_cc1 -fsyntax-only -triple aarch64-none-linux-gnu -target-feature +sme -verify=expected,notc2x -Wno-strict-prototypes %s // RUN: %clang_cc1 -fsyntax-only -triple aarch64-none-linux-gnu -target-feature +sme -verify=expected,c2x %s -enum __arm_streaming E { // expected-error {{'__arm_streaming' cannot be applied to a declaration}} - One __arm_streaming, // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +enum __arm_streaming E { // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} + One __arm_streaming, // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} Two, - Three __arm_streaming // expected-error {{'__arm_streaming' cannot be applied to a declaration}} + Three __arm_streaming // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} }; -enum __arm_streaming { Four }; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +enum __arm_streaming { Four }; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} __arm_streaming enum E2 { Five }; // expected-error {{misplaced '__arm_streaming'}} // FIXME: this diagnostic can be improved. @@ -16,7 +16,7 @@ // FIXME: this diagnostic can be improved. enum E3 __arm_streaming { Seven }; // expected-error {{expected identifier or '('}} -struct __arm_streaming S1 { // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +struct __arm_streaming S1 { // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} int i __arm_streaming; // expected-error {{'__arm_streaming' only applies to function types}} int __arm_streaming j; // expected-error {{'__arm_streaming' only applies to function types}} int k[10] __arm_streaming; // expected-error {{'__arm_streaming' only applies to function types}} @@ -32,20 +32,20 @@ __arm_streaming struct S2 { int a; }; // expected-error {{misplaced '__arm_streaming'}} struct S3 __arm_streaming { int a; }; // expected-error {{'__arm_streaming' cannot appear here}} \ - expected-error {{'__arm_streaming' cannot be applied to a declaration}} + expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} -union __arm_streaming U { // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +union __arm_streaming U { // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} double d __arm_streaming; // expected-error {{'__arm_streaming' only applies to function types; type here is 'double'}} __arm_streaming int i; // expected-error {{'__arm_streaming' only applies to function types; type here is 'int'}} }; __arm_streaming union U2 { double d; }; // expected-error {{misplaced '__arm_streaming'}} union U3 __arm_streaming { double d; }; // expected-error {{'__arm_streaming' cannot appear here}} \ - expected-error {{'__arm_streaming' cannot be applied to a declaration}} + expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} -struct __arm_streaming IncompleteStruct; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} -union __arm_streaming IncompleteUnion; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} -enum __arm_streaming IncompleteEnum; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +struct __arm_streaming IncompleteStruct; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} +union __arm_streaming IncompleteUnion; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} +enum __arm_streaming IncompleteEnum; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} __arm_streaming void f1(void); // expected-error {{'__arm_streaming' cannot be applied to a declaration}} void __arm_streaming f2(void); // expected-error {{'__arm_streaming' only applies to function types}} @@ -95,7 +95,7 @@ } goto foo; - __arm_streaming foo: (void)1; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} + __arm_streaming foo: (void)1; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} __arm_streaming for (;;); // expected-error {{'__arm_streaming' cannot be applied to a statement}} __arm_streaming while (1); // expected-error {{'__arm_streaming' cannot be applied to a statement}} @@ -106,7 +106,7 @@ __arm_streaming; // expected-error {{'__arm_streaming' cannot be applied to a statement}} (void)sizeof(int [4]__arm_streaming); // expected-error {{'__arm_streaming' only applies to function types}} - (void)sizeof(struct __arm_streaming S3 { int a __arm_streaming; }); // expected-error {{'__arm_streaming' cannot be applied to a declaration}} \ + (void)sizeof(struct __arm_streaming S3 { int a __arm_streaming; }); // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} \ // expected-error {{'__arm_streaming' only applies to function types; type here is 'int'}} __arm_streaming return; // expected-error {{'__arm_streaming' cannot be applied to a statement}} diff --git a/clang/test/Parser/c2x-attribute-keywords.m b/clang/test/Parser/c2x-attribute-keywords.m --- a/clang/test/Parser/c2x-attribute-keywords.m +++ b/clang/test/Parser/c2x-attribute-keywords.m @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -fsyntax-only -triple aarch64-none-linux-gnu -target-feature +sme -verify %s -enum __arm_streaming E1 : int; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +enum __arm_streaming E1 : int; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} @interface Base @end diff --git a/clang/test/Parser/cxx0x-keyword-attributes.cpp b/clang/test/Parser/cxx0x-keyword-attributes.cpp --- a/clang/test/Parser/cxx0x-keyword-attributes.cpp +++ b/clang/test/Parser/cxx0x-keyword-attributes.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fcxx-exceptions -fdeclspec -fexceptions -fsyntax-only -verify -std=c++11 -Wc++14-compat -Wc++14-extensions -Wc++17-extensions -triple aarch64-none-linux-gnu %s +// RUN: %clang_cc1 -fcxx-exceptions -fdeclspec -fexceptions -fsyntax-only -verify -std=c++11 -Wc++14-compat -Wc++14-extensions -Wc++17-extensions -triple aarch64-none-linux-gnu -target-feature +sme %s // Need std::initializer_list namespace std { @@ -48,10 +48,10 @@ struct MemberFnOrder { virtual void f() const volatile && noexcept __arm_streaming final = 0; }; -struct __arm_streaming struct_attr; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} -class __arm_streaming class_attr {}; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} -union __arm_streaming union_attr; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} -enum __arm_streaming E { }; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +struct __arm_streaming struct_attr; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} +class __arm_streaming class_attr {}; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} +union __arm_streaming union_attr; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} +enum __arm_streaming E { }; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} namespace test_misplacement { __arm_streaming struct struct_attr2; // expected-error {{misplaced '__arm_streaming'}} __arm_streaming class class_attr2; // expected-error {{misplaced '__arm_streaming'}} @@ -60,28 +60,28 @@ } // Checks attributes placed at wrong syntactic locations of class specifiers. -class __arm_streaming __arm_streaming // expected-error 2 {{'__arm_streaming' cannot be applied to a declaration}} +class __arm_streaming __arm_streaming // expected-error 2 {{'__arm_streaming' only applies to non-K&R-style functions}} attr_after_class_name_decl __arm_streaming __arm_streaming; // expected-error {{'__arm_streaming' cannot appear here}} \ - expected-error 2 {{'__arm_streaming' cannot be applied to a declaration}} + expected-error 2 {{'__arm_streaming' only applies to non-K&R-style functions}} -class __arm_streaming __arm_streaming // expected-error 2 {{'__arm_streaming' cannot be applied to a declaration}} +class __arm_streaming __arm_streaming // expected-error 2 {{'__arm_streaming' only applies to non-K&R-style functions}} attr_after_class_name_definition __arm_streaming __arm_streaming __arm_streaming{}; // expected-error {{'__arm_streaming' cannot appear here}} \ - expected-error 3 {{'__arm_streaming' cannot be applied to a declaration}} + expected-error 3 {{'__arm_streaming' only applies to non-K&R-style functions}} -class __arm_streaming c {}; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +class __arm_streaming c {}; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} class c __arm_streaming __arm_streaming x; // expected-error 2 {{'__arm_streaming' only applies to function types}} class c __arm_streaming __arm_streaming y __arm_streaming __arm_streaming; // expected-error 4 {{'__arm_streaming' only applies to function types}} class c final [(int){0}]; class base {}; -class __arm_streaming __arm_streaming final_class // expected-error 2 {{'__arm_streaming' cannot be applied to a declaration}} +class __arm_streaming __arm_streaming final_class // expected-error 2 {{'__arm_streaming' only applies to non-K&R-style functions}} __arm_streaming alignas(float) final // expected-error {{'__arm_streaming' cannot appear here}} \ - expected-error {{'__arm_streaming' cannot be applied to a declaration}} + expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} __arm_streaming alignas(float) __arm_streaming alignas(float): base{}; // expected-error {{'__arm_streaming' cannot appear here}} -class __arm_streaming __arm_streaming final_class_another // expected-error 2 {{'__arm_streaming' cannot be applied to a declaration}} +class __arm_streaming __arm_streaming final_class_another // expected-error 2 {{'__arm_streaming' only applies to non-K&R-style functions}} __arm_streaming __arm_streaming alignas(16) final // expected-error {{'__arm_streaming' cannot appear here}} \ - expected-error 2 {{'__arm_streaming' cannot be applied to a declaration}} + expected-error 2 {{'__arm_streaming' only applies to non-K&R-style functions}} __arm_streaming __arm_streaming alignas(16) __arm_streaming{}; // expected-error {{'__arm_streaming' cannot appear here}} class after_class_close {} __arm_streaming; // expected-error {{'__arm_streaming' cannot appear here, place it after "class" to apply it to the type declaration}} @@ -95,7 +95,7 @@ __arm_streaming struct with_init_declarators {} init_declarator; // expected-error {{'__arm_streaming' only applies to function types}} __arm_streaming struct no_init_declarators; // expected-error {{'__arm_streaming' cannot appear here}} } -__arm_streaming; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +__arm_streaming; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} struct ctordtor { __arm_streaming ctordtor __arm_streaming () __arm_streaming; // expected-error 2 {{'__arm_streaming' cannot be applied to a declaration}} ctordtor (C) __arm_streaming; @@ -122,16 +122,16 @@ __arm_streaming asm(""); // expected-error {{'__arm_streaming' cannot appear here}} __arm_streaming using ns::i; // expected-warning {{ISO C++}} \ - expected-error {{'__arm_streaming' cannot be applied to a declaration}} -__arm_streaming using namespace ns; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} + expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} +__arm_streaming using namespace ns; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} namespace __arm_streaming ns2 {} // expected-warning {{attributes on a namespace declaration are a C++17 extension}} \ - expected-error {{'__arm_streaming' cannot be applied to a declaration}} + expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} using __arm_streaming alignas(4)__arm_streaming ns::i; // expected-warning 2 {{ISO C++}} \ expected-error {{'__arm_streaming' cannot appear here}} \ expected-error {{'alignas' attribute only applies to variables, data members and tag types}} \ expected-warning {{ISO C++}} \ - expected-error 2 {{'__arm_streaming' cannot be applied to a declaration}} + expected-error 2 {{'__arm_streaming' only applies to non-K&R-style functions}} using __arm_streaming alignas(4) __arm_streaming foobar = int; // expected-error {{'__arm_streaming' cannot appear here}} \ expected-error {{'alignas' attribute only applies to}} \ expected-error 2 {{'__arm_streaming' only applies to function types}} @@ -140,25 +140,25 @@ using T __arm_streaming = int; // expected-error {{'__arm_streaming' only applies to function types}} template using U __arm_streaming = T; // expected-error {{'__arm_streaming' only applies to function types}} using ns::i __arm_streaming; // expected-warning {{ISO C++}} \ - expected-error {{'__arm_streaming' cannot be applied to a declaration}} + expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} using ns::i __arm_streaming, ns::i __arm_streaming; // expected-warning 2 {{ISO C++}} \ expected-warning {{use of multiple declarators in a single using declaration is a C++17 extension}} \ - expected-error 2 {{'__arm_streaming' cannot be applied to a declaration}} + expected-error 2 {{'__arm_streaming' only applies to non-K&R-style functions}} struct using_in_struct_base { typedef int i, j, k, l; }; struct using_in_struct : using_in_struct_base { __arm_streaming using using_in_struct_base::i; // expected-warning {{ISO C++}} \ - expected-error {{'__arm_streaming' cannot be applied to a declaration}} + expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} using using_in_struct_base::j __arm_streaming; // expected-warning {{ISO C++}} \ - expected-error {{'__arm_streaming' cannot be applied to a declaration}} + expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} __arm_streaming using using_in_struct_base::k __arm_streaming, using_in_struct_base::l __arm_streaming; // expected-warning 3 {{ISO C++}} \ expected-warning {{use of multiple declarators in a single using declaration is a C++17 extension}} \ - expected-error 4 {{'__arm_streaming' cannot be applied to a declaration}} + expected-error 4 {{'__arm_streaming' only applies to non-K&R-style functions}} }; using __arm_streaming ns::i; // expected-warning {{ISO C++}} \ expected-error {{'__arm_streaming' cannot appear here}} \ - expected-error {{'__arm_streaming' cannot be applied to a declaration}} + expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} using T __arm_streaming = int; // expected-error {{'__arm_streaming' only applies to function types}} auto trailing() -> __arm_streaming const int; // expected-error {{'__arm_streaming' cannot appear here}} @@ -177,20 +177,20 @@ struct __arm_streaming ::template Template u; // expected-error {{'__arm_streaming' cannot appear here}} template struct __arm_streaming Template; // expected-error {{'__arm_streaming' cannot appear here}} template struct __attribute__((pure)) Template; // We still allow GNU-style attributes here -template <> struct __arm_streaming Template; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +template <> struct __arm_streaming Template; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} -enum __arm_streaming E1 {}; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +enum __arm_streaming E1 {}; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} enum __arm_streaming E2; // expected-error {{forbids forward references}} \ - expected-error {{'__arm_streaming' cannot be applied to a declaration}} -enum __arm_streaming E1; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} -enum __arm_streaming E3 : int; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} -enum __arm_streaming { // expected-error {{'__arm_streaming' cannot be applied to a declaration}} + expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} +enum __arm_streaming E1; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} +enum __arm_streaming E3 : int; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} +enum __arm_streaming { // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} k_123 __arm_streaming = 123 // expected-warning {{attributes on an enumerator declaration are a C++17 extension}} \ - expected-error {{'__arm_streaming' cannot be applied to a declaration}} + expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} }; enum __arm_streaming E1 e; // expected-error {{'__arm_streaming' cannot appear here}} enum __arm_streaming class E4 { }; // expected-error {{'__arm_streaming' cannot appear here}} -enum struct __arm_streaming E5; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +enum struct __arm_streaming E5; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} enum E6 {} __arm_streaming; // expected-error {{'__arm_streaming' cannot appear here, place it after "enum" to apply it to the type declaration}} struct S { @@ -229,7 +229,7 @@ } __arm_streaming goto there; // expected-error {{'__arm_streaming' cannot be applied to a statement}} - __arm_streaming there: // expected-error {{'__arm_streaming' cannot be applied to a declaration}} + __arm_streaming there: // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} __arm_streaming try { // expected-error {{'__arm_streaming' cannot be applied to a statement}} } __arm_streaming catch (...) { // expected-error {{'__arm_streaming' cannot appear here}} @@ -277,7 +277,7 @@ enum class __attribute__((visibility("hidden"))) SecretKeepers { one, /* rest are deprecated */ two, three }; -enum class __arm_streaming EvenMoreSecrets {}; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +enum class __arm_streaming EvenMoreSecrets {}; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} // Forbid attributes on decl specifiers. unsigned __arm_streaming static int __arm_streaming v1; // expected-error {{'__arm_streaming' only applies to function types}} \ @@ -286,7 +286,7 @@ expected-error {{'__arm_streaming' cannot appear here}} int __arm_streaming foo(int __arm_streaming x); // expected-error 2 {{'__arm_streaming' only applies to function types}} -__arm_streaming; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} +__arm_streaming; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} class A { A(__arm_streaming int a); // expected-error {{'__arm_streaming' only applies to function types}} @@ -341,5 +341,5 @@ expected-error {{'__arm_streaming' cannot be applied to a base specifier}} } -namespace __arm_streaming ns_attr {}; // expected-error {{'__arm_streaming' cannot be applied to a declaration}} \ +namespace __arm_streaming ns_attr {}; // expected-error {{'__arm_streaming' only applies to non-K&R-style functions}} \ expected-warning {{attributes on a namespace declaration are a C++17 extension}}