From 64cd55a12676cf108f89438dfa7b47b9c1cf0b75 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 6 May 2014 07:45:39 +0000 Subject: [PATCH] Update programmers manual to cover llvm::function_ref, and add a note to the coding standard suggesting using it instead of the (unavailable) std::function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208067 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/CodingStandards.rst | 2 ++ docs/ProgrammersManual.rst | 72 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/docs/CodingStandards.rst b/docs/CodingStandards.rst index 0fcca0330f4..edbef3ace53 100644 --- a/docs/CodingStandards.rst +++ b/docs/CodingStandards.rst @@ -108,6 +108,8 @@ unlikely to be supported by our host compilers. * Lambdas: N2927_ * But *not* ``std::function``, until Clang implements `MSVC-compatible RTTI`_. + In many cases, you may be able to use ``llvm::function_ref`` instead, and it + is a superior choice in those cases. * And *not* lambdas with default arguments. * ``decltype``: N2343_ diff --git a/docs/ProgrammersManual.rst b/docs/ProgrammersManual.rst index 473d95df78c..7e46ac4e8e6 100644 --- a/docs/ProgrammersManual.rst +++ b/docs/ProgrammersManual.rst @@ -263,6 +263,78 @@ almost never be stored or mentioned directly. They are intended solely for use when defining a function which should be able to efficiently accept concatenated strings. +.. _function_apis: + +Passing functions and other callable objects +-------------------------------------------- + +Sometimes you may want a function to be passed a callback object. In order to +support lambda expressions and other function objects, you should not use the +traditional C approach of taking a function pointer and an opaque cookie: + +.. code-block:: c++ + + void takeCallback(bool (*Callback)(Function *, void *), void *Cookie); + +Instead, use one of the following approaches: + +Function template +^^^^^^^^^^^^^^^^^ + +If you don't mind putting the definition of your function into a header file, +make it a function template that is templated on the callable type. + +.. code-block:: c++ + + template + void takeCallback(Callable Callback) { + Callback(1, 2, 3); + } + +The ``function_ref`` class template +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The ``function_ref`` +(`doxygen `__) class +template represents a reference to a callable object, templated over the type +of the callable. This is a good choice for passing a callback to a function, +if you don't need to hold onto the callback after the function returns. + +``function_ref`` can be implicitly constructed from +any callable object that can be called with arguments of type ``Param1``, +``Param2``, ..., and returns a value that can be converted to type ``Ret``. +For example: + +.. code-block:: c++ + + void visitBasicBlocks(Function *F, function_ref Callback) { + for (BasicBlock &BB : *F) + if (Callback(&BB)) + return; + } + +can be called using: + +.. code-block:: c++ + + visitBasicBlocks(F, [&](BasicBlock *BB) { + if (process(BB)) + return isEmpty(BB); + return false; + }); + +Note that a ``function_ref`` object contains pointers to external memory, so +it is not generally safe to store an instance of the class (unless you know +that the external storage will not be freed). +``function_ref`` is small enough that it should always be passed by value. + +``std::function`` +^^^^^^^^^^^^^^^^^ + +You cannot use ``std::function`` within LLVM code, because it is not supported +by all our target toolchains. + + .. _DEBUG: The ``DEBUG()`` macro and ``-debug`` option -- 2.34.1