summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp130
1 files changed, 61 insertions, 69 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 410bf9a..bc10a58 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;
@@ -1579,10 +1582,10 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
CXXConversionDecl *Conv;
FunctionTemplateDecl *ConvTemplate;
- if ((ConvTemplate = dyn_cast<FunctionTemplateDecl>(*I)))
- Conv = dyn_cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
+ if ((ConvTemplate = dyn_cast<FunctionTemplateDecl>(D)))
+ Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
else
- Conv = dyn_cast<CXXConversionDecl>(*I);
+ Conv = cast<CXXConversionDecl>(D);
if (AllowExplicit || !Conv->isExplicit()) {
if (ConvTemplate)
@@ -2201,44 +2204,6 @@ Sema::TryCopyInitialization(Expr *From, QualType ToType,
}
}
-/// PerformCopyInitialization - Copy-initialize an object of type @p ToType with
-/// the expression @p From. Returns true (and emits a diagnostic) if there was
-/// an error, returns false if the initialization succeeded. Elidable should
-/// be true when the copy may be elided (C++ 12.8p15). Overload resolution works
-/// differently in C++0x for this case.
-bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType,
- AssignmentAction Action, bool Elidable) {
- if (!getLangOptions().CPlusPlus) {
- // In C, argument passing is the same as performing an assignment.
- QualType FromType = From->getType();
-
- AssignConvertType ConvTy =
- CheckSingleAssignmentConstraints(ToType, From);
- if (ConvTy != Compatible &&
- CheckTransparentUnionArgumentConstraints(ToType, From) == Compatible)
- ConvTy = Compatible;
-
- return DiagnoseAssignmentResult(ConvTy, From->getLocStart(), ToType,
- FromType, From, Action);
- }
-
- if (ToType->isReferenceType())
- return CheckReferenceInit(From, ToType,
- /*FIXME:*/From->getLocStart(),
- /*SuppressUserConversions=*/false,
- /*AllowExplicit=*/false,
- /*ForceRValue=*/false);
-
- if (!PerformImplicitConversion(From, ToType, Action,
- /*AllowExplicit=*/false, Elidable))
- return false;
- if (!DiagnoseMultipleUserDefinedConversion(From, ToType))
- return Diag(From->getSourceRange().getBegin(),
- diag::err_typecheck_convert_incompatible)
- << ToType << From->getType() << Action << From->getSourceRange();
- return true;
-}
-
/// TryObjectArgumentInitialization - Try to initialize the object
/// parameter of the given member function (@c Method) from the
/// expression @p From.
@@ -2316,6 +2281,7 @@ Sema::TryObjectArgumentInitialization(QualType OrigFromType,
bool
Sema::PerformObjectArgumentInitialization(Expr *&From,
NestedNameSpecifier *Qualifier,
+ NamedDecl *FoundDecl,
CXXMethodDecl *Method) {
QualType FromRecordType, DestType;
QualType ImplicitParamRecordType =
@@ -2340,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,
@@ -3344,13 +3310,16 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
= ClassDecl->getVisibleConversionFunctions();
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
+ NamedDecl *D = I.getDecl();
+ if (isa<UsingShadowDecl>(D))
+ D = cast<UsingShadowDecl>(D)->getTargetDecl();
// Skip conversion function templates; they don't tell us anything
// about which builtin types we can convert to.
- if (isa<FunctionTemplateDecl>(*I))
+ if (isa<FunctionTemplateDecl>(D))
continue;
- CXXConversionDecl *Conv = cast<CXXConversionDecl>(*I);
+ CXXConversionDecl *Conv = cast<CXXConversionDecl>(D);
if (AllowExplicitConversions || !Conv->isExplicit()) {
AddTypesConvertedFrom(Conv->getConversionType(), Loc, false, false,
VisibleQuals);
@@ -3412,7 +3381,10 @@ static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) {
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
- if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(*I)) {
+ NamedDecl *D = I.getDecl();
+ if (isa<UsingShadowDecl>(D))
+ D = cast<UsingShadowDecl>(D)->getTargetDecl();
+ if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(D)) {
QualType CanTy = Context.getCanonicalType(Conv->getConversionType());
if (const ReferenceType *ResTypeRef = CanTy->getAs<ReferenceType>())
CanTy = ResTypeRef->getPointeeType();
@@ -4733,7 +4705,7 @@ void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc,
if (!ICS.isAmbiguous()) continue;
S.DiagnoseAmbiguousConversion(ICS, OpLoc,
- PDiag(diag::note_ambiguous_type_conversion));
+ S.PDiag(diag::note_ambiguous_type_conversion));
}
}
@@ -4980,7 +4952,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>())
@@ -5018,6 +4991,8 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
// Look through all of the overloaded functions, searching for one
// whose type matches exactly.
llvm::SmallVector<std::pair<DeclAccessPair, FunctionDecl*>, 4> Matches;
+ llvm::SmallVector<FunctionDecl *, 4> NonMatches;
+
bool FoundNonTemplateFunction = false;
for (UnresolvedSetIterator I = OvlExpr->decls_begin(),
E = OvlExpr->decls_end(); I != E; ++I) {
@@ -5097,9 +5072,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;
}
@@ -5131,10 +5107,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);
}
@@ -5153,6 +5128,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);
@@ -5433,7 +5409,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);
}
@@ -5560,7 +5536,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.
@@ -5754,7 +5731,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>();
@@ -5921,7 +5898,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.
@@ -6026,10 +6003,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);
@@ -6079,6 +6058,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;
@@ -6106,7 +6086,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.
@@ -6131,9 +6111,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);
@@ -6173,7 +6156,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
if (RequireCompleteType(LParenLoc, Object->getType(),
- PartialDiagnostic(diag::err_incomplete_object_call)
+ PDiag(diag::err_incomplete_object_call)
<< Object->getSourceRange()))
return true;
@@ -6293,7 +6276,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),
@@ -6353,7 +6337,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);
@@ -6474,7 +6458,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.
@@ -6501,9 +6486,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();
@@ -6511,7 +6498,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");
@@ -6535,7 +6523,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();
@@ -6556,7 +6545,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();
@@ -6618,6 +6608,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
MemExpr->getQualifier(),
MemExpr->getQualifierRange(),
Fn,
+ Found,
MemExpr->getMemberLoc(),
TemplateArgs,
Fn->getType());
@@ -6628,8 +6619,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
OpenPOWER on IntegriCloud