修正了一些错误

This commit is contained in:
2026-07-26 20:32:26 +08:00
parent ca7c2120b8
commit 1837339f69
203 changed files with 374300 additions and 2638 deletions

View File

@@ -5,7 +5,7 @@ import stdio
import viperlib
import memhub
from linkedlist import GSList, GSListNode
from .__types import LLVMType, TypePrint, Array, PrintStructDefinition, get_struct_name, Struct
from .__types import LLVMType, TypePrint, Array, PrintStructDefinition, get_struct_name, Struct, ParamNode
from .__function import Function, FunctionPrint, _ll_name_needs_quote, Param
@@ -150,39 +150,82 @@ def module_set_datalayout(mod: LLVMModule | t.CPtr, layout: t.CChar | t.CPtr):
# ============================================================
# 命名结构体类型管理
# ============================================================
# ============================================================
# _is_opaque_struct - 检查类型是否是 opaque 结构体
#
# opaque 结构体特征: Struct 类型,字段数为 0 且字段列表为 None。
# 通过 Struct(pool, None, 0, name) 创建IR 输出为 %"name" = type opaque。
# 用于在 module_add_named_type 中区分 opaque 声明和完整定义,
# 确保 opaque 声明插入链表头部(在使用之前声明)。
#
# Returns: 1=是 opaque / 0=否
# ============================================================
def _is_opaque_struct(ty: LLVMType | t.CPtr) -> int:
"""检查类型是否是 opaque 结构体(无字段的命名结构体)"""
if ty is None:
return 0
match ty:
case LLVMType.Struct(fields, fcount, name):
# opaque: 字段数为 0 且字段列表为 None
if fcount == 0 and fields is None:
return 1
return 0
case _:
return 0
def module_add_named_type(mod: LLVMModule | t.CPtr, pool: memhub.MemBuddy | t.CPtr,
ty: LLVMType | t.CPtr):
"""将命名结构体类型添加到模块(用于输出 %"name" = type { ... } 定义行)
非命名结构体Name 为 None 或非 Struct 类型)会被忽略。
按 Name 去重,相同名称的类型只保留第一个
按 Name 去重;同名时 opaque 声明可被完整定义替换(供跨模块值类型 alloca
"""
if mod is None or pool is None or ty is None:
return
name: t.CChar | t.CPtr = get_struct_name(ty)
if name is None:
return
# 去重检查
# 去重检查opaque 声明可被完整定义替换)
cur: NamedTypeNode | t.CPtr = mod.NamedTypeHead
while cur is not None:
if cur.Ty is not None:
existing_name: t.CChar | t.CPtr = get_struct_name(cur.Ty)
if existing_name is not None:
if string.strcmp(existing_name, name) == 0:
# 已有完整定义则无需替换
if _is_opaque_struct(cur.Ty) == 0:
return
# 已有 opaque新类型也是 opaque 则不重复
if _is_opaque_struct(ty) != 0:
return
# 用完整定义替换 opaque 声明(原地替换 Ty 指针)
cur.Ty = ty
return
cur = cur.Next
# 创建新节点并追加到链表尾部
# 创建新节点
node: NamedTypeNode | t.CPtr = pool.alloc(NAMED_TYPE_NODE_SIZE)
if node is None:
return
string.memset(node, 0, NAMED_TYPE_NODE_SIZE)
node.Ty = ty
node.Next = None
if mod.NamedTypeHead is None:
# opaque 类型插入链表头部,确保在引用它的完整定义之前声明。
# 例如 TypeRegistry{HashTable*, ...} 中HashTable 的 opaque 声明
# 必须在 TypeRegistry 定义之前,否则 llc 报 "use of undefined type"。
# 完整定义追加到链表尾部,保持原有顺序。
if _is_opaque_struct(ty) != 0:
node.Next = mod.NamedTypeHead
if mod.NamedTypeHead is None:
mod.NamedTypeTail = node
mod.NamedTypeHead = node
else:
mod.NamedTypeTail.Next = node
mod.NamedTypeTail = node
node.Next = None
if mod.NamedTypeHead is None:
mod.NamedTypeHead = node
else:
mod.NamedTypeTail.Next = node
mod.NamedTypeTail = node
mod.NamedTypeCount += 1
@@ -228,8 +271,24 @@ def _scan_type_for_cross_module_refs(pool: memhub.MemBuddy | t.CPtr,
opaque_ty: LLVMType | t.CPtr = Struct(pool, None, 0, sname)
if opaque_ty is not None:
module_add_named_type(mod, pool, opaque_ty)
# 递归扫描结构体字段中的跨模块引用
# 例如 TypeRegistry{HashTable*, MemManager*} 中的 HashTable 引用
if sfields is not None:
fld: ParamNode | t.CPtr = sfields
while fld is not None:
if fld.Ty is not None:
_scan_type_for_cross_module_refs(pool, mod, fld.Ty)
fld = fld.Next
case _:
_scan_type_for_cross_module_refs(pool, mod, pointee)
case LLVMType.Struct(sfields2, sfcount2, sname2):
# 顶层结构体(非指针):递归扫描字段
if sfields2 is not None:
fld2: ParamNode | t.CPtr = sfields2
while fld2 is not None:
if fld2.Ty is not None:
_scan_type_for_cross_module_refs(pool, mod, fld2.Ty)
fld2 = fld2.Next
case LLVMType.Array(elem_ty, acount):
if elem_ty is not None:
_scan_type_for_cross_module_refs(pool, mod, elem_ty)
@@ -333,12 +392,14 @@ def LLVMModulePrint(buf: t.CChar | t.CPtr, size: t.CSizeT,
param_scan = param_scan.Next
func_scan = func_scan.Next
nt: NamedTypeNode | t.CPtr = mod.NamedTypeHead
# 结构体定义缓冲区48 字段 × ~50 字节/字段类型名 ≈ 2400 字节4096 足够
# 在循环外分配一次并复用,减少 pool 碎片
ty_buf: t.CChar | t.CPtr = pool.alloc(4096)
while nt is not None:
if nt.Ty is not None:
ty_buf: t.CChar | t.CPtr = pool.alloc(256)
if ty_buf is not None:
ty_buf[0] = '\0'
PrintStructDefinition(ty_buf, 256, nt.Ty, pool)
PrintStructDefinition(ty_buf, 4096, nt.Ty, pool)
_append_cstr(buf, size, ty_buf)
_append_cstr(buf, size, "\n")
nt = nt.Next