diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-01-29 16:53:55 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-01-29 16:53:55 +0000 |
commit | 0bb76897bedb8b747efc6523efb432fc24966118 (patch) | |
tree | f6113fbcc4b4a8e7c5749e565e20487704d2d5a6 /lib/CodeGen/CGExprAgg.cpp | |
parent | 5d2ff63254bf1c3d3ca6844c96f3bfd88561cc7c (diff) |
Clean up designated initialization of unions, so that CodeGen doesn't
have to try to guess which member is being initialized.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63315 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprAgg.cpp')
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 075a12c57e..b487bacc71 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -443,7 +443,38 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { unsigned NumInitElements = E->getNumInits(); RecordDecl *SD = E->getType()->getAsRecordType()->getDecl(); unsigned CurInitVal = 0; - bool isUnion = E->getType()->isUnionType(); + + if (E->getType()->isUnionType()) { + // Only initialize one field of a union. The field itself is + // specified by the initializer list. + if (!E->getInitializedFieldInUnion()) { + // Empty union; we have nothing to do. + +#ifndef NDEBUG + // Make sure that it's really an empty and not a failure of + // semantic analysis. + for (RecordDecl::field_iterator Field = SD->field_begin(), + FieldEnd = SD->field_end(); + Field != FieldEnd; ++Field) + assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed"); +#endif + return; + } + + // FIXME: volatility + FieldDecl *Field = E->getInitializedFieldInUnion(); + LValue FieldLoc = CGF.EmitLValueForField(DestPtr, Field, true, 0); + + if (NumInitElements) { + // Store the initializer into the field + EmitInitializationToLValue(E->getInit(0), FieldLoc); + } else { + // Default-initialize to null + EmitNullInitializationToLValue(FieldLoc, Field->getType()); + } + + return; + } // Here we iterate over the fields; this makes it simpler to both // default-initialize fields and skip over unnamed fields. @@ -457,29 +488,15 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { if (Field->isUnnamedBitfield()) continue; - // When we're coping with C99 designated initializers into a - // union, find the field that has the same type as the expression - // we're initializing the union with. - if (isUnion && CurInitVal < NumInitElements && - (CGF.getContext().getCanonicalType(Field->getType()) != - CGF.getContext().getCanonicalType(E->getInit(CurInitVal)->getType()))) - continue; - // FIXME: volatility - LValue FieldLoc = CGF.EmitLValueForField(DestPtr, *Field, isUnion,0); + LValue FieldLoc = CGF.EmitLValueForField(DestPtr, *Field, false, 0); if (CurInitVal < NumInitElements) { // Store the initializer into the field - // This will probably have to get a bit smarter when we support - // designators in initializers EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc); } else { // We're out of initalizers; default-initialize to null EmitNullInitializationToLValue(FieldLoc, Field->getType()); } - - // Unions only initialize one field. - if (isUnion) - break; } } |