chore(stubmerger): 删除 StubMergerIR 中 6 个无调用方的旧 IR 文本扫描助手
删除 _IsFuncDeclaredOrDefined / _CommentOutDeclareInBuf / _CommentOutGlobalInBuf / _HasGlobalInBuf / _CommentOutOpaqueTypeInBuf / _HasFullTypeDefinition —— 全仓无调用方 (去重判定早已迁移到 StubMergerBuild 的 _seen_* 哈希表),保留在用中的 _is_submodule_of_imported。顺带更新本模块头注释(现为 meta sidecar 工具)。 去 IR 化收尾清理;未编译验证。
This commit is contained in:
1 parent
611f49cfb6
commit
3b0ed04e70
1 file changed
+1
-190
@@ -27,7 +27,7 @@ import lib.Stub.StubMerger as StubMerger
|
||||
|
||||
|
||||
# ============================================================
|
||||
# StubMergerIR - IR 文本去重/注释与模块名-SHA1 映射工具
|
||||
# StubMergerIR - 模块结构化 sidecar({sha1}.meta)写出/读取、子模块判定与模块名-SHA1 映射工具
|
||||
# ============================================================
|
||||
|
||||
# ============================================================
|
||||
@@ -205,154 +205,6 @@ def IsDeclOnlyModule(temp_dir: str, td_len: sizet, sha1: str) -> int:
|
||||
return 0
|
||||
return 1
|
||||
# ============================================================
|
||||
# _IsFuncDeclaredOrDefined - 检查 out_buf 中是否已有函数的 declare/define
|
||||
#
|
||||
# 逐字节 strncmp 搜索 func_sig(如 @"sha1.func"(/ @printf(),命中后检查行首是否为 "declare "/"define ",跳过 call 语句
|
||||
# (避免 strstr 子串匹配误命中 call ... @"func"(...)。
|
||||
#
|
||||
# Args: out_buf 已有 IR 文本缓冲区;func_sig 函数签名片段,如 @"sha1.func"(/ @printf(
|
||||
# Returns: 1=已存在 declare/define, 0=不存在
|
||||
# ============================================================
|
||||
def _IsFuncDeclaredOrDefined(out_buf: bytes, func_sig: str) -> int:
|
||||
"""检查 out_buf 中是否已有函数的 declare 或 define 行"""
|
||||
if out_buf is None or func_sig is None:
|
||||
return 0
|
||||
sig_len: sizet = string.strlen(func_sig)
|
||||
out_len: sizet = string.strlen(out_buf)
|
||||
if sig_len == 0 or out_len == 0 or sig_len > out_len:
|
||||
return 0
|
||||
pos: sizet = 0
|
||||
for pos in range(0, out_len - sig_len + 1):
|
||||
if string.strncmp(out_buf + pos, func_sig, sig_len) == 0:
|
||||
ls: sizet = pos
|
||||
while ls > 0 and out_buf[ls - 1] != '\n':
|
||||
ls -= 1
|
||||
if string.strncmp(out_buf + ls, "declare ", 8) == 0:
|
||||
return 1
|
||||
if string.strncmp(out_buf + ls, "define ", 7) == 0:
|
||||
return 1
|
||||
return 0
|
||||
# ============================================================
|
||||
# _CommentOutDeclareInBuf - 将 out_buf 中匹配 func_sig 的 declare 行注释掉
|
||||
#
|
||||
# 用于解决 declare/define 冲突:当本地 text.ll 包含 define 而依赖
|
||||
# text.ll 已生成了同函数的 declare 时,将 declare 行首字符改为 ';'
|
||||
# 使其成为注释,然后追加 define 行。
|
||||
# ============================================================
|
||||
def _CommentOutDeclareInBuf(out_buf: bytes, func_sig: str) -> int:
|
||||
"""在 out_buf 中搜索 declare 行(包含 func_sig),将其注释掉"""
|
||||
if out_buf is None or func_sig is None:
|
||||
return 0
|
||||
sig_len: sizet = string.strlen(func_sig)
|
||||
out_len: sizet = string.strlen(out_buf)
|
||||
if sig_len == 0 or out_len == 0 or sig_len > out_len:
|
||||
return 0
|
||||
pos: sizet = 0
|
||||
while pos + sig_len <= out_len:
|
||||
if string.strncmp(out_buf + pos, func_sig, sig_len) == 0:
|
||||
ls: sizet = pos
|
||||
while ls > 0 and out_buf[ls - 1] != '\n':
|
||||
ls -= 1
|
||||
if string.strncmp(out_buf + ls, "declare ", 8) == 0:
|
||||
out_buf[ls] = ';'
|
||||
return 1
|
||||
pos += 1
|
||||
return 0
|
||||
# ============================================================
|
||||
# _CommentOutGlobalInBuf - 将 out_buf 中匹配全局变量名的行注释掉
|
||||
#
|
||||
# 解决 stub/text 全局变量重复定义问题:stub 中可能是 external 声明
|
||||
# 或完整定义,以 text 中的定义为准,将 stub 中的同名行注释掉。
|
||||
# ============================================================
|
||||
def _CommentOutGlobalInBuf(out_buf: bytes, global_name: str) -> int:
|
||||
"""在 out_buf 中搜索全局变量定义行(以 global_name 开头),将行首改为 ';'
|
||||
|
||||
注释掉**所有**匹配行(而非仅第一个):跨模块同名裸全局(如 main.vp 与
|
||||
argparse.vp 都声明 StubMerger._mbuddy)时,本地 stub external + 依赖 stub external +
|
||||
依赖 text 定义会同时存在。只注释第一个会导致依赖 text 的定义残留 →
|
||||
合成 IR 重复定义 → llc "redefinition of global '@StubMerger._mbuddy'"(ArgparseTest
|
||||
回归根因)。"以 text 中定义为准"的语义:后追加者注释掉全部旧行,最终
|
||||
只保留最后一个定义。
|
||||
"""
|
||||
if out_buf is None or global_name is None:
|
||||
return 0
|
||||
name_len: sizet = string.strlen(global_name)
|
||||
out_len: sizet = string.strlen(out_buf)
|
||||
if name_len == 0 or out_len == 0 or name_len > out_len:
|
||||
return 0
|
||||
pos: sizet = 0
|
||||
commented: int = 0
|
||||
while pos + name_len <= out_len:
|
||||
if string.strncmp(out_buf + pos, global_name, name_len) == 0:
|
||||
# 确认是行首(前一个是换行或 pos==0)
|
||||
if pos == 0 or out_buf[pos - 1] == '\n':
|
||||
out_buf[pos] = ';'
|
||||
commented = 1
|
||||
pos += 1
|
||||
return commented
|
||||
def _HasGlobalInBuf(out_buf: bytes, global_name: str) -> int:
|
||||
"""检测 out_buf 中是否已有同名全局变量行(行首匹配,未注释)
|
||||
|
||||
用于跳过重复追加依赖全局强定义:stub 注入已提供 external 声明,
|
||||
依赖 text.ll 的强定义只需在定义模块存在一份,复制进每个依赖方
|
||||
会导致 ld.lld duplicate symbol(如 _op_head、MemBuddy.vtable)。
|
||||
"""
|
||||
if out_buf is None or global_name is None:
|
||||
return 0
|
||||
name_len: sizet = string.strlen(global_name)
|
||||
out_len: sizet = string.strlen(out_buf)
|
||||
if name_len == 0 or out_len == 0 or name_len > out_len:
|
||||
return 0
|
||||
pos: sizet = 0
|
||||
while pos + name_len <= out_len:
|
||||
if string.strncmp(out_buf + pos, global_name, name_len) == 0:
|
||||
# 确认是行首(前一个是换行或 pos==0)
|
||||
if pos == 0 or out_buf[pos - 1] == '\n':
|
||||
return 1
|
||||
pos += 1
|
||||
return 0
|
||||
# ============================================================
|
||||
# _CommentOutOpaqueTypeInBuf - 将 out_buf 中匹配类型名的 opaque 声明行注释掉
|
||||
#
|
||||
# 解决跨模块类型定义冲突:本地 stub 可能包含自动生成的 opaque 声明
|
||||
#(如 %"sha1.Widget" = type opaque),而依赖 stub 包含完整定义
|
||||
#(如 %"sha1.Widget" = type { i8*, i32 })。去重时需要将 opaque 声明
|
||||
# 注释掉,让完整定义被追加,否则 LLC 报错 "Cannot allocate unsized type"。
|
||||
# ============================================================
|
||||
def _CommentOutOpaqueTypeInBuf(out_buf: bytes, type_name_prefix: str) -> int:
|
||||
"""在 out_buf 中搜索 type_name_prefix 对应的 opaque 声明行,将行首改为 ';'
|
||||
|
||||
type_name_prefix 格式: '%"sha1.ClassName"'(不含 '=' 和后续内容)
|
||||
返回 1=已注释, 0=未找到
|
||||
"""
|
||||
if out_buf is None or type_name_prefix is None:
|
||||
return 0
|
||||
prefix_len: sizet = string.strlen(type_name_prefix)
|
||||
out_len: sizet = string.strlen(out_buf)
|
||||
if prefix_len == 0 or out_len == 0 or prefix_len > out_len:
|
||||
return 0
|
||||
pos: sizet = 0
|
||||
while pos + prefix_len <= out_len:
|
||||
if string.strncmp(out_buf + pos, type_name_prefix, prefix_len) == 0:
|
||||
# 确认是行首(前一个是换行或 pos==0)
|
||||
if pos == 0 or out_buf[pos - 1] == '\n':
|
||||
# 检查后面是否是 " = type opaque"
|
||||
p: sizet = pos + prefix_len
|
||||
# 跳过空格
|
||||
while p < out_len and out_buf[p] == ' ':
|
||||
p += 1
|
||||
if p < out_len and out_buf[p] == '=':
|
||||
p += 1
|
||||
while p < out_len and out_buf[p] == ' ':
|
||||
p += 1
|
||||
if p + 11 <= out_len:
|
||||
if string.strncmp(out_buf + p, "type opaque", 11) == 0:
|
||||
# 找到 opaque 声明,将行首改为 ';'
|
||||
out_buf[pos] = ';'
|
||||
return 1
|
||||
pos += 1
|
||||
return 0
|
||||
# ============================================================
|
||||
# _is_submodule_of_imported - 检查模块名是否是已导入包的子模块
|
||||
#
|
||||
# deps_buf 只记录直接导入的模块名(如 "ast"),但包的 __init__.vp 内部 from .lexer import Lexer 会让 IR 引用 ast.lexer
|
||||
@@ -377,47 +229,6 @@ def _is_submodule_of_imported(deps_buf: str, mod_name: str) -> int:
|
||||
mod_name[pkg_len] = saved_ch
|
||||
return result
|
||||
# ============================================================
|
||||
# _HasFullTypeDefinition - 检查 out_buf 中是否已有完整类型定义(非 opaque)
|
||||
#
|
||||
# type_name_prefix 格式: '%"sha1.ClassName"'(不含 '=')
|
||||
# 完整定义: %"name" = type { ... } 或 %"name" = type < { ... } >
|
||||
# 返回 1=已有完整定义, 0=无完整定义
|
||||
# ============================================================
|
||||
def _HasFullTypeDefinition(out_buf: bytes, type_name_prefix: str) -> int:
|
||||
"""检查 out_buf 中是否已有 type_name_prefix 的完整定义"""
|
||||
if out_buf is None or type_name_prefix is None:
|
||||
return 0
|
||||
prefix_len: sizet = string.strlen(type_name_prefix)
|
||||
out_len: sizet = string.strlen(out_buf)
|
||||
if prefix_len == 0 or out_len == 0 or prefix_len > out_len:
|
||||
return 0
|
||||
pos: sizet = 0
|
||||
while pos + prefix_len <= out_len:
|
||||
if string.strncmp(out_buf + pos, type_name_prefix, prefix_len) == 0:
|
||||
# 确认是行首(前一个是换行或 pos==0),且未被注释(行首不是 ';')
|
||||
is_line_start: int = 0
|
||||
if pos == 0:
|
||||
is_line_start = 1
|
||||
elif out_buf[pos - 1] == '\n':
|
||||
is_line_start = 1
|
||||
if is_line_start == 1:
|
||||
# 检查后面是否是 " = type {" 或 " = type <"
|
||||
p: sizet = pos + prefix_len
|
||||
while p < out_len and out_buf[p] == ' ':
|
||||
p += 1
|
||||
if p < out_len and out_buf[p] == '=':
|
||||
p += 1
|
||||
while p < out_len and out_buf[p] == ' ':
|
||||
p += 1
|
||||
if p + 5 < out_len:
|
||||
if string.strncmp(out_buf + p, "type ", 5) == 0:
|
||||
p += 5
|
||||
if p < out_len:
|
||||
if out_buf[p] == '{' or out_buf[p] == '<':
|
||||
return 1
|
||||
pos += 1
|
||||
return 0
|
||||
# ============================================================
|
||||
# _BuildIncludesSha1Map - 从全局内存存储器构建 sha1 → module_name 映射
|
||||
#
|
||||
# 数据来源是 PopulateSha1MapStore 填充的全局存储器(不读取 _sha1_map.txt)。
|
||||
|
||||
Reference in new issue
Block a user