================
@@ -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();
+  }
+
+  // SerializationFormats are uppercase while file extensions are lowercase.
+  std::string CapitalizedExtension = Extension.upper();
+
+  if (!isFormatRegistered(CapitalizedExtension)) {
+    return nullptr;
+  }
+
+  auto Format = makeFormat(CapitalizedExtension);
+  SerializationFormat *Result = Format.get();
+  assert(Result);
+
+  ExtensionFormatList.emplace_back(Extension, std::move(Format));
+
+  return Result;
+}
+
+//===----------------------------------------------------------------------===//
+// Data Structures
+//===----------------------------------------------------------------------===//
+
+struct SummaryFile {
+  std::string Path;
+  SerializationFormat *Format = nullptr;
+
+  static SummaryFile FromPath(llvm::StringRef Path) {
+    llvm::StringRef Extension = path::extension(Path);
+    if (Extension.empty()) {
+      Fail(ErrorMessages::CannotValidateSummary, Path,
+           ErrorMessages::ExtensionNotSupplied);
+    }
+    Extension = Extension.drop_front();
+    SerializationFormat *Format = GetFormatForExtension(Extension);
+    if (!Format) {
+      std::string BadExtension =
+          llvm::formatv(ErrorMessages::NoFormatForExtension, Extension);
+      Fail(ErrorMessages::CannotValidateSummary, Path, BadExtension);
+    }
+    return {Path.str(), Format};
+  }
+};
+
+struct LinkerInput {
+  std::vector<SummaryFile> InputFiles;
+  SummaryFile OutputFile;
+  std::string LinkUnitName;
+};
+
+static void PrintVersion(llvm::raw_ostream &OS) { OS << ToolName << " 0.1\n"; }
----------------
steakhal wrote:

In the LLVM coding style, new code should follow lowerCamelCast function names. 
Only legacy functions don't honour this. This applies to across this whole PR.

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