From 3893db1346f09289bead91bb48932e8b0aaed4ac Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 15 Feb 2022 20:50:02 -0600 Subject: [PATCH] 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.) --- Parser.pas | 40 ++++++++++++++++++++-------------------- Scanner.pas | 44 +++++++++++++++++++++++--------------------- cc.notes | 4 ++++ 3 files changed, 47 insertions(+), 41 deletions(-) diff --git a/Parser.pas b/Parser.pas index 1ddf764..a2ce419 100644 --- a/Parser.pas +++ b/Parser.pas @@ -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; diff --git a/Scanner.pas b/Scanner.pas index 9aed3d7..09bb1f0 100644 --- a/Scanner.pas +++ b/Scanner.pas @@ -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} diff --git a/cc.notes b/cc.notes index 510a4e6..d77b90e 100644 --- a/cc.notes +++ b/cc.notes @@ -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.