]> granicus.if.org Git - clang/commitdiff
Perform typo correction for base class specifiers.
authorKaelyn Uhrain <rikka@google.com>
Fri, 22 Jun 2012 23:37:05 +0000 (23:37 +0000)
committerKaelyn Uhrain <rikka@google.com>
Fri, 22 Jun 2012 23:37:05 +0000 (23:37 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159046 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Parse/ParseDeclCXX.cpp
lib/Sema/SemaDecl.cpp
test/SemaCXX/typo-correction.cpp

index 16429ab6ddc40366e7e0d2bde32d5dfc208c0227..3a4c7feefc7b0f8d128dcba3a7063949b24169c1 100644 (file)
@@ -5550,6 +5550,8 @@ def warn_missing_method_return_type : Warning<
   InGroup<MissingMethodReturnType>, DefaultIgnore;
 
 // Spell-checking diagnostics
+def err_unknown_type_or_class_name_suggest : Error<
+  "unknown %select{type|class}2 name %0; did you mean %1?">;
 def err_unknown_typename_suggest : Error<
   "unknown type name %0; did you mean %1?">;
 def err_unknown_nested_typename_suggest : Error<
index 6e391c9022de6fd41f1b84e0da1104633b689fd6..67d1f2c9e1ac5be18a951722eda914775b8ef993 100644 (file)
@@ -874,10 +874,12 @@ Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
   }
 
   // We have an identifier; check whether it is actually a type.
+  IdentifierInfo *CorrectedII = 0;
   ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true,
                                         false, ParsedType(),
                                         /*IsCtorOrDtorName=*/false,
-                                        /*NonTrivialTypeSourceInfo=*/true);
+                                        /*NonTrivialTypeSourceInfo=*/true,
+                                        &CorrectedII);
   if (!Type) {
     Diag(IdLoc, diag::err_expected_class_name);
     return true;
index bee6557c2f0cf16fec3d09b8eba2e3aa3eefb720..1b0a0abdb2dd660f5c54277c732481445c7dd9d5 100644 (file)
@@ -60,7 +60,8 @@ namespace {
 
 class TypeNameValidatorCCC : public CorrectionCandidateCallback {
  public:
-  TypeNameValidatorCCC(bool AllowInvalid) : AllowInvalidDecl(AllowInvalid) {
+  TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false)
+      : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass) {
     WantExpressionKeywords = false;
     WantCXXNamedCasts = false;
     WantRemainingKeywords = false;
@@ -71,11 +72,12 @@ class TypeNameValidatorCCC : public CorrectionCandidateCallback {
       return (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) &&
           (AllowInvalidDecl || !ND->isInvalidDecl());
     else
-      return candidate.isKeyword();
+      return !WantClassName && candidate.isKeyword();
   }
 
  private:
   bool AllowInvalidDecl;
+  bool WantClassName;
 };
 
 }
@@ -209,7 +211,7 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
   case LookupResult::NotFound:
   case LookupResult::NotFoundInCurrentInstantiation:
     if (CorrectedII) {
-      TypeNameValidatorCCC Validator(true);
+      TypeNameValidatorCCC Validator(true, isClassName);
       TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(),
                                               Kind, S, SS, Validator);
       IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo();
@@ -238,8 +240,8 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
           std::string CorrectedStr(Correction.getAsString(getLangOpts()));
           std::string CorrectedQuotedStr(
               Correction.getQuoted(getLangOpts()));
-          Diag(NameLoc, diag::err_unknown_typename_suggest)
-              << Result.getLookupName() << CorrectedQuotedStr
+          Diag(NameLoc, diag::err_unknown_type_or_class_name_suggest)
+              << Result.getLookupName() << CorrectedQuotedStr << isClassName
               << FixItHint::CreateReplacement(SourceRange(NameLoc),
                                               CorrectedStr);
           if (NamedDecl *FirstDecl = Correction.getCorrectionDecl())
index 90fdb221f92d882f12d78f6e77bbd368ab6abbd0..77fca744406bb41a445086681acdec6b1e6f42e0 100644 (file)
@@ -219,3 +219,11 @@ namespace PR13051 {
     f(&S<int>::foo); // expected-error-re{{no member named 'foo' in 'PR13051::S<int>'$}}
   }
 }
+
+namespace PR6325 {
+class foo { }; // expected-note{{'foo' declared here}}
+// Note that for this example (pulled from the PR), if keywords are not excluded
+// as correction candidates then no suggestion would be given; correcting
+// 'boo' to 'bool' is the same edit distance as correcting 'boo' to 'foo'.
+class bar : boo { }; // expected-error{{unknown class name 'boo'; did you mean 'foo'?}}
+}