From 4e0bf1b76aebbf7b86f3445960d7402925fd0ae6 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Fri, 20 May 2022 09:50:15 -0700 Subject: [PATCH] ImportC add Windows cl preprocessor #define support --- src/dmd/cparse.d | 9 +++- src/dmd/link.d | 51 ++++++++++++++----- .../{testdefines.c => imports/defines.c} | 2 +- test/compilable/testdefines.d | 4 ++ 4 files changed, 51 insertions(+), 15 deletions(-) rename test/compilable/{testdefines.c => imports/defines.c} (59%) create mode 100644 test/compilable/testdefines.d diff --git a/src/dmd/cparse.d b/src/dmd/cparse.d index 8bcd35e1b621..344933ace83c 100644 --- a/src/dmd/cparse.d +++ b/src/dmd/cparse.d @@ -5156,6 +5156,11 @@ final class CParser(AST) : Parser!AST { auto id = n.ident; scan(&n); + if (n.value == TOK.endOfLine) // #define identifier + { + nextDefineLine(); + continue; + } if (n.value == TOK.int32Literal) { const value = n.intvalue; @@ -5168,12 +5173,14 @@ final class CParser(AST) : Parser!AST AST.Expression e = new AST.IntegerExp(scanloc, value, AST.Type.tint32); auto v = new AST.VarDeclaration(scanloc, AST.Type.tint32, id, new AST.ExpInitializer(scanloc, e), STC.manifest); symbols.push(v); + nextDefineLine(); + continue; } } } skipToNextLine(); } - else + else if (n.value != TOK.endOfLine) { skipToNextLine(); } diff --git a/src/dmd/link.d b/src/dmd/link.d index 020505b771d3..0968d7b0d7ae 100644 --- a/src/dmd/link.d +++ b/src/dmd/link.d @@ -1058,7 +1058,7 @@ public int runPreprocessor(const(char)[] cpp, const(char)[] filename, const(char */ OutBuffer buf; buf.writestring(cpp); - buf.printf(" /P /nologo %.*s /FI%s /Fi%.*s", + buf.printf(" /P /Zc:preprocessor /PD /nologo %.*s /FI%s /Fi%.*s", cast(int)filename.length, filename.ptr, importc_h, cast(int)output.length, output.ptr); /* Append preprocessor switches to command line @@ -1077,24 +1077,46 @@ public int runPreprocessor(const(char)[] cpp, const(char)[] filename, const(char ubyte[2048] buffer = void; - bool firstLine = true; + OutBuffer linebuf; // each line from stdout + bool print = false; // print line collected from stdout + + /* Collect text captured from stdout to linebuf[]. + * Then decide to print or discard the contents. + * Discarding lines that consist only of a filename is necessary to pass + * the D test suite which diffs the output. CL's emission of filenames cannot + * be turned off. + */ void sink(ubyte[] data) { - if (firstLine) + foreach (c; data) { - for (size_t i = 0; 1; ++i) + switch (c) { - if (i == data.length) - return; - if (data[i] == '\n') // reached end of first line - { - data = data[i + 1 .. data.length]; - firstLine = false; + case '\r': + break; + + case '\n': + if (print) + printf("%s\n", linebuf.peekChars()); + + // set up for next line + linebuf.setsize(0); + print = false; + break; + + case '\t': + case ';': + case '(': + case '\'': + case '"': // various non-filename characters + print = true; // mean it's not a filename + goto default; + + default: + linebuf.writeByte(c); break; - } } } - printf("%.*s", cast(int)data.length, data.ptr); } // Convert command to wchar @@ -1103,7 +1125,10 @@ public int runPreprocessor(const(char)[] cpp, const(char)[] filename, const(char auto szCommand = toWStringz(buf.peekChars()[0 .. buf.length], smbuf); int exitCode = runProcessCollectStdout(szCommand.ptr, buffer[], &sink); - printf("\n"); + + if (linebuf.length && print) // anything leftover from stdout collection + printf("%s\n", defines.peekChars()); + return exitCode; } else diff --git a/test/compilable/testdefines.c b/test/compilable/imports/defines.c similarity index 59% rename from test/compilable/testdefines.c rename to test/compilable/imports/defines.c index 0e54447e758a..f5bd6971375d 100644 --- a/test/compilable/testdefines.c +++ b/test/compilable/imports/defines.c @@ -1,3 +1,3 @@ -// DISABLED: win64 win32mscoff +/* */ #define GHI 3 _Static_assert(GHI == 3, "1"); diff --git a/test/compilable/testdefines.d b/test/compilable/testdefines.d new file mode 100644 index 000000000000..fad20002f989 --- /dev/null +++ b/test/compilable/testdefines.d @@ -0,0 +1,4 @@ +// EXTRA_FILES: imports/defines.c +import imports.defines; + +static assert(GHI == 3);