步骤2:VAR_TEMP 链接层(FB 布局排除 Temp 字段 + 顶层防御校验 + scope 符号映射 Local)+ linker_test

This commit is contained in:
2026-08-26 17:55:24 +08:00
parent aa0c66780c
commit 94634dc0b0
2 changed files with 75 additions and 5 deletions
+13 -5
View File
@@ -214,6 +214,11 @@ namespace {
b.vars.empty() ? 0 : b.vars[0].line,
b.vars.empty() ? 0 : b.vars[0].col);
}
if (b.section == VarSection::Temp) {
return fail(u.path, "VAR_TEMP only allowed in POU",
b.vars.empty() ? 0 : b.vars[0].line,
b.vars.empty() ? 0 : b.vars[0].col);
}
for (const VarDecl& d : b.vars) {
if (out_->global_index.count(d.name)) {
return fail(u.path, "duplicate global '" + d.name + "'",
@@ -266,9 +271,11 @@ namespace {
FbLayout lay;
lay.type_name = p.name;
for (const VarBlock& b : p.blocks) {
// 字段 = input / output / 内部 varexternalglobal 不是字段
// 字段 = input / output / 内部 varexternal/global/temp 不是字段
//(VAR_TEMP 不持久,每次调用重新初始化,走帧寄存器)
if (b.section == VarSection::External ||
b.section == VarSection::Global) {
b.section == VarSection::Global ||
b.section == VarSection::Temp) {
continue;
}
for (const VarDecl& d : b.vars) {
@@ -331,9 +338,10 @@ namespace {
/**
* @brief 建一个 POU 的局部符号
* @details VAR/INPUT/OUTPUT → 对应种类;VAR_EXTERNAL → 查全局表接同一槽
* (类型必须一致);FB 类型 → FbInstance + 布局(内建取冻结表,
* 用户类型查 fb_types);POU 内 VAR_GLOBAL → 拒绝
* @details VAR/INPUT/OUTPUT → 对应种类;VAR_TEMP → Local(帧寄存器,
* 不持久);VAR_EXTERNAL → 查全局表接同一槽(类型必须一致);
* FB 类型 → FbInstance + 布局(内建取冻结表,用户类型查 fb_types);
* POU 内 VAR_GLOBAL → 拒绝
* @param file 出错文件
* @param p POU AST
* @param sc 输出作用域(syms / fb_instances 被填充)