]> granicus.if.org Git - clang/commitdiff
Parser support for prefix __attribute__ on @protocol.
authorDaniel Dunbar <daniel@zuster.org>
Fri, 26 Sep 2008 04:48:09 +0000 (04:48 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Fri, 26 Sep 2008 04:48:09 +0000 (04:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56642 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticKinds.def
include/clang/Parse/Action.h
include/clang/Parse/Parser.h
lib/Parse/ParseObjc.cpp
lib/Parse/Parser.cpp
lib/Sema/Sema.h
lib/Sema/SemaDeclObjC.cpp
test/Parser/objc-quirks.m
test/Parser/prefix-attributes.m [new file with mode: 0644]

index 92e56ba80a07e6eb0e23d451cb87a685af98f93a..5d4d8931745d295f4982b6c80ed6d8a8e9fb0610 100644 (file)
@@ -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,
index a66d97dcb0d5fd058380cc0bafc3f350e1d16915..705d99ceedba56e16f2c1c62ec512948f2bf319c 100644 (file)
@@ -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
index 195398c705464e98e80d3b88f9804be70ca35daa..eb508d723441d280c7673b96733a2a91d23dfb64 100644 (file)
@@ -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;
 
index 8917eeb0ffa3685ac54673a3c7ba14f7c69e5aca..17488d523e4d6e44fec13f6f58a7b1e2e90e3c16 100644 (file)
@@ -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().
index 7598ff79969be21425a0af8caad6ec0d6ac07413..797de9284ecc2c71c1c2e506dfbc559ef42659a1 100644 (file)
@@ -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());
   }
 
index ef5954b6294cf7c12b9a21062d54e44097d482de..f553629a6c9305cfe411c8d922856a3f55aa58e3 100644 (file)
@@ -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,
index 1b166c4094ef3722439996613fe1aed884cc2b4a..a09daa0814b5ecf50b62aa179b2bd8a36e2825fe 100644 (file)
@@ -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) {
index af4f92610cac23bb6630d99c82ed3a42612eb365..b726d9a8274fce10557c4f3aa766a8f46534beac 100644 (file)
@@ -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/test/Parser/prefix-attributes.m b/test/Parser/prefix-attributes.m
new file mode 100644 (file)
index 0000000..46eb90c
--- /dev/null
@@ -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