]> granicus.if.org Git - clang/commitdiff
Be a bit smarter about what nested name qualifiers to allow when
authorKaelyn Uhrain <rikka@google.com>
Fri, 21 Mar 2014 21:54:25 +0000 (21:54 +0000)
committerKaelyn Uhrain <rikka@google.com>
Fri, 21 Mar 2014 21:54:25 +0000 (21:54 +0000)
performing typo correction on very short (1 or 2 char) identifiers.

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

lib/Sema/SemaLookup.cpp
test/SemaCXX/missing-members.cpp
test/SemaCXX/typo-correction-pt2.cpp

index 0dd0260a5b4ef210d18e9179e0c05713b5c810ec..020fafa8f561ea94c5e64e69f9cff59f9a042331 100644 (file)
@@ -4209,13 +4209,17 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
                                               IEnd = DI->second.end();
          I != IEnd; /* Increment in loop. */) {
       // If we only want nested name specifier corrections, ignore potential
-      // corrections that have a different base identifier from the typo.
-      if (AllowOnlyNNSChanges &&
-          I->second.front().getCorrectionAsIdentifierInfo() != Typo) {
-        TypoCorrectionConsumer::result_iterator Prev = I;
-        ++I;
-        DI->second.erase(Prev);
-        continue;
+      // corrections that have a different base identifier from the typo or
+      // which have a normalized edit distance longer than the typo itself.
+      if (AllowOnlyNNSChanges) {
+        TypoCorrection &TC = I->second.front();
+        if (TC.getCorrectionAsIdentifierInfo() != Typo ||
+            TC.getEditDistance(true) > TypoLen) {
+          TypoCorrectionConsumer::result_iterator Prev = I;
+          ++I;
+          DI->second.erase(Prev);
+          continue;
+        }
       }
 
       // If the item already has been looked up or is a keyword, keep it.
index 619bc61f250111094738118b26fae3615ab39a4e..96bed074db857352f3384d5c202b2bfa793441b1 100644 (file)
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 namespace A {
   namespace B {
-    class C { }; // expected-note {{'A::B::C' declared here}}
+    class C { }; // expected-note {{'A::B::C' declared here}}
     struct S { };
     union U { };
   }
@@ -18,13 +18,12 @@ namespace B {
 }
 
 void g() {
-  A::B::D::E; // expected-error {{no member named 'D' in namespace 'A::B'}}
+  A::B::D::E; // expected-error-re {{no member named 'D' in namespace 'A::B'{{$}}}}
   // FIXME: The typo corrections below should be suppressed since A::B::C
   // doesn't have a member named D.
   B::B::C::D; // expected-error {{no member named 'C' in 'B::B'; did you mean 'A::B::C'?}} \
-              // expected-error {{no member named 'D' in 'A::B::C'}}
-  ::C::D; // expected-error {{no member named 'C' in the global namespace; did you mean 'A::B::C'?}}\
-          // expected-error {{no member named 'D' in 'A::B::C'}}
+              // expected-error-re {{no member named 'D' in 'A::B::C'{{$}}}}
+  ::C::D; // expected-error-re {{no member named 'C' in the global namespace{{$}}}}
 }
 
 int A::B::i = 10; // expected-error {{no member named 'i' in namespace 'A::B'}}
index e39a24bd097ffb32327003dfa7b66bdbf9fa4eac..9943dd21f5562303718c8eee205c453b71ede214 100644 (file)
@@ -243,3 +243,16 @@ void func() {
   bar();  // expected-error-re {{use of undeclared identifier 'bar'{{$}}}}
 }
 }
+
+namespace std {
+class bernoulli_distribution {
+ public:
+  double p() const;
+};
+}
+void test() {
+  // Make sure that typo correction doesn't suggest changing 'p' to
+  // 'std::bernoulli_distribution::p' as that is most likely wrong.
+  if (p)  // expected-error-re {{use of undeclared identifier 'p'{{$}}}}
+    return;
+}