Skip to content

Commit 665efe8

Browse files
authored
[libc] Add LIBC_NAMESPACE_DECL macro (#97109)
This defines to LIBC_NAMESPACE with `__attribute__((visibility("hidden")))` so all the symbols under it have hidden visibility. This new macro should be used when declaring a new namespace that will have internal functions/globals and LIBC_NAMESPACE should be used as a means of accessing functions/globals declared within LIBC_NAMESPACE_DECL.
1 parent 089ba11 commit 665efe8

File tree

4 files changed

+52
-6
lines changed

4 files changed

+52
-6
lines changed

libc/docs/dev/clang_tidy_checks.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ This check that ensures any function call resolves to a function within the
6464
void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {}
6565
}
6666
67+
..
68+
TODO(97655): The clang-tidy check should be updated to ensure the namespace
69+
declaration uses LIBC_NAMESPACE_DECL as opposed to LIBC_NAMESPACE. The former
70+
should be used for accessing globals in LIBC_NAMESPACE rather than declaration.
71+
6772

6873
callee-namespace
6974
----------------

libc/docs/dev/code_style.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,3 +260,34 @@ Patches containing any amount of Assembly ideally should be approved by 2
260260
maintainers. llvm-libc maintainers reserve the right to reject Assembly
261261
contributions that they feel could be better maintained if rewritten in C++,
262262
and to revisit this policy in the future.
263+
264+
LIBC_NAMESPACE_DECL
265+
===================
266+
267+
llvm-libc provides a macro `LIBC_NAMESPACE` which contains internal implementations of
268+
libc functions and globals. This macro should only be used as an
269+
identifier for accessing such symbols within the namespace (like `LIBC_NAMESPACE::cpp::max`).
270+
Any usage of this namespace for declaring or defining internal symbols should
271+
instead use `LIBC_NAMESPACE_DECL` which declares `LIBC_NAMESPACE` with hidden visibility.
272+
273+
Example usage:
274+
275+
.. code-block:: c++
276+
277+
#include "src/__support/macros/config.h" // The macro is defined here.
278+
279+
namespace LIBC_NAMESPACE_DECL {
280+
281+
void new_function() {
282+
...
283+
}
284+
285+
} // LIBC_NAMESPACE_DECL
286+
287+
Having hidden visibility on the namespace ensures extern declarations in a given TU
288+
have known visibility and never generate GOT indirextions. The attribute guarantees
289+
this independently of global compile options and build systems.
290+
291+
..
292+
TODO(97655): We should have a clang-tidy check to enforce this and a
293+
fixit implementation.

libc/docs/dev/implementation_standard.rst

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,17 @@ example. The ``isalpha`` function will be declared in an internal header file
2626
#ifndef LLVM_LIBC_SRC_CTYPE_ISALPHA_H
2727
#define LLVM_LIBC_SRC_CTYPE_ISALPHA_H
2828

29-
namespace LIBC_NAMESPACE {
29+
namespace LIBC_NAMESPACE_DECL {
3030

3131
int isalpha(int c);
3232

33-
} // namespace LIBC_NAMESPACE
33+
} // namespace LIBC_NAMESPACE_DECL
3434

3535
#endif LLVM_LIBC_SRC_CTYPE_ISALPHA_H
3636

3737
Notice that the ``isalpha`` function declaration is nested inside the namespace
38-
``LIBC_NAMESPACE``. All implementation constructs in LLVM-libc are declared
39-
within the namespace ``LIBC_NAMESPACE``.
38+
``LIBC_NAMESPACE_DECL``. All implementation constructs in LLVM-libc are declared
39+
within the namespace ``LIBC_NAMESPACE_DECL``.
4040

4141
``.cpp`` File Structure
4242
-----------------------
@@ -49,13 +49,13 @@ which must be defined with the ``LLVM_LIBC_FUNCTION`` macro. For example, the
4949

5050
// --- isalpha.cpp --- //
5151

52-
namespace LIBC_NAMESPACE {
52+
namespace LIBC_NAMESPACE_DECL {
5353

5454
LLVM_LIBC_FUNCTION(int, isalpha, (int c)) {
5555
// ... implementation goes here.
5656
}
5757

58-
} // namespace LIBC_NAMESPACE
58+
} // namespace LIBC_NAMESPACE_DECL
5959

6060
Notice the use of the macro ``LLVM_LIBC_FUNCTION``. This macro helps us define
6161
a C alias symbol for the C++ implementation. For example, for a library build,

libc/src/__support/macros/config.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,14 @@
2727
#define LIBC_HAS_FEATURE(f) 0
2828
#endif
2929

30+
// Declare a LIBC_NAMESPACE with hidden visibility. `namespace
31+
// LIBC_NAMESPACE_DECL {` should be used around all declarations and definitions
32+
// for libc internals as opposed to just `namespace LIBC_NAMESPACE {`. This
33+
// ensures that all declarations within this namespace have hidden
34+
// visibility, which optimizes codegen for uses of symbols defined in other
35+
// translation units in ways that can be necessary for correctness by avoiding
36+
// dynamic relocations. This does not affect the public C symbols which are
37+
// controlled independently via `LLVM_LIBC_FUNCTION_ATTR`.
38+
#define LIBC_NAMESPACE_DECL [[gnu::visibility("hidden")]] LIBC_NAMESPACE
39+
3040
#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_CONFIG_H

0 commit comments

Comments
 (0)