Author: Konrad Kleine Date: 2026-01-29T15:28:58+01:00 New Revision: dea1d29d73f761901bcc9f4a6e4e7217a08d0983
URL: https://github.com/llvm/llvm-project/commit/dea1d29d73f761901bcc9f4a6e4e7217a08d0983 DIFF: https://github.com/llvm/llvm-project/commit/dea1d29d73f761901bcc9f4a6e4e7217a08d0983.diff LOG: [clang-tools-extra][docs] Add documentation for clang-reorder-fields (#178446) Add comprehensive documentation for the clang-reorder-fields tool, addressing #35520. The tool has existed in the repository but was previously undocumented. The documentation includes: - Basic usage examples for C and C++ structs/classes - Constructor initializer list reordering - Designated initializer support (C++20) - Detailed limitations and caveats - Command line option reference - Common use cases (memory layout optimization, etc.) Fixes #35520 --------- Co-authored-by: EugeneZelenko <[email protected]> Added: clang-tools-extra/docs/clang-reorder-fields.rst Modified: clang-tools-extra/docs/index.rst Removed: ################################################################################ diff --git a/clang-tools-extra/docs/clang-reorder-fields.rst b/clang-tools-extra/docs/clang-reorder-fields.rst new file mode 100644 index 0000000000000..1e09328872170 --- /dev/null +++ b/clang-tools-extra/docs/clang-reorder-fields.rst @@ -0,0 +1,423 @@ +==================== +Clang-Reorder-Fields +==================== + +.. contents:: + +.. toctree:: + :maxdepth: 1 + +:program:`clang-reorder-fields` is a refactoring tool to reorder fields in +C/C++ structs and classes. This tool automatically updates: + +- Field declarations in the record definition +- Constructor initializer lists in C++ classes +- Aggregate initialization expressions (both C and C++) +- Designated initializer lists (C++20) + +This can be useful for optimizing memory layout, improving cache performance, +or conforming to coding standards that require specific field orderings. + +Example usage +------------- + +Basic struct reordering +~~~~~~~~~~~~~~~~~~~~~~~ + +Consider this simple struct in `example.c`: + +.. code-block:: c + + struct Foo { + const int *x; + int y; + double z; + int w; + }; + + int main() { + const int val = 42; + struct Foo foo = { &val, 0, 1.5, 17 }; + return 0; + } + +To reorder the fields to `z, w, y, x`, run: + +.. code-block:: console + + clang-reorder-fields -record-name Foo -fields-order z,w,y,x example.c -- + +This will reorder both the struct definition and the initialization: + +.. code-block:: c + + struct Foo { + double z; + int w; + int y; + const int *x; + }; + + int main() { + const int val = 42; + struct Foo foo = { 1.5, 17, 0, &val }; + return 0; + } + +Namespaced structs +~~~~~~~~~~~~~~~~~~ + +For C++ code with namespaces, use the fully-qualified name: + +.. code-block:: c++ + + namespace bar { + struct Foo { + const int *x; + int y; + double z; + int w; + }; + } + +.. code-block:: console + + clang-reorder-fields -record-name ::bar::Foo -fields-order z,w,y,x example.cpp -- + +For classes defined in the global namespace (without any namespace), you can +use either the simple class name or prefix it with `::`: + +.. code-block:: console + + clang-reorder-fields -record-name Foo -fields-order z,w,y,x example.cpp -- + # or + clang-reorder-fields -record-name ::Foo -fields-order z,w,y,x example.cpp -- + +C++ constructor initializer lists +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The tool also reorders constructor initializer lists. Given: + +.. code-block:: c++ + + class Foo { + public: + Foo(); + + private: + int x; + const char *s1; + const char *s2; + double z; + }; + + Foo::Foo(): + x(12), + s1("abc"), + s2("def"), + z(3.14) + {} + +Running: + +.. code-block:: console + + clang-reorder-fields -record-name Foo -fields-order s1,x,z,s2 example.cpp -- + +Will reorder both the field declarations and the constructor initializers: + +.. code-block:: c++ + + class Foo { + public: + Foo(); + + private: + const char *s1; + int x; + double z; + const char *s2; + }; + + Foo::Foo(): + s1("abc"), + x(12), + z(3.14), + s2("def") + {} + +Designated initializers +~~~~~~~~~~~~~~~~~~~~~~~ + +For C++20 code using designated initializers: + +.. code-block:: c++ + + struct Bar { + char a; + int b; + int c; + }; + + int main() { + Bar bar1 = { 'a', 0, 123 }; + Bar bar2 = { .a = 'a', .b = 0, .c = 123 }; + return 0; + } + +.. code-block:: console + + clang-reorder-fields --extra-arg="-std=c++20" -record-name Bar \ + -fields-order c,a,b example.cpp -- + +Will produce: + +.. code-block:: c++ + + struct Bar { + int c; + char a; + int b; + }; + + int main() { + Bar bar1 = { 123, 'a', 0 }; + Bar bar2 = { .c = 123, .a = 'a', .b = 0 }; + return 0; + } + +In-place editing +~~~~~~~~~~~~~~~~ + +Use the `-i` flag to modify files in-place: + +.. code-block:: console + + clang-reorder-fields -record-name Foo -fields-order z,w,y,x -i example.c -- + +Limitations and Caveats +----------------------- + +Different access specifiers +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The tool cannot reorder fields with diff erent access specifiers +(``public/private/protected``). All fields being reordered must have the same +access level. + +.. code-block:: c++ + + class Example { + private: + int x; + public: + int y; // Cannot reorder x and y - diff erent access levels + }; + +Multiple field declarations +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Declarations with multiple fields in one statement are not supported: + +.. code-block:: c + + struct Example { + int a, b; // Not supported - multiple fields in one declaration + }; + +Macro-expanded fields +~~~~~~~~~~~~~~~~~~~~~ + +Macros that expand to multiple field declarations are not supported. However, +macros that expand to a single field declaration work correctly: + +.. code-block:: c + + #define INT_FIELD(NAME) int NAME // Supported - expands to one field + #define TWO_FIELDS int a; int b; // Not supported - expands to two fields + + struct Supported { + INT_FIELD(x); // OK - this is a single field + int y; + INT_FIELD(z); // OK - this is a single field + }; + + struct NotSupported { + TWO_FIELDS // Not OK - expands to multiple fields + int c; + }; + +The tool can reorder fields declared via macros as long as each macro invocation +expands to exactly one field declaration. + +Preprocessor directives +~~~~~~~~~~~~~~~~~~~~~~~ + +Structs with preprocessor directives between fields cannot be reordered: + +.. code-block:: c + + struct Example { + int a; + #ifdef FEATURE + int b; + #endif + int c; // Not supported - preprocessor directives present + }; + +Flexible array members +~~~~~~~~~~~~~~~~~~~~~~ + +In C, a flexible array member is an incomplete array type that must be the last +member of a struct (as specified by C99 and later standards). This allows the +struct to have a variable-length array at the end. Since this is a language +requirement, the tool enforces that flexible array members remain in the last +position: + +.. code-block:: c + + struct Example { + int count; + int data[]; // Flexible array member - must remain last + }; + +Attempting to reorder fields such that the flexible array member is no longer +last will result in an error: + +.. code-block:: console + + clang-reorder-fields -record-name Example -fields-order data,count example.c -- + +Will produce: + +.. code-block:: text + + Flexible array member must remain the last field in the struct + +This ensures the generated code remains valid C. + +Field dependencies in initializers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The tool will issue a warning if reordering causes a field to be used in an +initializer before it's initialized. Consider this example: + +.. code-block:: c++ + + class Foo { + public: + Foo(int x, char c); + int x; + char c; + Dummy z; + }; + + Foo::Foo(int x, char c) : + x(x), + c(c), + z(this->x, c) // z's initializer uses x and c + {} + +If you reorder the fields to `z, c, x`: + +.. code-block:: console + + clang-reorder-fields -record-name Foo -fields-order z,c,x example.cpp -- + +The tool will produce warnings: + +.. code-block:: text + + example.cpp:10:3: warning: reordering field x after z makes x uninitialized when used in init expression + example.cpp:10:3: warning: reordering field c after z makes c uninitialized when used in init expression + +This warns you that in C++, member initializers are executed in the order that +fields are declared in the class, not the order they appear in the initializer +list. After reordering, `z` would be initialized first, but its initializer +tries to use `x` and `c` which haven't been initialized yet. + +The tool will still perform the reordering but warns about the potential issue. +You should review these warnings and adjust your code accordingly. + +:program:`clang-reorder-fields` Command Line Options +---------------------------------------------------- + +.. option:: --record-name=<string> + + The fully-qualified name of the struct or class to reorder. Required. + + For C structs, use the struct name directly (e.g., `Foo`). + + For C++ classes/structs in namespaces, use the fully-qualified name including + namespaces (e.g., `::namespace::ClassName`). + + For C++ classes/structs in the global namespace, you can use either the simple + name (e.g., `Foo`) or prefix with `::` (e.g., `::Foo`). + +.. option:: --fields-order=<string> + + Comma-separated list of field names in the desired order. Required. + + All field names must exactly match the fields in the struct/class definition. + The number of fields must match the number in the definition. + +.. option:: -i + + Overwrite edited files in-place. If not specified, the rewritten code is + printed to stdout. + +.. option:: --extra-arg=<string> + + Additional argument to append to the compiler command line. + + Useful for specifying language standards (e.g., `--extra-arg="-std=c++20"`). + +.. option:: --extra-arg-before=<string> + + Additional argument to prepend to the compiler command line. + +.. option:: -p <string> + + Build path. Specifies the directory containing `compile_commands.json` for + compilation database support. + +Use Cases +--------- + +Memory layout optimization +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Reorder fields to minimize padding and improve cache locality: + +.. code-block:: c + + // Before: 24 bytes (with padding) + struct Data { + char a; // 1 byte + 7 padding + double b; // 8 bytes + char c; // 1 byte + 7 padding + }; + +.. code-block:: console + + clang-reorder-fields -record-name Data -fields-order b,a,c data.c -- + +.. code-block:: c + + // After: 16 bytes (less padding) + struct Data { + double b; // 8 bytes + char a; // 1 byte + char c; // 1 byte + 6 padding + }; + +Coding standard compliance +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Ensure fields are ordered according to project conventions (e.g., alphabetically, +by type, or by access pattern). + +Field grouping +~~~~~~~~~~~~~~ + +Group related fields together for better code organization and readability. diff --git a/clang-tools-extra/docs/index.rst b/clang-tools-extra/docs/index.rst index eba4a2cdbc558..55b231c02db6f 100644 --- a/clang-tools-extra/docs/index.rst +++ b/clang-tools-extra/docs/index.rst @@ -18,6 +18,7 @@ Contents clang-tidy/index clang-include-fixer clang-change-namespace + clang-reorder-fields modularize pp-trace clangd <https://clangd.llvm.org/> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
