mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-27 18:36:05 +00:00

EnumArgument may be a string or an identifier. If it is a string, it should be parsed as unevaluated string literal. Add IsString flag to EnumArgument so that the parser can choose the correct parsing method. Target-specific attributes that share spelling may have different attribute "prototypes". For example, ARM's version of "interrupt" attribute accepts a string enum, while MSP430's version accepts an unsigned integer. Adjust ClangAttrEmitter so that the generated `attributeStringLiteralListArg` returns the correct mask depending on target triple. It is worth noting that even after this change some string arguments are still parsed as identifiers or, worse, as expressions. This is because of some special logic in `ParseAttributeArgsCommon`. Fixing it is out of scope of this patch.
76 lines
3.5 KiB
C
76 lines
3.5 KiB
C
// RUN: %clang_cc1 %s -fsyntax-only -Wno-strict-prototypes -triple i386-unknown-unknown -verify
|
|
// RUN: %clang_cc1 %s -fsyntax-only -Wno-strict-prototypes -triple i386-unknown-unknown -fms-compatibility -DWIN -verify
|
|
|
|
void __attribute__((fastcall)) foo(float *a) {
|
|
}
|
|
|
|
void __attribute__((stdcall)) bar(float *a) {
|
|
}
|
|
|
|
void __attribute__((fastcall(1))) baz(float *a) { // expected-error {{'fastcall' attribute takes no arguments}}
|
|
}
|
|
|
|
void __attribute__((fastcall)) test0() {
|
|
}
|
|
|
|
void __attribute__((fastcall)) test1(void) {
|
|
}
|
|
|
|
void __attribute__((fastcall)) test2(int a, ...) { // expected-warning {{fastcall calling convention is not supported on variadic function}}
|
|
}
|
|
void __attribute__((stdcall)) test3(int a, ...) { // expected-warning {{stdcall calling convention is not supported on variadic function}}
|
|
}
|
|
void __attribute__((thiscall)) test4(int a, ...) { // expected-error {{variadic function cannot use thiscall calling convention}}
|
|
}
|
|
|
|
void __attribute__((cdecl)) ctest0() {}
|
|
|
|
void __attribute__((cdecl(1))) ctest1(float x) {} // expected-error {{'cdecl' attribute takes no arguments}}
|
|
|
|
void (__attribute__((fastcall)) *pfoo)(float*) = foo;
|
|
|
|
void (__attribute__((stdcall)) *pbar)(float*) = bar;
|
|
|
|
void (__attribute__((cdecl)) *ptest1)(void) = test1; // expected-error {{incompatible function pointer types}}
|
|
|
|
void (*pctest0)() = ctest0;
|
|
|
|
void ctest2() {}
|
|
void (__attribute__((cdecl)) *pctest2)() = ctest2;
|
|
|
|
typedef void (__attribute__((fastcall)) *Handler) (float *);
|
|
Handler H = foo;
|
|
|
|
int __attribute__((pcs("aapcs", "aapcs"))) pcs1(void); // expected-error {{'pcs' attribute takes one argument}}
|
|
int __attribute__((pcs())) pcs2(void); // expected-error {{'pcs' attribute takes one argument}}
|
|
int __attribute__((pcs(pcs1))) pcs3(void); // expected-error {{'pcs' attribute requires a string}} \
|
|
// expected-error {{invalid PCS type}}
|
|
int __attribute__((pcs(0))) pcs4(void); // expected-error {{expected string literal as argument of 'pcs' attribute}}
|
|
/* These are ignored because the target is i386 and not ARM */
|
|
int __attribute__((pcs("aapcs"))) pcs5(void); // expected-warning {{'pcs' calling convention is not supported for this target}}
|
|
int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // expected-warning {{'pcs' calling convention is not supported for this target}}
|
|
int __attribute__((pcs("foo"))) pcs7(void); // expected-error {{invalid PCS type}}
|
|
|
|
int __attribute__((aarch64_vector_pcs)) aavpcs(void); // expected-warning {{'aarch64_vector_pcs' calling convention is not supported for this target}}
|
|
int __attribute__((aarch64_sve_pcs)) aasvepcs(void); // expected-warning {{'aarch64_sve_pcs' calling convention is not supported for this target}}
|
|
|
|
int __attribute__((amdgpu_kernel)) amdgpu_kernel(void); // expected-warning {{'amdgpu_kernel' calling convention is not supported for this target}}
|
|
|
|
// PR6361
|
|
void ctest3();
|
|
void __attribute__((cdecl)) ctest3() {}
|
|
|
|
// PR6408
|
|
typedef __attribute__((stdcall)) void (*PROC)();
|
|
PROC __attribute__((cdecl)) ctest4(const char *x) {}
|
|
|
|
void __attribute__((intel_ocl_bicc)) inteloclbifunc(float *a) {}
|
|
|
|
typedef void typedef_fun_t(int);
|
|
typedef_fun_t typedef_fun; // expected-note {{previous declaration is here}}
|
|
void __attribute__((stdcall)) typedef_fun(int x) { } // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}
|
|
|
|
struct type_test {} __attribute__((stdcall)); // expected-warning {{'stdcall' attribute only applies to functions and methods}}
|
|
|
|
void __vectorcall __builtin_unreachable(); // expected-warning {{vectorcall calling convention is not supported on builtin function}}
|