clang  3.7.0
ModuleDependencyCollector.cpp
Go to the documentation of this file.
1 //===--- ModuleDependencyCollector.cpp - Collect module dependencies ------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Collect the dependencies of a set of modules.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/Frontend/Utils.h"
16 #include "llvm/ADT/StringSet.h"
17 #include "llvm/ADT/iterator_range.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/Path.h"
20 #include "llvm/Support/raw_ostream.h"
21 
22 using namespace clang;
23 
24 namespace {
25 /// Private implementation for ModuleDependencyCollector
26 class ModuleDependencyListener : public ASTReaderListener {
27  ModuleDependencyCollector &Collector;
28 
29  std::error_code copyToRoot(StringRef Src);
30 public:
31  ModuleDependencyListener(ModuleDependencyCollector &Collector)
32  : Collector(Collector) {}
33  bool needsInputFileVisitation() override { return true; }
34  bool needsSystemInputFileVisitation() override { return true; }
35  bool visitInputFile(StringRef Filename, bool IsSystem,
36  bool IsOverridden) override;
37 };
38 }
39 
41  R.addListener(llvm::make_unique<ModuleDependencyListener>(*this));
42 }
43 
45  if (Seen.empty())
46  return;
47 
48  SmallString<256> Dest = getDest();
49  llvm::sys::path::append(Dest, "vfs.yaml");
50 
51  std::error_code EC;
52  llvm::raw_fd_ostream OS(Dest, EC, llvm::sys::fs::F_Text);
53  if (EC) {
54  setHasErrors();
55  return;
56  }
57  VFSWriter.write(OS);
58 }
59 
60 std::error_code ModuleDependencyListener::copyToRoot(StringRef Src) {
61  using namespace llvm::sys;
62 
63  // We need an absolute path to append to the root.
64  SmallString<256> AbsoluteSrc = Src;
65  fs::make_absolute(AbsoluteSrc);
66  // Canonicalize to a native path to avoid mixed separator styles.
67  path::native(AbsoluteSrc);
68  // TODO: We probably need to handle .. as well as . in order to have valid
69  // input to the YAMLVFSWriter.
70  FileManager::removeDotPaths(AbsoluteSrc);
71 
72  // Build the destination path.
73  SmallString<256> Dest = Collector.getDest();
74  path::append(Dest, path::relative_path(AbsoluteSrc));
75 
76  // Copy the file into place.
77  if (std::error_code EC = fs::create_directories(path::parent_path(Dest),
78  /*IgnoreExisting=*/true))
79  return EC;
80  if (std::error_code EC = fs::copy_file(AbsoluteSrc, Dest))
81  return EC;
82  // Use the absolute path under the root for the file mapping.
83  Collector.addFileMapping(AbsoluteSrc, Dest);
84  return std::error_code();
85 }
86 
87 bool ModuleDependencyListener::visitInputFile(StringRef Filename, bool IsSystem,
88  bool IsOverridden) {
89  if (Collector.insertSeen(Filename))
90  if (copyToRoot(Filename))
91  Collector.setHasErrors();
92  return true;
93 }
static bool removeDotPaths(SmallVectorImpl< char > &Path)
Remove any './' components from a path.
void write(llvm::raw_ostream &OS)
void addListener(std::unique_ptr< ASTReaderListener > L)
Add an AST callback listener.
Definition: ASTReader.h:1373
Reads an AST files chain containing the contents of a translation unit.
Definition: ASTReader.h:302
Abstract interface for callback invocations by the ASTReader.
Definition: ASTReader.h:101