Some simple information syncing

This commit is contained in:
2026-07-28 21:08:58 +08:00
parent 1837339f69
commit 3633be1995
65 changed files with 1132 additions and 368581 deletions

View File

@@ -328,9 +328,14 @@ class ExprHandle(BaseHandle):
def _HandleNameLlvm(self, Node: ast.Name, VarType: ir.Type | str | None = None) -> ir.Value:
Gen: LlvmCodeGenerator = self.Trans.LlvmGen
VarName: str = Node.id
# [CD] 诊断仅对关键常量输出FOREGROUND_*, BACKGROUND_*, STD_*, *HANDLE*
import sys as _sys
_is_cd_key: bool = isinstance(VarName, str) and (VarName.startswith('FOREGROUND_') or VarName.startswith('BACKGROUND_') or 'STD_' in VarName or 'HANDLE' in VarName)
define_constants: dict[str, Any] = getattr(Gen, '_define_constants', {})
if VarName in define_constants:
val: Any = define_constants[VarName]
if _is_cd_key:
print(f"[CD] lookup: '{VarName}' found in _define_constants val={val}", file=_sys.stderr, flush=True)
if isinstance(val, int):
# Use VarType hint if available to avoid unnecessary type mismatch
if VarType is not None and isinstance(VarType, ir.IntType):
@@ -347,11 +352,13 @@ class ExprHandle(BaseHandle):
elif isinstance(val, str):
return Gen._create_string_global(val)
# 如果 _define_constants 中没有,尝试从符号表查找
if VarName not in getattr(Gen, '_define_constants', {}):
if VarName not in define_constants:
try:
sym_info: Any = self.translator.SymbolTable.lookup(VarName)
sym_info: Any = self.Trans.SymbolTable.lookup(VarName)
if sym_info and sym_info.IsDefine and sym_info.DefineValue is not None:
val = sym_info.DefineValue
if _is_cd_key:
print(f"[CD] lookup: '{VarName}' found in SymbolTable val={val}", file=_sys.stderr, flush=True)
if isinstance(val, int):
# Use VarType hint if available
if VarType is not None and isinstance(VarType, ir.IntType):
@@ -363,9 +370,32 @@ class ExprHandle(BaseHandle):
return ir.Constant(ir.DoubleType(), val)
elif isinstance(val, str):
return Gen._create_string_global(val)
elif _is_cd_key:
print(f"[CD] lookup: '{VarName}' NOT in SymbolTable", file=_sys.stderr, flush=True)
except Exception as _e:
if _config_mode == "strict":
self.Trans.LogWarning(f"异常被忽略: {_e}")
# 治本修复:如果符号表也没有,回退查询 _all_define_constants
# _all_define_constants 由 Phase2Translator 从所有 .pyi 文件预提取,
# 包含跨模块导入的 CDefine 常量(如 FOREGROUND_GREEN、STD_OUTPUT_HANDLE
if VarName not in define_constants:
all_dc: dict[str, Any] = getattr(Gen, '_all_define_constants', None) or getattr(self.Trans, '_all_define_constants', None) or {}
if VarName in all_dc:
val: Any = all_dc[VarName]
if _is_cd_key:
print(f"[CD] lookup: '{VarName}' found in _all_define_constants val={val}", file=_sys.stderr, flush=True)
if isinstance(val, int):
if VarType is not None and isinstance(VarType, ir.IntType):
return ir.Constant(VarType, val & ((1 << VarType.width) - 1))
if val < -(1 << 31) or val > 0xFFFFFFFF:
return ir.Constant(ir.IntType(64), val & 0xFFFFFFFFFFFFFFFF)
return ir.Constant(ir.IntType(32), val & 0xFFFFFFFF)
elif isinstance(val, float):
return ir.Constant(ir.DoubleType(), val)
elif isinstance(val, str):
return Gen._create_string_global(val)
elif _is_cd_key:
print(f"[CD] lookup: '{VarName}' NOT found in ANY CDefine table", file=_sys.stderr, flush=True)
# 优先检查 variablesalloca因为变量可能已被 += 等操作迁移到 variables
if VarName in Gen.variables and Gen.variables[VarName] is not None:
VarPtr: Any = Gen.variables[VarName]
@@ -410,7 +440,18 @@ class ExprHandle(BaseHandle):
return GVar
return Gen._load(GVar, name=VarName)
if VarName == 'self':
return Gen.GetVarPtr('self')
# 治本修复:方法名为 _get_var_ptr小写原 GetVarPtr 不存在会抛 AttributeError。
# 当 self 未注册到 variables 时(如 opaque struct 参数走了 else 分支),
# 通过 _get_var_ptr 兜底返回 None由调用方处理。
SelfPtr: ir.Value | None = Gen._get_var_ptr('self')
if SelfPtr is not None:
return SelfPtr
# 最终兜底:若 _get_var_ptr 返回 Noneself 既不在 _reg_values 也不在 variables
# 直接返回函数参数本身LLVM Argument。这避免了 AttributeError 导致的异常路径。
for arg in getattr(Gen.func, 'args', []):
if getattr(arg, 'name', None) == 'self':
return arg
return ir.Constant(ir.IntType(32), 0)
if Gen._has_function(VarName):
func: Any = Gen._get_function(VarName)
if func:

View File

@@ -2045,6 +2045,21 @@ class ExprCallHandle(BaseHandle):
arg = Gen.builder.sext(arg, ir.IntType(64), name=f"sext_vararg_{FuncName}")
else:
arg = Gen.builder.zext(arg, ir.IntType(64), name=f"zext_vararg_{FuncName}")
elif isinstance(arg.type, (ir.LiteralStructType, ir.IdentifiedStructType)):
# 治本修复:变参函数(如 printf不支持 struct by value 传递。
# 当 self 等 struct 值被错误地 load 为值(而非指针)传入变参时,
# ABI 不匹配会导致崩溃。修复:将 struct 值通过 alloca + bitcast
# 转换为 i8* 指针传递,确保与 %p / %s 等格式说明符兼容。
try:
alloca_tmp = Gen.builder.alloca(arg.type, name=f"vararg_struct_{FuncName}_{i}")
Gen.builder.store(arg, alloca_tmp)
arg = Gen.builder.bitcast(alloca_tmp, ir.IntType(8).as_pointer(), name=f"vararg_struct_ptr_{FuncName}_{i}")
except Exception:
# 回退alloca/store 失败时,尝试 ptrtoint 为 i64
try:
arg = Gen.builder.ptrtoint(arg, ir.IntType(64), name=f"vararg_struct_i64_{FuncName}_{i}")
except Exception:
pass # 最终回退:保留原值(可能仍会导致崩溃,但至少不阻塞编译)
adjusted.append(arg)
result = Gen.builder.call(func, adjusted, name=f"call_{FuncName}")
else:
@@ -2851,15 +2866,33 @@ class ExprCallHandle(BaseHandle):
if class_sha1 and ClassName in Gen.structs:
struct_type = Gen.structs[ClassName]
self_ptr_type = ir.PointerType(struct_type)
param_types = [self_ptr_type] + [a.type for a in CallArgs]
func_type = ir.FunctionType(ir.IntType(32), param_types)
# 修复 Bug 4: 从符号表获取完整参数列表(含默认参数)和正确返回类型,
# 而非仅使用 CallArgs漏掉默认参数和硬编码 i32 返回类型。
# 这避免了 main.py 中 declare Logger.info(...,i8*) 2参数
# 与 VLogger 中 define Logger.info(...,i8*,i8*) 3参数的签名冲突。
ret_type: Any = ir.IntType(32)
param_types: list[Any] = [self_ptr_type] + [a.type for a in CallArgs]
SymInfoFallback = self.LookupFunctionSymbol(MethodName, module_path=ClassName)
if SymInfoFallback and SymInfoFallback.IsFunction:
sig = self.BuildLLVMFuncTypeFromSig(SymInfoFallback, Gen)
if sig is not None:
sig_ret, sig_params, _ = sig
ret_type = sig_ret
is_static_fb = FuncMeta.STATIC_METHOD in SymInfoFallback.MetaList
if not is_static_fb:
sig_params = [self_ptr_type] + sig_params
param_types = sig_params
func_type = ir.FunctionType(ret_type, param_types)
func = ir.Function(Gen.module, func_type, name=FullMethodName)
Gen.functions[FullMethodName] = func
if isinstance(ObjVal.type, ir.PointerType) and ObjVal.type.pointee == struct_type:
call_self = ObjVal
else:
call_self = Gen.builder.bitcast(ObjVal, self_ptr_type, name=f"method_self_{ClassName}")
adjusted = Gen._adjust_args([call_self] + CallArgs, func)
call_args_fb = [call_self] + CallArgs
self._fill_default_args(call_args_fb, func, FullMethodName)
self._append_eh_msg_out_arg(call_args_fb, func, Gen)
adjusted = Gen._adjust_args(call_args_fb, func)
result = Gen.builder.call(func, adjusted, name=f"call_{FullMethodName}")
return result
raise Exception(f"Undefined method '{MethodName}' in class '{ClassName}' (no function declaration found for '{FullMethodName}')")

View File

@@ -112,20 +112,26 @@ class ImportHandle(BaseHandle):
# For 'from X import Y' (no asname), register CDefine constants
# into _define_constants so they can be found by _HandleNameLlvm
if not asname or asname == name:
define_constants = vars(Gen).setdefault('_define_constants', {})
# Check if this name is a CDefine constant in SymbolTable
sym_info = self.Trans.SymbolTable.lookup(name)
if sym_info and sym_info.IsDefine and sym_info.DefineValue is not None:
define_constants = vars(Gen).setdefault('_define_constants', {})
if name not in define_constants:
define_constants[name] = sym_info.DefineValue
# Also check with module prefix
for prefix_key in [f"{module}.{name}", name]:
sym_info2 = self.Trans.SymbolTable.lookup(prefix_key)
if sym_info2 and sym_info2.IsDefine and sym_info2.DefineValue is not None:
define_constants = vars(Gen).setdefault('_define_constants', {})
if name not in define_constants:
define_constants[name] = sym_info2.DefineValue
break
# 治本修复:如果符号表中没有,回退查询 _all_define_constants
# _all_define_constants 由 Phase2Translator 从所有 .pyi 文件预提取,
# 包含跨模块导入的 CDefine 常量(如 FOREGROUND_GREEN、STD_OUTPUT_HANDLE
if name not in define_constants:
all_dc: dict = getattr(Gen, '_all_define_constants', None) or getattr(self.Trans, '_all_define_constants', None) or {}
if name in all_dc:
define_constants[name] = all_dc[name]
continue
if not hasattr(self.Trans, '_t_c_imported_names'):
self.Trans._t_c_imported_names = {}

View File

@@ -211,6 +211,11 @@ class HandlesTypeMerge(BaseHandle):
elif TypeClass:
Info = CTypeInfo()
Info.BaseType = TypeClass
# 治本修复t.CDefine 注解必须设置 IsDefine=True
# 否则预扫描 (LlvmGenerator.py) 和主处理 (HandlesAnnAssign.py)
# 都无法识别 CDefine 常量,导致 FOREGROUND_GREEN 等解析为 0
if isinstance(TypeClass, type) and issubclass(TypeClass, t.CDefine):
Info.IsDefine = True
return Info
elif CTypeHelper.GetCName(TypeName):
return self._MakeCTypeInfoFromName(CTypeHelper.GetCName(TypeName))