Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[CIR] Handle explicit instantiation declaration in getVTableLinkage#193809

Open
AbdallahRashed wants to merge 1 commit intollvm:mainfrom
AbdallahRashed:cir-explicit-instanstiation-dec-linkage
Open

[CIR] Handle explicit instantiation declaration in getVTableLinkage#193809
AbdallahRashed wants to merge 1 commit intollvm:mainfrom
AbdallahRashed:cir-explicit-instanstiation-dec-linkage

Conversation

@AbdallahRashed
Copy link
Copy Markdown
Contributor

Replace errorNYI for TSK_ExplicitInstantiationDeclaration with the correct linkage logic: use discardable ODR linkage for MSVC, and for Itanium choose between AvailableExternallyLinkage (when the vtable can be speculatively emitted) or ExternalLinkage.

Fixes point 3 of #192330.

Replace errorNYI for TSK_ExplicitInstantiationDeclaration with the
correct linkage logic: use discardable ODR linkage for MSVC, and
for Itanium choose between AvailableExternallyLinkage (when the
vtable can be speculatively emitted) or ExternalLinkage.

Fixes point 3 of llvm#192330.
@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Apr 23, 2026
@llvmbot
Copy link
Copy Markdown
Member

llvmbot commented Apr 23, 2026

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clangir

Author: AbdallahRashed (AbdallahRashed)

Changes

Replace errorNYI for TSK_ExplicitInstantiationDeclaration with the correct linkage logic: use discardable ODR linkage for MSVC, and for Itanium choose between AvailableExternallyLinkage (when the vtable can be speculatively emitted) or ExternalLinkage.

Fixes point 3 of #192330.


Full diff: https://github.com/llvm/llvm-project/pull/193809.diff

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenVTables.cpp (+11-5)
  • (added) clang/test/CIR/CodeGen/vtable-linkage-explicit-instantiation.cpp (+27)
diff --git a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp
index 6e1a80926f679..ca83d7a355408 100644
--- a/clang/lib/CIR/CodeGen/CIRGenVTables.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenVTables.cpp
@@ -326,6 +326,9 @@ cir::GlobalOp CIRGenVTables::generateConstructionVTable(
   return vtable;
 }
 
+static bool shouldEmitAvailableExternallyVTable(const CIRGenModule &cgm,
+                                                const CXXRecordDecl *rd);
+
 /// Compute the required linkage of the vtable for the given class.
 ///
 /// Note that we only call this at the end of the translation unit.
@@ -395,11 +398,14 @@ cir::GlobalLinkageKind CIRGenModule::getVTableLinkage(const CXXRecordDecl *rd) {
   case TSK_ImplicitInstantiation:
     return discardableODRLinkage;
 
-  case TSK_ExplicitInstantiationDeclaration: {
-    errorNYI(rd->getSourceRange(),
-             "getVTableLinkage: explicit instantiation declaration");
-    return cir::GlobalLinkageKind::ExternalLinkage;
-  }
+  case TSK_ExplicitInstantiationDeclaration:
+    // Explicit instantiations in MSVC do not provide vtables, so we must emit
+    // our own.
+    if (getTarget().getCXXABI().isMicrosoft())
+      return discardableODRLinkage;
+    return shouldEmitAvailableExternallyVTable(*this, rd)
+               ? cir::GlobalLinkageKind::AvailableExternallyLinkage
+               : cir::GlobalLinkageKind::ExternalLinkage;
 
   case TSK_ExplicitInstantiationDefinition:
     return nonDiscardableODRLinkage;
diff --git a/clang/test/CIR/CodeGen/vtable-linkage-explicit-instantiation.cpp b/clang/test/CIR/CodeGen/vtable-linkage-explicit-instantiation.cpp
new file mode 100644
index 0000000000000..6fc4cc4d51fbf
--- /dev/null
+++ b/clang/test/CIR/CodeGen/vtable-linkage-explicit-instantiation.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+
+// Test that explicit instantiation declarations don't trigger
+// "getVTableLinkage: explicit instantiation declaration" errorNYI.
+
+template <typename T>
+struct Base {
+  virtual ~Base() {}
+  virtual void foo() {}
+  T val;
+};
+
+extern template class Base<int>;
+
+void use(Base<int> *p) {
+  p->foo();
+}
+
+// Verify the virtual call goes through the vtable.
+// CHECK: cir.func {{.*}} @_Z3useP4BaseIiE
+// CHECK:   cir.vtable.get_vptr
+// CHECK:   cir.vtable.get_virtual_fn_addr
+
+// LLVM: define {{.*}} @_Z3useP4BaseIiE

"getVTableLinkage: explicit instantiation declaration");
return cir::GlobalLinkageKind::ExternalLinkage;
}
case TSK_ExplicitInstantiationDeclaration:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The llvm_unreachable on line 375 relates to this same kind. It shouldn't be unreachable. That isn't implemented in the incubator, but it is in classic codegen (doing basically what you have here). Can you add that in this PR also. It will require an additional test case to reach that code.

// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s

// Test that explicit instantiation declarations don't trigger
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment isn't useful. I'd delete it.

@@ -0,0 +1,27 @@
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add RUN lines to compile without -fclangir? This is useful for verifying that we do the same thing as classic codegen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants