https://github.com/dwblaikie updated 
https://github.com/llvm/llvm-project/pull/202807

>From 196ec3726f4f462910c5b5616aa68f7e6e5abbcb Mon Sep 17 00:00:00 2001
From: David Blaikie <[email protected]>
Date: Wed, 20 May 2026 22:07:29 +0000
Subject: [PATCH 1/7] WIP

---
 clang/include/clang/CodeGen/ModuleBuilder.h   |  3 ++
 clang/lib/CodeGen/ModuleBuilder.cpp           | 11 +++++
 .../unittests/CodeGen/CodeGenExternalTest.cpp | 47 +++++++++++++++----
 3 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/clang/include/clang/CodeGen/ModuleBuilder.h 
b/clang/include/clang/CodeGen/ModuleBuilder.h
index 5173fd05d75d6..a144e904b0228 100644
--- a/clang/include/clang/CodeGen/ModuleBuilder.h
+++ b/clang/include/clang/CodeGen/ModuleBuilder.h
@@ -32,6 +32,7 @@ namespace llvm {
 inline constexpr llvm::StringRef ClangTrapPrefix = "__clang_trap_msg";
 
 namespace clang {
+  class BaseSubobject;
   class CodeGenOptions;
   class CoverageSourceInfo;
   class Decl;
@@ -105,6 +106,8 @@ class CodeGenerator : public ASTConsumer {
   ///   definition has been registered with this code generator.
   llvm::Constant *GetAddrOfGlobal(GlobalDecl decl, bool isForDefinition);
 
+  llvm::Constant *GetAddrOfVTable(BaseSubobject base, CXXRecordDecl *decl);
+
   /// Create a new \c llvm::Module after calling HandleTranslationUnit. This
   /// enable codegen in interactive processing environments.
   llvm::Module* StartModule(llvm::StringRef ModuleName, llvm::LLVMContext &C);
diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp 
b/clang/lib/CodeGen/ModuleBuilder.cpp
index 1888de4521abd..f91d9222e9232 100644
--- a/clang/lib/CodeGen/ModuleBuilder.cpp
+++ b/clang/lib/CodeGen/ModuleBuilder.cpp
@@ -11,6 +11,7 @@
 
//===----------------------------------------------------------------------===//
 
 #include "clang/CodeGen/ModuleBuilder.h"
+#include "CGCXXABI.h"
 #include "CGDebugInfo.h"
 #include "CodeGenModule.h"
 #include "clang/AST/ASTContext.h"
@@ -131,6 +132,11 @@ namespace {
       return Builder->GetAddrOfGlobal(global, 
ForDefinition_t(isForDefinition));
     }
 
+    llvm::Constant *GetAddrOfVTable(BaseSubobject subobject,
+                                    CXXRecordDecl *decl) {
+      return Builder->getCXXABI().getVTableAddressPoint(subobject, decl);
+    }
+
     llvm::Module *StartModule(llvm::StringRef ModuleName,
                               llvm::LLVMContext &C) {
       assert(!M && "Replacing existing Module?");
@@ -378,6 +384,11 @@ llvm::Constant *CodeGenerator::GetAddrOfGlobal(GlobalDecl 
global,
            ->GetAddrOfGlobal(global, isForDefinition);
 }
 
+llvm::Constant *CodeGenerator::GetAddrOfVTable(BaseSubobject base,
+                                               CXXRecordDecl *decl) {
+  return static_cast<CodeGeneratorImpl *>(this)->GetAddrOfVTable(base, decl);
+}
+
 llvm::Module *CodeGenerator::StartModule(llvm::StringRef ModuleName,
                                          llvm::LLVMContext &C) {
   return static_cast<CodeGeneratorImpl*>(this)->StartModule(ModuleName, C);
diff --git a/clang/unittests/CodeGen/CodeGenExternalTest.cpp 
b/clang/unittests/CodeGen/CodeGenExternalTest.cpp
index be3be147460f3..8ad1ead915328 100644
--- a/clang/unittests/CodeGen/CodeGenExternalTest.cpp
+++ b/clang/unittests/CodeGen/CodeGenExternalTest.cpp
@@ -10,6 +10,7 @@
 
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/BaseSubobject.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/TargetInfo.h"
@@ -21,6 +22,7 @@
 #include "clang/Sema/Sema.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Operator.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/TargetParser/Host.h"
@@ -163,7 +165,12 @@ bool MyASTConsumer::shouldSkipFunctionBody(Decl *D) {
 
 const char TestProgram[] =
     "struct mytest_struct { char x; short y; char p; long z; };\n"
-    "int mytest_fn(int x) { return x; }\n";
+    "int mytest_fn(int x) { return x; }\n"
+    "struct mytest_dynamic_struct {\n"
+    "  mytest_dynamic_struct();\n"
+    "  virtual void f1();\n"
+    "};\n"
+    "mytest_dynamic_struct::mytest_dynamic_struct() { }\n";
 
 // This function has the real test code here
 static void test_codegen_fns(MyASTConsumer *my) {
@@ -176,17 +183,19 @@ static void test_codegen_fns(MyASTConsumer *my) {
 
   for (auto decl : my->toplevel_decls ) {
     if (FunctionDecl *fd = dyn_cast<FunctionDecl>(decl)) {
-      if (fd->getName() == "mytest_fn") {
-        Constant *c = my->Builder->GetAddrOfGlobal(GlobalDecl(fd), false);
-        // Verify that we got a function.
-        ASSERT_TRUE(c != NULL);
-        if (DebugThisTest) {
-          c->print(dbgs(), true);
-          dbgs() << "\n";
+      if (fd->getDeclName().isIdentifier()) {
+        if (fd->getName() == "mytest_fn") {
+          Constant *c = my->Builder->GetAddrOfGlobal(GlobalDecl(fd), false);
+          // Verify that we got a function.
+          ASSERT_TRUE(c != NULL);
+          if (DebugThisTest) {
+            c->print(dbgs(), true);
+            dbgs() << "\n";
+          }
+          mytest_fn_ok = true;
         }
-        mytest_fn_ok = true;
       }
-    } else if(clang::RecordDecl *rd = dyn_cast<RecordDecl>(decl)) {
+    } else if(CXXRecordDecl *rd = dyn_cast<CXXRecordDecl>(decl)) {
       if (rd->getName() == "mytest_struct") {
         RecordDecl *def = rd->getDefinition();
         ASSERT_TRUE(def != NULL);
@@ -247,6 +256,24 @@ static void test_codegen_fns(MyASTConsumer *my) {
         ASSERT_GE(zTy->getPrimitiveSizeInBits(), 32u); // long is at least 32b
 
         mytest_struct_ok = true;
+      } else if (rd->getName() == "mytest_dynamic_struct") {
+        Constant *c = my->Builder->GetAddrOfVTable(
+            BaseSubobject(rd, CharUnits::fromQuantity(0)), rd);
+        ASSERT_NE(c, nullptr);
+        Value *vtableGlobal = c->getOperand(0);
+        ASSERT_NE(vtableGlobal, nullptr);
+        ASSERT_EQ(vtableGlobal->getName(), "_ZTV21mytest_dynamic_struct");
+        const DataLayout &dataLayout =
+            my->Builder->GetModule()->getDataLayout();
+        unsigned pointerSizeInBits =
+            dataLayout.getPointerTypeSizeInBits(c->getType());
+        APInt offset(pointerSizeInBits, 0);
+        GEPOperator* gepOperator = dyn_cast<GEPOperator>(c);
+        ASSERT_NE(gepOperator, nullptr);
+        gepOperator->accumulateConstantOffset(dataLayout, offset);
+        // Itanium ABI has a couple of pointersi (offset to top, type info)
+        // before the array of function pointers.
+        ASSERT_EQ(offset, (pointerSizeInBits / 8) * 2);
       }
     }
   }

>From 239c21617ff9eb4fa8f8b94c3d4e31d1063a45a1 Mon Sep 17 00:00:00 2001
From: David Blaikie <[email protected]>
Date: Wed, 10 Jun 2026 18:38:06 +0000
Subject: [PATCH 2/7] Formatting

---
 clang/include/clang/CodeGen/ModuleBuilder.h   | 20 +++++++++----------
 .../unittests/CodeGen/CodeGenExternalTest.cpp |  4 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/CodeGen/ModuleBuilder.h 
b/clang/include/clang/CodeGen/ModuleBuilder.h
index a144e904b0228..21dee80d60d65 100644
--- a/clang/include/clang/CodeGen/ModuleBuilder.h
+++ b/clang/include/clang/CodeGen/ModuleBuilder.h
@@ -32,16 +32,16 @@ namespace llvm {
 inline constexpr llvm::StringRef ClangTrapPrefix = "__clang_trap_msg";
 
 namespace clang {
-  class BaseSubobject;
-  class CodeGenOptions;
-  class CoverageSourceInfo;
-  class Decl;
-  class DiagnosticsEngine;
-  class GlobalDecl;
-  class HeaderSearchOptions;
-  class LangOptions;
-  class PreprocessorOptions;
-  class CompilerInstance;
+class BaseSubobject;
+class CodeGenOptions;
+class CoverageSourceInfo;
+class Decl;
+class DiagnosticsEngine;
+class GlobalDecl;
+class HeaderSearchOptions;
+class LangOptions;
+class PreprocessorOptions;
+class CompilerInstance;
 
 namespace CodeGen {
   class CodeGenModule;
diff --git a/clang/unittests/CodeGen/CodeGenExternalTest.cpp 
b/clang/unittests/CodeGen/CodeGenExternalTest.cpp
index 8ad1ead915328..dcb04f1f3237a 100644
--- a/clang/unittests/CodeGen/CodeGenExternalTest.cpp
+++ b/clang/unittests/CodeGen/CodeGenExternalTest.cpp
@@ -195,7 +195,7 @@ static void test_codegen_fns(MyASTConsumer *my) {
           mytest_fn_ok = true;
         }
       }
-    } else if(CXXRecordDecl *rd = dyn_cast<CXXRecordDecl>(decl)) {
+    } else if (CXXRecordDecl *rd = dyn_cast<CXXRecordDecl>(decl)) {
       if (rd->getName() == "mytest_struct") {
         RecordDecl *def = rd->getDefinition();
         ASSERT_TRUE(def != NULL);
@@ -268,7 +268,7 @@ static void test_codegen_fns(MyASTConsumer *my) {
         unsigned pointerSizeInBits =
             dataLayout.getPointerTypeSizeInBits(c->getType());
         APInt offset(pointerSizeInBits, 0);
-        GEPOperator* gepOperator = dyn_cast<GEPOperator>(c);
+        GEPOperator *gepOperator = dyn_cast<GEPOperator>(c);
         ASSERT_NE(gepOperator, nullptr);
         gepOperator->accumulateConstantOffset(dataLayout, offset);
         // Itanium ABI has a couple of pointersi (offset to top, type info)

>From f25541c777950df723f445a7d146cd6197044c61 Mon Sep 17 00:00:00 2001
From: David Blaikie <[email protected]>
Date: Wed, 10 Jun 2026 20:49:43 +0000
Subject: [PATCH 3/7] Typo

---
 clang/unittests/CodeGen/CodeGenExternalTest.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/unittests/CodeGen/CodeGenExternalTest.cpp 
b/clang/unittests/CodeGen/CodeGenExternalTest.cpp
index dcb04f1f3237a..8824451ccc2f4 100644
--- a/clang/unittests/CodeGen/CodeGenExternalTest.cpp
+++ b/clang/unittests/CodeGen/CodeGenExternalTest.cpp
@@ -271,7 +271,7 @@ static void test_codegen_fns(MyASTConsumer *my) {
         GEPOperator *gepOperator = dyn_cast<GEPOperator>(c);
         ASSERT_NE(gepOperator, nullptr);
         gepOperator->accumulateConstantOffset(dataLayout, offset);
-        // Itanium ABI has a couple of pointersi (offset to top, type info)
+        // Itanium ABI has a couple of pointers (offset to top, type info)
         // before the array of function pointers.
         ASSERT_EQ(offset, (pointerSizeInBits / 8) * 2);
       }

>From 2ee97ea8153e6f6227f473ba7b043af7d03da685 Mon Sep 17 00:00:00 2001
From: David Blaikie <[email protected]>
Date: Tue, 16 Jun 2026 22:04:17 +0000
Subject: [PATCH 4/7] make decl parameter const CXXRecordDecl*

---
 clang/include/clang/CodeGen/ModuleBuilder.h | 2 +-
 clang/lib/CodeGen/ModuleBuilder.cpp         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/include/clang/CodeGen/ModuleBuilder.h 
b/clang/include/clang/CodeGen/ModuleBuilder.h
index 21dee80d60d65..16bc7f2928303 100644
--- a/clang/include/clang/CodeGen/ModuleBuilder.h
+++ b/clang/include/clang/CodeGen/ModuleBuilder.h
@@ -106,7 +106,7 @@ class CodeGenerator : public ASTConsumer {
   ///   definition has been registered with this code generator.
   llvm::Constant *GetAddrOfGlobal(GlobalDecl decl, bool isForDefinition);
 
-  llvm::Constant *GetAddrOfVTable(BaseSubobject base, CXXRecordDecl *decl);
+  llvm::Constant *GetAddrOfVTable(BaseSubobject base, const CXXRecordDecl 
*decl);
 
   /// Create a new \c llvm::Module after calling HandleTranslationUnit. This
   /// enable codegen in interactive processing environments.
diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp 
b/clang/lib/CodeGen/ModuleBuilder.cpp
index f91d9222e9232..124783e36c6dc 100644
--- a/clang/lib/CodeGen/ModuleBuilder.cpp
+++ b/clang/lib/CodeGen/ModuleBuilder.cpp
@@ -133,7 +133,7 @@ namespace {
     }
 
     llvm::Constant *GetAddrOfVTable(BaseSubobject subobject,
-                                    CXXRecordDecl *decl) {
+                                    const CXXRecordDecl *decl) {
       return Builder->getCXXABI().getVTableAddressPoint(subobject, decl);
     }
 

>From 7fb3d794c46f883341003d11de81e29dc0870817 Mon Sep 17 00:00:00 2001
From: David Blaikie <[email protected]>
Date: Tue, 16 Jun 2026 22:07:19 +0000
Subject: [PATCH 5/7] Add comment

---
 clang/include/clang/CodeGen/ModuleBuilder.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/clang/include/clang/CodeGen/ModuleBuilder.h 
b/clang/include/clang/CodeGen/ModuleBuilder.h
index 16bc7f2928303..0815c9b9c734b 100644
--- a/clang/include/clang/CodeGen/ModuleBuilder.h
+++ b/clang/include/clang/CodeGen/ModuleBuilder.h
@@ -106,6 +106,10 @@ class CodeGenerator : public ASTConsumer {
   ///   definition has been registered with this code generator.
   llvm::Constant *GetAddrOfGlobal(GlobalDecl decl, bool isForDefinition);
 
+  /// Return the LLVM address of the vtable for the given base subobject.
+  ///
+  /// \param base The base subobject that owns the vptr to be initialized.
+  /// \param decl The derived type being initialized, that contains `base`.
   llvm::Constant *GetAddrOfVTable(BaseSubobject base, const CXXRecordDecl 
*decl);
 
   /// Create a new \c llvm::Module after calling HandleTranslationUnit. This

>From 1626ffa256c92b62e7aaab10925701740bb7dec2 Mon Sep 17 00:00:00 2001
From: David Blaikie <[email protected]>
Date: Tue, 16 Jun 2026 22:07:59 +0000
Subject: [PATCH 6/7] More const

---
 clang/lib/CodeGen/ModuleBuilder.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp 
b/clang/lib/CodeGen/ModuleBuilder.cpp
index 124783e36c6dc..0b00362487d2a 100644
--- a/clang/lib/CodeGen/ModuleBuilder.cpp
+++ b/clang/lib/CodeGen/ModuleBuilder.cpp
@@ -385,7 +385,7 @@ llvm::Constant *CodeGenerator::GetAddrOfGlobal(GlobalDecl 
global,
 }
 
 llvm::Constant *CodeGenerator::GetAddrOfVTable(BaseSubobject base,
-                                               CXXRecordDecl *decl) {
+                                               const CXXRecordDecl *decl) {
   return static_cast<CodeGeneratorImpl *>(this)->GetAddrOfVTable(base, decl);
 }
 

>From 446f407459eda2d4061a303241000b9ca012e89e Mon Sep 17 00:00:00 2001
From: David Blaikie <[email protected]>
Date: Wed, 17 Jun 2026 16:16:02 +0000
Subject: [PATCH 7/7] Format

---
 clang/include/clang/CodeGen/ModuleBuilder.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/CodeGen/ModuleBuilder.h 
b/clang/include/clang/CodeGen/ModuleBuilder.h
index 0815c9b9c734b..cd93ef7cc654a 100644
--- a/clang/include/clang/CodeGen/ModuleBuilder.h
+++ b/clang/include/clang/CodeGen/ModuleBuilder.h
@@ -110,7 +110,8 @@ class CodeGenerator : public ASTConsumer {
   ///
   /// \param base The base subobject that owns the vptr to be initialized.
   /// \param decl The derived type being initialized, that contains `base`.
-  llvm::Constant *GetAddrOfVTable(BaseSubobject base, const CXXRecordDecl 
*decl);
+  llvm::Constant *GetAddrOfVTable(BaseSubobject base,
+                                  const CXXRecordDecl *decl);
 
   /// Create a new \c llvm::Module after calling HandleTranslationUnit. This
   /// enable codegen in interactive processing environments.

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to