From ff18cc1141117b74a8b3eeb61b2d0f43cd83698b Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 31 Dec 2009 08:11:17 +0000 Subject: [PATCH] Typo correction for template names, e.g., typo.cpp:27:8: error: no template named 'basic_sting' in namespace 'std'; did you mean 'basic_string'? std::basic_sting b2; ~~~~~^~~~~~~~~~~ basic_string llvm-svn: 92348 --- .../clang/Basic/DiagnosticSemaKinds.td | 3 +++ clang/lib/Sema/SemaTemplate.cpp | 26 ++++++++++++++++++- clang/test/FixIt/typo.cpp | 4 +++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ffe328c3706f..8d7215514230 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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?">; } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 3dd024309193..8c6aa6a7d4a9 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -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(*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; diff --git a/clang/test/FixIt/typo.cpp b/clang/test/FixIt/typo.cpp index e0c7bf64dc63..a7cc0332fcec 100644 --- a/clang/test/FixIt/typo.cpp +++ b/clang/test/FixIt/typo.cpp @@ -23,6 +23,10 @@ float area(float radius, float pi) { } bool test_string(std::string s) { + basc_string b1; // expected-error{{no template named 'basc_string'; did you mean 'basic_string'?}} + std::basic_sting 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'; did you mean 'find'?}} == std::string::pos; // expected-error{{no member named 'pos' in 'class std::basic_string'; did you mean 'npos'?}} }