Hi revane,

The IncludeDirectives class allows the users to add angled-includes in a source
file. This is necessary for some transforms that add dependency to new STL
headers.

This is a start for this class that will need to evolve later (for example to
replace uses of tr1 it will be necessary to rename/remove includes).

http://llvm-reviews.chandlerc.com/D1287

Files:
  cpp11-migrate/Core/CMakeLists.txt
  cpp11-migrate/Core/IncludeDirectives.cpp
  cpp11-migrate/Core/IncludeDirectives.h
  unittests/cpp11-migrate/CMakeLists.txt
  unittests/cpp11-migrate/IncludeDirectivesTest.cpp
  unittests/cpp11-migrate/VirtualFileHelper.h
Index: cpp11-migrate/Core/CMakeLists.txt
===================================================================
--- cpp11-migrate/Core/CMakeLists.txt
+++ cpp11-migrate/Core/CMakeLists.txt
@@ -8,6 +8,7 @@
   IncludeExcludeInfo.cpp
   PerfSupport.cpp
   Reformatting.cpp
+  IncludeDirectives.cpp
   )
 target_link_libraries(migrateCore
   clangFormat
Index: cpp11-migrate/Core/IncludeDirectives.cpp
===================================================================
--- /dev/null
+++ cpp11-migrate/Core/IncludeDirectives.cpp
@@ -0,0 +1,266 @@
+//===-- Core/IncludeDirectives.h - Include directives handling ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file defines the IncludeDirectives class that helps detecting
+/// and modifying \#include directives.
+///
+//===----------------------------------------------------------------------===//
+
+#include "IncludeDirectives.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+
+using namespace clang;
+using llvm::StringRef;
+
+/// \brief PPCallbacks that fills-in the include information in the given
+/// \c IncludeDirectives.
+class IncludeDirectivesPPCallback : public clang::PPCallbacks {
+public:
+  IncludeDirectivesPPCallback(IncludeDirectives *Self) : Self(Self) {}
+
+private:
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) LLVM_OVERRIDE {
+    SourceManager &SM = Self->Sources;
+    const FileEntry *FE = SM.getFileEntryForID(SM.getFileID(HashLoc));
+    assert(FE && "Valid file expected.");
+
+    IncludeDirectives::Entry E(HashLoc, File, IsAngled);
+    Self->FileToEntries[FE].push_back(E);
+    Self->IncludeAsWrittenToLocationsMap[FileName].push_back(HashLoc);
+  }
+
+  IncludeDirectives *Self;
+};
+
+IncludeDirectives::IncludeDirectives(clang::CompilerInstance &CI)
+    : CI(CI), Sources(CI.getSourceManager()) {
+  CI.getPreprocessor().addPPCallbacks(new IncludeDirectivesPPCallback(this));
+}
+
+namespace {
+// Guess the end-of-line sequence used in the given FileID. If the sequence
+// can't be guessed return an Unix-style newline.
+StringRef guessEOL(SourceManager &SM, FileID ID) {
+  bool Invalid = false;
+  StringRef Content = SM.getBufferData(ID, &Invalid);
+  StringRef Buffer;
+  if (!Invalid)
+    Buffer = Content.substr(Content.find_first_of("\r\n"));
+
+  return llvm::StringSwitch<StringRef>(Buffer)
+      .StartsWith("\r\n", "\r\n")
+      .StartsWith("\n\r", "\n\r")
+      .StartsWith("\r", "\r")
+      .Default("\n");
+}
+} // end anonymous namespace
+
+/// \brief Recursively look if \p Include is included by \p File or any of the
+/// headers \p File includes.
+bool IncludeDirectives::lookForInclude(const FileEntry *File, StringRef Include,
+                                       const LocationVec &Locations,
+                                       SeenFilesSet &Seen) const {
+  // mark this file as visited
+  Seen.insert(File);
+
+  // First check if included directly in this file
+  for (LocationVec::const_iterator I = Locations.begin(), E = Locations.end();
+       I != E; ++I)
+    if (Sources.getFileEntryForID(Sources.getFileID(*I)) == File)
+      return true;
+
+  // Otherwise look recursively all the included files
+  FileToEntriesMap::const_iterator EntriesIt = FileToEntries.find(File);
+  if (EntriesIt == FileToEntries.end())
+    return false;
+  for (EntryVec::const_iterator I = EntriesIt->second.begin(),
+                                E = EntriesIt->second.end();
+       I != E; ++I) {
+    // skip if this header has already been checked before
+    if (Seen.count(I->getFile()))
+      continue;
+    if (lookForInclude(I->getFile(), Include, Locations, Seen))
+      return true;
+  }
+  return false;
+}
+
+bool IncludeDirectives::hasInclude(const FileEntry *File,
+                                   StringRef Include) const {
+  llvm::StringMap<LocationVec>::const_iterator It =
+      IncludeAsWrittenToLocationsMap.find(Include);
+
+  // Include isn't included in any file
+  if (It == IncludeAsWrittenToLocationsMap.end())
+    return false;
+
+  SeenFilesSet Seen;
+  return lookForInclude(File, Include, It->getValue(), Seen);
+}
+
+namespace {
+// Flags that describes where to insert newlines.
+enum NewLineFlags {
+  // Add a newline at the beginning of the insertion.
+  NL_Append = 0x1,
+
+  // Prepend a newline at the beginning of the insertion.
+  NL_Prepend = 0x2,
+
+  // Prepend another newline at the end of the insertion.
+  NL_PrependAnother = 0x4,
+
+  // Convenience value to enable both \c NL_Prepend and \c NL_PrependAnother.
+  NL_PrependTwice = NL_Prepend | NL_PrependAnother
+};
+} // end anonymous namespace
+
+tooling::Replacement IncludeDirectives::addAngledInclude(StringRef File,
+                                                         StringRef Include) {
+  const FileEntry *FE = Sources.getFileManager().getFile(File);
+  assert(FE && "Invalid file given!");
+  FileID FID = Sources.translateFile(FE);
+  assert(!FID.isInvalid() && "Invalid file entry given!");
+
+  if (hasInclude(FE, Include))
+    return tooling::Replacement();
+
+  unsigned Offset, NLFlags;
+  llvm::tie(Offset, NLFlags) = angledIncludeInsertionOffset(FID);
+
+  StringRef EOL = guessEOL(Sources, FID);
+  llvm::SmallString<32> InsertionText;
+  if (NLFlags & NL_Prepend)
+    InsertionText += EOL;
+  if (NLFlags & NL_PrependAnother)
+    InsertionText += EOL;
+  InsertionText += "#include <";
+  InsertionText += Include;
+  InsertionText += ">";
+  if (NLFlags & NL_Append)
+    InsertionText += EOL;
+  return tooling::Replacement(File, Offset, 0, InsertionText);
+}
+
+// Finds the end of a file header and returns a pair (FileOffset, NewLineFlags)
+std::pair<unsigned, unsigned>
+IncludeDirectives::findFileHeaderEndOffset(FileID FID) const {
+  unsigned NLFlags = NL_Prepend;
+  StringRef Content = Sources.getBufferData(FID);
+  Lexer Lex(Sources.getLocForStartOfFile(FID), CI.getLangOpts(),
+            Content.begin(), Content.begin(), Content.end());
+  Lex.SetCommentRetentionState(true);
+  Lex.SetKeepWhitespaceMode(true);
+
+  // find the first newline not part of a multi-line comment
+  Token Tok;
+  do {
+    Lex.LexFromRawLexer(Tok);
+    unsigned Offset = Sources.getFileOffset(Tok.getLocation());
+    // allow one newline between the comments
+    if (Tok.is(tok::unknown) && isWhitespace(Content[Offset])) {
+      StringRef Whitespaces(Content.substr(Offset, Tok.getLength()));
+      if (Whitespaces.count('\n') == 1 || Whitespaces.count('\r') == 1)
+        Lex.LexFromRawLexer(Tok);
+      else {
+        // add an empty line to separate the file header and the inclusion
+        NLFlags = NL_PrependTwice;
+      }
+    }
+  } while (Tok.is(tok::comment));
+
+  // apparently there is no header, insertion point is the beginning of the file
+  if (Tok.isNot(tok::unknown))
+    return std::make_pair(0, NL_Append);
+  return std::make_pair(Sources.getFileOffset(Tok.getLocation()), NLFlags);
+}
+
+// Get the position of the last angled include if any, or just the position of
+// the last include.
+// Returns a null SourceLocation if no entry are available.
+SourceLocation
+IncludeDirectives::angledIncludeHintLoc(const EntryVec &Entries) const {
+  if (Entries.empty())
+    return SourceLocation();
+  for (EntryVec::const_reverse_iterator I = Entries.rbegin(),
+                                        E = Entries.rend();
+       I != E; ++I)
+    if (I->isAngled())
+      return I->getLocation();
+  return Entries.back().getLocation();
+}
+
+// Finds the offset where an angled include should be added and returns a pair
+// (FileOffset, NewLineFlags).
+std::pair<unsigned, unsigned>
+IncludeDirectives::angledIncludeInsertionOffset(FileID FID) const {
+  const FileEntry *File = Sources.getFileEntryForID(FID);
+
+  // the location of an include directive that can be used to put our inclusion
+  // after
+  SourceLocation Hint;
+  FileToEntriesMap::const_iterator EntriesIt = FileToEntries.find(File);
+  if (EntriesIt != FileToEntries.end())
+    Hint = angledIncludeHintLoc(EntriesIt->second);
+
+  // no interesting #include lines, insertion is done after the file header
+  if (Hint.isInvalid())
+    return findFileHeaderEndOffset(FID);
+
+  unsigned Offset = Sources.getFileOffset(Hint);
+  StringRef Content = Sources.getBufferData(FID);
+
+  // find the newline after our include
+  Lexer Lex(Sources.getLocForStartOfFile(FID), CI.getLangOpts(),
+            Content.begin(), Content.begin() + Offset, Content.end());
+  Lex.SetCommentRetentionState(true);
+  Token Tok;
+  for (;;) {
+    // find beginning of end-of-line sequence
+    StringRef::size_type EOLOffset = Content.find_first_of("\r\n", Offset);
+    if (EOLOffset == StringRef::npos)
+      return std::make_pair(Content.size(), NL_Prepend); // newline missing
+    // check if the newline is directly past the end of the last token,
+    // otherwise the next Lex() call will omit this one.
+    if (Offset == EOLOffset)
+      return std::make_pair(Offset, NL_Prepend);
+
+    // look for the next end-of-line if this one is part of a multi-line comment
+    unsigned TokEnd = 0;
+    bool isInComment = false;
+    do {
+      Lex.LexFromRawLexer(Tok);
+      unsigned TokStart = Sources.getFileOffset(Tok.getLocation());
+      TokEnd = TokStart + Tok.getLength();
+
+      // the EOLOffset checks for StringRef::npos
+      assert(Tok.isNot(tok::eof) && "unexpected token!");
+
+      if (Tok.is(tok::comment)) {
+        if (EOLOffset > TokStart && EOLOffset < TokEnd) {
+          isInComment = true;
+          // skip after the comment for the new search of NL
+          Offset = TokEnd;
+        }
+      }
+    } while (TokEnd < EOLOffset);
+
+    if (!isInComment)
+      return std::make_pair(EOLOffset, NL_Prepend);
+  }
+}
Index: cpp11-migrate/Core/IncludeDirectives.h
===================================================================
--- /dev/null
+++ cpp11-migrate/Core/IncludeDirectives.h
@@ -0,0 +1,100 @@
+//===-- Core/IncludeDirectives.h - Include directives handling --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file declares the IncludeDirectives class that helps detecting
+/// and modifying \#include directives.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef CPP11_MIGRATE_INCLUDE_DIRECTIVES_H
+#define CPP11_MIGRATE_INCLUDE_DIRECTIVES_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Tooling/Refactoring.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallPtrSet.h"
+
+#include <vector>
+
+namespace clang {
+class Preprocessor;
+} // namespace clang
+
+/// \brief Support for include directives handling.
+///
+/// This class should be created with a \c clang::CompilerInstance before the
+/// file is preprocessed in order to collect the inclusion information. It can
+/// be queried as long as the compiler instance is valid.
+class IncludeDirectives {
+public:
+  IncludeDirectives(clang::CompilerInstance &CI);
+
+  /// \brief Add an angled include to a the given file.
+  ///
+  /// \param File A file accessible by a SourceManager
+  /// \param Include The include file as it should be written in the code.
+  ///
+  /// \return A replacement that is either null if the include already visible
+  /// by file (check with \c Replacement::isApplicable()) or non-null
+  /// replacement that will add the include when applied.
+  clang::tooling::Replacement addAngledInclude(llvm::StringRef File,
+                                               llvm::StringRef Include);
+
+private:
+  friend class IncludeDirectivesPPCallback;
+
+  /// \brief Contains some inclusion information.
+  class Entry {
+  public:
+    Entry(clang::SourceLocation Loc, const clang::FileEntry *File, bool Angled)
+        : Loc(Loc), File(File), Angled(Angled) {}
+
+    clang::SourceLocation getLocation() const { return Loc; }
+    const clang::FileEntry *getFile() const { return File; }
+    bool isAngled() const { return Angled; }
+
+  private:
+    clang::SourceLocation Loc;
+    const clang::FileEntry *File;
+    bool Angled;
+  };
+
+  // A list of entries.
+  typedef std::vector<Entry> EntryVec;
+
+  // A list of source locations.
+  typedef std::vector<clang::SourceLocation> LocationVec;
+
+  // Associates files to their includes.
+  typedef llvm::DenseMap<const clang::FileEntry *, EntryVec> FileToEntriesMap;
+
+  bool hasInclude(const clang::FileEntry *File, llvm::StringRef Include) const;
+
+  typedef llvm::SmallPtrSet<const clang::FileEntry *, 32> SeenFilesSet;
+  bool lookForInclude(const clang::FileEntry *File, llvm::StringRef Include,
+                      const LocationVec &Locations, SeenFilesSet &Seen) const;
+
+  std::pair<unsigned, unsigned>
+  angledIncludeInsertionOffset(clang::FileID FID) const;
+  clang::SourceLocation angledIncludeHintLoc(const EntryVec &Entries) const;
+
+  std::pair<unsigned, unsigned>
+  findFileHeaderEndOffset(clang::FileID FID) const;
+
+  clang::CompilerInstance &CI;
+  clang::SourceManager &Sources;
+  FileToEntriesMap FileToEntries;
+  // maps include filename as written in the source code to the source locations
+  // where it appears
+  llvm::StringMap<LocationVec> IncludeAsWrittenToLocationsMap;
+};
+
+#endif // CPP11_MIGRATE_INCLUDE_DIRECTIVES_H
Index: unittests/cpp11-migrate/CMakeLists.txt
===================================================================
--- unittests/cpp11-migrate/CMakeLists.txt
+++ unittests/cpp11-migrate/CMakeLists.txt
@@ -13,6 +13,7 @@
   PerfSupportTest.cpp
   TransformTest.cpp
   UniqueHeaderNameTest.cpp
+  IncludeDirectivesTest.cpp
   )
 
 target_link_libraries(Cpp11MigrateTests
Index: unittests/cpp11-migrate/IncludeDirectivesTest.cpp
===================================================================
--- /dev/null
+++ unittests/cpp11-migrate/IncludeDirectivesTest.cpp
@@ -0,0 +1,186 @@
+//===- cpp11-migrate/IncludeDirectivesTest.cpp ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Core/IncludeDirectives.h"
+#include "gtest/gtest.h"
+#include "VirtualFileHelper.h"
+
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+
+using namespace llvm;
+using namespace clang;
+
+namespace {
+class TestAddIncludeAction : public PreprocessOnlyAction {
+public:
+  TestAddIncludeAction(StringRef Include, tooling::Replacements &Replaces,
+                       const char *HeaderToModify = 0)
+      : Include(Include), Replaces(Replaces), HeaderToModify(HeaderToModify) {
+    // some headers that the tests can include
+    VFHelper.mapFile("/virtual/foo-inner.h", "\n");
+    VFHelper.mapFile("/virtual/foo.h", "#include </virtual/foo-inner.h>\n");
+    VFHelper.mapFile("/virtual/bar-inner.h", "\n");
+    VFHelper.mapFile("/virtual/bar.h", "#include </virtual/bar-inner.h>\n");
+  }
+
+  void addVirtualFile(StringRef FileName, StringRef Content) {
+    VFHelper.mapFile(FileName, Content);
+  }
+
+private:
+  virtual bool BeginSourceFileAction(CompilerInstance &CI,
+                                     StringRef FileName) LLVM_OVERRIDE {
+    if (!PreprocessOnlyAction::BeginSourceFileAction(CI, FileName))
+      return false;
+    VFHelper.mapVirtualFiles(CI.getSourceManager());
+
+    FileToModify = HeaderToModify ? HeaderToModify : FileName;
+    FileIncludes.reset(new IncludeDirectives(CI));
+    return true;
+  }
+
+  virtual void EndSourceFileAction() LLVM_OVERRIDE {
+    const tooling::Replacement &Replace = FileIncludes->addAngledInclude(FileToModify, Include);
+    if (Replace.isApplicable())
+      Replaces.insert(Replace);
+  }
+
+  StringRef Include;
+  VirtualFileHelper VFHelper;
+  tooling::Replacements &Replaces;
+  OwningPtr<IncludeDirectives> FileIncludes;
+  StringRef FileToModify;
+  // if non-null, add the include directives in this file instead of the main
+  // file.
+  const char *HeaderToModify;
+};
+
+std::string addIncludeInCode(StringRef Include, StringRef Code) {
+  tooling::Replacements Replaces;
+  EXPECT_TRUE(tooling::runToolOnCode(
+      new TestAddIncludeAction(Include, Replaces), Code));
+  return tooling::applyAllReplacements(Code, Replaces);
+}
+} // end anonymous namespace
+
+TEST(IncludeDirectivesTest, endOfLinesVariants) {
+  EXPECT_EQ("#include </virtual/foo.h>\n"
+            "#include <bar>\n",
+            addIncludeInCode("bar", "#include </virtual/foo.h>\n"));
+  EXPECT_EQ("#include </virtual/foo.h>\r\n"
+            "#include <bar>\r\n",
+            addIncludeInCode("bar", "#include </virtual/foo.h>\r\n"));
+  EXPECT_EQ("#include </virtual/foo.h>\r"
+            "#include <bar>\r",
+            addIncludeInCode("bar", "#include </virtual/foo.h>\r"));
+}
+
+TEST(IncludeDirectivesTest, ppToken) {
+  EXPECT_EQ("#define FOO </virtual/foo.h>\n"
+            "#include FOO\n"
+            "#include <bar>\n"
+            "int i;\n",
+            addIncludeInCode("bar", "#define FOO </virtual/foo.h>\n"
+                                    "#include FOO\n"
+                                    "int i;\n"));
+}
+
+TEST(IncludeDirectivesTest, noFileHeader) {
+  EXPECT_EQ("#include <bar>\n"
+            "int foo;\n",
+            addIncludeInCode("bar", "int foo;\n"));
+}
+
+TEST(IncludeDirectivesTest, commentBeforeTopMostCode) {
+  EXPECT_EQ("#include <bar>\n"
+            "// Foo\n"
+            "int foo;\n",
+            addIncludeInCode("bar", "// Foo\n"
+                                    "int foo;\n"));
+}
+
+TEST(IncludeDirectivesTest, multiLineComment) {
+  EXPECT_EQ("#include </virtual/foo.h> /* \n */\n"
+            "#include <bar>\n",
+            addIncludeInCode("bar", "#include </virtual/foo.h> /* \n */\n"));
+  EXPECT_EQ("#include </virtual/foo.h> /* \n */"
+            "\n#include <bar>",
+            addIncludeInCode("bar", "#include </virtual/foo.h> /* \n */"));
+}
+
+TEST(IncludeDirectivesTest, fileHeaders) {
+  EXPECT_EQ("// this is a header\n"
+            "// some license stuff here\n"
+            "\n"
+            "#include <bar>\n"
+            "\n"
+            "/// \\brief Foo\n"
+            "int foo;\n",
+            addIncludeInCode("bar", "// this is a header\n"
+                                    "// some license stuff here\n"
+                                    "\n"
+                                    "/// \\brief Foo\n"
+                                    "int foo;\n"));
+}
+
+TEST(IncludeDirectivesTest, preferablyAngledNextToAngled) {
+  EXPECT_EQ("#include </virtual/foo.h>\n"
+            "#include <bar>\n"
+            "#include \"/virtual/bar.h\"\n",
+            addIncludeInCode("bar", "#include </virtual/foo.h>\n"
+                                    "#include \"/virtual/bar.h\"\n"));
+  EXPECT_EQ("#include \"/virtual/foo.h\"\n"
+            "#include \"/virtual/bar.h\"\n"
+            "#include <bar>\n",
+            addIncludeInCode("bar", "#include \"/virtual/foo.h\"\n"
+                                    "#include \"/virtual/bar.h\"\n"));
+}
+
+TEST(IncludeDirectivesTest, avoidDuplicates) {
+  EXPECT_EQ("#include </virtual/foo.h>\n",
+            addIncludeInCode("/virtual/foo.h", "#include </virtual/foo.h>\n"));
+}
+
+namespace {
+TestAddIncludeAction *makeIndirectTestsAction(const char *HeaderToModify,
+                                              tooling::Replacements &Replaces) {
+  StringRef Include = "/virtual/c.h";
+  TestAddIncludeAction *TestAction =
+      new TestAddIncludeAction(Include, Replaces, HeaderToModify);
+  TestAction->addVirtualFile("/virtual/c.h", "\n");
+  TestAction->addVirtualFile("/virtual/a.h", "#include </virtual/c.h>\n");
+  TestAction->addVirtualFile("/virtual/b.h", "\n");
+  return TestAction;
+}
+} // end anonymous namespace
+
+TEST(IncludeDirectivesTest, indirectIncludes) {
+  EXPECT_EQ(
+      "#include </virtual/foo.h>\n",
+      addIncludeInCode("/virtual/foo-inner.h", "#include </virtual/foo.h>\n"));
+
+  // Test a.h that already include
+  tooling::Replacements Replaces;
+  StringRef Code = "#include </virtual/a.h>\n"
+                   "#include </virtual/b.h>\n";
+
+  {
+    FrontendAction *Action = makeIndirectTestsAction("/virtual/a.h", Replaces);
+    EXPECT_TRUE(tooling::runToolOnCode(Action, Code));
+    EXPECT_EQ(unsigned(0), Replaces.size());
+  }
+
+  {
+    FrontendAction *Action = makeIndirectTestsAction("/virtual/b.h", Replaces);
+    EXPECT_TRUE(tooling::runToolOnCode(Action, Code));
+    EXPECT_EQ("#include </virtual/c.h>\n\n",
+              tooling::applyAllReplacements("\n", Replaces));
+  }
+}
Index: unittests/cpp11-migrate/VirtualFileHelper.h
===================================================================
--- unittests/cpp11-migrate/VirtualFileHelper.h
+++ unittests/cpp11-migrate/VirtualFileHelper.h
@@ -49,15 +49,21 @@
   /// mapped to it.
   SourceManager &getNewSourceManager() {
     Sources.reset(new SourceManager(Diagnostics, Files));
-    for (llvm::SmallVectorImpl<VirtualFile>::iterator I = VirtualFiles.begin(),
-                                                      E = VirtualFiles.end();
+    mapVirtualFiles(*Sources);
+    return *Sources;
+  }
+
+  /// \brief Map the virtual file contents in the given \c SourceManager.
+  void mapVirtualFiles(SourceManager &SM) const {
+    for (llvm::SmallVectorImpl<VirtualFile>::const_iterator
+             I = VirtualFiles.begin(),
+             E = VirtualFiles.end();
          I != E; ++I) {
       llvm::MemoryBuffer *Buf = llvm::MemoryBuffer::getMemBuffer(I->Code);
-      const FileEntry *Entry = Files.getVirtualFile(
+      const FileEntry *Entry = SM.getFileManager().getVirtualFile(
           I->FileName, Buf->getBufferSize(), /*ModificationTime=*/0);
-      Sources->overrideFileContents(Entry, Buf);
+      SM.overrideFileContents(Entry, Buf);
     }
-    return *Sources;
   }
 
 private:
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to