Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/include/clang/Frontend/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ class DependencyFileGenerator : public DependencyCollector {
void outputDependencyFile(llvm::raw_ostream &OS);

private:
void outputDependencyFilename(llvm::raw_ostream &OS,
StringRef Filename) const;

void outputDependencyFile(DiagnosticsEngine &Diags);

std::string OutputFile;
Expand All @@ -128,6 +131,7 @@ class DependencyFileGenerator : public DependencyCollector {
bool SeenMissingHeader;
bool IncludeModuleFiles;
DependencyOutputFormat OutputFormat;
bool MSCompatible;
unsigned InputFileIndex;
};

Expand Down
25 changes: 18 additions & 7 deletions clang/lib/Frontend/DependencyFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ DependencyFileGenerator::DependencyFileGenerator(
PhonyTarget(Opts.UsePhonyTargets),
AddMissingHeaderDeps(Opts.AddMissingHeaderDeps), SeenMissingHeader(false),
IncludeModuleFiles(Opts.IncludeModuleFiles),
OutputFormat(Opts.OutputFormat), InputFileIndex(0) {
OutputFormat(Opts.OutputFormat), MSCompatible(false), InputFileIndex(0) {
for (const auto &ExtraDep : Opts.ExtraDeps) {
if (addDependency(ExtraDep.first))
++InputFileIndex;
Expand All @@ -235,6 +235,8 @@ void DependencyFileGenerator::attachToPreprocessor(Preprocessor &PP) {
if (AddMissingHeaderDeps)
PP.SetSuppressIncludeNotFoundError(true);

MSCompatible = PP.getLangOpts().MicrosoftExt;

DependencyCollector::attachToPreprocessor(PP);
}

Expand Down Expand Up @@ -312,11 +314,20 @@ void DependencyFileGenerator::finishedMainFile(DiagnosticsEngine &Diags) {
/// https://msdn.microsoft.com/en-us/library/dd9y37ha.aspx for NMake info,
/// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
/// for Windows file-naming info.
static void PrintFilename(raw_ostream &OS, StringRef Filename,
DependencyOutputFormat OutputFormat) {
// Convert filename to platform native path
///
/// Whether backslashes in the filename are treated as path separators or
/// ordinary characters depends on whether the Clang invocation is MS-compatible
/// (-fms-compatibility). If it is, backslashes are treated as path separators,
/// and are converted to the native path separator (backslash on Windows,
/// forward slash on other platforms); if not, backslashes are treated as
/// ordinary characters, and are not converted.
void DependencyFileGenerator::outputDependencyFilename(
raw_ostream &OS, StringRef Filename) const {
llvm::SmallString<256> NativePath;
llvm::sys::path::native(Filename.str(), NativePath);
if (MSCompatible)
llvm::sys::path::native(Filename.str(), NativePath);
else
NativePath = Filename;

if (OutputFormat == DependencyOutputFormat::NMake) {
// Add quotes if needed. These are the characters listed as "special" to
Expand Down Expand Up @@ -400,7 +411,7 @@ void DependencyFileGenerator::outputDependencyFile(llvm::raw_ostream &OS) {
Columns = 2;
}
OS << ' ';
PrintFilename(OS, File, OutputFormat);
outputDependencyFilename(OS, File);
Columns += N + 1;
}
OS << '\n';
Expand All @@ -411,7 +422,7 @@ void DependencyFileGenerator::outputDependencyFile(llvm::raw_ostream &OS) {
for (auto I = Files.begin(), E = Files.end(); I != E; ++I) {
if (Index++ == InputFileIndex)
continue;
PrintFilename(OS, *I, OutputFormat);
outputDependencyFilename(OS, *I);
OS << ":\n";
}
}
Expand Down
17 changes: 17 additions & 0 deletions clang/test/Frontend/dependency-gen-posix-ms-compatible.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// REQUIRES: !system-windows
// RUN: rm -rf %t.dir
// RUN: mkdir -p %t.dir/include/foo
// RUN: echo > %t.dir/include/foo/bar.h
// RUN: echo > %t.dir/include/foo\\bar.h

// RUN: %clang -MD -MF - %s -fsyntax-only -fms-compatibility -I %t.dir/include | FileCheck -check-prefix=CHECK-ONE %s
// CHECK-ONE: foo/bar.h
// CHECK-ONE-NOT: foo\bar.h
// CHECK-ONE-NOT: foo\\bar.h

// RUN: %clang -MD -MF - %s -fsyntax-only -fno-ms-compatibility -I %t.dir/include | FileCheck -check-prefix=CHECK-TWO %s
// CHECK-TWO: foo\bar.h
// CHECK-TWO-NOT: foo/bar.h
// CHECK-TWO-NOT: foo\\bar.h

#include "foo\bar.h"