feat(parser,descriptor): static 作为注解位置描述符(名字: static T)
新增 _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)。
This commit is contained in:
1 parent
6e3231d04c
commit
6b88b3feff
1 file changed
+35
-3
+35
-3
@@ -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 成
|
||||
|
||||
Reference in new issue
Block a user