[clang] [CIR] Implement NYI: function declaration that forces code gen (PR #194663)

Zaky Hermawan via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 28 09:06:25 PDT 2026


https://github.com/ZakyHermawan updated https://github.com/llvm/llvm-project/pull/194663

>From a05413586dc4d19eb8f5d9037c08faaca1bf9c25 Mon Sep 17 00:00:00 2001
From: ZakyHermawan <zaky.hermawan9615 at gmail.com>
Date: Tue, 28 Apr 2026 22:51:41 +0700
Subject: [PATCH 1/2] [CIR] Fix NYI: forcecd externally visible def

Signed-off-by: ZakyHermawan <zaky.hermawan9615 at gmail.com>
---
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        | 20 +++++++++++++++++--
 .../CodeGen/force-externally-visibile-def.c   | 12 +++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/force-externally-visibile-def.c

diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 7d719600a6025..230f20971f7c5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -517,12 +517,20 @@ void CIRGenModule::emitGlobal(clang::GlobalDecl gd) {
       if (getGlobalValue(mangledName))
         deferredAnnotations[mangledName] = fd;
     }
+
+    // Forward declarations are emitted lazily on first use.
     if (!fd->doesThisDeclarationHaveABody()) {
       if (!fd->doesDeclarationForceExternallyVisibleDefinition())
         return;
 
-      errorNYI(fd->getSourceRange(),
-               "function declaration that forces code gen");
+      StringRef mangledName = getMangledName(gd);
+
+      // Compute the function info and CIR func type.
+      const CIRGenFunctionInfo &fi = getTypes().arrangeGlobalDeclaration(gd);
+      cir::FuncType ty = getTypes().getFunctionType(fi);
+
+      getOrCreateCIRFunction(mangledName, ty, gd, /*ForVTable=*/false,
+                              /*DontDefer=*/false);
       return;
     }
   } else {
@@ -2716,7 +2724,15 @@ void CIRGenModule::setFunctionAttributes(GlobalDecl globalDecl,
   // represent them in dedicated ops. The correct attributes are ensured during
   // translation to LLVM. Thus, we don't need to check for them here.
 
+  // If this function has a body somewhere in the AST, we must use that
+  // definition for attributes and linkage calculation. This prevents AST 
+  // assertions when forcing inline definitions from forward declarations.
   const auto *funcDecl = cast<FunctionDecl>(globalDecl.getDecl());
+  const FunctionDecl *fdDef;
+  if (funcDecl->hasBody(fdDef)) {
+    funcDecl = fdDef;
+    globalDecl = globalDecl.getWithDecl(fdDef);
+  }
 
   if (!isIncompleteFunction)
     setCIRFunctionAttributes(globalDecl,
diff --git a/clang/test/CIR/CodeGen/force-externally-visibile-def.c b/clang/test/CIR/CodeGen/force-externally-visibile-def.c
new file mode 100644
index 0000000000000..133e49211b8ff
--- /dev/null
+++ b/clang/test/CIR/CodeGen/force-externally-visibile-def.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fclangir -emit-cir -std=c99 %s -o - | FileCheck %s
+
+inline void my_func() {}
+
+// Force the externally visible definition
+extern inline void my_func();
+
+// CHECK: module {{.*}} attributes {cir.lang = #cir.lang<c>{{.*}} {
+// CHECK-NEXT:   cir.func no_inline no_proto @my_func() attributes {nothrow} {
+// CHECK-NEXT:     cir.return
+// CHECK-NEXT:   }
+// CHECK-NEXT: }

>From b18682c88ce6a6273283157fdfbb92e6112f454b Mon Sep 17 00:00:00 2001
From: ZakyHermawan <zaky.hermawan9615 at gmail.com>
Date: Tue, 28 Apr 2026 23:05:59 +0700
Subject: [PATCH 2/2] fix clang-format error

Signed-off-by: ZakyHermawan <zaky.hermawan9615 at gmail.com>
---
 clang/lib/CIR/CodeGen/CIRGenModule.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 230f20971f7c5..d746d87ca7258 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -530,7 +530,7 @@ void CIRGenModule::emitGlobal(clang::GlobalDecl gd) {
       cir::FuncType ty = getTypes().getFunctionType(fi);
 
       getOrCreateCIRFunction(mangledName, ty, gd, /*ForVTable=*/false,
-                              /*DontDefer=*/false);
+                             /*DontDefer=*/false);
       return;
     }
   } else {
@@ -2725,7 +2725,7 @@ void CIRGenModule::setFunctionAttributes(GlobalDecl globalDecl,
   // translation to LLVM. Thus, we don't need to check for them here.
 
   // If this function has a body somewhere in the AST, we must use that
-  // definition for attributes and linkage calculation. This prevents AST 
+  // definition for attributes and linkage calculation. This prevents AST
   // assertions when forcing inline definitions from forward declarations.
   const auto *funcDecl = cast<FunctionDecl>(globalDecl.getDecl());
   const FunctionDecl *fdDef;



More information about the cfe-commits mailing list