@@ -357,10 +357,98 @@ void AggExprEmitter::visitCXXParenListOrInitListExpr(
357
357
emitArrayInit (dest.getAddress (), arrayTy, e->getType (), e, args,
358
358
arrayFiller);
359
359
return ;
360
+ } else if (e->getType ()->isVariableArrayType ()) {
361
+ cgf.cgm .errorNYI (e->getSourceRange (),
362
+ " visitCXXParenListOrInitListExpr variable array type" );
363
+ return ;
364
+ }
365
+
366
+ if (e->getType ()->isArrayType ()) {
367
+ cgf.cgm .errorNYI (e->getSourceRange (),
368
+ " visitCXXParenListOrInitListExpr array type" );
369
+ return ;
370
+ }
371
+
372
+ assert (e->getType ()->isRecordType () && " Only support structs/unions here!" );
373
+
374
+ // Do struct initialization; this code just sets each individual member
375
+ // to the approprate value. This makes bitfield support automatic;
376
+ // the disadvantage is that the generated code is more difficult for
377
+ // the optimizer, especially with bitfields.
378
+ unsigned numInitElements = args.size ();
379
+ RecordDecl *record = e->getType ()->castAs <RecordType>()->getDecl ();
380
+
381
+ // We'll need to enter cleanup scopes in case any of the element
382
+ // initializers throws an exception.
383
+ assert (!cir::MissingFeatures::requiresCleanups ());
384
+
385
+ unsigned curInitIndex = 0 ;
386
+
387
+ // Emit initialization of base classes.
388
+ if (auto *cxxrd = dyn_cast<CXXRecordDecl>(record)) {
389
+ assert (numInitElements >= cxxrd->getNumBases () &&
390
+ " missing initializer for base class" );
391
+ if (cxxrd->getNumBases () > 0 ) {
392
+ cgf.cgm .errorNYI (e->getSourceRange (),
393
+ " visitCXXParenListOrInitListExpr base class init" );
394
+ return ;
395
+ }
396
+ }
397
+
398
+ LValue destLV = cgf.makeAddrLValue (dest.getAddress (), e->getType ());
399
+
400
+ if (record->isUnion ()) {
401
+ cgf.cgm .errorNYI (e->getSourceRange (),
402
+ " visitCXXParenListOrInitListExpr union type" );
403
+ return ;
360
404
}
361
405
362
- cgf.cgm .errorNYI (
363
- " visitCXXParenListOrInitListExpr Record or VariableSizeArray type" );
406
+ // Here we iterate over the fields; this makes it simpler to both
407
+ // default-initialize fields and skip over unnamed fields.
408
+ for (const FieldDecl *field : record->fields ()) {
409
+ // We're done once we hit the flexible array member.
410
+ if (field->getType ()->isIncompleteArrayType ())
411
+ break ;
412
+
413
+ // Always skip anonymous bitfields.
414
+ if (field->isUnnamedBitField ())
415
+ continue ;
416
+
417
+ // We're done if we reach the end of the explicit initializers, we
418
+ // have a zeroed object, and the rest of the fields are
419
+ // zero-initializable.
420
+ if (curInitIndex == numInitElements && dest.isZeroed () &&
421
+ cgf.getTypes ().isZeroInitializable (e->getType ()))
422
+ break ;
423
+ LValue lv =
424
+ cgf.emitLValueForFieldInitialization (destLV, field, field->getName ());
425
+ // We never generate write-barriers for initialized fields.
426
+ assert (!cir::MissingFeatures::setNonGC ());
427
+
428
+ if (curInitIndex < numInitElements) {
429
+ // Store the initializer into the field.
430
+ CIRGenFunction::SourceLocRAIIObject loc{
431
+ cgf, cgf.getLoc (record->getSourceRange ())};
432
+ emitInitializationToLValue (args[curInitIndex++], lv);
433
+ } else {
434
+ // We're out of initializers; default-initialize to null
435
+ emitNullInitializationToLValue (cgf.getLoc (e->getSourceRange ()), lv);
436
+ }
437
+
438
+ // Push a destructor if necessary.
439
+ // FIXME: if we have an array of structures, all explicitly
440
+ // initialized, we can end up pushing a linear number of cleanups.
441
+ if (QualType::DestructionKind dtorKind =
442
+ field->getType ().isDestructedType ()) {
443
+ cgf.cgm .errorNYI (e->getSourceRange (),
444
+ " visitCXXParenListOrInitListExpr destructor" );
445
+ return ;
446
+ }
447
+
448
+ // From classic codegen, maybe not useful for CIR:
449
+ // If the GEP didn't get used because of a dead zero init or something
450
+ // else, clean it up for -O0 builds and general tidiness.
451
+ }
364
452
}
365
453
366
454
// TODO(cir): This could be shared with classic codegen.
0 commit comments