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 成