================ @@ -0,0 +1,329 @@ +//===--- tools/ssaf-linker/SSAFLinker.cpp - SSAF Linker -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the SSAF entity linker tool that performs entity +// linking across multiple TU summaries using the EntityLinker framework. +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/Scalable/EntityLinker/EntityLinker.h" +#include "clang/Analysis/Scalable/EntityLinker/TUSummaryEncoding.h" +#include "clang/Analysis/Scalable/Model/BuildNamespace.h" +#include "clang/Analysis/Scalable/Serialization/JSONFormat.h" +#include "clang/Analysis/Scalable/Serialization/SerializationFormatRegistry.h" +#include "clang/Analysis/Scalable/Support/ErrorBuilder.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/InitLLVM.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Process.h" +#include "llvm/Support/Timer.h" +#include "llvm/Support/WithColor.h" +#include "llvm/Support/raw_ostream.h" +#include <memory> +#include <string> +#include <system_error> + +using namespace llvm; +using namespace clang::ssaf; + +namespace fs = llvm::sys::fs; +namespace path = llvm::sys::path; + +namespace { + +//===----------------------------------------------------------------------===// +// Command-Line Options +//===----------------------------------------------------------------------===// + +cl::OptionCategory SsafLinkerCategory("ssaf-linker options"); + +cl::list<std::string> InputPaths(cl::Positional, cl::desc("<input files>"), + cl::OneOrMore, cl::cat(SsafLinkerCategory)); + +cl::opt<std::string> OutputPath("o", cl::desc("Output summary path"), + cl::value_desc("path"), cl::Required, + cl::cat(SsafLinkerCategory)); + +cl::opt<bool> Verbose("verbose", cl::desc("Enable verbose output"), + cl::init(false), cl::cat(SsafLinkerCategory)); + +cl::opt<bool> Time("time", cl::desc("Enable timing"), cl::init(false), + cl::cat(SsafLinkerCategory)); + +//===----------------------------------------------------------------------===// +// Error Messages +//===----------------------------------------------------------------------===// + +namespace ErrorMessages { + +constexpr const char *CannotValidateSummary = + "failed to validate summary '{0}': {1}."; + +constexpr const char *OutputDirectoryMissing = + "Parent directory does not exist."; + +constexpr const char *OutputDirectoryNotWritable = + "Parent directory is not writable."; + +constexpr const char *ExtensionNotSupplied = "Extension not supplied."; + +constexpr const char *NoFormatForExtension = + "Format not registered for extension '{0}'."; + +constexpr const char *LinkingSummary = "Linking summary '{0}'"; + +} // namespace ErrorMessages + +//===----------------------------------------------------------------------===// +// Diagnostic Utilities +//===----------------------------------------------------------------------===// + +constexpr unsigned IndentationWidth = 2; + +llvm::StringRef ToolName; + +template <typename... Ts> [[noreturn]] void Fail(const char *Msg) { + llvm::WithColor::error(llvm::errs(), ToolName) << Msg << "\n"; + llvm::sys::Process::Exit(1); +} + +template <typename... Ts> +[[noreturn]] void Fail(const char *Fmt, Ts &&...Args) { + std::string Message = llvm::formatv(Fmt, std::forward<Ts>(Args)...); + Fail(Message.data()); +} + +template <typename... Ts> [[noreturn]] void Fail(llvm::Error Err) { + std::string Message = toString(std::move(Err)); + Fail(Message.data()); +} + +template <typename... Ts> +void Info(unsigned IndentationLevel, const char *Fmt, Ts &&...Args) { + if (Verbose) { + llvm::WithColor::note() + << std::string(IndentationLevel * IndentationWidth, ' ') << "- " + << llvm::formatv(Fmt, std::forward<Ts>(Args)...) << "\n"; + } +} + +//===----------------------------------------------------------------------===// +// Format Registry +//===----------------------------------------------------------------------===// + +SerializationFormat *GetFormatForExtension(llvm::StringRef Extension) { + static llvm::SmallVector< + std::pair<std::string, std::unique_ptr<SerializationFormat>>, 4> + ExtensionFormatList; + + // Most recently used format is most likely to be reused again. + auto ReversedList = llvm::reverse(ExtensionFormatList); + auto It = llvm::find_if(ReversedList, [&](const auto &Entry) { + return Entry.first == Extension; + }); + if (It != ReversedList.end()) { + return It->second.get(); + } ---------------- steakhal wrote:
Is it reasonable to expect that users should provide all the inputs in the same format? Maybe, we could also assume that the input and output are in the same format? (I'm more flexible on this front though). https://github.com/llvm/llvm-project/pull/184713 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
