From b81ac4a7b9b709358d0ff8e52031c46fdb02cab6 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sat, 3 Jun 2023 17:32:43 -0700 Subject: [PATCH] chore: Refactor error handling and reporting --- CMakeLists.txt | 1 + include/mrdox/ADT/AnyList.hpp | 1 + include/mrdox/Config.hpp | 1 - include/mrdox/Corpus.hpp | 10 +- include/mrdox/Error.hpp | 158 ---------------- include/mrdox/Generator.hpp | 31 +--- include/mrdox/Reporter.hpp | 250 -------------------------- include/mrdox/Support/Error.hpp | 211 +++++++++++----------- include/mrdox/Support/Expected.hpp | 163 +++++++++++++++++ include/mrdox/Support/Report.hpp | 146 +++++++++++++++ source/-XML/XMLGenerator.cpp | 9 +- source/-XML/XMLGenerator.hpp | 5 +- source/-XML/XMLWriter.cpp | 12 +- source/-XML/XMLWriter.hpp | 8 +- source/-adoc/AdocGenerator.cpp | 16 +- source/-adoc/AdocGenerator.hpp | 10 +- source/-adoc/AdocMultiPageWriter.cpp | 5 +- source/-adoc/AdocMultiPageWriter.hpp | 3 +- source/-adoc/AdocPagesBuilder.cpp | 24 ++- source/-adoc/AdocPagesBuilder.hpp | 9 +- source/-adoc/AdocSinglePageWriter.cpp | 11 +- source/-adoc/AdocSinglePageWriter.hpp | 5 +- source/-adoc/AdocWriter.cpp | 12 +- source/-adoc/AdocWriter.hpp | 8 +- source/-bitcode/BitcodeGenerator.cpp | 51 +++--- source/-bitcode/BitcodeGenerator.hpp | 10 +- source/AST/ASTVisitor.cpp | 11 +- source/AST/ASTVisitor.hpp | 9 +- source/AST/AnyBlock.hpp | 243 ++++++++++++------------- source/AST/AnyNodeList.hpp | 128 ++++++------- source/AST/Bitcode.hpp | 8 +- source/AST/BitcodeReader.cpp | 117 ++++++------ source/AST/BitcodeReader.hpp | 29 ++- source/AST/DecodeRecord.hpp | 85 ++++----- source/AST/FrontendAction.cpp | 19 +- source/AST/FrontendAction.hpp | 4 +- source/AST/ParseJavadoc.cpp | 10 +- source/AST/ParseJavadoc.hpp | 4 +- source/Config.cpp | 2 +- source/ConfigImpl.cpp | 85 +++------ source/ConfigImpl.hpp | 40 ++--- source/Corpus.cpp | 35 ++-- source/CorpusImpl.cpp | 6 +- source/CorpusImpl.hpp | 3 +- source/GenerateAction.cpp | 65 ++----- source/Support/Error.cpp | 99 +--------- source/Support/Error.hpp | 58 ++++++ source/Support/Generator.cpp | 29 ++- source/Support/GeneratorsImpl.cpp | 13 +- source/Support/GeneratorsImpl.hpp | 4 +- source/Support/Report.cpp | 46 +++++ source/Support/Reporter.cpp | 72 -------- source/TestAction.cpp | 114 ++++++------ source/ToolMain.cpp | 24 ++- 54 files changed, 1128 insertions(+), 1404 deletions(-) delete mode 100644 include/mrdox/Error.hpp delete mode 100644 include/mrdox/Reporter.hpp create mode 100644 include/mrdox/Support/Expected.hpp create mode 100644 include/mrdox/Support/Report.hpp create mode 100644 source/Support/Error.hpp create mode 100644 source/Support/Report.cpp delete mode 100644 source/Support/Reporter.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 916f83b13..048442d2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -143,6 +143,7 @@ if (WIN32) -D_WIN32_WINNT=0x0601 -D_CRT_SECURE_NO_WARNINGS -D_SILENCE_CXX20_CISO646_REMOVED_WARNING + -DFMT_HEADER_ONLY # because of _ITERATOR_DEBUG_LEVEL ) get_target_property(LLVM_CONFIGURATION_TYPE LLVMCore IMPORTED_CONFIGURATIONS) if (LLVM_CONFIGURATION_TYPE STREQUAL RELWITHDEBINFO) diff --git a/include/mrdox/ADT/AnyList.hpp b/include/mrdox/ADT/AnyList.hpp index bbf870bfb..e7dab0375 100644 --- a/include/mrdox/ADT/AnyList.hpp +++ b/include/mrdox/ADT/AnyList.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/include/mrdox/Config.hpp b/include/mrdox/Config.hpp index 4e58d07c8..93f40a921 100644 --- a/include/mrdox/Config.hpp +++ b/include/mrdox/Config.hpp @@ -13,7 +13,6 @@ #define MRDOX_API_CONFIG_HPP #include -#include #include #include #include diff --git a/include/mrdox/Corpus.hpp b/include/mrdox/Corpus.hpp index 9eb021358..bfe8574bf 100644 --- a/include/mrdox/Corpus.hpp +++ b/include/mrdox/Corpus.hpp @@ -15,10 +15,8 @@ #include #include #include -#include #include #include -#include #include #include #include @@ -134,18 +132,14 @@ class MRDOX_VISIBLE /** Build metadata for a set of translation units. @param config A shared pointer to the configuration. - - @param R The diagnostic reporting object to - use for delivering errors and information. */ MRDOX_DECL [[nodiscard]] static - llvm::Expected> + Expected> build( tooling::ToolExecutor& ex, - std::shared_ptr config, - Reporter& R); + std::shared_ptr config); // KRYSTIAN NOTE: temporary MRDOX_DECL diff --git a/include/mrdox/Error.hpp b/include/mrdox/Error.hpp deleted file mode 100644 index db5917497..000000000 --- a/include/mrdox/Error.hpp +++ /dev/null @@ -1,158 +0,0 @@ -// -// This is a derivative work. originally part of the LLVM Project. -// Licensed 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 -// -// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) -// -// Official repository: https://github.com/cppalliance/mrdox -// - -#ifndef MRDOX_API_ERROR_HPP -#define MRDOX_API_ERROR_HPP - -#include -#include -#include -#include -#include -#include -#include - -namespace clang { -namespace mrdox { - -//------------------------------------------------ - -class Err -{ - std::string text_; - -public: - Err() = default; - - explicit - Err(std::string text) - : text_(std::move(text)) - { - } - - explicit - operator bool() const noexcept - { - return ! text_.empty(); - } - - std::string_view - message() const noexcept - { - return text_; - } -}; - -//------------------------------------------------ -/* - nice output for variadic error functions - - These are used to convert arguments to - strings in makeError and Reporter members. -*/ - -template -T& nice(T& t) -{ - return t; -} - -template -T&& nice(T&& t) -{ - return std::forward(t); -} - -template -auto nice(llvm::Expected&& e) -{ - return nice(e.takeError()); -} - -inline auto nice(std::error_code ec) -{ - return ec.message(); -} - -inline auto nice(Err e) -{ - return e.message(); -} - -template -auto nice(llvm::ErrorOr&& e) -{ - return nice(e.getError()); -} - -MRDOX_DECL -llvm::StringRef -nice(std::source_location loc); - -//------------------------------------------------ - -/** Return an Error with descriptive information. - - @param reason A phrase describing the cause of the failure. - - @param loc The source location where the failure occurred. -*/ -MRDOX_DECL -[[nodiscard]] -llvm::Error -makeErrorString( - std::string reason, - std::source_location loc = - std::source_location::current()); - -template -struct makeError : llvm::Error -{ - makeError( - Arg0&& arg0, - Args&&... args, - std::source_location loc = - std::source_location::current()) - : llvm::Error( - [&] - { - std::string temp; - llvm::raw_string_ostream os(temp); - os << nice(std::forward(arg0)); - if constexpr(sizeof...(args) > 0) - (os << ... << nice(std::forward(args))); - os << ' ' << nice(loc); - return makeErrorString(std::move(temp), loc); - }()) - { - } -}; - -template -makeError(Arg0&&, Args&&...) -> makeError; - -template -Err makeErr(Args&&... args) -{ - auto err = makeError(std::forward(args)...); - if(! err) - return Err(); - std::string s; - llvm::raw_string_ostream os(s); - os << err; - return Err(s.c_str()); -} - - -} // mrdox -} // clang - -#endif diff --git a/include/mrdox/Generator.hpp b/include/mrdox/Generator.hpp index 21c15cdff..b402e8401 100644 --- a/include/mrdox/Generator.hpp +++ b/include/mrdox/Generator.hpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -91,17 +91,13 @@ class MRDOX_VISIBLE the object before returning. @param config The configuration to use. - - @param R The diagnostic reporting object to - use for delivering errors and information. */ MRDOX_DECL virtual - Err + Error build( std::string_view outputPath, - Corpus const& corpus, - Reporter& R) const; + Corpus const& corpus) const; /** Build reference documentation for the corpus. @@ -118,16 +114,13 @@ class MRDOX_VISIBLE @param os The stream to write to. @param corpus The metadata to emit. - - @param R The diagnostic reporting object to use. */ MRDOX_DECL virtual - Err + Error buildOne( std::ostream& os, - Corpus const& corpus, - Reporter& R) const = 0; + Corpus const& corpus) const = 0; /** Build the reference as a single page to a file. @@ -141,15 +134,12 @@ class MRDOX_VISIBLE file already exists, it will be overwritten. @param corpus The metadata to emit. - - @param R The diagnostic reporting object to use. */ MRDOX_DECL - Err + Error buildOne( std::string_view fileName, - Corpus const& corpus, - Reporter& R) const; + Corpus const& corpus) const; /** Build the reference as a single page to a string. @@ -160,15 +150,12 @@ class MRDOX_VISIBLE not be accessed by any other threads. @param corpus The metadata to emit. - - @param R The diagnostic reporting object to use. */ MRDOX_DECL - Err + Error buildOneString( std::string& dest, - Corpus const& corpus, - Reporter& R) const; + Corpus const& corpus) const; }; } // mrdox diff --git a/include/mrdox/Reporter.hpp b/include/mrdox/Reporter.hpp deleted file mode 100644 index df1ba4b71..000000000 --- a/include/mrdox/Reporter.hpp +++ /dev/null @@ -1,250 +0,0 @@ -// -// This is a derivative work. originally part of the LLVM Project. -// Licensed 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 -// -// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) -// -// Official repository: https://github.com/cppalliance/mrdox -// - -#ifndef MRDOX_API_REPORTER_HPP -#define MRDOX_API_REPORTER_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace clang { -namespace mrdox { - -/** Used to check and report errors uniformly. -*/ -class Reporter -{ -public: - /** Return a suitable exit code. - */ - int getExitCode() const noexcept; - - /** Print formatted output. - - @param arg0, args The values to write. - */ - template - void - print( - Arg0&& arg, Args&&... args); - - /** Report the failure of an action. - - @param arg0, args The values to write. - */ - template - void - failed( - Arg0&& arg, Args&&... args); - - /** Return true and report a message if an error is indicated. - - The error object `e` is inspected for a failure - condition. If `e` does not contain a failure, - then this function returns `false`. Otherwise - the function emits a diagnostic message to the - error channel and returns `true`. - - @par Output - The diagnostic message will always have the form: - @code - error: couldn't %1 because %2 - @endcode - The first string is formed from the `actionFormat` - parameter and the variadic list of arguments, - while the second string is formed from the error - object. - - If source location information is available, it - is reported on additional indented lines following - the diagnostic message. - - @par Effects - The number of errors seen by the reporter - is incremented by one. - - @return true if `e` indicates a failure. - - @param e The error object to inspect. - - @param arg0, args The values to write. - */ - /** @{ */ - template< - class E, - class Arg0, class... Args> - [[nodiscard]] - bool - error( - E&& e, - Arg0&& arg0, - Args&&... args); - - template< - class E, - class Arg0, class... Args> - [[nodiscard]] - bool - error( - E& e, - Arg0&& arg0, - Args&&... args); - /** @} */ - - //-------------------------------------------- - - /** Increment the count of errors. - - @par Thread Safety - May be called concurrently. - */ - void - reportError(); - -private: - //-------------------------------------------- - - template - static bool isFailure(llvm::Expected&& e) noexcept - { - return ! e.operator bool(); - } - - template - static bool isFailure(llvm::ErrorOr&& e) noexcept - { - return ! e.operator bool(); - } - - static bool isFailure(Err const& e) noexcept - { - return e.operator bool(); - } - - static bool isFailure(llvm::Error&& e) noexcept - { - return e.operator bool(); - } - - static bool isFailure(std::error_code&& ec) noexcept - { - return ec.operator bool(); - } - - void - threadSafePrint( - llvm::raw_fd_ostream& os, - llvm::StringRef s, - std::size_t* n = nullptr); - - static std::string& temp_string(); - -private: - llvm::sys::Mutex mutable m_; - std::size_t errorCount_ = 0; -}; - -//------------------------------------------------ - -template< - class Arg0, class... Args> -void -Reporter:: -print( - Arg0&& arg, - Args&&... args) -{ - auto& temp = temp_string(); - temp.clear(); - { - llvm::raw_string_ostream os(temp); - os << nice(std::forward(arg)); - if constexpr(sizeof...(args) > 0) - (os << ... << nice(std::forward(args))); - } - threadSafePrint(llvm::outs(), temp, nullptr); -} - -template< - class Arg0, class... Args> -void -Reporter:: -failed( - Arg0&& arg, - Args&&... args) -{ - auto& temp = temp_string(); - temp.clear(); - { - llvm::raw_string_ostream os(temp); - os << "error: Couldn't "; - os << nice(std::forward(arg)); - if constexpr(sizeof...(args) > 0) - (os << ... << nice(std::forward(args))); - os << "."; - } - threadSafePrint(llvm::errs(), temp, &errorCount_); -} - -template< - class E, - class Arg0, class... Args> -bool -Reporter:: -error( - E&& e, - Arg0&& arg0, - Args&&... args) -{ - if(! isFailure(std::forward(e))) - return false; - auto& temp = temp_string(); - temp.clear(); - { - llvm::raw_string_ostream os(temp); - os << "error: Couldn't "; - os << nice(std::forward(arg0)); - if constexpr(sizeof...(args) > 0) - (os << ... << nice(std::forward(args))); - os << " because " << nice(std::forward(e)) << '.'; - } - threadSafePrint(llvm::errs(), temp, &errorCount_); - return true; -} - -template< - class E, - class Arg0, class... Args> -bool -Reporter:: -error( - E& e, - Arg0&& arg0, - Args&&... args) -{ - return error( - std::move(e), - std::forward(arg0), - std::forward(args)...); -} - -} // mrdox -} // clang - -#endif diff --git a/include/mrdox/Support/Error.hpp b/include/mrdox/Support/Error.hpp index 7ee560561..80abd9c39 100644 --- a/include/mrdox/Support/Error.hpp +++ b/include/mrdox/Support/Error.hpp @@ -13,146 +13,157 @@ #define MRDOX_API_SUPPORT_ERROR_HPP #include -#include -#include +#include +#include #include #include #include +#include #include namespace clang { namespace mrdox { -//------------------------------------------------ - -class Err +/** Holds the description of an error, or success. +*/ +class [[nodiscard]] Error { std::string text_; + std::source_location loc_; public: - Err() = default; + /** Constructor. + + A default constructed error is + equivalent to success. + */ + Error() = default; + + /** Constructor. + */ + Error(Error&&) = default; + + /** Constructor. + */ + Error(Error const&) = default; + + /** Constructor. + */ + Error& operator=(Error&&) = default; + + /** Assignment. + */ + Error& operator=(Error const&) = default; + /** Constructor. + + @param text A message describing the error. + An empty string indicates success. + */ explicit - Err(std::string text) - : text_(std::move(text)) + Error( + std::string_view text) + : text_(text) { } + /** Constructor. + + @param fs The format string. An empty + string indicates success. + + @param arg0,args The arguments to use + with the format string. + */ + template explicit - operator bool() const noexcept + Error( + fmt::format_string fs, + Arg0&& arg0, Args&&... args) + { + text_ = fmt::format(fs, + std::forward(arg0), + std::forward(args)...); + } + + /** Constructor. + + @param ec The error code. + */ + explicit + Error( + std::error_code const& ec) + : Error(ec + ? std::string_view(ec.message()) + : std::string_view()) + { + } + + /** Return true if this holds an error. + */ + bool failed() const noexcept { return ! text_.empty(); } + /** Return true if this holds an error. + */ + explicit + operator bool() const noexcept + { + return failed(); + } + + /** Return the error string. + */ std::string_view message() const noexcept { return text_; } -}; - -//------------------------------------------------ -/* - nice output for variadic error functions - - These are used to convert arguments to - strings in makeError and Reporter members. -*/ -template -T& nice(T& t) -{ - return t; -} - -template -T&& nice(T&& t) -{ - return std::forward(t); -} - -template -auto nice(llvm::Expected&& e) -{ - return nice(e.takeError()); -} - -inline auto nice(std::error_code ec) -{ - return ec.message(); -} - -inline auto nice(Err e) -{ - return e.message(); -} + /** Return a value indicating success. + */ + static + Error + success() noexcept; +}; -template -auto nice(llvm::ErrorOr&& e) +inline +Error +Error:: +success() noexcept { - return nice(e.getError()); + return Error(); } -MRDOX_DECL -llvm::StringRef -nice(std::source_location loc); +} // mrdox +} // clang //------------------------------------------------ -/** Return an Error with descriptive information. - - @param reason A phrase describing the cause of the failure. - - @param loc The source location where the failure occurred. -*/ -MRDOX_DECL -[[nodiscard]] -llvm::Error -makeErrorString( - std::string reason, - std::source_location loc = - std::source_location::current()); - -template -struct makeError : llvm::Error +template<> +struct fmt::formatter + : fmt::formatter { - makeError( - Arg0&& arg0, - Args&&... args, - std::source_location loc = - std::source_location::current()) - : llvm::Error( - [&] - { - std::string temp; - llvm::raw_string_ostream os(temp); - os << nice(std::forward(arg0)); - if constexpr(sizeof...(args) > 0) - (os << ... << nice(std::forward(args))); - os << ' ' << nice(loc); - return makeErrorString(std::move(temp), loc); - }()) + auto format( + clang::mrdox::Error const& err, + fmt::format_context& ctx) const { + return fmt::formatter::format(err.message(), ctx); } }; -template -makeError(Arg0&&, Args&&...) -> makeError; - -template -Err makeErr(Args&&... args) +template<> +struct fmt::formatter + : fmt::formatter { - auto err = makeError(std::forward(args)...); - if(! err) - return Err(); - std::string s; - llvm::raw_string_ostream os(s); - os << err; - return Err(s.c_str()); -} - - -} // mrdox -} // clang + auto format( + std::error_code const& ec, + fmt::format_context& ctx) const + { + return fmt::formatter::format(ec.message(), ctx); + } +}; #endif diff --git a/include/mrdox/Support/Expected.hpp b/include/mrdox/Support/Expected.hpp new file mode 100644 index 000000000..dcfc97280 --- /dev/null +++ b/include/mrdox/Support/Expected.hpp @@ -0,0 +1,163 @@ +// +// This is a derivative work. originally part of the LLVM Project. +// Licensed 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 +// +// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) +// +// Official repository: https://github.com/cppalliance/mrdox +// + +#ifndef MRDOX_API_SUPPORT_EXPECTED_HPP +#define MRDOX_API_SUPPORT_EXPECTED_HPP + +#include +#include +#include +#include +#include + +namespace clang { +namespace mrdox { + +/** A container holding an error or a value. +*/ +template +class [[nodiscard]] Expected +{ + static_assert(! std::is_reference_v); + + union + { + T t_; + Error e_; + }; + bool has_error_; + +public: + using value_type = T; + using pointer = std::remove_reference_t*; + using reference = std::remove_reference_t&; + using const_pointer = std::remove_reference_t const*; + using const_reference = std::remove_reference_t const&; + + Expected(Expected const&) = delete; + Expected& operator=(Expected const&) = delete; + + /** Destructor. + */ + ~Expected() + { + if(has_error_) + e_.~Error(); + else + t_.~T(); + } + + /** Constructor. + + @param err The error. + */ + Expected( + Error err) noexcept + : has_error_(true) + { + assert(err.failed()); + new(&e_) Error(std::move(err)); + } + + Expected(Expected&& other) + : has_error_(other.has_error_) + { + if(other.has_error_) + new(&e_) Error(std::move(other.e_)); + else + new(&t_) T(std::move(other.t_)); + } + + template + requires std::is_convertible_v + Expected(U&& u) + : has_error_(false) + { + new(&t_) T(std::forward(u)); + } + + Expected& operator=(Expected&& other) + { + if(this != &other) + { + this->~Expected(); + new(this) Expected(std::move(other)); + } + return *this; + } + + template + requires std::is_convertible_v + Expected& operator=(Expected&& other) + { + this->~Expected(); + new(this) Expected(std::move(other)); + return *this; + } + + Error const& + getError() const + { + assert(has_error_); + return e_; + } + + bool has_value() const noexcept + { + return ! has_error_; + } + + explicit operator bool() + { + return ! has_error_; + } + + reference get() noexcept + { + assert(! has_error_); + return t_; + }; + + const_reference get() const noexcept + { + assert(! has_error_); + return t_; + }; + + pointer operator->() noexcept + { + assert(! has_error_); + return &t_; + } + + reference operator*() noexcept + { + assert(! has_error_); + return t_; + } + + const_pointer operator->() const noexcept + { + assert(! has_error_); + return &t_; + } + + const_reference operator*() const noexcept + { + assert(! has_error_); + return t_; + } +}; + +} // mrdox +} // clang + +#endif diff --git a/include/mrdox/Support/Report.hpp b/include/mrdox/Support/Report.hpp new file mode 100644 index 000000000..7079d837b --- /dev/null +++ b/include/mrdox/Support/Report.hpp @@ -0,0 +1,146 @@ +// +// Licensed 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 +// +// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) +// +// Official repository: https://github.com/cppalliance/mrdox +// + +#ifndef MRDOX_API_SUPPORT_REPORT_HPP +#define MRDOX_API_SUPPORT_REPORT_HPP + +#include +#include +#include +#include +#include + +namespace clang { +namespace mrdox { + +/** Report an error to the console. + + @param text The message contents. A newline + will be added automatically to the output. +*/ +MRDOX_DECL +void +reportError( + std::string_view text); + +/** Format an error to the console. + + @param fs The operation format string. + + @param arg0,args The arguments to use + with the format string. +*/ +template +void +reportError( + fmt::format_string fs, + Arg0&& arg0, Args&&... args) +{ + reportError(fmt::format(fs, + std::forward(arg0), + std::forward(args)...)); +} + +/** Format an error to the console. + + This function formats an error message + to the console, of the form: + @code + "Could not {1} because {2}." + @endcode + Where 1 is the operation which failed, + specified by the format arguments, and + 2 is the reason for the failure. + + @param err The error which occurred. + + @param fs The operation format string. + + @param arg0,args The arguments to use + with the format string. +*/ +template +void +reportError( + Error const& err, + fmt::format_string fs, + Args&&... args) +{ + assert(err.failed()); + reportError(fmt::format( + "Could not {} because {}", + fmt::format(fs, std::forward(args)...), + err.message())); +} + +/** Report a warning to the console. + + @param text The message contents. A newline + will be added automatically to the output. +*/ +MRDOX_DECL +void +reportWarning( + std::string_view text); + +/** Format a warning to the console. + + @param fs The message format string. + A newline will be added automatically + to the output. + + @param arg0,args The arguments to use + with the format string. +*/ +template +void +reportWarning( + fmt::format_string fs, + Arg0&& arg0, Args&&... args) +{ + reportWarning(fmt::format(fs, + std::forward(arg0), + std::forward(args)...)); +} + +/** Report information to the console. + + @param text The message contents. A newline + will be added automatically to the output. +*/ +MRDOX_DECL +void +reportInfo( + std::string_view text); + +/** Format information to the console. + + @param fs The message format string. + A newline will be added automatically + to the output. + + @param arg0,args The arguments to use + with the format string. +*/ +template +void +reportInfo( + fmt::format_string fs, + Arg0&& arg0, Args&&... args) +{ + reportInfo(fmt::format(fs, + std::forward(arg0), + std::forward(args)...)); +} + +} // mrdox +} // clang + +#endif diff --git a/source/-XML/XMLGenerator.cpp b/source/-XML/XMLGenerator.cpp index 7333e6abb..a9fb5a1dd 100644 --- a/source/-XML/XMLGenerator.cpp +++ b/source/-XML/XMLGenerator.cpp @@ -13,23 +13,22 @@ #include "XMLWriter.hpp" #include "Support/Radix.hpp" #include "Support/RawOstream.hpp" -#include +#include #include namespace clang { namespace mrdox { namespace xml { -Err +Error XMLGenerator:: buildOne( std::ostream& os, - Corpus const& corpus, - Reporter& R) const + Corpus const& corpus) const { namespace fs = llvm::sys::fs; RawOstream raw_os(os); - return XMLWriter(raw_os, corpus, R).build(); + return XMLWriter(raw_os, corpus).build(); } } // xml diff --git a/source/-XML/XMLGenerator.hpp b/source/-XML/XMLGenerator.hpp index 24e1744ba..5d3d48ce6 100644 --- a/source/-XML/XMLGenerator.hpp +++ b/source/-XML/XMLGenerator.hpp @@ -44,11 +44,10 @@ struct XMLGenerator : Generator return "xml"; } - Err + Error buildOne( std::ostream& os, - Corpus const& corpus, - Reporter& R) const override; + Corpus const& corpus) const override; }; } // xml diff --git a/source/-XML/XMLWriter.cpp b/source/-XML/XMLWriter.cpp index 6ea52e3f5..017e822d6 100644 --- a/source/-XML/XMLWriter.cpp +++ b/source/-XML/XMLWriter.cpp @@ -108,16 +108,14 @@ namespace xml { XMLWriter:: XMLWriter( llvm::raw_ostream& os, - Corpus const& corpus, - Reporter& R) noexcept + Corpus const& corpus) noexcept : tags_(os) , os_(os) , corpus_(corpus) - , R_(R) { } -Err +Error XMLWriter:: build() { @@ -128,7 +126,7 @@ build() yin.setAllowUnknownKeys(true); yin >> options_; if(auto ec = yin.error()) - return makeErr(ec); + return Error(ec); } { llvm::yaml::Input yin( @@ -137,7 +135,7 @@ build() yin.setAllowUnknownKeys(true); yin >> options_; if(auto ec = yin.error()) - return makeErr(ec); + return Error(ec); } if(options_.prolog) @@ -150,7 +148,7 @@ build() writeIndex(); if(! corpus_.traverse(*this, SymbolID::zero)) - return makeErr("visit failed"); + return Error("visitation aborted"); if(options_.prolog) os_ << "\n"; diff --git a/source/-XML/XMLWriter.hpp b/source/-XML/XMLWriter.hpp index 4d7540176..d9403b198 100644 --- a/source/-XML/XMLWriter.hpp +++ b/source/-XML/XMLWriter.hpp @@ -14,9 +14,9 @@ #include "XMLTags.hpp" #include "Support/YamlFwd.hpp" -#include #include #include +#include #include namespace clang { @@ -37,7 +37,6 @@ class XMLWriter XMLTags tags_; llvm::raw_ostream& os_; Corpus const& corpus_; - Reporter& R_; struct GenKey; struct XmlKey; @@ -52,10 +51,9 @@ class XMLWriter public: XMLWriter( llvm::raw_ostream& os, - Corpus const& corpus, - Reporter& R) noexcept; + Corpus const& corpus) noexcept; - Err build(); + Error build(); private: void writeIndex(); diff --git a/source/-adoc/AdocGenerator.cpp b/source/-adoc/AdocGenerator.cpp index fd35f8173..37bafc084 100644 --- a/source/-adoc/AdocGenerator.cpp +++ b/source/-adoc/AdocGenerator.cpp @@ -26,28 +26,26 @@ namespace adoc { // //------------------------------------------------ -Err +Error AdocGenerator:: build( std::string_view outputPath, - Corpus const& corpus, - Reporter& R) const + Corpus const& corpus) const { if(corpus.config.singlePage) - return Generator::build(outputPath, corpus, R); + return Generator::build(outputPath, corpus); return AdocPagesBuilder( - llvm::StringRef(outputPath), corpus, R).build(); + llvm::StringRef(outputPath), corpus).build(); } -Err +Error AdocGenerator:: buildOne( std::ostream& os, - Corpus const& corpus, - Reporter& R) const + Corpus const& corpus) const { RawOstream raw_os(os); - return AdocSinglePageWriter(raw_os, corpus, R).build(); + return AdocSinglePageWriter(raw_os, corpus).build(); } } // adoc diff --git a/source/-adoc/AdocGenerator.hpp b/source/-adoc/AdocGenerator.hpp index c2711558d..550325130 100644 --- a/source/-adoc/AdocGenerator.hpp +++ b/source/-adoc/AdocGenerator.hpp @@ -45,17 +45,15 @@ class AdocGenerator return "adoc"; } - Err + Error build( std::string_view outputPath, - Corpus const& corpus, - Reporter& R) const override; + Corpus const& corpus) const override; - Err + Error buildOne( std::ostream& os, - Corpus const& corpus, - Reporter& R) const override; + Corpus const& corpus) const override; }; } // adoc diff --git a/source/-adoc/AdocMultiPageWriter.cpp b/source/-adoc/AdocMultiPageWriter.cpp index 65039ce60..a928485ba 100644 --- a/source/-adoc/AdocMultiPageWriter.cpp +++ b/source/-adoc/AdocMultiPageWriter.cpp @@ -20,9 +20,8 @@ AdocMultiPageWriter:: AdocMultiPageWriter( llvm::raw_ostream& os, Corpus const& corpus, - SafeNames const& names, - Reporter& R) noexcept - : AdocWriter(os, names, corpus, R) + SafeNames const& names) noexcept + : AdocWriter(os, names, corpus) , names_(names) { } diff --git a/source/-adoc/AdocMultiPageWriter.hpp b/source/-adoc/AdocMultiPageWriter.hpp index eb721d12b..101fd8929 100644 --- a/source/-adoc/AdocMultiPageWriter.hpp +++ b/source/-adoc/AdocMultiPageWriter.hpp @@ -28,8 +28,7 @@ class AdocMultiPageWriter AdocMultiPageWriter( llvm::raw_ostream& os, Corpus const& corpus, - SafeNames const& names, - Reporter& R) noexcept; + SafeNames const& names) noexcept; void build(NamespaceInfo const&); void build(RecordInfo const&); diff --git a/source/-adoc/AdocPagesBuilder.cpp b/source/-adoc/AdocPagesBuilder.cpp index b82fce240..130480fc3 100644 --- a/source/-adoc/AdocPagesBuilder.cpp +++ b/source/-adoc/AdocPagesBuilder.cpp @@ -10,8 +10,10 @@ #include "AdocPagesBuilder.hpp" #include "AdocMultiPageWriter.hpp" +#include "Support/Error.hpp" #include "Support/Radix.hpp" #include +#include #include #include #include @@ -20,7 +22,7 @@ namespace clang { namespace mrdox { namespace adoc { -Err +Error AdocPagesBuilder:: build() { @@ -47,13 +49,21 @@ build( filePath.append(".adoc"); std::error_code ec; llvm::raw_fd_ostream os(filePath, ec, fs::CD_CreateAlways); - if(! R_.error(ec, "open '", filePath, "'")) + if(ec) { - AdocMultiPageWriter writer(os, corpus_, names_, R_); - writer.build(I); - if(auto ec = os.error()) - if(R_.error(ec, "write '", filePath, "'")) - return; + reportError( + Error("raw_fd_ostream(\"{}\") returned \"{}\"", filePath, ec.message()), + "generate Asciidoc reference"); + return; + } + AdocMultiPageWriter writer(os, corpus_, names_); + writer.build(I); + if(auto ec = os.error()) + { + reportError( + Error("AdocMultiPageWriter returned \"{}\"", ec.message()), + "generate Asciidoc reference"); + return; } }); } diff --git a/source/-adoc/AdocPagesBuilder.hpp b/source/-adoc/AdocPagesBuilder.hpp index 6523ca289..0a567105f 100644 --- a/source/-adoc/AdocPagesBuilder.hpp +++ b/source/-adoc/AdocPagesBuilder.hpp @@ -12,9 +12,9 @@ #define MRDOX_ADOC_ADOCPAGESBUILDER_HPP #include "Support/SafeNames.hpp" -#include #include #include +#include #include namespace clang { @@ -25,7 +25,6 @@ class AdocPagesBuilder : public Corpus::Visitor { Corpus const& corpus_; - Reporter& R_; SafeNames names_; llvm::StringRef outputPath_; Config::WorkGroup wg_; @@ -33,17 +32,15 @@ class AdocPagesBuilder public: AdocPagesBuilder( llvm::StringRef outputPath, - Corpus const& corpus, - Reporter& R) + Corpus const& corpus) : corpus_(corpus) - , R_(R) , names_(corpus_) , outputPath_(outputPath) , wg_(&corpus.config) { } - Err build(); + Error build(); template void build(T const& I); diff --git a/source/-adoc/AdocSinglePageWriter.cpp b/source/-adoc/AdocSinglePageWriter.cpp index a02d3c1fc..7047fb1e3 100644 --- a/source/-adoc/AdocSinglePageWriter.cpp +++ b/source/-adoc/AdocSinglePageWriter.cpp @@ -19,19 +19,18 @@ namespace adoc { AdocSinglePageWriter:: AdocSinglePageWriter( llvm::raw_ostream& os, - Corpus const& corpus, - Reporter& R) noexcept - : AdocWriter(os, names_, corpus, R) + Corpus const& corpus) noexcept + : AdocWriter(os, names_, corpus) , names_(corpus) { } -Err +Error AdocSinglePageWriter:: build() { - if(auto E = AdocWriter::init()) - return makeErr("init failed"); + if(auto err = AdocWriter::init()) + return err; Assert(sect_.level == 0); sect_.level = 1; sect_.markup = "="; diff --git a/source/-adoc/AdocSinglePageWriter.hpp b/source/-adoc/AdocSinglePageWriter.hpp index ea6f59d61..ed9eb92c5 100644 --- a/source/-adoc/AdocSinglePageWriter.hpp +++ b/source/-adoc/AdocSinglePageWriter.hpp @@ -28,10 +28,9 @@ class AdocSinglePageWriter public: AdocSinglePageWriter( llvm::raw_ostream& os, - Corpus const& corpus, - Reporter& R) noexcept; + Corpus const& corpus) noexcept; - Err build(); + Error build(); private: /** Return an array of info pointers display-sorted by symbol. diff --git a/source/-adoc/AdocWriter.cpp b/source/-adoc/AdocWriter.cpp index 71fd50e5e..4422f8aa5 100644 --- a/source/-adoc/AdocWriter.cpp +++ b/source/-adoc/AdocWriter.cpp @@ -166,16 +166,14 @@ AdocWriter:: AdocWriter( llvm::raw_ostream& os, SafeNames const& names, - Corpus const& corpus, - Reporter& R) noexcept + Corpus const& corpus) noexcept : names_(names) , os_(os) , corpus_(corpus) - , R_(R) { } -llvm::Error +Error AdocWriter:: init() { @@ -186,7 +184,7 @@ init() yin.setAllowUnknownKeys(true); yin >> options_; if(auto ec = yin.error()) - return makeError(ec); + return Error(ec); } { llvm::yaml::Input yin( @@ -195,10 +193,10 @@ init() yin.setAllowUnknownKeys(true); yin >> options_; if(auto ec = yin.error()) - return makeError(ec); + return Error(ec); } - return llvm::Error::success(); + return Error::success(); } //------------------------------------------------ diff --git a/source/-adoc/AdocWriter.hpp b/source/-adoc/AdocWriter.hpp index 0f3b73cb4..ebbf6a6e5 100644 --- a/source/-adoc/AdocWriter.hpp +++ b/source/-adoc/AdocWriter.hpp @@ -14,9 +14,9 @@ #include "Support/SafeNames.hpp" #include "Support/YamlFwd.hpp" -#include #include #include +#include #include namespace clang { @@ -61,7 +61,6 @@ class AdocWriter llvm::raw_ostream& os_; Corpus const& corpus_; - Reporter& R_; Section sect_; std::string temp_; @@ -72,10 +71,9 @@ class AdocWriter AdocWriter( llvm::raw_ostream& os, SafeNames const& names, - Corpus const& corpus, - Reporter& R) noexcept; + Corpus const& corpus) noexcept; - llvm::Error init(); + Error init(); struct FormalParam; struct TypeName; diff --git a/source/-bitcode/BitcodeGenerator.cpp b/source/-bitcode/BitcodeGenerator.cpp index 315b25d54..1142464d3 100644 --- a/source/-bitcode/BitcodeGenerator.cpp +++ b/source/-bitcode/BitcodeGenerator.cpp @@ -10,9 +10,10 @@ // #include "BitcodeGenerator.hpp" +#include "Support/Error.hpp" #include "Support/SafeNames.hpp" #include "AST/Bitcode.hpp" -#include +#include #include namespace clang { @@ -22,7 +23,6 @@ namespace bitcode { class MultiFileBuilder : public Corpus::Visitor { Corpus const& corpus_; - Reporter& R_; std::string_view outputPath_; SafeNames names_; Config::WorkGroup wg_; @@ -30,22 +30,20 @@ class MultiFileBuilder : public Corpus::Visitor public: MultiFileBuilder( std::string_view outputPath, - Corpus const& corpus, - Reporter& R) + Corpus const& corpus) : corpus_(corpus) - , R_(R) , outputPath_(outputPath) , names_(corpus_) , wg_(&corpus.config) { } - Err + Error build() { corpus_.traverse(*this, SymbolID::zero); wg_.wait(); - return Err(); + return Error(); } template @@ -63,14 +61,18 @@ class MultiFileBuilder : public Corpus::Visitor filePath.append(".bc"); std::error_code ec; llvm::raw_fd_ostream os(filePath, ec, fs::CD_CreateAlways); - if(! R_.error(ec, "open '", filePath, "'")) + if(ec) { - auto bc = writeBitcode(I); - if(auto ec = os.error()) - if(R_.error(ec, "write '", filePath, "'")) - return; - os.write(bc.data.data(), bc.data.size()); + reportError(Error(ec), "open \"{}\"", filePath); + return; } + auto bc = writeBitcode(I); + if(auto ec = os.error()) + { + reportError(Error(ec), "write \"{}\"", filePath); + return; + } + os.write(bc.data.data(), bc.data.size()); }); } @@ -111,25 +113,22 @@ class MultiFileBuilder : public Corpus::Visitor class SingleFileBuilder : public Corpus::Visitor { Corpus const& corpus_; - [[maybe_unused]] Reporter& R_; std::ostream& os_; public: SingleFileBuilder( std::ostream& os, - Corpus const& corpus, - Reporter& R) + Corpus const& corpus) : corpus_(corpus) - , R_(R) , os_(os) { } - Err + Error build() { corpus_.traverse(*this, SymbolID::zero); - return Err(); + return Error(); } template @@ -173,24 +172,22 @@ class SingleFileBuilder : public Corpus::Visitor //------------------------------------------------ -Err +Error BitcodeGenerator:: build( std::string_view outputPath, - Corpus const& corpus, - Reporter& R) const + Corpus const& corpus) const { - return MultiFileBuilder(outputPath, corpus, R).build(); + return MultiFileBuilder(outputPath, corpus).build(); } -Err +Error BitcodeGenerator:: buildOne( std::ostream& os, - Corpus const& corpus, - Reporter& R) const + Corpus const& corpus) const { - return SingleFileBuilder(os, corpus, R).build(); + return SingleFileBuilder(os, corpus).build(); } } // xml diff --git a/source/-bitcode/BitcodeGenerator.hpp b/source/-bitcode/BitcodeGenerator.hpp index c86b2b9d6..e8041157f 100644 --- a/source/-bitcode/BitcodeGenerator.hpp +++ b/source/-bitcode/BitcodeGenerator.hpp @@ -42,17 +42,15 @@ struct BitcodeGenerator : Generator return "bc"; } - Err + Error build( std::string_view outputPath, - Corpus const& corpus, - Reporter& R) const override; + Corpus const& corpus) const override; - Err + Error buildOne( std::ostream& os, - Corpus const& corpus, - Reporter& R) const override; + Corpus const& corpus) const override; }; } // bitcode diff --git a/source/AST/ASTVisitor.cpp b/source/AST/ASTVisitor.cpp index f92cbe49a..e0ed32f0e 100644 --- a/source/AST/ASTVisitor.cpp +++ b/source/AST/ASTVisitor.cpp @@ -46,11 +46,9 @@ ASTVisitor:: ASTVisitor( tooling::ExecutionContext& ex, ConfigImpl const& config, - clang::CompilerInstance& compiler, - Reporter& R) noexcept + clang::CompilerInstance& compiler) noexcept : ex_(ex) , config_(config) - , R_(R) , IsFileInRootDir_(true) , compiler_(compiler) { @@ -446,8 +444,7 @@ void ASTVisitor:: parseRawComment( std::unique_ptr& javadoc, - Decl const* D, - Reporter& R) + Decl const* D) { // VFALCO investigate whether we can use // ASTContext::getCommentForDecl instead @@ -457,7 +454,7 @@ parseRawComment( { RC->setAttached(); javadoc = std::make_unique( - parseJavadoc(RC, D, R)); + parseJavadoc(RC, D)); } else { @@ -585,7 +582,7 @@ extractInfo( if(! extractSymbolID(D, I.id)) return false; I.Name = D->getNameAsString(); - parseRawComment(I.javadoc, D, R_); + parseRawComment(I.javadoc, D); return true; } diff --git a/source/AST/ASTVisitor.hpp b/source/AST/ASTVisitor.hpp index bcea501f3..43dc83f01 100644 --- a/source/AST/ASTVisitor.hpp +++ b/source/AST/ASTVisitor.hpp @@ -14,7 +14,6 @@ #define MRDOX_AST_ASTVISITOR_HPP #include "ConfigImpl.hpp" -#include #include #include #include @@ -47,8 +46,6 @@ class ASTVisitor tooling::ExecutionContext& ex_; ConfigImpl const& config_; - Reporter& R_; - llvm::SmallString<512> File_; bool IsFileInRootDir_; @@ -68,8 +65,7 @@ class ASTVisitor ASTVisitor( tooling::ExecutionContext& ex, ConfigImpl const& config, - clang::CompilerInstance& compiler, - Reporter& R) noexcept; + clang::CompilerInstance& compiler) noexcept; bool extractSymbolID( @@ -168,8 +164,7 @@ class ASTVisitor void parseRawComment( std::unique_ptr& javadoc, - Decl const* D, - Reporter& R); + Decl const* D); void parseEnumerators( diff --git a/source/AST/AnyBlock.hpp b/source/AST/AnyBlock.hpp index e4231ec35..f49bfb1a1 100644 --- a/source/AST/AnyBlock.hpp +++ b/source/AST/AnyBlock.hpp @@ -17,6 +17,7 @@ #include "AnyNodeList.hpp" #include "DecodeRecord.hpp" #include "Support/Debug.hpp" +#include "Support/Error.hpp" namespace clang { namespace mrdox { @@ -28,27 +29,27 @@ struct BitcodeReader::AnyBlock virtual ~AnyBlock() = default; virtual - llvm::Error + Error parseRecord( Record const& R, unsigned ID, llvm::StringRef Blob) { - return makeError("unexpected record with ID=", ID); + return Error("unexpected record with ID={}", ID); } virtual - llvm::Error + Error readSubBlock(unsigned ID) { - return makeError("unexpected sub-block with ID=", ID); + return Error("unexpected sub-block with ID={}", ID); } - llvm::Error + Error makeWrongFieldError(FieldId F) { - return makeError("unexpected FieldId=", - static_cast>(F)); + return Error("unexpected FieldId"); + //static_cast>(F)); } }; @@ -60,18 +61,18 @@ class VersionBlock public: unsigned V; - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { switch(ID) { case VERSION: - if(auto Err = decodeRecord(R, V, Blob)) - return Err; + if(auto err = decodeRecord(R, V, Blob)) + return err; if(V != BitcodeVersion) - return makeError("wrong ID for Version"); - return llvm::Error::success(); + return Error("wrong ID for Version"); + return Error::success(); default: return AnyBlock::parseRecord(R, ID, Blob); } @@ -97,7 +98,7 @@ class ReferenceBlock { } - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { @@ -138,17 +139,17 @@ class ReferencesBlock { } - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { ReferenceBlock B(br_); - if(auto Err = br_.readBlock(B, ID)) - return Err; + if(auto err = br_.readBlock(B, ID)) + return err; //if(B.F != F_) //return makeWrongFieldError(B.F); C_.emplace_back(B.I); - return llvm::Error::success(); + return Error::success(); } }; @@ -173,7 +174,7 @@ class JavadocNodesBlock { } - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { @@ -182,22 +183,22 @@ class JavadocNodesBlock case JAVADOC_LIST_KIND: { Javadoc::Kind kind; - if(auto Err = decodeRecord(R, kind, Blob)) - return Err; + if(auto err = decodeRecord(R, kind, Blob)) + return err; return J.setKind(kind); } case JAVADOC_NODE_KIND: { Javadoc::Kind kind; - if(auto Err = decodeRecord(R, kind, Blob)) - return Err; + if(auto err = decodeRecord(R, kind, Blob)) + return err; return J.getNodes().appendChild(kind); } case JAVADOC_PARAM_DIRECTION: { Javadoc::ParamDirection direction; - if(auto Err = decodeRecord(R, direction, Blob)) - return Err; + if(auto err = decodeRecord(R, direction, Blob)) + return err; return J.getNodes().setDirection(direction); } case JAVADOC_NODE_STRING: @@ -207,15 +208,15 @@ class JavadocNodesBlock case JAVADOC_NODE_STYLE: { Javadoc::Style style; - if(auto Err = decodeRecord(R, style, Blob)) - return Err; + if(auto err = decodeRecord(R, style, Blob)) + return err; return J.getNodes().setStyle(style); } case JAVADOC_NODE_ADMONISH: { Javadoc::Admonish admonish; - if(auto Err = decodeRecord(R, admonish, Blob)) - return Err; + if(auto err = decodeRecord(R, admonish, Blob)) + return err; return J.getNodes().setAdmonish(admonish); } default: @@ -223,7 +224,7 @@ class JavadocNodesBlock } } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -236,11 +237,11 @@ class JavadocNodesBlock case BI_JAVADOC_LIST_BLOCK_ID: { JavadocNodesBlock B(J.stack(), br_); - if(auto Err = br_.readBlock(B, ID)) - return Err; - if(auto Err = B.J.spliceIntoParent()) - return Err; - return llvm::Error::success(); + if(auto err = br_.readBlock(B, ID)) + return err; + if(auto err = B.J.spliceIntoParent()) + return err; + return Error::success(); } default: return AnyBlock::readSubBlock(ID); @@ -269,7 +270,7 @@ class JavadocBlock I_ = std::make_unique(); } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -278,11 +279,11 @@ class JavadocBlock case BI_JAVADOC_LIST_BLOCK_ID: { JavadocNodesBlock B(stack_, br_); - if(auto Err = br_.readBlock(B, ID)) - return Err; - if(auto Err = B.J.spliceInto(I_->getBlocks())) - return Err; - return llvm::Error::success(); + if(auto err = br_.readBlock(B, ID)) + return err; + if(auto err = B.J.spliceInto(I_->getBlocks())) + return err; + return Error::success(); } default: return AnyBlock::readSubBlock(ID); @@ -308,7 +309,7 @@ class InfoPartBlock { } - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { @@ -325,7 +326,7 @@ class InfoPartBlock } } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -361,7 +362,7 @@ class SymbolPartBlock { } - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { @@ -397,7 +398,7 @@ class TypeBlock { } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -406,12 +407,12 @@ class TypeBlock case BI_REFERENCE_BLOCK_ID: { ReferenceBlock B(br_); - if(auto Err = br_.readBlock(B, ID)) - return Err; + if(auto err = br_.readBlock(B, ID)) + return err; F = B.F; static_cast(I_) = std::move(B.I); - return llvm::Error::success(); + return Error::success(); } default: return AnyBlock::readSubBlock(ID); @@ -435,7 +436,7 @@ class BaseBlock v_.emplace_back(); } - llvm::Error + Error parseRecord( Record const& R, unsigned ID, @@ -471,7 +472,7 @@ class TemplateArgBlock { } - llvm::Error + Error parseRecord( Record const& R, unsigned ID, @@ -504,7 +505,7 @@ class TemplateParamBlock { } - llvm::Error + Error parseRecord( Record const& R, unsigned ID, @@ -523,8 +524,8 @@ class TemplateParamBlock case TEMPLATE_PARAM_KIND: { TParamKind kind = TParamKind::None; - if(auto Err = decodeRecord(R, kind, Blob)) - return Err; + if(auto err = decodeRecord(R, kind, Blob)) + return err; switch(kind) { case TParamKind::Type: @@ -537,9 +538,9 @@ class TemplateParamBlock I_.emplace(); break; default: - return makeError("invalid template parameter kind"); + return Error("invalid template parameter kind"); } - return llvm::Error::success(); + return Error::success(); } case TEMPLATE_PARAM_DEFAULT: { @@ -552,7 +553,7 @@ class TemplateParamBlock return decodeRecord(R, I_.get().Default.emplace(), Blob); default: - return makeError("invalid template parameter kind"); + return Error("invalid template parameter kind"); } } @@ -561,7 +562,7 @@ class TemplateParamBlock } } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -570,11 +571,11 @@ class TemplateParamBlock case BI_TEMPLATE_PARAM_BLOCK_ID: { if(I_.Kind != TParamKind::Template) - return makeError("only TemplateTParam may have template parameters"); + return Error("only TemplateTParam may have template parameters"); TemplateParamBlock P(I_.get().Params.emplace_back(), br_); - if(auto Err = br_.readBlock(P, ID)) - return Err; - return llvm::Error::success(); + if(auto err = br_.readBlock(P, ID)) + return err; + return Error::success(); } case BI_TYPE_BLOCK_ID: { @@ -588,11 +589,11 @@ class TemplateParamBlock t = &I_.get().Type; break; default: - return makeError("invalid TypeInfo block in TParam"); + return Error("invalid TypeInfo block in TParam"); } TypeBlock B(*t, br_); - if(auto Err = br_.readBlock(B, ID)) - return Err; + if(auto err = br_.readBlock(B, ID)) + return err; // KRYSTIAN NOTE: is this check correct? // copied from a function with TypeInfo sub-block switch(B.F) @@ -602,7 +603,7 @@ class TemplateParamBlock default: return makeWrongFieldError(B.F); } - return llvm::Error::success(); + return Error::success(); } default: break; @@ -629,7 +630,7 @@ class TemplateBlock { } - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { @@ -642,7 +643,7 @@ class TemplateBlock } } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -652,17 +653,17 @@ class TemplateBlock { TemplateArgBlock A( I_.Args.emplace_back()); - if(auto Err = br_.readBlock(A, ID)) - return Err; - return llvm::Error::success(); + if(auto err = br_.readBlock(A, ID)) + return err; + return Error::success(); } case BI_TEMPLATE_PARAM_BLOCK_ID: { TemplateParamBlock P( I_.Params.emplace_back(), br_); - if(auto Err = br_.readBlock(P, ID)) - return Err; - return llvm::Error::success(); + if(auto err = br_.readBlock(P, ID)) + return err; + return Error::success(); } default: return AnyBlock::readSubBlock(ID); @@ -687,7 +688,7 @@ class FunctionParamBlock { } - llvm::Error + Error parseRecord( Record const& R, unsigned ID, @@ -714,7 +715,7 @@ class FunctionParamBlock } } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -723,8 +724,8 @@ class FunctionParamBlock case BI_TYPE_BLOCK_ID: { TypeBlock B(I_.Type, br_); - if(auto Err = br_.readBlock(B, ID)) - return Err; + if(auto err = br_.readBlock(B, ID)) + return err; // KRYSTIAN NOTE: is this check correct? // copied from a function with TypeInfo sub-block switch(B.F) @@ -734,7 +735,7 @@ class FunctionParamBlock default: return makeWrongFieldError(B.F); } - return llvm::Error::success(); + return Error::success(); } default: break; @@ -765,7 +766,7 @@ class TopLevelBlock } #if 0 - llvm::Error + Error insertChild( Reference&& R, FieldId Id) { @@ -778,7 +779,7 @@ class TopLevelBlock std::derived_from) { I->Children.Namespaces.emplace_back(std::move(R)); - return llvm::Error::success(); + return Error::success(); } break; } @@ -789,7 +790,7 @@ class TopLevelBlock std::derived_from) { I->Children.Records.emplace_back(std::move(R)); - return llvm::Error::success(); + return Error::success(); } break; } @@ -800,7 +801,7 @@ class TopLevelBlock std::derived_from) { I->Children.Functions.emplace_back(std::move(R)); - return llvm::Error::success(); + return Error::success(); } break; } @@ -811,7 +812,7 @@ class TopLevelBlock std::derived_from) { I->Children.Typedefs.emplace_back(std::move(R)); - return llvm::Error::success(); + return Error::success(); } break; } @@ -822,7 +823,7 @@ class TopLevelBlock std::derived_from) { I->Children.Enums.emplace_back(std::move(R)); - return llvm::Error::success(); + return Error::success(); } break; } @@ -833,7 +834,7 @@ class TopLevelBlock std::derived_from) { I->Children.Vars.emplace_back(std::move(R)); - return llvm::Error::success(); + return Error::success(); } break; } @@ -846,19 +847,19 @@ class TopLevelBlock std::derived_from) { Assert("RecordInfo doesn't use Scope"); - return llvm::Error::success(); + return Error::success(); } break; } default: return makeWrongFieldError(Id); } - return makeError("unknown type"); + return Error("unknown type"); } #endif - llvm::Error readChild(Scope& I, unsigned ID); - llvm::Error readSubBlock(unsigned ID) override; + Error readChild(Scope& I, unsigned ID); + Error readSubBlock(unsigned ID) override; }; //------------------------------------------------ @@ -889,7 +890,7 @@ class RecordBlock { } - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { @@ -920,7 +921,7 @@ class RecordBlock } } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -957,7 +958,7 @@ class FunctionBlock { } - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { @@ -970,7 +971,7 @@ class FunctionBlock } } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -979,8 +980,8 @@ class FunctionBlock case BI_TYPE_BLOCK_ID: { TypeBlock B(I->ReturnType, br_); - if(auto Err = br_.readBlock(B, ID)) - return Err; + if(auto err = br_.readBlock(B, ID)) + return err; switch(B.F) { case FieldId::F_type: @@ -988,7 +989,7 @@ class FunctionBlock default: return makeWrongFieldError(B.F); } - return llvm::Error::success(); + return Error::success(); } case BI_FUNCTION_PARAM_BLOCK_ID: { @@ -1022,7 +1023,7 @@ class TypedefBlock { } - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { @@ -1036,7 +1037,7 @@ class TypedefBlock return TopLevelBlock::parseRecord(R, ID, Blob); } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -1045,8 +1046,8 @@ class TypedefBlock case BI_TYPE_BLOCK_ID: { TypeBlock B(I->Underlying, br_); - if(auto Err = br_.readBlock(B, ID)) - return Err; + if(auto err = br_.readBlock(B, ID)) + return err; switch(B.F) { case FieldId::F_type: @@ -1054,7 +1055,7 @@ class TypedefBlock default: return makeWrongFieldError(B.F); } - return llvm::Error::success(); + return Error::success(); } case BI_TEMPLATE_BLOCK_ID: { @@ -1082,7 +1083,7 @@ class EnumValueBlock : public BitcodeReader::AnyBlock { } - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { @@ -1111,7 +1112,7 @@ class EnumBlock { } - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { @@ -1125,7 +1126,7 @@ class EnumBlock return TopLevelBlock::parseRecord(R, ID, Blob); } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -1141,9 +1142,9 @@ class EnumBlock { I->Members.emplace_back(); EnumValueBlock B(I->Members.back()); - if(auto Err = br_.readBlock(B, ID)) - return Err; - return llvm::Error::success(); + if(auto err = br_.readBlock(B, ID)) + return err; + return Error::success(); } default: break; @@ -1166,7 +1167,7 @@ class VarBlock { } - llvm::Error + Error parseRecord(Record const& R, unsigned ID, llvm::StringRef Blob) override { @@ -1180,7 +1181,7 @@ class VarBlock return TopLevelBlock::parseRecord(R, ID, Blob); } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -1217,7 +1218,7 @@ class FieldBlock { } - llvm::Error + Error parseRecord( Record const& R, unsigned ID, @@ -1236,7 +1237,7 @@ class FieldBlock } } - llvm::Error + Error readSubBlock( unsigned ID) override { @@ -1257,14 +1258,14 @@ class FieldBlock //------------------------------------------------ template -llvm::Error +Error TopLevelBlock:: readChild( Scope& I, unsigned ID) { ReferenceBlock B(br_); - if(auto Err = br_.readBlock(B, ID)) - return Err; + if(auto err = br_.readBlock(B, ID)) + return err; switch(B.F) { case FieldId::F_child_namespace: @@ -1288,11 +1289,11 @@ readChild( default: return makeWrongFieldError(B.F); } - return llvm::Error::success(); + return Error::success(); } template -llvm::Error +Error TopLevelBlock:: readSubBlock( unsigned ID) @@ -1304,9 +1305,9 @@ readSubBlock( if constexpr(std::derived_from) { InfoPartBlock B(*I.get(), br_); - if(auto Err = br_.readBlock(B, ID)) - return Err; - return llvm::Error::success(); + if(auto err = br_.readBlock(B, ID)) + return err; + return Error::success(); } break; } @@ -1315,9 +1316,9 @@ readSubBlock( if constexpr(std::derived_from) { SymbolPartBlock B(*I.get(), br_); - if(auto Err = br_.readBlock(B, ID)) - return Err; - return llvm::Error::success(); + if(auto err = br_.readBlock(B, ID)) + return err; + return Error::success(); } break; } diff --git a/source/AST/AnyNodeList.hpp b/source/AST/AnyNodeList.hpp index 7d74e886b..488c8e5cd 100644 --- a/source/AST/AnyNodeList.hpp +++ b/source/AST/AnyNodeList.hpp @@ -12,7 +12,7 @@ #define MRDOX_AST_ANYNODELIST_HPP #include -#include +#include #include #include @@ -27,11 +27,11 @@ class AnyNodeList struct Nodes { virtual ~Nodes() = default; - virtual llvm::Error appendChild(Javadoc::Kind kind) = 0; - virtual llvm::Error setStyle(Javadoc::Style style) = 0; - virtual llvm::Error setString(llvm::StringRef string) = 0; - virtual llvm::Error setAdmonish(Javadoc::Admonish admonish) = 0; - virtual llvm::Error setDirection(Javadoc::ParamDirection direction) = 0; + virtual Error appendChild(Javadoc::Kind kind) = 0; + virtual Error setStyle(Javadoc::Style style) = 0; + virtual Error setString(llvm::StringRef string) = 0; + virtual Error setAdmonish(Javadoc::Admonish admonish) = 0; + virtual Error setDirection(Javadoc::ParamDirection direction) = 0; virtual AnyListNodes extractNodes() = 0; virtual void spliceBack(AnyListNodes&& nodes) noexcept = 0; }; @@ -49,11 +49,11 @@ class AnyNodeList Nodes& getNodes(); bool isTopLevel() const noexcept; - llvm::Error setKind(Javadoc::Kind kind); + Error setKind(Javadoc::Kind kind); template - llvm::Error spliceInto(AnyList& nodes); - llvm::Error spliceIntoParent(); + Error spliceInto(AnyList& nodes); + Error spliceIntoParent(); private: template @@ -61,11 +61,11 @@ class AnyNodeList { AnyList list; - llvm::Error appendChild(Javadoc::Kind kind) override; - llvm::Error setStyle(Javadoc::Style style) override; - llvm::Error setString(llvm::StringRef string) override; - llvm::Error setAdmonish(Javadoc::Admonish admonish) override; - llvm::Error setDirection(Javadoc::ParamDirection direction) override; + Error appendChild(Javadoc::Kind kind) override; + Error setStyle(Javadoc::Style style) override; + Error setString(llvm::StringRef string) override; + Error setAdmonish(Javadoc::Admonish admonish) override; + Error setDirection(Javadoc::ParamDirection direction) override; AnyListNodes extractNodes() override; void spliceBack(AnyListNodes&& nodes) noexcept override; }; @@ -107,29 +107,29 @@ getNodes() -> struct ErrorNodes : Nodes { - llvm::Error appendChild(Javadoc::Kind) override + Error appendChild(Javadoc::Kind) override { - return makeError("missing kind"); + return Error("kind is missing"); } - llvm::Error setStyle(Javadoc::Style) override + Error setStyle(Javadoc::Style) override { - return makeError("missing kind"); + return Error("kind is missing"); } - llvm::Error setString(llvm::StringRef) override + Error setString(llvm::StringRef) override { - return makeError("missing kind"); + return Error("kind is missing"); } - llvm::Error setAdmonish(Javadoc::Admonish) override + Error setAdmonish(Javadoc::Admonish) override { - return makeError("missing kind"); + return Error("kind is missing"); } - llvm::Error setDirection(Javadoc::ParamDirection) override + Error setDirection(Javadoc::ParamDirection) override { - return makeError("missing kind"); + return Error("kind is missing"); } AnyListNodes extractNodes() override @@ -154,13 +154,13 @@ isTopLevel() const noexcept } inline -llvm::Error +Error AnyNodeList:: setKind( Javadoc::Kind kind) { if(nodes_ != nullptr) - return makeError("kind already set"); + return Error("kind already set"); switch(kind) { case Javadoc::Kind::block: @@ -170,44 +170,44 @@ setKind( nodes_ = new NodesImpl(); break; default: - return makeError("wrong or unknown kind"); + return Error("wrong or unknown kind"); } - return llvm::Error::success(); + return Error::success(); } template -llvm::Error +Error AnyNodeList:: spliceInto( AnyList& nodes) { if(nodes_ == nullptr) - return makeError("splice without nodes"); + return Error("splice without nodes"); // splice `*nodes_` to the end of `nodes` nodes.spliceBack(nodes_->extractNodes()); - return llvm::Error::success(); + return Error::success(); } inline -llvm::Error +Error AnyNodeList:: spliceIntoParent() { if(prev_ == nullptr) - return makeError("splice without parent"); + return Error("splice without parent"); // splice `*nodes_` to the end of `*prev_->nodes_` prev_->nodes_->spliceBack(nodes_->extractNodes()); - return llvm::Error::success(); + return Error::success(); } //------------------------------------------------ template -llvm::Error +Error AnyNodeList:: NodesImpl:: appendChild( @@ -217,38 +217,38 @@ appendChild( { case Javadoc::Kind::text: Javadoc::append(list, Javadoc::Text()); - return llvm::Error::success(); + return Error::success(); case Javadoc::Kind::styled: Javadoc::append(list, Javadoc::StyledText()); - return llvm::Error::success(); + return Error::success(); case Javadoc::Kind::paragraph: Javadoc::append(list, Javadoc::Paragraph()); - return llvm::Error::success(); + return Error::success(); case Javadoc::Kind::brief: Javadoc::append(list, Javadoc::Brief()); - return llvm::Error::success(); + return Error::success(); case Javadoc::Kind::admonition: Javadoc::append(list, Javadoc::Admonition()); - return llvm::Error::success(); + return Error::success(); case Javadoc::Kind::code: Javadoc::append(list, Javadoc::Code()); - return llvm::Error::success(); + return Error::success(); case Javadoc::Kind::returns: Javadoc::append(list, Javadoc::Returns()); - return llvm::Error::success(); + return Error::success(); case Javadoc::Kind::param: Javadoc::append(list, Javadoc::Param()); - return llvm::Error::success(); + return Error::success(); case Javadoc::Kind::tparam: Javadoc::append(list, Javadoc::TParam()); - return llvm::Error::success(); + return Error::success(); default: - return makeError("invalid kind"); + return Error("invalid kind"); } } template -llvm::Error +Error AnyNodeList:: NodesImpl:: setStyle( @@ -257,19 +257,19 @@ setStyle( if constexpr(std::derived_from) { if(list.back().kind != Javadoc::Kind::styled) - return makeError("style on wrong kind"); + return Error("style on wrong kind"); auto& node = static_cast(list.back()); node.style = style; - return llvm::Error::success(); + return Error::success(); } else { - return makeError("style on wrong kind"); + return Error("style on wrong kind"); } } template -llvm::Error +Error AnyNodeList:: NodesImpl:: setString( @@ -279,7 +279,7 @@ setString( { auto& node = static_cast(list.back()); node.string = string.str(); - return llvm::Error::success(); + return Error::success(); } else if constexpr(std::derived_from) { @@ -289,13 +289,13 @@ setString( { auto& node = static_cast(list.back()); node.name = string.str(); - return llvm::Error::success(); + return Error::success(); } case Javadoc::Kind::tparam: { auto& node = static_cast(list.back()); node.name = string.str(); - return llvm::Error::success(); + return Error::success(); } default: break; @@ -308,20 +308,20 @@ setString( { auto& node = static_cast(list.back()); node.name = string.str(); - return llvm::Error::success(); + return Error::success(); } else if constexpr(std::derived_from) { auto& node = static_cast(list.back()); node.name = string.str(); - return llvm::Error::success(); + return Error::success(); } #endif - return makeError("string on wrong kind"); + return Error("string on wrong kind"); } template -llvm::Error +Error AnyNodeList:: NodesImpl:: setAdmonish( @@ -330,19 +330,19 @@ setAdmonish( if constexpr(std::derived_from) { if(list.back().kind != Javadoc::Kind::admonition) - return makeError("admonish on wrong kind"); + return Error("admonish on wrong kind"); auto& node = static_cast(list.back()); node.style = admonish; - return llvm::Error::success(); + return Error::success(); } else { - return makeError("admonish on wrong kind"); + return Error("admonish on wrong kind"); } } template -llvm::Error +Error AnyNodeList:: NodesImpl:: setDirection( @@ -351,14 +351,14 @@ setDirection( if constexpr(std::derived_from) { if(list.back().kind != Javadoc::Kind::param) - return makeError("direction on wrong kind"); + return Error("direction on wrong kind"); auto& node = static_cast(list.back()); node.direction = direction; - return llvm::Error::success(); + return Error::success(); } else { - return makeError("direction on wrong kind"); + return Error("direction on wrong kind"); } } diff --git a/source/AST/Bitcode.hpp b/source/AST/Bitcode.hpp index a9150c901..96e883d9d 100644 --- a/source/AST/Bitcode.hpp +++ b/source/AST/Bitcode.hpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -79,11 +78,8 @@ writeBitcode( /** Return an array of Info read from a bitstream. */ -llvm::Expected< - std::vector>> -readBitcode( - llvm::StringRef bitcode, - Reporter& R); +Expected>> +readBitcode(llvm::StringRef bitcode); /** Store a key/value pair in the tool results. diff --git a/source/AST/BitcodeReader.cpp b/source/AST/BitcodeReader.cpp index e71730eee..93c38a186 100644 --- a/source/AST/BitcodeReader.cpp +++ b/source/AST/BitcodeReader.cpp @@ -13,31 +13,31 @@ #include "AnyBlock.hpp" #include "DecodeRecord.hpp" #include "Support/Debug.hpp" +#include "Support/Error.hpp" namespace clang { namespace mrdox { // Entry point -llvm::Expected< - std::vector>> +Expected>> BitcodeReader:: getInfos() { std::vector> Infos; - if (auto Err = validateStream()) - return std::move(Err); + if (auto err = validateStream()) + return err; // Read the top level blocks. while (!Stream.AtEndOfStream()) { - Expected MaybeCode = Stream.ReadCode(); + llvm::Expected MaybeCode = Stream.ReadCode(); if (!MaybeCode) - return MaybeCode.takeError(); + return toError(MaybeCode.takeError()); if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK) - return makeError("no blocks in input"); - Expected MaybeID = Stream.ReadSubBlockID(); + return Error("no blocks in input"); + llvm::Expected MaybeID = Stream.ReadSubBlockID(); if (!MaybeID) - return MaybeID.takeError(); + return toError(MaybeID.takeError()); unsigned ID = MaybeID.get(); switch (ID) { @@ -45,8 +45,8 @@ getInfos() case BI_VERSION_BLOCK_ID: { VersionBlock B; - if (auto Err = readBlock(B, ID)) - return std::move(Err); + if (auto err = readBlock(B, ID)) + return std::move(err); continue; } @@ -55,7 +55,7 @@ getInfos() { auto I = readInfo(ID); if(! I) - return I.takeError(); + return I.getError(); Infos.emplace_back(std::move(I.get())); continue; } @@ -63,7 +63,7 @@ getInfos() { auto I = readInfo(ID); if(! I) - return I.takeError(); + return I.getError(); Infos.emplace_back(std::move(I.get())); continue; } @@ -71,7 +71,7 @@ getInfos() { auto I = readInfo(ID); if(! I) - return I.takeError(); + return I.getError(); Infos.emplace_back(std::move(I.get())); continue; } @@ -79,7 +79,7 @@ getInfos() { auto I = readInfo(ID); if(! I) - return I.takeError(); + return I.getError(); Infos.emplace_back(std::move(I.get())); continue; } @@ -87,7 +87,7 @@ getInfos() { auto I = readInfo(ID); if(! I) - return I.takeError(); + return I.getError(); Infos.emplace_back(std::move(I.get())); continue; } @@ -95,7 +95,7 @@ getInfos() { auto I = readInfo(ID); if(! I) - return I.takeError(); + return I.getError(); Infos.emplace_back(std::move(I.get())); continue; } @@ -105,7 +105,7 @@ getInfos() { auto I = readInfo(ID); if(! I) - return I.takeError(); + return I.getError(); Infos.emplace_back(std::move(I.get())); continue; } @@ -117,15 +117,16 @@ getInfos() case BI_JAVADOC_LIST_BLOCK_ID: case BI_JAVADOC_NODE_BLOCK_ID: case BI_REFERENCE_BLOCK_ID: - return makeError("invalid top level block"); + return Error("invalid top level block"); case llvm::bitc::BLOCKINFO_BLOCK_ID: - if (auto Err = readBlockInfoBlock()) - return std::move(Err); + if (auto err = readBlockInfoBlock()) + return std::move(err); continue; default: - if (llvm::Error Err = Stream.SkipBlock()) { + if (llvm::Error err = Stream.SkipBlock()) + { // FIXME this drops the error on the floor. - consumeError(std::move(Err)); + consumeError(std::move(err)); } continue; } @@ -135,62 +136,62 @@ getInfos() //------------------------------------------------ -llvm::Error +Error BitcodeReader:: validateStream() { if (Stream.AtEndOfStream()) - return makeError("premature end of stream"); + return Error("premature end of stream"); // Sniff for the signature. for (int i = 0; i != 4; ++i) { - Expected MaybeRead = Stream.Read(8); + llvm::Expected MaybeRead = Stream.Read(8); if (!MaybeRead) - return MaybeRead.takeError(); + return toError(MaybeRead.takeError()); else if (MaybeRead.get() != BitCodeConstants::Signature[i]) - return makeError("invalid bitcode signature"); + return Error("invalid bitcode signature"); } - return llvm::Error::success(); + return Error::success(); } -llvm::Error +Error BitcodeReader:: readBlockInfoBlock() { - Expected> MaybeBlockInfo = + llvm::Expected> MaybeBlockInfo = Stream.ReadBlockInfoBlock(); if (!MaybeBlockInfo) - return MaybeBlockInfo.takeError(); + return toError(MaybeBlockInfo.takeError()); BlockInfo = MaybeBlockInfo.get(); if (!BlockInfo) - return makeError("unable to parse BlockInfoBlock"); + return Error("unable to parse BlockInfoBlock"); Stream.setBlockInfo(&*BlockInfo); - return llvm::Error::success(); + return Error::success(); } //------------------------------------------------ template -llvm::Expected> +Expected> BitcodeReader:: readInfo( unsigned ID) { T B(*this); - if(auto Err = readBlock(B, ID)) - return Err; + if(auto err = readBlock(B, ID)) + return err; return std::move(B.I); } -llvm::Error +Error BitcodeReader:: readBlock( AnyBlock& B, unsigned ID) { blockStack_.push_back(&B); if (auto err = Stream.EnterSubBlock(ID)) - return err; + return toError(std::move(err)); for(;;) { @@ -200,30 +201,32 @@ readBlock( switch (Res) { case Cursor::BadBlock: - return makeError("bad block found"); + return Error("bad block found"); case Cursor::BlockEnd: blockStack_.pop_back(); - return llvm::Error::success(); + return Error::success(); case Cursor::BlockBegin: - if (auto Err = blockStack_.back()->readSubBlock(BlockOrCode)) + if (auto err = blockStack_.back()->readSubBlock(BlockOrCode)) { if (llvm::Error Skipped = Stream.SkipBlock()) - return joinErrors(std::move(Err), std::move(Skipped)); - return Err; + { + return toError(std::move(Skipped)); + } + return err; } continue; case Cursor::Record: break; } - if (auto Err = readRecord(BlockOrCode)) - return Err; + if (auto err = readRecord(BlockOrCode)) + return err; } } //------------------------------------------------ // Read records from bitcode into AnyBlock -llvm::Error +Error BitcodeReader:: readRecord(unsigned ID) { @@ -232,7 +235,7 @@ readRecord(unsigned ID) llvm::Expected MaybeRecID = Stream.readRecord(ID, R, &Blob); if (!MaybeRecID) - return MaybeRecID.takeError(); + return toError(MaybeRecID.takeError()); return blockStack_.back()->parseRecord(R, MaybeRecID.get(), Blob); } @@ -248,7 +251,7 @@ skipUntilRecordOrBlock( while (!Stream.AtEndOfStream()) { - Expected MaybeCode = Stream.ReadCode(); + llvm::Expected MaybeCode = Stream.ReadCode(); if (!MaybeCode) { // FIXME this drops the error on the floor. @@ -265,7 +268,7 @@ skipUntilRecordOrBlock( switch (static_cast(Code)) { case llvm::bitc::ENTER_SUBBLOCK: - if (Expected MaybeID = Stream.ReadSubBlockID()) + if (llvm::Expected MaybeID = Stream.ReadSubBlockID()) BlockOrRecordID = MaybeID.get(); else { // FIXME this drops the error on the floor. @@ -277,9 +280,10 @@ skipUntilRecordOrBlock( return Cursor::BadBlock; return Cursor::BlockEnd; case llvm::bitc::DEFINE_ABBREV: - if (llvm::Error Err = Stream.ReadAbbrevRecord()) { + if (llvm::Error err = Stream.ReadAbbrevRecord()) + { // FIXME this drops the error on the floor. - consumeError(std::move(Err)); + consumeError(std::move(err)); } continue; case llvm::bitc::UNABBREV_RECORD: @@ -294,14 +298,11 @@ skipUntilRecordOrBlock( //------------------------------------------------ // Calls readBlock to read each block in the given bitcode. -llvm::Expected< - std::vector>> -readBitcode( - llvm::StringRef bitcode, - Reporter& R) +Expected>> +readBitcode(llvm::StringRef bitcode) { llvm::BitstreamCursor Stream(bitcode); - BitcodeReader reader(Stream, R); + BitcodeReader reader(Stream); return reader.getInfos(); } diff --git a/source/AST/BitcodeReader.hpp b/source/AST/BitcodeReader.hpp index e3eb10ed1..cd78e18c2 100644 --- a/source/AST/BitcodeReader.hpp +++ b/source/AST/BitcodeReader.hpp @@ -21,9 +21,8 @@ #include #include "BitcodeIDs.hpp" -#include +#include #include -#include #include #include #include @@ -39,18 +38,15 @@ class BitcodeReader { public: BitcodeReader( - llvm::BitstreamCursor& Stream, - Reporter& R) - : R_(R) - , Stream(Stream) + llvm::BitstreamCursor& Stream) + : Stream(Stream) { } // Main entry point, calls readBlock to read each block in the given stream. - llvm::Expected< - std::vector>> - getInfos(); - + auto + getInfos() -> + Expected>>; public: struct AnyBlock; @@ -62,35 +58,32 @@ class BitcodeReader BlockBegin }; - llvm::Error validateStream(); - llvm::Error readBlockInfoBlock(); + Error validateStream(); + Error readBlockInfoBlock(); /** Return the next decoded Info from the stream. */ template - llvm::Expected> + Expected> readInfo(unsigned ID); /** Read a single block. Calls readRecord on each record found. */ - llvm::Error - readBlock(AnyBlock& B, unsigned ID); + Error readBlock(AnyBlock& B, unsigned ID); /** Read a record into a data field. This calls parseRecord after casting. */ - llvm::Error - readRecord(unsigned ID); + Error readRecord(unsigned ID); // Helper function to step through blocks to find and dispatch the next record // or block to be read. Cursor skipUntilRecordOrBlock(unsigned &BlockOrRecordID); public: - Reporter& R_; llvm::BitstreamCursor& Stream; std::optional BlockInfo; std::vector blockStack_; diff --git a/source/AST/DecodeRecord.hpp b/source/AST/DecodeRecord.hpp index 605e20243..e34af324e 100644 --- a/source/AST/DecodeRecord.hpp +++ b/source/AST/DecodeRecord.hpp @@ -19,20 +19,20 @@ namespace mrdox { // bool inline -llvm::Error +Error decodeRecord( Record const& R, bool& Field, llvm::StringRef Blob) { Field = R[0] != 0; - return llvm::Error::success(); + return Error::success(); } // integral types template requires std::is_integral_v -llvm::Error +Error decodeRecord( Record const& R, IntTy& v, @@ -40,15 +40,15 @@ decodeRecord( { v = 0; if (R[0] > (std::numeric_limits::max)()) - return makeError("integer overflow"); + return Error("integer overflow"); v = static_cast(R[0]); - return llvm::Error::success(); + return Error::success(); } // enumerations template requires std::is_enum_v -llvm::Error +Error decodeRecord( Record const& R, Enum& value, @@ -58,14 +58,14 @@ decodeRecord( if(auto err = decodeRecord(R, temp, blob)) return err; value = static_cast(temp); - return llvm::Error::success(); + return Error::success(); } // container of char template requires std::is_same_v< typename Field::value_type, char> -llvm::Error +Error decodeRecord( const Record& R, Field& f, @@ -76,12 +76,12 @@ decodeRecord( } { f.assign(blob.begin(), blob.end()); - return llvm::Error::success(); + return Error::success(); } // range inline -llvm::Error +Error decodeRecord( Record const& R, std::vector& f, @@ -96,12 +96,12 @@ decodeRecord( *dest++ = SymbolID(src); src += BitCodeConstants::USRHashSize; } - return llvm::Error::success(); + return Error::success(); } // vector inline -llvm::Error +Error decodeRecord( Record const& R, std::vector& f, @@ -110,41 +110,41 @@ decodeRecord( constexpr auto MemberRefSize = BitCodeConstants::USRHashSize + 1; if(R.empty()) - return makeError("empty"); + return Error("record is empty"); auto n = R.size() / MemberRefSize; if(R.size() != n * MemberRefSize) - return makeError("short Record"); + return Error("record is short"); auto src = R.begin(); f.resize(n); auto* dest = &f[0]; while(n--) { if(*src > 2) // Access::Private - return makeError("invalid Access"); + return Error("invalid Access={}", *src); dest->access = static_cast(*src++); dest->id = SymbolID(src); ++dest; src += BitCodeConstants::USRHashSize; } - return llvm::Error::success(); + return Error::success(); } inline -llvm::Error +Error decodeRecord( const Record& R, SymbolID& Field, llvm::StringRef Blob) { if (R[0] != BitCodeConstants::USRHashSize) - return makeError("incorrect USR digest size"); + return Error("USR digest size={}", R[0]); Field = SymbolID(&R[1]); - return llvm::Error::success(); + return Error::success(); } inline -llvm::Error +Error decodeRecord( Record const& R, AccessSpecifier& Field, @@ -157,15 +157,15 @@ decodeRecord( case AS_protected: case AS_none: Field = (AccessSpecifier)R[0]; - return llvm::Error::success(); + return Error::success(); default: Field = AS_none; - return makeError("invalid value for AccessSpecifier"); + return Error("AccessSpecifier={} is invalid", R[0]); } } inline -llvm::Error +Error decodeRecord( Record const& R, TagTypeKind& Field, @@ -179,28 +179,28 @@ decodeRecord( case TTK_Class: case TTK_Enum: Field = (TagTypeKind)R[0]; - return llvm::Error::success(); + return Error::success(); default: Field = TTK_Struct; - return makeError("invalid value for TagTypeKind"); + return Error("TagTypeKind={} is invalid", R[0]); } } inline -llvm::Error +Error decodeRecord( Record const& R, std::optional& Field, llvm::StringRef Blob) { if (R[0] > INT_MAX) - return makeError("integer too large to parse"); + return Error("integer value {} too large", R[0]); Field.emplace((int)R[0], Blob, (bool)R[1]); - return llvm::Error::success(); + return Error::success(); } inline -llvm::Error +Error decodeRecord( Record const& R, InfoType& Field, @@ -215,21 +215,22 @@ decodeRecord( case InfoType::IT_typedef: case InfoType::IT_variable: Field = IT; - return llvm::Error::success(); + return Error::success(); default: Field = InfoType::IT_default; - return makeError("invalid value for InfoType"); + return Error("InfoType is invalid"); } } inline -llvm::Error +Error decodeRecord( Record const& R, FieldId& Field, llvm::StringRef Blob) { - switch (auto F = static_cast(R[0])) + auto F = static_cast(R[0]); + switch(F) { case FieldId::F_namespace: case FieldId::F_vparent: @@ -242,27 +243,27 @@ decodeRecord( case FieldId::F_child_variable: case FieldId::F_default: Field = F; - return llvm::Error::success(); + return Error::success(); } Field = FieldId::F_default; - return makeError("invalid value for FieldId"); + return Error("FieldId is invalid"); } inline -llvm::Error +Error decodeRecord( const Record& R, std::vector& Field, llvm::StringRef Blob) { if (R[0] > INT_MAX) - return makeError("integer too large to parse"); + return Error("integer {} is too large", R[0]); Field.emplace_back((int)R[0], Blob, (bool)R[1]); - return llvm::Error::success(); + return Error::success(); } inline -llvm::Error +Error decodeRecord( Record const& R, std::initializer_list values, @@ -270,7 +271,7 @@ decodeRecord( { auto n = R[0]; if(n != values.size()) - return makeError("wrong size(", n, ") for Bitfields[", values.size(), "]"); + return Error("wrong size={} for Bitfields[{}]", n, values.size()); auto itr = values.begin(); for(std::size_t i = 0; i < values.size(); ++i) @@ -278,10 +279,10 @@ decodeRecord( auto const v = R[i + 1]; if(v > (std::numeric_limits::max)()) - return makeError(v, " is out of range for Bits"); + return Error("{} is out of range for Bits", v); **itr++ = v; } - return llvm::Error::success(); + return Error::success(); } } // mrdox diff --git a/source/AST/FrontendAction.cpp b/source/AST/FrontendAction.cpp index 0288061fb..11096ee55 100644 --- a/source/AST/FrontendAction.cpp +++ b/source/AST/FrontendAction.cpp @@ -23,11 +23,9 @@ struct Action { Action( tooling::ExecutionContext& exc, - ConfigImpl const& config, - Reporter& R) noexcept + ConfigImpl const& config) noexcept : ex_(exc) , config_(config) - , R_(R) { } @@ -37,13 +35,12 @@ struct Action llvm::StringRef InFile) override { return std::make_unique( - ex_, config_, Compiler, R_); + ex_, config_, Compiler); } private: tooling::ExecutionContext& ex_; ConfigImpl const& config_; - Reporter& R_; }; //------------------------------------------------ @@ -52,24 +49,21 @@ struct Factory : tooling::FrontendActionFactory { Factory( tooling::ExecutionContext& exc, - ConfigImpl const& config, - Reporter& R) noexcept + ConfigImpl const& config) noexcept : ex_(exc) , config_(config) - , R_(R) { } std::unique_ptr create() override { - return std::make_unique(ex_, config_, R_); + return std::make_unique(ex_, config_); } private: tooling::ExecutionContext& ex_; ConfigImpl const& config_; - Reporter& R_; }; } // (anon) @@ -79,10 +73,9 @@ struct Factory : tooling::FrontendActionFactory std::unique_ptr makeFrontendActionFactory( tooling::ExecutionContext& exc, - ConfigImpl const& config, - Reporter& R) + ConfigImpl const& config) { - return std::make_unique(exc, config, R); + return std::make_unique(exc, config); } } // mrdox diff --git a/source/AST/FrontendAction.hpp b/source/AST/FrontendAction.hpp index 4682355b4..4e9a72692 100644 --- a/source/AST/FrontendAction.hpp +++ b/source/AST/FrontendAction.hpp @@ -20,15 +20,13 @@ namespace clang { namespace mrdox { class ConfigImpl; -class Reporter; /** Return a factory used to create our visitor. */ std::unique_ptr makeFrontendActionFactory( tooling::ExecutionContext& exc, - ConfigImpl const& config, - Reporter& R); + ConfigImpl const& config); } // mrdox } // clang diff --git a/source/AST/ParseJavadoc.cpp b/source/AST/ParseJavadoc.cpp index 8d10e1440..75465410c 100644 --- a/source/AST/ParseJavadoc.cpp +++ b/source/AST/ParseJavadoc.cpp @@ -171,11 +171,9 @@ class JavadocVisitor public: JavadocVisitor( RawComment const* RC, - Decl const* D, - Reporter& R) + Decl const* D) : FC_(RC->parse(D->getASTContext(), nullptr, D)) , ctx_(D->getASTContext()) - , R_(R) { } @@ -405,7 +403,6 @@ class JavadocVisitor private: FullComment const* FC_; ASTContext const& ctx_; - [[maybe_unused]] Reporter& R_; AnyList blocks_; AnyList params_; Javadoc::Paragraph* para_ = nullptr; @@ -570,10 +567,9 @@ initCustomCommentCommands(ASTContext& context) Javadoc parseJavadoc( RawComment const* RC, - Decl const* D, - Reporter& R) + Decl const* D) { - return JavadocVisitor(RC, D, R).build(); + return JavadocVisitor(RC, D).build(); } } // mrdox diff --git a/source/AST/ParseJavadoc.hpp b/source/AST/ParseJavadoc.hpp index 92e257500..07d798d70 100644 --- a/source/AST/ParseJavadoc.hpp +++ b/source/AST/ParseJavadoc.hpp @@ -13,7 +13,6 @@ #define MRDOX_AST_PARSEJAVADOC_HPP #include -#include #include namespace clang { @@ -38,8 +37,7 @@ initCustomCommentCommands( Javadoc parseJavadoc( RawComment const* RC, - Decl const* D, - Reporter& R); + Decl const* D); } // mrdox diff --git a/source/Config.cpp b/source/Config.cpp index b7ede5b1e..27bc15372 100644 --- a/source/Config.cpp +++ b/source/Config.cpp @@ -11,7 +11,7 @@ #include "ConfigImpl.hpp" #include "Support/Path.hpp" -#include +#include #include #include diff --git a/source/ConfigImpl.cpp b/source/ConfigImpl.cpp index 6b262fbc0..5eea93282 100644 --- a/source/ConfigImpl.cpp +++ b/source/ConfigImpl.cpp @@ -10,9 +10,10 @@ // #include "ConfigImpl.hpp" +#include "Support/Debug.hpp" +#include "Support/Error.hpp" #include "Support/Path.hpp" #include "Support/YamlFwd.hpp" -#include "Support/Debug.hpp" #include #include #include @@ -20,6 +21,8 @@ #include #include +#include + //------------------------------------------------ // // YAML @@ -63,7 +66,7 @@ struct llvm::yaml::MappingTraits< namespace clang { namespace mrdox { -llvm::Error +Error ConfigImpl:: construct( llvm::StringRef workingDir, @@ -78,7 +81,7 @@ construct( if(workingDir.empty()) { if(auto ec = fs::current_path(s)) - return makeError(ec); + return Error(ec); } else { @@ -101,14 +104,14 @@ construct( yin.setAllowUnknownKeys(true); yin >> *this; if(auto ec = yin.error()) - return makeError(ec); + return Error(ec); } { llvm::yaml::Input yin(extraYaml, this, yamlDiagnostic); yin.setAllowUnknownKeys(true); yin >> *this; if(auto ec = yin.error()) - return makeError(ec); + return Error(ec); } // Post-process as needed @@ -122,7 +125,7 @@ construct( for(auto& name : inputFileIncludes_) name = normalizedPath(name).str(); - return llvm::Error::success(); + return Error::success(); } llvm::SmallString<0> @@ -203,87 +206,53 @@ yamlDiagnostic( //------------------------------------------------ -auto +Expected> createConfigFromYAML( llvm::StringRef workingDir, llvm::StringRef configYaml, - llvm::StringRef extraYaml) -> - llvm::ErrorOr> + llvm::StringRef extraYaml) { - namespace path = llvm::sys::path; - auto config = std::make_shared(); - - if(auto Err = config->construct( + if(auto err = config->construct( workingDir, configYaml, extraYaml)) - return std::make_error_code( - std::errc::invalid_argument); - + return err; return config; } -std::shared_ptr +Expected> loadConfigFile( - std::string_view fileName, - std::string_view extraYaml, - std::error_code& ec) + std::string_view fileNameArg, + std::string_view extraYaml) { namespace fs = llvm::sys::fs; namespace path = llvm::sys::path; + std::error_code ec; + + llvm::SmallString<512> fileName(fileNameArg); + path::remove_dots(fileName, true); + // ensure fileName is a regular file fs::file_status stat; if((ec = fs::status(fileName, stat))) - return {}; + return Error("fs::status(\"{}\") returned \"{}\"", fileName, ec); if(stat.type() != fs::file_type::regular_file) - { - ec = std::make_error_code( - std::errc::invalid_argument); - return {}; - } + return Error("\"{}\" is not a regular file", fileName); // load the file into a string auto fileText = llvm::MemoryBuffer::getFile(fileName); if(! fileText) - { - ec = fileText.getError(); - return {}; - } + return Error("getFile(\"{}\") returned \"{}\"", fileName, fileText.getError()); // calculate the working directory llvm::SmallString<64> workingDir(fileName); path::remove_filename(workingDir); if((ec = fs::make_absolute(workingDir))) - return {}; + return Error("fs::make_absolute(\"{}\") returned \"{}\"", workingDir, ec); // attempt to create the config - auto result = createConfigFromYAML( - workingDir, (*fileText)->getBuffer(), extraYaml); - - if(! result) - { - ec = result.getError(); - return {}; - } - return result.get(); -} - -std::shared_ptr -loadConfigString( - std::string_view workingDir, - std::string_view configYaml, - std::error_code& ec) -{ - auto result = createConfigFromYAML( - workingDir, configYaml, ""); - if(! result) - { - ec = result.getError(); - return {}; - } - ec = {}; - return result.get(); + return createConfigFromYAML(workingDir, + (*fileText)->getBuffer(), extraYaml); } } // mrdox diff --git a/source/ConfigImpl.hpp b/source/ConfigImpl.hpp index bbbf090bc..bbeca983e 100644 --- a/source/ConfigImpl.hpp +++ b/source/ConfigImpl.hpp @@ -14,6 +14,8 @@ #include "Support/YamlFwd.hpp" #include +#include +#include #include #include @@ -60,7 +62,7 @@ class ConfigImpl template friend struct llvm::yaml::MappingTraits; - llvm::Error construct( + Error construct( llvm::StringRef workingDir, llvm::StringRef configYaml, llvm::StringRef extraYaml); @@ -152,13 +154,12 @@ class ConfigImpl additional valid YAML which will be parsed and applied to the existing configuration. */ - friend auto + friend + Expected> createConfigFromYAML( llvm::StringRef workingDir, llvm::StringRef configYaml, - llvm::StringRef extraYaml) -> - llvm::ErrorOr>; + llvm::StringRef extraYaml); }; //------------------------------------------------ @@ -197,14 +198,11 @@ class ConfigImpl additional valid YAML which will be parsed and applied to the existing configuration. */ -auto +Expected> createConfigFromYAML( llvm::StringRef workingDir, llvm::StringRef configYaml, - llvm::StringRef extraYaml) -> - llvm::ErrorOr>; - + llvm::StringRef extraYaml); /** Create a configuration by loading a YAML file. @@ -235,11 +233,10 @@ createConfigFromYAML( @param ec [out] Set to the error, if any occurred. */ MRDOX_DECL -std::shared_ptr +Expected> loadConfigFile( std::string_view fileName, - std::string_view extraYaml, - std::error_code& ec); + std::string_view extraYaml); /** Return a configuration by loading a YAML file. @@ -258,12 +255,11 @@ loadConfigFile( @param ec [out] Set to the error, if any occurred. */ inline -std::shared_ptr +Expected> loadConfigFile( - std::string_view fileName, - std::error_code& ec) + std::string_view fileName) { - return loadConfigFile(fileName, "", ec); + return loadConfigFile(fileName, ""); } /** Create a configuration by loading a YAML string. @@ -289,12 +285,14 @@ loadConfigFile( @param ec [out] Set to the error, if any occurred. */ -MRDOX_DECL -std::shared_ptr +inline +Expected> loadConfigString( std::string_view workingDir, - std::string_view configYaml, - std::error_code& ec); + std::string_view configYaml) +{ + return createConfigFromYAML(workingDir, configYaml, ""); +} } // mrdox } // clang diff --git a/source/Corpus.cpp b/source/Corpus.cpp index c0f5507d9..36854e57a 100644 --- a/source/Corpus.cpp +++ b/source/Corpus.cpp @@ -14,7 +14,8 @@ #include "AST/Bitcode.hpp" #include "AST/FrontendAction.hpp" #include "Metadata/Reduce.hpp" -#include +#include "Support/Error.hpp" +#include #include #include #include @@ -284,12 +285,11 @@ traverse( // //------------------------------------------------ -llvm::Expected> +Expected> Corpus:: build( tooling::ToolExecutor& ex, - std::shared_ptr config_, - Reporter& R) + std::shared_ptr config_) { auto config = std::dynamic_pointer_cast(config_); auto corpus = std::make_unique(config); @@ -313,15 +313,14 @@ build( // and emit serializd bitcode into tool results. // This operation happens ona thread pool. if(corpus->config.verboseOutput) - R.print("Mapping declarations"); + reportInfo("Mapping declarations"); if(auto err = ex.execute( makeFrontendActionFactory( - *ex.getExecutionContext(), *config, R), - ArgAdjuster)) + *ex.getExecutionContext(), *config), ArgAdjuster)) { if(! corpus->config.ignoreFailures) - return err; - R.print("warning: mapping failed because ", toString(std::move(err))); + return toError(std::move(err)); + reportWarning("warning: mapping failed because ", toString(std::move(err))); } // Inject the global namespace @@ -338,12 +337,12 @@ build( // a vector of one or more bitcodes. These will // be merged later. if(corpus->config.verboseOutput) - R.print("Collecting symbols"); + reportInfo("Collecting symbols"); auto bitcodes = collectBitcodes(ex); // First reducing phase (reduce all decls into one info per decl). if(corpus->config.verboseOutput) - R.print("Reducing ", bitcodes.size(), " declarations"); + reportInfo("Reducing {} declarations", bitcodes.size()); std::atomic GotFailure; GotFailure = false; corpus->config.parallelForEach( @@ -356,9 +355,10 @@ build( // Each Bitcode can have multiple Infos for (auto& bitcode : Group.getValue()) { - auto infos = readBitcode(bitcode, R); - if(R.error(infos, "read bitcode")) + auto infos = readBitcode(bitcode); + if(! infos) { + reportError(infos.getError(), "read bitcode"); GotFailure = true; return; } @@ -369,8 +369,9 @@ build( } auto merged = mergeInfos(Infos); - if(R.error(merged, "merge metadata")) + if(! merged) { + reportError(toError(merged.takeError()), "merge metadata"); GotFailure = true; return; } @@ -381,12 +382,12 @@ build( }); if(corpus->config.verboseOutput) - R.print("Collected ", corpus->InfoMap.size(), " symbols.\n"); + llvm::outs() << "Collected " << corpus->InfoMap.size() << " symbols.\n"; if(GotFailure) - return makeErrorString("one or more errors occurred"); + return Error("multiple errors occurred"); - corpus->canonicalize(R); + corpus->canonicalize(); return corpus; } diff --git a/source/CorpusImpl.cpp b/source/CorpusImpl.cpp index 570e10d54..42eb3423d 100644 --- a/source/CorpusImpl.cpp +++ b/source/CorpusImpl.cpp @@ -11,6 +11,7 @@ #include "CorpusImpl.hpp" #include +#include #include namespace clang { @@ -233,13 +234,12 @@ class CorpusImpl:: void CorpusImpl:: -canonicalize( - Reporter& R) +canonicalize() { if(isCanonical_) return; if(config_->verboseOutput) - R.print("Canonicalizing..."); + reportInfo("Canonicalizing..."); Canonicalizer cn(*this); traverse(cn, SymbolID::zero); std::string temp0; diff --git a/source/CorpusImpl.hpp b/source/CorpusImpl.hpp index 7a1c27fe3..15900dfce 100644 --- a/source/CorpusImpl.hpp +++ b/source/CorpusImpl.hpp @@ -15,6 +15,7 @@ #include "Support/Debug.hpp" #include #include +#include #include namespace clang { @@ -102,7 +103,7 @@ class CorpusImpl : public Corpus @param R The diagnostic reporting object to use for delivering errors and information. */ - void canonicalize(Reporter& R); + void canonicalize(); std::shared_ptr config_; diff --git a/source/GenerateAction.cpp b/source/GenerateAction.cpp index 1c4e63abd..19802874a 100644 --- a/source/GenerateAction.cpp +++ b/source/GenerateAction.cpp @@ -12,7 +12,6 @@ #include "Options.hpp" #include "ConfigImpl.hpp" #include -#include #include #include #include @@ -20,8 +19,8 @@ namespace clang { namespace mrdox { -int -DoGenerateAction(Reporter& R) +Error +DoGenerateAction() { auto& generators = getGenerators(); @@ -35,42 +34,21 @@ DoGenerateAction(Reporter& R) // Load configuration file if(! ConfigPath.hasArgStr()) - { - llvm::errs() << - "Missing configuration file path argument.\n"; - return EXIT_FAILURE; - } - std::error_code ec; - auto config = loadConfigFile(ConfigPath, extraYaml, ec); - if(ec) - { - (void)R.error(ec, "load config file '", ConfigPath, "'"); - return EXIT_FAILURE; - } + return Error("the config path argument is missing"); + auto config = loadConfigFile(ConfigPath, extraYaml); + if(! config) + return config.getError(); // Load the compilation database if(InputPaths.empty()) - { - llvm::errs() << - "Missing path to compilation database argument.\n"; - return EXIT_FAILURE; - } + return Error("the compilation database path argument is missing"); if(InputPaths.size() > 1) - { - llvm::errs() << - "Expected one input path argument, got more than one.\n"; - return EXIT_FAILURE; - } + return Error("got {} input paths where 1 was expected", InputPaths.size()); std::string errorMessage; - auto compilations = - tooling::JSONCompilationDatabase::loadFromFile( - InputPaths.front(), errorMessage, - tooling::JSONCommandLineSyntax::AutoDetect); + auto compilations = tooling::JSONCompilationDatabase::loadFromFile( + InputPaths.front(), errorMessage, tooling::JSONCommandLineSyntax::AutoDetect); if(! compilations) - { - llvm::errs() << errorMessage << '\n'; - return EXIT_FAILURE; - } + return Error(std::move(errorMessage)); // Create the ToolExecutor from the compilation database int ThreadCount = 0; @@ -80,26 +58,17 @@ DoGenerateAction(Reporter& R) // Create the generator auto generator = generators.find(FormatType.getValue()); if(! generator) - { - R.print("Generator '", FormatType.getValue(), "' not found."); - return EXIT_FAILURE; - } + return Error("the Generator \"{}\" was not found", FormatType.getValue()); // Run the tool, this can take a while - auto corpus = Corpus::build(*ex, config, R); - if(R.error(corpus, "build the documentation corpus")) - return EXIT_FAILURE; + auto corpus = Corpus::build(*ex, *config); + if(! corpus) + return Error("Corpus::build returned \"{}\"", corpus.getError()); // Run the generator. - if(config->verboseOutput) + if(config.get()->verboseOutput) llvm::outs() << "Generating docs...\n"; - auto err = generator->build(OutputPath.getValue(), **corpus, R); - if(err) - { - R.print(err.message(), "generate '", OutputPath, "'"); - return EXIT_FAILURE; - } - return EXIT_SUCCESS; + return generator->build(OutputPath.getValue(), **corpus); } } // mrdox diff --git a/source/Support/Error.cpp b/source/Support/Error.cpp index f774b127c..b66ba8c6c 100644 --- a/source/Support/Error.cpp +++ b/source/Support/Error.cpp @@ -1,5 +1,4 @@ // -// This is a derivative work. originally part of the LLVM Project. // Licensed 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 @@ -9,106 +8,10 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include -#include -#include -#include +#include namespace clang { namespace mrdox { -llvm::StringRef -nice( - std::source_location loc) -{ - namespace path = llvm::sys::path; - - static thread_local llvm::SmallString<0> temp; - - llvm::StringRef fileName(loc.file_name()); - auto it = path::rbegin(fileName); - auto const end = path::rend(fileName); - if(it == end) - { - temp.clear(); - return {}; - } - for(;;) - { - // VFALCO This assumes the directory - // layout of the source files. - if( *it == "source" || - *it == "include") - { - temp.assign( - it->data(), - fileName.end()); - break; - } - ++it; - if(it == end) - { - temp = fileName; - break; - } - } - path::remove_dots(temp, true); - temp.push_back('('); - temp.append(std::to_string(loc.line())); - temp.push_back(')'); - return temp; -} - -namespace { - -class ErrorInfoPlus - : public llvm::ErrorInfo -{ - std::string action_; - std::source_location loc_; - -public: - static char ID; - - ErrorInfoPlus( - std::string action, - std::source_location loc) - : action_(std::move(action)) - , loc_(loc) - { - } - - void - log( - llvm::raw_ostream &os) const override - { - os << action_ << " at " << nice(loc_); - } - - std::error_code - convertToErrorCode() const override - { - return llvm::inconvertibleErrorCode(); - } - - void const* - dynamicClassID() const override - { - return this; - } -}; - -char ErrorInfoPlus::ID{}; - -} // (anon) - -llvm::Error -makeErrorString( - std::string reason, - std::source_location loc) -{ - return llvm::make_error(std::move(reason), loc); -} - } // mrdox } // clang diff --git a/source/Support/Error.hpp b/source/Support/Error.hpp new file mode 100644 index 000000000..de81c4d06 --- /dev/null +++ b/source/Support/Error.hpp @@ -0,0 +1,58 @@ +// +// Licensed 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 +// +// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) +// +// Official repository: https://github.com/cppalliance/mrdox +// + +#ifndef MRDOX_SUPPORT_ERROR_HPP +#define MRDOX_SUPPORT_ERROR_HPP + +#include +#include +#include +#include + +template<> +struct fmt::formatter + : fmt::formatter +{ + auto format( + llvm::StringRef s, + fmt::format_context& ctx) const + { + return fmt::formatter::format( + std::string_view(s.data(), s.size()), ctx); + } +}; + +template +struct fmt::formatter> + : fmt::formatter +{ + auto format( + llvm::SmallString const& s, + fmt::format_context& ctx) const + { + return fmt::formatter::format( + std::string_view(s.data(), s.size()), ctx); + } +}; + +namespace clang { +namespace mrdox { + +inline +Error +toError(llvm::Error err) +{ + return Error(toString(std::move(err))); +} + +} // mrdox +} // clang + +#endif diff --git a/source/Support/Generator.cpp b/source/Support/Generator.cpp index d6ed855a1..1fab42963 100644 --- a/source/Support/Generator.cpp +++ b/source/Support/Generator.cpp @@ -10,7 +10,7 @@ // #include "AST/ParseJavadoc.hpp" -#include +#include #include #include #include @@ -29,12 +29,11 @@ Generator:: the file reference.ext using the extension of the generator. */ -Err +Error Generator:: build( std::string_view outputPath, - Corpus const& corpus, - Reporter& R) const + Corpus const& corpus) const { namespace path = llvm::sys::path; @@ -51,15 +50,14 @@ build( path::replace_extension(fileName, ext); } - return buildOne(fileName.str(), corpus, R); + return buildOne(fileName.str(), corpus); } -Err +Error Generator:: buildOne( std::string_view fileName, - Corpus const& corpus, - Reporter& R) const + Corpus const& corpus) const { std::ofstream os; @@ -73,31 +71,30 @@ buildOne( } catch(std::exception const& ex) { - return makeErr("std::ofstream threw ", ex.what()); + return Error("std::ofstream threw \"{}\"", ex.what()); } try { - return buildOne(os, corpus, R); + return buildOne(os, corpus); } catch(std::exception const& ex) { - return makeErr("buildOne threw ", ex.what() ); + return Error("buildOne threw \"{}\"", ex.what()); } } -Err +Error Generator:: buildOneString( std::string& dest, - Corpus const& corpus, - Reporter& R) const + Corpus const& corpus) const { dest.clear(); std::stringstream ss; try { - auto err = buildOne(ss, corpus, R); + auto err = buildOne(ss, corpus); if(err) return err; dest = ss.str(); @@ -105,7 +102,7 @@ buildOneString( } catch(std::exception const& ex) { - return makeErr("buildOne threw ", ex.what() ); + return Error("buildOne threw \"{}\"", ex.what()); } } diff --git a/source/Support/GeneratorsImpl.cpp b/source/Support/GeneratorsImpl.cpp index cf6f6816e..1ea31af42 100644 --- a/source/Support/GeneratorsImpl.cpp +++ b/source/Support/GeneratorsImpl.cpp @@ -42,9 +42,10 @@ refresh_plist() GeneratorsImpl:: GeneratorsImpl() { - llvm::handleAllErrors(insert(makeAdocGenerator())); - llvm::handleAllErrors(insert(makeBitcodeGenerator())); - llvm::handleAllErrors(insert(makeXMLGenerator())); + Error err; + err = insert(makeAdocGenerator()); + err = insert(makeBitcodeGenerator()); + err = insert(makeXMLGenerator()); } Generator const* @@ -58,16 +59,16 @@ find( return nullptr; } -llvm::Error +Error GeneratorsImpl:: insert( std::unique_ptr G) { if(find(G->id()) != nullptr) - return makeError("generator id = '", G->id(), "' already exists"); + return Error("generator id=\"{}\" already exists", G->id()); list_.emplace_back(std::move(G)); refresh_plist(); - return llvm::Error::success(); + return Error::success(); } //------------------------------------------------ diff --git a/source/Support/GeneratorsImpl.hpp b/source/Support/GeneratorsImpl.hpp index e439490cd..404612a66 100644 --- a/source/Support/GeneratorsImpl.hpp +++ b/source/Support/GeneratorsImpl.hpp @@ -11,7 +11,7 @@ #ifndef MRDOX_SUPPORT_GENERATORSIMPL_HPP #define MRDOX_SUPPORT_GENERATORSIMPL_HPP -#include +#include #include #include #include @@ -53,7 +53,7 @@ class MRDOX_VISIBLE /** Insert a generator */ - llvm::Error + Error insert(std::unique_ptr G); }; diff --git a/source/Support/Report.cpp b/source/Support/Report.cpp new file mode 100644 index 000000000..1d3eac39f --- /dev/null +++ b/source/Support/Report.cpp @@ -0,0 +1,46 @@ +// +// Licensed 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 +// +// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) +// +// Official repository: https://github.com/cppalliance/mrdox +// + +#include +#include +#include +#include + +namespace clang { +namespace mrdox { + +static llvm::sys::Mutex report_mutex_; + +void +reportError( + std::string_view text) +{ + std::lock_guard lock(report_mutex_); + llvm::errs() << text << '\n'; +} + +void +reportWarning( + std::string_view text) +{ + std::lock_guard lock(report_mutex_); + llvm::errs() << text << '\n'; +} + +void +reportInfo( + std::string_view text) +{ + std::lock_guard lock(report_mutex_); + llvm::errs() << text << '\n'; +} + +} // mrdox +} // clang diff --git a/source/Support/Reporter.cpp b/source/Support/Reporter.cpp deleted file mode 100644 index 053d0e2b4..000000000 --- a/source/Support/Reporter.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// -// This is a derivative work. originally part of the LLVM Project. -// Licensed 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 -// -// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com) -// -// Official repository: https://github.com/cppalliance/mrdox -// - -#include -#include -#include -#include -#include -#include - -namespace clang { -namespace mrdox { - -//------------------------------------------------ -// -// Reporter -// -//------------------------------------------------ - -int -Reporter:: -getExitCode() const noexcept -{ - if(errorCount_ > 0) - return EXIT_FAILURE; - return EXIT_SUCCESS; -} - -//------------------------------------------------ - -void -Reporter:: -threadSafePrint( - llvm::raw_fd_ostream& os, - llvm::StringRef s, - std::size_t* n) - -{ - std::lock_guard lock(m_); - os << s << '\n'; - if(n) - (*n)++; -} - -std::string& -Reporter:: -temp_string() -{ - static thread_local std::string s; - return s; -} - -//------------------------------------------------ - -void -Reporter:: -reportError() -{ - std::lock_guard lock(m_); - ++errorCount_; -} - -} // mrdox -} // clang diff --git a/source/TestAction.cpp b/source/TestAction.cpp index a126a66c6..f74bd2ed4 100644 --- a/source/TestAction.cpp +++ b/source/TestAction.cpp @@ -12,9 +12,10 @@ #include "SingleFileDB.hpp" #include "ConfigImpl.hpp" #include "Support/Debug.hpp" +#include "Support/Error.hpp" #include -#include #include +#include #include #include #include @@ -75,7 +76,7 @@ class TestRunner std::string extraYaml_; std::shared_ptr config_; Config::WorkGroup wg_; - Reporter& R_; + llvm::ErrorOr diff_; Generator const* xmlGen_; Generator const* adocGen_; @@ -83,32 +84,31 @@ class TestRunner makeConfig( llvm::StringRef workingDir); - llvm::Error + Error writeFile( llvm::StringRef filePath, llvm::StringRef contents); - llvm::Error + Error handleFile( llvm::StringRef filePath, std::shared_ptr const& config); - llvm::Error + Error handleDir( llvm::StringRef dirPath); public: TestRunner( Results& results, - llvm::StringRef extraYaml, - Reporter& R); + llvm::StringRef extraYaml); /** Check a single file, or a directory recursively. This function checks the specified path and blocks until completed. */ - llvm::Error + Error checkPath( llvm::StringRef inputPath); }; @@ -118,20 +118,19 @@ class TestRunner TestRunner:: TestRunner( Results& results, - llvm::StringRef extraYaml, - Reporter& R) + llvm::StringRef extraYaml) : results_(results) , extraYaml_(extraYaml) , config_([&extraYaml] { std::error_code ec; auto config = loadConfigString( - "", extraYaml.str(), ec); - Assert(! ec); - return config; + "", extraYaml.str()); + Assert(config); + return *config; }()) , wg_(config_.get()) - , R_(R) + , diff_(llvm::sys::findProgramByName("diff")) , xmlGen_(getGenerators().find("xml")) , adocGen_(getGenerators().find("adoc")) { @@ -156,13 +155,12 @@ makeConfig( std::error_code ec; auto config = loadConfigString( - workingDir, configYaml, - ec); - Assert(! ec); - return config; + workingDir, configYaml); + Assert(config); + return *config; } -llvm::Error +Error TestRunner:: writeFile( llvm::StringRef filePath, @@ -173,20 +171,19 @@ writeFile( if(ec) { results_.numberOfErrors++; - return makeError("raw_fd_ostream returned ", ec); + return Error("raw_fd_ostream(\"{}\") returned \"{}\"", filePath, ec); } os << contents; if(os.error()) { results_.numberOfErrors++; - return makeError("raw_fd_ostream::write returned ", os.error()); + return Error("raw_fd_ostream::write returned \"{}\"", os.error()); } - //R_.print("File '", outputPath, "' written."); results_.numberofFilesWritten++; - return llvm::Error::success(); + return Error::success(); } -llvm::Error +Error TestRunner:: handleFile( llvm::StringRef filePath, @@ -210,23 +207,22 @@ handleFile( { SingleFileDB db(dirPath, filePath); tooling::StandaloneToolExecutor ex(db, { std::string(filePath) }); - auto result = Corpus::build(ex, config, R_); - if(R_.error(result, "build Corpus for '", filePath, "'")) + auto result = Corpus::build(ex, config); + if(! result) { - results_.numberOfErrors++; - return llvm::Error::success(); // keep going + reportError(result.getError(), "build Corpus for \"{}\"", filePath); + return Error::success(); // keep going } corpus = std::move(result.get()); } // Generate XML std::string generatedXml; - if(R_.error( - xmlGen_->buildOneString(generatedXml, *corpus, R_), - "build XML string for '", filePath, "'")) + if(auto err = xmlGen_->buildOneString(generatedXml, *corpus)) { + reportError(err, "build XML string for \"{}\"", filePath); results_.numberOfErrors++; - return llvm::Error::success(); // keep going + return Error::success(); // keep going } if(ToolAction == Action::test) @@ -243,13 +239,15 @@ handleFile( if( result.getError() != std::errc::no_such_file_or_directory) { // Some kind of system problem - (void)R_.error(result.getError(), "load '", outputPath, "'"); - return llvm::Error::success(); // keep going + reportError( + Error("MemoryBuffer::getFile(\"{}\") returned \"{}\""), + "load the reference XML"); + return Error::success(); // keep going } // File does not exist, so write it if(auto err = writeFile(outputPath, generatedXml)) - return llvm::Error::success(); + return Error::success(); } else { @@ -263,7 +261,7 @@ handleFile( { // The output did not match results_.numberOfFailures++; - R_.print("Failed: '", filePath, "'\n"); + reportError("Test for \"{}\" failed", filePath); if(badOption.getValue()) { @@ -273,21 +271,21 @@ handleFile( { std::error_code ec; llvm::raw_fd_ostream os(bad, ec, llvm::sys::fs::OF_None); - if (ec) { + if (ec) + { results_.numberOfErrors++; - return makeError("raw_fd_ostream returned ", ec); + return Error("raw_fd_ostream(\"{}\") returned \"{}\"", bad, ec); } os << generatedXml; } - auto diff = llvm::sys::findProgramByName("diff"); - - if (!diff.getError()) + // VFALCO We are calling this over and over again instead of once? + if(! diff_.getError()) { path::replace_extension(bad, "xml"); std::array args { - diff.get(), "-u", "--color", bad, outputPath }; - llvm::sys::ExecuteAndWait(diff.get(), args); + diff_.get(), "-u", "--color", bad, outputPath }; + llvm::sys::ExecuteAndWait(diff_.get(), args); } // Fix the path for the code that follows @@ -306,14 +304,14 @@ handleFile( if(auto err = writeFile(outputPath, generatedXml)) { results_.numberOfErrors++; - return llvm::Error::success(); + return Error::success(); } } - return llvm::Error::success(); + return Error::success(); } -llvm::Error +Error TestRunner:: handleDir( llvm::StringRef dirPath) @@ -327,7 +325,7 @@ handleDir( std::error_code ec; fs::directory_iterator iter(dirPath, ec, false); if(ec) - return makeError("directory_iterator returned ", ec); + return Error("fs::directory_iterator(\"{}\") returned \"{}\"", dirPath, ec); fs::directory_iterator const end{}; auto const config = makeConfig(dirPath); @@ -355,12 +353,12 @@ handleDir( } iter.increment(ec); if(ec) - return makeError("directory_iterator returned ", ec); + return Error("directory_iterator::increment returned \"{}\"", ec); } - return llvm::Error::success(); + return Error::success(); } -llvm::Error +Error TestRunner:: checkPath( llvm::StringRef inputPath) @@ -373,14 +371,14 @@ checkPath( if(auto ec = fs::status(inputPath, fileStatus)) { results_.numberOfErrors++; - return makeError("fs::status returned '", ec, "'"); + return Error("fs::status(\"{}\") returned \"{}\"", inputPath, ec); } if(fileStatus.type() == fs::file_type::regular_file) { auto const ext = path::extension(inputPath); if(! ext.equals_insensitive(".cpp")) - return makeError("expected a .cpp file"); + return Error("\"{}\" is not a .cpp file"); // Calculate the workingDir SmallString workingDir(inputPath); @@ -403,11 +401,11 @@ checkPath( return err; } - return makeError("wrong fs::file_type=", static_cast(fileStatus.type())); + return Error("fs::file_type was not directory_file"); } int -DoTestAction(Reporter& R) +DoTestAction() { using namespace clang::mrdox; @@ -417,10 +415,12 @@ DoTestAction(Reporter& R) Results results; for(auto const& inputPath : InputPaths) { - TestRunner instance(results, extraYaml, R); + TestRunner instance(results, extraYaml); if(auto err = instance.checkPath(inputPath)) - if(R.error(err, "check path '", inputPath, "'")) - break; + { + reportError(err, "check path \"{}\"", inputPath); + break; + } } auto& os = debug_outs(); diff --git a/source/ToolMain.cpp b/source/ToolMain.cpp index be3b89b60..691fa5960 100644 --- a/source/ToolMain.cpp +++ b/source/ToolMain.cpp @@ -34,7 +34,7 @@ #include "Options.hpp" #include "Support/Debug.hpp" -#include +#include #include #include #include @@ -44,8 +44,8 @@ namespace clang { namespace mrdox { -extern int DoGenerateAction(Reporter&); -extern int DoTestAction(Reporter&); +extern Error DoGenerateAction(); +extern int DoTestAction(); inline void print_version(llvm::raw_ostream& os) { @@ -80,11 +80,17 @@ int main(int argc, char const** argv) } } - Reporter R; - int toolResult; + // Generate if(clang::mrdox::ToolAction == Action::generate) - toolResult = DoGenerateAction(R); - else - toolResult = DoTestAction(R); - return toolResult; + { + auto err = DoGenerateAction(); + if(! err) + return EXIT_SUCCESS; + + reportError(err, "generate reference documentation"); + return EXIT_FAILURE; + } + + // Test + return DoTestAction(); }