diff options
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 68 |
1 files changed, 45 insertions, 23 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 58d7d67508..8d3313982c 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -567,6 +567,8 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, // array-to-pointer conversion, or function-to-pointer conversion // (C++ 4p1). + DeclAccessPair AccessPair; + // Lvalue-to-rvalue conversion (C++ 4.1): // An lvalue (3.10) of a non-function, non-array type T can be // converted to an rvalue. @@ -612,7 +614,8 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, // function. (C++ 4.3p1). FromType = Context.getPointerType(FromType); } else if (FunctionDecl *Fn - = ResolveAddressOfOverloadedFunction(From, ToType, false)) { + = ResolveAddressOfOverloadedFunction(From, ToType, false, + AccessPair)) { // Address of overloaded function (C++ [over.over]). SCS.First = ICK_Function_To_Pointer; @@ -2278,6 +2281,7 @@ Sema::TryObjectArgumentInitialization(QualType OrigFromType, bool Sema::PerformObjectArgumentInitialization(Expr *&From, NestedNameSpecifier *Qualifier, + NamedDecl *FoundDecl, CXXMethodDecl *Method) { QualType FromRecordType, DestType; QualType ImplicitParamRecordType = @@ -2302,7 +2306,7 @@ Sema::PerformObjectArgumentInitialization(Expr *&From, << ImplicitParamRecordType << FromRecordType << From->getSourceRange(); if (ICS.Standard.Second == ICK_Derived_To_Base) - return PerformObjectMemberConversion(From, Qualifier, Method); + return PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method); if (!Context.hasSameType(From->getType(), DestType)) ImpCastExprToType(From, DestType, CastExpr::CK_NoOp, @@ -4942,7 +4946,8 @@ static bool CheckUnresolvedAccess(Sema &S, OverloadExpr *E, DeclAccessPair D) { /// routine will emit diagnostics if there is an error. FunctionDecl * Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, - bool Complain) { + bool Complain, + DeclAccessPair &FoundResult) { QualType FunctionType = ToType; bool IsMember = false; if (const PointerType *ToTypePtr = ToType->getAs<PointerType>()) @@ -5059,9 +5064,10 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, return 0; else if (Matches.size() == 1) { FunctionDecl *Result = Matches[0].second; + FoundResult = Matches[0].first; MarkDeclarationReferenced(From->getLocStart(), Result); if (Complain) - CheckUnresolvedAccess(*this, OvlExpr, Matches[0].first); + CheckAddressOfMemberAccess(OvlExpr, Matches[0].first); return Result; } @@ -5093,10 +5099,9 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, << (unsigned) oc_function_template); assert(Result != MatchesCopy.end() && "no most-specialized template"); MarkDeclarationReferenced(From->getLocStart(), *Result); - if (Complain) { - DeclAccessPair FoundDecl = Matches[Result - MatchesCopy.begin()].first; - CheckUnresolvedAccess(*this, OvlExpr, FoundDecl); - } + FoundResult = Matches[Result - MatchesCopy.begin()].first; + if (Complain) + CheckUnresolvedAccess(*this, OvlExpr, FoundResult); return cast<FunctionDecl>(*Result); } @@ -5115,6 +5120,7 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, // selected function. if (Matches.size() == 1) { MarkDeclarationReferenced(From->getLocStart(), Matches[0].second); + FoundResult = Matches[0].first; if (Complain) CheckUnresolvedAccess(*this, OvlExpr, Matches[0].first); return cast<FunctionDecl>(Matches[0].second); @@ -5395,7 +5401,7 @@ Sema::BuildOverloadedCallExpr(Expr *Fn, UnresolvedLookupExpr *ULE, case OR_Success: { FunctionDecl *FDecl = Best->Function; CheckUnresolvedLookupAccess(ULE, Best->FoundDecl); - Fn = FixOverloadedFunctionReference(Fn, FDecl); + Fn = FixOverloadedFunctionReference(Fn, Best->FoundDecl, FDecl); return BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs, RParenLoc); } @@ -5522,7 +5528,8 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) { CheckMemberOperatorAccess(OpLoc, Args[0], 0, Best->FoundDecl); - if (PerformObjectArgumentInitialization(Input, /*Qualifier=*/0, Method)) + if (PerformObjectArgumentInitialization(Input, /*Qualifier=*/0, + Best->FoundDecl, Method)) return ExprError(); } else { // Convert the arguments. @@ -5716,7 +5723,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, return ExprError(); if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0, - Method)) + Best->FoundDecl, Method)) return ExprError(); Args[1] = RHS = Arg1.takeAs<Expr>(); @@ -5883,7 +5890,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, // Convert the arguments. CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl); if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0, - Method)) + Best->FoundDecl, Method)) return ExprError(); // Convert the arguments. @@ -5988,10 +5995,12 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, MemberExpr *MemExpr; CXXMethodDecl *Method = 0; + NamedDecl *FoundDecl = 0; NestedNameSpecifier *Qualifier = 0; if (isa<MemberExpr>(NakedMemExpr)) { MemExpr = cast<MemberExpr>(NakedMemExpr); Method = cast<CXXMethodDecl>(MemExpr->getMemberDecl()); + FoundDecl = MemExpr->getFoundDecl(); Qualifier = MemExpr->getQualifier(); } else { UnresolvedMemberExpr *UnresExpr = cast<UnresolvedMemberExpr>(NakedMemExpr); @@ -6041,6 +6050,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, switch (BestViableFunction(CandidateSet, UnresExpr->getLocStart(), Best)) { case OR_Success: Method = cast<CXXMethodDecl>(Best->Function); + FoundDecl = Best->FoundDecl; CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl); break; @@ -6068,7 +6078,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, return ExprError(); } - MemExprE = FixOverloadedFunctionReference(MemExprE, Method); + MemExprE = FixOverloadedFunctionReference(MemExprE, FoundDecl, Method); // If overload resolution picked a static member, build a // non-member call based on that function. @@ -6093,9 +6103,12 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, return ExprError(); // Convert the object argument (for a non-static member function call). + // We only need to do this if there was actually an overload; otherwise + // it was done at lookup. Expr *ObjectArg = MemExpr->getBase(); if (!Method->isStatic() && - PerformObjectArgumentInitialization(ObjectArg, Qualifier, Method)) + PerformObjectArgumentInitialization(ObjectArg, Qualifier, + FoundDecl, Method)) return ExprError(); MemExpr->setBase(ObjectArg); @@ -6255,7 +6268,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, // Create an implicit member expr to refer to the conversion operator. // and then call it. - CXXMemberCallExpr *CE = BuildCXXMemberCallExpr(Object, Conv); + CXXMemberCallExpr *CE = BuildCXXMemberCallExpr(Object, Best->FoundDecl, + Conv); return ActOnCallExpr(S, ExprArg(*this, CE), LParenLoc, MultiExprArg(*this, (ExprTy**)Args, NumArgs), @@ -6315,7 +6329,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, // Initialize the implicit object parameter. IsError |= PerformObjectArgumentInitialization(Object, /*Qualifier=*/0, - Method); + Best->FoundDecl, Method); TheCall->setArg(0, Object); @@ -6436,7 +6450,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) { // Convert the object parameter. CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function); - if (PerformObjectArgumentInitialization(Base, /*Qualifier=*/0, Method)) + if (PerformObjectArgumentInitialization(Base, /*Qualifier=*/0, + Best->FoundDecl, Method)) return ExprError(); // No concerns about early exits now. @@ -6463,9 +6478,11 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) { /// perhaps a '&' around it). We have resolved the overloaded function /// to the function declaration Fn, so patch up the expression E to /// refer (possibly indirectly) to Fn. Returns the new expr. -Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { +Expr *Sema::FixOverloadedFunctionReference(Expr *E, NamedDecl *Found, + FunctionDecl *Fn) { if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) { - Expr *SubExpr = FixOverloadedFunctionReference(PE->getSubExpr(), Fn); + Expr *SubExpr = FixOverloadedFunctionReference(PE->getSubExpr(), + Found, Fn); if (SubExpr == PE->getSubExpr()) return PE->Retain(); @@ -6473,7 +6490,8 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { } if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) { - Expr *SubExpr = FixOverloadedFunctionReference(ICE->getSubExpr(), Fn); + Expr *SubExpr = FixOverloadedFunctionReference(ICE->getSubExpr(), + Found, Fn); assert(Context.hasSameType(ICE->getSubExpr()->getType(), SubExpr->getType()) && "Implicit cast type cannot be determined from overload"); @@ -6497,7 +6515,8 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { // Fix the sub expression, which really has to be an // UnresolvedLookupExpr holding an overloaded member function // or template. - Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn); + Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), + Found, Fn); if (SubExpr == UnOp->getSubExpr()) return UnOp->Retain(); @@ -6518,7 +6537,8 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { MemPtrType, UnOp->getOperatorLoc()); } } - Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn); + Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), + Found, Fn); if (SubExpr == UnOp->getSubExpr()) return UnOp->Retain(); @@ -6580,6 +6600,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { MemExpr->getQualifier(), MemExpr->getQualifierRange(), Fn, + Found, MemExpr->getMemberLoc(), TemplateArgs, Fn->getType()); @@ -6590,8 +6611,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) { } Sema::OwningExprResult Sema::FixOverloadedFunctionReference(OwningExprResult E, + NamedDecl *Found, FunctionDecl *Fn) { - return Owned(FixOverloadedFunctionReference((Expr *)E.get(), Fn)); + return Owned(FixOverloadedFunctionReference((Expr *)E.get(), Found, Fn)); } } // end namespace clang |