fix(assign): 类型变量赋值限定链根为模块
f19d2578 退役 t/c 模块时移除了 IsTModule 检查,任意 x = y.attr 都被当作类型变量赋值:只发射 __x_fmt/__x_kind 两个 store 就 return,真实赋值丢失。includes/json 链表遍历 cur = cur.next 因此不前进,viperc.exe 运行卡在 Load_project_config。恢复判据:链根必须是 import 模块,且属性名是已知类型名。
This commit is contained in:
1 parent
103cd4ff26
commit
077d705609
1 file changed
+52
-29
@@ -65,36 +65,59 @@ class AssignHandle(BaseHandle):
|
||||
sys.exit(1)
|
||||
if isinstance(Node.value, ast.Attribute) and isinstance(Node.value.value, ast.Name) :
|
||||
AttrName: str = Node.value.attr
|
||||
Gen.var_type_info[VarName] = {'type': 't_type', 'name': AttrName}
|
||||
Gen.var_type_assignments.setdefault(VarName, []).append({'type': 't_type', 'name': AttrName})
|
||||
c_type_name: str = ''
|
||||
resolved: tuple[type, int] | None = CTypeRegistry.ResolveName(AttrName)
|
||||
if resolved is not None:
|
||||
ctype_cls: type = resolved[0]
|
||||
ptr_level: int = resolved[1]
|
||||
c_type_name = CTypeRegistry.CTypeToName(ctype_cls)
|
||||
if ptr_level > 0 and c_type_name:
|
||||
c_type_name = c_type_name + ' *'
|
||||
if not c_type_name:
|
||||
if AttrName == 'CPtr':
|
||||
c_type_name = 'void *'
|
||||
is_unsigned: bool = Gen._is_type_unsigned(c_type_name) if c_type_name else False
|
||||
fmt_str: str = "%u\n" if is_unsigned else "%d\n"
|
||||
fmt_ptr: ir.Value = Gen._create_string_global(fmt_str)
|
||||
fmt_var_name: str = f"__{VarName}_fmt"
|
||||
if fmt_var_name not in Gen.variables:
|
||||
fmt_alloca: ir.AllocaInstr = Gen._allocaEntry(ir.PointerType(ir.IntType(8)), name=fmt_var_name)
|
||||
Gen.variables[fmt_var_name] = fmt_alloca
|
||||
Gen.builder.store(fmt_ptr, Gen.variables[fmt_var_name])
|
||||
kind_var_name: str = f"__{VarName}_kind"
|
||||
if kind_var_name not in Gen.variables:
|
||||
kind_alloca: ir.AllocaInstr = Gen._allocaEntry(ir.IntType(32), name=kind_var_name)
|
||||
Gen.variables[kind_var_name] = kind_alloca
|
||||
Gen.builder.store(ir.Constant(ir.IntType(32), 0), Gen.variables[kind_var_name])
|
||||
if VarName not in Gen.variables:
|
||||
dummy_var: ir.AllocaInstr = Gen._alloca(ir.IntType(8), name=VarName)
|
||||
Gen.variables[VarName] = dummy_var
|
||||
return
|
||||
# 只有"模块名.类型名"才是类型变量赋值(旧 t/c 模块写法:x = t.CInt32T)。
|
||||
# 判据必须限定链根是模块:f19d2578 退役 t/c 时丢了 IsTModule 检查,
|
||||
# 使普通属性读取赋值(如 cur = cur.next)也被当成类型赋值 —— 只发射
|
||||
# __<var>_fmt / __<var>_kind 两个无效 store 就 return,真实赋值丢失
|
||||
# (现场:includes/json 链表遍历 cur 永不前进 → 死循环)。
|
||||
_BaseName: str = Node.value.value.id
|
||||
_SymTab = self.Trans.SymbolTable
|
||||
_BaseIsModule: bool = bool(
|
||||
_BaseName in (getattr(self.Trans, '_ImportedModules', None) or set())
|
||||
or _BaseName in _SymTab.import_aliases)
|
||||
if not _BaseIsModule:
|
||||
_AliasInfo = _SymTab.lookup(_BaseName)
|
||||
_BaseIsModule = bool(_AliasInfo is not None
|
||||
and getattr(_AliasInfo, 'IsModuleAlias', False))
|
||||
_TypeInfo = _SymTab.lookup(AttrName)
|
||||
_IsTypeName: bool = bool(
|
||||
_BaseIsModule and (
|
||||
resolved is not None or AttrName == 'CPtr'
|
||||
or (_TypeInfo is not None and (
|
||||
getattr(_TypeInfo, 'IsTypedef', False)
|
||||
or getattr(_TypeInfo, 'IsStruct', False)
|
||||
or getattr(_TypeInfo, 'IsEnum', False)))))
|
||||
if _IsTypeName:
|
||||
Gen.var_type_info[VarName] = {'type': 't_type', 'name': AttrName}
|
||||
Gen.var_type_assignments.setdefault(VarName, []).append({'type': 't_type', 'name': AttrName})
|
||||
c_type_name: str = ''
|
||||
if resolved is not None:
|
||||
ctype_cls: type = resolved[0]
|
||||
ptr_level: int = resolved[1]
|
||||
c_type_name = CTypeRegistry.CTypeToName(ctype_cls)
|
||||
if ptr_level > 0 and c_type_name:
|
||||
c_type_name = c_type_name + ' *'
|
||||
if not c_type_name:
|
||||
if AttrName == 'CPtr':
|
||||
c_type_name = 'void *'
|
||||
is_unsigned: bool = Gen._is_type_unsigned(c_type_name) if c_type_name else False
|
||||
fmt_str: str = "%u\n" if is_unsigned else "%d\n"
|
||||
fmt_ptr: ir.Value = Gen._create_string_global(fmt_str)
|
||||
fmt_var_name: str = f"__{VarName}_fmt"
|
||||
if fmt_var_name not in Gen.variables:
|
||||
fmt_alloca: ir.AllocaInstr = Gen._allocaEntry(ir.PointerType(ir.IntType(8)), name=fmt_var_name)
|
||||
Gen.variables[fmt_var_name] = fmt_alloca
|
||||
Gen.builder.store(fmt_ptr, Gen.variables[fmt_var_name])
|
||||
kind_var_name: str = f"__{VarName}_kind"
|
||||
if kind_var_name not in Gen.variables:
|
||||
kind_alloca: ir.AllocaInstr = Gen._allocaEntry(ir.IntType(32), name=kind_var_name)
|
||||
Gen.variables[kind_var_name] = kind_alloca
|
||||
Gen.builder.store(ir.Constant(ir.IntType(32), 0), Gen.variables[kind_var_name])
|
||||
if VarName not in Gen.variables:
|
||||
dummy_var: ir.AllocaInstr = Gen._alloca(ir.IntType(8), name=VarName)
|
||||
Gen.variables[VarName] = dummy_var
|
||||
return
|
||||
if isinstance(Node.value, ast.Name) and Node.value.id in Gen.structs:
|
||||
ClassName: str = Node.value.id
|
||||
Gen.var_type_info[VarName] = {'type': 'class_cast', 'name': ClassName}
|
||||
|
||||
Reference in new issue
Block a user