diff options
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 8a5e2c87d3..3364132910 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -1450,6 +1450,32 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index, Result->setType(CurrentObjectType); + // Pre-allocate storage for the structured initializer list. + unsigned NumElements = 0; + if (const ArrayType *AType + = SemaRef.Context.getAsArrayType(CurrentObjectType)) { + if (const ConstantArrayType *CAType = dyn_cast<ConstantArrayType>(AType)) { + NumElements = CAType->getSize().getZExtValue(); + // Simple heuristic so that we don't allocate a very large + // initializer with many empty entries at the end. + if (IList && NumElements > IList->getNumInits()) + NumElements = 0; + } + } else if (const VectorType *VType = CurrentObjectType->getAsVectorType()) + NumElements = VType->getNumElements(); + else if (const RecordType *RType = CurrentObjectType->getAsRecordType()) { + RecordDecl *RDecl = RType->getDecl(); + if (RDecl->isUnion()) + NumElements = 1; + else + NumElements = std::distance(RDecl->field_begin(), RDecl->field_end()); + } + + if (IList && NumElements < IList->getNumInits()) + NumElements = IList->getNumInits(); + + Result->reserveInits(NumElements); + // Link this new initializer list into the structured initializer // lists. if (StructuredList) |