forked from OSchip/llvm-project
Implement value initialization in InitializationSequence; untested
WIP, yet again. llvm-svn: 91368
This commit is contained in:
parent
68943780a6
commit
7dc42e5d4c
|
@ -1970,6 +1970,7 @@ void InitializationSequence::Step::Destroy() {
|
|||
case SK_QualificationConversionLValue:
|
||||
case SK_ListInitialization:
|
||||
case SK_ConstructorInitialization:
|
||||
case SK_ZeroInitialization:
|
||||
break;
|
||||
|
||||
case SK_ConversionSequence:
|
||||
|
@ -2048,6 +2049,13 @@ InitializationSequence::AddConstructorInitializationStep(
|
|||
Steps.push_back(S);
|
||||
}
|
||||
|
||||
void InitializationSequence::AddZeroInitializationStep(QualType T) {
|
||||
Step S;
|
||||
S.Kind = SK_ZeroInitialization;
|
||||
S.Type = T;
|
||||
Steps.push_back(S);
|
||||
}
|
||||
|
||||
void InitializationSequence::SetOverloadFailure(FailureKind Failure,
|
||||
OverloadingResult Result) {
|
||||
SequenceKind = FailedSequence;
|
||||
|
@ -2458,14 +2466,6 @@ static void TryStringLiteralInitialization(Sema &S,
|
|||
// FIXME: Implement!
|
||||
}
|
||||
|
||||
/// \brief Attempt value initialization (C++ [dcl.init]p7).
|
||||
static void TryValueInitialization(Sema &S,
|
||||
const InitializedEntity &Entity,
|
||||
const InitializationKind &Kind,
|
||||
InitializationSequence &Sequence) {
|
||||
// FIXME: Implement!
|
||||
}
|
||||
|
||||
/// \brief Attempt initialization by constructor (C++ [dcl.init]), which
|
||||
/// enumerates the constructors of the initialized entity and performs overload
|
||||
/// resolution to select the best.
|
||||
|
@ -2473,6 +2473,7 @@ static void TryConstructorInitialization(Sema &S,
|
|||
const InitializedEntity &Entity,
|
||||
const InitializationKind &Kind,
|
||||
Expr **Args, unsigned NumArgs,
|
||||
QualType DestType,
|
||||
InitializationSequence &Sequence) {
|
||||
Sequence.setSequenceKind(InitializationSequence::ConstructorInitialization);
|
||||
|
||||
|
@ -2489,7 +2490,6 @@ static void TryConstructorInitialization(Sema &S,
|
|||
|
||||
// The type we're converting to is a class type. Enumerate its constructors
|
||||
// to see if one is suitable.
|
||||
QualType DestType = Entity.getType().getType();
|
||||
const RecordType *DestRecordType = DestType->getAs<RecordType>();
|
||||
assert(DestRecordType && "Constructor initialization requires record type");
|
||||
CXXRecordDecl *DestRecordDecl
|
||||
|
@ -2540,6 +2540,41 @@ static void TryConstructorInitialization(Sema &S,
|
|||
DestType);
|
||||
}
|
||||
|
||||
/// \brief Attempt value initialization (C++ [dcl.init]p7).
|
||||
static void TryValueInitialization(Sema &S,
|
||||
const InitializedEntity &Entity,
|
||||
const InitializationKind &Kind,
|
||||
InitializationSequence &Sequence) {
|
||||
// C++ [dcl.init]p5:
|
||||
//
|
||||
// To value-initialize an object of type T means:
|
||||
QualType T = Entity.getType().getType();
|
||||
|
||||
// -- if T is an array type, then each element is value-initialized;
|
||||
while (const ArrayType *AT = S.Context.getAsArrayType(T))
|
||||
T = AT->getElementType();
|
||||
|
||||
if (const RecordType *RT = T->getAs<RecordType>()) {
|
||||
if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
|
||||
// -- if T is a class type (clause 9) with a user-declared
|
||||
// constructor (12.1), then the default constructor for T is
|
||||
// called (and the initialization is ill-formed if T has no
|
||||
// accessible default constructor);
|
||||
//
|
||||
// FIXME: we really want to refer to a single subobject of the array,
|
||||
// but Entity doesn't have a way to capture that (yet).
|
||||
if (ClassDecl->hasUserDeclaredConstructor())
|
||||
return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence);
|
||||
|
||||
// FIXME: non-union class type w/ non-trivial default constructor gets
|
||||
// zero-initialized, then constructor gets called.
|
||||
}
|
||||
}
|
||||
|
||||
Sequence.AddZeroInitializationStep(Entity.getType().getType());
|
||||
Sequence.setSequenceKind(InitializationSequence::ZeroInitialization);
|
||||
}
|
||||
|
||||
/// \brief Attempt a user-defined conversion between two types (C++ [dcl.init]),
|
||||
/// which enumerates all conversion functions and performs overload resolution
|
||||
/// to select the best.
|
||||
|
@ -2776,7 +2811,8 @@ InitializationSequence::InitializationSequence(Sema &S,
|
|||
(Kind.getKind() == InitializationKind::IK_Copy &&
|
||||
(Context.hasSameUnqualifiedType(SourceType, DestType) ||
|
||||
S.IsDerivedFrom(SourceType, DestType))))
|
||||
TryConstructorInitialization(S, Entity, Kind, Args, NumArgs, *this);
|
||||
TryConstructorInitialization(S, Entity, Kind, Args, NumArgs,
|
||||
Entity.getType().getType(), *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
|
||||
|
@ -3067,6 +3103,16 @@ InitializationSequence::Perform(Sema &S,
|
|||
CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
|
||||
break;
|
||||
}
|
||||
|
||||
case SK_ZeroInitialization: {
|
||||
if (Kind.getKind() == InitializationKind::IK_Value)
|
||||
CurInit = S.Owned(new (S.Context) CXXZeroInitValueExpr(Step->Type,
|
||||
Kind.getRange().getBegin(),
|
||||
Kind.getRange().getEnd()));
|
||||
else
|
||||
CurInit = S.Owned(new (S.Context) ImplicitValueInitExpr(Step->Type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -269,7 +269,7 @@ public:
|
|||
|
||||
/// \brief Retrieve the source range that covers the initialization.
|
||||
SourceRange getRange() const {
|
||||
return SourceRange(Locations[0], Locations[1]);
|
||||
return SourceRange(Locations[0], Locations[2]);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the equal sign for copy initialization
|
||||
|
@ -293,6 +293,9 @@ public:
|
|||
class InitializationSequence {
|
||||
public:
|
||||
/// \brief Describes the kind of initialization sequence computed.
|
||||
///
|
||||
/// FIXME: Much of this information is in the initialization steps... why is
|
||||
/// it duplicated here?
|
||||
enum SequenceKind {
|
||||
/// \brief A failed initialization sequence. The failure kind tells what
|
||||
/// happened.
|
||||
|
@ -313,7 +316,10 @@ public:
|
|||
ReferenceBinding,
|
||||
|
||||
/// \brief List initialization
|
||||
ListInitialization
|
||||
ListInitialization,
|
||||
|
||||
/// \brief Zero-initialization.
|
||||
ZeroInitialization
|
||||
};
|
||||
|
||||
/// \brief Describes the kind of a particular step in an initialization
|
||||
|
@ -342,7 +348,9 @@ public:
|
|||
/// \brief Perform list-initialization
|
||||
SK_ListInitialization,
|
||||
/// \brief Perform initialization via a constructor.
|
||||
SK_ConstructorInitialization
|
||||
SK_ConstructorInitialization,
|
||||
/// \brief Zero-initialize the object
|
||||
SK_ZeroInitialization
|
||||
};
|
||||
|
||||
/// \brief A single step in the initialization sequence.
|
||||
|
@ -536,10 +544,13 @@ public:
|
|||
/// \brief Add a list-initialiation step
|
||||
void AddListInitializationStep(QualType T);
|
||||
|
||||
/// \brief Add a a constructor-initialization step.
|
||||
/// \brief Add a constructor-initialization step.
|
||||
void AddConstructorInitializationStep(CXXConstructorDecl *Constructor,
|
||||
QualType T);
|
||||
|
||||
/// \brief Add a zero-initialization step.
|
||||
void AddZeroInitializationStep(QualType T);
|
||||
|
||||
/// \brief Note that this initialization sequence failed.
|
||||
void SetFailed(FailureKind Failure) {
|
||||
SequenceKind = FailedSequence;
|
||||
|
|
Loading…
Reference in New Issue