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