xref: /llvm-project/llvm/tools/llvm-libtool-darwin/DependencyInfo.h (revision 10f22335f3b7c7b78b54ee6b995f6ed97e4c225d)
1*10f22335SKeith Smiley //===-- DependencyInfo.h --------------------------------------------------===//
2*10f22335SKeith Smiley //
3*10f22335SKeith Smiley // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*10f22335SKeith Smiley // See https://llvm.org/LICENSE.txt for license information.
5*10f22335SKeith Smiley // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*10f22335SKeith Smiley //
7*10f22335SKeith Smiley //===----------------------------------------------------------------------===//
8*10f22335SKeith Smiley 
9*10f22335SKeith Smiley #include "llvm/ADT/StringRef.h"
10*10f22335SKeith Smiley #include "llvm/Support/FileSystem.h"
11*10f22335SKeith Smiley #include "llvm/Support/WithColor.h"
12*10f22335SKeith Smiley #include "llvm/Support/raw_ostream.h"
13*10f22335SKeith Smiley 
14*10f22335SKeith Smiley #include <set>
15*10f22335SKeith Smiley 
16*10f22335SKeith Smiley class DependencyInfo {
17*10f22335SKeith Smiley public:
DependencyInfo(std::string DependencyInfoPath)18*10f22335SKeith Smiley   explicit DependencyInfo(std::string DependencyInfoPath)
19*10f22335SKeith Smiley       : DependencyInfoPath(DependencyInfoPath) {}
20*10f22335SKeith Smiley 
~DependencyInfo()21*10f22335SKeith Smiley   virtual ~DependencyInfo(){};
22*10f22335SKeith Smiley 
addMissingInput(llvm::StringRef Path)23*10f22335SKeith Smiley   virtual void addMissingInput(llvm::StringRef Path) {
24*10f22335SKeith Smiley     NotFounds.insert(Path.str());
25*10f22335SKeith Smiley   }
26*10f22335SKeith Smiley 
27*10f22335SKeith Smiley   // Writes the dependencies to specified path. The content is first sorted by
28*10f22335SKeith Smiley   // OpCode and then by the filename (in alphabetical order).
write(llvm::Twine Version,const std::vector<std::string> & Inputs,std::string Output)29*10f22335SKeith Smiley   virtual void write(llvm::Twine Version,
30*10f22335SKeith Smiley                      const std::vector<std::string> &Inputs,
31*10f22335SKeith Smiley                      std::string Output) {
32*10f22335SKeith Smiley     std::error_code EC;
33*10f22335SKeith Smiley     llvm::raw_fd_ostream OS(DependencyInfoPath, EC, llvm::sys::fs::OF_None);
34*10f22335SKeith Smiley     if (EC) {
35*10f22335SKeith Smiley       llvm::WithColor::defaultErrorHandler(llvm::createStringError(
36*10f22335SKeith Smiley           EC,
37*10f22335SKeith Smiley           "failed to write to " + DependencyInfoPath + ": " + EC.message()));
38*10f22335SKeith Smiley       return;
39*10f22335SKeith Smiley     }
40*10f22335SKeith Smiley 
41*10f22335SKeith Smiley     auto AddDep = [&OS](DependencyInfoOpcode Opcode,
42*10f22335SKeith Smiley                         const llvm::StringRef &Path) {
43*10f22335SKeith Smiley       OS << static_cast<uint8_t>(Opcode);
44*10f22335SKeith Smiley       OS << Path;
45*10f22335SKeith Smiley       OS << '\0';
46*10f22335SKeith Smiley     };
47*10f22335SKeith Smiley 
48*10f22335SKeith Smiley     AddDep(DependencyInfoOpcode::Tool, Version.str());
49*10f22335SKeith Smiley 
50*10f22335SKeith Smiley     // Sort the input by its names.
51*10f22335SKeith Smiley     std::vector<llvm::StringRef> InputNames;
52*10f22335SKeith Smiley     InputNames.reserve(Inputs.size());
53*10f22335SKeith Smiley     for (const auto &F : Inputs)
54*10f22335SKeith Smiley       InputNames.push_back(F);
55*10f22335SKeith Smiley     llvm::sort(InputNames);
56*10f22335SKeith Smiley 
57*10f22335SKeith Smiley     for (const auto &In : InputNames)
58*10f22335SKeith Smiley       AddDep(DependencyInfoOpcode::InputFound, In);
59*10f22335SKeith Smiley 
60*10f22335SKeith Smiley     for (const std::string &F : NotFounds)
61*10f22335SKeith Smiley       AddDep(DependencyInfoOpcode::InputMissing, F);
62*10f22335SKeith Smiley 
63*10f22335SKeith Smiley     AddDep(DependencyInfoOpcode::Output, Output);
64*10f22335SKeith Smiley   }
65*10f22335SKeith Smiley 
66*10f22335SKeith Smiley private:
67*10f22335SKeith Smiley   enum DependencyInfoOpcode : uint8_t {
68*10f22335SKeith Smiley     Tool = 0x00,
69*10f22335SKeith Smiley     InputFound = 0x10,
70*10f22335SKeith Smiley     InputMissing = 0x11,
71*10f22335SKeith Smiley     Output = 0x40,
72*10f22335SKeith Smiley   };
73*10f22335SKeith Smiley 
74*10f22335SKeith Smiley   const std::string DependencyInfoPath;
75*10f22335SKeith Smiley   std::set<std::string> NotFounds;
76*10f22335SKeith Smiley };
77*10f22335SKeith Smiley 
78*10f22335SKeith Smiley // Subclass to avoid any overhead when not using this feature
79*10f22335SKeith Smiley class DummyDependencyInfo : public DependencyInfo {
80*10f22335SKeith Smiley public:
DummyDependencyInfo()81*10f22335SKeith Smiley   DummyDependencyInfo() : DependencyInfo("") {}
addMissingInput(llvm::StringRef Path)82*10f22335SKeith Smiley   void addMissingInput(llvm::StringRef Path) override {}
write(llvm::Twine Version,const std::vector<std::string> & Inputs,std::string Output)83*10f22335SKeith Smiley   void write(llvm::Twine Version, const std::vector<std::string> &Inputs,
84*10f22335SKeith Smiley              std::string Output) override {}
85*10f22335SKeith Smiley };
86