diff options
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 19 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp | 8 | ||||
-rw-r--r-- | test/Parser/cxx-using-directive.cpp | 5 | ||||
-rw-r--r-- | test/SemaCXX/elaborated-type-specifier.cpp | 7 | ||||
-rw-r--r-- | test/SemaCXX/nested-name-spec.cpp | 20 | ||||
-rw-r--r-- | test/SemaCXX/qualified-id-lookup.cpp | 5 |
6 files changed, 48 insertions, 16 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 1ee594c2a3..91d76de172 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -3795,6 +3795,9 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, bool SearchNamespaces = getLangOpts().CPlusPlus && (IsUnqualifiedLookup || (QualifiedDC && QualifiedDC->isNamespace())); + // In a few cases we *only* want to search for corrections bases on just + // adding or changing the nested name specifier. + bool AllowOnlyNNSChanges = Typo->getName().size() < 3; if (IsUnqualifiedLookup || SearchNamespaces) { // For unqualified lookup, look through all of the names that we have @@ -3831,8 +3834,8 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, return TypoCorrection(); } - // Make sure that the user typed at least 3 characters for each correction - // made. Otherwise, we don't even both looking at the results. + // Make sure the best edit distance (prior to adding any namespace qualifiers) + // is not more that about a third of the length of the typo's identifier. unsigned ED = Consumer.getBestEditDistance(true); if (ED > 0 && Typo->getName().size() / ED < 3) { // If this was an unqualified lookup, note that no correction was found. @@ -3872,6 +3875,16 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, for (TypoCorrectionConsumer::result_iterator I = DI->second.begin(), 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; + } + // If the item already has been looked up or is a keyword, keep it. // If a validator callback object was given, drop the correction // unless it passes validation. @@ -4013,7 +4026,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, TypoResultsMap &BestResults = Consumer.getBestResults(); ED = Consumer.getBestEditDistance(true); - if (ED > 0 && Typo->getName().size() / ED < 3) { + if (!AllowOnlyNNSChanges && ED > 0 && Typo->getName().size() / ED < 3) { // If this was an unqualified lookup and we believe the callback // object wouldn't have filtered out possible corrections, note // that no correction was found. diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp index 84841cb60f..c8b7def5a4 100644 --- a/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp +++ b/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp @@ -1,10 +1,14 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s namespace N { - template<class T> class X; + template<class T> class X; // expected-note {{'N::X' declared here}} \ + // expected-note {{explicitly specialized declaration is here}} } -template<> class X<int> { /* ... */ }; // expected-error {{non-template class 'X'}} +// TODO: Don't add a namespace qualifier to the template if it would trigger +// the warning about the specialization being outside of the namespace. +template<> class X<int> { /* ... */ }; // expected-error {{no template named 'X'; did you mean 'N::X'?}} \ + // expected-warning {{first declaration of class template specialization of 'X' outside namespace 'N' is a C++11 extension}} namespace N { diff --git a/test/Parser/cxx-using-directive.cpp b/test/Parser/cxx-using-directive.cpp index 1d781fbdcf..9a1a6de892 100644 --- a/test/Parser/cxx-using-directive.cpp +++ b/test/Parser/cxx-using-directive.cpp @@ -3,7 +3,8 @@ class A {}; namespace B { - namespace A {} // expected-note{{namespace '::B::A' defined here}} + namespace A {} // expected-note{{namespace '::B::A' defined here}} \ + // expected-note{{namespace 'B::A' defined here}} using namespace A ; } @@ -25,7 +26,7 @@ namespace D { } using namespace ! ; // expected-error{{expected namespace name}} -using namespace A ; // expected-error{{expected namespace name}} +using namespace A ; // expected-error{{no namespace named 'A'; did you mean 'B::A'?}} using namespace ::A // expected-error{{expected namespace name}} \ // expected-error{{expected ';' after namespace name}} B ; diff --git a/test/SemaCXX/elaborated-type-specifier.cpp b/test/SemaCXX/elaborated-type-specifier.cpp index 760079f3b0..1b1770a89f 100644 --- a/test/SemaCXX/elaborated-type-specifier.cpp +++ b/test/SemaCXX/elaborated-type-specifier.cpp @@ -19,7 +19,7 @@ bool test_elab(S1 *s1, struct S2 *s2, struct S3 *s3) { namespace NS { class X { public: - void test_elab2(struct S4 *s4); + void test_elab2(struct S4 *s4); // expected-note{{'NS::S4' declared here}} }; void X::test_elab2(S4 *s4) { } // expected-note{{passing argument to parameter 's4' here}} @@ -35,8 +35,7 @@ namespace NS { } void test_S5_scope() { - S4 *s4; // expected-error{{use of undeclared identifier 'S4'}} \ - // expected-error{{use of undeclared identifier 's4'}} + S4 *s4; // expected-error{{unknown type name 'S4'; did you mean 'NS::S4'?}} } int test_funcparam_scope(struct S5 * s5) { @@ -44,5 +43,3 @@ int test_funcparam_scope(struct S5 * s5) { if (s5 == s5_2) return 1; // expected-error {{comparison of distinct pointer types ('struct S5 *' and 'struct S5 *')}} return 0; } - - diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp index b317634844..d57a8523bb 100644 --- a/test/SemaCXX/nested-name-spec.cpp +++ b/test/SemaCXX/nested-name-spec.cpp @@ -113,7 +113,8 @@ namespace E { X = 0 }; - void f() { + void f() { // expected-note{{'E::Nested::f' declared here}} \ + // expected-note{{previous definition is here}} return E::X; // expected-error{{expected a class or namespace}} } } @@ -143,7 +144,10 @@ namespace A { void g(int&); // expected-note{{type of 1st parameter of member declaration does not match definition ('int &' vs 'const int &')}} } -void A::f() {} // expected-error{{out-of-line definition of 'f' does not match any declaration in namespace 'A'}} +// TODO: Suppress the typo correction for an invalid redeclaration if the chosen +// correction is a function that already has a body. +void A::f() {} // expected-error{{out-of-line definition of 'f' does not match any declaration in namespace 'A'; did you mean 'E::Nested::f'?}} \ + // expected-error{{redefinition of 'f'}} void A::g(const int&) { } // expected-error{{out-of-line definition of 'g' does not match any declaration in namespace 'A'}} @@ -286,3 +290,15 @@ protected: template <typename T> struct A2<T>::B::C; // expected-error {{no struct named 'C'}} } + +namespace PR13033 { +namespace NS { + int a; // expected-note {{'NS::a' declared here}} + int longer_b; //expected-note {{'NS::longer_b' declared here}} +} + +// Suggest adding a namespace qualifier to both variable names even though one +// is only a single character long. +int foobar = a + longer_b; // expected-error {{use of undeclared identifier 'a'; did you mean 'NS::a'?}} \ + // expected-error {{use of undeclared identifier 'longer_b'; did you mean 'NS::longer_b'?}} +} diff --git a/test/SemaCXX/qualified-id-lookup.cpp b/test/SemaCXX/qualified-id-lookup.cpp index d65a4684e6..a14193cc7a 100644 --- a/test/SemaCXX/qualified-id-lookup.cpp +++ b/test/SemaCXX/qualified-id-lookup.cpp @@ -86,14 +86,15 @@ namespace a { namespace a { namespace a { // A1 namespace a { // A2 - int i; + int i; // expected-note{{'::a::a::a::i' declared here}} } } } void test_a() { - a::a::i = 3; // expected-error{{no member named 'i'}} + a::a::i = 3; // expected-error{{no member named 'i' in namespace 'a::a'; did you mean '::a::a::a::i'?}} a::a::a::i = 4; + a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'$}} } struct Undef { // expected-note{{definition of 'Undef' is not complete until the closing '}'}} |