forked from OSchip/llvm-project
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:
parent
701e4e9b2b
commit
5582451e91
|
@ -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!");
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue