diff --git a/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst b/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst index ec52b9f73a3f..a00e476e0643 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/llvmlibc/implementation-in-namespace.rst @@ -13,7 +13,7 @@ correct namespace. // - LIBC_NAMESPACE_DECL is a macro // - LIBC_NAMESPACE_DECL expansion starts with `[[gnu::visibility("hidden")]] __llvm_libc` namespace LIBC_NAMESPACE_DECL { - void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} + LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {} // Namespaces within LIBC_NAMESPACE_DECL namespace are allowed. namespace inner { int localVar = 0; @@ -23,15 +23,15 @@ correct namespace. } // Incorrect: implementation not in the LIBC_NAMESPACE_DECL namespace. - void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} + LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {} // Incorrect: outer most namespace is not the LIBC_NAMESPACE_DECL macro. namespace something_else { - void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} + LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {} } // Incorrect: outer most namespace expansion does not start with `[[gnu::visibility("hidden")]] __llvm_libc`. #define LIBC_NAMESPACE_DECL custom_namespace namespace LIBC_NAMESPACE_DECL { - void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} + LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {} } diff --git a/libc/docs/Helpers/Styles.rst b/libc/docs/Helpers/Styles.rst deleted file mode 100644 index fd6364176738..000000000000 --- a/libc/docs/Helpers/Styles.rst +++ /dev/null @@ -1,40 +0,0 @@ -.. --------------------------------------------------------------------------- - Shared substitution definitions for implementation-status badges. - This file is excluded from the toctree (via exclude_patterns in conf.py). - Include it in any RST page that needs status badges: - - .. include:: /Helpers/Styles.rst (adjust path as needed) - - Usage:: - - |Complete| — feature/function is fully implemented - |Partial| — partial implementation (some variants/platforms missing) - |InProgress| — implementation underway, not yet merged - |NotStarted| — no implementation exists yet - |GPUOnly| — implemented on GPU targets only - |LinuxOnly| — implemented on Linux targets only - --------------------------------------------------------------------------- - -.. |Complete| raw:: html - - Complete - -.. |Partial| raw:: html - - Partial - -.. |InProgress| raw:: html - - In Progress - -.. |NotStarted| raw:: html - - Not Started - -.. |GPUOnly| raw:: html - - GPU Only - -.. |LinuxOnly| raw:: html - - Linux Only diff --git a/libc/docs/check.rst b/libc/docs/check.rst deleted file mode 100644 index 750ab605308e..000000000000 --- a/libc/docs/check.rst +++ /dev/null @@ -1,6 +0,0 @@ -.. role:: raw-html(raw) - :format: html - -.. |check| replace:: :raw-html:`✅` - - diff --git a/libc/docs/conf.py b/libc/docs/conf.py index 51e93fa96ce5..4608a0282c24 100644 --- a/libc/docs/conf.py +++ b/libc/docs/conf.py @@ -69,7 +69,14 @@ today_fmt = "%Y-%m-%d" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ["_build", "Helpers"] +exclude_patterns = ["_build"] + +rst_prolog = """ +.. role:: raw-html(raw) + :format: html + +.. |check| replace:: :raw-html:`✅` +""" # The reST default role (used for this markup: `text`) to use for all documents. # default_role = None diff --git a/libc/docs/dev/clang_tidy_checks.rst b/libc/docs/dev/clang_tidy_checks.rst deleted file mode 100644 index cf660dcf4267..000000000000 --- a/libc/docs/dev/clang_tidy_checks.rst +++ /dev/null @@ -1,119 +0,0 @@ -.. _clang_tidy_checks: - -LLVM libc clang-tidy checks -=========================== - -Configuration -------------- - -LLVM libc uses layered ``.clang-tidy`` configuration files: - -- ``libc/.clang-tidy``: baseline checks for the ``libc`` subtree (currently - focuses on identifier naming conventions). -- ``libc/src/.clang-tidy``: adds LLVM-libc-specific checks (``llvmlibc-*``) for - implementation code under ``libc/src`` and also enables - ``readability-identifier-naming`` and ``llvm-header-guard``. Diagnostics from - ``llvmlibc-*`` checks are treated as errors. - -LLVM-libc checks ----------------- - -restrict-system-libc-headers ----------------------------- -Check name: ``llvmlibc-restrict-system-libc-headers``. - -One of libc-project’s design goals is to use kernel headers and compiler -provided headers to prevent code duplication on a per platform basis. This -presents a problem when writing implementations since system libc headers are -easy to include accidentally and we can't just use the ``-nostdinc`` flag. -Improperly included system headers can introduce runtime errors because the C -standard outlines function prototypes and behaviors but doesn’t define -underlying implementation details such as the layout of a struct. - -This check prevents accidental inclusion of system libc headers when writing a -libc implementation. - -.. code-block:: c++ - - #include // Not allowed because it is part of system libc. - #include // Allowed because it is provided by the compiler. - #include "internal/stdio.h" // Allowed because it is NOT part of system libc. - -implementation-in-namespace ---------------------------- -Check name: ``llvmlibc-implementation-in-namespace``. - -All LLVM-libc implementation constructs must be enclosed in the -``LIBC_NAMESPACE_DECL`` namespace. See :ref:`code_style` for the full technical -rationale and macro definitions. - -This check ensures that top-level declarations in a translation unit are -enclosed within the ``LIBC_NAMESPACE_DECL`` namespace. - -.. code-block:: c++ - - // Correct: implementation inside the correct namespace. - namespace LIBC_NAMESPACE_DECL { - void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} - // Namespaces within LIBC_NAMESPACE namespace are allowed. - namespace inner{ - int localVar = 0; - } - // Functions with C linkage are allowed. - extern "C" void str_fuzz(){} - } - - // Incorrect: implementation not in a namespace. - void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} - - // Incorrect: outer most namespace is not correct. - namespace something_else { - void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} - } - -callee-namespace ----------------- -Check name: ``llvmlibc-callee-namespace``. - -LLVM-libc is distinct because it is designed to maintain interoperability with -other libc libraries, including the one that lives on the system. This feature -creates some uncertainty about which library a call resolves to especially when -a public header with non-namespaced functions like ``string.h`` is included. - -This check ensures any function call resolves to a function within the -LIBC_NAMESPACE namespace. - -There are exceptions for the following functions: -``__errno_location`` so that ``errno`` can be set; -``malloc``, ``calloc``, ``realloc``, ``aligned_alloc``, and ``free`` since they -are always external and can be intercepted. - -.. code-block:: c++ - - namespace LIBC_NAMESPACE_DECL { - - // Allow calls with the fully qualified name. - LIBC_NAMESPACE::strlen("hello"); - - // Allow calls to compiler provided functions. - (void)__builtin_abs(-1); - - // Bare calls are allowed as long as they resolve to the correct namespace. - strlen("world"); - - // Disallow calling into functions in the global namespace. - ::strlen("!"); - - // Allow calling into specific global functions (explained above) - ::malloc(10); - - } // namespace LIBC_NAMESPACE_DECL - - -inline-function-decl --------------------- -Check name: ``llvmlibc-inline-function-decl``. - -LLVM libc uses the ``LIBC_INLINE`` macro to tag inline function declarations in -headers. This check enforces that any inline function declaration in a header -begins with ``LIBC_INLINE`` and provides a fix-it to insert the macro. diff --git a/libc/docs/dev/cmake_build_rules.rst b/libc/docs/dev/cmake_build_rules.rst deleted file mode 100644 index a47fbf0dc12a..000000000000 --- a/libc/docs/dev/cmake_build_rules.rst +++ /dev/null @@ -1,28 +0,0 @@ -.. _cmake_build_rules: - -=========================== -The libc CMake build system -=========================== - -At the cost of verbosity, we want to keep the build system of LLVM libc -as simple as possible. We also want to be highly modular with our build -targets. This makes picking and choosing desired pieces a straightforward -task. - -Targets for entrypoints ------------------------ - -Every entrypoint in LLVM-libc has its own build target, listed using the -``add_entrypoint_object`` rule. This rule generates a single object file -containing the implementation. - -For more technical details on how to register entrypoints, see the -:ref:`entrypoints` documentation. - -Targets for entrypoint libraries --------------------------------- - -Standards like POSIX require that a libc provide certain library files like -``libc.a``, ``libm.a``, etc. The targets for such library files are listed in -the ``lib`` directory as ``add_entrypoint_library`` targets. - diff --git a/libc/docs/dev/code_style.rst b/libc/docs/dev/code_style.rst index 7c53ad30a5d4..96397e4621f5 100644 --- a/libc/docs/dev/code_style.rst +++ b/libc/docs/dev/code_style.rst @@ -289,3 +289,123 @@ Example usage: Having hidden visibility on the namespace ensures extern declarations in a given TU have known visibility and never generate GOT indirections. The attribute guarantees this independently of global compile options and build systems. + +.. _clang_tidy_checks: + +Static Analysis & Clang-Tidy +============================= + +Configuration +------------- + +LLVM libc uses layered ``.clang-tidy`` configuration files: + +- ``libc/.clang-tidy``: baseline checks for the ``libc`` subtree (currently + focuses on identifier naming conventions). +- ``libc/src/.clang-tidy``: adds LLVM-libc-specific checks (``llvmlibc-*``) for + implementation code under ``libc/src`` and also enables + ``readability-identifier-naming`` and ``llvm-header-guard``. Diagnostics from + ``llvmlibc-*`` checks are treated as errors. + +LLVM-libc checks +---------------- + +restrict-system-libc-headers +---------------------------- +Check name: ``llvmlibc-restrict-system-libc-headers``. + +One of libc-project's design goals is to use kernel headers and compiler +provided headers to prevent code duplication on a per platform basis. This +presents a problem when writing implementations since system libc headers are +easy to include accidentally and we can't just use the ``-nostdinc`` flag. +Improperly included system headers can introduce runtime errors because the C +standard outlines function prototypes and behaviors but doesn't define +underlying implementation details such as the layout of a struct. + +This check prevents accidental inclusion of system libc headers when writing a +libc implementation. + +.. code-block:: c++ + + #include // Not allowed because it is part of system libc. + #include // Allowed because it is provided by the compiler. + #include "internal/stdio.h" // Allowed because it is NOT part of system libc. + +implementation-in-namespace +--------------------------- +Check name: ``llvmlibc-implementation-in-namespace``. + +All LLVM-libc implementation constructs must be enclosed in the +``LIBC_NAMESPACE_DECL`` namespace. See :ref:`code_style` for the full technical +rationale and macro definitions. + +This check ensures that top-level declarations in a translation unit are +enclosed within the ``LIBC_NAMESPACE_DECL`` namespace. + +.. code-block:: c++ + + // Correct: implementation inside the correct namespace. + namespace LIBC_NAMESPACE_DECL { + LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {} + // Namespaces within LIBC_NAMESPACE namespace are allowed. + namespace inner{ + int localVar = 0; + } + // Functions with C linkage are allowed. + extern "C" void str_fuzz(){} + } + + // Incorrect: implementation not in a namespace. + LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {} + + // Incorrect: outer most namespace is not correct. + namespace something_else { + LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {} + } + +callee-namespace +---------------- +Check name: ``llvmlibc-callee-namespace``. + +LLVM-libc is distinct because it is designed to maintain interoperability with +other libc libraries, including the one that lives on the system. This feature +creates some uncertainty about which library a call resolves to especially when +a public header with non-namespaced functions like ``string.h`` is included. + +This check ensures any function call resolves to a function within the +LIBC_NAMESPACE namespace. + +There are exceptions for the following functions: +``__errno_location`` so that ``errno`` can be set; +``malloc``, ``calloc``, ``realloc``, ``aligned_alloc``, and ``free`` since they +are always external and can be intercepted. + +.. code-block:: c++ + + namespace LIBC_NAMESPACE_DECL { + + // Disallow calls to the public versions with the LIBC_NAMESPACE. + LIBC_NAMESPACE::strlen("hello"); + + // Allow calls to compiler provided functions. + (void)__builtin_abs(-1); + + // Disallow bare calls. + strlen("world"); + + // Disallow calling into functions in the global namespace. + ::strlen("!"); + + // Allow calling into specific global functions (explained above). + ::malloc(10); + + } // namespace LIBC_NAMESPACE_DECL + + +inline-function-decl +-------------------- +Check name: ``llvmlibc-inline-function-decl``. + +LLVM libc uses the ``LIBC_INLINE`` macro to tag inline function declarations in +headers. This check enforces that any inline function declaration in a header +begins with ``LIBC_INLINE`` and provides a fix-it to insert the macro. diff --git a/libc/docs/dev/index.rst b/libc/docs/dev/index.rst index b61e46a59a43..e6463712e385 100644 --- a/libc/docs/dev/index.rst +++ b/libc/docs/dev/index.rst @@ -14,9 +14,7 @@ Navigate to the links below for information on the respective topics: source_tree_layout entrypoints implementing_a_function - cmake_build_rules config_options - clang_tidy_checks fuzzing header_generation implementation_standard diff --git a/libc/docs/gpu/support.rst b/libc/docs/gpu/support.rst index 11868227bb93..6bc36c2c5c49 100644 --- a/libc/docs/gpu/support.rst +++ b/libc/docs/gpu/support.rst @@ -4,8 +4,6 @@ Supported Functions =================== -.. include:: ../check.rst - The following functions and headers are supported at least partially on the device. Some functions are implemented fully on the GPU, while others require a `remote procedure call `_. diff --git a/libc/docs/headers/complex.rst b/libc/docs/headers/complex.rst index 7195f2695457..ba7d73eb499a 100644 --- a/libc/docs/headers/complex.rst +++ b/libc/docs/headers/complex.rst @@ -1,5 +1,3 @@ -.. include:: ../check.rst - ========= complex.h ========= diff --git a/libc/docs/headers/math/index.rst b/libc/docs/headers/math/index.rst index 14152ac62435..a2465e1de2cc 100644 --- a/libc/docs/headers/math/index.rst +++ b/libc/docs/headers/math/index.rst @@ -4,8 +4,6 @@ math.h ====== -.. include:: ../../check.rst - .. raw:: html diff --git a/libc/docs/headers/search.rst b/libc/docs/headers/search.rst index 82c3496eeb0e..63eb943d46cd 100644 --- a/libc/docs/headers/search.rst +++ b/libc/docs/headers/search.rst @@ -2,8 +2,6 @@ search.h ======== -.. include:: ../check.rst - --------------- Source Location --------------- diff --git a/libc/docs/headers/stdfix.rst b/libc/docs/headers/stdfix.rst index e75b9d8aac44..76ac7e7b71c9 100644 --- a/libc/docs/headers/stdfix.rst +++ b/libc/docs/headers/stdfix.rst @@ -2,8 +2,6 @@ stdfix.h ======== -.. include:: ../check.rst - Standards and Goals ------------------- diff --git a/libc/docs/headers/time.rst b/libc/docs/headers/time.rst index e29a3ce3ee1e..4b9c97683251 100644 --- a/libc/docs/headers/time.rst +++ b/libc/docs/headers/time.rst @@ -2,8 +2,6 @@ time.h ====== -.. include:: ../check.rst - --------------- Source location --------------- diff --git a/libc/docs/uefi/support.rst b/libc/docs/uefi/support.rst index 81067a73f3cc..976aab832843 100644 --- a/libc/docs/uefi/support.rst +++ b/libc/docs/uefi/support.rst @@ -4,8 +4,6 @@ Supported Functions =================== -.. include:: ../check.rst - The follow functions and headers are supported at least partially in UEFI. Some functions are implemented fully for UEFI. diff --git a/libc/utils/docgen/docgen.py b/libc/utils/docgen/docgen.py index 108d35ddce41..9ee87a97b263 100755 --- a/libc/utils/docgen/docgen.py +++ b/libc/utils/docgen/docgen.py @@ -183,11 +183,6 @@ def print_macros_rst(header: Header, macros: Dict): def print_impl_status_rst(header: Header, api: Dict): - if os.sep in header.name: - print(".. include:: ../../check.rst\n") - else: - print(".. include:: ../check.rst\n") - print("=" * len(header.name)) print(header.name) print("=" * len(header.name))