From 69a7914fec813ab597d4e0d77c510fc0b0db8105 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Thu, 4 Apr 2013 00:15:10 +0000 Subject: [PATCH] Make the ObjC attributes diagnostics a bit more informative. llvm-svn: 178720 --- .../include/clang/Basic/DiagnosticParseKinds.td | 3 +++ clang/include/clang/Parse/Parser.h | 2 +- clang/lib/Parse/ParseObjc.cpp | 16 ++++++++++------ clang/test/Parser/attributes.mm | 10 +++++----- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 26820dbddfa2..04a433c0a6a2 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -401,6 +401,9 @@ def err_objc_unexpected_attr : Error< "prefix attribute must be followed by an interface or protocol">; def err_objc_postfix_attribute : Error < "postfix attributes are not allowed on Objective-C directives">; +def err_objc_postfix_attribute_hint : Error < + "postfix attributes are not allowed on Objective-C directives, place" + " them in front of '%select{@interface|@protocol}0'">; def err_objc_directive_only_in_protocol : Error< "directive may only be specified in protocols only">; def err_missing_catch_finally : Error< diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 7ff6f96ff99e..8cc60a29dfa3 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -1113,7 +1113,7 @@ private: ExprResult ParseAsmStringLiteral(); // Objective-C External Declarations - void MaybeSkipAttributes(); + void MaybeSkipAttributes(tok::ObjCKeywordKind Kind); DeclGroupPtrTy ParseObjCAtDirectives(); DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc); Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 844a3d12e931..ad95dd5821ce 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -23,10 +23,14 @@ using namespace clang; /// Skips attributes after an Objective-C @ directive. Emits a diagnostic. -void Parser::MaybeSkipAttributes() { +void Parser::MaybeSkipAttributes(tok::ObjCKeywordKind Kind) { ParsedAttributes attrs(AttrFactory); if (Tok.is(tok::kw___attribute)) { - Diag(Tok, diag::err_objc_postfix_attribute); + if (Kind == tok::objc_interface || Kind == tok::objc_protocol) + Diag(Tok, diag::err_objc_postfix_attribute_hint) + << (Kind == tok::objc_protocol); + else + Diag(Tok, diag::err_objc_postfix_attribute); ParseGNUAttributes(attrs); } } @@ -101,7 +105,7 @@ Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { while (1) { - MaybeSkipAttributes(); + MaybeSkipAttributes(tok::objc_class); if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); SkipUntil(tok::semi); @@ -188,7 +192,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, return 0; } - MaybeSkipAttributes(); + MaybeSkipAttributes(tok::objc_interface); if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); // missing class or category name. @@ -1408,7 +1412,7 @@ Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, return DeclGroupPtrTy(); } - MaybeSkipAttributes(); + MaybeSkipAttributes(tok::objc_protocol); if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); // missing protocol name. @@ -1501,7 +1505,7 @@ Parser::ParseObjCAtImplementationDeclaration(SourceLocation AtLoc) { return DeclGroupPtrTy(); } - MaybeSkipAttributes(); + MaybeSkipAttributes(tok::objc_implementation); if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); // missing class or category name. diff --git a/clang/test/Parser/attributes.mm b/clang/test/Parser/attributes.mm index 812d543e3e2a..d92e3d35cfbf 100644 --- a/clang/test/Parser/attributes.mm +++ b/clang/test/Parser/attributes.mm @@ -11,15 +11,15 @@ __attribute__((deprecated)) @protocol P1 class EXP C {}; EXP class C2 {}; // expected-warning {{attribute 'visibility' is ignored, place it after "class" to apply attribute to type declaration}} -@interface EXP I @end // expected-error {{postfix attributes are not allowed on Objective-C directives}} +@interface EXP I @end // expected-error {{postfix attributes are not allowed on Objective-C directives, place them in front of '@interface'}} EXP @interface I2 @end -@implementation EXP I @end // expected-error {{postfix attributes are not allowed on Objective-C directives}} +@implementation EXP I @end // expected-error-re {{postfix attributes are not allowed on Objective-C directives$}} // FIXME: Prefix attribute recovery skips until ';' -EXP @implementation I2 @end; // expected-error{{prefix attribute must be followed by an interface or protocol}} +EXP @implementation I2 @end; // expected-error {{prefix attribute must be followed by an interface or protocol}} -@class EXP OC; // expected-error {{postfix attributes are not allowed on Objective-C directives}} +@class EXP OC; // expected-error-re {{postfix attributes are not allowed on Objective-C directives$}} EXP @class OC2; // expected-error {{prefix attribute must be followed by an interface or protocol}} -@protocol EXP P @end // expected-error {{postfix attributes are not allowed on Objective-C directives}} +@protocol EXP P @end // expected-error {{postfix attributes are not allowed on Objective-C directives, place them in front of '@protocol'}} EXP @protocol P2 @end -- GitLab