summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticKinds.def2
-rw-r--r--clang/include/clang/Parse/Action.h3
-rw-r--r--clang/include/clang/Parse/Parser.h3
-rw-r--r--clang/lib/Parse/ParseObjc.cpp5
-rw-r--r--clang/lib/Parse/Parser.cpp11
-rw-r--r--clang/lib/Sema/Sema.h3
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp4
-rw-r--r--clang/test/Parser/objc-quirks.m3
-rw-r--r--clang/test/Parser/prefix-attributes.m8
9 files changed, 32 insertions, 10 deletions
diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def
index 92e56ba80a0..5d4d8931745 100644
--- a/clang/include/clang/Basic/DiagnosticKinds.def
+++ b/clang/include/clang/Basic/DiagnosticKinds.def
@@ -421,6 +421,8 @@ DIAG(err_objc_expected_equal, ERROR,
"setter/getter expects '=' followed by name")
DIAG(err_objc_expected_property_attr, ERROR,
"unknown property attribute detected")
+DIAG(err_objc_unexpected_attr, ERROR,
+ "prefix attribute must be followed by an interface or protocol")
DIAG(err_objc_property_attr_mutually_exclusive, ERROR,
"property attributes '%0' and '%1' are mutually exclusive")
DIAG(warn_objc_property_no_assignment_attribute, WARNING,
diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h
index a66d97dcb0d..705d99ceedb 100644
--- a/clang/include/clang/Parse/Action.h
+++ b/clang/include/clang/Parse/Action.h
@@ -694,7 +694,8 @@ public:
SourceLocation ProtocolLoc,
DeclTy * const *ProtoRefs,
unsigned NumProtoRefs,
- SourceLocation EndProtoLoc) {
+ SourceLocation EndProtoLoc,
+ AttributeList *AttrList) {
return 0;
}
// ActOnStartCategoryInterface - this action is called immdiately after
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 195398c7054..eb508d72344 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -331,7 +331,8 @@ private:
SourceLocation &EndProtoLoc);
void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
tok::ObjCKeywordKind contextKey);
- DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc);
+ DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
+ AttributeList *prefixAttrs = 0);
DeclTy *ObjCImpDecl;
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index 8917eeb0ffa..17488d523e4 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -920,7 +920,8 @@ void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl,
/// "@protocol identifier ;" should be resolved as "@protocol
/// identifier-list ;": objc-interface-decl-list may not start with a
/// semicolon in the first alternative if objc-protocol-refs are omitted.
-Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc) {
+Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
+ AttributeList *attrList) {
assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
"ParseObjCAtProtocolDeclaration(): Expected @protocol");
ConsumeToken(); // the "protocol" identifier
@@ -978,7 +979,7 @@ Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc) {
DeclTy *ProtoType =
Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc,
&ProtocolRefs[0], ProtocolRefs.size(),
- EndProtoLoc);
+ EndProtoLoc, attrList);
ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
// The @ sign was already consumed by ParseObjCInterfaceDeclList().
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 7598ff79969..797de9284ec 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -393,17 +393,22 @@ Parser::DeclTy *Parser::ParseDeclarationOrFunctionDefinition() {
return Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
}
- // ObjC2 allows prefix attributes on class interfaces.
+ // ObjC2 allows prefix attributes on class interfaces and protocols.
+ // FIXME: This still needs better diagnostics. We should only accept
+ // attributes here, no types, etc.
if (getLang().ObjC2 && Tok.is(tok::at)) {
SourceLocation AtLoc = ConsumeToken(); // the "@"
- if (!Tok.isObjCAtKeyword(tok::objc_interface)) {
- Diag(Tok, diag::err_objc_expected_property_attr);//FIXME:better diagnostic
+ if (!Tok.isObjCAtKeyword(tok::objc_interface) &&
+ !Tok.isObjCAtKeyword(tok::objc_protocol)) {
+ Diag(Tok, diag::err_objc_unexpected_attr);
SkipUntil(tok::semi); // FIXME: better skip?
return 0;
}
const char *PrevSpec = 0;
if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec))
Diag(AtLoc, diag::err_invalid_decl_spec_combination, PrevSpec);
+ if (Tok.isObjCAtKeyword(tok::objc_protocol))
+ return ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes());
return ParseObjCAtInterfaceDeclaration(AtLoc, DS.getAttributes());
}
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index ef5954b6294..f553629a6c9 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -686,7 +686,8 @@ public:
SourceLocation AtProtoInterfaceLoc,
IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
DeclTy * const *ProtoRefNames, unsigned NumProtoRefs,
- SourceLocation EndProtoLoc);
+ SourceLocation EndProtoLoc,
+ AttributeList *AttrList);
virtual DeclTy *ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
IdentifierInfo *ClassName,
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 1b166c4094e..a09daa0814b 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -173,7 +173,9 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
SourceLocation ProtocolLoc,
DeclTy * const *ProtoRefs,
unsigned NumProtoRefs,
- SourceLocation EndProtoLoc) {
+ SourceLocation EndProtoLoc,
+ AttributeList *AttrList) {
+ // FIXME: Deal with AttrList.
assert(ProtocolName && "Missing protocol identifier");
ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolName];
if (PDecl) {
diff --git a/clang/test/Parser/objc-quirks.m b/clang/test/Parser/objc-quirks.m
index af4f92610ca..b726d9a8274 100644
--- a/clang/test/Parser/objc-quirks.m
+++ b/clang/test/Parser/objc-quirks.m
@@ -1,3 +1,4 @@
// RUN: clang -fsyntax-only -verify %s
-int @"s" = 5; // expected-error {{unknown}}
+// FIXME: This is a horrible error message here. Fix.
+int @"s" = 5; // expected-error {{prefix attribute must be}}
diff --git a/clang/test/Parser/prefix-attributes.m b/clang/test/Parser/prefix-attributes.m
new file mode 100644
index 00000000000..46eb90cd2b3
--- /dev/null
+++ b/clang/test/Parser/prefix-attributes.m
@@ -0,0 +1,8 @@
+// RUN: clang -verify -fsyntax-only %s
+
+__attribute__((deprecated)) @class B; // expected-error {{prefix attribute must be followed by an interface or protocol}}
+
+__attribute__((deprecated)) @interface A @end
+__attribute__((deprecated)) @protocol P0;
+__attribute__((deprecated)) @protocol P1
+@end
OpenPOWER on IntegriCloud