diff --git a/llvm/docs/ProgrammersManual.rst b/llvm/docs/ProgrammersManual.rst --- a/llvm/docs/ProgrammersManual.rst +++ b/llvm/docs/ProgrammersManual.rst @@ -278,15 +278,17 @@ outputs such as ``llvm-readobj`` to printing verbose disassembly listings and LLDB runtime logging, the need for string formatting is pervasive. -The ``formatv`` is similar in spirit to ``printf``, but uses a different syntax -which borrows heavily from Python and C#. Unlike ``printf`` it deduces the type -to be formatted at compile time, so it does not need a format specifier such as -``%d``. This reduces the mental overhead of trying to construct portable format -strings, especially for platform-specific types like ``size_t`` or pointer types. -Unlike both ``printf`` and Python, it additionally fails to compile if LLVM does -not know how to format the type. These two properties ensure that the function -is both safer and simpler to use than traditional formatting methods such as -the ``printf`` family of functions. +The ``formatv`` function (`doxygen +`__) is similar in +spirit to ``printf``, but uses a different syntax which borrows heavily from +Python and C#. Unlike ``printf`` it deduces the type to be formatted at compile +time, so it does not need a format specifier such as ``%d``. This reduces the +mental overhead of trying to construct portable format strings, especially for +platform-specific types like ``size_t`` or pointer types. Unlike both +``printf`` and Python, it additionally fails to compile if LLVM does not know +how to format the type. These two properties ensure that the function is both +safer and simpler to use than traditional formatting methods such as the +``printf`` family of functions. Simple formatting ^^^^^^^^^^^^^^^^^ @@ -454,14 +456,15 @@ situations where you absolutely must emit a non-programmatic error and the ``Error`` model isn't workable you can call ``report_fatal_error``, which will call installed error handlers, print a message, and abort the - program. The use of `report_fatal_error` in this case is discouraged. + program. The use of ``report_fatal_error`` in this case is discouraged. -Recoverable errors are modeled using LLVM's ``Error`` scheme. This scheme -represents errors using function return values, similar to classic C integer -error codes, or C++'s ``std::error_code``. However, the ``Error`` class is -actually a lightweight wrapper for user-defined error types, allowing arbitrary -information to be attached to describe the error. This is similar to the way C++ -exceptions allow throwing of user-defined types. +Recoverable errors are modeled using LLVM's ``Error`` scheme (`doxygen +`__). This scheme represents +errors using function return values, similar to classic C integer error codes, +or C++'s ``std::error_code``. However, the ``Error`` class is actually a +lightweight wrapper for user-defined error types, allowing arbitrary information +to be attached to describe the error. This is similar to the way C++ exceptions +allow throwing of user-defined types. Success values are created by calling ``Error::success()``, E.g.: @@ -520,12 +523,13 @@ ... For functions that can fail but need to return a value the ``Expected`` -utility can be used. Values of this type can be constructed with either a -``T``, or an ``Error``. Expected values are also implicitly convertible to -boolean, but with the opposite convention to ``Error``: true for success, false -for error. If success, the ``T`` value can be accessed via the dereference -operator. If failure, the ``Error`` value can be extracted using the -``takeError()`` method. Idiomatic usage looks like: +utility can be used (`doxygen +`__). Values of this type +can be constructed with either a ``T``, or an ``Error``. Expected values are +also implicitly convertible to boolean, but with the opposite convention to +``Error``: true for success, false for error. If success, the ``T`` value can be +accessed via the dereference operator. If failure, the ``Error`` value can be +extracted using the ``takeError()`` method. Idiomatic usage looks like: .. code-block:: c++ @@ -660,10 +664,11 @@ Many kinds of errors have no recovery strategy, the only action that can be taken is to report them to the user so that the user can attempt to fix the environment. In this case representing the error as a string makes perfect -sense. LLVM provides the ``StringError`` class for this purpose. It takes two -arguments: A string error message, and an equivalent ``std::error_code`` for -interoperability. It also provides a ``createStringError`` function to simplify -common usage of this class: +sense. LLVM provides the ``StringError`` class (`doxygen +`__) for this +purpose. It takes two arguments: A string error message, and an equivalent +``std::error_code`` for interoperability. It also provides a +``createStringError`` function to simplify common usage of this class: .. code-block:: c++ @@ -697,13 +702,14 @@ """"""""""""""""""""""""""""""""""""""""""""""""" Many existing LLVM APIs use ``std::error_code`` and its partner ``ErrorOr`` -(which plays the same role as ``Expected``, but wraps a ``std::error_code`` -rather than an ``Error``). The infectious nature of error types means that an -attempt to change one of these functions to return ``Error`` or ``Expected`` -instead often results in an avalanche of changes to callers, callers of callers, -and so on. (The first such attempt, returning an ``Error`` from -MachOObjectFile's constructor, was abandoned after the diff reached 3000 lines, -impacted half a dozen libraries, and was still growing). +(`doxygen `__), which plays +the same role as ``Expected``, but wraps a ``std::error_code`` rather than an +``Error``. The infectious nature of error types means that an attempt to change +one of these functions to return ``Error`` or ``Expected`` instead often +results in an avalanche of changes to callers, callers of callers, and so +on. (The first such attempt, returning an ``Error`` from MachOObjectFile's +constructor, was abandoned after the diff reached 3000 lines, impacted half a +dozen libraries, and was still growing). To solve this problem, the ``Error``/``std::error_code`` interoperability requirement was introduced. Two pairs of functions allow any ``Error`` value to be converted to a @@ -754,9 +760,11 @@ ``exit`` upon encountering an error dramatically simplifies control flow as the error no longer needs to be propagated up the stack. This allows code to be written in straight-line style, as long as each fallible call is wrapped in a -check and call to exit. The ``ExitOnError`` class supports this pattern by -providing call operators that inspect ``Error`` values, stripping the error away -in the success case and logging to ``stderr`` then exiting in the failure case. +check and call to exit. The ``ExitOnError`` class (`doxygen +`__) supports this +pattern by providing call operators that inspect ``Error`` values, stripping the +error away in the success case and logging to ``stderr`` then exiting in the +failure case. To use this class, declare a global ``ExitOnError`` variable in your program: @@ -804,9 +812,10 @@ Some functions may only fail for a subset of their inputs, so calls using known safe inputs can be assumed to succeed. -The cantFail functions encapsulate this by wrapping an assertion that their -argument is a success value and, in the case of Expected, unwrapping the -T value: +The ``cantFail`` functions (`doxygen +`__) encapsulate this by +wrapping an assertion that their argument is a success value and, in the case of +``Expected``, unwrapping the T value: .. code-block:: c++ @@ -819,16 +828,16 @@ ... } -Like the ExitOnError utility, cantFail simplifies control flow. Their treatment -of error cases is very different however: Where ExitOnError is guaranteed to -terminate the program on an error input, cantFail simply asserts that the result -is success. In debug builds this will result in an assertion failure if an error -is encountered. In release builds the behavior of cantFail for failure values is -undefined. As such, care must be taken in the use of cantFail: clients must be -certain that a cantFail wrapped call really can not fail with the given -arguments. +Like the ``ExitOnError`` utility, ``cantFail`` simplifies control flow. Their +treatment of error cases is very different however: Where ``ExitOnError`` is +guaranteed to terminate the program on an error input, ``cantFail`` simply +asserts that the result is success. In debug builds this will result in an +assertion failure if an error is encountered. In release builds the behavior of +``cantFail`` for failure values is undefined. As such, care must be taken in the +use of ``cantFail``: clients must be certain that a ``cantFail`` wrapped call +really can not fail with the given arguments. -Use of the cantFail functions should be rare in library code, but they are +Use of the ``cantFail`` functions should be rare in library code, but they are likely to be of more use in tool and unit-test code where inputs and/or mocked-up classes or functions may be known to be safe.