]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Frontend/ModuleDependencyCollector.cpp
Merge clang trunk r238337 from ^/vendor/clang/dist, resolve conflicts,
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Frontend / ModuleDependencyCollector.cpp
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"
15 #include "clang/Serialization/ASTReader.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
40 void ModuleDependencyCollector::attachToASTReader(ASTReader &R) {
41   R.addListener(llvm::make_unique<ModuleDependencyListener>(*this));
42 }
43
44 void ModuleDependencyCollector::writeFileMap() {
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 }