[clang] [clang][ssaf] Consolidate tools and shared utilities under `clang/tools/clang-ssaf/` (PR #187439)
Aviral Goel via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 20 08:26:47 PDT 2026
https://github.com/aviralg updated https://github.com/llvm/llvm-project/pull/187439
>From ce22b377fb90dd28ffebe23cc3ad9fa11745d7a3 Mon Sep 17 00:00:00 2001
From: Aviral Goel <agoel26 at apple.com>
Date: Wed, 18 Mar 2026 22:08:00 -0700
Subject: [PATCH] Move common code out
---
.../Tool/Utils.h | 115 ++++++++++++++++
.../Tool/Utils.cpp | 127 +++++++++++++++++
clang/tools/CMakeLists.txt | 3 +-
clang/tools/clang-ssaf-format/SSAFFormat.cpp | 130 ++----------------
clang/tools/clang-ssaf-linker/SSAFLinker.cpp | 126 +++--------------
5 files changed, 270 insertions(+), 231 deletions(-)
create mode 100644 clang/include/clang/ScalableStaticAnalysisFramework/Tool/Utils.h
create mode 100644 clang/lib/ScalableStaticAnalysisFramework/Tool/Utils.cpp
diff --git a/clang/include/clang/ScalableStaticAnalysisFramework/Tool/Utils.h b/clang/include/clang/ScalableStaticAnalysisFramework/Tool/Utils.h
new file mode 100644
index 0000000000000..1667d6165f32d
--- /dev/null
+++ b/clang/include/clang/ScalableStaticAnalysisFramework/Tool/Utils.h
@@ -0,0 +1,115 @@
+//===- Utils.h - Shared utilities for SSAF tools ----------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Shared error-handling, format-registry cache, and summary-file abstraction
+// used by clang-ssaf-linker and clang-ssaf-format.
+//
+// All declarations live in the clang::ssaf::tool namespace.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_SSAF_UTILS_H
+#define CLANG_SSAF_UTILS_H
+
+#include "clang/ScalableStaticAnalysisFramework/Core/Serialization/SerializationFormatRegistry.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+
+namespace clang::ssaf::tool {
+
+//===----------------------------------------------------------------------===//
+// Tool Identity
+//===----------------------------------------------------------------------===//
+
+/// Identifies the running tool in diagnostic messages. Must be assigned in
+/// main() before any call to fail().
+extern llvm::StringRef ToolName;
+
+/// Prints "<ToolName> <ToolVersion>\n". Suitable for cl::SetVersionPrinter().
+void printVersion(llvm::raw_ostream &OS);
+
+//===----------------------------------------------------------------------===//
+// Error Messages
+//===----------------------------------------------------------------------===//
+
+namespace ErrorMessages {
+
+constexpr const char *CannotValidateSummary =
+ "failed to validate summary '{0}': {1}";
+
+constexpr const char *ExtensionNotSupplied = "Extension not supplied";
+
+constexpr const char *NoFormatForExtension =
+ "Format not registered for extension '{0}'";
+
+constexpr const char *OutputDirectoryMissing =
+ "Parent directory does not exist";
+
+constexpr const char *FailedToLoadPlugin = "failed to load plugin '{0}': {1}";
+
+} // namespace ErrorMessages
+
+//===----------------------------------------------------------------------===//
+// Diagnostic Utilities
+//===----------------------------------------------------------------------===//
+
+[[noreturn]] void fail(const char *Msg);
+
+template <typename... Ts>
+[[noreturn]] inline void fail(const char *Fmt, Ts &&...Args) {
+ std::string Message = llvm::formatv(Fmt, std::forward<Ts>(Args)...);
+ fail(Message.data());
+}
+
+[[noreturn]] void fail(llvm::Error Err);
+
+//===----------------------------------------------------------------------===//
+// Plugin Loading
+//===----------------------------------------------------------------------===//
+
+void loadPlugins(llvm::ArrayRef<std::string> Paths);
+
+//===----------------------------------------------------------------------===//
+// Initialization
+//===----------------------------------------------------------------------===//
+
+/// Sets ToolName, ToolVersion, and the version printer, hides unrelated
+/// command-line options, and parses arguments. Must be called after InitLLVM.
+void initTool(int argc, const char **argv, llvm::StringRef Version,
+ llvm::cl::OptionCategory &Category, llvm::StringRef ToolHeading);
+
+//===----------------------------------------------------------------------===//
+// Format Registry
+//===----------------------------------------------------------------------===//
+
+/// Returns the SerializationFormat registered for \p Extension, or nullptr if
+/// none is registered. Results are cached for the lifetime of the process.
+SerializationFormat *getFormatForExtension(llvm::StringRef Extension);
+
+//===----------------------------------------------------------------------===//
+// Data Structures
+//===----------------------------------------------------------------------===//
+
+struct SummaryFile {
+ std::string Path;
+ SerializationFormat *Format = nullptr;
+
+ /// Constructs a SummaryFile by resolving the serialization format from the
+ /// file extension. Calls fail() and exits if the extension is missing or
+ /// unregistered.
+ static SummaryFile fromPath(llvm::StringRef Path);
+};
+
+} // namespace clang::ssaf::tool
+
+#endif // CLANG_SSAF_UTILS_H
diff --git a/clang/lib/ScalableStaticAnalysisFramework/Tool/Utils.cpp b/clang/lib/ScalableStaticAnalysisFramework/Tool/Utils.cpp
new file mode 100644
index 0000000000000..295857e9244bd
--- /dev/null
+++ b/clang/lib/ScalableStaticAnalysisFramework/Tool/Utils.cpp
@@ -0,0 +1,127 @@
+//===- Utils.cpp - Shared utilities for SSAF tools -----------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "Utils.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <memory>
+#include <string>
+
+namespace clang::ssaf::tool {
+
+namespace path = llvm::sys::path;
+
+llvm::StringRef ToolName;
+static llvm::StringRef ToolVersion;
+
+void printVersion(llvm::raw_ostream &OS) {
+ OS << ToolName << " " << ToolVersion << "\n";
+}
+
+[[noreturn]] void fail(const char *Msg) {
+ llvm::WithColor::error(llvm::errs(), ToolName) << Msg << "\n";
+ llvm::sys::Process::Exit(1);
+}
+
+[[noreturn]] void fail(llvm::Error Err) {
+ std::string Message = llvm::toString(std::move(Err));
+ fail(Message.data());
+}
+
+void loadPlugins(llvm::ArrayRef<std::string> Paths) {
+ for (const std::string &PluginPath : Paths) {
+ std::string ErrMsg;
+ if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(PluginPath.c_str(),
+ &ErrMsg)) {
+ fail(ErrorMessages::FailedToLoadPlugin, PluginPath, ErrMsg);
+ }
+ }
+}
+
+void initTool(int argc, const char **argv, llvm::StringRef Version,
+ llvm::cl::OptionCategory &Category, llvm::StringRef ToolHeading) {
+ // path::stem strips the .exe extension on Windows so ToolName is consistent.
+ ToolName = path::stem(argv[0]);
+
+ // Set tool version for the version printer.
+ ToolVersion = Version;
+
+ // Hide options unrelated to the tool from --help output.
+ llvm::cl::HideUnrelatedOptions(Category);
+
+ // Register a custom version printer for the --version flag.
+ llvm::cl::SetVersionPrinter(printVersion);
+
+ // Parse command-line arguments and exit with an error if they are invalid.
+ std::string Overview = (ToolHeading + "\n").str();
+ llvm::cl::ParseCommandLineOptions(argc, argv, Overview);
+}
+
+// FIXME: This will be revisited after we add support for registering formats
+// with extensions.
+SerializationFormat *getFormatForExtension(llvm::StringRef Extension) {
+ // This cache is not thread-safe. SSAF tools are single-threaded CLIs, so
+ // concurrent calls to this function are not expected.
+
+ // Realistically, we don't expect to encounter more than four registered
+ // formats.
+ 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();
+ }
+
+ if (!isFormatRegistered(Extension)) {
+ return nullptr;
+ }
+
+ auto Format = makeFormat(Extension);
+ SerializationFormat *Result = Format.get();
+ assert(Result &&
+ "makeFormat must return non-null for a registered extension");
+
+ ExtensionFormatList.emplace_back(Extension, std::move(Format));
+
+ return Result;
+}
+
+SummaryFile 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};
+}
+
+} // namespace clang::ssaf::tool
diff --git a/clang/tools/CMakeLists.txt b/clang/tools/CMakeLists.txt
index 891043ec31f77..63af6c3dabe46 100644
--- a/clang/tools/CMakeLists.txt
+++ b/clang/tools/CMakeLists.txt
@@ -15,8 +15,7 @@ add_clang_subdirectory(clang-linker-wrapper)
add_clang_subdirectory(clang-nvlink-wrapper)
add_clang_subdirectory(clang-offload-bundler)
add_clang_subdirectory(clang-scan-deps)
-add_clang_subdirectory(clang-ssaf-format)
-add_clang_subdirectory(clang-ssaf-linker)
+add_clang_subdirectory(clang-ssaf)
add_clang_subdirectory(clang-sycl-linker)
add_clang_subdirectory(clang-installapi)
if(HAVE_CLANG_REPL_SUPPORT)
diff --git a/clang/tools/clang-ssaf-format/SSAFFormat.cpp b/clang/tools/clang-ssaf-format/SSAFFormat.cpp
index d91ff9402f7ec..379f9ca66dc4d 100644
--- a/clang/tools/clang-ssaf-format/SSAFFormat.cpp
+++ b/clang/tools/clang-ssaf-format/SSAFFormat.cpp
@@ -16,18 +16,16 @@
#include "clang/ScalableStaticAnalysisFramework/Core/Serialization/JSONFormat.h"
#include "clang/ScalableStaticAnalysisFramework/Core/Serialization/SerializationFormatRegistry.h"
#include "clang/ScalableStaticAnalysisFramework/SSAFForceLinker.h" // IWYU pragma: keep
+#include "clang/ScalableStaticAnalysisFramework/Tool/Utils.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
-#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <memory>
#include <optional>
@@ -36,6 +34,7 @@
using namespace llvm;
using namespace clang::ssaf;
+using namespace clang::ssaf::tool;
namespace {
@@ -84,87 +83,18 @@ cl::opt<bool> ListFormats("list",
"analyses, then exit"),
cl::init(false), cl::cat(SsafFormatCategory));
-llvm::StringRef ToolName;
-
-void printVersion(llvm::raw_ostream &OS) { OS << ToolName << " 0.1\n"; }
-
//===----------------------------------------------------------------------===//
// Error Messages
//===----------------------------------------------------------------------===//
-namespace ErrorMessages {
-
-constexpr const char *FailedToLoadPlugin = "failed to load plugin '{0}': {1}";
-
-constexpr const char *CannotValidateSummary =
- "failed to validate summary '{0}': {1}";
-
-constexpr const char *ExtensionNotSupplied = "Extension not supplied";
-
-constexpr const char *NoFormatForExtension =
- "Format not registered for extension '{0}'";
-
-constexpr const char *OutputDirectoryMissing =
- "Parent directory does not exist";
+namespace LocalErrorMessages {
constexpr const char *OutputFileAlreadyExists = "Output file already exists";
constexpr const char *InputOutputSamePath =
"Input and Output resolve to the same path";
-} // namespace ErrorMessages
-
-//===----------------------------------------------------------------------===//
-// Diagnostic Utilities
-//===----------------------------------------------------------------------===//
-
-[[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());
-}
-
-[[noreturn]] void fail(llvm::Error Err) {
- fail(toString(std::move(Err)).data());
-}
-
-//===----------------------------------------------------------------------===//
-// Format Registry
-//===----------------------------------------------------------------------===//
-
-// FIXME: This will be revisited after we add support for registering formats
-// with extensions.
-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();
- }
-
- if (!isFormatRegistered(Extension)) {
- return nullptr;
- }
-
- auto Format = makeFormat(Extension);
- SerializationFormat *Result = Format.get();
- assert(Result);
-
- ExtensionFormatList.emplace_back(Extension, std::move(Format));
-
- return Result;
-}
+} // namespace LocalErrorMessages
//===----------------------------------------------------------------------===//
// Format Listing
@@ -295,47 +225,10 @@ void listFormats() {
printFormats(Formats, computePrintLayout(Formats));
}
-//===----------------------------------------------------------------------===//
-// Plugin Loading
-//===----------------------------------------------------------------------===//
-
-void loadPlugins() {
- for (const auto &PluginPath : LoadPlugins) {
- std::string ErrMsg;
- if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(PluginPath.c_str(),
- &ErrMsg)) {
- fail(ErrorMessages::FailedToLoadPlugin, PluginPath, ErrMsg);
- }
- }
-}
-
//===----------------------------------------------------------------------===//
// Input Validation
//===----------------------------------------------------------------------===//
-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 Msg =
- llvm::formatv(ErrorMessages::NoFormatForExtension, Extension);
- fail(ErrorMessages::CannotValidateSummary, Path, Msg);
- }
-
- return {Path.str(), Format};
- }
-};
-
struct FormatInput {
SummaryFile InputFile;
std::optional<SummaryFile> OutputFile;
@@ -391,12 +284,12 @@ FormatInput validateInput() {
if (RealOutputPath == FI.InputFile.Path) {
fail(ErrorMessages::CannotValidateSummary, OutputPath,
- ErrorMessages::InputOutputSamePath);
+ LocalErrorMessages::InputOutputSamePath);
}
if (fs::exists(RealOutputPath)) {
fail(ErrorMessages::CannotValidateSummary, OutputPath,
- ErrorMessages::OutputFileAlreadyExists);
+ LocalErrorMessages::OutputFileAlreadyExists);
}
FI.OutputFile = SummaryFile::fromPath(RealOutputPath);
@@ -458,15 +351,12 @@ void convert(const FormatInput &FI) {
//===----------------------------------------------------------------------===//
int main(int argc, const char **argv) {
- InitLLVM X(argc, argv);
- // path::stem strips the .exe extension on Windows so ToolName is consistent.
- ToolName = path::stem(argv[0]);
+ llvm::StringRef ToolHeading = "SSAF Format";
- cl::HideUnrelatedOptions(SsafFormatCategory);
- cl::SetVersionPrinter(printVersion);
- cl::ParseCommandLineOptions(argc, argv, "SSAF Format\n");
+ InitLLVM X(argc, argv);
+ initTool(argc, argv, "0.1", SsafFormatCategory, ToolHeading);
- loadPlugins();
+ loadPlugins(LoadPlugins);
if (ListFormats) {
listFormats();
diff --git a/clang/tools/clang-ssaf-linker/SSAFLinker.cpp b/clang/tools/clang-ssaf-linker/SSAFLinker.cpp
index 3c57a2fe2cf98..77ac3978a23d2 100644
--- a/clang/tools/clang-ssaf-linker/SSAFLinker.cpp
+++ b/clang/tools/clang-ssaf-linker/SSAFLinker.cpp
@@ -14,9 +14,9 @@
#include "clang/ScalableStaticAnalysisFramework/Core/EntityLinker/EntityLinker.h"
#include "clang/ScalableStaticAnalysisFramework/Core/EntityLinker/TUSummaryEncoding.h"
#include "clang/ScalableStaticAnalysisFramework/Core/Model/BuildNamespace.h"
-#include "clang/ScalableStaticAnalysisFramework/Core/Serialization/SerializationFormatRegistry.h"
#include "clang/ScalableStaticAnalysisFramework/Core/Support/ErrorBuilder.h"
#include "clang/ScalableStaticAnalysisFramework/SSAFForceLinker.h" // IWYU pragma: keep
+#include "clang/ScalableStaticAnalysisFramework/Tool/Utils.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/CommandLine.h"
@@ -24,7 +24,6 @@
#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"
@@ -34,6 +33,7 @@
using namespace llvm;
using namespace clang::ssaf;
+using namespace clang::ssaf::tool;
namespace fs = llvm::sys::fs;
namespace path = llvm::sys::path;
@@ -59,53 +59,12 @@ cl::opt<bool> Verbose("verbose", cl::desc("Enable verbose output"),
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) {
- fail(toString(std::move(Err)).data());
-}
-
template <typename... Ts>
void info(unsigned IndentationLevel, const char *Fmt, Ts &&...Args) {
if (Verbose) {
@@ -115,74 +74,29 @@ void info(unsigned IndentationLevel, const char *Fmt, Ts &&...Args) {
}
}
-//===----------------------------------------------------------------------===//
-// 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();
- }
-
- if (!isFormatRegistered(Extension)) {
- return nullptr;
- }
-
- auto Format = makeFormat(Extension);
- 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"; }
-
//===----------------------------------------------------------------------===//
// Pipeline
//===----------------------------------------------------------------------===//
+namespace LocalErrorMessages {
+
+constexpr const char *OutputDirectoryNotWritable =
+ "Parent directory is not writable";
+
+constexpr const char *LinkingSummary = "Linking summary '{0}'";
+
+} // namespace LocalErrorMessages
+
LinkerInput validate(llvm::TimerGroup &TG) {
llvm::Timer TValidate("validate", "Validate Input", TG);
LinkerInput LI;
@@ -199,7 +113,7 @@ LinkerInput validate(llvm::TimerGroup &TG) {
if (fs::access(DirToCheck, fs::AccessMode::Write)) {
fail(ErrorMessages::CannotValidateSummary, OutputPath,
- ErrorMessages::OutputDirectoryNotWritable);
+ LocalErrorMessages::OutputDirectoryNotWritable);
}
LI.OutputFile = SummaryFile::fromPath(OutputPath);
@@ -264,7 +178,7 @@ void link(const LinkerInput &LI, llvm::TimerGroup &TG) {
if (auto Err = EL.link(std::move(Summary))) {
fail(ErrorBuilder::wrap(std::move(Err))
- .context(ErrorMessages::LinkingSummary, InputFile.Path)
+ .context(LocalErrorMessages::LinkingSummary, InputFile.Path)
.build());
}
}
@@ -290,18 +204,12 @@ void link(const LinkerInput &LI, llvm::TimerGroup &TG) {
//===----------------------------------------------------------------------===//
int main(int argc, const char **argv) {
- InitLLVM X(argc, argv);
- // path::stem strips the .exe extension on Windows so ToolName is consistent.
- ToolName = llvm::sys::path::stem(argv[0]);
+ llvm::StringRef ToolHeading = "SSAF Linker";
- // Hide options unrelated to clang-ssaf-linker from --help output.
- cl::HideUnrelatedOptions(SsafLinkerCategory);
- // Register a custom version printer for the --version flag.
- cl::SetVersionPrinter(printVersion);
- // Parse command-line arguments and exit with an error if they are invalid.
- cl::ParseCommandLineOptions(argc, argv, "SSAF Linker\n");
+ InitLLVM X(argc, argv);
+ initTool(argc, argv, "0.1", SsafLinkerCategory, ToolHeading);
- llvm::TimerGroup LinkerTimers(ToolName, "SSAF Linker");
+ llvm::TimerGroup LinkerTimers(ToolName, ToolHeading);
LinkerInput LI;
{
More information about the cfe-commits
mailing list