From 6b88b3feffa5bc2cb5f6b40da417a386149d6f1f Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sun, 27 Sep 2026 14:18:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(parser,descriptor):=20static=20=E4=BD=9C?= =?UTF-8?q?=E4=B8=BA=E6=B3=A8=E8=A7=A3=E4=BD=8D=E7=BD=AE=E6=8F=8F=E8=BF=B0?= =?UTF-8?q?=E7=AC=A6=EF=BC=88=E5=90=8D=E5=AD=97:=20static=20T=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 _IsStaticDescriptorKeyword 并接入 _parse_type_ann 的描述符循环:注解位置的 static(名字: static T,ViperOS 驱动广泛写 pack_head: static uint32 = 0)与 const/volatile 同位置、顺序自由、可混写,落成同一个 t.CStatic 标记(与语句起始 static 名字: T 的 pending_static 通道、手写 t.CStatic | T 三处同源)。此前注解位置的 static 未被消费,退化成一个叫 static 的类名并被建成 opaque 结构体(@a = global 类型为 sha1.static 的 zeroinitializer,llvm-link 报 invalid type for null constant)。 --- ast/parser.vp | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/ast/parser.vp b/ast/parser.vp index ee1d8a5..91f1bf7 100644 --- a/ast/parser.vp +++ b/ast/parser.vp @@ -754,6 +754,24 @@ def _IsStaticModifier(ps: rawptr[Parser]) -> int: return 0 +def _IsStaticDescriptorKeyword(ps: rawptr[Parser]) -> int: + """当前 token 是否为注解位置的 `static` 描述符(软关键字),1=是 / 0=否 + + 与 const / volatile 同族:只在注解位置(`:` 后的 AnnAssign/形参注解、`->` 后的 + 返回注解)由 `_parse_type_ann` 消费,作标识符的位置不受影响。 + 支持 `名字: static 类型` 写法(ViperOS 驱动广泛使用:`pack_head: static uint32 = 0`), + 与语句起始的 `static 名字: 类型`(pending_static 通道)、手写 `t.CStatic | T` + **三处同源**——都落成同一个 `t.CStatic` 标记(此前注解位置的 static 未被消费, + 退化成一个叫 static 的"类名",被建成 opaque 结构体 @a = global %"sha1.static")。 + """ + if _cur_type(ps) != TokenType.Name: + return 0 + s: str = _cur_str(ps) + if s is None or string.strcmp(s, "static") != 0: + return 0 + return 1 + + def _MakeStaticMarker(ps: rawptr[Parser]) -> rawptr[AST]: """构造标记节点 Attribute(Name('t'), 'CStatic') @@ -2497,13 +2515,16 @@ def _parse_array_prefix_declarator(ps: rawptr[Parser]) -> rawptr[AST]: def _parse_type_ann(ps: rawptr[Parser]) -> rawptr[AST]: - """解析类型注解,支持类型描述符前缀(const / volatile)与 C 风格指针后缀(* / **)。 + """解析类型注解,支持类型描述符前缀(const / volatile / static / __attribute__)与 C 风格指针后缀(* / **)。 类型描述符(软关键字,只在注解位置生效;与 TPC 侧 - `SymbolUtils._ExpandTypeDescriptors` 的展开产物逐字段同形): + `SymbolUtils._ExpandTypeDescriptors` / `_ExpandAttributeDescriptors` 的展开产物逐字段同形): const int → t.CConst | int volatile int → t.CVolatile | int const volatile int → t.CConst | t.CVolatile | int(顺序任意,两限定符都累积) + static int → t.CStatic | int(`名字: static T`;与语句起始 + `static 名字: T`、`@t.CStatic`、手写 `t.CStatic | int` 同源) + __attribute__(x, y(a)) → t.attr.x | t.attr.y(a)(顺序自由、可与上述混写) const t.CInt32T → t.CConst | t.CInt32T const rawptr[Foo] → t.CConst | rawptr[Foo] const int | t.CPtr → t.CConst | int | t.CPtr(粘贴在联合的最左操作数:与 @@ -2538,11 +2559,22 @@ def _parse_type_ann(ps: rawptr[Parser]) -> rawptr[AST]: if st_mk is not None: mods.append(st_mk) mod_count += 1 - while _IsDescriptorKeyword(ps) != 0 or _IsMagicAttributeCall(ps) != 0: + while _IsDescriptorKeyword(ps) != 0 or _IsMagicAttributeCall(ps) != 0 \ + or _IsStaticDescriptorKeyword(ps) != 0: if mods is None: # 元素大小显式传 8:list[T](pool, elem_size) 按字节步长寻址,传 4 会让 # 两个及以上描述符(如 `const volatile`)的第 2 个 8 字节指针越位写入。 mods = list[rawptr[AST]](ps.pool, 8) + if _IsStaticDescriptorKeyword(ps) != 0: + # 注解位置的 `static`(`名字: static T`):与 const/volatile 同位置、 + # 顺序自由、可混写,落成**同一个** t.CStatic 标记(与语句起始 + # `static 名字: T` 的 pending_static 通道、手写 `t.CStatic | T` 三处同源)。 + st_mk_an: rawptr[AST] = _MakeStaticMarker(ps) + if st_mk_an is not None: + mods.append(st_mk_an) + mod_count += 1 + _advance(ps) + continue if _IsMagicAttributeCall(ps) != 0: # C 风格 `a: __attribute__(section(".text.wo"), aligned(16)) const int = ...`: # 与 const / volatile 同位置、同顺序自由、可混写;每个实参 desugar 成