mirror of
https://github.com/golang/go
synced 2024-11-23 20:00:04 -07:00
cmd/asm: fix handling of nested #if[n]defs
The lexer needs to process all #if[n]defs, even those found when processing is disabled by a preceding failed conditional, or the first #endif in something like: #ifdef <undefined> #ifdef whatever #endif #endif terminates the first #ifdef and the second causes an error. And then the processing of the inner #ifdefs needs to ignore their argument when they are disabled by an outer failed condition. Change-Id: Iba259498f1e16042f5b7580b9c000bb0599733d0 Reviewed-on: https://go-review.googlesource.com/14253 Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
13e06d89c3
commit
eaea5ade2b
@ -136,10 +136,11 @@ func (in *Input) hash() bool {
|
|||||||
in.expectText("expected identifier after '#'")
|
in.expectText("expected identifier after '#'")
|
||||||
}
|
}
|
||||||
if !in.enabled() {
|
if !in.enabled() {
|
||||||
// Can only start including again if we are at #else or #endif.
|
// Can only start including again if we are at #else or #endif but also
|
||||||
|
// need to keep track of nested #if[n]defs.
|
||||||
// We let #line through because it might affect errors.
|
// We let #line through because it might affect errors.
|
||||||
switch in.Stack.Text() {
|
switch in.Stack.Text() {
|
||||||
case "else", "endif", "line":
|
case "else", "endif", "ifdef", "ifndef", "line":
|
||||||
// Press on.
|
// Press on.
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
@ -360,7 +361,9 @@ func (in *Input) collectArgument(macro *Macro) ([]Token, ScanToken) {
|
|||||||
func (in *Input) ifdef(truth bool) {
|
func (in *Input) ifdef(truth bool) {
|
||||||
name := in.macroName()
|
name := in.macroName()
|
||||||
in.expectNewline("#if[n]def")
|
in.expectNewline("#if[n]def")
|
||||||
if _, defined := in.macros[name]; !defined {
|
if !in.enabled() {
|
||||||
|
truth = false
|
||||||
|
} else if _, defined := in.macros[name]; !defined {
|
||||||
truth = !truth
|
truth = !truth
|
||||||
}
|
}
|
||||||
in.ifdefStack = append(in.ifdefStack, truth)
|
in.ifdefStack = append(in.ifdefStack, truth)
|
||||||
@ -372,7 +375,9 @@ func (in *Input) else_() {
|
|||||||
if len(in.ifdefStack) == 0 {
|
if len(in.ifdefStack) == 0 {
|
||||||
in.Error("unmatched #else")
|
in.Error("unmatched #else")
|
||||||
}
|
}
|
||||||
in.ifdefStack[len(in.ifdefStack)-1] = !in.ifdefStack[len(in.ifdefStack)-1]
|
if len(in.ifdefStack) == 1 || in.ifdefStack[len(in.ifdefStack)-2] {
|
||||||
|
in.ifdefStack[len(in.ifdefStack)-1] = !in.ifdefStack[len(in.ifdefStack)-1]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// #endif processing.
|
// #endif processing.
|
||||||
|
@ -120,6 +120,112 @@ var lexTests = []lexTest{
|
|||||||
),
|
),
|
||||||
"\n.MOVBLZX.(.BP.).(.DX.*.4.).,.R8.\n.\n.MOVBLZX.(.(.8.+.1.).*.4.).(.R12.).,.BX.\n.ADDB.BX.,.DX.\n.MOVB.R8.,.(.8.*.4.).(.R12.).\n.PINSRW.$.0.,.(.BP.).(.R8.*.4.).,.X0.\n",
|
"\n.MOVBLZX.(.BP.).(.DX.*.4.).,.R8.\n.\n.MOVBLZX.(.(.8.+.1.).*.4.).(.R12.).,.BX.\n.ADDB.BX.,.DX.\n.MOVB.R8.,.(.8.*.4.).(.R12.).\n.PINSRW.$.0.,.(.BP.).(.R8.*.4.).,.X0.\n",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"taken #ifdef",
|
||||||
|
lines(
|
||||||
|
"#define A",
|
||||||
|
"#ifdef A",
|
||||||
|
"#define B 1234",
|
||||||
|
"#endif",
|
||||||
|
"B",
|
||||||
|
),
|
||||||
|
"1234.\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"not taken #ifdef",
|
||||||
|
lines(
|
||||||
|
"#ifdef A",
|
||||||
|
"#define B 1234",
|
||||||
|
"#endif",
|
||||||
|
"B",
|
||||||
|
),
|
||||||
|
"B.\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"taken #ifdef with else",
|
||||||
|
lines(
|
||||||
|
"#define A",
|
||||||
|
"#ifdef A",
|
||||||
|
"#define B 1234",
|
||||||
|
"#else",
|
||||||
|
"#define B 5678",
|
||||||
|
"#endif",
|
||||||
|
"B",
|
||||||
|
),
|
||||||
|
"1234.\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"not taken #ifdef with else",
|
||||||
|
lines(
|
||||||
|
"#ifdef A",
|
||||||
|
"#define B 1234",
|
||||||
|
"#else",
|
||||||
|
"#define B 5678",
|
||||||
|
"#endif",
|
||||||
|
"B",
|
||||||
|
),
|
||||||
|
"5678.\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nested taken/taken #ifdef",
|
||||||
|
lines(
|
||||||
|
"#define A",
|
||||||
|
"#define B",
|
||||||
|
"#ifdef A",
|
||||||
|
"#ifdef B",
|
||||||
|
"#define C 1234",
|
||||||
|
"#else",
|
||||||
|
"#define C 5678",
|
||||||
|
"#endif",
|
||||||
|
"#endif",
|
||||||
|
"C",
|
||||||
|
),
|
||||||
|
"1234.\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nested taken/not-taken #ifdef",
|
||||||
|
lines(
|
||||||
|
"#define A",
|
||||||
|
"#ifdef A",
|
||||||
|
"#ifdef B",
|
||||||
|
"#define C 1234",
|
||||||
|
"#else",
|
||||||
|
"#define C 5678",
|
||||||
|
"#endif",
|
||||||
|
"#endif",
|
||||||
|
"C",
|
||||||
|
),
|
||||||
|
"5678.\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nested not-taken/would-be-taken #ifdef",
|
||||||
|
lines(
|
||||||
|
"#define B",
|
||||||
|
"#ifdef A",
|
||||||
|
"#ifdef B",
|
||||||
|
"#define C 1234",
|
||||||
|
"#else",
|
||||||
|
"#define C 5678",
|
||||||
|
"#endif",
|
||||||
|
"#endif",
|
||||||
|
"C",
|
||||||
|
),
|
||||||
|
"C.\n",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nested not-taken/not-taken #ifdef",
|
||||||
|
lines(
|
||||||
|
"#ifdef A",
|
||||||
|
"#ifdef B",
|
||||||
|
"#define C 1234",
|
||||||
|
"#else",
|
||||||
|
"#define C 5678",
|
||||||
|
"#endif",
|
||||||
|
"#endif",
|
||||||
|
"C",
|
||||||
|
),
|
||||||
|
"C.\n",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLex(t *testing.T) {
|
func TestLex(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user