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),
|
: WantTypeSpecifiers(true), WantExpressionKeywords(true),
|
||||||
WantCXXNamedCasts(true), WantRemainingKeywords(true),
|
WantCXXNamedCasts(true), WantRemainingKeywords(true),
|
||||||
WantObjCSuper(false),
|
WantObjCSuper(false),
|
||||||
IsObjCIvarLookup(false) {}
|
IsObjCIvarLookup(false), AllowAddedQualifier(true) {}
|
||||||
|
|
||||||
virtual ~CorrectionCandidateCallback() {}
|
virtual ~CorrectionCandidateCallback() {}
|
||||||
|
|
||||||
|
@ -239,6 +239,10 @@ class CorrectionCandidateCallback {
|
||||||
// Temporary hack for the one case where a CorrectTypoContext enum is used
|
// Temporary hack for the one case where a CorrectTypoContext enum is used
|
||||||
// when looking up results.
|
// when looking up results.
|
||||||
bool IsObjCIvarLookup;
|
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
|
/// @brief Simple template class for restricting typo correction candidates
|
||||||
|
|
|
@ -4478,7 +4478,14 @@ namespace {
|
||||||
class DifferentNameValidatorCCC : public CorrectionCandidateCallback {
|
class DifferentNameValidatorCCC : public CorrectionCandidateCallback {
|
||||||
public:
|
public:
|
||||||
DifferentNameValidatorCCC(CXXRecordDecl *Parent)
|
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) {
|
virtual bool ValidateCandidate(const TypoCorrection &candidate) {
|
||||||
if (candidate.getEditDistance() == 0)
|
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
|
// For unqualified lookup, look through all of the names that we have
|
||||||
// seen in this translation unit.
|
// seen in this translation unit.
|
||||||
// FIXME: Re-add the ability to skip very unlikely potential corrections.
|
// FIXME: Re-add the ability to skip very unlikely potential corrections.
|
||||||
|
@ -3852,8 +3858,9 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
|
||||||
return TypoCorrection();
|
return TypoCorrection();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the NestedNameSpecifiers for the KnownNamespaces
|
// Build the NestedNameSpecifiers for the KnownNamespaces, if we're going
|
||||||
if (getLangOpts().CPlusPlus) {
|
// to search those namespaces.
|
||||||
|
if (SearchNamespaces) {
|
||||||
// Load any externally-known namespaces.
|
// Load any externally-known namespaces.
|
||||||
if (ExternalSource && !LoadedExternalKnownNamespaces) {
|
if (ExternalSource && !LoadedExternalKnownNamespaces) {
|
||||||
SmallVector<NamespaceDecl *, 4> ExternalKnownNamespaces;
|
SmallVector<NamespaceDecl *, 4> ExternalKnownNamespaces;
|
||||||
|
@ -3948,7 +3955,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Only perform the qualified lookups for C++
|
// Only perform the qualified lookups for C++
|
||||||
if (getLangOpts().CPlusPlus) {
|
if (SearchNamespaces) {
|
||||||
TmpRes.suppressDiagnostics();
|
TmpRes.suppressDiagnostics();
|
||||||
for (llvm::SmallVector<TypoCorrection,
|
for (llvm::SmallVector<TypoCorrection,
|
||||||
16>::iterator QRI = QualifiedResults.begin(),
|
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 {{reference to overloaded function could not be resolved; did you mean to call it?}} \
|
||||||
// expected-error {{use of undeclared identifier 't'}}
|
// 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