[cfe-commits] r100248 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td lib/Parse/ParseObjc.cpp test/Parser/check-syntax-1.m

Fariborz Jahanian fjahanian at apple.com
Fri Apr 2 16:15:40 PDT 2010


Author: fjahanian
Date: Fri Apr  2 18:15:40 2010
New Revision: 100248

URL: http://llvm.org/viewvc/llvm-project?rev=100248&view=rev
Log:
Improve diagnosing when a method type does not start with '-'|'+'
when parsing. Fixes radar 7822196.

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

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=100248&r1=100247&r2=100248&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Fri Apr  2 18:15:40 2010
@@ -182,6 +182,8 @@
   "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">;

Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=100248&r1=100247&r2=100248&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Fri Apr  2 18:15:40 2010
@@ -142,12 +142,11 @@
   // 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 @@
     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 @@
       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);
+      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))
+      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 @@
     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 @@
                        "", 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();

Modified: cfe/trunk/test/Parser/check-syntax-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/check-syntax-1.m?rev=100248&r1=100247&r2=100248&view=diff
==============================================================================
--- cfe/trunk/test/Parser/check-syntax-1.m (original)
+++ cfe/trunk/test/Parser/check-syntax-1.m Fri Apr  2 18:15:40 2010
@@ -9,3 +9,13 @@
                                                       // expected-error {{ expected ';' after method prototype}}
 @end
 
+// rdar: // 7822196
+ at 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;
+ at end
+
+





More information about the cfe-commits mailing list