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

>From 70015607bb633e937327f512f79139c077202b8a Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Fri, 11 Jul 2025 18:39:16 +0000
Subject: [PATCH 01/13] [doc] Add documentation for clang-change-namespace

This adds rst documentation for the `clang-change-namespace` program.

I ran the examples locally to ensure they work.

See #35519
---
 .../docs/clang-change-namespace.rst           | 158 ++++++++++++++++++
 clang-tools-extra/docs/index.rst              |   1 +
 2 files changed, 159 insertions(+)
 create mode 100644 clang-tools-extra/docs/clang-change-namespace.rst

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
new file mode 100644
index 0000000000000..23c3dcc8b7412
--- /dev/null
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -0,0 +1,158 @@
+======================
+Clang-Change-Namespace
+======================
+
+.. contents::
+
+.. toctree::
+  :maxdepth: 1
+
+:program:`clang-change-namespace` can be used to change the surrounding
+namespaces of class/function definitions.
+
+Classes/functions in the moved namespace will have new namespaces while
+references to symbols (e.g. types, functions) which are not defined in the
+changed namespace will be correctly qualified by prepending namespace 
specifiers
+before them. This will try to add shortest namespace specifiers possible.
+
+When a symbol reference needs to be fully-qualified, this adds a `::` prefix to
+the namespace specifiers unless the new namespace is the global namespace. For
+classes, only classes that are declared/defined in the given namespace in
+specified files will be moved: forward declarations will remain in the old
+namespace. The will be demonstrated in the next example.
+
+Example usage
+-------------
+
+For example, consider this `test.cc` example here with the forward declared
+class `FWD` and the defined class `A`, both in the namespace `a`.
+
+.. code-block:: c++
+  :linenos:
+
+  namespace a {
+  class FWD;
+  class A {
+    FWD *fwd;
+  };
+  } // namespace a
+
+And now let's change the namespace `a` to `x`.
+
+.. code-block:: console
+  clang-change-namespace \
+    --old_namespace "a" \
+    --new_namespace "x" \
+    --file_pattern "test.cc" \
+    --i \
+    test.cc
+
+Note that in the code below there's still the forward decalred class `FWD` that
+stayed in the namespace `a`. It wasn't moved to the new namespace because it
+wasn't defined/declared here in `a` but only forward declared.
+
+.. code-block:: c++
+  :linenos:
+
+  namespace a {
+  class FWD;
+  } // namespace a
+  namespace x {
+
+  class A {
+    a::FWD *fwd;
+  };
+  } // namespace x
+
+
+Another example
+---------------
+
+Consider this `test.cc` file:
+
+.. code-block:: c++
+  :linenos:
+
+  namespace na {
+  class X {};
+  namespace nb {
+  class Y {
+    X x;
+  };
+  } // namespace nb
+  } // namespace na
+
+To move the definition of class `Y` from namespace `na::nb` to `x::y`, run:
+
+.. code-block:: console
+
+  clang-change-namespace \
+    --old_namespace "na::nb" \
+    --new_namespace "x::y" \
+    --file_pattern "test.cc" \
+    --i \
+    test.cc
+
+This will overwrite `test.cc` to look like this:
+
+.. code-block:: c++
+  :linenos:
+
+  namespace na {
+  class X {};
+
+  } // namespace na
+  namespace x {
+  namespace y {
+  class Y {
+    na::X x;
+  };
+  } // namespace y
+  } // namespace x
+
+Note, that we've successfully moved the class `Y` from namespace `na::nb` to
+namespace `x::y`.
+
+:program:`clang-change-namespace` Command Line Options
+======================================================
+
+.. option:: --allowed_file=<string>     
+
+  A file containing regexes of symbol names that are not expected to be updated
+  when changing namespaces around them.
+
+.. option:: --dump_result               
+
+  Dump new file contents in YAML, if specified.
+
+.. option:: --extra-arg=<string>        
+
+  Additional argument to append to the compiler command line
+
+.. option:: --extra-arg-before=<string> 
+
+  Additional argument to prepend to the compiler command line
+
+.. option:: --file_pattern=<string>     
+
+  Only rename namespaces in files that match the given pattern.
+
+.. option:: -i                          
+ 
+  Inplace edit <file>s, if specified.
+
+.. option:: --new_namespace=<string>    
+ 
+  New namespace.
+
+.. option:: --old_namespace=<string>    
+ 
+  Old namespace.
+
+.. option:: -p <string>                 
+ 
+  Build path
+
+.. option:: --style=<string>            
+ 
+  The style name used for reformatting.
diff --git a/clang-tools-extra/docs/index.rst b/clang-tools-extra/docs/index.rst
index 9f7324fcf7419..3f3a99d1b70c6 100644
--- a/clang-tools-extra/docs/index.rst
+++ b/clang-tools-extra/docs/index.rst
@@ -17,6 +17,7 @@ Contents
 
    clang-tidy/index
    clang-include-fixer
+   clang-change-namespace
    modularize
    pp-trace
    clangd <https://clangd.llvm.org/>

>From 0b75d62928fccf4ac36acafdc921b27fd714b557 Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Fri, 11 Jul 2025 21:34:07 +0000
Subject: [PATCH 02/13] Fixup

---
 clang-tools-extra/docs/clang-change-namespace.rst | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
index 23c3dcc8b7412..0e83165c48cfc 100644
--- a/clang-tools-extra/docs/clang-change-namespace.rst
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -28,7 +28,6 @@ For example, consider this `test.cc` example here with the 
forward declared
 class `FWD` and the defined class `A`, both in the namespace `a`.
 
 .. code-block:: c++
-  :linenos:
 
   namespace a {
   class FWD;
@@ -40,6 +39,7 @@ class `FWD` and the defined class `A`, both in the namespace 
`a`.
 And now let's change the namespace `a` to `x`.
 
 .. code-block:: console
+
   clang-change-namespace \
     --old_namespace "a" \
     --new_namespace "x" \
@@ -52,7 +52,6 @@ stayed in the namespace `a`. It wasn't moved to the new 
namespace because it
 wasn't defined/declared here in `a` but only forward declared.
 
 .. code-block:: c++
-  :linenos:
 
   namespace a {
   class FWD;
@@ -71,7 +70,6 @@ Another example
 Consider this `test.cc` file:
 
 .. code-block:: c++
-  :linenos:
 
   namespace na {
   class X {};
@@ -96,7 +94,6 @@ To move the definition of class `Y` from namespace `na::nb` 
to `x::y`, run:
 This will overwrite `test.cc` to look like this:
 
 .. code-block:: c++
-  :linenos:
 
   namespace na {
   class X {};

>From 9d052696527588696135fe4af0f6f3dc40c6b7a0 Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Mon, 18 Aug 2025 10:39:25 +0000
Subject: [PATCH 03/13] Add caveats section

Document the problem when content already exists in new namespace.
---
 .../docs/clang-change-namespace.rst           | 54 +++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
index 0e83165c48cfc..c6419cc8849ff 100644
--- a/clang-tools-extra/docs/clang-change-namespace.rst
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -110,6 +110,60 @@ This will overwrite `test.cc` to look like this:
 Note, that we've successfully moved the class `Y` from namespace `na::nb` to
 namespace `x::y`.
 
+Caveats
+=======
+
+Content already exists in new namespace
+---------------------------------------
+
+Consider this `test.cc` example that defines two `class A` one inside the
+namespace `a` and one in namespace `b`:
+
+.. code-block:: c++
+
+  namespace a {
+  class A {
+      int classAFromWithinNamespace_a;
+  };
+  } // namespace a
+
+  namespace b {
+  class A {
+      int classAFromWithinNamespace_b;
+  };
+  } //namespace b
+
+Let's move everything from the namespace `a` to the global namespace
+(`--new_namespace ""` means global namespace):
+
+.. code-block:: console
+
+  clang-change-namespace \
+    --old_namespace "a" \
+    --new_namespace "b" \
+    --file_pattern test.cc \
+    test.cc
+
+As expected we now have to definitions of `class A` inside the namespace `b`:
+
+.. code-block:: c++
+
+  namespace b {
+  class A {
+    int classAFromWithinNamespace_a;
+  };
+  } // namespace b
+
+  namespace b {
+  class A {
+      int classAFromWithinNamespace_b;
+  };
+  } //namespace b
+
+The re-factoring looks correct but the code will not compile due to the name
+duplication. It is not up to the tool to ensure compilability in that sense.
+But one has to be aware of that.
+
 :program:`clang-change-namespace` Command Line Options
 ======================================================
 

>From 02076a75e0e6bb708cd584c5bbf1b20e9270cb71 Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Mon, 18 Aug 2025 10:47:17 +0000
Subject: [PATCH 04/13] Document --file_pattern parameter to be regular
 expression

---
 clang-tools-extra/docs/clang-change-namespace.rst | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
index c6419cc8849ff..64be182383812 100644
--- a/clang-tools-extra/docs/clang-change-namespace.rst
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -184,11 +184,12 @@ But one has to be aware of that.
 
   Additional argument to prepend to the compiler command line
 
-.. option:: --file_pattern=<string>     
+.. option:: --file_pattern=<string>
 
-  Only rename namespaces in files that match the given pattern.
+  Only rename namespaces in files that match the given regular expression
+  pattern.
 
-.. option:: -i                          
+.. option:: -i     
  
   Inplace edit <file>s, if specified.
 

>From 2a45d7546002338d077f8ab2c72dfffea34f9106 Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Mon, 18 Aug 2025 10:49:20 +0000
Subject: [PATCH 05/13] Document --new_namespace global namespace

---
 clang-tools-extra/docs/clang-change-namespace.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
index 64be182383812..faf92e42b0ba2 100644
--- a/clang-tools-extra/docs/clang-change-namespace.rst
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -195,7 +195,7 @@ But one has to be aware of that.
 
 .. option:: --new_namespace=<string>    
  
-  New namespace.
+  New namespace. Use `""` when you target the global namespace.
 
 .. option:: --old_namespace=<string>    
  

>From e58947cb98e1192514e9f8297aa22970d7045fef Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Mon, 18 Aug 2025 10:49:33 +0000
Subject: [PATCH 06/13] Trim trailing whitespaces

---
 .../docs/clang-change-namespace.rst           | 28 +++++++++----------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
index faf92e42b0ba2..d2b7b5032d2f0 100644
--- a/clang-tools-extra/docs/clang-change-namespace.rst
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -167,20 +167,20 @@ But one has to be aware of that.
 :program:`clang-change-namespace` Command Line Options
 ======================================================
 
-.. option:: --allowed_file=<string>     
+.. option:: --allowed_file=<string>
 
   A file containing regexes of symbol names that are not expected to be updated
   when changing namespaces around them.
 
-.. option:: --dump_result               
+.. option:: --dump_result
 
   Dump new file contents in YAML, if specified.
 
-.. option:: --extra-arg=<string>        
+.. option:: --extra-arg=<string>
 
   Additional argument to append to the compiler command line
 
-.. option:: --extra-arg-before=<string> 
+.. option:: --extra-arg-before=<string>
 
   Additional argument to prepend to the compiler command line
 
@@ -189,22 +189,22 @@ But one has to be aware of that.
   Only rename namespaces in files that match the given regular expression
   pattern.
 
-.. option:: -i     
- 
+.. option:: -i
+
   Inplace edit <file>s, if specified.
 
-.. option:: --new_namespace=<string>    
- 
+.. option:: --new_namespace=<string>
+
   New namespace. Use `""` when you target the global namespace.
 
-.. option:: --old_namespace=<string>    
- 
+.. option:: --old_namespace=<string>
+
   Old namespace.
 
-.. option:: -p <string>                 
- 
+.. option:: -p <string>
+
   Build path
 
-.. option:: --style=<string>            
- 
+.. option:: --style=<string>
+
   The style name used for reformatting.

>From 9beeb698c5fb2edeb1e89430346750052e3bfb33 Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Mon, 18 Aug 2025 11:06:26 +0000
Subject: [PATCH 07/13] Add caveat sub-section on inlining namespaces

---
 .../docs/clang-change-namespace.rst           | 63 +++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
index d2b7b5032d2f0..1b6a845b987f9 100644
--- a/clang-tools-extra/docs/clang-change-namespace.rst
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -164,6 +164,69 @@ The re-factoring looks correct but the code will not 
compile due to the name
 duplication. It is not up to the tool to ensure compilability in that sense.
 But one has to be aware of that.
 
+Inline namespace doesn't work
+-----------------------------
+
+Consider this usage of two versions of implementations for a `greet` function:
+
+.. code-block:: c++
+  #include <cstdio>
+
+  namespace Greeter {
+  inline namespace Version1 {
+    const char* greet() { return "Hello from version 1!"; }
+  } // namespace Version1
+  namespace Version2 {
+    const char* greet() { return "Hello from version 2!"; }
+  } // namespace Version2
+  } // namespace Greeter
+
+  int main(int argc, char* argv[]) {
+    printf("%s\n", Greeter::greet());
+    return 0;
+  }
+
+Note, that currently `Greeter::greet()` will result in a call to
+`Greeter::Version1::greet()` because that's the inlined namespace.
+
+Let's say you want to move one and make `Version2` the default now and remove
+the `inline` from the `Version1`. First let's try to turn `namespace Version2`
+into `inline namespace Version2`:
+
+.. code-block:: console
+
+  clang-change-namespace \
+    --old_namespace "Greeter::Version2" \
+    --new_namespace "inline Version2" \
+    --file_pattern main.cc main.cc
+
+But this will put the `inline` keyword in the wrong place resulting in:
+
+.. code-block:: c++
+
+  #include <cstdio>
+
+  namespace Greeter {
+  inline namespace Version1 {
+          const char* greet() { return "Hello from version 1!"; }
+  } // namespace Version1
+
+  } // namespace Greeter
+  namespace inline Greeter {
+  namespace Version2 {
+  const char *greet() { return "Hello from version 2!"; }
+  } // namespace Version2
+  } // namespace inline Greeter
+
+  int main(int argc, char* argv[]) {
+          printf("%s\n", Greeter::greet());
+          return 0;
+  }
+
+Apparently one cannot use `:program:`clang-change-namespace` to inline a
+namespace.
+
+
 :program:`clang-change-namespace` Command Line Options
 ======================================================
 

>From ec825b46d673820a15d0c4001ddfd6b7bc6b8559 Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Mon, 18 Aug 2025 11:15:31 +0000
Subject: [PATCH 08/13] Add empty line after code block

---
 clang-tools-extra/docs/clang-change-namespace.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
index 1b6a845b987f9..41e104d09777b 100644
--- a/clang-tools-extra/docs/clang-change-namespace.rst
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -170,6 +170,7 @@ Inline namespace doesn't work
 Consider this usage of two versions of implementations for a `greet` function:
 
 .. code-block:: c++
+
   #include <cstdio>
 
   namespace Greeter {

>From f10f7d87fa93dbdb259f75fef6d78cb7803a2205 Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Mon, 18 Aug 2025 12:47:21 +0000
Subject: [PATCH 09/13] Add caveat: symbol references not updated

---
 .../docs/clang-change-namespace.rst           | 36 +++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
index 41e104d09777b..7e5c4fc331ffa 100644
--- a/clang-tools-extra/docs/clang-change-namespace.rst
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -227,6 +227,42 @@ But this will put the `inline` keyword in the wrong place 
resulting in:
 Apparently one cannot use `:program:`clang-change-namespace` to inline a
 namespace.
 
+Symbol references not updated
+-----------------------------
+
+Consider this `test.cc` file:
+
+.. code-block:: c++
+
+  namespace old {
+  struct foo {};
+  }  // namespace old
+
+  namespace b {
+  old::foo g_foo;
+  }  // namespace b
+
+Notice that namespace `b` defines a global variable of type `old::foo`. If we
+now change the name of the `old` namespace to `modern`, the reference will not
+be updated:
+
+.. code-block:: console
+
+  clang-change-namespace --old_namespace 'old' --new_namespace 'modern' 
--file_pattern test.cc test.cc
+
+.. code-block:: c++
+
+  namespace modern {
+  struct foo {};
+  } // namespace modern
+
+  namespace b {
+  old::foo g_foo;
+  }  // namespace b
+
+`g_foo` is still of the no longer existing type `old::foo` while instead it
+should use `modern::foo`.
+
 
 :program:`clang-change-namespace` Command Line Options
 ======================================================

>From 30bf1f851af7dea31985645e66c41f356589dfa7 Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Mon, 18 Aug 2025 15:50:13 +0000
Subject: [PATCH 10/13] Fixup documentation

---
 clang-tools-extra/docs/clang-change-namespace.rst | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
index 7e5c4fc331ffa..a968ff9509b5d 100644
--- a/clang-tools-extra/docs/clang-change-namespace.rst
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -133,8 +133,7 @@ namespace `a` and one in namespace `b`:
   };
   } //namespace b
 
-Let's move everything from the namespace `a` to the global namespace
-(`--new_namespace ""` means global namespace):
+Let's move everything from namespace `a` to namespace `b`:
 
 .. code-block:: console
 

>From 55e69ff428d5c32638f4742d44acc067099801cc Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Mon, 18 Aug 2025 15:52:21 +0000
Subject: [PATCH 11/13] Symbol reference info

---
 clang-tools-extra/docs/clang-change-namespace.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
index a968ff9509b5d..9eec85ff32c7f 100644
--- a/clang-tools-extra/docs/clang-change-namespace.rst
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -262,6 +262,8 @@ be updated:
 `g_foo` is still of the no longer existing type `old::foo` while instead it
 should use `modern::foo`.
 
+Only symbol references in the moved namespace are updated, not outside of it.
+
 
 :program:`clang-change-namespace` Command Line Options
 ======================================================

>From 64ad789b414b74efb47c0a73aa2f9955dd015504 Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Mon, 18 Aug 2025 15:53:12 +0000
Subject: [PATCH 12/13] Remove Apparently from documentation

---
 clang-tools-extra/docs/clang-change-namespace.rst | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
index 9eec85ff32c7f..54f55adc6533a 100644
--- a/clang-tools-extra/docs/clang-change-namespace.rst
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -223,8 +223,7 @@ But this will put the `inline` keyword in the wrong place 
resulting in:
           return 0;
   }
 
-Apparently one cannot use `:program:`clang-change-namespace` to inline a
-namespace.
+One cannot use `:program:`clang-change-namespace` to inline a namespace.
 
 Symbol references not updated
 -----------------------------

>From c653ba231982e175abc22f1f4d7e079c474b8e0b Mon Sep 17 00:00:00 2001
From: Konrad Kleine <kkle...@redhat.com>
Date: Mon, 18 Aug 2025 15:58:22 +0000
Subject: [PATCH 13/13] Consistently break up console command

---
 clang-tools-extra/docs/clang-change-namespace.rst | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/docs/clang-change-namespace.rst 
b/clang-tools-extra/docs/clang-change-namespace.rst
index 54f55adc6533a..1eab83f5069b6 100644
--- a/clang-tools-extra/docs/clang-change-namespace.rst
+++ b/clang-tools-extra/docs/clang-change-namespace.rst
@@ -246,7 +246,11 @@ be updated:
 
 .. code-block:: console
 
-  clang-change-namespace --old_namespace 'old' --new_namespace 'modern' 
--file_pattern test.cc test.cc
+  clang-change-namespace \
+    --old_namespace "old" \
+    --new_namespace "modern" \
+    --file_pattern test.cc \
+    test.cc
 
 .. code-block:: c++
 

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to