]> granicus.if.org Git - clang/commitdiff
Recover from user typo not having proper @interface decl and a bad foreach decl.
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 10 Jan 2008 20:33:58 +0000 (20:33 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 10 Jan 2008 20:33:58 +0000 (20:33 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45839 91177308-0d34-0410-b5e6-96231b3b80d8

Sema/SemaDeclObjC.cpp
Sema/SemaStmt.cpp
test/Parser/objc-foreach-error-1.m [new file with mode: 0644]

index 89b7611d865add7dbe88362204d380576b3d34db..b2e7b7955663b4098ef95118e22e2142a7650be6 100644 (file)
@@ -43,9 +43,14 @@ void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
   PI.IdentLoc = SourceLocation(); // synthesized vars have a null location.
   PI.InvalidType = false;
   if (MDecl->isInstance()) {
-    QualType selfTy = Context.getObjCInterfaceType(MDecl->getClassInterface());
-    selfTy = Context.getPointerType(selfTy);
-    PI.TypeInfo = selfTy.getAsOpaquePtr();
+    ObjCInterfaceDecl *OID = MDecl->getClassInterface();
+    // There may be no interface context due to error in declaration of the 
+    // interface (which has been reported). Recover gracefully
+    if (OID) {
+      QualType selfTy = Context.getObjCInterfaceType(OID);
+      selfTy = Context.getPointerType(selfTy);
+      PI.TypeInfo = selfTy.getAsOpaquePtr();
+    }
   } else
     PI.TypeInfo = Context.getObjCIdType().getAsOpaquePtr();
   CurMethodDecl->setSelfDecl(ActOnParamDeclarator(PI, FnBodyScope));
index fbe9294b2035a5336ab6126f0e2da975aa927529..4cad4a9f66952693717943ced0524c39181f4d7e 100644 (file)
@@ -538,23 +538,25 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
   Stmt *First  = static_cast<Stmt*>(first);
   Expr *Second = static_cast<Expr*>(second);
   Stmt *Body  = static_cast<Stmt*>(body);
-  QualType FirstType;
-  if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {
-    FirstType = cast<ValueDecl>(DS->getDecl())->getType();
-    // C99 6.8.5p3: The declaration part of a 'for' statement shall only declare
-    // identifiers for objects having storage class 'auto' or 'register'.
-    ScopedDecl *D = DS->getDecl();
-    BlockVarDecl *BVD = cast<BlockVarDecl>(D);
-    if (!BVD->hasLocalStorage())
-      return Diag(BVD->getLocation(), diag::err_non_variable_decl_in_for);
-    if (D->getNextDeclarator())
-      return Diag(D->getLocation(), diag::err_toomany_element_decls);
+  if (First) {
+    QualType FirstType;
+    if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) {
+      FirstType = cast<ValueDecl>(DS->getDecl())->getType();
+      // C99 6.8.5p3: The declaration part of a 'for' statement shall only declare
+      // identifiers for objects having storage class 'auto' or 'register'.
+      ScopedDecl *D = DS->getDecl();
+      BlockVarDecl *BVD = cast<BlockVarDecl>(D);
+      if (!BVD->hasLocalStorage())
+        return Diag(BVD->getLocation(), diag::err_non_variable_decl_in_for);
+      if (D->getNextDeclarator())
+        return Diag(D->getLocation(), diag::err_toomany_element_decls);
+    }
+    else
+      FirstType = static_cast<Expr*>(first)->getType();
+    if (!isObjCObjectPointerType(FirstType))
+        Diag(ForLoc, diag::err_selector_element_type,
+             FirstType.getAsString(), First->getSourceRange());
   }
-  else
-    FirstType = static_cast<Expr*>(first)->getType();
-  if (!isObjCObjectPointerType(FirstType))
-      Diag(ForLoc, diag::err_selector_element_type,
-           FirstType.getAsString(), First->getSourceRange());
   if (Second) {
     DefaultFunctionArrayConversion(Second);
     QualType SecondType = Second->getType();
diff --git a/test/Parser/objc-foreach-error-1.m b/test/Parser/objc-foreach-error-1.m
new file mode 100644 (file)
index 0000000..693f12e
--- /dev/null
@@ -0,0 +1,25 @@
+// RUN: clang -fsyntax-only -verify %s
+
+ce MyList // expected-error {{expected '=', ',', ';', 'asm', or '__attribute__' after declarator}}
+@end
+
+
+@implementation MyList
+- (unsigned int)countByEnumeratingWithState:  (struct __objcFastEnumerationState *)state objects:  (id *)items count:(unsigned int)stackcount
+{
+     return 0;
+}
+@end
+
+
+int LOOP();
+
+@implementation MyList (BasicTest)  // expected-error {{cannot find interface declaration for 'MyList'}}
+- (void)compilerTestAgainst {
+MyList * el;  // expected-error {{use of undeclared identifier 'MyList'}}
+     for (el in @"foo")    // expected-error {{use of undeclared identifier 'el'}} \
+                          // expected-error {{cannot find interface declaration for 'NSConstantString'}}
+         { LOOP(); }
+}
+@end
+