[cfe-commits] r55215 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def lib/Parse/ParseObjc.cpp test/SemaObjC/method-def-1.m

Chris Lattner sabre at nondot.org
Fri Aug 22 18:48:04 PDT 2008


Author: lattner
Date: Fri Aug 22 20:48:03 2008
New Revision: 55215

URL: http://llvm.org/viewvc/llvm-project?rev=55215&view=rev
Log:
Fix a FIXME by not creating an invalid AST on erroneous input.  Also 
make diagnostic output in some other malformed cases significantly
more useful.  This fixes PR2708

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/lib/Parse/ParseObjc.cpp
    cfe/trunk/test/SemaObjC/method-def-1.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=55215&r1=55214&r2=55215&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri Aug 22 20:48:03 2008
@@ -322,8 +322,8 @@
      "parse error")
 DIAG(err_expected_expression, ERROR,
      "expected expression")
-DIAG(err_invalid_receiver_to_message, ERROR,
-     "invalid receiver to message expression")
+DIAG(err_expected_type, ERROR,
+     "expected a type")
 DIAG(err_expected_external_declaration, ERROR,
      "expected external declaration")
 DIAG(err_expected_ident, ERROR,
@@ -386,6 +386,8 @@
      "expected string literal")
 DIAG(err_expected_asm_operand, ERROR,
      "expected string literal or '[' for asm operand")
+DIAG(err_expected_selector_for_method, ERROR,
+     "expected selector for Objective-C method")
 
 DIAG(err_unexpected_at, ERROR,
      "unexpected '@' in program")
@@ -409,6 +411,8 @@
 DIAG(warn_objc_array_of_interfaces, WARNING,
      "array of interface '%0' should probably be an array of pointers")
 
+DIAG(err_invalid_receiver_to_message, ERROR,
+     "invalid receiver to message expression")
 DIAG(err_objc_illegal_visibility_spec, ERROR,
      "illegal visibility specification")
 DIAG(err_objc_illegal_interface_qual, ERROR,

Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=55215&r1=55214&r2=55215&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Fri Aug 22 20:48:03 2008
@@ -561,6 +561,7 @@
   assert(Tok.is(tok::l_paren) && "expected (");
   
   SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
+  SourceLocation TypeStartLoc = Tok.getLocation();
   TypeTy *Ty = 0;
   
   // Parse type qualifiers, in, inout, etc.
@@ -571,9 +572,17 @@
     // FIXME: back when Sema support is in place...
     // assert(Ty && "Parser::ParseObjCTypeName(): missing type");
   }
+  
   if (Tok.isNot(tok::r_paren)) {
-    MatchRHSPunctuation(tok::r_paren, LParenLoc);
-    return 0; // FIXME: decide how we want to handle this error...
+    // If we didn't eat any tokens, then this isn't a type.
+    if (Tok.getLocation() == TypeStartLoc) {
+      Diag(Tok.getLocation(), diag::err_expected_type);
+      SkipUntil(tok::r_brace);
+    } else {
+      // Otherwise, we found *something*, but didn't get a ')' in the right
+      // place.  Emit an error then return what we have as the type.
+      MatchRHSPunctuation(tok::r_paren, LParenLoc);
+    }
   }
   RParenLoc = ConsumeParen();
   return Ty;
@@ -612,20 +621,24 @@
                                             DeclTy *IDecl,
                                             tok::ObjCKeywordKind MethodImplKind)
 {
-  // Parse the return type.
+  // Parse the return type if present.
   TypeTy *ReturnType = 0;
   ObjCDeclSpec DSRet;
   if (Tok.is(tok::l_paren))
     ReturnType = ParseObjCTypeName(DSRet);
+  
   SourceLocation selLoc;
   IdentifierInfo *SelIdent = ParseObjCSelector(selLoc);
+
+  if (!SelIdent) { // missing selector name.
+    Diag(Tok.getLocation(), diag::err_expected_selector_for_method,
+         SourceRange(mLoc, Tok.getLocation()));
+    // Skip until we get a ; or {}.
+    SkipUntil(tok::r_brace);
+    return 0;
+  }
+  
   if (Tok.isNot(tok::colon)) {
-    if (!SelIdent) {
-      Diag(Tok, diag::err_expected_ident); // missing selector name.
-      // FIXME: this creates a unary selector with a null identifier, is this
-      // ok??  Maybe we should skip to the next semicolon or something.
-    }
-    
     // If attributes exist after the method, parse them.
     AttributeList *MethodAttrs = 0;
     if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) 
@@ -653,9 +666,8 @@
     }
     ConsumeToken(); // Eat the ':'.
     ObjCDeclSpec DSType;
-    if (Tok.is(tok::l_paren))  { // Parse the argument type.
+    if (Tok.is(tok::l_paren)) // Parse the argument type.
       TypeInfo = ParseObjCTypeName(DSType);
-    }
     else
       TypeInfo = 0;
     KeyTypes.push_back(TypeInfo);

Modified: cfe/trunk/test/SemaObjC/method-def-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/method-def-1.m?rev=55215&r1=55214&r2=55215&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/method-def-1.m (original)
+++ cfe/trunk/test/SemaObjC/method-def-1.m Fri Aug 22 20:48:03 2008
@@ -1,4 +1,4 @@
-// RUN: clang -fsyntax-only %s
+// RUN: clang -fsyntax-only -verify %s
 
 @interface foo
 - (int)meth;
@@ -8,3 +8,14 @@
 - (int) meth { return [self meth]; }
 @end
 
+// PR2708
+ at interface MyClass
++- (void)myMethod;   // expected-error {{expected selector for Objective-C method}}
+- (vid)myMethod2;    // expected-error {{expected a type}}
+ at end
+
+ at implementation MyClass
+- (void)myMethod { }
+- (void)myMethod2 { }
+ at end
+





More information about the cfe-commits mailing list