================
@@ -238,31 +238,44 @@ void CIRGenFunction::emitCtorPrologue(const 
CXXConstructorDecl *cd,
   bool constructVBases = ctorType != Ctor_Base &&
                          classDecl->getNumVBases() != 0 &&
                          !classDecl->isAbstract();
-  if (constructVBases) {
-    cgm.errorNYI(cd->getSourceRange(), "emitCtorPrologue: virtual base");
-    return;
-  }
-
-  const mlir::Value oldThisValue = cxxThisValue;
-  if (!constructVBases && b != e && (*b)->isBaseInitializer() &&
-      (*b)->isBaseVirtual()) {
+  if (constructVBases &&
+      !cgm.getTarget().getCXXABI().hasConstructorVariants()) {
     cgm.errorNYI(cd->getSourceRange(),
-                 "emitCtorPrologue: virtual base initializer");
+                 "emitCtorPrologue: virtual base without variants");
     return;
   }
 
-  // Handle non-virtual base initializers.
-  for (; b != e && (*b)->isBaseInitializer(); b++) {
-    assert(!(*b)->isBaseVirtual());
+  const mlir::Value oldThisValue = cxxThisValue;
 
+  // Initialize virtual bases.
+  auto emitInitializer = [&](CXXCtorInitializer *baseInit) {
     if (cgm.getCodeGenOpts().StrictVTablePointers &&
         cgm.getCodeGenOpts().OptimizationLevel > 0 &&
-        isInitializerOfDynamicClass(*b)) {
+        isInitializerOfDynamicClass(baseInit)) {
+      // It's OK to continue after emitting the error here. The missing code
+      // just "launders" the 'this' pointer.
       cgm.errorNYI(cd->getSourceRange(),
-                   "emitCtorPrologue: strict vtable pointers");
-      return;
+                   "emitCtorPrologue: strict vtable pointers for vbase");
     }
-    emitBaseInitializer(getLoc(cd->getBeginLoc()), classDecl, *b);
+    emitBaseInitializer(getLoc(cd->getBeginLoc()), classDecl, baseInit);
+  };
+
+  for (; b != e && (*b)->isBaseInitializer() && (*b)->isBaseVirtual(); b++) {
+    if (!constructVBases)
----------------
andykaylor wrote:

This is inside the loop because if we are not constructing vbases we need to 
update the iterator to move past them. The initializers are ordered such that 
all virtual bases occur before the first non-virtual base. This loop is 
necessary to position the iterator for the loop below.

The MS CXXABI throws a bit of a wrench into the possibility of a range loop, 
because we need to insert a branch to a continue block between the virtual 
initializers and the non-virtual initializers, but we can probably use a flag 
to check for the conditions to do that. I'll play around with this loop in OGCG 
and see if I can simplify it without breaking anything.

https://github.com/llvm/llvm-project/pull/155534
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to