summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-07-31 06:31:19 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-07-31 06:31:19 +0000
commit77be48ac4744554b08b9a6587a4ade8601c9cc90 (patch)
treec1087a1b801effbd2418a6b09d1e749410ea6590 /clang/lib/Sema/SemaInit.cpp
parentc537bd2da4c07c56dfa49a8bc593e4e61a84c5d2 (diff)
downloadbcm5719-llvm-77be48ac4744554b08b9a6587a4ade8601c9cc90.tar.gz
bcm5719-llvm-77be48ac4744554b08b9a6587a4ade8601c9cc90.zip
PR18097: Support initializing an _Atomic(T) from an object of C++ class type T
or a class derived from T. We already supported this when initializing _Atomic(T) from T for most (and maybe all) other reasonable values of T. llvm-svn: 214390
Diffstat (limited to 'clang/lib/Sema/SemaInit.cpp')
-rw-r--r--clang/lib/Sema/SemaInit.cpp55
1 files changed, 43 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 947be780e02..d9f86c6e4fc 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -2767,6 +2767,7 @@ void InitializationSequence::Step::Destroy() {
case SK_QualificationConversionRValue:
case SK_QualificationConversionXValue:
case SK_QualificationConversionLValue:
+ case SK_AtomicConversion:
case SK_LValueToRValue:
case SK_ListInitialization:
case SK_UnwrapInitList:
@@ -2919,6 +2920,13 @@ void InitializationSequence::AddQualificationConversionStep(QualType Ty,
Steps.push_back(S);
}
+void InitializationSequence::AddAtomicConversionStep(QualType Ty) {
+ Step S;
+ S.Kind = SK_AtomicConversion;
+ S.Type = Ty;
+ Steps.push_back(S);
+}
+
void InitializationSequence::AddLValueToRValueStep(QualType Ty) {
assert(!Ty.hasQualifiers() && "rvalues may not have qualifiers");
@@ -4174,12 +4182,11 @@ static void TryDefaultInitialization(Sema &S,
/// which enumerates all conversion functions and performs overload resolution
/// to select the best.
static void TryUserDefinedConversion(Sema &S,
- const InitializedEntity &Entity,
+ QualType DestType,
const InitializationKind &Kind,
Expr *Initializer,
InitializationSequence &Sequence,
bool TopLevelOfInitList) {
- QualType DestType = Entity.getType();
assert(!DestType->isReferenceType() && "References are handled elsewhere");
QualType SourceType = Initializer->getType();
assert((DestType->isRecordType() || SourceType->isRecordType()) &&
@@ -4596,7 +4603,6 @@ void InitializationSequence::InitializeFrom(Sema &S,
Initializer) ||
S.ConversionToObjCStringLiteralCheck(DestType, Initializer))
Args[0] = Initializer;
-
}
if (!isa<InitListExpr>(Initializer))
SourceType = Initializer->getType();
@@ -4741,7 +4747,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
(Context.hasSameUnqualifiedType(SourceType, DestType) ||
S.IsDerivedFrom(SourceType, DestType))))
TryConstructorInitialization(S, Entity, Kind, Args,
- Entity.getType(), *this);
+ DestType, *this);
// - Otherwise (i.e., for the remaining copy-initialization cases),
// user-defined conversion sequences that can convert from the source
// type to the destination type or (when a conversion function is
@@ -4749,7 +4755,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
// 13.3.1.4, and the best one is chosen through overload resolution
// (13.3).
else
- TryUserDefinedConversion(S, Entity, Kind, Initializer, *this,
+ TryUserDefinedConversion(S, DestType, Kind, Initializer, *this,
TopLevelOfInitList);
return;
}
@@ -4763,9 +4769,22 @@ void InitializationSequence::InitializeFrom(Sema &S,
// - Otherwise, if the source type is a (possibly cv-qualified) class
// type, conversion functions are considered.
if (!SourceType.isNull() && SourceType->isRecordType()) {
- TryUserDefinedConversion(S, Entity, Kind, Initializer, *this,
+ // For a conversion to _Atomic(T) from either T or a class type derived
+ // from T, initialize the T object then convert to _Atomic type.
+ bool NeedAtomicConversion = false;
+ if (const AtomicType *Atomic = DestType->getAs<AtomicType>()) {
+ if (Context.hasSameUnqualifiedType(SourceType, Atomic->getValueType()) ||
+ S.IsDerivedFrom(SourceType, Atomic->getValueType())) {
+ DestType = Atomic->getValueType();
+ NeedAtomicConversion = true;
+ }
+ }
+
+ TryUserDefinedConversion(S, DestType, Kind, Initializer, *this,
TopLevelOfInitList);
MaybeProduceObjCObject(S, *this, Entity);
+ if (!Failed() && NeedAtomicConversion)
+ AddAtomicConversionStep(Entity.getType());
return;
}
@@ -4774,16 +4793,16 @@ void InitializationSequence::InitializeFrom(Sema &S,
// conversions (Clause 4) will be used, if necessary, to convert the
// initializer expression to the cv-unqualified version of the
// destination type; no user-defined conversions are considered.
-
+
ImplicitConversionSequence ICS
- = S.TryImplicitConversion(Initializer, Entity.getType(),
+ = S.TryImplicitConversion(Initializer, DestType,
/*SuppressUserConversions*/true,
/*AllowExplicitConversions*/ false,
/*InOverloadResolution*/ false,
/*CStyle=*/Kind.isCStyleOrFunctionalCast(),
allowObjCWritebackConversion);
-
- if (ICS.isStandard() &&
+
+ if (ICS.isStandard() &&
ICS.Standard.Second == ICK_Writeback_Conversion) {
// Objective-C ARC writeback conversion.
@@ -4804,7 +4823,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
AddConversionSequenceStep(LvalueICS, ICS.Standard.getToType(0));
}
- AddPassByIndirectCopyRestoreStep(Entity.getType(), ShouldCopy);
+ AddPassByIndirectCopyRestoreStep(DestType, ShouldCopy);
} else if (ICS.isBad()) {
DeclAccessPair dap;
if (isLibstdcxxPointerReturnFalseHack(S, Entity, Initializer)) {
@@ -4816,7 +4835,7 @@ void InitializationSequence::InitializeFrom(Sema &S,
else
SetFailed(InitializationSequence::FK_ConversionFailed);
} else {
- AddConversionSequenceStep(ICS, Entity.getType(), TopLevelOfInitList);
+ AddConversionSequenceStep(ICS, DestType, TopLevelOfInitList);
MaybeProduceObjCObject(S, *this, Entity);
}
@@ -5772,6 +5791,7 @@ InitializationSequence::Perform(Sema &S,
case SK_QualificationConversionLValue:
case SK_QualificationConversionXValue:
case SK_QualificationConversionRValue:
+ case SK_AtomicConversion:
case SK_LValueToRValue:
case SK_ConversionSequence:
case SK_ConversionSequenceNoNarrowing:
@@ -6062,6 +6082,13 @@ InitializationSequence::Perform(Sema &S,
break;
}
+ case SK_AtomicConversion: {
+ assert(CurInit.get()->isRValue() && "cannot convert glvalue to atomic");
+ CurInit = S.ImpCastExprToType(CurInit.get(), Step->Type,
+ CK_NonAtomicToAtomic, VK_RValue);
+ break;
+ }
+
case SK_LValueToRValue: {
assert(CurInit.get()->isGLValue() && "cannot load from a prvalue");
CurInit = ImplicitCastExpr::Create(S.Context, Step->Type,
@@ -7033,6 +7060,10 @@ void InitializationSequence::dump(raw_ostream &OS) const {
OS << "qualification conversion (lvalue)";
break;
+ case SK_AtomicConversion:
+ OS << "non-atomic-to-atomic conversion";
+ break;
+
case SK_LValueToRValue:
OS << "load (lvalue to rvalue)";
break;
OpenPOWER on IntegriCloud