Make sure #pragma expand is properly applied in all cases.

There were various places where the flag for macro expansions was saved, set to false, and then later restored. If #pragma expand was used within those areas, it would not be properly applied. Here is an example showing that problem:

void f(void
#pragma expand 1
) {}

This could also affect some uses of #pragma expand within precompiled headers, e.g.:

#pragma expand 1
#include "a.h"
#undef foobar
#include "b.h"
...

Also, add a note saying that code in precompiled headers will not be expanded. (This has always been the case, but was not clearly documented.)
This commit is contained in:
Stephen Heumann 2022-02-15 20:50:02 -06:00
parent 8c0d65616c
commit 3893db1346
3 changed files with 47 additions and 41 deletions

View File

@ -436,7 +436,7 @@ label 1;
var
lToken,tToken: tokenType; {for look-ahead}
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
function GetSwitchRecord: statementPtr;
@ -981,14 +981,14 @@ case token.kind of
gotosy: GotoStatement;
typedef,
ident: begin
lPrintMacroExpansions := printMacroExpansions;
printMacroExpansions := false;
lSuppressMacroExpansions := suppressMacroExpansions;
suppressMacroExpansions := true;
lToken := token;
NextToken;
tToken := token;
PutBackToken(token, true);
token := lToken;
printMacroExpansions := lPrintMacroExpansions;
suppressMacroExpansions := lSuppressMacroExpansions;
if tToken.kind = colonch then begin
LabelStatement;
goto 1;
@ -1099,7 +1099,7 @@ var
ltoken: tokenType; {for putting ; on stack}
stPtr: statementPtr; {work pointer}
tl,tk: tokenStackPtr; {for forming expression list}
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
begin {EndForStatement}
if c99Scope then PopTable;
@ -1118,13 +1118,13 @@ if tl <> nil then begin
tl := tl^.next;
dispose(tk);
end; {while}
lPrintMacroExpansions := printMacroExpansions; {inhibit token echo}
printMacroExpansions := false;
lSuppressMacroExpansions := suppressMacroExpansions; {inhibit token echo}
suppressMacroExpansions := true;
NextToken; {evaluate the expression}
Expression(normalExpression, [semicolonch]);
Gen0t(pc_pop, UsualUnaryConversions);
NextToken; {skip the semicolon}
printMacroExpansions := lPrintMacroExpansions;
suppressMacroExpansions := lSuppressMacroExpansions;
end; {if}
Gen1(pc_ujp, stPtr^.forLoop); {loop to the test}
@ -1329,7 +1329,7 @@ var
lstorageClass: tokenEnum; {storage class of the declaration}
ltypeSpec: typePtr; {type specifier}
luseGlobalPool: boolean; {local copy of useGlobalPool}
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
lSuppressMacroExpansions: boolean;{local copy of suppressMacroExpansions}
begin {StackDeclarations}
lastWasIdentifier := false; {used to see if the declaration is a fn}
@ -1458,10 +1458,10 @@ var
if token.symbolPtr^.itype^.baseType = cgVoid then
isVoid := true;
if isVoid then begin {check for a void prototype}
lPrintMacroExpansions := printMacroExpansions;
printMacroExpansions := false;
lSuppressMacroExpansions := suppressMacroExpansions;
suppressMacroExpansions := true;
NextToken;
printMacroExpansions := lPrintMacroExpansions;
suppressMacroExpansions := lSuppressMacroExpansions;
if token.kind = rparench then begin
PutBackToken(token, false);
NextToken;
@ -2392,7 +2392,7 @@ var
ip: identPtr; {for tracing field lists}
kind: typeKind; {base type of an initializer}
ktp: typePtr; {array type with definedTypes removed}
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
lSuppressMacroExpansions: boolean;{local copy of suppressMacroExpansions}
stringElementType: typePtr; {element type of string literal}
stringLength: integer; {elements in a string literal}
@ -2618,12 +2618,12 @@ var
count := tp^.size;
ip := tp^.fieldList;
bitCount := 0;
lPrintMacroExpansions := printMacroExpansions;
lSuppressMacroExpansions := suppressMacroExpansions;
while (ip <> nil) and (ip^.itype^.size > 0) do begin
if ip^.isForwardDeclared then
ResolveForwardReference(ip);
if token.kind = rbracech then begin {initialize this field to 0}
printMacroExpansions := false; {inhibit token echo}
suppressMacroExpansions := true; {inhibit token echo}
PutBackToken(token, false);
PutBackToken(token, false);
token.kind := intconst;
@ -2672,7 +2672,7 @@ var
if count > 0 then
if variable^.storage in [external,global,private] then
Fill(count, sCharPtr);
printMacroExpansions := lPrintMacroExpansions;
suppressMacroExpansions := lSuppressMacroExpansions;
end {if}
else {struct/union assignment initializer}
GetInitializerValue(tp, bitsize, bitdisp);
@ -4245,7 +4245,7 @@ var
lToken: tokenType; {temporary copy of old token}
nToken: tokenType; {new token}
hasStatementNext: boolean; {is a stmt next within a compound stmt?}
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
begin {DoStatement}
case statementList^.kind of
@ -4264,10 +4264,10 @@ case statementList^.kind of
DoDeclaration(false)
else begin
lToken := token;
lPrintMacroExpansions := printMacroExpansions; {inhibit token echo}
printMacroExpansions := false;
lSuppressMacroExpansions := suppressMacroExpansions;
suppressMacroExpansions := true; {inhibit token echo}
NextToken;
printMacroExpansions := lPrintMacroExpansions;
suppressMacroExpansions := lSuppressMacroExpansions;
nToken := token;
PutBackToken(nToken, false);
token := lToken;

View File

@ -77,6 +77,7 @@ var
macros: ^macroTable; {preprocessor macro list}
pathList: pathRecordPtr; {additional search paths}
printMacroExpansions: boolean; {print the token list?}
suppressMacroExpansions: boolean; {suppress printing even if requested?}
reportEOL: boolean; {report eolsy as a token?}
token: tokenType; {next token to process}
@ -1098,7 +1099,7 @@ while mPtr <> nil do begin
FindMacro := mPtr
else if tokenList = nil then begin
while charKinds[ord(ch)] in [ch_white, ch_eol] do begin
if printMacroExpansions then
if printMacroExpansions and not suppressMacroExpansions then
if charKinds[ord(ch)] = ch_eol then
writeln
else
@ -1559,7 +1560,7 @@ var
i: integer; {loop counter}
inhibit: boolean; {inhibit parameter expansion?}
lexpandMacros: boolean; {local copy of expandMacros}
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
mPtr: macroRecordPtr; {for checking list of macros}
newParm: parameterPtr; {for building a new parameter entry}
tlPtr, tPtr, tcPtr, lastPtr: tokenListRecordPtr; {work pointers}
@ -1573,8 +1574,8 @@ var
endParmTokens: tokenSet; {tokens that end a parameter}
begin {Expand}
lPrintMacroExpansions := printMacroExpansions; {inhibit token printing}
printMacroExpansions := false;
lSuppressMacroExpansions := suppressMacroExpansions; {inhibit token printing}
suppressMacroExpansions := true;
lexpandMacros := expandMacros; {prevent expansion of parameters}
expandMacros := false;
saveNumber := true; {save numeric strings}
@ -1859,7 +1860,7 @@ while parms <> nil do begin {dispose of the parameter list}
parms := parmEnd;
end; {while}
expandMacros := lexpandMacros; {restore the flags}
printMacroExpansions := lPrintMacroExpansions;
suppressMacroExpansions := lSuppressMacroExpansions;
saveNumber := false; {stop saving numeric strings}
end; {Expand}
@ -2202,7 +2203,7 @@ procedure PreProcess;
label 2;
var
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
lReportEOL: boolean; {local copy of reportEOL}
tSkipping: boolean; {temp copy of the skipping variable}
val: integer; {expression value}
@ -2990,8 +2991,8 @@ var
begin {PreProcess}
lPrintMacroExpansions := printMacroExpansions; {inhibit token printing}
printMacroExpansions := false;
lSuppressMacroExpansions := suppressMacroExpansions; {inhibit token printing}
suppressMacroExpansions := true;
lReportEOL := reportEOL; {we need to see eol's}
reportEOL := true;
tSkipping := skipping; {don't skip the directive name!}
@ -3153,7 +3154,7 @@ if ch in ['a','d','e','i','l','p','u','w'] then begin
else if token.name^ = 'expand' then begin
FlagPragmas(p_expand);
NumericDirective;
lPrintMacroExpansions := expressionValue <> 0;
printMacroExpansions := expressionValue <> 0;
if token.kind <> eolsy then
Error(11);
end {else if}
@ -3349,7 +3350,7 @@ flagOverflows := true;
expandMacros := true;
charKinds[ord('#')] := illegal; {don't allow # as a token}
reportEOL := lReportEOL; {restore flags}
printMacroExpansions := lPrintMacroExpansions;
suppressMacroExpansions := lSuppressMacroExpansions;
skipping := tskipping;
if nextLineNumber >= 0 then
lineNumber := nextLineNumber;
@ -4082,6 +4083,7 @@ var
begin {InitScanner}
printMacroExpansions := false; {don't print the token list}
suppressMacroExpansions := false; {...but do not suppress token printing}
skipIllegalTokens := false; {flag illegal tokens in skipped code}
allowLongIntChar := false; {allow long int char constants}
allowTokensAfterEndif := false; {allow tokens after #endif}
@ -4420,7 +4422,7 @@ var
mPtr: macroRecordPtr; {for checking list of macros}
rword: tokenEnum; {loop variable}
sp: stringPtr; {for saving identifier names}
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
begin {CheckIdentifier}
if expandMacros then {handle macro expansions}
@ -4428,10 +4430,10 @@ if expandMacros then {handle macro expansions}
mPtr := FindMacro(@workstring);
if mPtr <> nil then begin
Expand(mPtr);
lPrintMacroExpansions := printMacroExpansions;
printMacroExpansions := false;
lSuppressMacroExpansions := suppressMacroExpansions;
suppressMacroExpansions := true;
NextToken;
printMacroExpansions := lPrintMacroExpansions;
suppressMacroExpansions := lSuppressMacroExpansions;
goto 1;
end;
end; {if}
@ -4487,7 +4489,7 @@ var
i,j: 0..maxint; {loop/index counter}
inhibit: boolean; {inhibit macro expansion?}
lExpandMacros: boolean; {local copy of expandMacros}
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
lSuppressMacroExpansions: boolean; {local copy of suppressMacroExpansions}
mPtr: macroRecordPtr; {for checking list of macros}
setLength: boolean; {is the current string a p-string?}
tPtr: tokenListRecordPtr; {for removing tokens from putback buffer}
@ -4805,7 +4807,7 @@ while charKinds[ord(ch)] in [illegal,ch_white,ch_eol] do begin
goto 2;
end {if}
else begin {skip white space}
if printMacroExpansions then
if printMacroExpansions and not suppressMacroExpansions then
if charKinds[ord(ch)] = ch_eol then begin
StopSpin;
writeln;
@ -5254,12 +5256,12 @@ if (token.kind = stringconst) and not mergingStrings {handle adjacent strings}
goto 1;
end; {if}
tToken := token;
lPrintMacroExpansions := printMacroExpansions;
printMacroExpansions := false;
lSuppressMacroExpansions := suppressMacroExpansions;
suppressMacroExpansions := true;
mergingStrings := true;
NextToken;
mergingStrings := false;
printMacroExpansions := lPrintMacroExpansions;
suppressMacroExpansions := lSuppressMacroExpansions;
if token.kind = stringconst then begin
Merge(tToken, token);
done := false;
@ -5280,8 +5282,8 @@ if doingPPExpression then begin
if token.kind = typedef then
token.kind := ident;
end; {if}
if printMacroExpansions then {print the token stream}
PrintToken(token);
if printMacroExpansions and not suppressMacroExpansions then
PrintToken(token); {print the token stream}
end; {NextToken}

View File

@ -185,6 +185,8 @@ p. 257
The #pragma expand directive has been changed to use three-digit octal escape sequences (rather than hexadecimal ones) in strings it outputs. (This ensures that subsequent characters in the string cannot be interpreted as part of the escape sequence.)
If precompiled headers are being used, #pragma expand will not print the tokens for the portion of the code that has been precompiled and represented in the .sym file. It will still print the tokens for the remainder of the code (including all functions). If you want to see the tokens for all of the code, you can use the -I flag to make ORCA/C ignore the .sym file.
p. 258
The #pragma ignore directive supports several new bits.
@ -1778,6 +1780,8 @@ int foo(int[42]);
180. Certain #undef directives might be ignored when using a .sym file.
181. #pragma expand might not work correctly when used in certain places.
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
1. In some situations, fread() reread the first 1K or so of the file.