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