diff options
author | Douglas Gregor <dgregor@apple.com> | 2008-11-03 17:51:48 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2008-11-03 17:51:48 +0000 |
commit | 396b7cd9f6b35d87d17ae03e9448b5c1f2184598 (patch) | |
tree | 9fdb8e3d52d7c975a07f8444618bbd5b017bbb00 /lib/Sema/SemaOverload.cpp | |
parent | d934112e6170b0fd940d8e40db6936cea2cdcf62 (diff) |
Add implicitly-declared default and copy constructors to C++ classes,
when appropriate.
Conversions for class types now make use of copy constructors. I've
replaced the egregious hack allowing class-to-class conversions with a
slightly less egregious hack calling these conversions standard
conversions (for overloading reasons).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58622 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 69c025518e..b20c026f71 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -350,24 +350,34 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType) ImplicitConversionSequence ICS; if (IsStandardConversion(From, ToType, ICS.Standard)) ICS.ConversionKind = ImplicitConversionSequence::StandardConversion; - else if (IsUserDefinedConversion(From, ToType, ICS.UserDefined)) + else if (IsUserDefinedConversion(From, ToType, ICS.UserDefined)) { ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion; - else { - // FIXME: This is a hack to allow a class type S to implicitly - // convert to another class type S, at least until we have proper - // support for implicitly-declared copy constructors. - QualType FromType = Context.getCanonicalType(From->getType()); - ToType = Context.getCanonicalType(ToType); - if (FromType.getUnqualifiedType() == ToType.getUnqualifiedType()) { - ICS.Standard.setAsIdentityConversion(); - ICS.Standard.FromTypePtr = From->getType().getAsOpaquePtr(); - ICS.Standard.ToTypePtr = ToType.getAsOpaquePtr(); - ICS.ConversionKind = ImplicitConversionSequence::StandardConversion; - return ICS; + // C++ [over.ics.user]p4: + // A conversion of an expression of class type to the same class + // type is given Exact Match rank, and a conversion of an + // expression of class type to a base class of that type is + // given Conversion rank, in spite of the fact that a copy + // constructor (i.e., a user-defined conversion function) is + // called for those cases. + if (CXXConstructorDecl *Constructor + = dyn_cast<CXXConstructorDecl>(ICS.UserDefined.ConversionFunction)) { + if (Constructor->isCopyConstructor(Context)) { + // FIXME: This is a temporary hack to give copy-constructor + // calls the appropriate rank (Exact Match or Conversion) by + // making them into standard conversions. To really fix this, we + // need to tweak the rank-checking logic to deal with ranking + // different kinds of user conversions. + ICS.ConversionKind = ImplicitConversionSequence::StandardConversion; + ICS.Standard.setAsIdentityConversion(); + ICS.Standard.FromTypePtr = From->getType().getAsOpaquePtr(); + ICS.Standard.ToTypePtr = ToType.getAsOpaquePtr(); + if (IsDerivedFrom(From->getType().getUnqualifiedType(), + ToType.getUnqualifiedType())) + ICS.Standard.Second = ICK_Derived_To_Base; + } } - + } else ICS.ConversionKind = ImplicitConversionSequence::BadConversion; - } return ICS; } |