aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2008-11-03 17:51:48 +0000
committerDouglas Gregor <dgregor@apple.com>2008-11-03 17:51:48 +0000
commit396b7cd9f6b35d87d17ae03e9448b5c1f2184598 (patch)
tree9fdb8e3d52d7c975a07f8444618bbd5b017bbb00 /lib/Sema/SemaOverload.cpp
parentd934112e6170b0fd940d8e40db6936cea2cdcf62 (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.cpp40
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;
}