[clang] [clang][ssaf] Implement JSONFormat (PR #180021)

Balázs Benics via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 12 08:47:13 PST 2026


================
@@ -0,0 +1,966 @@
+#include "clang/Analysis/Scalable/Serialization/JSONFormat.h"
+#include "clang/Analysis/Scalable/TUSummary/TUSummary.h"
+
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/JSON.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Registry.h"
+
+using namespace clang::ssaf;
+
+using Array = llvm::json::Array;
+using Object = llvm::json::Object;
+using Value = llvm::json::Value;
+
+//----------------------------------------------------------------------------
+// ErrorBuilder - Fluent API for constructing contextual errors
+//----------------------------------------------------------------------------
+
+namespace {
+
+class ErrorBuilder {
+private:
+  std::error_code Code;
+  std::vector<std::string> ContextStack;
+
+  // Private constructor - only accessible via static factories
+  explicit ErrorBuilder(std::error_code EC) : Code(EC) {}
+
+  // Helper: Format message and add to context stack
+  template <typename... Args>
+  void addFormattedContext(const char *Fmt, Args &&...ArgVals) {
+    std::string Message =
+        llvm::formatv(Fmt, std::forward<Args>(ArgVals)...).str();
+    ContextStack.push_back(std::move(Message));
+  }
+
+public:
+  // Static factory: Create new error from error code and formatted message
+  template <typename... Args>
+  static ErrorBuilder create(std::error_code EC, const char *Fmt,
+                             Args &&...ArgVals) {
+    ErrorBuilder Builder(EC);
+    Builder.addFormattedContext(Fmt, std::forward<Args>(ArgVals)...);
+    return Builder;
+  }
+
+  // Convenience overload for std::errc
+  template <typename... Args>
+  static ErrorBuilder create(std::errc EC, const char *Fmt, Args &&...ArgVals) {
+    return create(std::make_error_code(EC), Fmt,
+                  std::forward<Args>(ArgVals)...);
+  }
+
+  // Static factory: Wrap existing error and optionally add context
+  static ErrorBuilder wrap(llvm::Error E) {
+    if (!E) {
+      llvm::consumeError(std::move(E));
+      // Return builder with generic error code for success case
+      return ErrorBuilder(std::make_error_code(std::errc::invalid_argument));
+    }
+
+    std::error_code EC;
+    std::string ErrorMsg;
+
+    llvm::handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EI) {
+      EC = EI.convertToErrorCode();
+      ErrorMsg = EI.message();
+    });
+
+    ErrorBuilder Builder(EC);
+    if (!ErrorMsg.empty()) {
+      Builder.ContextStack.push_back(std::move(ErrorMsg));
+    }
+    return Builder;
+  }
+
+  // Add context (plain string)
+  ErrorBuilder &context(const char *Msg) {
+    ContextStack.push_back(Msg);
+    return *this;
+  }
+
+  // Add context (formatted string)
+  template <typename... Args>
+  ErrorBuilder &context(const char *Fmt, Args &&...ArgVals) {
+    addFormattedContext(Fmt, std::forward<Args>(ArgVals)...);
+    return *this;
+  }
+
+  // Build the final error
+  llvm::Error build() {
+    if (ContextStack.empty())
+      return llvm::Error::success();
----------------
steakhal wrote:

This branch was not hit in the unit tests.

https://github.com/llvm/llvm-project/pull/180021


More information about the cfe-commits mailing list