[clang-tools-extra] [clang-tools-extra][docs] Add documentation for clang-reorder-fields (PR #178446)

Konrad Kleine via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 28 10:09:40 PST 2026


https://github.com/kwk updated https://github.com/llvm/llvm-project/pull/178446

>From 6e9633e3a3f13406668e3090cfa04eef4bbe300d Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkleine at redhat.com>
Date: Wed, 28 Jan 2026 15:27:15 +0000
Subject: [PATCH 1/6] [clang-tools-extra][docs] Add documentation for
 clang-reorder-fields

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
---
 .../docs/clang-reorder-fields.rst             | 411 ++++++++++++++++++
 clang-tools-extra/docs/index.rst              |   1 +
 2 files changed, 412 insertions(+)
 create mode 100644 clang-tools-extra/docs/clang-reorder-fields.rst

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..43cb072b25392
--- /dev/null
+++ b/clang-tools-extra/docs/clang-reorder-fields.rst
@@ -0,0 +1,411 @@
+====================
+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 different 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 - different 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. 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/>

>From 6ee4e123823392868115c7ab4bc1b0e29e2b3ec8 Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkleine at redhat.com>
Date: Wed, 28 Jan 2026 15:42:56 +0000
Subject: [PATCH 2/6] [clang-tools-extra][docs] Add flexible array member error
 example and fix RST structure

- Added concrete example showing the error message when trying to reorder
  a flexible array member to a non-last position
- Fixed RST section hierarchy to use consistent heading markers:
  - Level 1 sections: `---` (dashes)
  - Level 2 subsections: `~~~` (tildes)
- This resolves Sphinx build warnings about inconsistent title levels
---
 .../docs/clang-reorder-fields.rst             | 38 ++++++++++++-------
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/clang-tools-extra/docs/clang-reorder-fields.rst b/clang-tools-extra/docs/clang-reorder-fields.rst
index 43cb072b25392..36f83e444d4bf 100644
--- a/clang-tools-extra/docs/clang-reorder-fields.rst
+++ b/clang-tools-extra/docs/clang-reorder-fields.rst
@@ -196,10 +196,10 @@ Use the `-i` flag to modify files in-place:
   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 different access specifiers
 (public/private/protected). All fields being reordered must have the same
@@ -215,7 +215,7 @@ access level.
   };
 
 Multiple field declarations
----------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Declarations with multiple fields in one statement are not supported:
 
@@ -226,7 +226,7 @@ Declarations with multiple fields in one statement are not supported:
   };
 
 Macro-expanded fields
----------------------
+~~~~~~~~~~~~~~~~~~~~~
 
 Macros that expand to multiple field declarations are not supported. However,
 macros that expand to a single field declaration work correctly:
@@ -251,7 +251,7 @@ 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:
 
@@ -266,7 +266,7 @@ Structs with preprocessor directives between fields cannot be reordered:
   };
 
 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
@@ -282,10 +282,22 @@ position:
   };
 
 Attempting to reorder fields such that the flexible array member is no longer
-last will result in an error. This ensures the generated code remains valid C.
+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:
@@ -328,7 +340,7 @@ 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>
 
@@ -370,10 +382,10 @@ You should review these warnings and adjust your code accordingly.
   compilation database support.
 
 Use Cases
-=========
+---------
 
 Memory layout optimization
---------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Reorder fields to minimize padding and improve cache locality:
 
@@ -400,12 +412,12 @@ Reorder fields to minimize padding and improve cache locality:
   };
 
 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.

>From 4fc0c80bb0f8553d4eab021833cd0bdd50fe5eae Mon Sep 17 00:00:00 2001
From: Konrad Kleine <konrad.kleine at posteo.de>
Date: Wed, 28 Jan 2026 19:09:04 +0100
Subject: [PATCH 3/6] Update clang-tools-extra/docs/clang-reorder-fields.rst

Co-authored-by: EugeneZelenko <eugene.zelenko at gmail.com>
---
 clang-tools-extra/docs/clang-reorder-fields.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/docs/clang-reorder-fields.rst b/clang-tools-extra/docs/clang-reorder-fields.rst
index 36f83e444d4bf..bf5a4286eee5e 100644
--- a/clang-tools-extra/docs/clang-reorder-fields.rst
+++ b/clang-tools-extra/docs/clang-reorder-fields.rst
@@ -297,7 +297,7 @@ Will produce:
 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:

>From d2d28a0119fac174309123c47f9beeebe327eeab Mon Sep 17 00:00:00 2001
From: Konrad Kleine <konrad.kleine at posteo.de>
Date: Wed, 28 Jan 2026 19:09:13 +0100
Subject: [PATCH 4/6] Update clang-tools-extra/docs/clang-reorder-fields.rst

Co-authored-by: EugeneZelenko <eugene.zelenko at gmail.com>
---
 clang-tools-extra/docs/clang-reorder-fields.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/docs/clang-reorder-fields.rst b/clang-tools-extra/docs/clang-reorder-fields.rst
index bf5a4286eee5e..eb92df9e1706c 100644
--- a/clang-tools-extra/docs/clang-reorder-fields.rst
+++ b/clang-tools-extra/docs/clang-reorder-fields.rst
@@ -22,7 +22,7 @@ Example usage
 -------------
 
 Basic struct reordering
-~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~
 
 Consider this simple struct in `example.c`:
 

>From 662e7d7b8054f286ed47123a2c0ff73ef2571fa8 Mon Sep 17 00:00:00 2001
From: Konrad Kleine <konrad.kleine at posteo.de>
Date: Wed, 28 Jan 2026 19:09:21 +0100
Subject: [PATCH 5/6] Update clang-tools-extra/docs/clang-reorder-fields.rst

Co-authored-by: EugeneZelenko <eugene.zelenko at gmail.com>
---
 clang-tools-extra/docs/clang-reorder-fields.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/docs/clang-reorder-fields.rst b/clang-tools-extra/docs/clang-reorder-fields.rst
index eb92df9e1706c..9efcdcd8fa010 100644
--- a/clang-tools-extra/docs/clang-reorder-fields.rst
+++ b/clang-tools-extra/docs/clang-reorder-fields.rst
@@ -94,7 +94,7 @@ use either the simple class name or prefix it with `::`:
   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:
 

>From 4a120fb924d88e5c5f0a860c3b7aedd2252c9bb5 Mon Sep 17 00:00:00 2001
From: Konrad Kleine <konrad.kleine at posteo.de>
Date: Wed, 28 Jan 2026 19:09:29 +0100
Subject: [PATCH 6/6] Update clang-tools-extra/docs/clang-reorder-fields.rst

Co-authored-by: EugeneZelenko <eugene.zelenko at gmail.com>
---
 clang-tools-extra/docs/clang-reorder-fields.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/docs/clang-reorder-fields.rst b/clang-tools-extra/docs/clang-reorder-fields.rst
index 9efcdcd8fa010..88a8660b73a23 100644
--- a/clang-tools-extra/docs/clang-reorder-fields.rst
+++ b/clang-tools-extra/docs/clang-reorder-fields.rst
@@ -202,7 +202,7 @@ Different access specifiers
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 The tool cannot reorder fields with different access specifiers
-(public/private/protected). All fields being reordered must have the same
+(``public/private/protected``). All fields being reordered must have the same
 access level.
 
 .. code-block:: c++



More information about the cfe-commits mailing list