Pretty up the wrong-number-of-arguments-for-attribute diagnostic by

using a custom plural form.  Split out the range diagnostics as their
own message.

llvm-svn: 126840
This commit is contained in:
John McCall 2011-03-02 12:15:05 +00:00
parent 86bc21ffcf
commit 80ee5963fd
19 changed files with 38 additions and 40 deletions

View File

@ -984,7 +984,10 @@ def err_attribute_can_be_applied_only_to_symbol_declaration : Error<
def err_attributes_are_not_compatible : Error<
"%0 and %1 attributes are not compatible">;
def err_attribute_wrong_number_arguments : Error<
"attribute requires %0 argument(s)">;
"attribute %plural{0:takes no arguments|1:takes one argument|"
":requires exactly %0 arguments}0">;
def err_attribute_too_many_arguments : Error<
"attribute takes no more than %0 argument%s0">;
def err_iboutletcollection_type : Error<
"invalid type %0 as argument of iboutletcollection attribute">;
def err_iboutletcollection_object_type : Error<

View File

@ -953,9 +953,8 @@ static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// check the attribute arguments.
if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
<< "0 or 1";
if (Attr.getNumArgs() > 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
return;
}
@ -984,9 +983,8 @@ static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// check the attribute arguments.
if (Attr.getNumArgs() != 0 && Attr.getNumArgs() != 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
<< "0 or 1";
if (Attr.getNumArgs() > 1) {
S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
return;
}
@ -1016,8 +1014,7 @@ static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
unsigned NumArgs = Attr.getNumArgs();
if (NumArgs > 1) {
S.Diag(Attr.getLoc(),
diag::err_attribute_wrong_number_arguments) << "0 or 1";
S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
return;
}
@ -1039,8 +1036,7 @@ static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
unsigned NumArgs = Attr.getNumArgs();
if (NumArgs > 1) {
S.Diag(Attr.getLoc(),
diag::err_attribute_wrong_number_arguments) << "0 or 1";
S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 1;
return;
}
@ -1213,8 +1209,7 @@ static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// check the attribute arguments.
if (Attr.getNumArgs() > 2) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
<< "0, 1 or 2";
S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
return;
}
@ -2461,8 +2456,8 @@ static void HandleLaunchBoundsAttr(Decl *d, const AttributeList &Attr, Sema &S){
if (S.LangOpts.CUDA) {
// check the attribute arguments.
if (Attr.getNumArgs() != 1 && Attr.getNumArgs() != 2) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
<< "1 or 2";
// FIXME: 0 is not okay.
S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) << 2;
return;
}

View File

@ -3,5 +3,5 @@
void __attribute__((annotate("foo"))) foo(float *a) {
__attribute__((annotate("bar"))) int x;
__attribute__((annotate(1))) int y; // expected-error {{argument to annotate attribute was not a string literal}}
__attribute__((annotate("bar", 1))) int z; // expected-error {{attribute requires 1 argument(s)}}
__attribute__((annotate("bar", 1))) int z; // expected-error {{attribute takes one argument}}
}

View File

@ -8,8 +8,8 @@ static int g3 __attribute((cleanup(c1))); // expected-warning {{cleanup attribut
void t1()
{
int v1 __attribute((cleanup)); // expected-error {{attribute requires 1 argument(s)}}
int v2 __attribute((cleanup(1, 2))); // expected-error {{attribute requires 1 argument(s)}}
int v1 __attribute((cleanup)); // expected-error {{attribute takes one argument}}
int v2 __attribute((cleanup(1, 2))); // expected-error {{attribute takes one argument}}
static int v3 __attribute((cleanup(c1))); // expected-warning {{cleanup attribute ignored}}

View File

@ -4,5 +4,5 @@ int a __attribute__((naked)); // expected-warning {{'naked' attribute only appli
void t1() __attribute__((naked));
void t2() __attribute__((naked(2))); // expected-error {{attribute requires 0 argument(s)}}
void t2() __attribute__((naked(2))); // expected-error {{attribute takes no arguments}}

View File

@ -4,5 +4,5 @@ int a __attribute__((nodebug)); // expected-warning {{'nodebug' attribute only a
void t1() __attribute__((nodebug));
void t2() __attribute__((nodebug(2))); // expected-error {{attribute requires 0 argument(s)}}
void t2() __attribute__((nodebug(2))); // expected-error {{attribute takes no arguments}}

View File

@ -4,5 +4,5 @@ int a __attribute__((noinline)); // expected-warning {{'noinline' attribute only
void t1() __attribute__((noinline));
void t2() __attribute__((noinline(2))); // expected-error {{attribute requires 0 argument(s)}}
void t2() __attribute__((noinline(2))); // expected-error {{attribute takes no arguments}}

View File

@ -13,7 +13,7 @@ int f1() __attribute__((noreturn));
int g0 __attribute__((noreturn)); // expected-warning {{'noreturn' only applies to function types; type here is 'int'}}
int f2() __attribute__((noreturn(1, 2))); // expected-error {{attribute requires 0 argument(s)}}
int f2() __attribute__((noreturn(1, 2))); // expected-error {{attribute takes no arguments}}
void f3() __attribute__((noreturn));
void f3() {
@ -41,4 +41,4 @@ __attribute__((noreturn)) void f(__attribute__((noreturn)) void (*x)(void)) {
x();
}
typedef void (*Fun)(void) __attribute__ ((noreturn(2))); // expected-error {{attribute requires 0 argument(s)}}
typedef void (*Fun)(void) __attribute__ ((noreturn(2))); // expected-error {{attribute takes no arguments}}

View File

@ -4,7 +4,7 @@ __attribute((regparm(2))) int x0(void);
__attribute((regparm(1.0))) int x1(void); // expected-error{{'regparm' attribute requires integer constant}}
__attribute((regparm(-1))) int x2(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
__attribute((regparm(5))) int x3(void); // expected-error{{'regparm' parameter must be between 0 and 3 inclusive}}
__attribute((regparm(5,3))) int x4(void); // expected-error{{attribute requires 1 argument(s)}}
__attribute((regparm(5,3))) int x4(void); // expected-error{{attribute takes one argument}}
void __attribute__((regparm(3))) x5(int);
void x5(int); // expected-note{{previous declaration is here}}

View File

@ -9,7 +9,7 @@ int f1() __attribute__((unused));
int g0 __attribute__((unused));
int f2() __attribute__((unused(1, 2))); // expected-error {{attribute requires 0 argument(s)}}
int f2() __attribute__((unused(1, 2))); // expected-error {{attribute takes no arguments}}
struct Test0_unused {} __attribute__((unused));
struct Test0_not_unused {};

View File

@ -6,7 +6,7 @@ void __attribute__((fastcall)) foo(float *a) {
void __attribute__((stdcall)) bar(float *a) {
}
void __attribute__((fastcall(1))) baz(float *a) { // expected-error {{attribute requires 0 argument(s)}}
void __attribute__((fastcall(1))) baz(float *a) { // expected-error {{attribute takes no arguments}}
}
void __attribute__((fastcall)) test0() { // expected-error {{function with no prototype cannot use fastcall calling convention}}
@ -20,7 +20,7 @@ void __attribute__((fastcall)) test2(int a, ...) { // expected-error {{variadic
void __attribute__((cdecl)) ctest0() {}
void __attribute__((cdecl(1))) ctest1(float x) {} // expected-error {{attribute requires 0 argument(s)}}
void __attribute__((cdecl(1))) ctest1(float x) {} // expected-error {{attribute takes no arguments}}
void (__attribute__((fastcall)) *pfoo)(float*) = foo;

View File

@ -3,13 +3,13 @@
int x __attribute__((constructor)); // expected-warning {{'constructor' attribute only applies to functions}}
int f() __attribute__((constructor));
int f() __attribute__((constructor(1)));
int f() __attribute__((constructor(1,2))); // expected-error {{attribute requires 0 or 1 argument(s)}}
int f() __attribute__((constructor(1,2))); // expected-error {{attribute takes no more than 1 argument}}
int f() __attribute__((constructor(1.0))); // expected-error {{'constructor' attribute requires parameter 1 to be an integer constant}}
int x __attribute__((destructor)); // expected-warning {{'destructor' attribute only applies to functions}}
int f() __attribute__((destructor));
int f() __attribute__((destructor(1)));
int f() __attribute__((destructor(1,2))); // expected-error {{attribute requires 0 or 1 argument(s)}}
int f() __attribute__((destructor(1,2))); // expected-error {{attribute takes no more than 1 argument}}
int f() __attribute__((destructor(1.0))); // expected-error {{'destructor' attribute requires parameter 1 to be an integer constant}}

View File

@ -16,7 +16,7 @@ typedef __attribute__((neon_polyvector_type(16))) poly8_t poly8x16_t;
typedef __attribute__((neon_polyvector_type(8))) poly16_t poly16x8_t;
// The attributes must have a single argument.
typedef __attribute__((neon_vector_type(2, 4))) int only_one_arg; // expected-error{{attribute requires 1 argument(s)}}
typedef __attribute__((neon_vector_type(2, 4))) int only_one_arg; // expected-error{{attribute takes one argument}}
// The number of elements must be an ICE.
typedef __attribute__((neon_vector_type(2.0))) int non_int_width; // expected-error{{attribute requires integer constant}}

View File

@ -5,7 +5,7 @@ void f1(int a, ...) __attribute__ ((sentinel));
void f2(int a, ...) __attribute__ ((sentinel(1)));
void f3(int a, ...) __attribute__ ((sentinel("hello"))); //expected-error{{'sentinel' attribute requires parameter 1 to be an integer constant}}
void f4(int a, ...) __attribute__ ((sentinel(1, 2, 3))); //expected-error{{attribute requires 0, 1 or 2 argument(s)}}
void f4(int a, ...) __attribute__ ((sentinel(1, 2, 3))); //expected-error{{attribute takes no more than 2 arguments}}
void f4(int a, ...) __attribute__ ((sentinel(-1))); //expected-error{{parameter 1 less than zero}}
void f4(int a, ...) __attribute__ ((sentinel(0, 2))); // expected-error{{parameter 2 not 0 or 1}}

View File

@ -19,7 +19,7 @@ extern Two koo[];
Two foo __attribute__((init_priority(101))) ( 5, 6 );
Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{attribute requires 1 argument(s)}}
Two goo __attribute__((init_priority(2,3))) ( 5, 6 ); // expected-error {{attribute takes one argument}}
Two coo[2] __attribute__((init_priority(3))); // expected-error {{init_priority attribute requires integer constant between 101 and 65535 inclusive}}

View File

@ -4,5 +4,5 @@ static id __attribute((objc_gc(strong))) b;
static id __attribute((objc_gc())) c; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}}
static id __attribute((objc_gc(123))) d; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}}
static id __attribute((objc_gc(foo, 456))) e; // expected-error{{attribute requires 1 argument(s)}}
static id __attribute((objc_gc(foo, 456))) e; // expected-error{{attribute takes one argument}}
static id __attribute((objc_gc(hello))) f; // expected-warning{{'objc_gc' attribute argument not supported: 'hello'}}

View File

@ -5,16 +5,16 @@
extern NSString *fa2 (const NSString *) __attribute__((format_arg(1)));
extern NSString *fa3 (NSString *) __attribute__((format_arg(1)));
extern void fc1 (const NSString *) __attribute__((format_arg)); // expected-error {{attribute requires 1 argument(s)}}
extern void fc2 (const NSString *) __attribute__((format_arg())); // expected-error {{attribute requires 1 argument(s)}}
extern void fc3 (const NSString *) __attribute__((format_arg(1, 2))); // expected-error {{attribute requires 1 argument(s)}}
extern void fc1 (const NSString *) __attribute__((format_arg)); // expected-error {{attribute takes one argument}}
extern void fc2 (const NSString *) __attribute__((format_arg())); // expected-error {{attribute takes one argument}}
extern void fc3 (const NSString *) __attribute__((format_arg(1, 2))); // expected-error {{attribute takes one argument}}
struct s1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to functions}}
union u1 { int i; } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to functions}}
enum e1 { E1V0 } __attribute__((format_arg(1))); // expected-warning {{'format_arg' attribute only applies to functions}}
extern NSString *ff3 (const NSString *) __attribute__((format_arg(3-2)));
extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{attribute requires 1 argument(s)}}
extern NSString *ff4 (const NSString *) __attribute__((format_arg(foo))); // expected-error {{attribute takes one argument}}
/* format_arg formats must take and return a string. */
extern NSString *fi0 (int) __attribute__((format_arg(1))); // expected-error {{format argument not a string type}}

View File

@ -16,13 +16,13 @@
typedef void *PV;
@interface BAD {
__attribute__((iboutletcollection(I, 1))) id ivar1; // expected-error {{attribute requires 1 argument(s)}}
__attribute__((iboutletcollection(I, 1))) id ivar1; // expected-error {{attribute takes one argument}}
__attribute__((iboutletcollection(B))) id ivar2; // expected-error {{invalid type 'B' as argument of iboutletcollection attribute}}
__attribute__((iboutletcollection(PV))) id ivar3; // expected-error {{invalid type 'PV' as argument of iboutletcollection attribute}}
__attribute__((iboutletcollection(PV))) void *ivar4; // expected-error {{ivar with iboutletcollection attribute must have object type (invalid 'void *')}}
__attribute__((iboutletcollection(int))) id ivar5; // expected-error {{type argument of iboutletcollection attribute cannot be a builtin type}}
}
@property (nonatomic, retain) __attribute__((iboutletcollection(I,2,3))) id prop1; // expected-error {{attribute requires 1 argument(s)}}
@property (nonatomic, retain) __attribute__((iboutletcollection(I,2,3))) id prop1; // expected-error {{attribute takes one argument}}
@property (nonatomic, retain) __attribute__((iboutletcollection(B))) id prop2; // expected-error {{invalid type 'B' as argument of iboutletcollection attribute}}
@property __attribute__((iboutletcollection(BAD))) int prop3; // expected-error {{property with iboutletcollection attribute must have object type (invalid 'int')}}

View File

@ -13,7 +13,7 @@
- (void) foo8 : (int)x, ... __attribute__ ((__sentinel__("a"))); // expected-error {{'sentinel' attribute requires parameter 1 to be an integer constant}}
- (void) foo9 : (int)x, ... __attribute__ ((__sentinel__(-1))); // expected-error {{'sentinel' parameter 1 less than zero}}
- (void) foo10 : (int)x, ... __attribute__ ((__sentinel__(1,1)));
- (void) foo11 : (int)x, ... __attribute__ ((__sentinel__(1,1,3))); // expected-error {{attribute requires 0, 1 or 2 argument(s)}}
- (void) foo11 : (int)x, ... __attribute__ ((__sentinel__(1,1,3))); // expected-error {{attribute takes no more than 2 arguments}}
- (void) foo12 : (int)x, ... ATTR; // expected-note {{method has been explicitly marked sentinel here}}
// rdar://7975788