This patch implements Sema for clause 13.3.3.1p4.

It has to do with vararg constructors used as conversion
functions. Code gen needs work. This is WIP.

llvm-svn: 86207
This commit is contained in:
Fariborz Jahanian 2009-11-06 00:23:08 +00:00
parent 701e4e9b2b
commit 5582451e91
4 changed files with 30 additions and 11 deletions

View File

@ -3827,6 +3827,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
ICS->UserDefined.Before = Best->Conversions[0].Standard;
ICS->UserDefined.After = Best->FinalConversion;
ICS->UserDefined.ConversionFunction = Best->Function;
ICS->UserDefined.EllipsisConversion = false;
assert(ICS->UserDefined.After.ReferenceBinding &&
ICS->UserDefined.After.DirectBinding &&
"Expected a direct reference binding!");

View File

@ -1086,18 +1086,21 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
} else if (const CXXConstructorDecl *Ctor =
dyn_cast<CXXConstructorDecl>(FD)) {
CastKind = CastExpr::CK_ConstructorConversion;
// If the user-defined conversion is specified by a constructor, the
// initial standard conversion sequence converts the source type to the
// type required by the argument of the constructor
BeforeToType = Ctor->getParamDecl(0)->getType();
// Do no conversion if dealing with ... for the first conversion.
if (!ICS.UserDefined.EllipsisConversion)
// If the user-defined conversion is specified by a constructor, the
// initial standard conversion sequence converts the source type to the
// type required by the argument of the constructor
BeforeToType = Ctor->getParamDecl(0)->getType();
}
else
assert(0 && "Unknown conversion function kind!");
if (PerformImplicitConversion(From, BeforeToType,
ICS.UserDefined.Before, "converting"))
return true;
// Whatch out for elipsis conversion.
if (!BeforeToType.isNull()) {
if (PerformImplicitConversion(From, BeforeToType,
ICS.UserDefined.Before, "converting"))
return true;
}
OwningExprResult CastArg
= BuildCXXCastArgument(From->getLocStart(),

View File

@ -1481,9 +1481,14 @@ Sema::OverloadingResult Sema::IsUserDefinedConversion(
// sequence converts the source type to the type required by
// the argument of the constructor.
//
// FIXME: What about ellipsis conversions?
QualType ThisType = Constructor->getThisType(Context);
User.Before = Best->Conversions[0].Standard;
if (Best->Conversions[0].ConversionKind ==
ImplicitConversionSequence::EllipsisConversion)
User.EllipsisConversion = true;
else {
User.Before = Best->Conversions[0].Standard;
User.EllipsisConversion = false;
}
User.ConversionFunction = Constructor;
User.After.setAsIdentityConversion();
User.After.FromTypePtr
@ -1500,6 +1505,7 @@ Sema::OverloadingResult Sema::IsUserDefinedConversion(
// implicit object parameter of the conversion function.
User.Before = Best->Conversions[0].Standard;
User.ConversionFunction = Conversion;
User.EllipsisConversion = false;
// C++ [over.ics.user]p2:
// The second standard conversion sequence converts the
@ -2693,6 +2699,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
Candidate.Conversions[0].ConversionKind
= ImplicitConversionSequence::UserDefinedConversion;
Candidate.Conversions[0].UserDefined.Before = ObjectInit.Standard;
Candidate.Conversions[0].UserDefined.EllipsisConversion = false;
Candidate.Conversions[0].UserDefined.ConversionFunction = Conversion;
Candidate.Conversions[0].UserDefined.After
= Candidate.Conversions[0].UserDefined.Before;

View File

@ -156,6 +156,14 @@ namespace clang {
/// object parameter of the conversion function.
StandardConversionSequence Before;
/// EllipsisConversion - When this is true, it means user-defined
/// conversion sequence starts with a ... (elipsis) conversion, instead of
/// a standard conversion. In this case, 'Before' field must be ignored.
// FIXME. I much rather put this as the first field. But there seems to be
// a gcc code gen. bug which causes a crash in a test. Putting it here seems
// to work around the crash.
bool EllipsisConversion : 1;
/// After - Represents the standard conversion that occurs after
/// the actual user-defined conversion.
StandardConversionSequence After;