diff --git a/lib/core/Handles/HandlesExpr.py b/lib/core/Handles/HandlesExpr.py index da8640a..46f1d6a 100644 --- a/lib/core/Handles/HandlesExpr.py +++ b/lib/core/Handles/HandlesExpr.py @@ -9,7 +9,8 @@ import llvmlite.ir as ir from lib.core.Handles.HandlesBase import BaseHandle from lib.constants.config import mode as _config_mode from lib.includes.t import CTypeRegistry as _CR -from lib.core.SymbolUtils import RequireDefineUseWidthAt, RequireIntLiteralStorable, RequireNameDefined, DefineDeclTypeValue +from lib.core.SymbolUtils import (RequireDefineUseWidthAt, RequireIntLiteralStorable, RequireNameDefined, + DefineDeclTypeValue, GlobalDeclShadowsDefine) # --------------------------------------------------------------- @@ -480,7 +481,7 @@ class ExprHandle(BaseHandle): # 治本修复:如果符号表也没有,回退查询 _all_define_constants # _all_define_constants 由 Phase2Translator 从所有 .pyi 文件预提取, # 包含跨模块导入的 CDefine 常量(如 FOREGROUND_GREEN、STD_OUTPUT_HANDLE) - if VarName not in define_constants and VarName not in Gen.variables and not (hasattr(Gen, 'module') and VarName in Gen.module.globals): + if VarName not in define_constants and VarName not in Gen.variables and not GlobalDeclShadowsDefine(Gen, VarName): 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] diff --git a/lib/core/Handles/HandlesExprAttr.py b/lib/core/Handles/HandlesExprAttr.py index c663fdc..5635847 100644 --- a/lib/core/Handles/HandlesExprAttr.py +++ b/lib/core/Handles/HandlesExprAttr.py @@ -5,7 +5,7 @@ if TYPE_CHECKING: from lib.core.LlvmCodeGenerator import LlvmCodeGenerator from lib.core.Handles.HandlesBase import BaseHandle, FuncMeta from lib.core.VLogger import get_logger as _vlog -from lib.core.SymbolUtils import DefineDeclTypeValue +from lib.core.SymbolUtils import DefineDeclTypeValue, GlobalDeclShadowsDefine import vast as ast import llvmlite.ir as ir @@ -440,9 +440,10 @@ class ExprAttrHandle(BaseHandle): # 与 _HandleNameLlvm 的裸名回退同源)。**模块属性访问**(`win32file.STD_OUTPUT_HANDLE`) # 此前只查 SymbolTable/_define_constants → 未命中就落到 _lookup_module_global 生成 # `@STD_OUTPUT_HANDLE` 全局引用(无定义 → 链接期 undefined symbol)。 - # 与裸名路径同口径:仅当本模块没有同名变量/全局时才用常量(避免遮蔽真正的模块全局)。 - _has_shadow: bool = AttrName in Gen.variables \ - or (hasattr(Gen, 'module') and AttrName in getattr(Gen.module, 'globals', {})) + # 与裸名路径同口径:仅当本模块没有同名变量/(**已定义的**)全局时才用常量。 + # 注意:跨模块 stub 注入的 `@X = external global`(无初值)**不算**遮蔽 —— 否则 + # 一条错误的 stub declare 会把 .vpi 的 CDefine 常量顶掉,退化成未定义全局符号。 + _has_shadow: bool = AttrName in Gen.variables or GlobalDeclShadowsDefine(Gen, AttrName) if not _has_shadow: all_dc: dict[str, Any] = getattr(Gen, '_all_define_constants', None) or getattr(self.Trans, '_all_define_constants', None) or {} for key2 in (f"{VarName}.{AttrName}", AttrName): diff --git a/lib/core/SymbolUtils.py b/lib/core/SymbolUtils.py index d8058d6..5be8ca0 100644 --- a/lib/core/SymbolUtils.py +++ b/lib/core/SymbolUtils.py @@ -1934,16 +1934,25 @@ def DefineDeclIntTypeFromAnnotation(symtab: object, annotation: object) -> tuple if entry is None or not getattr(entry, 'IsTypedef', False): return None base: object | None = getattr(entry, 'BaseType', None) - # 别名链:OriginalType 可能是内层 CTypeInfo(同一 typedef 的底层解析结果) + # 别名链:`DWORD` 这类 typedef 的 BaseType 常为 None,底层类型记在 OriginalType 里: + # ① 字符串 t 类名(实测 `DWORD` → `'CUInt32T'`、`ULONG` → `'CUInt32T'`); + # ② 内层 CTypeInfo(再取它的 BaseType)。 + # 带空格/指针的串(如 `'void *'`)不是整数别名 → 放弃。 + orig: object | None = getattr(entry, 'OriginalType', None) depth: int = 0 - while base is None and depth < 8: - orig: object | None = getattr(entry, 'OriginalType', None) - if not isinstance(orig, type(base)) and orig is not None and hasattr(orig, 'BaseType'): - entry = orig - base = getattr(entry, 'BaseType', None) - else: - break + while base is None and orig is not None and depth < 8: depth += 1 + if isinstance(orig, str): + cand: object | None = getattr(t, orig, None) + if cand is None: + break + base = cand + break + if hasattr(orig, 'BaseType'): + base = getattr(orig, 'BaseType', None) + orig = getattr(orig, 'OriginalType', None) + continue + break width: int | None = DefineIntWidthOf(base) if width is None: return None @@ -1981,6 +1990,23 @@ def DefineDeclTypeValue(DeclTypes: object | None, Name: str | None, Value: objec return (width, v) +def GlobalDeclShadowsDefine(Gen: object, Name: str | None) -> bool: + """该名字在本模块是否有**已定义**(带初值)的全局 → 视为遮蔽同名 CDefine 常量。 + + 仅 `external global`(**无初值**,典型来自跨模块 stub 注入的 declare)**不算**遮蔽: + 否则 stub 里一条错误的 `@X = external global` 会把 .vpi 里的 CDefine 常量顶掉, + 读路径退化成"加载该全局" → 链接期 undefined symbol(现场:win32file 的 STD_*_HANDLE)。 + 真正的本模块全局在 IR 里带初值/存储,仍按既有优先级遮蔽常量。 + """ + mod: object | None = getattr(Gen, 'module', None) + if mod is None or Name is None: + return False + g: object | None = getattr(mod, 'globals', {}).get(Name) + if g is None: + return False + return getattr(g, 'initializer', None) is not None + + def RequireDefineIntStorable(Value: object, BaseType: object | None, Name: str, AnnotationText: str, Lineno: int, Col: int, FilePath: str, CodeLine: str) -> None: