From ff4ba5dfa221380aeba85134c8e62266b27cd904 Mon Sep 17 00:00:00 2001 From: Andy Kaylor Date: Wed, 3 Sep 2025 16:12:58 -0700 Subject: [PATCH] [CIR] Finish record layout for classes with virtual bases There was a small piece left unimplemented for classes with a primary virtual base. This adds that implementation. --- .../CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp | 5 ++-- clang/test/CIR/CodeGen/vbase.cpp | 23 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp index 6c7cf75aa2c99..d732248f31a00 100644 --- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp @@ -913,8 +913,9 @@ void CIRRecordLowering::computeVolatileBitfields() { void CIRRecordLowering::accumulateBases() { // If we've got a primary virtual base, we need to add it with the bases. if (astRecordLayout.isPrimaryBaseVirtual()) { - cirGenTypes.getCGModule().errorNYI(recordDecl->getSourceRange(), - "accumulateBases: primary virtual base"); + const CXXRecordDecl *baseDecl = astRecordLayout.getPrimaryBase(); + members.push_back(MemberInfo(CharUnits::Zero(), MemberInfo::InfoKind::Base, + getStorageType(baseDecl), baseDecl)); } // Accumulate the non-virtual bases. diff --git a/clang/test/CIR/CodeGen/vbase.cpp b/clang/test/CIR/CodeGen/vbase.cpp index 1d1b5e083bfc9..2e0345c24b069 100644 --- a/clang/test/CIR/CodeGen/vbase.cpp +++ b/clang/test/CIR/CodeGen/vbase.cpp @@ -5,6 +5,29 @@ // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll // RUN: FileCheck --input-file=%t.ll %s --check-prefix=OGCG +// Test the record layout for a class with a primary virtual base. +class Base { +public: + virtual void f(); +}; + +class Derived : public virtual Base {}; + +// This is just here to force the record types to be emitted. +void f() { + Derived d; +} + +// CIR: !rec_Base = !cir.record +// CIR: !rec_Derived = !cir.record + +// LLVM: %class.Derived = type { %class.Base } +// LLVM: %class.Base = type { ptr } + +// OGCG: %class.Derived = type { %class.Base } +// OGCG: %class.Base = type { ptr } + +// Test the constructor handling for a class with a virtual base. struct A { int a; };