@@ -1271,10 +1271,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
12711271
12721272 const CXXRecordDecl *ClassDecl = CD->getParent ();
12731273
1274- CXXConstructorDecl::init_const_iterator B = CD->init_begin (),
1275- E = CD->init_end ();
1276-
1277- // Virtual base initializers first, if any. They aren't needed if:
1274+ // Virtual base initializers aren't needed if:
12781275 // - This is a base ctor variant
12791276 // - There are no vbases
12801277 // - The class is abstract, so a complete object of it cannot be constructed
@@ -1296,15 +1293,36 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
12961293 assert (BaseCtorContinueBB);
12971294 }
12981295
1299- for (; B != E && (*B)->isBaseInitializer () && (*B)->isBaseVirtual (); B++) {
1300- if (!ConstructVBases)
1301- continue ;
1302- SaveAndRestore ThisRAII (CXXThisValue);
1303- if (CGM.getCodeGenOpts ().StrictVTablePointers &&
1304- CGM.getCodeGenOpts ().OptimizationLevel > 0 &&
1305- isInitializerOfDynamicClass (*B))
1306- CXXThisValue = Builder.CreateLaunderInvariantGroup (LoadCXXThis ());
1307- EmitBaseInitializer (*this , ClassDecl, *B);
1296+ // Create three separate ranges for the different types of initializers.
1297+ auto AllInits = CD->inits ();
1298+
1299+ // Find the boundaries between the three groups.
1300+ auto VirtualBaseEnd = std::find_if (
1301+ AllInits.begin (), AllInits.end (), [](const CXXCtorInitializer *Init) {
1302+ return !(Init->isBaseInitializer () && Init->isBaseVirtual ());
1303+ });
1304+
1305+ auto NonVirtualBaseEnd = std::find_if (VirtualBaseEnd, AllInits.end (),
1306+ [](const CXXCtorInitializer *Init) {
1307+ return !Init->isBaseInitializer ();
1308+ });
1309+
1310+ // Create the three ranges.
1311+ auto VirtualBaseInits = llvm::make_range (AllInits.begin (), VirtualBaseEnd);
1312+ auto NonVirtualBaseInits =
1313+ llvm::make_range (VirtualBaseEnd, NonVirtualBaseEnd);
1314+ auto MemberInits = llvm::make_range (NonVirtualBaseEnd, AllInits.end ());
1315+
1316+ // Process virtual base initializers, if necessary.
1317+ if (ConstructVBases) {
1318+ for (CXXCtorInitializer *Initializer : VirtualBaseInits) {
1319+ SaveAndRestore ThisRAII (CXXThisValue);
1320+ if (CGM.getCodeGenOpts ().StrictVTablePointers &&
1321+ CGM.getCodeGenOpts ().OptimizationLevel > 0 &&
1322+ isInitializerOfDynamicClass (Initializer))
1323+ CXXThisValue = Builder.CreateLaunderInvariantGroup (LoadCXXThis ());
1324+ EmitBaseInitializer (*this , ClassDecl, Initializer);
1325+ }
13081326 }
13091327
13101328 if (BaseCtorContinueBB) {
@@ -1314,23 +1332,22 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
13141332 }
13151333
13161334 // Then, non-virtual base initializers.
1317- for (; B != E && (*B)-> isBaseInitializer (); B++ ) {
1318- assert (!(*B) ->isBaseVirtual ());
1335+ for (CXXCtorInitializer *Initializer : NonVirtualBaseInits ) {
1336+ assert (!Initializer ->isBaseVirtual ());
13191337 SaveAndRestore ThisRAII (CXXThisValue);
13201338 if (CGM.getCodeGenOpts ().StrictVTablePointers &&
13211339 CGM.getCodeGenOpts ().OptimizationLevel > 0 &&
1322- isInitializerOfDynamicClass (*B ))
1340+ isInitializerOfDynamicClass (Initializer ))
13231341 CXXThisValue = Builder.CreateLaunderInvariantGroup (LoadCXXThis ());
1324- EmitBaseInitializer (*this , ClassDecl, *B );
1342+ EmitBaseInitializer (*this , ClassDecl, Initializer );
13251343 }
13261344
13271345 InitializeVTablePointers (ClassDecl);
13281346
13291347 // And finally, initialize class members.
13301348 FieldConstructionScope FCS (*this , LoadCXXThisAddress ());
13311349 ConstructorMemcpyizer CM (*this , CD, Args);
1332- for (; B != E; B++) {
1333- CXXCtorInitializer *Member = (*B);
1350+ for (CXXCtorInitializer *Member : MemberInits) {
13341351 assert (!Member->isBaseInitializer ());
13351352 assert (Member->isAnyMemberInitializer () &&
13361353 " Delegating initializer on non-delegating constructor" );
0 commit comments