forked from OSchip/llvm-project
When diagnosing an invalid out-of-line redeclaration, don't permit
typo correction to introduce a nested-name-specifier; we aren't prepared to handle it here. Fixes PR12297 / <rdar://problem/11075219>. llvm-svn: 153445
This commit is contained in:
parent
0a4f8dc0cb
commit
b11f94590c
|
@ -205,7 +205,7 @@ class CorrectionCandidateCallback {
|
|||
: WantTypeSpecifiers(true), WantExpressionKeywords(true),
|
||||
WantCXXNamedCasts(true), WantRemainingKeywords(true),
|
||||
WantObjCSuper(false),
|
||||
IsObjCIvarLookup(false) {}
|
||||
IsObjCIvarLookup(false), AllowAddedQualifier(true) {}
|
||||
|
||||
virtual ~CorrectionCandidateCallback() {}
|
||||
|
||||
|
@ -239,6 +239,10 @@ class CorrectionCandidateCallback {
|
|||
// Temporary hack for the one case where a CorrectTypoContext enum is used
|
||||
// when looking up results.
|
||||
bool IsObjCIvarLookup;
|
||||
|
||||
/// \brief Whether to allow this typo correction to add a
|
||||
/// nested-name-specifier.
|
||||
bool AllowAddedQualifier;
|
||||
};
|
||||
|
||||
/// @brief Simple template class for restricting typo correction candidates
|
||||
|
|
|
@ -4478,7 +4478,14 @@ namespace {
|
|||
class DifferentNameValidatorCCC : public CorrectionCandidateCallback {
|
||||
public:
|
||||
DifferentNameValidatorCCC(CXXRecordDecl *Parent)
|
||||
: ExpectedParent(Parent ? Parent->getCanonicalDecl() : 0) {}
|
||||
: ExpectedParent(Parent ? Parent->getCanonicalDecl() : 0) {
|
||||
// Don't allow any additional qualification.
|
||||
// FIXME: It would be nice to perform this additional qualification.
|
||||
// However, DiagnoseInvalidRedeclaration is unable to handle the
|
||||
// qualification, because it doesn't know how to pass the corrected
|
||||
// nested-name-specifier through to ActOnFunctionDeclarator.
|
||||
AllowAddedQualifier = false;
|
||||
}
|
||||
|
||||
virtual bool ValidateCandidate(const TypoCorrection &candidate) {
|
||||
if (candidate.getEditDistance() == 0)
|
||||
|
|
|
@ -3806,7 +3806,13 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
|
|||
}
|
||||
}
|
||||
|
||||
if (IsUnqualifiedLookup || (QualifiedDC && QualifiedDC->isNamespace())) {
|
||||
// Determine whether we are going to search in the various namespaces for
|
||||
// corrections.
|
||||
bool SearchNamespaces
|
||||
= getLangOpts().CPlusPlus && CCC.AllowAddedQualifier &&
|
||||
(IsUnqualifiedLookup || (QualifiedDC && QualifiedDC->isNamespace()));
|
||||
|
||||
if (IsUnqualifiedLookup || SearchNamespaces) {
|
||||
// For unqualified lookup, look through all of the names that we have
|
||||
// seen in this translation unit.
|
||||
// FIXME: Re-add the ability to skip very unlikely potential corrections.
|
||||
|
@ -3852,8 +3858,9 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
|
|||
return TypoCorrection();
|
||||
}
|
||||
|
||||
// Build the NestedNameSpecifiers for the KnownNamespaces
|
||||
if (getLangOpts().CPlusPlus) {
|
||||
// Build the NestedNameSpecifiers for the KnownNamespaces, if we're going
|
||||
// to search those namespaces.
|
||||
if (SearchNamespaces) {
|
||||
// Load any externally-known namespaces.
|
||||
if (ExternalSource && !LoadedExternalKnownNamespaces) {
|
||||
SmallVector<NamespaceDecl *, 4> ExternalKnownNamespaces;
|
||||
|
@ -3948,7 +3955,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
|
|||
break;
|
||||
|
||||
// Only perform the qualified lookups for C++
|
||||
if (getLangOpts().CPlusPlus) {
|
||||
if (SearchNamespaces) {
|
||||
TmpRes.suppressDiagnostics();
|
||||
for (llvm::SmallVector<TypoCorrection,
|
||||
16>::iterator QRI = QualifiedResults.begin(),
|
||||
|
|
|
@ -10,3 +10,20 @@ template<typename T> void template_id1() { // expected-note {{'template_id1' dec
|
|||
// expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} \
|
||||
// expected-error {{use of undeclared identifier 't'}}
|
||||
}
|
||||
|
||||
// FIXME: It would be nice if we could get this correction right.
|
||||
namespace PR12297 {
|
||||
namespace A {
|
||||
typedef short T;
|
||||
|
||||
namespace B {
|
||||
typedef short T;
|
||||
|
||||
T global();
|
||||
}
|
||||
}
|
||||
|
||||
using namespace A::B;
|
||||
|
||||
T A::global(); // expected-error{{out-of-line definition of 'global' does not match any declaration in namespace 'PR12297::A'}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue