forked from OSchip/llvm-project
When typo-correcting a member using-declaration, only consider members of base classes.
llvm-svn: 207680
This commit is contained in:
parent
307625c974
commit
21866c3267
|
@ -7318,9 +7318,9 @@ namespace {
|
|||
class UsingValidatorCCC : public CorrectionCandidateCallback {
|
||||
public:
|
||||
UsingValidatorCCC(bool HasTypenameKeyword, bool IsInstantiation,
|
||||
bool RequireMember)
|
||||
CXXRecordDecl *RequireMemberOf)
|
||||
: HasTypenameKeyword(HasTypenameKeyword),
|
||||
IsInstantiation(IsInstantiation), RequireMember(RequireMember) {}
|
||||
IsInstantiation(IsInstantiation), RequireMemberOf(RequireMemberOf) {}
|
||||
|
||||
bool ValidateCandidate(const TypoCorrection &Candidate) override {
|
||||
NamedDecl *ND = Candidate.getCorrectionDecl();
|
||||
|
@ -7329,13 +7329,14 @@ public:
|
|||
if (!ND || isa<NamespaceDecl>(ND))
|
||||
return false;
|
||||
|
||||
// FIXME: We should check if ND is member of base class of class having
|
||||
// using declaration and direct base class in case using declaration names
|
||||
// a constructor.
|
||||
if (RequireMember && !ND->isCXXClassMember())
|
||||
return false;
|
||||
if (RequireMemberOf) {
|
||||
auto *RD = dyn_cast<CXXRecordDecl>(ND->getDeclContext());
|
||||
if (!RD || RequireMemberOf->isProvablyNotDerivedFrom(RD))
|
||||
return false;
|
||||
// FIXME: Check that the base class member is accessible?
|
||||
}
|
||||
|
||||
if (RequireMember && !isa<FieldDecl>(ND) && !isa<CXXMethodDecl>(ND) &&
|
||||
if (RequireMemberOf && !isa<FieldDecl>(ND) && !isa<CXXMethodDecl>(ND) &&
|
||||
!isa<TypeDecl>(ND))
|
||||
return false;
|
||||
|
||||
|
@ -7352,7 +7353,7 @@ public:
|
|||
private:
|
||||
bool HasTypenameKeyword;
|
||||
bool IsInstantiation;
|
||||
bool RequireMember;
|
||||
CXXRecordDecl *RequireMemberOf;
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
@ -7476,7 +7477,7 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
|
|||
// Try to correct typos if possible.
|
||||
if (R.empty()) {
|
||||
UsingValidatorCCC CCC(HasTypenameKeyword, IsInstantiation,
|
||||
CurContext->isRecord());
|
||||
dyn_cast<CXXRecordDecl>(CurContext));
|
||||
if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(),
|
||||
R.getLookupKind(), S, &SS, CCC,
|
||||
CTK_ErrorRecovery)){
|
||||
|
|
|
@ -207,7 +207,7 @@ struct Y : S {
|
|||
using S::S; // expected-error {{no member named 'S' in 'S'}}
|
||||
};
|
||||
|
||||
// [namespace.udecl] Para3: In a using-declaration used as a member-declaration,
|
||||
// [namespace.udecl]p3: In a using-declaration used as a member-declaration,
|
||||
// the nested-name-specifier shall name a base class of the class being defined.
|
||||
// If such a using-declaration names a constructor, the nested-name-specifier
|
||||
// shall name a direct base class of the class being defined;
|
||||
|
@ -216,14 +216,11 @@ struct Y : S {
|
|||
struct PR19171_B { }; // expected-note {{'PR19171_B' declared here}}
|
||||
struct PR19171_C : PR19171_B { };
|
||||
struct PR19171_D : PR19171_C {
|
||||
using PR19171_B::PR19171_C; // expected-error{{no member named 'PR19171_C' in 'PR19171_B'; did you mean 'PR19171_B'?}}
|
||||
using PR19171_B::PR19171_C; // expected-error{{no member named 'PR19171_C' in 'PR19171_B'; did you mean 'PR19171_B'?}}
|
||||
};
|
||||
|
||||
// FIXME: Typo correction should only consider member of base classes
|
||||
struct PR19171_E { };
|
||||
struct PR19171_EE { int EE; }; // expected-note {{'PR19171_EE::EE' declared here}} \
|
||||
// expected-note {{target of using declaration}}
|
||||
struct PR19171_EE { int EE; };
|
||||
struct PR19171_F : PR19171_E {
|
||||
using PR19171_E::EE; // expected-error{{no member named 'EE' in 'PR19171_E'; did you mean 'PR19171_EE::EE'?}} \
|
||||
// expected-error{{using declaration refers into 'PR19171_E::', which is not a base class of 'PR19171_F'}}
|
||||
using PR19171_E::EE; // expected-error-re{{no member named 'EE' in 'PR19171_E'{{$}}}}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue