Introduce support for C++0x explicit conversion operators (N2437)

Small cleanup in the handling of user-defined conversions. 

Also, implement an optimization when constructing a call. We avoid
recomputing implicit conversion sequences and instead use those
conversion sequences that we computed as part of overload resolution.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62231 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 65c1416..20f0522 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -128,7 +128,8 @@
   Expr *DefaultArgPtr = DefaultArg.get();
   bool DefaultInitFailed = CheckInitializerTypes(DefaultArgPtr, ParamType,
                                                  EqualLoc,
-                                                 Param->getDeclName());
+                                                 Param->getDeclName(),
+                                                 /*DirectInit=*/false);
   if (DefaultArgPtr != DefaultArg.get()) {
     DefaultArg.take();
     DefaultArg.reset(DefaultArgPtr);
@@ -1299,6 +1300,12 @@
   R = Context.getFunctionType(ConvType, 0, 0, false, 
                               R->getAsFunctionTypeProto()->getTypeQuals());
 
+  // C++0x explicit conversion operators.
+  if (D.getDeclSpec().isExplicitSpecified() && !getLangOptions().CPlusPlus0x)
+    Diag(D.getDeclSpec().getExplicitSpecLoc(), 
+         diag::warn_explicit_conversion_functions)
+      << SourceRange(D.getDeclSpec().getExplicitSpecLoc());
+
   return isInvalid;
 }
 
@@ -1538,7 +1545,7 @@
 
   assert(NumExprs == 1 && "Expected 1 expression");
   // Set the init expression, handles conversions.
-  AddInitializerToDecl(Dcl, ExprArg(*this, ExprTys[0]));
+  AddInitializerToDecl(Dcl, ExprArg(*this, ExprTys[0]), /*DirectInit=*/true);
 }
 
 /// PerformInitializationByConstructor - Perform initialization by
@@ -1677,10 +1684,13 @@
 ///
 /// When @p SuppressUserConversions, user-defined conversions are
 /// suppressed.
+/// When @p AllowExplicit, we also permit explicit user-defined
+/// conversion functions.
 bool 
 Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType, 
                          ImplicitConversionSequence *ICS,
-                         bool SuppressUserConversions) {
+                         bool SuppressUserConversions,
+                         bool AllowExplicit) {
   assert(DeclType->isReferenceType() && "Reference init needs a reference");
 
   QualType T1 = DeclType->getAsReferenceType()->getPointeeType();
@@ -1780,7 +1790,8 @@
       // If the conversion function doesn't return a reference type,
       // it can't be considered for this conversion.
       // FIXME: This will change when we support rvalue references.
-      if (Conv->getConversionType()->isReferenceType())
+      if (Conv->getConversionType()->isReferenceType() &&
+          (AllowExplicit || !Conv->isExplicit()))
         AddConversionCandidate(Conv, Init, DeclType, CandidateSet);
     }