]> granicus.if.org Git - clang/commitdiff
Typo correction for template names, e.g.,
authorDouglas Gregor <dgregor@apple.com>
Thu, 31 Dec 2009 08:11:17 +0000 (08:11 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 31 Dec 2009 08:11:17 +0000 (08:11 +0000)
typo.cpp:27:8: error: no template named 'basic_sting' in namespace 'std';
    did you mean 'basic_string'?
  std::basic_sting<char> b2;
  ~~~~~^~~~~~~~~~~
       basic_string

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaTemplate.cpp
test/FixIt/typo.cpp

index ffe328c3706f985c495d20f2c023f901f4e64f37..8d7215514230281641881ec2b6ab2db043653ca5 100644 (file)
@@ -2557,6 +2557,9 @@ def err_undeclared_use_suggest : Error<
   "use of undeclared %0; did you mean %1?">;
 def err_undeclared_var_use_suggest : Error<
   "use of undeclared identifier %0; did you mean %1?">;
+def err_no_template_suggest : Error<"no template named %0; did you mean %1?">;
+def err_no_member_template_suggest : Error<
+  "no template named %0 in %1; did you mean %2?">;
 
 }
 
index 3dd024309193abaa31f01f5c3c3610efe4c0bf43..8c6aa6a7d4a9426a60320e91cfc4b3a25aecfe4f 100644 (file)
@@ -102,7 +102,8 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
 
   QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
 
-  LookupResult R(*this, TName, SourceLocation(), LookupOrdinaryName);
+  LookupResult R(*this, TName, Name.getSourceRange().getBegin(), 
+                 LookupOrdinaryName);
   R.suppressDiagnostics();
   LookupTemplateName(R, S, SS, ObjectType, EnteringContext);
   if (R.empty())
@@ -202,6 +203,29 @@ void Sema::LookupTemplateName(LookupResult &Found,
   assert(!Found.isAmbiguous() &&
          "Cannot handle template name-lookup ambiguities");
 
+  if (Found.empty()) {
+    // If we did not find any names, attempt to correct any typos.
+    DeclarationName Name = Found.getLookupName();
+    if (CorrectTypo(Found, S, &SS, LookupCtx)) {
+      FilterAcceptableTemplateNames(Context, Found);
+      if (!Found.empty() && isa<TemplateDecl>(*Found.begin())) {
+        if (LookupCtx)
+          Diag(Found.getNameLoc(), diag::err_no_member_template_suggest)
+            << Name << LookupCtx << Found.getLookupName() << SS.getRange()
+            << CodeModificationHint::CreateReplacement(Found.getNameLoc(),
+                                          Found.getLookupName().getAsString());
+        else
+          Diag(Found.getNameLoc(), diag::err_no_template_suggest)
+            << Name << Found.getLookupName()
+            << CodeModificationHint::CreateReplacement(Found.getNameLoc(),
+                                          Found.getLookupName().getAsString());
+      } else
+        Found.clear();
+    } else {
+      Found.clear();
+    }
+  }
+
   FilterAcceptableTemplateNames(Context, Found);
   if (Found.empty())
     return;
index e0c7bf64dc63facf829709e3f044b6c5770d82ae..a7cc0332fcec5f2a06df586653f213fbae94ee10 100644 (file)
@@ -23,6 +23,10 @@ float area(float radius, float pi) {
 }
 
 bool test_string(std::string s) {
+  basc_string<char> b1; // expected-error{{no template named 'basc_string'; did you mean 'basic_string'?}}
+  std::basic_sting<char> b2; // expected-error{{no template named 'basic_sting' in namespace 'std'; did you mean 'basic_string'?}}
+  (void)b1;
+  (void)b2;
   return s.fnd("hello") // expected-error{{no member named 'fnd' in 'class std::basic_string<char>'; did you mean 'find'?}}
     == std::string::pos; // expected-error{{no member named 'pos' in 'class std::basic_string<char>'; did you mean 'npos'?}}
 }