================
@@ -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();
+  }
----------------
aviralg wrote:

I chose the most general solution because it imposes no restriction and can be 
implemented nearly as efficiently in a few lines of code. Requiring all inputs 
in the same format would require an extra check, error message, and test. 

https://github.com/llvm/llvm-project/pull/184713
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to