}
}
-void InitializationSequence::AddAddressOverloadResolutionStep(
- FunctionDecl *Function,
- DeclAccessPair Found) {
+void
+InitializationSequence
+::AddAddressOverloadResolutionStep(FunctionDecl *Function,
+ DeclAccessPair Found,
+ bool HadMultipleCandidates) {
Step S;
S.Kind = SK_ResolveAddressOfOverloadedFunction;
S.Type = Function->getType();
- S.Function.HadMultipleCandidates = false;
+ S.Function.HadMultipleCandidates = HadMultipleCandidates;
S.Function.Function = Function;
S.Function.FoundDecl = Found;
Steps.push_back(S);
Steps.push_back(S);
}
-void InitializationSequence::AddUserConversionStep(FunctionDecl *Function,
- DeclAccessPair FoundDecl,
- QualType T) {
+void
+InitializationSequence::AddUserConversionStep(FunctionDecl *Function,
+ DeclAccessPair FoundDecl,
+ QualType T,
+ bool HadMultipleCandidates) {
Step S;
S.Kind = SK_UserConversion;
S.Type = T;
- S.Function.HadMultipleCandidates = false;
+ S.Function.HadMultipleCandidates = HadMultipleCandidates;
S.Function.Function = Function;
S.Function.FoundDecl = FoundDecl;
Steps.push_back(S);
}
void
-InitializationSequence::AddConstructorInitializationStep(
- CXXConstructorDecl *Constructor,
- AccessSpecifier Access,
- QualType T) {
+InitializationSequence
+::AddConstructorInitializationStep(CXXConstructorDecl *Constructor,
+ AccessSpecifier Access,
+ QualType T,
+ bool HadMultipleCandidates) {
Step S;
S.Kind = SK_ConstructorInitialization;
S.Type = T;
- S.Function.HadMultipleCandidates = false;
+ S.Function.HadMultipleCandidates = HadMultipleCandidates;
S.Function.Function = Constructor;
S.Function.FoundDecl = DeclAccessPair::make(Constructor, Access);
Steps.push_back(S);
T2 = cv1T1;
// Add the user-defined conversion step.
+ bool HadMultipleCandidates = (CandidateSet.size() > 1);
Sequence.AddUserConversionStep(Function, Best->FoundDecl,
- T2.getNonLValueExprType(S.Context));
+ T2.getNonLValueExprType(S.Context),
+ HadMultipleCandidates);
// Determine whether we need to perform derived-to-base or
// cv-qualification adjustments.
// type of the resulting function.
if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) {
DeclAccessPair Found;
- if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Initializer,
- T1,
- false,
- Found)) {
- Sequence.AddAddressOverloadResolutionStep(Fn, Found);
+ bool HadMultipleCandidates = false;
+ if (FunctionDecl *Fn
+ = S.ResolveAddressOfOverloadedFunction(Initializer, T1, false, Found,
+ &HadMultipleCandidates)) {
+ Sequence.AddAddressOverloadResolutionStep(Fn, Found,
+ HadMultipleCandidates);
cv2T2 = Fn->getType();
T2 = cv2T2.getUnqualifiedType();
} else if (!T1->isRecordType()) {
// Add the constructor initialization step. Any cv-qualification conversion is
// subsumed by the initialization.
- Sequence.AddConstructorInitializationStep(
- cast<CXXConstructorDecl>(Best->Function),
- Best->FoundDecl.getAccess(),
- DestType);
+ bool HadMultipleCandidates = (CandidateSet.size() > 1);
+ CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
+ Sequence.AddConstructorInitializationStep(CtorDecl,
+ Best->FoundDecl.getAccess(),
+ DestType, HadMultipleCandidates);
}
/// \brief Attempt value initialization (C++ [dcl.init]p7).
FunctionDecl *Function = Best->Function;
S.MarkDeclarationReferenced(DeclLoc, Function);
+ bool HadMultipleCandidates = (CandidateSet.size() > 1);
if (isa<CXXConstructorDecl>(Function)) {
// Add the user-defined conversion step. Any cv-qualification conversion is
// subsumed by the initialization.
- Sequence.AddUserConversionStep(Function, Best->FoundDecl, DestType);
+ Sequence.AddUserConversionStep(Function, Best->FoundDecl, DestType,
+ HadMultipleCandidates);
return;
}
// we just make a note of the actual destination type (possibly a
// base class of the type returned by the conversion function) and
// let the user-defined conversion step handle the conversion.
- Sequence.AddUserConversionStep(Function, Best->FoundDecl, DestType);
+ Sequence.AddUserConversionStep(Function, Best->FoundDecl, DestType,
+ HadMultipleCandidates);
return;
}
- Sequence.AddUserConversionStep(Function, Best->FoundDecl, ConvType);
+ Sequence.AddUserConversionStep(Function, Best->FoundDecl, ConvType,
+ HadMultipleCandidates);
// If the conversion following the call to the conversion function
// is interesting, add it as a separate step.
<< OvlExpr->getSourceRange();
S.NoteAllOverloadCandidates(OvlExpr);
}
-
+
+ bool hadMultipleCandidates() const { return (OvlExpr->getNumDecls() > 1); }
+
int getNumMatches() const { return Matches.size(); }
FunctionDecl* getMatchingFunctionDecl() const {
/// resolved, and NULL otherwise. When @p Complain is true, this
/// routine will emit diagnostics if there is an error.
FunctionDecl *
-Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, QualType TargetType,
- bool Complain,
- DeclAccessPair &FoundResult) {
-
+Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr,
+ QualType TargetType,
+ bool Complain,
+ DeclAccessPair &FoundResult,
+ bool *pHadMultipleCandidates) {
assert(AddressOfExpr->getType() == Context.OverloadTy);
-
- AddressOfFunctionResolver Resolver(*this, AddressOfExpr, TargetType, Complain);
+
+ AddressOfFunctionResolver Resolver(*this, AddressOfExpr, TargetType,
+ Complain);
int NumMatches = Resolver.getNumMatches();
FunctionDecl* Fn = 0;
- if ( NumMatches == 0 && Complain) {
+ if (NumMatches == 0 && Complain) {
if (Resolver.IsInvalidFormOfPointerToMemberFunction())
Resolver.ComplainIsInvalidFormOfPointerToMemberFunction();
else
if (Complain)
CheckAddressOfMemberAccess(AddressOfExpr, FoundResult);
}
-
+
+ if (pHadMultipleCandidates)
+ *pHadMultipleCandidates = Resolver.hadMultipleCandidates();
return Fn;
}