[clang] [CIR] Implement lowering for LinkageSpecDecl (PR #137634)

via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 28 06:47:18 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clangir

Author: Erich Keane (erichkeane)

<details>
<summary>Changes</summary>

Like the NamespaceDecl, this is just emitted as a decl-context, where all its internal declarations get emitted for it. The incubator doesn't seem to have any good tests for this, so I wrote what I could think of as a half-decent test for this one, though the lowering doesn't manage whether these should be mangled, so the test is mostly just for spot-checking purposes.

I'm implementing this as it will make writing further tests for future features a little easier.

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


3 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenDecl.cpp (+1) 
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+2-1) 
- (added) clang/test/CIR/CodeGen/linkage-spec.cpp (+42) 


``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index 8026f22b00117..f16671cc3f522 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -260,6 +260,7 @@ void CIRGenFunction::emitExprAsInit(const Expr *init, const ValueDecl *d,
 
 void CIRGenFunction::emitDecl(const Decl &d) {
   switch (d.getKind()) {
+  case Decl::LinkageSpec:
   case Decl::Namespace:
     llvm_unreachable("Declaration should not be in declstmts!");
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 8aa57d1dbf9b3..8a493501392dc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -677,8 +677,9 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
     break;
 
   // C++ Decls
+  case Decl::LinkageSpec:
   case Decl::Namespace:
-    emitDeclContext(cast<NamespaceDecl>(decl));
+    emitDeclContext(Decl::castToDeclContext(decl));
     break;
   }
 }
diff --git a/clang/test/CIR/CodeGen/linkage-spec.cpp b/clang/test/CIR/CodeGen/linkage-spec.cpp
new file mode 100644
index 0000000000000..01c4e3fbe181d
--- /dev/null
+++ b/clang/test/CIR/CodeGen/linkage-spec.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - 2>&1 | FileCheck %s
+
+extern "C" void TopLevelC(){}
+// CHECK: cir.func @TopLevelC() {
+extern "C++" void TopLevelCpp(){}
+// CHECK: cir.func @_Z11TopLevelCppv() {
+
+extern "C++" {
+  void ExternCppEmpty(){}
+  // CHECK: cir.func @_Z14ExternCppEmptyv() {
+  extern "C" void ExternCpp_C(){}
+  // CHECK: cir.func @ExternCpp_C() {
+  extern "C++" void ExternCpp_Cpp(){}
+  // CHECK: cir.func @_Z13ExternCpp_Cppv() {
+
+  extern "C" {
+  void ExternCpp_CEmpty(){}
+  // CHECK: cir.func @ExternCpp_CEmpty() {
+  extern "C" void ExternCpp_C_C(){}
+  // CHECK: cir.func @ExternCpp_C_C() {
+  extern "C++" void ExternCpp_C_Cpp(){}
+  // CHECK: cir.func @_Z15ExternCpp_C_Cppv() {
+  }
+}
+
+extern "C" {
+  void ExternCEmpty(){}
+  // CHECK: cir.func @ExternCEmpty() {
+  extern "C" void ExternC_C(){}
+  // CHECK: cir.func @ExternC_C() {
+  extern "C++" void ExternC_Cpp(){}
+  // CHECK: cir.func @_Z11ExternC_Cppv() {
+  extern "C++" {
+  void ExternC_CppEmpty(){}
+  // CHECK: cir.func @_Z16ExternC_CppEmptyv() {
+  extern "C" void ExternC_Cpp_C(){}
+  // CHECK: cir.func @ExternC_Cpp_C() {
+  extern "C++" void ExternC_Cpp_Cpp(){}
+  // CHECK: cir.func @_Z15ExternC_Cpp_Cppv() {
+  }
+}
+

``````````

</details>


https://github.com/llvm/llvm-project/pull/137634


More information about the cfe-commits mailing list