fix(llvmlite): opaque与空结构体区分(fcount哨兵);ast表达式节点调整
This commit is contained in:
1 parent
99bf970452
commit
b4567ffb9a
5 files changed
+58
-42
No files matched your search
@@ -9,7 +9,7 @@ from .tokens import (
|
||||
)
|
||||
# Common Section: Base Classes, Enums, Constants, Helper Functions, Dump
|
||||
from .base import (
|
||||
AST, Stmt, Expr, ASTKind, ASTCtx, OpKind, ASTFlag,
|
||||
AST, Stmt, ExprNode, ASTKind, ASTCtx, OpKind, ASTFlag,
|
||||
# Constants
|
||||
CONST_INT, CONST_FLOAT, CONST_STR, CONST_BOOL, CONST_NONE, CONST_CHAR,
|
||||
FLAG_IS_ASYNC, FLAG_SIMPLE, FLAG_HAS_STAR,
|
||||
|
||||
@@ -472,14 +472,17 @@ class Stmt(AST):
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Expr - Expression Base Class
|
||||
# ExprNode - Expression Base Class
|
||||
#
|
||||
# 所有表达式节点(Name/Constant/Call/BinOp/...)继承 Expr。
|
||||
# isinstance(node, ast.Expr) 可在运行时区分"表达式"与"语句"。
|
||||
# 所有表达式节点(Name/Constant/Call/BinOp/...)继承 ExprNode。
|
||||
# isinstance(node, ast.ExprNode) 可在运行时区分"表达式"与"语句"。
|
||||
#
|
||||
# 命名说明:不能叫 Expr——ASTKind.Expr(base.vp L23)与 stmts.vp 的
|
||||
# Expr 类已是"表达式语句"(Expression Statement)的既有语义。
|
||||
# ============================================================
|
||||
|
||||
@t.CVTable
|
||||
class Expr(AST):
|
||||
class ExprNode(AST):
|
||||
"""表达式节点基类(Name/Constant/Call/BinOp/...)"""
|
||||
|
||||
|
||||
|
||||
+28
-28
@@ -3,7 +3,7 @@ from stdint import *
|
||||
import memhub
|
||||
import string
|
||||
from .base import (
|
||||
AST, Expr, ASTKind, ASTCtx, OpKind,
|
||||
AST, ExprNode, ASTKind, ASTCtx, OpKind,
|
||||
_init_ast, _copy_str, _set_parent_list,
|
||||
_emit, _emit_str, _emit_int, _dump_list, _dump_op_list, _op_name,
|
||||
CONST_INT, CONST_FLOAT, CONST_STR, CONST_BOOL, CONST_NONE, CONST_CHAR
|
||||
@@ -14,7 +14,7 @@ from .base import (
|
||||
# Name node
|
||||
# ============================================================
|
||||
|
||||
class Name(Expr):
|
||||
class Name(ExprNode):
|
||||
"""Name(id: str, ctx: ASTCtx)"""
|
||||
id: str
|
||||
ctx: t.CInt
|
||||
@@ -57,7 +57,7 @@ class Name(Expr):
|
||||
# Constant nodes (subtype marked by const_kind)
|
||||
# ============================================================
|
||||
|
||||
class Constant(Expr):
|
||||
class Constant(ExprNode):
|
||||
"""Constant(int_val/float_val/str_val, const_kind)"""
|
||||
int_val: t.CInt64T
|
||||
float_val: t.CDouble
|
||||
@@ -126,7 +126,7 @@ class Constant(Expr):
|
||||
# BinOp Node
|
||||
# ============================================================
|
||||
|
||||
class BinOp(Expr):
|
||||
class BinOp(ExprNode):
|
||||
"""BinOp(left: AST, op: OpKind, right: AST)"""
|
||||
left: AST | t.CPtr
|
||||
op: t.CInt
|
||||
@@ -174,7 +174,7 @@ class BinOp(Expr):
|
||||
# UnaryOp Node
|
||||
# ============================================================
|
||||
|
||||
class UnaryOp(Expr):
|
||||
class UnaryOp(ExprNode):
|
||||
"""UnaryOp(op: OpKind, operand: AST)"""
|
||||
op: t.CInt
|
||||
operand: AST | t.CPtr
|
||||
@@ -215,7 +215,7 @@ class UnaryOp(Expr):
|
||||
# Compare Node
|
||||
# ============================================================
|
||||
|
||||
class Compare(Expr):
|
||||
class Compare(ExprNode):
|
||||
"""Compare(left: AST, ops: list[CInt], comparators: list[AST | CPtr])"""
|
||||
left: AST | t.CPtr
|
||||
ops: t.CPtr
|
||||
@@ -265,7 +265,7 @@ class Compare(Expr):
|
||||
# Call Node
|
||||
# ============================================================
|
||||
|
||||
class Call(Expr):
|
||||
class Call(ExprNode):
|
||||
"""Call(func: AST, args: list[AST | CPtr], keywords: list[AST | CPtr])"""
|
||||
func: AST | t.CPtr
|
||||
args: list[AST | t.CPtr] | t.CPtr
|
||||
@@ -314,7 +314,7 @@ class Call(Expr):
|
||||
# BoolOp Node
|
||||
# ============================================================
|
||||
|
||||
class BoolOp(Expr):
|
||||
class BoolOp(ExprNode):
|
||||
"""BoolOp(op: CInt, values: list[AST | CPtr])"""
|
||||
op: t.CInt
|
||||
values: list[AST | t.CPtr] | t.CPtr
|
||||
@@ -355,7 +355,7 @@ class BoolOp(Expr):
|
||||
# Lambda Node
|
||||
# ============================================================
|
||||
|
||||
class Lambda(Expr):
|
||||
class Lambda(ExprNode):
|
||||
"""Lambda(args: AST, body: AST)"""
|
||||
args: AST | t.CPtr
|
||||
body: AST | t.CPtr
|
||||
@@ -399,7 +399,7 @@ class Lambda(Expr):
|
||||
# IfExp Node
|
||||
# ============================================================
|
||||
|
||||
class IfExp(Expr):
|
||||
class IfExp(ExprNode):
|
||||
"""IfExp(test: AST, body: AST, orelse: AST)"""
|
||||
test: AST | t.CPtr
|
||||
body: AST | t.CPtr
|
||||
@@ -452,7 +452,7 @@ class IfExp(Expr):
|
||||
# Dict Node
|
||||
# ============================================================
|
||||
|
||||
class Dict(Expr):
|
||||
class Dict(ExprNode):
|
||||
"""Dict(keys: list[AST | CPtr], values: list[AST | CPtr])"""
|
||||
keys: list[AST | t.CPtr] | t.CPtr
|
||||
values: list[AST | t.CPtr] | t.CPtr
|
||||
@@ -494,7 +494,7 @@ class Dict(Expr):
|
||||
# Set Node
|
||||
# ============================================================
|
||||
|
||||
class Set(Expr):
|
||||
class Set(ExprNode):
|
||||
"""Set(elts: list[AST | CPtr])"""
|
||||
elts: list[AST | t.CPtr] | t.CPtr
|
||||
|
||||
@@ -529,7 +529,7 @@ class Set(Expr):
|
||||
# ListComp Node
|
||||
# ============================================================
|
||||
|
||||
class ListComp(Expr):
|
||||
class ListComp(ExprNode):
|
||||
"""ListComp(elt: AST, generators: list[AST | CPtr])"""
|
||||
elt: AST | t.CPtr
|
||||
generators: list[AST | t.CPtr] | t.CPtr
|
||||
@@ -573,7 +573,7 @@ class ListComp(Expr):
|
||||
# SetComp Node
|
||||
# ============================================================
|
||||
|
||||
class SetComp(Expr):
|
||||
class SetComp(ExprNode):
|
||||
"""SetComp(elt: AST, generators: list[AST | CPtr])"""
|
||||
elt: AST | t.CPtr
|
||||
generators: list[AST | t.CPtr] | t.CPtr
|
||||
@@ -617,7 +617,7 @@ class SetComp(Expr):
|
||||
# DictComp Node
|
||||
# ============================================================
|
||||
|
||||
class DictComp(Expr):
|
||||
class DictComp(ExprNode):
|
||||
"""DictComp(key: AST, value: AST, generators: list[AST | CPtr])"""
|
||||
key: AST | t.CPtr
|
||||
value: AST | t.CPtr
|
||||
@@ -668,7 +668,7 @@ class DictComp(Expr):
|
||||
# GeneratorExp Node
|
||||
# ============================================================
|
||||
|
||||
class GeneratorExp(Expr):
|
||||
class GeneratorExp(ExprNode):
|
||||
"""GeneratorExp(elt: AST, generators: list[AST | CPtr])"""
|
||||
elt: AST | t.CPtr
|
||||
generators: list[AST | t.CPtr] | t.CPtr
|
||||
@@ -712,7 +712,7 @@ class GeneratorExp(Expr):
|
||||
# Await Node
|
||||
# ============================================================
|
||||
|
||||
class Await(Expr):
|
||||
class Await(ExprNode):
|
||||
"""Await(value: AST)"""
|
||||
value: AST | t.CPtr
|
||||
|
||||
@@ -747,7 +747,7 @@ class Await(Expr):
|
||||
# Yield Node
|
||||
# ============================================================
|
||||
|
||||
class Yield(Expr):
|
||||
class Yield(ExprNode):
|
||||
"""Yield(value: AST)"""
|
||||
value: AST | t.CPtr
|
||||
|
||||
@@ -782,7 +782,7 @@ class Yield(Expr):
|
||||
# YieldFrom Node
|
||||
# ============================================================
|
||||
|
||||
class YieldFrom(Expr):
|
||||
class YieldFrom(ExprNode):
|
||||
"""YieldFrom(value: AST)"""
|
||||
value: AST | t.CPtr
|
||||
|
||||
@@ -817,7 +817,7 @@ class YieldFrom(Expr):
|
||||
# FormattedValue Node
|
||||
# ============================================================
|
||||
|
||||
class FormattedValue(Expr):
|
||||
class FormattedValue(ExprNode):
|
||||
"""FormattedValue(value: AST, conversion: CInt, format_spec: AST)"""
|
||||
value: AST | t.CPtr
|
||||
conversion: t.CInt
|
||||
@@ -867,7 +867,7 @@ class FormattedValue(Expr):
|
||||
# JoinedStr Node
|
||||
# ============================================================
|
||||
|
||||
class JoinedStr(Expr):
|
||||
class JoinedStr(ExprNode):
|
||||
"""JoinedStr(values: list[AST | CPtr])"""
|
||||
values: list[AST | t.CPtr] | t.CPtr
|
||||
|
||||
@@ -902,7 +902,7 @@ class JoinedStr(Expr):
|
||||
# Attribute Node
|
||||
# ============================================================
|
||||
|
||||
class Attribute(Expr):
|
||||
class Attribute(ExprNode):
|
||||
"""Attribute(value: AST, attr: str, ctx: CInt)"""
|
||||
value: AST | t.CPtr
|
||||
attr: str
|
||||
@@ -947,7 +947,7 @@ class Attribute(Expr):
|
||||
# Subscript Node
|
||||
# ============================================================
|
||||
|
||||
class Subscript(Expr):
|
||||
class Subscript(ExprNode):
|
||||
"""Subscript(value: AST, slice: AST, ctx: CInt)"""
|
||||
value: AST | t.CPtr
|
||||
slice: AST | t.CPtr
|
||||
@@ -995,7 +995,7 @@ class Subscript(Expr):
|
||||
# Starred Node
|
||||
# ============================================================
|
||||
|
||||
class Starred(Expr):
|
||||
class Starred(ExprNode):
|
||||
"""Starred(value: AST, ctx: CInt)"""
|
||||
value: AST | t.CPtr
|
||||
ctx: t.CInt
|
||||
@@ -1036,7 +1036,7 @@ class Starred(Expr):
|
||||
# List Node
|
||||
# ============================================================
|
||||
|
||||
class List(Expr):
|
||||
class List(ExprNode):
|
||||
"""List(elts: list[AST | CPtr], ctx: CInt)"""
|
||||
elts: list[AST | t.CPtr] | t.CPtr
|
||||
ctx: t.CInt
|
||||
@@ -1075,7 +1075,7 @@ class List(Expr):
|
||||
# Tuple Node
|
||||
# ============================================================
|
||||
|
||||
class Tuple(Expr):
|
||||
class Tuple(ExprNode):
|
||||
"""Tuple(elts: list[AST | CPtr], ctx: CInt)"""
|
||||
elts: list[AST | t.CPtr] | t.CPtr
|
||||
ctx: t.CInt
|
||||
@@ -1114,7 +1114,7 @@ class Tuple(Expr):
|
||||
# Slice Node
|
||||
# ============================================================
|
||||
|
||||
class Slice(Expr):
|
||||
class Slice(ExprNode):
|
||||
"""Slice(lower: AST, upper: AST, step: AST)"""
|
||||
lower: AST | t.CPtr
|
||||
upper: AST | t.CPtr
|
||||
@@ -1167,7 +1167,7 @@ class Slice(Expr):
|
||||
# NamedExpr Node
|
||||
# ============================================================
|
||||
|
||||
class NamedExpr(Expr):
|
||||
class NamedExpr(ExprNode):
|
||||
"""NamedExpr(target: AST, value: AST)"""
|
||||
target: AST | t.CPtr
|
||||
value: AST | t.CPtr
|
||||
|
||||
@@ -366,21 +366,31 @@ 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。
|
||||
# opaque 结构体特征: Struct 类型,fcount == -1(哨兵标记,跨模块前向
|
||||
# 声明,仅名称无字段定义)。通过 Struct(pool, None, -1, name) 创建,
|
||||
# IR 输出为 %"name" = type opaque。注意区分空结构体(fcount==0,
|
||||
# fields==None,无字段类)——它是合法完整定义(= type {},可 alloca)。
|
||||
# 用于在 module_add_named_type 中区分 opaque 声明和完整定义,
|
||||
# 确保 opaque 声明插入链表头部(在使用之前声明)。
|
||||
#
|
||||
# Returns: 1=是 opaque / 0=否
|
||||
# ============================================================
|
||||
def _is_opaque_struct(ty: LLVMType | t.CPtr) -> int:
|
||||
"""检查类型是否是 opaque 结构体(无字段的命名结构体)"""
|
||||
"""检查类型是否是 opaque 结构体
|
||||
|
||||
opaque 是跨模块前向声明(仅名称无字段定义),由
|
||||
_scan_type_for_cross_module_refs 创建,fcount=-1 哨兵标记。
|
||||
空结构体(fcount==0, fields==None,无字段类)是合法完整定义
|
||||
(LLVM {} 类型,可 alloca),必须与 opaque 区分——此前混淆导致
|
||||
空类结构体被输出为 "= type opaque",alloca 报 Cannot allocate
|
||||
unsized type。
|
||||
"""
|
||||
if ty is None:
|
||||
return 0
|
||||
match ty:
|
||||
case LLVMType.Struct(fields, fcount, name):
|
||||
# opaque: 字段数为 0 且字段列表为 None
|
||||
if fcount == 0 and fields is None:
|
||||
# opaque: fcount == -1(哨兵)
|
||||
if fcount < 0:
|
||||
return 1
|
||||
return 0
|
||||
case _:
|
||||
@@ -425,7 +435,9 @@ def _scan_type_for_cross_module_refs(pool: memhub.MemBuddy | t.CPtr,
|
||||
# 检查是否已在模块中定义
|
||||
if _is_type_defined_in_module(mod, sname) == 0:
|
||||
# 创建 opaque 类型并添加到模块
|
||||
opaque_ty: LLVMType | t.CPtr = Struct(pool, None, 0, sname)
|
||||
# fcount=-1 哨兵标记 opaque(区别于空结构体 {},
|
||||
# 后者 fcount==0 是合法完整定义,可 alloca)
|
||||
opaque_ty: LLVMType | t.CPtr = Struct(pool, None, -1, sname)
|
||||
if opaque_ty is not None:
|
||||
module_add_named_type(mod, pool, opaque_ty)
|
||||
# 递归扫描结构体字段中的跨模块引用
|
||||
|
||||
@@ -580,7 +580,8 @@ def PrintStructDefinition(buf: t.CChar | t.CPtr, size: t.CSizeT,
|
||||
ty: LLVMType | t.CPtr, pool: memhub.MemBuddy | t.CPtr):
|
||||
"""打印命名结构体类型定义行 %"name" = type { ty1, ty2, ... }
|
||||
|
||||
当 fcount==0 且 fields is None 时,输出 opaque 声明: %"name" = type opaque
|
||||
当 fcount == -1(哨兵)时输出 opaque 声明: %"name" = type opaque。
|
||||
空结构体(fcount==0, fields==None,无字段类)是完整定义,输出 "= type {}"。
|
||||
"""
|
||||
if ty is None or buf is None or size == 0:
|
||||
return
|
||||
@@ -589,8 +590,8 @@ def PrintStructDefinition(buf: t.CChar | t.CPtr, size: t.CSizeT,
|
||||
if name is None:
|
||||
return
|
||||
# 使用 snprintf 构建 "%%"name" = type" 前缀,避免 _strappend 截断
|
||||
# opaque 类型: fcount==0 且 fields is None(跨模块前向声明)
|
||||
if fcount == 0 and fields is None:
|
||||
# opaque 类型: fcount == -1(哨兵,跨模块前向声明)
|
||||
if fcount < 0:
|
||||
viperlib.snprintf(buf, size, "%%\"%s\" = type opaque", name)
|
||||
else:
|
||||
viperlib.snprintf(buf, size, "%%\"%s\" = type ", name)
|
||||
|
||||
Reference in new issue
Block a user