[cfe-commits] r92449 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclObjC.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaLookup.cpp test/FixIt/typo.m test/SemaObjC/category-1.m test/SemaObjC/undef-class-messagin-error.m

Douglas Gregor dgregor at apple.com
Sun Jan 3 10:02:00 PST 2010


Author: dgregor
Date: Sun Jan  3 12:01:57 2010
New Revision: 92449

URL: http://llvm.org/viewvc/llvm-project?rev=92449&view=rev
Log:
Implement typo correction for a variety of Objective-C-specific
constructs:

  - Instance variable lookup ("foo->ivar" and, in instance methods, "ivar")
  - Property name lookup ("foo.prop")
  - Superclasses
  - Various places where a class name is required
  - Protocol names (e.g., id<proto>)

This seems to cover many of the common places where typos could occur.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/test/FixIt/typo.m
    cfe/trunk/test/SemaObjC/category-1.m
    cfe/trunk/test/SemaObjC/undef-class-messagin-error.m

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=92449&r1=92448&r2=92449&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Jan  3 12:01:57 2010
@@ -2569,6 +2569,17 @@
 def err_field_designator_unknown_suggest : Error<
   "field designator %0 does not refer to any field in type %1; did you mean "
   "%2?">;
+def err_typecheck_member_reference_ivar_suggest : Error<
+  "%0 does not have a member named %1; did you mean %2?">;
+def err_property_not_found_suggest : Error<
+  "property %0 not found on object of type %1; did you mean %2?">;
+def err_undef_interface_suggest : Error<
+  "cannot find interface declaration for %0; did you mean %1?">;
+def err_undef_superclass_suggest : Error<
+  "cannot find interface declaration for %0, superclass of %1; did you mean "
+  "%2?">;
+def err_undeclared_protocol_suggest : Error<
+  "cannot find protocol declaration for %0; did you mean %1?">;
 
 }
 

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=92449&r1=92448&r2=92449&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sun Jan  3 12:01:57 2010
@@ -1208,7 +1208,8 @@
 
   bool CorrectTypo(LookupResult &R, Scope *S, const CXXScopeSpec *SS,
                    DeclContext *MemberContext = 0,
-                   bool EnteringContext = false);
+                   bool EnteringContext = false,
+                   const ObjCObjectPointerType *OPT = 0);
 
   void FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
                                    AssociatedNamespaceSet &AssociatedNamespaces,
@@ -1217,7 +1218,8 @@
   bool DiagnoseAmbiguousLookup(LookupResult &Result);
   //@}
 
-  ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
+  ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id,
+                                 SourceLocation RecoverLoc = SourceLocation());
   NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
                                  Scope *S, bool ForRedeclaration,
                                  SourceLocation Loc);

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=92449&r1=92448&r2=92449&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Jan  3 12:01:57 2010
@@ -555,11 +555,35 @@
 
 /// getObjCInterfaceDecl - Look up a for a class declaration in the scope.
 /// return 0 if one not found.
-ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
+///
+/// \param Id the name of the Objective-C class we're looking for. If
+/// typo-correction fixes this name, the Id will be updated
+/// to the fixed name.
+///
+/// \param RecoverLoc if provided, this routine will attempt to
+/// recover from a typo in the name of an existing Objective-C class
+/// and, if successful, will return the lookup that results from
+/// typo-correction.
+ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id,
+                                              SourceLocation RecoverLoc) {
   // The third "scope" argument is 0 since we aren't enabling lazy built-in
   // creation from this context.
   NamedDecl *IDecl = LookupSingleName(TUScope, Id, LookupOrdinaryName);
 
+  if (!IDecl && !RecoverLoc.isInvalid()) {
+    // Perform typo correction at the given location, but only if we
+    // find an Objective-C class name.
+    LookupResult R(*this, Id, RecoverLoc, LookupOrdinaryName);
+    if (CorrectTypo(R, TUScope, 0) &&
+        (IDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
+      Diag(RecoverLoc, diag::err_undef_interface_suggest)
+        << Id << IDecl->getDeclName() 
+        << CodeModificationHint::CreateReplacement(RecoverLoc, 
+                                                   IDecl->getNameAsString());
+      Id = IDecl->getIdentifier();
+    }
+  }
+
   return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl);
 }
 

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=92449&r1=92448&r2=92449&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Sun Jan  3 12:01:57 2010
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Sema.h"
+#include "Lookup.h"
 #include "clang/Sema/ExternalSemaSource.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ASTContext.h"
@@ -133,6 +134,17 @@
   if (SuperName) {
     // Check if a different kind of symbol declared in this scope.
     PrevDecl = LookupSingleName(TUScope, SuperName, LookupOrdinaryName);
+
+    if (!PrevDecl) {
+      // Try to correct for a typo in the superclass name.
+      LookupResult R(*this, SuperName, SuperLoc, LookupOrdinaryName);
+      if (CorrectTypo(R, TUScope, 0) &&
+          (PrevDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
+        Diag(SuperLoc, diag::err_undef_superclass_suggest)
+          << SuperName << ClassName << PrevDecl->getDeclName();
+      }
+    }
+
     if (PrevDecl == IDecl) {
       Diag(SuperLoc, diag::err_recursive_superclass)
         << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
@@ -317,6 +329,16 @@
   for (unsigned i = 0; i != NumProtocols; ++i) {
     ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolId[i].first);
     if (!PDecl) {
+      LookupResult R(*this, ProtocolId[i].first, ProtocolId[i].second,
+                     LookupObjCProtocolName);
+      if (CorrectTypo(R, TUScope, 0) &&
+          (PDecl = R.getAsSingle<ObjCProtocolDecl>())) {
+        Diag(ProtocolId[i].second, diag::err_undeclared_protocol_suggest)
+          << ProtocolId[i].first << R.getLookupName();
+      }
+    }
+
+    if (!PDecl) {
       Diag(ProtocolId[i].second, diag::err_undeclared_protocol)
         << ProtocolId[i].first;
       continue;
@@ -568,7 +590,7 @@
   // FIXME: PushOnScopeChains?
   CurContext->addDecl(CDecl);
 
-  ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
+  ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc);
   /// Check that class of this category is already completely declared.
   if (!IDecl || IDecl->isForwardDecl()) {
     CDecl->setInvalidDecl();
@@ -616,7 +638,7 @@
                       SourceLocation AtCatImplLoc,
                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
                       IdentifierInfo *CatName, SourceLocation CatLoc) {
-  ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
+  ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc);
   ObjCCategoryDecl *CatIDecl = 0;
   if (IDecl) {
     CatIDecl = IDecl->FindCategoryDeclaration(CatName);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=92449&r1=92448&r2=92449&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Jan  3 12:01:57 2010
@@ -1059,6 +1059,16 @@
 
       assert(!R.empty() &&
              "DiagnoseEmptyLookup returned false but added no results");
+
+      // If we found an Objective-C instance variable, let
+      // LookupInObjCMethod build the appropriate expression to
+      // reference the ivar. 
+      if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) {
+        R.clear();
+        OwningExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
+        assert(E.isInvalid() || E.get());
+        return move(E);
+      }
     }
   }
 
@@ -2848,6 +2858,20 @@
       ObjCInterfaceDecl *ClassDeclared;
       ObjCIvarDecl *IV = IDecl->lookupInstanceVariable(Member, ClassDeclared);
 
+      if (!IV) {
+        // Attempt to correct for typos in ivar names.
+        LookupResult Res(*this, R.getLookupName(), R.getNameLoc(),
+                         LookupMemberName);
+        if (CorrectTypo(Res, 0, 0, IDecl) &&
+            (IV = Res.getAsSingle<ObjCIvarDecl>())) {
+          Diag(R.getNameLoc(), 
+               diag::err_typecheck_member_reference_ivar_suggest)
+            << IDecl->getDeclName() << MemberName << IV->getDeclName()
+            << CodeModificationHint::CreateReplacement(R.getNameLoc(),
+                                                       IV->getNameAsString());
+        }
+      }
+
       if (IV) {
         // If the decl being referenced had an error, return an error for this
         // sub-expr without emitting another error, in order to avoid cascading
@@ -3014,6 +3038,20 @@
       return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType,
                                       Setter, MemberLoc, BaseExpr));
     }
+
+    // Attempt to correct for typos in property names.
+    LookupResult Res(*this, R.getLookupName(), R.getNameLoc(),
+                     LookupOrdinaryName);
+    if (CorrectTypo(Res, 0, 0, IFace, false, OPT) && 
+        Res.getAsSingle<ObjCPropertyDecl>()) {
+      Diag(R.getNameLoc(), diag::err_property_not_found_suggest)
+        << MemberName << BaseType << Res.getLookupName()
+        << CodeModificationHint::CreateReplacement(R.getNameLoc(),
+                                           Res.getLookupName().getAsString());
+      return LookupMemberExpr(Res, BaseExpr, IsArrow, OpLoc, SS,
+                              FirstQualifierInScope, ObjCImpDecl);
+    }
+
     return ExprError(Diag(MemberLoc, diag::err_property_not_found)
       << MemberName << BaseType);
   }

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=92449&r1=92448&r2=92449&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Sun Jan  3 12:01:57 2010
@@ -287,7 +287,8 @@
   SourceLocation &receiverNameLoc,
   SourceLocation &propertyNameLoc) {
 
-  ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(&receiverName);
+  IdentifierInfo *receiverNamePtr = &receiverName;
+  ObjCInterfaceDecl *IFace = getObjCInterfaceDecl(receiverNamePtr);
 
   // Search for a declared property first.
 
@@ -400,7 +401,7 @@
       return Diag(receiverLoc, diag::err_undeclared_var_use) << receiverName;
     }
   } else
-    ClassDecl = getObjCInterfaceDecl(receiverName);
+    ClassDecl = getObjCInterfaceDecl(receiverName, receiverLoc);
 
   // The following code allows for the following GCC-ism:
   //

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=92449&r1=92448&r2=92449&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Sun Jan  3 12:01:57 2010
@@ -1913,7 +1913,7 @@
     }
   }
 
-  // Traverse the contexts of inherited classes.
+  // Traverse the contexts of inherited C++ classes.
   if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
     for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
                                          BEnd = Record->bases_end();
@@ -1955,7 +1955,42 @@
     }
   }
   
-  // FIXME: Look into base classes in Objective-C!
+  // Traverse the contexts of Objective-C classes.
+  if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Ctx)) {
+    // Traverse categories.
+    for (ObjCCategoryDecl *Category = IFace->getCategoryList();
+         Category; Category = Category->getNextClassCategory()) {
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(Category, Result, QualifiedNameLookup, Consumer, 
+                         Visited);
+    }
+
+    // Traverse protocols.
+    for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
+         E = IFace->protocol_end(); I != E; ++I) {
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(*I, Result, QualifiedNameLookup, Consumer, Visited);
+    }
+
+    // Traverse the superclass.
+    if (IFace->getSuperClass()) {
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(IFace->getSuperClass(), Result, QualifiedNameLookup,
+                         Consumer, Visited);
+    }
+  } else if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Ctx)) {
+    for (ObjCProtocolDecl::protocol_iterator I = Protocol->protocol_begin(),
+           E = Protocol->protocol_end(); I != E; ++I) {
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(*I, Result, QualifiedNameLookup, Consumer, Visited);
+    }
+  } else if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Ctx)) {
+    for (ObjCCategoryDecl::protocol_iterator I = Category->protocol_begin(),
+           E = Category->protocol_end(); I != E; ++I) {
+      ShadowContextRAII Shadow(Visited);
+      LookupVisibleDecls(*I, Result, QualifiedNameLookup, Consumer, Visited);
+    }
+  }
 }
 
 static void LookupVisibleDecls(Scope *S, LookupResult &Result,
@@ -1975,6 +2010,22 @@
     
     for (DeclContext *Ctx = Entity; Ctx && Ctx->getPrimaryContext() != OuterCtx;
          Ctx = Ctx->getLookupParent()) {
+      if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(Ctx)) {
+        if (Method->isInstanceMethod()) {
+          // For instance methods, look for ivars in the method's interface.
+          LookupResult IvarResult(Result.getSema(), Result.getLookupName(),
+                                  Result.getNameLoc(), Sema::LookupMemberName);
+          ObjCInterfaceDecl *IFace = Method->getClassInterface();
+          LookupVisibleDecls(IFace, IvarResult, /*QualifiedNameLookup=*/false, 
+                             Consumer, Visited);
+        }
+
+        // We've already performed all of the name lookup that we need
+        // to for Objective-C methods; the next context will be the
+        // outer scope.
+        break;
+      }
+
       if (Ctx->isFunctionOrMethod())
         continue;
       
@@ -2139,11 +2190,15 @@
 /// \param EnteringContext whether we're entering the context described by 
 /// the nested-name-specifier SS.
 ///
+/// \param OPT when non-NULL, the search for visible declarations will
+/// also walk the protocols in the qualified interfaces of \p OPT.
+///
 /// \returns true if the typo was corrected, in which case the \p Res
 /// structure will contain the results of name lookup for the
 /// corrected name. Otherwise, returns false.
 bool Sema::CorrectTypo(LookupResult &Res, Scope *S, const CXXScopeSpec *SS,
-                       DeclContext *MemberContext, bool EnteringContext) {
+                       DeclContext *MemberContext, bool EnteringContext,
+                       const ObjCObjectPointerType *OPT) {
   // We only attempt to correct typos for identifiers.
   IdentifierInfo *Typo = Res.getLookupName().getAsIdentifierInfo();
   if (!Typo)
@@ -2160,9 +2215,17 @@
     return false;
 
   TypoCorrectionConsumer Consumer(Typo);
-  if (MemberContext)
+  if (MemberContext) {
     LookupVisibleDecls(MemberContext, Res.getLookupKind(), Consumer);
-  else if (SS && SS->isSet()) {
+
+    // Look in qualified interfaces.
+    if (OPT) {
+      for (ObjCObjectPointerType::qual_iterator 
+             I = OPT->qual_begin(), E = OPT->qual_end(); 
+           I != E; ++I)
+        LookupVisibleDecls(*I, Res.getLookupKind(), Consumer);
+    }
+  } else if (SS && SS->isSet()) {
     DeclContext *DC = computeDeclContext(*SS, EnteringContext);
     if (!DC)
       return false;
@@ -2179,10 +2242,22 @@
   // have overloads of that name, though).
   TypoCorrectionConsumer::iterator I = Consumer.begin();
   DeclarationName BestName = (*I)->getDeclName();
+
+  // If we've found an Objective-C ivar or property, don't perform
+  // name lookup again; we'll just return the result directly.
+  NamedDecl *FoundBest = 0;
+  if (isa<ObjCIvarDecl>(*I) || isa<ObjCPropertyDecl>(*I))
+    FoundBest = *I;
   ++I;
   for(TypoCorrectionConsumer::iterator IEnd = Consumer.end(); I != IEnd; ++I) {
     if (BestName != (*I)->getDeclName())
       return false;
+
+    // FIXME: If there are both ivars and properties of the same name,
+    // don't return both because the callee can't handle two
+    // results. We really need to separate ivar lookup from property
+    // lookup to avoid this problem.
+    FoundBest = 0;
   }
 
   // BestName is the closest viable name to what the user
@@ -2197,8 +2272,16 @@
   // success if we found something that was not ambiguous.
   Res.clear();
   Res.setLookupName(BestName);
-  if (MemberContext)
+
+  // If we found an ivar or property, add that result; no further
+  // lookup is required.
+  if (FoundBest)
+    Res.addDecl(FoundBest);  
+  // If we're looking into the context of a member, perform qualified
+  // name lookup on the best name.
+  else if (MemberContext)
     LookupQualifiedName(Res, MemberContext);
+  // Perform lookup as if we had just parsed the best name.
   else
     LookupParsedName(Res, S, SS, /*AllowBuiltinCreation=*/false, 
                      EnteringContext);

Modified: cfe/trunk/test/FixIt/typo.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/typo.m?rev=92449&r1=92448&r2=92449&view=diff

==============================================================================
--- cfe/trunk/test/FixIt/typo.m (original)
+++ cfe/trunk/test/FixIt/typo.m Sun Jan  3 12:01:57 2010
@@ -1,9 +1,89 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
+// FIXME: the test below isn't testing quite what we want...
 // RUN: %clang_cc1 -fsyntax-only -fixit -o - %s | %clang_cc1 -fsyntax-only -pedantic -Werror -x objective-c -
 
 @interface NSString
++ (int)method:(int)x;
 @end
 
 void test() {
+  // FIXME: not providing fix-its
   NSstring *str = @"A string"; // expected-error{{use of undeclared identifier 'NSstring'; did you mean 'NSString'?}}
 }
+
+ at protocol P1
+ at property int *sprop;
+ at end
+
+ at interface A
+{
+  int his_ivar;
+  float wibble;
+}
+
+ at property int his_prop;
+ at end
+
+ at interface B : A <P1>
+{
+  int her_ivar;
+}
+
+ at property int her_prop;
+- (void)inst_method1:(int)a;
++ (void)class_method1;
+ at end
+
+ at implementation A
+ at synthesize his_prop = his_ivar;
+ at end
+
+ at implementation B
+ at synthesize her_prop = her_ivar;
+
+-(void)inst_method1:(int)a {
+  herivar = a; // expected-error{{use of undeclared identifier 'herivar'; did you mean 'her_ivar'?}}
+  hisivar = a; // expected-error{{use of undeclared identifier 'hisivar'; did you mean 'his_ivar'?}}
+  self->herivar = a; // expected-error{{'B' does not have a member named 'herivar'; did you mean 'her_ivar'?}}
+  self->hisivar = a; // expected-error{{'B' does not have a member named 'hisivar'; did you mean 'his_ivar'?}}
+  self.hisprop = 0; // expected-error{{property 'hisprop' not found on object of type 'B *'; did you mean 'his_prop'?}}
+  self.herprop = 0; // expected-error{{property 'herprop' not found on object of type 'B *'; did you mean 'her_prop'?}}
+  self.s_prop = 0; // expected-error{{property 's_prop' not found on object of type 'B *'; did you mean 'sprop'?}}
+}
+
++(void)class_method1 {
+}
+ at end
+
+void test_message_send(B* b) {
+  // FIXME: Not providing fix-its
+  [NSstring method:17]; // expected-error{{use of undeclared identifier 'NSstring'; did you mean 'NSString'?}}
+}
+
+ at interface Collide
+{
+ at public
+  int value;
+}
+
+ at property int value;
+ at end
+
+ at implementation Collide
+ at synthesize value = value;
+ at end
+
+void test2(Collide *a) {
+  a.valu = 17; // expected-error{{property 'valu' not found on object of type 'Collide *'; did you mean 'value'?}}
+  a->vale = 17; // expected-error{{'Collide' does not have a member named 'vale'; did you mean 'value'?}}
+}
+
+ at interface Derived : Collid // expected-error{{cannot find interface declaration for 'Collid', superclass of 'Derived'; did you mean 'Collide'?}}
+ at end
+
+ at protocol NetworkSocket
+- (int)send:(void*)buffer bytes:(int)bytes;
+ at end
+
+ at interface IPv8 <Network_Socket> // expected-error{{cannot find protocol declaration for 'Network_Socket'; did you mean 'NetworkSocket'?}}
+ at end

Modified: cfe/trunk/test/SemaObjC/category-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/category-1.m?rev=92449&r1=92448&r2=92449&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/category-1.m (original)
+++ cfe/trunk/test/SemaObjC/category-1.m Sun Jan  3 12:01:57 2010
@@ -29,7 +29,7 @@
 
 @interface MyClass1 (Category) <p2, p3> @end  // expected-warning {{cannot find protocol definition for 'p2'}}
 
- at interface MyClass  (Category) @end // expected-error {{cannot find interface declaration for 'MyClass'}}
+ at interface UnknownClass  (Category) @end // expected-error {{cannot find interface declaration for 'UnknownClass'}}
 
 @class MyClass2;
 

Modified: cfe/trunk/test/SemaObjC/undef-class-messagin-error.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/undef-class-messagin-error.m?rev=92449&r1=92448&r2=92449&view=diff

==============================================================================
--- cfe/trunk/test/SemaObjC/undef-class-messagin-error.m (original)
+++ cfe/trunk/test/SemaObjC/undef-class-messagin-error.m Sun Jan  3 12:01:57 2010
@@ -4,10 +4,10 @@
 + (int) flashCache;
 @end
 
- at interface Child (Categ) // expected-error {{cannot find interface declaration for 'Child'}}
+ at interface Child (Categ) // expected-error {{cannot find interface declaration for 'Child'; did you mean '_Child'?}}
 + (int) flushCache2;
 @end
 
- at implementation Child (Categ) // expected-error {{cannot find interface declaration for 'Child'}}
+ at implementation OtherChild (Categ) // expected-error {{cannot find interface declaration for 'OtherChild'}}
 + (int) flushCache2 { [super flashCache]; } // expected-error {{no @interface declaration found in class messaging of 'flushCache2'}}
 @end





More information about the cfe-commits mailing list