[clang] [clang][ssaf] Implement JSONFormat (PR #180021)
Aviral Goel via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 14 10:19:42 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();
----------------
aviralg wrote:
The ErrorBuilder class APIs are externally inaccessible and only used by JSONFormat.cpp. There is no way to trigger this case from the tests. While the ErrorBuilder class is designed only for handling errors in JSONFormat.cpp, the APIs have been crafted with a bit more generality than currently needed.
https://github.com/llvm/llvm-project/pull/180021
More information about the cfe-commits
mailing list