修正了一些错误

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

@@ -36,6 +36,7 @@ class VarEntry:
Alloca: llvmlite.Value | t.CPtr
Used: t.CInt
AnnotClassName: t.CChar | t.CPtr # 原始类型注解的类名str 别名在结构体字段中触发编译器 bug改用显式联合类型
IsPtrElement: t.CInt # 标志: 1=注解为 bytes|t.CPtr 或 str|t.CPtr, 下标按 8 字节步长
# ============================================================
@@ -154,6 +155,25 @@ def set_var_annot_class_name(symtab: SymbolTable | t.CPtr,
return 0
# ============================================================
# set_var_ptr_element — 标记变量为"指针到 str/bytes"类型
#
# 注解为 bytes|t.CPtr 或 str|t.CPtr 的变量,其 alloca 类型是 i8*
# 但下标访问应按 8 字节步长i8** 语义),而非 1 字节步长i8* 语义)。
# 此标志在 HandlesAnnAssign 中根据注解形式设置。
# ============================================================
def set_var_ptr_element(symtab: SymbolTable | t.CPtr,
name: str) -> int:
"""标记变量为 ptr_element 类型,返回 0=成功 / 1=失败"""
if symtab is None or name is None:
return 1
entry: VarEntry | t.CPtr = lookup_var_entry(symtab, name)
if entry is None:
return 1
entry.IsPtrElement = 1
return 0
# ============================================================
# add_var — 添加变量到变量表
# ============================================================
@@ -175,6 +195,27 @@ def add_var(vars_ptr: VarEntry | t.CPtr,
return 0
# ============================================================
# _alloca_at_entry - 在函数入口块生成 alloca确保支配性
#
# LLVM IR 要求指令支配所有使用点。如果 alloca 在条件分支内生成,
# 但在其他分支使用会违反支配性Instruction does not dominate all uses
# 标准做法:所有 alloca 在函数入口块生成。
#
# 临时切换 builder.CurBlock 到入口块,生成 alloca然后恢复。
# ============================================================
def _alloca_at_entry(builder: llvmlite.IRBuilder | t.CPtr,
ty: llvmlite.LLVMType | t.CPtr) -> llvmlite.Value | t.CPtr:
"""在函数入口块生成 alloca返回 alloca 值
使用 llvmlite.build_alloca_at_entry 在入口块终止指令之前插入 alloca
确保所有 alloca 在入口块,避免支配性违规。
"""
if builder is None or ty is None:
return None
return llvmlite.build_alloca_at_entry(builder, ty)
# ============================================================
# get_or_create_var — 查找或创建变量 alloca旧版兼容
# ============================================================
@@ -188,7 +229,7 @@ def get_or_create_var(pool: memhub.MemBuddy | t.CPtr,
existing: llvmlite.Value | t.CPtr = find_var(vars_ptr, var_count, name)
if existing is not None:
return existing
alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(builder, ty)
alloca: llvmlite.Value | t.CPtr = _alloca_at_entry(builder, ty)
if alloca is None:
return None
if add_var(vars_ptr, var_count, name, alloca) != 0:
@@ -358,7 +399,7 @@ def get_or_create_sym(symtab: SymbolTable | t.CPtr,
existing: llvmlite.Value | t.CPtr = lookup_current(symtab, name)
if existing is not None:
return existing
alloca: llvmlite.Value | t.CPtr = llvmlite.build_alloca(builder, ty)
alloca: llvmlite.Value | t.CPtr = _alloca_at_entry(builder, ty)
if alloca is None:
return None
define_var(symtab, name, alloca)