fix(stubmerger): define→declare 降级时剥掉行尾函数级元数据附加(!dbg !N)

llc 对 declare 不接受元数据附加,报 expected = here(实证 LLvmLiteTest 949685246c8e241c.ll:898:104 的 declare ... !dbg !71)

根因:降级只删尾部 ' {',源 define 头行的 ' !dbg !71' 被原样抄下;declare 无函数体,!dbg 无意义(FunctionPrint 对 declare 从不打印 !dbg)

判据:参数表之后、括号深度 0、不在双引号内的 ' !';连同前导空白一起截断
This commit is contained in:
TermiNexus committed 2026-09-27 18:30:39 +08:00
1 parent 66e697e8df
commit 31898ab4a5
1 file changed
+37
@@ -549,6 +549,43 @@ def _LoadAndAppendTextDeclares(temp_dir: str, td_len: sizet, dep_sha1: str,
if dep_buf[decl_end - 1] == '{' and dep_buf[decl_end - 2] == ' ':
decl_end -= 2
# 剥掉行尾的**函数级元数据附加**(`!dbg !71`;可多组如 `!dbg !71 !prof !72`)。
# declare **不接受**函数级元数据附加:llc 直接报 "expected '='"(实证
# LLvmLiteTest 合并产物 949685246c8e241c.ll:898:104 —
# `declare void @"…GSList[Param].__init__"(…) !dbg !71`)。这条残留正是
# "文本降级 define→declare"自身带出来的:源 define 头行形如
# `define linkonce_odr void @"…"(…) !dbg !71 {`,上面只删掉了尾部 `" {"`,
# 其后的 ` !dbg !71` 被原样抄下。declare 无函数体,!dbg 本就无意义
# (FunctionPrint 对 declare 从不打印 !dbg,见 llvmlite/__function.vp 的
# IsDeclared==1 提前返回分支),故在此直接截断。
# 判据:参数表之后、括号深度 0、且不在双引号内的 ` !`(元数据附加恒在行尾,
# 裸标识符不允许含 '!',唯一可能含 '!' 的是带引号的符号名 → 用引号态排除)。
meta_pos_lt: sizet = ls
meta_depth_lt: int = 0
meta_in_str_lt: int = 0
meta_cut_lt: sizet = 0
while meta_pos_lt < decl_end:
meta_ch_lt: int = dep_buf[meta_pos_lt]
if meta_ch_lt == '"':
meta_in_str_lt = 1 - meta_in_str_lt
elif meta_in_str_lt == 0:
if meta_ch_lt == '(' or meta_ch_lt == '[' or meta_ch_lt == '{':
meta_depth_lt += 1
elif meta_ch_lt == ')' or meta_ch_lt == ']' or meta_ch_lt == '}':
if meta_depth_lt > 0:
meta_depth_lt -= 1
elif meta_ch_lt == '!' and meta_depth_lt == 0 and meta_pos_lt > ls \
and dep_buf[meta_pos_lt - 1] <= ' ':
meta_cut_lt = meta_pos_lt
break
meta_pos_lt += 1
if meta_cut_lt != 0:
# 连同前导空白一起截掉,避免残留行尾空白
# (`<= ' '` 同时覆盖空格与制表符,且不会误吃 ')' 等非空白字符)
while meta_cut_lt > ls and dep_buf[meta_cut_lt - 1] <= ' ':
meta_cut_lt -= 1
decl_end = meta_cut_lt
# 输出: declare + content(跳过 "define " 及其后所有 linkage 词,至多到 decl_end)。
# 泛型特化方法 define 名为 "define linkonce_odr ..."(名含 '['):只跳 "define " 会拼出 "declare linkonce_odr ..." →
# llc 报 "invalid linkage for function declaration"(declare 只能 external),故循环剥掉全部 linkage 词。