Author: Andy Kaylor Date: 2025-09-09T09:56:24-07:00 New Revision: 20c08f36d7d39c97a4979d9a9fd1a5b7fb53e268
URL: https://github.com/llvm/llvm-project/commit/20c08f36d7d39c97a4979d9a9fd1a5b7fb53e268 DIFF: https://github.com/llvm/llvm-project/commit/20c08f36d7d39c97a4979d9a9fd1a5b7fb53e268.diff LOG: [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. Added: Modified: clang/lib/CodeGen/CGClass.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 6742c196053a2..8346ee3aa6a8d 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1271,10 +1271,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, const CXXRecordDecl *ClassDecl = CD->getParent(); - CXXConstructorDecl::init_const_iterator B = CD->init_begin(), - E = CD->init_end(); - - // Virtual base initializers first, if any. They aren't needed if: + // Virtual base initializers aren't needed if: // - This is a base ctor variant // - There are no vbases // - The class is abstract, so a complete object of it cannot be constructed @@ -1296,15 +1293,36 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, assert(BaseCtorContinueBB); } - for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) { - if (!ConstructVBases) - continue; - SaveAndRestore ThisRAII(CXXThisValue); - if (CGM.getCodeGenOpts().StrictVTablePointers && - CGM.getCodeGenOpts().OptimizationLevel > 0 && - isInitializerOfDynamicClass(*B)) - CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); - EmitBaseInitializer(*this, ClassDecl, *B); + // Create three separate ranges for the diff erent types of initializers. + auto AllInits = CD->inits(); + + // Find the boundaries between the three groups. + auto VirtualBaseEnd = std::find_if( + AllInits.begin(), AllInits.end(), [](const CXXCtorInitializer *Init) { + return !(Init->isBaseInitializer() && Init->isBaseVirtual()); + }); + + auto NonVirtualBaseEnd = std::find_if(VirtualBaseEnd, AllInits.end(), + [](const CXXCtorInitializer *Init) { + return !Init->isBaseInitializer(); + }); + + // Create the three ranges. + auto VirtualBaseInits = llvm::make_range(AllInits.begin(), VirtualBaseEnd); + auto NonVirtualBaseInits = + llvm::make_range(VirtualBaseEnd, NonVirtualBaseEnd); + auto MemberInits = llvm::make_range(NonVirtualBaseEnd, AllInits.end()); + + // Process virtual base initializers, if necessary. + if (ConstructVBases) { + for (CXXCtorInitializer *Initializer : VirtualBaseInits) { + SaveAndRestore ThisRAII(CXXThisValue); + if (CGM.getCodeGenOpts().StrictVTablePointers && + CGM.getCodeGenOpts().OptimizationLevel > 0 && + isInitializerOfDynamicClass(Initializer)) + CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); + EmitBaseInitializer(*this, ClassDecl, Initializer); + } } if (BaseCtorContinueBB) { @@ -1314,14 +1332,14 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, } // Then, non-virtual base initializers. - for (; B != E && (*B)->isBaseInitializer(); B++) { - assert(!(*B)->isBaseVirtual()); + for (CXXCtorInitializer *Initializer : NonVirtualBaseInits) { + assert(!Initializer->isBaseVirtual()); SaveAndRestore ThisRAII(CXXThisValue); if (CGM.getCodeGenOpts().StrictVTablePointers && CGM.getCodeGenOpts().OptimizationLevel > 0 && - isInitializerOfDynamicClass(*B)) + isInitializerOfDynamicClass(Initializer)) CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis()); - EmitBaseInitializer(*this, ClassDecl, *B); + EmitBaseInitializer(*this, ClassDecl, Initializer); } InitializeVTablePointers(ClassDecl); @@ -1329,8 +1347,7 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD, // And finally, initialize class members. FieldConstructionScope FCS(*this, LoadCXXThisAddress()); ConstructorMemcpyizer CM(*this, CD, Args); - for (; B != E; B++) { - CXXCtorInitializer *Member = (*B); + for (CXXCtorInitializer *Member : MemberInits) { assert(!Member->isBaseInitializer()); assert(Member->isAnyMemberInitializer() && "Delegating initializer on non-delegating constructor"); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
