phosek updated this revision to Diff 303567.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87928/new/

https://reviews.llvm.org/D87928

Files:
  clang/include/clang/Basic/CodeGenOptions.h
  clang/include/clang/Driver/Options.td
  clang/include/clang/Lex/PreprocessorOptions.h
  clang/lib/CodeGen/CoverageMappingGen.cpp
  clang/lib/CodeGen/CoverageMappingGen.h
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Lex/PPMacroExpansion.cpp
  clang/test/CoverageMapping/source_dir.c
  clang/test/Preprocessor/file_test.c
  llvm/include/llvm/Support/Path.h
  llvm/lib/Support/Path.cpp
  llvm/unittests/Support/Path.cpp

Index: llvm/unittests/Support/Path.cpp
===================================================================
--- llvm/unittests/Support/Path.cpp
+++ llvm/unittests/Support/Path.cpp
@@ -1547,6 +1547,35 @@
   EXPECT_EQ(Path, "C:\\old/foo\\bar");
 }
 
+static std::string make_relative(StringRef from, StringRef to,
+                                 path::Style style) {
+  SmallString<256> buffer;
+  path::make_relative(from, to, buffer, style);
+  return std::string(buffer.str());
+}
+
+TEST(Support, MakeRelative) {
+  EXPECT_EQ("", make_relative("/a/b/c/d", "/a/b/c/d", path::Style::posix));
+  EXPECT_EQ("d", make_relative("/a/b/c/d", "/a/b/c", path::Style::posix));
+  EXPECT_EQ("c/d", make_relative("/a/b/c/d", "/a/b", path::Style::posix));
+  EXPECT_EQ("../../c/d",
+            make_relative("/a/b/c/d", "/a/b/e/f", path::Style::posix));
+  EXPECT_EQ("../../../../a/b/c/d",
+            make_relative("/a/b/c/d", "/e/f/g/h", path::Style::posix));
+
+  EXPECT_EQ("", make_relative("C:\\a\\b\\c\\d", "C:\\a\\b\\c\\d",
+                              path::Style::windows));
+  EXPECT_EQ("d", make_relative("C:\\a\\b\\c\\d", "C:\\a\\b\\c",
+                               path::Style::windows));
+  EXPECT_EQ("c\\d",
+            make_relative("C:\\a\\b\\c\\d", "C:\\a\\b", path::Style::windows));
+  EXPECT_EQ("..\\..\\c\\d", make_relative("C:\\a\\b\\c\\d", "C:\\a\\b\\e\\f",
+                                          path::Style::windows));
+  EXPECT_EQ(
+      "..\\..\\..\\..\\a\\b\\c\\d",
+      make_relative("C:\\a\\b\\c\\d", "C:\\e\\f\\g\\h", path::Style::windows));
+}
+
 TEST_F(FileSystemTest, OpenFileForRead) {
   // Create a temp file.
   int FileDescriptor;
Index: llvm/lib/Support/Path.cpp
===================================================================
--- llvm/lib/Support/Path.cpp
+++ llvm/lib/Support/Path.cpp
@@ -775,6 +775,22 @@
   return true;
 }
 
+void make_relative(StringRef from, StringRef to, SmallVectorImpl<char> &result,
+                   Style style) {
+  SmallString<256> buffer;
+  auto fromIt = begin(from, style), fromE = end(from);
+  auto toIt = begin(to, style), toE = end(to);
+  // Find a common base.
+  for (; fromIt != fromE && toIt != toE && *fromIt == *toIt; ++fromIt, ++toIt)
+    ;
+  // Navigate backwards to the base.
+  for (; toIt != toE; ++toIt)
+    if (*toIt != ".")
+      append(buffer, style, "..");
+  append(buffer, fromIt, fromE, style);
+  result.swap(buffer);
+}
+
 } // end namespace path
 
 namespace fs {
Index: llvm/include/llvm/Support/Path.h
===================================================================
--- llvm/include/llvm/Support/Path.h
+++ llvm/include/llvm/Support/Path.h
@@ -514,6 +514,10 @@
 bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot = false,
                  Style style = Style::native);
 
+/// Return a path that when appeneded to from resolves to the same as to.
+void make_relative(StringRef from, StringRef to, SmallVectorImpl<char> &result,
+                   Style style = Style::native);
+
 } // end namespace path
 } // end namespace sys
 } // end namespace llvm
Index: clang/test/Preprocessor/file_test.c
===================================================================
--- clang/test/Preprocessor/file_test.c
+++ clang/test/Preprocessor/file_test.c
@@ -3,6 +3,7 @@
 // RUN: %clang -E -fmacro-prefix-map=%p=/UNLIKELY_PATH/empty -c -o - %s | FileCheck %s
 // RUN: %clang -E -fmacro-prefix-map=%p=/UNLIKELY_PATH=empty -c -o - %s | FileCheck %s -check-prefix CHECK-EVIL
 // RUN: %clang -E -fmacro-prefix-map=%p/= -c -o - %s | FileCheck %s --check-prefix CHECK-REMOVE
+// RUN: %clang -E -fsource-dir %S -c -o - %s | FileCheck %s --check-prefix CHECK-RELATIVE
 
 filename: __FILE__
 #include "Inputs/include-file-test/file_test.h"
@@ -21,3 +22,8 @@
 // CHECK-REMOVE: filename: "Inputs/include-file-test/file_test.h"
 // CHECK-REMOVE: basefile: "file_test.c"
 // CHECK-REMOVE-NOT: filename:
+
+// CHECK-RELATIVE: filename: "file_test.c"
+// CHECK-RELATIVE: filename: "Inputs/include-file-test/file_test.h"
+// CHECK-RELATIVE: basefile: "file_test.c"
+// CHECK-RELATIVE-NOT: filename:
Index: clang/test/CoverageMapping/source_dir.c
===================================================================
--- /dev/null
+++ clang/test/CoverageMapping/source_dir.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -mllvm -enable-name-compression=false -emit-llvm %s -o - | FileCheck -check-prefix=ABSPATH %s
+
+// ABSPATH: @__llvm_coverage_mapping = {{.*}}"\01
+// ABSPATH: {{[/\\].*(/|\\\\)test(/|\\\\)CoverageMapping(/|\\\\)source_dir}}.c
+// ABSPATH: "
+
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -mllvm -enable-name-compression=false -emit-llvm -fsource-dir %S %s -o - | FileCheck -check-prefix=RELPATH %s
+
+// RELPATH: @__llvm_coverage_mapping = {{.*}}"\01
+// RELPATH: source_dir.c
+// RELPATH: "
+
+void f1() {}
Index: clang/lib/Lex/PPMacroExpansion.cpp
===================================================================
--- clang/lib/Lex/PPMacroExpansion.cpp
+++ clang/lib/Lex/PPMacroExpansion.cpp
@@ -1542,6 +1542,9 @@
         FN += PLoc.getFilename();
       }
       remapMacroPath(FN, PPOpts->MacroPrefixMap);
+      StringRef SourceDir = PPOpts->SourceDir;
+      if (!SourceDir.empty() && FN.startswith(SourceDir))
+        llvm::sys::path::make_relative(FN, SourceDir, FN);
       Lexer::Stringify(FN);
       OS << '"' << FN << '"';
     }
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -1188,8 +1188,16 @@
   }
 
   Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations);
+
+  SmallString<128> P(Args.getLastArgValue(OPT_fsource_dir));
+  if (!P.empty() && !llvm::sys::path::is_absolute(P))
+    llvm::sys::fs::make_absolute(P);
+  llvm::sys::path::remove_dots(P, /*remove_dot_dot=*/true);
+  Opts.SourceDir = std::string(P.str());
+
   Opts.DebugCompilationDir =
       std::string(Args.getLastArgValue(OPT_fdebug_compilation_dir));
+
   for (auto *A :
        Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) {
     CodeGenOptions::BitcodeFileToLink F;
@@ -3631,6 +3639,12 @@
   for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
     Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue());
 
+  SmallString<128> P(Args.getLastArgValue(OPT_fsource_dir));
+  if (!P.empty() && !llvm::sys::path::is_absolute(P))
+    llvm::sys::fs::make_absolute(P);
+  llvm::sys::path::remove_dots(P, /*remove_dot_dot=*/true);
+  Opts.SourceDir = std::string(P.str());
+
   for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) {
     auto Split = StringRef(A).split('=');
     Opts.MacroPrefixMap.insert(
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -5189,6 +5189,11 @@
   if (!ShouldEnableAutolink(Args, TC, JA))
     CmdArgs.push_back("-fno-autolink");
 
+  if (Arg *A = Args.getLastArg(options::OPT_fsource_dir)) {
+    CmdArgs.push_back("-fsource-dir");
+    CmdArgs.push_back(A->getValue());
+  }
+
   // Add in -fdebug-compilation-dir if necessary.
   addDebugCompDirArg(Args, CmdArgs, D.getVFS());
 
Index: clang/lib/CodeGen/CoverageMappingGen.h
===================================================================
--- clang/lib/CodeGen/CoverageMappingGen.h
+++ clang/lib/CodeGen/CoverageMappingGen.h
@@ -94,6 +94,8 @@
   std::vector<llvm::Constant *> FunctionNames;
   std::vector<FunctionInfo> FunctionRecords;
 
+  std::string normalizeFilename(StringRef Filename);
+
   /// Emit a function record.
   void emitFunctionMappingRecord(const FunctionInfo &Info,
                                  uint64_t FilenamesRef);
Index: clang/lib/CodeGen/CoverageMappingGen.cpp
===================================================================
--- clang/lib/CodeGen/CoverageMappingGen.cpp
+++ clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -1368,13 +1368,6 @@
   }
 };
 
-std::string normalizeFilename(StringRef Filename) {
-  llvm::SmallString<256> Path(Filename);
-  llvm::sys::fs::make_absolute(Path);
-  llvm::sys::path::remove_dots(Path, /*remove_dot_dot=*/true);
-  return std::string(Path);
-}
-
 } // end anonymous namespace
 
 static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
@@ -1413,6 +1406,16 @@
       SK, CGM.getContext().getTargetInfo().getTriple().getObjectFormat());
 }
 
+std::string CoverageMappingModuleGen::normalizeFilename(StringRef Filename) {
+  llvm::SmallString<256> Path(Filename);
+  llvm::sys::fs::make_absolute(Path);
+  llvm::sys::path::remove_dots(Path, /*remove_dot_dot=*/true);
+  StringRef SourceDir = CGM.getCodeGenOpts().SourceDir;
+  if (!SourceDir.empty() && Path.startswith(SourceDir))
+    llvm::sys::path::make_relative(Path, SourceDir, Path);
+  return std::string(Path);
+}
+
 void CoverageMappingModuleGen::emitFunctionMappingRecord(
     const FunctionInfo &Info, uint64_t FilenamesRef) {
   llvm::LLVMContext &Ctx = CGM.getLLVMContext();
Index: clang/include/clang/Lex/PreprocessorOptions.h
===================================================================
--- clang/include/clang/Lex/PreprocessorOptions.h
+++ clang/include/clang/Lex/PreprocessorOptions.h
@@ -175,6 +175,9 @@
   /// build it again.
   std::shared_ptr<FailedModulesSet> FailedModules;
 
+  /// The directory all source files are relative to.
+  std::string SourceDir;
+
   /// A prefix map for __FILE__ and __BASE_FILE__.
   std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap;
 
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -870,6 +870,13 @@
     Group<f_Group>, Flags<[CC1Option, CoreOption]>,
     HelpText<"Generate instrumented code to collect order file into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
 
+def fsource_dir : Separate<["-"], "fsource-dir">,
+    Group<f_Group>, Flags<[CC1Option, CC1AsOption, CoreOption]>,
+    HelpText<"The directory all source files are relative to.">;
+def fsource_dir_EQ : Joined<["-"], "fsource-dir=">,
+    Group<f_Group>, Flags<[CC1Option, CC1AsOption, CoreOption]>,
+    Alias<fsource_dir>;
+
 defm addrsig : OptInFFlag<"addrsig", "Emit", "Don't emit", " an address-significance table", [CoreOption]>;
 defm blocks : OptInFFlag<"blocks", "Enable the 'blocks' language feature", "", "", [CoreOption]>;
 def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>;
Index: clang/include/clang/Basic/CodeGenOptions.h
===================================================================
--- clang/include/clang/Basic/CodeGenOptions.h
+++ clang/include/clang/Basic/CodeGenOptions.h
@@ -152,6 +152,9 @@
   /// The version string to put into coverage files.
   char CoverageVersion[4];
 
+  /// The directory all source files are relative to.
+  std::string SourceDir;
+
   /// Enable additional debugging information.
   std::string DebugPass;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to