diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 36 | ||||
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 28 |
3 files changed, 46 insertions, 20 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 953a00fa422..fab72929993 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1596,13 +1596,13 @@ public: QualType BaseType, SourceLocation OpLoc, bool IsArrow, const CXXScopeSpec &SS, + NamedDecl *FirstQualifierInScope, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs); OwningExprResult LookupMemberExpr(LookupResult &R, Expr *&Base, bool &IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, - NamedDecl *FirstQualifierInScope, DeclPtrTy ObjCImpDecl); bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index e02dbd6bebd..034accd1c4e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1397,7 +1397,9 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS, return BuildMemberReferenceExpr(ExprArg(*this, This), ThisType, /*OpLoc*/ SourceLocation(), /*IsArrow*/ true, - SS, R, TemplateArgs); + SS, + /*FirstQualifierInScope*/ 0, + R, TemplateArgs); } bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, @@ -2471,8 +2473,7 @@ Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType, } else { OwningExprResult Result = LookupMemberExpr(R, Base, IsArrow, OpLoc, - SS, FirstQualifierInScope, - /*ObjCImpDecl*/ DeclPtrTy()); + SS, /*ObjCImpDecl*/ DeclPtrTy()); if (Result.isInvalid()) { Owned(Base); @@ -2484,13 +2485,15 @@ Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType, } return BuildMemberReferenceExpr(ExprArg(*this, Base), BaseType, - OpLoc, IsArrow, SS, R, TemplateArgs); + OpLoc, IsArrow, SS, FirstQualifierInScope, + R, TemplateArgs); } Sema::OwningExprResult Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType, SourceLocation OpLoc, bool IsArrow, const CXXScopeSpec &SS, + NamedDecl *FirstQualifierInScope, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs) { Expr *BaseExpr = Base.takeAs<Expr>(); @@ -2520,11 +2523,17 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType, return ExprError(); } - // 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)) + // Diagnose lookups that find only declarations from a non-base + // type. This is possible for either qualified lookups (which may + // have been qualified with an unrelated type) or implicit member + // expressions (which were found with unqualified lookup and thus + // may have come from an enclosing scope). 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() || !BaseExpr || + (isa<CXXThisExpr>(BaseExpr) && + cast<CXXThisExpr>(BaseExpr)->isImplicit())) && + CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R)) return ExprError(); // Construct an unresolved result if we in fact got an unresolved @@ -2666,7 +2675,6 @@ Sema::OwningExprResult Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, bool &IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, - NamedDecl *FirstQualifierInScope, DeclPtrTy ObjCImpDecl) { assert(BaseExpr && "no base expression"); @@ -3101,7 +3109,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, << Property->getDeclName(); return LookupMemberExpr(Res, BaseExpr, IsArrow, OpLoc, SS, - FirstQualifierInScope, ObjCImpDecl); + ObjCImpDecl); } return ExprError(Diag(MemberLoc, diag::err_property_not_found) @@ -3204,8 +3212,7 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg, DecomposeTemplateName(R, Id); } else { Result = LookupMemberExpr(R, Base, IsArrow, OpLoc, - SS, FirstQualifierInScope, - ObjCImpDecl); + SS, ObjCImpDecl); if (Result.isInvalid()) { Owned(Base); @@ -3226,7 +3233,8 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg, } Result = BuildMemberReferenceExpr(ExprArg(*this, Base), Base->getType(), - OpLoc, IsArrow, SS, R, TemplateArgs); + OpLoc, IsArrow, SS, FirstQualifierInScope, + R, TemplateArgs); } return move(Result); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 419dd9c00f9..445ef0dac79 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -975,12 +975,15 @@ public: QualType BaseType = ((Expr*) Base.get())->getType(); - // FIXME: wait, this is re-performing lookup? + LookupResult R(getSema(), Member->getDeclName(), MemberLoc, + Sema::LookupMemberName); + R.addDecl(Member); + R.resolveKind(); + return getSema().BuildMemberReferenceExpr(move(Base), BaseType, OpLoc, isArrow, SS, FirstQualifierInScope, - Member->getDeclName(), MemberLoc, - ExplicitTemplateArgs); + R, ExplicitTemplateArgs); } /// \brief Build a new binary operator expression. @@ -1561,6 +1564,7 @@ public: bool IsArrow, NestedNameSpecifier *Qualifier, SourceRange QualifierRange, + NamedDecl *FirstQualifierInScope, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs) { CXXScopeSpec SS; @@ -1569,7 +1573,8 @@ public: return SemaRef.BuildMemberReferenceExpr(move(BaseE), BaseType, OperatorLoc, IsArrow, - SS, R, TemplateArgs); + SS, FirstQualifierInScope, + R, TemplateArgs); } /// \brief Build a new Objective-C @encode expression. @@ -3713,6 +3718,12 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) { SourceLocation FakeOperatorLoc = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd()); + // FIXME: to do this check properly, we will need to preserve the + // first-qualifier-in-scope here, just in case we had a dependent + // base (and therefore couldn't do the check) and a + // nested-name-qualifier (and therefore could do the lookup). + NamedDecl *FirstQualifierInScope = 0; + return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc, E->isArrow(), Qualifier, @@ -3721,7 +3732,7 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) { Member, (E->hasExplicitTemplateArgumentList() ? &TransArgs : 0), - 0); + FirstQualifierInScope); } template<typename Derived> @@ -5029,6 +5040,12 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) TransArgs.addArgument(Loc); } } + + // FIXME: to do this check properly, we will need to preserve the + // first-qualifier-in-scope here, just in case we had a dependent + // base (and therefore couldn't do the check) and a + // nested-name-qualifier (and therefore could do the lookup). + NamedDecl *FirstQualifierInScope = 0; return getDerived().RebuildUnresolvedMemberExpr(move(Base), BaseType, @@ -5036,6 +5053,7 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) Old->isArrow(), Qualifier, Old->getQualifierRange(), + FirstQualifierInScope, R, (Old->hasExplicitTemplateArgs() ? &TransArgs : 0)); |

