]> granicus.if.org Git - clang/commitdiff
When typo correction for an id-expression finds a type (or Objective-C
authorDouglas Gregor <dgregor@apple.com>
Fri, 1 Jan 2010 00:15:04 +0000 (00:15 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 1 Jan 2010 00:15:04 +0000 (00:15 +0000)
class), provide a suggestion for the type or class found. However,
since we can't recover properly in this case, don't provide a fix-it
hint. Example:

test/FixIt/typo.m:8:3: error: use of undeclared identifier 'NSstring';
did you
      mean 'NSString'?
  NSstring *str = @"A string";
  ...
  ^
1 diagnostic generated.

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

lib/Sema/SemaExpr.cpp
test/FixIt/typo.m [new file with mode: 0644]

index 6bb6ea3e512a250069c13d52f3a6f7c5b82aebf4..7bf04d88cd5991c6c144eaf015647cac7ad60273 100644 (file)
@@ -931,21 +931,41 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, const CXXScopeSpec &SS,
   }
 
   // We didn't find anything, so try to correct for a typo.
-  if (S && CorrectTypo(R, S, &SS) && 
-      (isa<ValueDecl>(*R.begin()) || isa<FunctionTemplateDecl>(*R.begin()))) {
-    if (SS.isEmpty())
-      Diag(R.getNameLoc(), diagnostic_suggest) << Name << R.getLookupName()
-        << CodeModificationHint::CreateReplacement(R.getNameLoc(),
+  if (S && CorrectTypo(R, S, &SS)) {
+    if (isa<ValueDecl>(*R.begin()) || isa<FunctionTemplateDecl>(*R.begin())) {
+      if (SS.isEmpty())
+        Diag(R.getNameLoc(), diagnostic_suggest) << Name << R.getLookupName()
+          << CodeModificationHint::CreateReplacement(R.getNameLoc(),
                                               R.getLookupName().getAsString());
-    else 
-      Diag(R.getNameLoc(), diag::err_no_member_suggest)
-        << Name << computeDeclContext(SS, false) << R.getLookupName()
-        << SS.getRange()
-        << CodeModificationHint::CreateReplacement(R.getNameLoc(),
+      else 
+        Diag(R.getNameLoc(), diag::err_no_member_suggest)
+          << Name << computeDeclContext(SS, false) << R.getLookupName()
+          << SS.getRange()
+          << CodeModificationHint::CreateReplacement(R.getNameLoc(),
                                               R.getLookupName().getAsString());
 
-    // Tell the callee to try to recover.
-    return false;
+      // Tell the callee to try to recover.
+      return false;
+    }
+
+    if (isa<TypeDecl>(*R.begin()) || isa<ObjCInterfaceDecl>(*R.begin())) {
+      // FIXME: If we ended up with a typo for a type name or
+      // Objective-C class name, we're in trouble because the parser
+      // is in the wrong place to recover. Suggest the typo
+      // correction, but don't make it a fix-it since we're not going
+      // to recover well anyway.
+      if (SS.isEmpty())
+        Diag(R.getNameLoc(), diagnostic_suggest) << Name << R.getLookupName();
+      else 
+        Diag(R.getNameLoc(), diag::err_no_member_suggest)
+          << Name << computeDeclContext(SS, false) << R.getLookupName()
+          << SS.getRange();
+
+      // Don't try to recover; it won't work.
+      return true;
+    }
+
+    R.clear();
   }
 
   // Emit a special diagnostic for failed member lookups.
diff --git a/test/FixIt/typo.m b/test/FixIt/typo.m
new file mode 100644 (file)
index 0000000..2516849
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fixit -o - | %clang_cc1 -fsyntax-only -pedantic -Werror -x objective-c -
+
+@interface NSString
+@end
+
+void test() {
+  NSstring *str = @"A string"; // expected-error{{use of undeclared identifier 'NSstring'; did you mean 'NSString'?}}
+}