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);
}