Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -250,6 +250,8 @@ HelpText<"Specify name of main file output to quote in depfile">; def MT : JoinedOrSeparate<["-"], "MT">, Group, Flags<[CC1Option]>, HelpText<"Specify name of main file output in depfile">; +def MV : Flag<["-"], "MV">, Group, Flags<[CC1Option]>, + HelpText<"Use double-quotes to escape special characters in depfile">; def Mach : Flag<["-"], "Mach">; def O0 : Flag<["-"], "O0">, Group, Flags<[CC1Option]>; def O4 : Flag<["-"], "O4">, Group, Flags<[CC1Option]>; Index: include/clang/Frontend/DependencyOutputOptions.h =================================================================== --- include/clang/Frontend/DependencyOutputOptions.h +++ include/clang/Frontend/DependencyOutputOptions.h @@ -27,7 +27,9 @@ unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info. unsigned IncludeModuleFiles : 1; ///< Include module file dependencies. - + unsigned UseDoubleQuotes : 1; ///< Use double-quotes to escape special + /// characters in the dependency file. + /// The file to write dependency output to. std::string OutputFile; @@ -55,6 +57,7 @@ AddMissingHeaderDeps = 0; PrintShowIncludes = 0; IncludeModuleFiles = 0; + UseDoubleQuotes = 0; } }; Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -338,6 +338,7 @@ } Args.AddLastArg(CmdArgs, options::OPT_MP); + Args.AddLastArg(CmdArgs, options::OPT_MV); // Convert all -MQ args to -MT for (arg_iterator it = Args.filtered_begin(options::OPT_MT, Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -661,6 +661,7 @@ Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot); Opts.ModuleDependencyOutputDir = Args.getLastArgValue(OPT_module_dependency_dir); + Opts.UseDoubleQuotes = Args.hasArg(OPT_MV); } bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args, Index: lib/Frontend/DependencyFile.cpp =================================================================== --- lib/Frontend/DependencyFile.cpp +++ lib/Frontend/DependencyFile.cpp @@ -150,6 +150,7 @@ bool AddMissingHeaderDeps; bool SeenMissingHeader; bool IncludeModuleFiles; + bool UseDoubleQuotes; private: bool FileMatchesDepCriteria(const char *Filename, SrcMgr::CharacteristicKind FileType); @@ -162,7 +163,8 @@ PhonyTarget(Opts.UsePhonyTargets), AddMissingHeaderDeps(Opts.AddMissingHeaderDeps), SeenMissingHeader(false), - IncludeModuleFiles(Opts.IncludeModuleFiles) {} + IncludeModuleFiles(Opts.IncludeModuleFiles), + UseDoubleQuotes(Opts.UseDoubleQuotes) {} void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, @@ -290,8 +292,17 @@ } /// PrintFilename - GCC escapes spaces, # and $, but apparently not ' or " or -/// other scary characters. -static void PrintFilename(raw_ostream &OS, StringRef Filename) { +/// other scary characters. Jom wants these wrapped in double-quotes. +static void PrintFilename(raw_ostream &OS, StringRef Filename, + bool UseDoubleQuotes) { + if (UseDoubleQuotes) { + // Add quotes only if needed. + if (Filename.find_first_of(" #$") != StringRef::npos) + OS << '\"' << Filename << '\"'; + else + OS << Filename; + return; + } for (unsigned i = 0, e = Filename.size(); i != e; ++i) { if (Filename[i] == ' ' || Filename[i] == '#') OS << '\\'; @@ -354,7 +365,7 @@ Columns = 2; } OS << ' '; - PrintFilename(OS, *I); + PrintFilename(OS, *I, UseDoubleQuotes); Columns += N + 1; } OS << '\n'; @@ -365,7 +376,7 @@ for (std::vector::iterator I = Files.begin() + 1, E = Files.end(); I != E; ++I) { OS << '\n'; - PrintFilename(OS, *I); + PrintFilename(OS, *I, UseDoubleQuotes); OS << ":\n"; } } Index: test/Frontend/dependency-gen-escaping.c =================================================================== --- test/Frontend/dependency-gen-escaping.c +++ test/Frontend/dependency-gen-escaping.c @@ -4,13 +4,22 @@ // RUN: echo > '%t.dir/ .h' // RUN: echo > '%t.dir/$$.h' // RUN: echo > '%t.dir/##.h' +// RUN: echo > '%t.dir/normal.h' // RUN: cd %t.dir // RUN: %clang -MD -MF - %s -fsyntax-only -I. | FileCheck -strict-whitespace %s +// RUN: %clang -MD -MF - -MV %s -fsyntax-only -I. | FileCheck -strict-whitespace %s --check-prefix=QUOTE // CHECK: \ \ \ \ .h // CHECK: $$$$.h // CHECK: \#\#.h +// QUOTE: " .h" +// QUOTE: "$$.h" +// QUOTE: "##.h" +// QUOTE-NOT: " +// QUOTE: normal.h +// QUOTE-NOT: " #include " .h" #include "$$.h" #include "##.h" +#include "normal.h"