r207680 - When typo-correcting a member using-declaration, only consider members of base classes.
Richard Smith
richard-llvm at metafoo.co.uk
Wed Apr 30 11:03:22 PDT 2014
Author: rsmith
Date: Wed Apr 30 13:03:21 2014
New Revision: 207680
URL: http://llvm.org/viewvc/llvm-project?rev=207680&view=rev
Log:
When typo-correcting a member using-declaration, only consider members of base classes.
Modified:
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/SemaCXX/using-decl-1.cpp
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=207680&r1=207679&r2=207680&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Apr 30 13:03:21 2014
@@ -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(S
// 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)){
Modified: cfe/trunk/test/SemaCXX/using-decl-1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/using-decl-1.cpp?rev=207680&r1=207679&r2=207680&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/using-decl-1.cpp (original)
+++ cfe/trunk/test/SemaCXX/using-decl-1.cpp Wed Apr 30 13:03:21 2014
@@ -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'{{$}}}}
};
More information about the cfe-commits
mailing list