fix(parser): 类型注解位的 __attribute__(...) 只解析调用本身,不再吞掉后续 []T
原实现用 _parse_test 解析 __attribute__(...) —— 那是通用表达式解析器,解析完调用后
会继续吃 postfix trailer,把紧随的 C 风格前置数组 `[]T` 的 `[]` 当作**合法空下标**
吞掉(_parse_slice 显式支持空下标 T[],见其注释)。后果:ac_node 不再是 Call ⇒
描述符循环 break(markers 一个都没收集),且 _match_op(Lsqb) 此时看到的是元素类型
⇒ 数组分支被跳过 ⇒ 整个注解退化成裸元素类型,且**全程零报错**。
现场:TransPyV/App/main.vp:44
V_TPV_VERSION: __attribute__(section(".PRVERSN")) []char = "0.0.5-dev.479"
被解析成 `char`:stub 记 `V_TPV_VERSION: char`、IR 出
`@g = global i8 getelementptr ...`(opt: got 'ptr' but expected 'i8')、段名 ".PRVERSN" 丢失。
改为:_advance 过 `__attribute__` 后用 _parse_call 解析 `( 实参表 )`,postfix 不再被
误吃,`[]char` 交回数组分支脱糖为 t.CArray[char, None] → i8*。
This commit is contained in:
1 parent
c27ebc1b69
commit
d4234c75cc
1 file changed
+17
-1
+17
-1
@@ -2631,7 +2631,23 @@ def _parse_type_ann(ps: rawptr[Parser]) -> rawptr[AST]:
|
||||
# 与 const / volatile 同位置、同顺序自由、可混写;每个实参 desugar 成
|
||||
# `t.attr.<name>`(带调用则保留实参)后并入同一 markers 列表,由
|
||||
# _PrependDescriptorMarkers 贴到类型联合最左(与 TPC 文本展开同形)。
|
||||
ac_node: rawptr[AST] = _parse_test(ps)
|
||||
#
|
||||
# ⚠ 只用 _parse_call 解析**这个调用本身**,绝不能用 _parse_test:后者是
|
||||
# 通用表达式解析器,解析完 `__attribute__(...)` 会继续吃 postfix trailer,
|
||||
# 把紧随的 C 风格前置数组 `[]T` 的 `[]` 当作**合法空下标**吞掉
|
||||
# (_parse_slice 显式支持空下标 `T[]`,见其注释)——全程**零报错**,
|
||||
# 但 ac_node 已不是 Call ⇒ 本循环 break、markers 一个都没收集,且
|
||||
# `_match_op(Lsqb)` 此时看到的是元素类型 ⇒ 数组分支被跳过 ⇒ 注解整体
|
||||
# 退化成裸元素类型。现场:main.vp:44
|
||||
# V_TPV_VERSION: __attribute__(section(".PRVERSN")) []char = "…"
|
||||
# 被解析成 `char`(stub 记 `V_TPV_VERSION: char`、IR 出
|
||||
# `global i8 <getelementptr>` 非法、段名 ".PRVERSN" 丢失)。
|
||||
mka_lineno: int = _cur_lineno(ps)
|
||||
mka_col: int = _cur_col(ps)
|
||||
mka_fn: rawptr[AST] = Name(ps.pool, "__attribute__", ASTCtx.Load)
|
||||
_set_pos(mka_fn, mka_lineno, mka_col, 0, 0)
|
||||
_advance(ps) # 消费 `__attribute__`
|
||||
ac_node: rawptr[AST] = _parse_call(ps, mka_fn) # 只解析 `( 实参表 )`
|
||||
if ac_node is None:
|
||||
break
|
||||
if ac_node.kind() != ASTKind.Call:
|
||||
|
||||
Reference in new issue
Block a user