From 3f81a4902a985f09050289669233fca3ffa44572 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Tue, 3 Feb 2026 08:11:53 -0500 Subject: [PATCH] BaseTools/VfrCompile: Add #pragma once support The C preprocessor turns each .vfr file into a pre-processed .i file. At this step, the C preprocessor processes `#pragma once`. Then, VfrCompile is called (with `-n` to prevent preprocessing) to parse the pre-processed .i files. The .i files may still contain `#pragma once` lines. Currently, VfrCompile treats `once` as an unknown token, causing parse failures. Originally, this change was going to add a `PragmaOnce` token rule to the VFR lexer grammar (in VfrSyntax.g) that matched `#pragma once` lines and silently skipped them using `skip()` and `newline()`. The `newline()` call would keep line numbers stable for error reporting. This was consistent with how other preprocessor artifacts were already handled like `#line` directives (`LineDefinition` and `GccLineDefinition` tokens) and `extern` declarations (skipped with `mode(CPP_COMMENT)`). Writing a regular expression to match `#pragma once` was simple enough, but it makes overall pragma token recognition more fragile at the lexer level. When the lexer is walking the DFA state table, it could begin to match a `#pragma ` line but then not be able to match remaining characters to recognize tokens other than `once`. Instead, this change handles `#pragma once` lines in the VFR parser grammar in `vfrPragmaDefinition` alongside where `pack` is already handled. Signed-off-by: Michael Kubacki --- BaseTools/Source/C/VfrCompile/VfrSyntax.g | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/BaseTools/Source/C/VfrCompile/VfrSyntax.g b/BaseTools/Source/C/VfrCompile/VfrSyntax.g index 433a4e8200..27e8198f78 100644 --- a/BaseTools/Source/C/VfrCompile/VfrSyntax.g +++ b/BaseTools/Source/C/VfrCompile/VfrSyntax.g @@ -267,7 +267,7 @@ vfrProgram > [UINT8 Return] : mConstantOnlyInExpression = FALSE; >> ( - vfrPragmaPackDefinition + vfrPragmaDefinition | vfrDataStructDefinition | vfrDataUnionDefinition )* @@ -308,14 +308,18 @@ pragmaPackNumber : << gCVfrVarDataTypeDB.Pack (LineNum, VFR_PACK_ASSIGN, NULL, PackNumber); >> ; -vfrPragmaPackDefinition : - "\#pragma" "pack" "\(" - { - pragmaPackShowDef - | pragmaPackStackDef - | pragmaPackNumber - } - "\)" +vfrPragmaDefinition : + "\#pragma" + ( + "pack" "\(" + { + pragmaPackShowDef + | pragmaPackStackDef + | pragmaPackNumber + } + "\)" + | "once" // Skip '#pragma once' in preprocessed output + ) ; vfrDataUnionDefinition :