diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-04-05 01:13:04 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-04-05 01:13:04 +0000 |
commit | a85cf39786fffd6860a940523be01eb02a4935c0 (patch) | |
tree | 49e6b78abb519f6ddf1db6d7a31f3fbd66ea43c7 /lib/Sema/SemaExprMember.cpp | |
parent | 4fd05dc4062580acea72f8b8231fb0ea3ee49032 (diff) |
Improve diagnostics for invalid use of non-static members / this:
* s/nonstatic/non-static/ in the diagnostics, since the latter form outvoted
the former by 28-2 in our diagnostics.
* Fix the "use of member in static member function" diagnostic to correctly
detect this situation inside a block or lambda.
* Produce a more specific "invalid use of non-static member" diagnostic for
the case where a nested class member refers to a member of a
lexically-surrounding class.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154073 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprMember.cpp')
-rw-r--r-- | lib/Sema/SemaExprMember.cpp | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 4155fdb9db..26b88a2a7e 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -194,30 +194,38 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, } /// Diagnose a reference to a field with no object available. -static void DiagnoseInstanceReference(Sema &SemaRef, +static void diagnoseInstanceReference(Sema &SemaRef, const CXXScopeSpec &SS, - NamedDecl *rep, + NamedDecl *Rep, const DeclarationNameInfo &nameInfo) { SourceLocation Loc = nameInfo.getLoc(); SourceRange Range(Loc); if (SS.isSet()) Range.setBegin(SS.getRange().getBegin()); - - if (isa<FieldDecl>(rep) || isa<IndirectFieldDecl>(rep)) { - if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(SemaRef.CurContext)) { - if (MD->isStatic()) { - // "invalid use of member 'x' in static member function" - SemaRef.Diag(Loc, diag::err_invalid_member_use_in_static_method) - << Range << nameInfo.getName(); - return; - } - } + DeclContext *FunctionLevelDC = SemaRef.getFunctionLevelDeclContext(); + CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FunctionLevelDC); + CXXRecordDecl *ContextClass = Method ? Method->getParent() : 0; + CXXRecordDecl *RepClass = dyn_cast<CXXRecordDecl>(Rep->getDeclContext()); + + bool InStaticMethod = Method && Method->isStatic(); + bool IsField = isa<FieldDecl>(Rep) || isa<IndirectFieldDecl>(Rep); + + if (IsField && InStaticMethod) + // "invalid use of member 'x' in static member function" + SemaRef.Diag(Loc, diag::err_invalid_member_use_in_static_method) + << Range << nameInfo.getName(); + else if (ContextClass && RepClass && SS.isEmpty() && !InStaticMethod && + !RepClass->Equals(ContextClass) && RepClass->Encloses(ContextClass)) + // Unqualified lookup in a non-static member function found a member of an + // enclosing class. + SemaRef.Diag(Loc, diag::err_nested_non_static_member_use) + << IsField << RepClass << nameInfo.getName() << ContextClass << Range; + else if (IsField) SemaRef.Diag(Loc, diag::err_invalid_non_static_member_use) - << nameInfo.getName() << Range; - return; - } - - SemaRef.Diag(Loc, diag::err_member_call_without_object) << Range; + << nameInfo.getName() << Range; + else + SemaRef.Diag(Loc, diag::err_member_call_without_object) + << Range; } /// Builds an expression which might be an implicit member expression. @@ -248,7 +256,7 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, case IMA_Error_StaticContext: case IMA_Error_Unrelated: - DiagnoseInstanceReference(*this, SS, R.getRepresentativeDecl(), + diagnoseInstanceReference(*this, SS, R.getRepresentativeDecl(), R.getLookupNameInfo()); return ExprError(); } @@ -468,7 +476,7 @@ static void DiagnoseQualifiedMemberReference(Sema &SemaRef, // If this is an implicit member access, use a different set of // diagnostics. if (!BaseExpr) - return DiagnoseInstanceReference(SemaRef, SS, rep, nameInfo); + return diagnoseInstanceReference(SemaRef, SS, rep, nameInfo); SemaRef.Diag(nameInfo.getLoc(), diag::err_qualified_member_of_unrelated) << SS.getRange() << rep << BaseType; |