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_QualificationConversionLValue:
|
||||||
case SK_ListInitialization:
|
case SK_ListInitialization:
|
||||||
case SK_ConstructorInitialization:
|
case SK_ConstructorInitialization:
|
||||||
|
case SK_ZeroInitialization:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SK_ConversionSequence:
|
case SK_ConversionSequence:
|
||||||
|
@ -2048,6 +2049,13 @@ InitializationSequence::AddConstructorInitializationStep(
|
||||||
Steps.push_back(S);
|
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,
|
void InitializationSequence::SetOverloadFailure(FailureKind Failure,
|
||||||
OverloadingResult Result) {
|
OverloadingResult Result) {
|
||||||
SequenceKind = FailedSequence;
|
SequenceKind = FailedSequence;
|
||||||
|
@ -2458,14 +2466,6 @@ static void TryStringLiteralInitialization(Sema &S,
|
||||||
// FIXME: Implement!
|
// 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
|
/// \brief Attempt initialization by constructor (C++ [dcl.init]), which
|
||||||
/// enumerates the constructors of the initialized entity and performs overload
|
/// enumerates the constructors of the initialized entity and performs overload
|
||||||
/// resolution to select the best.
|
/// resolution to select the best.
|
||||||
|
@ -2473,6 +2473,7 @@ static void TryConstructorInitialization(Sema &S,
|
||||||
const InitializedEntity &Entity,
|
const InitializedEntity &Entity,
|
||||||
const InitializationKind &Kind,
|
const InitializationKind &Kind,
|
||||||
Expr **Args, unsigned NumArgs,
|
Expr **Args, unsigned NumArgs,
|
||||||
|
QualType DestType,
|
||||||
InitializationSequence &Sequence) {
|
InitializationSequence &Sequence) {
|
||||||
Sequence.setSequenceKind(InitializationSequence::ConstructorInitialization);
|
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
|
// The type we're converting to is a class type. Enumerate its constructors
|
||||||
// to see if one is suitable.
|
// to see if one is suitable.
|
||||||
QualType DestType = Entity.getType().getType();
|
|
||||||
const RecordType *DestRecordType = DestType->getAs<RecordType>();
|
const RecordType *DestRecordType = DestType->getAs<RecordType>();
|
||||||
assert(DestRecordType && "Constructor initialization requires record type");
|
assert(DestRecordType && "Constructor initialization requires record type");
|
||||||
CXXRecordDecl *DestRecordDecl
|
CXXRecordDecl *DestRecordDecl
|
||||||
|
@ -2540,6 +2540,41 @@ static void TryConstructorInitialization(Sema &S,
|
||||||
DestType);
|
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]),
|
/// \brief Attempt a user-defined conversion between two types (C++ [dcl.init]),
|
||||||
/// which enumerates all conversion functions and performs overload resolution
|
/// which enumerates all conversion functions and performs overload resolution
|
||||||
/// to select the best.
|
/// to select the best.
|
||||||
|
@ -2776,7 +2811,8 @@ InitializationSequence::InitializationSequence(Sema &S,
|
||||||
(Kind.getKind() == InitializationKind::IK_Copy &&
|
(Kind.getKind() == InitializationKind::IK_Copy &&
|
||||||
(Context.hasSameUnqualifiedType(SourceType, DestType) ||
|
(Context.hasSameUnqualifiedType(SourceType, DestType) ||
|
||||||
S.IsDerivedFrom(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),
|
// - Otherwise (i.e., for the remaining copy-initialization cases),
|
||||||
// user-defined conversion sequences that can convert from the source
|
// user-defined conversion sequences that can convert from the source
|
||||||
// type to the destination type or (when a conversion function is
|
// 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>());
|
CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
|
||||||
break;
|
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.
|
/// \brief Retrieve the source range that covers the initialization.
|
||||||
SourceRange getRange() const {
|
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
|
/// \brief Retrieve the location of the equal sign for copy initialization
|
||||||
|
@ -293,6 +293,9 @@ public:
|
||||||
class InitializationSequence {
|
class InitializationSequence {
|
||||||
public:
|
public:
|
||||||
/// \brief Describes the kind of initialization sequence computed.
|
/// \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 {
|
enum SequenceKind {
|
||||||
/// \brief A failed initialization sequence. The failure kind tells what
|
/// \brief A failed initialization sequence. The failure kind tells what
|
||||||
/// happened.
|
/// happened.
|
||||||
|
@ -313,7 +316,10 @@ public:
|
||||||
ReferenceBinding,
|
ReferenceBinding,
|
||||||
|
|
||||||
/// \brief List initialization
|
/// \brief List initialization
|
||||||
ListInitialization
|
ListInitialization,
|
||||||
|
|
||||||
|
/// \brief Zero-initialization.
|
||||||
|
ZeroInitialization
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Describes the kind of a particular step in an initialization
|
/// \brief Describes the kind of a particular step in an initialization
|
||||||
|
@ -342,7 +348,9 @@ public:
|
||||||
/// \brief Perform list-initialization
|
/// \brief Perform list-initialization
|
||||||
SK_ListInitialization,
|
SK_ListInitialization,
|
||||||
/// \brief Perform initialization via a constructor.
|
/// \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.
|
/// \brief A single step in the initialization sequence.
|
||||||
|
@ -536,9 +544,12 @@ public:
|
||||||
/// \brief Add a list-initialiation step
|
/// \brief Add a list-initialiation step
|
||||||
void AddListInitializationStep(QualType T);
|
void AddListInitializationStep(QualType T);
|
||||||
|
|
||||||
/// \brief Add a a constructor-initialization step.
|
/// \brief Add a constructor-initialization step.
|
||||||
void AddConstructorInitializationStep(CXXConstructorDecl *Constructor,
|
void AddConstructorInitializationStep(CXXConstructorDecl *Constructor,
|
||||||
QualType T);
|
QualType T);
|
||||||
|
|
||||||
|
/// \brief Add a zero-initialization step.
|
||||||
|
void AddZeroInitializationStep(QualType T);
|
||||||
|
|
||||||
/// \brief Note that this initialization sequence failed.
|
/// \brief Note that this initialization sequence failed.
|
||||||
void SetFailed(FailureKind Failure) {
|
void SetFailed(FailureKind Failure) {
|
||||||
|
|
Loading…
Reference in New Issue