[clang] Avoid linking libdl unless needed
[llvm-project.git] / libc / docs / implementation_standard.rst
blob87cee06adf2eeca7e826f6428e522ace4b88e6e1
1 Convention for implementing entrypoints
2 =======================================
4 LLVM-libc entrypoints are defined in the entrypoints document. In this document,
5 we explain how the entrypoints are implemented. The source layout document
6 explains that, within the high level ``src`` directory, there exists one
7 directory for every public header file provided by LLVM-libc. The
8 implementations of related group of entrypoints will also live in a directory of
9 their own. This directory will have a name indicative of the related group of
10 entrypoints, and will be under the directory corresponding to the header file of
11 the entrypoints. For example, functions like ``fopen`` and ``fclose`` cannot be
12 tested independent of each other and hence will live in a directory named
13 ``src/stdio/file_operations``. On the other hand, the implementation of the
14 ``round`` function from ``math.h`` can be tested by itself, so it will live in
15 the directory of its own named ``src/math/round/``.
17 Implementation of entrypoints can span multiple ``.cpp`` and ``.h`` files, but
18 there will be atleast one header file with name of the form
19 ``<entrypoint name>.h`` for every entrypoint. This header file is called as the
20 implementation header file. For the ``round`` function, the path to the
21 implementation header file will be ``src/math/round/round.h``. The rest of this
22 document explains the structure of implementation header files and ``.cpp``
23 files.
25 Implementation Header File Structure
26 ------------------------------------
28 We will use the ``round`` function from the public ``math.h`` header file as an
29 example. The ``round`` function will be declared in an internal header file
30 ``src/math/round/round.h`` as follows::
32     // --- round.h --- //
33     #ifndef LLVM_LIBC_SRC_MATH_ROUND_ROUND_H
34     #define LLVM_LIBC_SRC_MATH_ROUND_ROUND_H
36     namespace __llvm_libc {
38     double round(double);
40     } // namespace __llvm_libc
42     #endif LLVM_LIBC_SRC_MATH_ROUND_ROUND_H
44 Notice that the ``round`` function declaration is nested inside the namespace
45 ``__llvm_libc``. All implementation constructs in LLVM-libc are declared within
46 the namespace ``__llvm_libc``.
48 ``.cpp`` File Structure
49 -----------------------
51 The implementation can span multiple ``.cpp`` files. However, the signature of
52 the entrypoint function should make use of a special macro. For example, the
53 ``round`` function from ``math.h`` should be defined as follows, say in the file
54 ``src/math/math/round.cpp``::
56     // --- round.cpp --- //
58     namespace __llvm_libc {
60     double LLVM_LIBC_ENTRYPOINT(round)(double d) {
61       // ... implementation goes here.
62     }
64     } // namespace __llvm_libc
66 Notice the use of the macro ``LLVM_LIBC_ENTRYPOINT``. This macro helps us define
67 an C alias symbol for the C++ implementation. The C alias need not be added by
68 the macro by itself. For example, for ELF targets, the macro is defined as
69 follows::
71     #define ENTRYPOINT_SECTION_ATTRIBUTE(name) \
72         __attribute__((section(".llvm.libc.entrypoint."#name)))
73     #define LLVM_LIBC_ENTRYPOINT(name) ENTRYPOINT_SECTION_ATTRIBUTE(name) name
75 The macro places the C++ function in a unique section with name
76 ``.llvm.libc.entrypoint.<function name>``. This allows us to add a C alias using
77 a post build step. For example, for the ``round`` function, one can use
78 ``objcopy`` to add an alias symbol as follows::
80     objcopy --add-symbol round=.llvm.libc.entrypoint.round:0,function round.o
82 NOTE: We use a post build ``objcopy`` step to add an alias instead of using
83 the ``__attribute__((alias))``. For C++, this ``alias`` attribute requires
84 mangled names of the referees. Using the post build ``objcopy`` step helps
85 us avoid putting mangled names with ``alias`` attributes.