PR12670: Support for initializing an array of non-aggregate class type from an

initializer list. Patch by Olivier Goffart, with extra testcases by Meador Inge
and Daniel Lunow.

llvm-svn: 159896
This commit is contained in:
Richard Smith
2012-07-07 08:35:56 +00:00
parent 4ff9ff974c
commit e20c83d9ed
6 changed files with 226 additions and 42 deletions

View File

@@ -687,22 +687,21 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity,
} else if (DeclType->isVectorType()) {
CheckVectorType(Entity, IList, DeclType, Index,
StructuredList, StructuredIndex);
} else if (DeclType->isAggregateType()) {
if (DeclType->isRecordType()) {
RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();
CheckStructUnionTypes(Entity, IList, DeclType, RD->field_begin(),
SubobjectIsDesignatorContext, Index,
StructuredList, StructuredIndex,
TopLevelObject);
} else if (DeclType->isArrayType()) {
llvm::APSInt Zero(
SemaRef.Context.getTypeSize(SemaRef.Context.getSizeType()),
false);
CheckArrayType(Entity, IList, DeclType, Zero,
SubobjectIsDesignatorContext, Index,
StructuredList, StructuredIndex);
} else
llvm_unreachable("Aggregate that isn't a structure or array?!");
} else if (DeclType->isRecordType()) {
assert(DeclType->isAggregateType() &&
"non-aggregate records should be handed in CheckSubElementType");
RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();
CheckStructUnionTypes(Entity, IList, DeclType, RD->field_begin(),
SubobjectIsDesignatorContext, Index,
StructuredList, StructuredIndex,
TopLevelObject);
} else if (DeclType->isArrayType()) {
llvm::APSInt Zero(
SemaRef.Context.getTypeSize(SemaRef.Context.getSizeType()),
false);
CheckArrayType(Entity, IList, DeclType, Zero,
SubobjectIsDesignatorContext, Index,
StructuredList, StructuredIndex);
} else if (DeclType->isVoidType() || DeclType->isFunctionType()) {
// This type is invalid, issue a diagnostic.
++Index;
@@ -710,19 +709,6 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity,
SemaRef.Diag(IList->getLocStart(), diag::err_illegal_initializer_type)
<< DeclType;
hadError = true;
} else if (DeclType->isRecordType()) {
// C++ [dcl.init]p14:
// [...] If the class is an aggregate (8.5.1), and the initializer
// is a brace-enclosed list, see 8.5.1.
//
// Note: 8.5.1 is handled below; here, we diagnose the case where
// we have an initializer list and a destination type that is not
// an aggregate.
// FIXME: In C++0x, this is yet another form of initialization.
if (!VerifyOnly)
SemaRef.Diag(IList->getLocStart(), diag::err_init_non_aggr_init_list)
<< DeclType << IList->getSourceRange();
hadError = true;
} else if (DeclType->isReferenceType()) {
CheckReferenceType(Entity, IList, DeclType, Index,
StructuredList, StructuredIndex);
@@ -747,18 +733,25 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
unsigned &StructuredIndex) {
Expr *expr = IList->getInit(Index);
if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) {
unsigned newIndex = 0;
unsigned newStructuredIndex = 0;
InitListExpr *newStructuredList
= getStructuredSubobjectInit(IList, Index, ElemType,
StructuredList, StructuredIndex,
SubInitList->getSourceRange());
CheckExplicitInitList(Entity, SubInitList, ElemType, newIndex,
newStructuredList, newStructuredIndex);
++StructuredIndex;
++Index;
return;
} else if (ElemType->isScalarType()) {
if (!ElemType->isRecordType() || ElemType->isAggregateType()) {
unsigned newIndex = 0;
unsigned newStructuredIndex = 0;
InitListExpr *newStructuredList
= getStructuredSubobjectInit(IList, Index, ElemType,
StructuredList, StructuredIndex,
SubInitList->getSourceRange());
CheckExplicitInitList(Entity, SubInitList, ElemType, newIndex,
newStructuredList, newStructuredIndex);
++StructuredIndex;
++Index;
return;
}
assert(SemaRef.getLangOpts().CPlusPlus &&
"non-aggregate records are only possible in C++");
// C++ initialization is handled later.
}
if (ElemType->isScalarType()) {
return CheckScalarType(Entity, IList, ElemType, Index,
StructuredList, StructuredIndex);
} else if (ElemType->isReferenceType()) {