Skip to content

Commit 20c08f3

Browse files
authored
[Clang][CodeGen]NFC] Modernize loops in EmitCtorPrologue (#155668)
This patch updates the loops in EmitCtorPrologue to use range-based for loops rather than looping over a single iterator which was being shared between three loops. Setting up three separate ranges adds a very small amount of overhead, but it improves the readability and maintainability of the code.
1 parent 0b9a79b commit 20c08f3

File tree

1 file changed

+36
-19
lines changed

1 file changed

+36
-19
lines changed

clang/lib/CodeGen/CGClass.cpp

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)