diff options
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 36ab6ed44bd..ae6ba321a22 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -901,10 +901,8 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, // Determine whether this is a member of an unknown specialization; // we need to handle these differently. if (SS.isSet() && IsDependentIdExpression(*this, SS)) { - bool CheckForImplicitMember = !isAddressOfOperand; - return ActOnDependentIdExpression(SS, Name, NameLoc, - CheckForImplicitMember, + isAddressOfOperand, TemplateArgs); } @@ -2140,15 +2138,18 @@ Sema::ActOnDependentMemberExpr(ExprArg Base, QualType BaseType, static void DiagnoseQualifiedMemberReference(Sema &SemaRef, Expr *BaseExpr, QualType BaseType, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + const CXXScopeSpec &SS, const LookupResult &R) { - DeclContext *DC = R.getRepresentativeDecl()->getDeclContext(); + // If this is an implicit member access, use a different set of + // diagnostics. + if (!BaseExpr) + return DiagnoseInstanceReference(SemaRef, SS, R); // FIXME: this is an exceedingly lame diagnostic for some of the more // complicated cases here. + DeclContext *DC = R.getRepresentativeDecl()->getDeclContext(); SemaRef.Diag(R.getNameLoc(), diag::err_not_direct_base_or_virtual) - << QualifierRange << DC << BaseType; + << SS.getRange() << DC << BaseType; } // Check whether the declarations we found through a nested-name @@ -2165,8 +2166,7 @@ static void DiagnoseQualifiedMemberReference(Sema &SemaRef, // we actually pick through overload resolution is from a superclass. bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, + const CXXScopeSpec &SS, const LookupResult &R) { const RecordType *BaseRT = BaseType->getAs<RecordType>(); if (!BaseRT) { @@ -2195,8 +2195,7 @@ bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr, return false; } - DiagnoseQualifiedMemberReference(*this, BaseExpr, BaseType, - Qualifier, QualifierRange, R); + DiagnoseQualifiedMemberReference(*this, BaseExpr, BaseType, SS, R); return true; } @@ -2216,6 +2215,12 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, // nested-name-specifier. DC = SemaRef.computeDeclContext(SS, false); + if (SemaRef.RequireCompleteDeclContext(SS)) { + SemaRef.Diag(SS.getRange().getEnd(), diag::err_typecheck_incomplete_tag) + << SS.getRange() << DC; + return true; + } + assert(DC && "Cannot handle non-computable dependent contexts in lookup"); if (!isa<TypeDecl>(DC)) { @@ -2240,7 +2245,8 @@ Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType, const TemplateArgumentListInfo *TemplateArgs) { Expr *Base = BaseArg.takeAs<Expr>(); - if (BaseType->isDependentType()) + if (BaseType->isDependentType() || + (SS.isSet() && isDependentScopeSpecifier(SS))) return ActOnDependentMemberExpr(ExprArg(*this, Base), BaseType, IsArrow, OpLoc, SS, FirstQualifierInScope, @@ -2311,11 +2317,11 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType, return ExprError(); } - // We can't always diagnose the problem yet: it's permitted for - // lookup to find things from an invalid context as long as they - // don't get picked by overload resolution. - if (SS.isSet() && CheckQualifiedMemberReference(BaseExpr, BaseType, - Qualifier, SS.getRange(), R)) + // Diagnose qualified lookups that find only declarations from a + // non-base type. Note that it's okay for lookup to find + // declarations from a non-base type as long as those aren't the + // ones picked by overload resolution. + if (SS.isSet() && CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R)) return ExprError(); // Construct an unresolved result if we in fact got an unresolved |