diff --git a/llvm/test/tools/llvm-rc/windres-preproc.test b/llvm/test/tools/llvm-rc/windres-preproc.test --- a/llvm/test/tools/llvm-rc/windres-preproc.test +++ b/llvm/test/tools/llvm-rc/windres-preproc.test @@ -4,6 +4,7 @@ ; REQUIRES: shell ; RUN: llvm-windres -### --include-dir %p/incdir1 --include %p/incdir2 "-DFOO1=\\\"foo bar\\\"" -UFOO2 -D FOO3 --preprocessor-arg "-DFOO4=\\\"baz baz\\\"" -DFOO5=\"bar\" %p/Inputs/empty.rc %t.res | FileCheck %s --check-prefix=CHECK1 +; RUN: llvm-windres -### --include-dir %p/incdir1 --include %p/incdir2 "-DFOO1=\"foo bar\"" -UFOO2 -D FOO3 --preprocessor-arg "-DFOO4=\"baz baz\"" "-DFOO5=bar" %p/Inputs/empty.rc %t.res --use-temp-file | FileCheck %s --check-prefix=CHECK1 ; CHECK1: {{^}} "clang" "--driver-mode=gcc" "-target" "{{.*}}-{{.*}}{{mingw32|windows-gnu}}" "-E" "-xc" "-DRC_INVOKED" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc" "-I" "{{.*}}incdir1" "-I" "{{.*}}incdir2" "-D" "FOO1=\"foo bar\"" "-U" "FOO2" "-D" "FOO3" "-DFOO4=\"baz baz\"" "-D" "FOO5=bar"{{$}} ; RUN: llvm-windres -### --preprocessor "i686-w64-mingw32-gcc -E -DFOO=\\\"foo\\ bar\\\"" %p/Inputs/empty.rc %t.res | FileCheck %s --check-prefix=CHECK2 ; CHECK2: {{^}} "i686-w64-mingw32-gcc" "-E" "-DFOO=\"foo bar\"" "{{.*}}empty.rc" "-o" "{{.*}}preproc-{{.*}}.rc"{{$}} diff --git a/llvm/tools/llvm-rc/WindresOpts.td b/llvm/tools/llvm-rc/WindresOpts.td --- a/llvm/tools/llvm-rc/WindresOpts.td +++ b/llvm/tools/llvm-rc/WindresOpts.td @@ -48,6 +48,10 @@ defm language : LongShort<"l", "language", "Default language to use (0x0-0xffff)">; +def use_temp_file: Flag<["--"], "use-temp-file">, + HelpText<"Mimic GNU windres preprocessor option handling " + "(don't unescape preprocessor options)">; + defm verbose : F<"v", "verbose", "Enable verbose output">; defm version : F<"V", "version", "Display version">; @@ -57,6 +61,3 @@ def _HASH_HASH_HASH : Flag<["-"], "###">; def no_preprocess : Flag<["--"], "no-preprocess">; - -// Unimplemented options for compatibility -def use_temp_file: Flag<["--"], "use-temp-file">; diff --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp --- a/llvm/tools/llvm-rc/llvm-rc.cpp +++ b/llvm/tools/llvm-rc/llvm-rc.cpp @@ -461,7 +461,14 @@ // done this double escaping) probably is confined to cases like these // quoted string defines, and those happen to work the same across unix // and windows. - std::string Unescaped = unescape(Arg->getValue()); + // + // If GNU windres is executed with --use-temp-file, it doesn't use + // popen() to invoke the preprocessor, but uses another function which + // actually preserves tricky characters better. To mimic this behaviour, + // don't unescape arguments here. + std::string Value = Arg->getValue(); + if (!InputArgs.hasArg(WINDRES_use_temp_file)) + Value = unescape(Value); switch (Arg->getOption().getID()) { case WINDRES_include_dir: // Technically, these are handled the same way as e.g. defines, but @@ -475,17 +482,19 @@ break; case WINDRES_define: Opts.PreprocessArgs.push_back("-D"); - Opts.PreprocessArgs.push_back(Unescaped); + Opts.PreprocessArgs.push_back(Value); break; case WINDRES_undef: Opts.PreprocessArgs.push_back("-U"); - Opts.PreprocessArgs.push_back(Unescaped); + Opts.PreprocessArgs.push_back(Value); break; case WINDRES_preprocessor_arg: - Opts.PreprocessArgs.push_back(Unescaped); + Opts.PreprocessArgs.push_back(Value); break; } } + // TODO: If --use-temp-file is set, we shouldn't be unescaping + // the --preprocessor argument either, only splitting it. if (InputArgs.hasArg(WINDRES_preprocessor)) Opts.PreprocessCmd = unescapeSplit(InputArgs.getLastArgValue(WINDRES_preprocessor));