]> granicus.if.org Git - clang/commitdiff
Introduce a new clang-cc option
authorDouglas Gregor <dgregor@apple.com>
Wed, 2 Dec 2009 08:08:39 +0000 (08:08 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 2 Dec 2009 08:08:39 +0000 (08:08 +0000)
  -remap-file=from;to

which takes the file "from" and transparently replaces its contents
with the contents of the file "to" from the source manager's
perspective. This is the moral equivalent of

  cp from saved
  cp to from
  <call clang>
  cp saved from
  rm saved

without all of the pesky file copying.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90307 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticFrontendKinds.td
include/clang/Frontend/PreprocessorOptions.h
lib/Frontend/CompilerInstance.cpp
test/Misc/Inputs/remapped-file [new file with mode: 0644]
test/Misc/remap-file.c [new file with mode: 0644]
tools/clang-cc/Options.cpp

index 9dbd9cfa210992a6c2dc6d20c5662ecc8a16efa1..50d997c9869e4aced7ddcbee76fd3eb6ccbee7d3 100644 (file)
@@ -33,6 +33,10 @@ def err_fe_expected_compiler_job : Error<
     "unable to handle compilation, expected exactly one compiler job in '%0'">;
 def err_fe_expected_clang_command : Error<
     "expected a clang compiler command">;
+def err_fe_remap_missing_to_file : Error<
+    "could not remap file '%0' to the contents of file '%1'">, DefaultFatal;
+def err_fe_remap_missing_from_file : Error<
+    "could not remap from missing file '%0'">, DefaultFatal;
 
 def err_verify_bogus_characters : Error<
     "bogus characters before '{{' in expected string">;
index f0c1d3c2c38dfb6fd93398c2ec9de704aa9a0424..c43a1feb8c057dd0974ed7ef95025972e598ca86 100644 (file)
@@ -13,6 +13,7 @@
 #include "llvm/ADT/StringRef.h"
 #include <cassert>
 #include <string>
+#include <utility>
 #include <vector>
 
 namespace clang {
@@ -41,6 +42,21 @@ public:
   /// If given, a PTH cache file to use for speeding up header parsing.
   std::string TokenCache;
 
+  /// \brief The set of file remappings, which take existing files on
+  /// the system (the first part of each pair) and gives them the
+  /// contents of other files on the system (the second part of each
+  /// pair).
+  std::vector<std::pair<std::string, std::string> >  RemappedFiles;
+
+  typedef std::vector<std::pair<std::string, std::string> >::const_iterator
+    remapped_file_iterator;
+  remapped_file_iterator remapped_file_begin() const { 
+    return RemappedFiles.begin();
+  }
+  remapped_file_iterator remapped_file_end() const { 
+    return RemappedFiles.end();
+  }
+
 public:
   PreprocessorOptions() : UsePredefines(true) {}
 
@@ -50,6 +66,9 @@ public:
   void addMacroUndef(llvm::StringRef Name) {
     Macros.push_back(std::make_pair(Name, true));
   }
+  void addRemappedFile(llvm::StringRef From, llvm::StringRef To) {
+    RemappedFiles.push_back(std::make_pair(From, To));
+  }
 };
 
 } // end namespace clang
index 2d58beead8b57f53d4d7b892ec8064ac625e6c02..02b24b4976278942741eddb2443cfa6f179db682 100644 (file)
@@ -190,6 +190,45 @@ CompilerInstance::createPreprocessor(Diagnostic &Diags,
     PP->setPTHManager(PTHMgr);
   }
 
+  // Remap files in the source manager.
+  for (PreprocessorOptions::remapped_file_iterator
+         Remap = PPOpts.remapped_file_begin(),
+         RemapEnd = PPOpts.remapped_file_end();
+       Remap != RemapEnd;
+       ++Remap) {
+    // Find the file that we're mapping to.
+    const FileEntry *ToFile = FileMgr.getFile(Remap->second);
+    if (!ToFile) {
+      Diags.Report(diag::err_fe_remap_missing_to_file)
+        << Remap->first << Remap->second;
+      continue;
+    }
+
+    // Find the file that we're mapping from.
+    const FileEntry *FromFile = FileMgr.getFile(Remap->first);
+    if (!FromFile) {
+      // FIXME: We could actually recover from this, by faking a
+      // FileEntry based on the "ToFile".
+      Diags.Report(diag::err_fe_remap_missing_from_file)
+        << Remap->first;
+      continue;
+    }
+
+    // Load the contents of the file we're mapping to.
+    std::string ErrorStr;
+    const llvm::MemoryBuffer *Buffer
+      = llvm::MemoryBuffer::getFile(ToFile->getName(), &ErrorStr);
+    if (!Buffer) {
+      Diags.Report(diag::err_fe_error_opening)
+        << Remap->second << ErrorStr;
+      continue;
+    }
+
+    // Override the contents of the "from" file with the contents of
+    // the "to" file.
+    SourceMgr.overrideFileContents(FromFile, Buffer);
+  }
+
   InitializePreprocessor(*PP, PPOpts, HSOpts);
 
   // Handle generating dependencies, if requested.
diff --git a/test/Misc/Inputs/remapped-file b/test/Misc/Inputs/remapped-file
new file mode 100644 (file)
index 0000000..657613e
--- /dev/null
@@ -0,0 +1 @@
+int *f(float *fp) { return fp; }
diff --git a/test/Misc/remap-file.c b/test/Misc/remap-file.c
new file mode 100644 (file)
index 0000000..e8aa3e4
--- /dev/null
@@ -0,0 +1,5 @@
+// RUN: clang-cc -remap-file="%s;%S/Inputs/remapped-file" -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: remap-file.c:1:28: warning: incompatible pointer types
+
+int
index a18598ef7c215dd06c9f469c725e3fd0840e526a..c97d4ca8c9de17782a1a3411f9c5062aba214c5a 100644 (file)
@@ -673,6 +673,10 @@ static llvm::cl::opt<bool>
 UndefMacros("undef", llvm::cl::value_desc("macro"),
             llvm::cl::desc("undef all system defines"));
 
+static llvm::cl::list<std::string>
+RemappedFiles("remap-file", llvm::cl::value_desc("<from>;<to>"),
+              llvm::cl::desc("replace the contents of the <from> file with the contents of the <to> file"));
+
 }
 
 //===----------------------------------------------------------------------===//
@@ -1071,6 +1075,20 @@ void clang::InitializePreprocessorOptions(PreprocessorOptions &Opts) {
 
   for (unsigned i = 0, e = OrderedPaths.size(); i != e; ++i)
     Opts.Includes.push_back(*OrderedPaths[i].second);
+
+  // Handle file remapping.
+  for (unsigned i = 0, e = RemappedFiles.size(); i != e; ++i) {
+    std::string::size_type Semi = RemappedFiles[i].find(';');
+    if (Semi == std::string::npos) {
+      // FIXME: Don't fail like this.
+      fprintf(stderr, 
+              "error: -remap-file not of the form <from-file>;<to-file>\n");
+      continue;
+    }
+
+    Opts.addRemappedFile(llvm::StringRef(RemappedFiles[i].c_str(), Semi),
+                         llvm::StringRef(RemappedFiles[i].c_str() + Semi + 1));
+  }
 }
 
 void clang::InitializeLangOptions(LangOptions &Options,