]> granicus.if.org Git - clang/commitdiff
Improve diagnosing when a method type does not start with '-'|'+'
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 2 Apr 2010 23:15:40 +0000 (23:15 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 2 Apr 2010 23:15:40 +0000 (23:15 +0000)
when parsing. Fixes radar 7822196.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100248 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseObjc.cpp
test/Parser/check-syntax-1.m

index facf15f52e85e4d97c30506fc0cf7d57a9c07d50..3e0956fb946040b0dbddc692a3bd3e2aae3c00cc 100644 (file)
@@ -182,6 +182,8 @@ def err_unexected_colon_in_nested_name_spec : Error<
   "unexpected ':' in nested name specifier">;
 
 /// Objective-C parser diagnostics
+def err_expected_minus_or_plus : Error<
+  "method type specifier must start with '-' or '+'">;
 def err_objc_no_attributes_on_category : Error<
   "attributes may not be specified on a category">;
 def err_objc_missing_end : Error<"missing @end">;
index 9a3473f042ed560af0ad5a2c91342ab1767998a5..243be0ed45aec71f890daab914ae41b37238ddc8 100644 (file)
@@ -142,12 +142,11 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
   // We have a class or category name - consume it.
   IdentifierInfo *nameId = Tok.getIdentifierInfo();
   SourceLocation nameLoc = ConsumeToken();
-
+  bool Err = false;
   if (Tok.is(tok::l_paren)) { // we have a category.
     SourceLocation lparenLoc = ConsumeParen();
     SourceLocation categoryLoc, rparenLoc;
     IdentifierInfo *categoryId = 0;
-
     if (Tok.is(tok::code_completion)) {
       Actions.CodeCompleteObjCInterfaceCategory(CurScope, nameId);
       ConsumeToken();
@@ -157,7 +156,14 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
     if (Tok.is(tok::identifier)) {
       categoryId = Tok.getIdentifierInfo();
       categoryLoc = ConsumeToken();
-    } else if (!getLang().ObjC2) {
+    }
+    else if (isKnownToBeTypeSpecifier(Tok)) {
+      // Fall thru after diagnosing for better error recovery.
+      Diag(Tok, diag::err_expected_minus_or_plus);
+      ConsumeToken();
+      Err = true;
+    }
+    else if (!getLang().ObjC2) {
       Diag(Tok, diag::err_expected_ident); // missing category name.
       return DeclPtrTy();
     }
@@ -167,33 +173,34 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
       return DeclPtrTy();
     }
     rparenLoc = ConsumeParen();
-
-    // Next, we need to check for any protocol references.
-    SourceLocation LAngleLoc, EndProtoLoc;
-    llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
-    llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
-    if (Tok.is(tok::less) &&
-        ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
+    if (!Err) {
+      // Next, we need to check for any protocol references.
+      SourceLocation LAngleLoc, EndProtoLoc;
+      llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
+      llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
+      if (Tok.is(tok::less) &&
+          ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
                                     LAngleLoc, EndProtoLoc))
-      return DeclPtrTy();
+        return DeclPtrTy();
 
-    if (attrList) // categories don't support attributes.
-      Diag(Tok, diag::err_objc_no_attributes_on_category);
-
-    DeclPtrTy CategoryType =
-      Actions.ActOnStartCategoryInterface(atLoc,
-                                          nameId, nameLoc,
-                                          categoryId, categoryLoc,
-                                          ProtocolRefs.data(),
-                                          ProtocolRefs.size(),
-                                          ProtocolLocs.data(),
-                                          EndProtoLoc);
-    if (Tok.is(tok::l_brace))
+      if (attrList) // categories don't support attributes.
+        Diag(Tok, diag::err_objc_no_attributes_on_category);
+
+      DeclPtrTy CategoryType =
+        Actions.ActOnStartCategoryInterface(atLoc,
+                                            nameId, nameLoc,
+                                            categoryId, categoryLoc,
+                                            ProtocolRefs.data(),
+                                            ProtocolRefs.size(),
+                                            ProtocolLocs.data(),
+                                            EndProtoLoc);
+        if (Tok.is(tok::l_brace))
       ParseObjCClassInstanceVariables(CategoryType, tok::objc_private,
                                       atLoc);
     
-    ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
-    return CategoryType;
+      ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
+      return CategoryType;
+    }
   }
   // Parse a class interface.
   IdentifierInfo *superClassId = 0;
@@ -235,7 +242,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
     ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
 
   ParseObjCInterfaceDeclList(ClsType, tok::objc_interface);
-  return ClsType;
+  return Err ? DeclPtrTy() : ClsType;
 }
 
 /// The Objective-C property callback.  This should be defined where
@@ -328,7 +335,14 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
                        "", tok::semi);
       continue;
     }
-
+    if (Tok.is(tok::l_paren)) {
+      Diag(Tok, diag::err_expected_minus_or_plus);
+      DeclPtrTy methodPrototype = ParseObjCMethodDecl(Tok.getLocation(), 
+                                                      tok::minus, 
+                                                      interfaceDecl,
+                                                      MethodImplKind);
+      continue;
+    }
     // Ignore excess semicolons.
     if (Tok.is(tok::semi)) {
       ConsumeToken();
index a1999def5982711eadf9254b53983eaffec764f0..085ff4cf67a1b97875a26af3b2904c1b96894823 100644 (file)
@@ -9,3 +9,13 @@ typedef float CGFloat;
                                                       // expected-error {{ expected ';' after method prototype}}
 @end
 
+// rdar: // 7822196
+@interface A
+(void) x;      // expected-error {{method type specifier must start with '-' or '+'}} \
+               // expected-warning {{type specifier missing, defaults to 'int' [-Wimplicit-int]}} \
+               // expected-error {{cannot declare variable inside @interface or @protocol}}
+(int)im; // expected-error {{method type specifier must start with '-' or '+'}} \
+- ok;
+@end
+
+