[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-09-01 Thread LLVM Continuous Integration via cfe-commits

llvm-ci wrote:

LLVM Buildbot has detected a new failure on builder `clang-ppc64le-rhel` 
running on `ppc64le-clang-rhel-test` while building `clang-tools-extra` at step 
5 "build-unified-tree".

Full details are available at: 
https://lab.llvm.org/buildbot/#/builders/145/builds/9503


Here is the relevant piece of the build log for the reference

```
Step 5 (build-unified-tree) failure: build (failure)
...
51.038 [1031/33/5575] Building CXX object 
tools/clang/tools/extra/clangd/refactor/tweaks/CMakeFiles/obj.clangDaemonTweaks.dir/DumpAST.cpp.o
51.071 [1031/32/5576] Building CXX object 
tools/clang/tools/extra/clangd/tool/CMakeFiles/obj.clangdMain.dir/Check.cpp.o
51.084 [1031/31/5577] Building CXX object 
tools/clang/tools/extra/clangd/refactor/tweaks/CMakeFiles/obj.clangDaemonTweaks.dir/ExpandMacro.cpp.o
51.085 [1031/30/5578] Building CXX object 
tools/clang/tools/extra/clang-query/CMakeFiles/obj.clangQuery.dir/Query.cpp.o
51.093 [1031/29/5579] Linking CXX shared library 
lib/libclangIncludeCleaner.so.22.0git
51.101 [1030/29/5580] Creating library symlink lib/libclangIncludeCleaner.so
51.120 [1030/28/5581] Building CXX object 
tools/clang/tools/extra/clangd/tool/CMakeFiles/obj.clangdMain.dir/ClangdMain.cpp.o
51.131 [1030/27/5582] Building CXX object 
tools/clang/tools/extra/clangd/refactor/tweaks/CMakeFiles/obj.clangDaemonTweaks.dir/DefineInline.cpp.o
51.292 [1030/26/5583] Building CXX object 
tools/clang/tools/extra/clangd/refactor/tweaks/CMakeFiles/obj.clangDaemonTweaks.dir/RemoveUsingNamespace.cpp.o
53.238 [1030/25/5584] Building CXX object 
tools/clang/tools/extra/clang-reorder-fields/CMakeFiles/obj.clangReorderFields.dir/Designator.cpp.o
FAILED: 
tools/clang/tools/extra/clang-reorder-fields/CMakeFiles/obj.clangReorderFields.dir/Designator.cpp.o
 
ccache /home/buildbots/llvm-external-buildbots/clang.19.1.7/bin/clang++ 
--gcc-toolchain=/gcc-toolchain/usr -DGTEST_HAS_RTTI=0 -D_DEBUG 
-D_GLIBCXX_ASSERTIONS -D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE 
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 
-I/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/tools/clang/tools/extra/clang-reorder-fields
 
-I/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/clang-tools-extra/clang-reorder-fields
 
-I/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/clang/include
 
-I/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/tools/clang/include
 
-I/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/build/include
 
-I/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/llvm/include
 -fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror 
-Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra 
-Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers 
-pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough 
-Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor 
-Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion 
-Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color 
-ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual 
-Wno-nested-anon-types -O3 -DNDEBUG -std=c++17  -fno-exceptions -funwind-tables 
-fno-rtti -UNDEBUG -MD -MT 
tools/clang/tools/extra/clang-reorder-fields/CMakeFiles/obj.clangReorderFields.dir/Designator.cpp.o
 -MF 
tools/clang/tools/extra/clang-reorder-fields/CMakeFiles/obj.clangReorderFields.dir/Designator.cpp.o.d
 -o 
tools/clang/tools/extra/clang-reorder-fields/CMakeFiles/obj.clangReorderFields.dir/Designator.cpp.o
 -c 
/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/clang-tools-extra/clang-reorder-fields/Designator.cpp
In file included from 
/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/clang-tools-extra/clang-reorder-fields/Designator.cpp:15:
/home/buildbots/llvm-external-buildbots/workers/ppc64le-clang-rhel-test/clang-ppc64le-rhel/llvm-project/clang-tools-extra/clang-reorder-fields/Designator.h:157:23:
 error: private field 'ILE' is not used [-Werror,-Wunused-private-field]
  157 |   const InitListExpr *ILE;
  |   ^
1 error generated.
53.523 [1030/24/5585] Building CXX object 
tools/clang/lib/Driver/CMakeFiles/obj.clangDriver.dir/ToolChains/HIPUtility.cpp.o
53.847 [1030/23/5586] Building RISCVGenInstrInfo.inc...
55.328 [1030/22/5587] Building AArch64GenSubtargetInfo.inc...
57.717 [1030/21/5588] Building AArch64GenInstrInfo.inc...
58.620 [1030/20/5589] Building RISCVGenDAGISel.inc...
61.264 [1030/19/5590] Building CXX object 
lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/AsmPrinter.cpp.o
61.634 [1030/18/5591] Building CXX object 
lib/LTO/

[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-09-01 Thread Vladimir Vuksanovic via cfe-commits

vvuksanovic wrote:

Thanks!

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-09-01 Thread via cfe-commits

github-actions[bot] wrote:



@vvuksanovic Congratulations on having your first Pull Request (PR) merged into 
the LLVM Project!

Your changes will be combined with recent changes from other authors, then 
tested by our [build bots](https://lab.llvm.org/buildbot/). If there is a 
problem with a build, you may receive a report in an email or a comment on this 
PR.

Please check whether problems have been caused by your change specifically, as 
the builds can include changes from many authors. It is not uncommon for your 
change to be included in a build that fails due to someone else's changes, or 
infrastructure issues.

How to do this, and the rest of the post-merge process, is covered in detail 
[here](https://llvm.org/docs/MyFirstTypoFix.html#myfirsttypofix-issues-after-landing-your-pr).

If your change does cause a problem, it may be reverted, or you can revert it 
yourself. This is a normal part of [LLVM 
development](https://llvm.org/docs/DeveloperPolicy.html#patch-reversion-policy).
 You can fix your changes and open a new PR to merge them again.

If you don't get any reports, no action is required from you. Your changes are 
working as expected, well done!


https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-09-01 Thread Nikita Popov via cfe-commits

nikic wrote:

Fixed by 
https://github.com/llvm/llvm-project/commit/c128b8c46f2a3b750c9abcba1e303f92d6531e5f.

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-09-01 Thread Nikita Popov via cfe-commits

nikic wrote:

```
Building CXX object 
tools/clang/tools/extra/clang-reorder-fields/CMakeFiles/obj.clangReorderFields.dir/Designator.cpp.o

FAILED: 
tools/clang/tools/extra/clang-reorder-fields/CMakeFiles/obj.clangReorderFields.dir/Designator.cpp.o
sccache /opt/llvm/bin/clang++ -DGTEST_HAS_RTTI=0 -D_DEBUG -D_GLIBCXX_ASSERTIONS 
-D_GLIBCXX_USE_CXX11_ABI=1 -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS 
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/tools/extra/clang-reorder-fields
 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang-tools-extra/clang-reorder-fields
 -I/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/clang/include
 -I/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include 
-I/home/gha/actions-runner/_work/llvm-project/llvm-project/llvm/include -gmlt 
-fPIC -fno-semantic-interposition -fvisibility-inlines-hidden -Werror 
-Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra 
-Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers 
-pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough 
-Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor 
-Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion 
-Wmisleading-indentation -Wctad-maybe-unsupported -fdiagnostics-color 
-ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual 
-Wno-nested-anon-types -O3 -DNDEBUG -std=c++17  -fno-exceptions -funwind-tables 
-fno-rtti -UNDEBUG -MD -MT 
tools/clang/tools/extra/clang-reorder-fields/CMakeFiles/obj.clangReorderFields.dir/Designator.cpp.o
 -MF 
tools/clang/tools/extra/clang-reorder-fields/CMakeFiles/obj.clangReorderFields.dir/Designator.cpp.o.d
 -o 
tools/clang/tools/extra/clang-reorder-fields/CMakeFiles/obj.clangReorderFields.dir/Designator.cpp.o
 -c 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang-tools-extra/clang-reorder-fields/Designator.cpp
In file included from 
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang-tools-extra/clang-reorder-fields/Designator.cpp:15:
/home/gha/actions-runner/_work/llvm-project/llvm-project/clang-tools-extra/clang-reorder-fields/Designator.h:157:23:
 error: private field 'ILE' is not used [-Werror,-Wunused-private-field]
157 |   const InitListExpr *ILE;
|   ^
1 error generated.
```

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-09-01 Thread Alexander Shaposhnikov via cfe-commits

https://github.com/alexander-shaposhnikov closed 
https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-09-01 Thread Vladimir Vuksanovic via cfe-commits

vvuksanovic wrote:

Thank you for your patience. Can you please merge?

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-29 Thread Alexander Shaposhnikov via cfe-commits

alexander-shaposhnikov wrote:

lgtm

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-29 Thread Vladimir Vuksanovic via cfe-commits




vvuksanovic wrote:

Added `InitializerListExcessElements.c` and `IdiomaticZeroInitializer.c` tests. 
I can't find test cases for non constant-sized arrays in structs. I would 
change those checks for asserts, but there might be some way to trigger that, 
that I didn't think of.

Also modified the message to include the location of the problematic 
initializer list.

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-27 Thread Alexander Shaposhnikov via cfe-commits

https://github.com/alexander-shaposhnikov approved this pull request.

LGTM (modulo comments)

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-22 Thread Alexander Shaposhnikov via cfe-commits


@@ -0,0 +1,213 @@
+//===-- tools/extra/clang-reorder-fields/utils/Designator.cpp ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+/// \file
+/// This file contains the definition of the DesignatorIter and Designators
+/// utility classes.
+///
+//===--===//
+
+#include "Designator.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+
+namespace clang {
+namespace reorder_fields {
+
+DesignatorIter &DesignatorIter::operator++() {
+  assert(!isFinished() && "Iterator is already finished");
+  switch (Tag) {
+  case STRUCT:
+if (StructIt.Record->isUnion()) {
+  // Union always finishes on first increment.
+  StructIt.Field = StructIt.Record->field_end();
+  Type = QualType();
+  break;
+}
+++StructIt.Field;
+if (StructIt.Field != StructIt.Record->field_end()) {
+  Type = StructIt.Field->getType();
+} else {
+  Type = QualType();
+}
+break;
+  case ARRAY:
+++ArrayIt.Index;
+break;
+  case ARRAY_RANGE:
+ArrayIt.Index = ArrayRangeIt.End + 1;
+ArrayIt.Size = ArrayRangeIt.Size;
+Tag = ARRAY;
+break;
+  }
+  return *this;
+}
+
+bool DesignatorIter::isFinished() {
+  switch (Tag) {
+  case STRUCT:
+return StructIt.Field == StructIt.Record->field_end();
+  case ARRAY:
+return ArrayIt.Index == ArrayIt.Size;
+  case ARRAY_RANGE:
+return ArrayRangeIt.End == ArrayRangeIt.Size;
+  }
+  return false;
+}
+
+Designators::Designators(const Expr *Init, const InitListExpr *ILE,
+ const ASTContext *Context)
+: ILE(ILE), Context(Context) {
+  if (ILE->getType()->isArrayType()) {
+const ConstantArrayType *CAT =
+Context->getAsConstantArrayType(ILE->getType());
+// Only constant size arrays are supported.
+if (!CAT) {
+  DesignatorList.clear();
+  return;
+}
+DesignatorList.push_back(
+{CAT->getElementType(), 0, CAT->getSize().getZExtValue()});
+  } else {
+const RecordDecl *DesignatorRD = ILE->getType()->getAsRecordDecl();
+DesignatorList.push_back({DesignatorRD->field_begin()->getType(),
+  DesignatorRD->field_begin(), DesignatorRD});
+  }
+
+  // If the designator list is empty at this point, then there must be excess
+  // elements in the initializer list. They are not currently supported.
+  if (DesignatorList.empty())
+return;
+
+  if (!enterImplicitInitLists(Init))
+DesignatorList.clear();
+}
+
+Designators::Designators(const DesignatedInitExpr *DIE, const InitListExpr 
*ILE,
+ const ASTContext *Context)
+: ILE(ILE), Context(Context) {
+  for (const auto &D : DIE->designators()) {
+if (D.isFieldDesignator()) {
+  RecordDecl *DesignatorRecord = D.getFieldDecl()->getParent();
+  for (auto FieldIt = DesignatorRecord->field_begin();
+   FieldIt != DesignatorRecord->field_end(); ++FieldIt) {
+if (*FieldIt == D.getFieldDecl()) {
+  DesignatorList.push_back(
+  {FieldIt->getType(), FieldIt, DesignatorRecord});
+  break;
+}
+  }
+} else {
+  const QualType CurrentType = DesignatorList.empty()
+   ? ILE->getType()
+   : DesignatorList.back().getType();
+  const ConstantArrayType *CAT =
+  Context->getAsConstantArrayType(CurrentType);
+  if (!CAT) {
+// Non-constant-sized arrays are not supported.
+DesignatorList.clear();
+return;
+  }
+  if (D.isArrayDesignator()) {
+DesignatorList.push_back({CAT->getElementType(),
+  DIE->getArrayIndex(D)
+  ->EvaluateKnownConstInt(*Context)
+  .getZExtValue(),
+  CAT->getSize().getZExtValue()});
+  } else if (D.isArrayRangeDesignator()) {
+DesignatorList.push_back({CAT->getElementType(),
+  DIE->getArrayRangeStart(D)
+  ->EvaluateKnownConstInt(*Context)
+  .getZExtValue(),
+  DIE->getArrayRangeEnd(D)
+  ->EvaluateKnownConstInt(*Context)
+  .getZExtValue(),
+  CAT->getSize().getZExtValue()});
+  } else {
+llvm_unreachable("Unexpected designator kind");
+  }
+}
+  }
+}
+
+bool Designators::advanceToNextField(const Expr *Init) {
+  // Remove all designators that refer to the last field of a struct or final
+

[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-22 Thread Alexander Shaposhnikov via cfe-commits




alexander-shaposhnikov wrote:

p.s. also would be good to add a test with unsupported cases (and check that 
the file is unchanged for now)

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-22 Thread Alexander Shaposhnikov via cfe-commits


@@ -0,0 +1,158 @@
+//===-- tools/extra/clang-reorder-fields/utils/Designator.h -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+/// \file
+/// This file contains the declarations of the DesignatorIter and Designators
+/// utility class.
+///
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REORDER_FIELDS_UTILS_DESIGNATOR_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REORDER_FIELDS_UTILS_DESIGNATOR_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
+
+namespace clang {
+namespace reorder_fields {
+
+class DesignatorIter {

alexander-shaposhnikov wrote:

1. Would be good to add a class-level comment.
2. I don't have a strong opinion, so up to you, but I'd consider renaming this 
class to `Designator`. 
Yes, it resembles an iterator, but not really suitable for use with any 
standard algorithms, so, perhaps,
we can rename operator++ to advanceToNextElement()


https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-22 Thread Alexander Shaposhnikov via cfe-commits




alexander-shaposhnikov wrote:

Do you mind adding a test with c++20 designated initializers ?

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-22 Thread Vladimir Vuksanovic via cfe-commits

vvuksanovic wrote:

Thank you for the suggestions, the code looks cleaner now. I don't see any new 
comments?

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-20 Thread Alexander Shaposhnikov via cfe-commits

alexander-shaposhnikov wrote:

I've added a couple of comments, but overall this looks reasonable to me, thank 
your for your patience

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-20 Thread Alexander Shaposhnikov via cfe-commits


@@ -289,35 +321,215 @@ static void reorderFieldsInConstructor(
  Replacements);
 }
 
+/// Replacement for broken InitListExpr::isExplicit function.
+/// FIXME: Remove when InitListExpr::isExplicit is fixed.
+static bool isImplicitILE(const InitListExpr *ILE, const ASTContext &Context) {
+  // The ILE is implicit if either:
+  // - The left brace loc of the ILE matches the start of first init expression
+  //   (for non designated decls)
+  // - The right brace loc of the ILE matches the end of first init expression
+  //   (for designated decls)
+  // The first init expression should be taken from the syntactic form, but
+  // since the ILE could be implicit, there might not be a syntactic form.
+  // For that reason we have to check against all init expressions.
+  for (const Expr *Init : ILE->inits()) {
+if (ILE->getLBraceLoc() == Init->getBeginLoc() ||
+ILE->getRBraceLoc() == Init->getEndLoc())
+  return true;
+  }
+  return false;
+}
+
+/// Compares compatible designators according to the new struct order.
+/// Returns a negative value if Lhs < Rhs, positive value if Lhs > Rhs and 0 if
+/// they are equal.
+static int cmpDesignators(const DesignatorIter &Lhs, const DesignatorIter &Rhs,
+  const ReorderedStruct &Struct) {
+  switch (Lhs.getTag()) {
+  case DesignatorIter::STRUCT:
+assert(Rhs.getTag() == DesignatorIter::STRUCT &&
+   "Incompatible designators");
+assert(Lhs.getStructDecl() == Rhs.getStructDecl() &&
+   "Incompatible structs");
+// Use the new layout for reordered struct.
+if (Struct.Definition == Lhs.getStructDecl()) {
+  return Struct.NewFieldsPositions[Lhs.getStructIter()->getFieldIndex()] -
+ Struct.NewFieldsPositions[Rhs.getStructIter()->getFieldIndex()];
+}
+return Lhs.getStructIter()->getFieldIndex() -
+   Rhs.getStructIter()->getFieldIndex();
+  case DesignatorIter::ARRAY:
+  case DesignatorIter::ARRAY_RANGE:
+// Array designators can be compared to array range designators.
+assert((Rhs.getTag() == DesignatorIter::ARRAY ||
+Rhs.getTag() == DesignatorIter::ARRAY_RANGE) &&
+   "Incompatible designators");
+size_t LhsIdx = Lhs.getTag() == DesignatorIter::ARRAY
+? Lhs.getArrayIndex()
+: Lhs.getArrayRangeStart();
+size_t RhsIdx = Rhs.getTag() == DesignatorIter::ARRAY
+? Rhs.getArrayIndex()
+: Rhs.getArrayRangeStart();
+return LhsIdx - RhsIdx;
+  }
+  llvm_unreachable("Invalid designator tag");
+}
+
+/// Compares compatible designator lists according to the new struct order.
+/// Returns a negative value if Lhs < Rhs, positive value if Lhs > Rhs and 0 if
+/// they are equal.
+static int cmpDesignatorLists(const Designators &Lhs, const Designators &Rhs,
+  const ReorderedStruct &Reorders) {
+  for (unsigned Idx = 0, Size = std::min(Lhs.size(), Rhs.size()); Idx < Size;
+   ++Idx) {
+int DesignatorComp = cmpDesignators(Lhs[Idx], Rhs[Idx], Reorders);
+// If the current designators are not equal, return the result
+if (DesignatorComp != 0)
+  return DesignatorComp;
+// Otherwise, continue to the next pair.
+  }
+  // If all common designators were equal, compare the sizes of the designator
+  // lists.
+  return Lhs.size() - Rhs.size();
+}
+
+/// Finds the semantic form of the first explicit ancestor of the given
+/// initializer list including itself.
+static const InitListExpr *getExplicitILE(const InitListExpr *ILE,
+  ASTContext &Context) {
+  if (!isImplicitILE(ILE, Context))
+return ILE;
+  const InitListExpr *TopLevelILE = ILE;
+  DynTypedNodeList Parents = Context.getParents(*TopLevelILE);
+  while (!Parents.empty() && Parents.begin()->get()) {
+TopLevelILE = Parents.begin()->get();
+Parents = Context.getParents(*TopLevelILE);
+if (!isImplicitILE(TopLevelILE, Context))
+  break;
+  }
+  if (!TopLevelILE->isSemanticForm()) {
+return TopLevelILE->getSemanticForm();
+  }
+  return TopLevelILE;
+}
+
 /// Reorders initializers in the brace initialization of an aggregate.
 ///
 /// At the moment partial initialization is not supported.
 /// \returns true on success
 static bool reorderFieldsInInitListExpr(
-const InitListExpr *InitListEx, ArrayRef NewFieldsOrder,
-const ASTContext &Context,
+const InitListExpr *InitListEx, const ReorderedStruct &RS,
+ASTContext &Context,
 std::map &Replacements) {
   assert(InitListEx && "Init list expression is null");
-  // We care only about InitListExprs which originate from source code.
-  // Implicit InitListExprs are created by the semantic analyzer.
-  if (!InitListEx->isExplicit())
+  // Only process semantic forms of initializer lists.
+  if (!InitListEx->isSemanticForm()) {
 return true;
-  // The method InitListExpr::getSyntacticForm 

[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-20 Thread Vladimir Vuksanovic via cfe-commits

https://github.com/vvuksanovic updated 
https://github.com/llvm/llvm-project/pull/142150

>From 69381c74c9c3adf97770cdd2e72f0bd8d862e33c Mon Sep 17 00:00:00 2001
From: Vladimir Vuksanovic 
Date: Tue, 22 Jul 2025 02:50:02 -0700
Subject: [PATCH 1/3] [clang-reorder-fields] Refactor the new order information

Move the new fields order information to a new struct.
---
 .../ReorderFieldsAction.cpp   | 82 +++
 1 file changed, 48 insertions(+), 34 deletions(-)

diff --git a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp 
b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
index ea0207619fb2b..e5bdf9ab5957e 100644
--- a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
+++ b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
@@ -81,6 +81,20 @@ getNewFieldsOrder(const RecordDecl *Definition,
   return NewFieldsOrder;
 }
 
+struct ReorderedStruct {
+public:
+  ReorderedStruct(const RecordDecl *Decl, ArrayRef NewFieldsOrder)
+  : Definition(Decl), NewFieldsOrder(NewFieldsOrder),
+NewFieldsPositions(NewFieldsOrder.size()) {
+for (unsigned I = 0; I < NewFieldsPositions.size(); ++I)
+  NewFieldsPositions[NewFieldsOrder[I]] = I;
+  }
+
+  const RecordDecl *Definition;
+  ArrayRef NewFieldsOrder;
+  SmallVector NewFieldsPositions;
+};
+
 // FIXME: error-handling
 /// Replaces one range of source code by another.
 static void
@@ -194,33 +208,33 @@ static SourceRange getFullFieldSourceRange(const 
FieldDecl &Field,
 /// different accesses (public/protected/private) is not supported.
 /// \returns true on success.
 static bool reorderFieldsInDefinition(
-const RecordDecl *Definition, ArrayRef NewFieldsOrder,
-const ASTContext &Context,
+const ReorderedStruct &RS, const ASTContext &Context,
 std::map &Replacements) {
-  assert(Definition && "Definition is null");
+  assert(RS.Definition && "Definition is null");
 
   SmallVector Fields;
-  for (const auto *Field : Definition->fields())
+  for (const auto *Field : RS.Definition->fields())
 Fields.push_back(Field);
 
   // Check that the permutation of the fields doesn't change the accesses
-  for (const auto *Field : Definition->fields()) {
+  for (const auto *Field : RS.Definition->fields()) {
 const auto FieldIndex = Field->getFieldIndex();
-if (Field->getAccess() != Fields[NewFieldsOrder[FieldIndex]]->getAccess()) 
{
+if (Field->getAccess() !=
+Fields[RS.NewFieldsOrder[FieldIndex]]->getAccess()) {
   llvm::errs() << "Currently reordering of fields with different accesses "
   "is not supported\n";
   return false;
 }
   }
 
-  for (const auto *Field : Definition->fields()) {
+  for (const auto *Field : RS.Definition->fields()) {
 const auto FieldIndex = Field->getFieldIndex();
-if (FieldIndex == NewFieldsOrder[FieldIndex])
+if (FieldIndex == RS.NewFieldsOrder[FieldIndex])
   continue;
-addReplacement(
-getFullFieldSourceRange(*Field, Context),
-getFullFieldSourceRange(*Fields[NewFieldsOrder[FieldIndex]], Context),
-Context, Replacements);
+addReplacement(getFullFieldSourceRange(*Field, Context),
+   getFullFieldSourceRange(
+   *Fields[RS.NewFieldsOrder[FieldIndex]], Context),
+   Context, Replacements);
   }
   return true;
 }
@@ -231,7 +245,7 @@ static bool reorderFieldsInDefinition(
 /// fields. Thus, we need to ensure that we reorder just the initializers that
 /// are present.
 static void reorderFieldsInConstructor(
-const CXXConstructorDecl *CtorDecl, ArrayRef NewFieldsOrder,
+const CXXConstructorDecl *CtorDecl, const ReorderedStruct &RS,
 ASTContext &Context,
 std::map &Replacements) {
   assert(CtorDecl && "Constructor declaration is null");
@@ -243,10 +257,6 @@ static void reorderFieldsInConstructor(
   // Thus this assert needs to be after the previous checks.
   assert(CtorDecl->isThisDeclarationADefinition() && "Not a definition");
 
-  SmallVector NewFieldsPositions(NewFieldsOrder.size());
-  for (unsigned i = 0, e = NewFieldsOrder.size(); i < e; ++i)
-NewFieldsPositions[NewFieldsOrder[i]] = i;
-
   SmallVector OldWrittenInitializersOrder;
   SmallVector NewWrittenInitializersOrder;
   for (const auto *Initializer : CtorDecl->inits()) {
@@ -257,8 +267,8 @@ static void reorderFieldsInConstructor(
 const FieldDecl *ThisM = Initializer->getMember();
 const auto UsedMembers = findMembersUsedInInitExpr(Initializer, Context);
 for (const FieldDecl *UM : UsedMembers) {
-  if (NewFieldsPositions[UM->getFieldIndex()] >
-  NewFieldsPositions[ThisM->getFieldIndex()]) {
+  if (RS.NewFieldsPositions[UM->getFieldIndex()] >
+  RS.NewFieldsPositions[ThisM->getFieldIndex()]) {
 DiagnosticsEngine &DiagEngine = Context.getDiagnostics();
 auto Description = ("reordering field " + UM->getName() + " after " +
 

[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-18 Thread Alexander Shaposhnikov via cfe-commits

https://github.com/alexander-shaposhnikov edited 
https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-08-17 Thread Vladimir Vuksanovic via cfe-commits

vvuksanovic wrote:

Ping

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-24 Thread Vladimir Vuksanovic via cfe-commits


@@ -81,18 +83,52 @@ getNewFieldsOrder(const RecordDecl *Definition,
   return NewFieldsOrder;
 }
 
+struct ReorderedStruct {

vvuksanovic wrote:

Okay, I separated the commits.

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-24 Thread Vladimir Vuksanovic via cfe-commits

https://github.com/vvuksanovic updated 
https://github.com/llvm/llvm-project/pull/142150

>From 69381c74c9c3adf97770cdd2e72f0bd8d862e33c Mon Sep 17 00:00:00 2001
From: Vladimir Vuksanovic 
Date: Tue, 22 Jul 2025 02:50:02 -0700
Subject: [PATCH 1/2] [clang-reorder-fields] Refactor the new order information

Move the new fields order information to a new struct.
---
 .../ReorderFieldsAction.cpp   | 82 +++
 1 file changed, 48 insertions(+), 34 deletions(-)

diff --git a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp 
b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
index ea0207619fb2b..e5bdf9ab5957e 100644
--- a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
+++ b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
@@ -81,6 +81,20 @@ getNewFieldsOrder(const RecordDecl *Definition,
   return NewFieldsOrder;
 }
 
+struct ReorderedStruct {
+public:
+  ReorderedStruct(const RecordDecl *Decl, ArrayRef NewFieldsOrder)
+  : Definition(Decl), NewFieldsOrder(NewFieldsOrder),
+NewFieldsPositions(NewFieldsOrder.size()) {
+for (unsigned I = 0; I < NewFieldsPositions.size(); ++I)
+  NewFieldsPositions[NewFieldsOrder[I]] = I;
+  }
+
+  const RecordDecl *Definition;
+  ArrayRef NewFieldsOrder;
+  SmallVector NewFieldsPositions;
+};
+
 // FIXME: error-handling
 /// Replaces one range of source code by another.
 static void
@@ -194,33 +208,33 @@ static SourceRange getFullFieldSourceRange(const 
FieldDecl &Field,
 /// different accesses (public/protected/private) is not supported.
 /// \returns true on success.
 static bool reorderFieldsInDefinition(
-const RecordDecl *Definition, ArrayRef NewFieldsOrder,
-const ASTContext &Context,
+const ReorderedStruct &RS, const ASTContext &Context,
 std::map &Replacements) {
-  assert(Definition && "Definition is null");
+  assert(RS.Definition && "Definition is null");
 
   SmallVector Fields;
-  for (const auto *Field : Definition->fields())
+  for (const auto *Field : RS.Definition->fields())
 Fields.push_back(Field);
 
   // Check that the permutation of the fields doesn't change the accesses
-  for (const auto *Field : Definition->fields()) {
+  for (const auto *Field : RS.Definition->fields()) {
 const auto FieldIndex = Field->getFieldIndex();
-if (Field->getAccess() != Fields[NewFieldsOrder[FieldIndex]]->getAccess()) 
{
+if (Field->getAccess() !=
+Fields[RS.NewFieldsOrder[FieldIndex]]->getAccess()) {
   llvm::errs() << "Currently reordering of fields with different accesses "
   "is not supported\n";
   return false;
 }
   }
 
-  for (const auto *Field : Definition->fields()) {
+  for (const auto *Field : RS.Definition->fields()) {
 const auto FieldIndex = Field->getFieldIndex();
-if (FieldIndex == NewFieldsOrder[FieldIndex])
+if (FieldIndex == RS.NewFieldsOrder[FieldIndex])
   continue;
-addReplacement(
-getFullFieldSourceRange(*Field, Context),
-getFullFieldSourceRange(*Fields[NewFieldsOrder[FieldIndex]], Context),
-Context, Replacements);
+addReplacement(getFullFieldSourceRange(*Field, Context),
+   getFullFieldSourceRange(
+   *Fields[RS.NewFieldsOrder[FieldIndex]], Context),
+   Context, Replacements);
   }
   return true;
 }
@@ -231,7 +245,7 @@ static bool reorderFieldsInDefinition(
 /// fields. Thus, we need to ensure that we reorder just the initializers that
 /// are present.
 static void reorderFieldsInConstructor(
-const CXXConstructorDecl *CtorDecl, ArrayRef NewFieldsOrder,
+const CXXConstructorDecl *CtorDecl, const ReorderedStruct &RS,
 ASTContext &Context,
 std::map &Replacements) {
   assert(CtorDecl && "Constructor declaration is null");
@@ -243,10 +257,6 @@ static void reorderFieldsInConstructor(
   // Thus this assert needs to be after the previous checks.
   assert(CtorDecl->isThisDeclarationADefinition() && "Not a definition");
 
-  SmallVector NewFieldsPositions(NewFieldsOrder.size());
-  for (unsigned i = 0, e = NewFieldsOrder.size(); i < e; ++i)
-NewFieldsPositions[NewFieldsOrder[i]] = i;
-
   SmallVector OldWrittenInitializersOrder;
   SmallVector NewWrittenInitializersOrder;
   for (const auto *Initializer : CtorDecl->inits()) {
@@ -257,8 +267,8 @@ static void reorderFieldsInConstructor(
 const FieldDecl *ThisM = Initializer->getMember();
 const auto UsedMembers = findMembersUsedInInitExpr(Initializer, Context);
 for (const FieldDecl *UM : UsedMembers) {
-  if (NewFieldsPositions[UM->getFieldIndex()] >
-  NewFieldsPositions[ThisM->getFieldIndex()]) {
+  if (RS.NewFieldsPositions[UM->getFieldIndex()] >
+  RS.NewFieldsPositions[ThisM->getFieldIndex()]) {
 DiagnosticsEngine &DiagEngine = Context.getDiagnostics();
 auto Description = ("reordering field " + UM->getName() + " after " +
 

[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-21 Thread Clement Courbet via cfe-commits


@@ -81,18 +83,52 @@ getNewFieldsOrder(const RecordDecl *Definition,
   return NewFieldsOrder;
 }
 
+struct ReorderedStruct {

legrosbuffle wrote:

> Should I move addReplacement changes there?

Your choice, the idea is mostly to separate the logical and the refactoring 
changes to make review easier, we can squash before merge.

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-21 Thread Alexander Shaposhnikov via cfe-commits

alexander-shaposhnikov wrote:

apologize for the delay, I'll get back to this PR within a couple of days

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-17 Thread Vladimir Vuksanovic via cfe-commits

vvuksanovic wrote:

ping @legrosbuffle 

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-01 Thread Vladimir Vuksanovic via cfe-commits


@@ -81,18 +83,52 @@ getNewFieldsOrder(const RecordDecl *Definition,
   return NewFieldsOrder;
 }
 
+struct ReorderedStruct {

vvuksanovic wrote:

Can you clarify what should I pull to a separate commit? I can create a new 
commit for the `ReorderedStruct` changes, before the designator changes. Should 
I move `addReplacement` changes there? The new overload would be unused in that 
commit.

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-01 Thread Vladimir Vuksanovic via cfe-commits


@@ -0,0 +1,256 @@
+//===-- tools/extra/clang-reorder-fields/utils/Designator.cpp ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+/// \file
+/// This file contains the definition of the DesignatorIter and Designators
+/// utility classes.
+///
+//===--===//
+
+#include "Designator.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+
+namespace clang {
+namespace reorder_fields {
+
+DesignatorIter::DesignatorIter(const QualType Type,

vvuksanovic wrote:

Done.

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-01 Thread Vladimir Vuksanovic via cfe-commits


@@ -0,0 +1,256 @@
+//===-- tools/extra/clang-reorder-fields/utils/Designator.cpp ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+/// \file
+/// This file contains the definition of the DesignatorIter and Designators
+/// utility classes.
+///
+//===--===//
+
+#include "Designator.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+
+namespace clang {
+namespace reorder_fields {
+
+DesignatorIter::DesignatorIter(const QualType Type,
+   RecordDecl::field_iterator Field,
+   const RecordDecl *RD)
+: Tag(STRUCT), Type(Type), StructIt({Field, RD}) {}
+
+DesignatorIter::DesignatorIter(const QualType Type, uint64_t Idx, uint64_t 
Size)
+: Tag(ARRAY), Type(Type), ArrayIt({Idx, Size}) {}
+
+DesignatorIter::DesignatorIter(const QualType Type, uint64_t Start,
+   uint64_t End, uint64_t Size)
+: Tag(ARRAY_RANGE), Type(Type), ArrayRangeIt({Start, End, Size}) {}
+
+DesignatorIter &DesignatorIter::operator++() {
+  assert(!isFinished() && "Iterator is already finished");
+  switch (Tag) {
+  case STRUCT:
+if (StructIt.Record->isUnion()) {
+  // Union always finishes on first increment.
+  StructIt.Field = StructIt.Record->field_end();
+  Type = QualType();
+  break;
+}
+++StructIt.Field;
+if (StructIt.Field != StructIt.Record->field_end()) {
+  Type = StructIt.Field->getType();
+} else {
+  Type = QualType();
+}
+break;
+  case ARRAY:
+++ArrayIt.Index;
+break;
+  case ARRAY_RANGE:
+ArrayIt.Index = ArrayRangeIt.End + 1;
+ArrayIt.Size = ArrayRangeIt.Size;
+Tag = ARRAY;
+break;
+  }
+  return *this;
+}
+
+bool DesignatorIter::isFinished() {
+  switch (Tag) {
+  case STRUCT:
+return StructIt.Field == StructIt.Record->field_end();
+  case ARRAY:
+return ArrayIt.Index == ArrayIt.Size;
+  case ARRAY_RANGE:
+return ArrayRangeIt.End == ArrayRangeIt.Size;
+  }
+  return false;
+}
+
+DesignatorIter::Kind DesignatorIter::getTag() const { return Tag; }
+
+QualType DesignatorIter::getType() const { return Type; }
+
+RecordDecl::field_iterator &DesignatorIter::getStructIter() {

vvuksanovic wrote:

Done.

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-01 Thread Vladimir Vuksanovic via cfe-commits


@@ -289,35 +321,213 @@ static void reorderFieldsInConstructor(
  Replacements);
 }
 
+/// Replacement for broken InitListExpr::isExplicit function.
+/// TODO: Remove when InitListExpr::isExplicit is fixed.

vvuksanovic wrote:

Replaced. I can't find an open issue, but there is a comment at that function: 
`FIXME: This is wrong; InitListExprs created by semantic analysis have valid 
source locations too!`

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-01 Thread Vladimir Vuksanovic via cfe-commits


@@ -289,35 +321,213 @@ static void reorderFieldsInConstructor(
  Replacements);
 }
 
+/// Replacement for broken InitListExpr::isExplicit function.
+/// TODO: Remove when InitListExpr::isExplicit is fixed.
+static bool isImplicitILE(const InitListExpr *ILE, const ASTContext &Context) {
+  // The ILE is implicit if either:
+  // - The left brace loc of the ILE matches the start of first init expression
+  //   (for non designated decls)
+  // - The right brace loc of the ILE matches the end of first init expression
+  //   (for designated decls)
+  // The first init expression should be taken from the syntactic form, but
+  // since the ILE could be implicit, there might not be a syntactic form.
+  // For that reason we have to check against all init expressions.
+  for (const Expr *Init : ILE->inits()) {
+if (ILE->getLBraceLoc() == Init->getBeginLoc() ||
+ILE->getRBraceLoc() == Init->getEndLoc())
+  return true;
+  }
+  return false;
+}
+
+/// Compares compatible designators according to the new struct order.
+/// Returns a negative value if Lhs < Rhs, positive value if Lhs > Rhs and 0 if
+/// they are equal.
+static int cmpDesignators(const DesignatorIter &Lhs, const DesignatorIter &Rhs,
+  const ReorderedStruct &Struct) {
+  if (Lhs.getTag() == DesignatorIter::STRUCT) {

vvuksanovic wrote:

Done.

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-01 Thread Vladimir Vuksanovic via cfe-commits




vvuksanovic wrote:

Moved to parent directory.

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-01 Thread Vladimir Vuksanovic via cfe-commits

https://github.com/vvuksanovic updated 
https://github.com/llvm/llvm-project/pull/142150

>From df2e394f94397bf5d371586703a70b8e9bec1aaa Mon Sep 17 00:00:00 2001
From: Vladimir Vuksanovic 
Date: Fri, 30 May 2025 05:37:06 -0700
Subject: [PATCH 1/3] [clang-reorder-fields] Support designated initializers

Initializer lists with designators, missing elements or omitted braces can now 
be rewritten. Any missing designators are added and they get sorted according 
to the new order.

```
struct Foo {
  int a;
  int b;
  int c;
};
struct Foo foo = { .a = 1, 2, 3 }
```

when reordering elements to "b,a,c" becomes:

```
struct Foo {
  int b;
  int a;
  int c;
};
struct Foo foo = { .b = 2, .a = 1, .c = 3 }
```
---
 .../clang-reorder-fields/CMakeLists.txt   |   1 +
 .../ReorderFieldsAction.cpp   | 309 +++---
 .../clang-reorder-fields/utils/Designator.cpp | 256 +++
 .../clang-reorder-fields/utils/Designator.h   | 118 +++
 .../DesignatedInitializerList.c   |  31 ++
 5 files changed, 667 insertions(+), 48 deletions(-)
 create mode 100644 clang-tools-extra/clang-reorder-fields/utils/Designator.cpp
 create mode 100644 clang-tools-extra/clang-reorder-fields/utils/Designator.h
 create mode 100644 
clang-tools-extra/test/clang-reorder-fields/DesignatedInitializerList.c

diff --git a/clang-tools-extra/clang-reorder-fields/CMakeLists.txt 
b/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
index 2fdeb65d89767..dfb28234fd548 100644
--- a/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
+++ b/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
 )
 
 add_clang_library(clangReorderFields STATIC
+  utils/Designator.cpp
   ReorderFieldsAction.cpp
 
   DEPENDS
diff --git a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp 
b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
index ea0207619fb2b..b243723b21a32 100644
--- a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
+++ b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
@@ -13,6 +13,7 @@
 
//===--===//
 
 #include "ReorderFieldsAction.h"
+#include "utils/Designator.h"
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
@@ -23,6 +24,7 @@
 #include "clang/Tooling/Refactoring.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/Support/ErrorHandling.h"
 #include 
 
 namespace clang {
@@ -81,7 +83,44 @@ getNewFieldsOrder(const RecordDecl *Definition,
   return NewFieldsOrder;
 }
 
+struct ReorderedStruct {
+public:
+  ReorderedStruct(const RecordDecl *Decl, ArrayRef NewFieldsOrder)
+  : Definition(Decl), NewFieldsOrder(NewFieldsOrder),
+NewFieldsPositions(NewFieldsOrder.size()) {
+for (unsigned I = 0; I < NewFieldsPositions.size(); ++I)
+  NewFieldsPositions[NewFieldsOrder[I]] = I;
+  }
+
+  const RecordDecl *Definition;
+  ArrayRef NewFieldsOrder;
+  SmallVector NewFieldsPositions;
+};
+
 // FIXME: error-handling
+/// Replaces a range of source code by the specified text.
+static void
+addReplacement(SourceRange Old, StringRef New, const ASTContext &Context,
+   std::map &Replacements) {
+  tooling::Replacement R(Context.getSourceManager(),
+ CharSourceRange::getTokenRange(Old), New,
+ Context.getLangOpts());
+  consumeError(Replacements[std::string(R.getFilePath())].add(R));
+}
+
+/// Replaces one range of source code by another and adds a prefix.
+static void
+addReplacement(SourceRange Old, SourceRange New, StringRef Prefix,
+   const ASTContext &Context,
+   std::map &Replacements) {
+  std::string NewText =
+  (Prefix + Lexer::getSourceText(CharSourceRange::getTokenRange(New),
+ Context.getSourceManager(),
+ Context.getLangOpts()))
+  .str();
+  addReplacement(Old, NewText, Context, Replacements);
+}
+
 /// Replaces one range of source code by another.
 static void
 addReplacement(SourceRange Old, SourceRange New, const ASTContext &Context,
@@ -89,10 +128,7 @@ addReplacement(SourceRange Old, SourceRange New, const 
ASTContext &Context,
   StringRef NewText =
   Lexer::getSourceText(CharSourceRange::getTokenRange(New),
Context.getSourceManager(), Context.getLangOpts());
-  tooling::Replacement R(Context.getSourceManager(),
- CharSourceRange::getTokenRange(Old), NewText,
- Context.getLangOpts());
-  consumeError(Replacements[std::string(R.getFilePath())].add(R));
+  addReplacement(Old, NewText.str(), Context, Replacements);
 }
 
 /// Find all member fields used in the given init-list initializer expr
@@ -194,33 +230,33 @@ static SourceRange getFullFieldSourceRange(const 
FieldDecl &Field,
 /// different accesse

[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-07-01 Thread Vladimir Vuksanovic via cfe-commits

https://github.com/vvuksanovic updated 
https://github.com/llvm/llvm-project/pull/142150

>From df2e394f94397bf5d371586703a70b8e9bec1aaa Mon Sep 17 00:00:00 2001
From: Vladimir Vuksanovic 
Date: Fri, 30 May 2025 05:37:06 -0700
Subject: [PATCH 1/2] [clang-reorder-fields] Support designated initializers

Initializer lists with designators, missing elements or omitted braces can now 
be rewritten. Any missing designators are added and they get sorted according 
to the new order.

```
struct Foo {
  int a;
  int b;
  int c;
};
struct Foo foo = { .a = 1, 2, 3 }
```

when reordering elements to "b,a,c" becomes:

```
struct Foo {
  int b;
  int a;
  int c;
};
struct Foo foo = { .b = 2, .a = 1, .c = 3 }
```
---
 .../clang-reorder-fields/CMakeLists.txt   |   1 +
 .../ReorderFieldsAction.cpp   | 309 +++---
 .../clang-reorder-fields/utils/Designator.cpp | 256 +++
 .../clang-reorder-fields/utils/Designator.h   | 118 +++
 .../DesignatedInitializerList.c   |  31 ++
 5 files changed, 667 insertions(+), 48 deletions(-)
 create mode 100644 clang-tools-extra/clang-reorder-fields/utils/Designator.cpp
 create mode 100644 clang-tools-extra/clang-reorder-fields/utils/Designator.h
 create mode 100644 
clang-tools-extra/test/clang-reorder-fields/DesignatedInitializerList.c

diff --git a/clang-tools-extra/clang-reorder-fields/CMakeLists.txt 
b/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
index 2fdeb65d89767..dfb28234fd548 100644
--- a/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
+++ b/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
 )
 
 add_clang_library(clangReorderFields STATIC
+  utils/Designator.cpp
   ReorderFieldsAction.cpp
 
   DEPENDS
diff --git a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp 
b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
index ea0207619fb2b..b243723b21a32 100644
--- a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
+++ b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
@@ -13,6 +13,7 @@
 
//===--===//
 
 #include "ReorderFieldsAction.h"
+#include "utils/Designator.h"
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
@@ -23,6 +24,7 @@
 #include "clang/Tooling/Refactoring.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/Support/ErrorHandling.h"
 #include 
 
 namespace clang {
@@ -81,7 +83,44 @@ getNewFieldsOrder(const RecordDecl *Definition,
   return NewFieldsOrder;
 }
 
+struct ReorderedStruct {
+public:
+  ReorderedStruct(const RecordDecl *Decl, ArrayRef NewFieldsOrder)
+  : Definition(Decl), NewFieldsOrder(NewFieldsOrder),
+NewFieldsPositions(NewFieldsOrder.size()) {
+for (unsigned I = 0; I < NewFieldsPositions.size(); ++I)
+  NewFieldsPositions[NewFieldsOrder[I]] = I;
+  }
+
+  const RecordDecl *Definition;
+  ArrayRef NewFieldsOrder;
+  SmallVector NewFieldsPositions;
+};
+
 // FIXME: error-handling
+/// Replaces a range of source code by the specified text.
+static void
+addReplacement(SourceRange Old, StringRef New, const ASTContext &Context,
+   std::map &Replacements) {
+  tooling::Replacement R(Context.getSourceManager(),
+ CharSourceRange::getTokenRange(Old), New,
+ Context.getLangOpts());
+  consumeError(Replacements[std::string(R.getFilePath())].add(R));
+}
+
+/// Replaces one range of source code by another and adds a prefix.
+static void
+addReplacement(SourceRange Old, SourceRange New, StringRef Prefix,
+   const ASTContext &Context,
+   std::map &Replacements) {
+  std::string NewText =
+  (Prefix + Lexer::getSourceText(CharSourceRange::getTokenRange(New),
+ Context.getSourceManager(),
+ Context.getLangOpts()))
+  .str();
+  addReplacement(Old, NewText, Context, Replacements);
+}
+
 /// Replaces one range of source code by another.
 static void
 addReplacement(SourceRange Old, SourceRange New, const ASTContext &Context,
@@ -89,10 +128,7 @@ addReplacement(SourceRange Old, SourceRange New, const 
ASTContext &Context,
   StringRef NewText =
   Lexer::getSourceText(CharSourceRange::getTokenRange(New),
Context.getSourceManager(), Context.getLangOpts());
-  tooling::Replacement R(Context.getSourceManager(),
- CharSourceRange::getTokenRange(Old), NewText,
- Context.getLangOpts());
-  consumeError(Replacements[std::string(R.getFilePath())].add(R));
+  addReplacement(Old, NewText.str(), Context, Replacements);
 }
 
 /// Find all member fields used in the given init-list initializer expr
@@ -194,33 +230,33 @@ static SourceRange getFullFieldSourceRange(const 
FieldDecl &Field,
 /// different accesse

[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-06-26 Thread Clement Courbet via cfe-commits


@@ -81,18 +83,52 @@ getNewFieldsOrder(const RecordDecl *Definition,
   return NewFieldsOrder;
 }
 
+struct ReorderedStruct {

legrosbuffle wrote:

If you can pull out this refactoring (`ReorderedStruct` + `addRepacement`) to a 
separate commit that'd be great.

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-06-26 Thread Clement Courbet via cfe-commits


@@ -0,0 +1,256 @@
+//===-- tools/extra/clang-reorder-fields/utils/Designator.cpp ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+/// \file
+/// This file contains the definition of the DesignatorIter and Designators
+/// utility classes.
+///
+//===--===//
+
+#include "Designator.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+
+namespace clang {
+namespace reorder_fields {
+
+DesignatorIter::DesignatorIter(const QualType Type,

legrosbuffle wrote:

[nit] Inline those three constructors ?

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-06-26 Thread Clement Courbet via cfe-commits


@@ -289,35 +321,213 @@ static void reorderFieldsInConstructor(
  Replacements);
 }
 
+/// Replacement for broken InitListExpr::isExplicit function.
+/// TODO: Remove when InitListExpr::isExplicit is fixed.

legrosbuffle wrote:

s/TODO/FIXME/

If there and open bug for this ?

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-06-26 Thread Clement Courbet via cfe-commits


@@ -0,0 +1,256 @@
+//===-- tools/extra/clang-reorder-fields/utils/Designator.cpp ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+///
+/// \file
+/// This file contains the definition of the DesignatorIter and Designators
+/// utility classes.
+///
+//===--===//
+
+#include "Designator.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+
+namespace clang {
+namespace reorder_fields {
+
+DesignatorIter::DesignatorIter(const QualType Type,
+   RecordDecl::field_iterator Field,
+   const RecordDecl *RD)
+: Tag(STRUCT), Type(Type), StructIt({Field, RD}) {}
+
+DesignatorIter::DesignatorIter(const QualType Type, uint64_t Idx, uint64_t 
Size)
+: Tag(ARRAY), Type(Type), ArrayIt({Idx, Size}) {}
+
+DesignatorIter::DesignatorIter(const QualType Type, uint64_t Start,
+   uint64_t End, uint64_t Size)
+: Tag(ARRAY_RANGE), Type(Type), ArrayRangeIt({Start, End, Size}) {}
+
+DesignatorIter &DesignatorIter::operator++() {
+  assert(!isFinished() && "Iterator is already finished");
+  switch (Tag) {
+  case STRUCT:
+if (StructIt.Record->isUnion()) {
+  // Union always finishes on first increment.
+  StructIt.Field = StructIt.Record->field_end();
+  Type = QualType();
+  break;
+}
+++StructIt.Field;
+if (StructIt.Field != StructIt.Record->field_end()) {
+  Type = StructIt.Field->getType();
+} else {
+  Type = QualType();
+}
+break;
+  case ARRAY:
+++ArrayIt.Index;
+break;
+  case ARRAY_RANGE:
+ArrayIt.Index = ArrayRangeIt.End + 1;
+ArrayIt.Size = ArrayRangeIt.Size;
+Tag = ARRAY;
+break;
+  }
+  return *this;
+}
+
+bool DesignatorIter::isFinished() {
+  switch (Tag) {
+  case STRUCT:
+return StructIt.Field == StructIt.Record->field_end();
+  case ARRAY:
+return ArrayIt.Index == ArrayIt.Size;
+  case ARRAY_RANGE:
+return ArrayRangeIt.End == ArrayRangeIt.Size;
+  }
+  return false;
+}
+
+DesignatorIter::Kind DesignatorIter::getTag() const { return Tag; }
+
+QualType DesignatorIter::getType() const { return Type; }
+
+RecordDecl::field_iterator &DesignatorIter::getStructIter() {

legrosbuffle wrote:

Inline all those ?

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-06-26 Thread Clement Courbet via cfe-commits




legrosbuffle wrote:

I would put this in the parent directory, the `utils/` subdir does not bring 
that much IMO.

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-06-26 Thread Clement Courbet via cfe-commits


@@ -289,35 +321,213 @@ static void reorderFieldsInConstructor(
  Replacements);
 }
 
+/// Replacement for broken InitListExpr::isExplicit function.
+/// TODO: Remove when InitListExpr::isExplicit is fixed.
+static bool isImplicitILE(const InitListExpr *ILE, const ASTContext &Context) {
+  // The ILE is implicit if either:
+  // - The left brace loc of the ILE matches the start of first init expression
+  //   (for non designated decls)
+  // - The right brace loc of the ILE matches the end of first init expression
+  //   (for designated decls)
+  // The first init expression should be taken from the syntactic form, but
+  // since the ILE could be implicit, there might not be a syntactic form.
+  // For that reason we have to check against all init expressions.
+  for (const Expr *Init : ILE->inits()) {
+if (ILE->getLBraceLoc() == Init->getBeginLoc() ||
+ILE->getRBraceLoc() == Init->getEndLoc())
+  return true;
+  }
+  return false;
+}
+
+/// Compares compatible designators according to the new struct order.
+/// Returns a negative value if Lhs < Rhs, positive value if Lhs > Rhs and 0 if
+/// they are equal.
+static int cmpDesignators(const DesignatorIter &Lhs, const DesignatorIter &Rhs,
+  const ReorderedStruct &Struct) {
+  if (Lhs.getTag() == DesignatorIter::STRUCT) {

legrosbuffle wrote:

a `switch` might make this a bit more readable

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-06-26 Thread Clement Courbet via cfe-commits

https://github.com/legrosbuffle commented:

Nice ! Conceptually this looks good, only stylistic comments.

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-06-26 Thread Clement Courbet via cfe-commits

https://github.com/legrosbuffle edited 
https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-06-24 Thread Vladimir Vuksanovic via cfe-commits

vvuksanovic wrote:

@alexander-shaposhnikov 

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-06-16 Thread Vladimir Vuksanovic via cfe-commits

https://github.com/vvuksanovic updated 
https://github.com/llvm/llvm-project/pull/142150

>From df2e394f94397bf5d371586703a70b8e9bec1aaa Mon Sep 17 00:00:00 2001
From: Vladimir Vuksanovic 
Date: Fri, 30 May 2025 05:37:06 -0700
Subject: [PATCH] [clang-reorder-fields] Support designated initializers

Initializer lists with designators, missing elements or omitted braces can now 
be rewritten. Any missing designators are added and they get sorted according 
to the new order.

```
struct Foo {
  int a;
  int b;
  int c;
};
struct Foo foo = { .a = 1, 2, 3 }
```

when reordering elements to "b,a,c" becomes:

```
struct Foo {
  int b;
  int a;
  int c;
};
struct Foo foo = { .b = 2, .a = 1, .c = 3 }
```
---
 .../clang-reorder-fields/CMakeLists.txt   |   1 +
 .../ReorderFieldsAction.cpp   | 309 +++---
 .../clang-reorder-fields/utils/Designator.cpp | 256 +++
 .../clang-reorder-fields/utils/Designator.h   | 118 +++
 .../DesignatedInitializerList.c   |  31 ++
 5 files changed, 667 insertions(+), 48 deletions(-)
 create mode 100644 clang-tools-extra/clang-reorder-fields/utils/Designator.cpp
 create mode 100644 clang-tools-extra/clang-reorder-fields/utils/Designator.h
 create mode 100644 
clang-tools-extra/test/clang-reorder-fields/DesignatedInitializerList.c

diff --git a/clang-tools-extra/clang-reorder-fields/CMakeLists.txt 
b/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
index 2fdeb65d89767..dfb28234fd548 100644
--- a/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
+++ b/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
 )
 
 add_clang_library(clangReorderFields STATIC
+  utils/Designator.cpp
   ReorderFieldsAction.cpp
 
   DEPENDS
diff --git a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp 
b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
index ea0207619fb2b..b243723b21a32 100644
--- a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
+++ b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
@@ -13,6 +13,7 @@
 
//===--===//
 
 #include "ReorderFieldsAction.h"
+#include "utils/Designator.h"
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
@@ -23,6 +24,7 @@
 #include "clang/Tooling/Refactoring.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/Support/ErrorHandling.h"
 #include 
 
 namespace clang {
@@ -81,7 +83,44 @@ getNewFieldsOrder(const RecordDecl *Definition,
   return NewFieldsOrder;
 }
 
+struct ReorderedStruct {
+public:
+  ReorderedStruct(const RecordDecl *Decl, ArrayRef NewFieldsOrder)
+  : Definition(Decl), NewFieldsOrder(NewFieldsOrder),
+NewFieldsPositions(NewFieldsOrder.size()) {
+for (unsigned I = 0; I < NewFieldsPositions.size(); ++I)
+  NewFieldsPositions[NewFieldsOrder[I]] = I;
+  }
+
+  const RecordDecl *Definition;
+  ArrayRef NewFieldsOrder;
+  SmallVector NewFieldsPositions;
+};
+
 // FIXME: error-handling
+/// Replaces a range of source code by the specified text.
+static void
+addReplacement(SourceRange Old, StringRef New, const ASTContext &Context,
+   std::map &Replacements) {
+  tooling::Replacement R(Context.getSourceManager(),
+ CharSourceRange::getTokenRange(Old), New,
+ Context.getLangOpts());
+  consumeError(Replacements[std::string(R.getFilePath())].add(R));
+}
+
+/// Replaces one range of source code by another and adds a prefix.
+static void
+addReplacement(SourceRange Old, SourceRange New, StringRef Prefix,
+   const ASTContext &Context,
+   std::map &Replacements) {
+  std::string NewText =
+  (Prefix + Lexer::getSourceText(CharSourceRange::getTokenRange(New),
+ Context.getSourceManager(),
+ Context.getLangOpts()))
+  .str();
+  addReplacement(Old, NewText, Context, Replacements);
+}
+
 /// Replaces one range of source code by another.
 static void
 addReplacement(SourceRange Old, SourceRange New, const ASTContext &Context,
@@ -89,10 +128,7 @@ addReplacement(SourceRange Old, SourceRange New, const 
ASTContext &Context,
   StringRef NewText =
   Lexer::getSourceText(CharSourceRange::getTokenRange(New),
Context.getSourceManager(), Context.getLangOpts());
-  tooling::Replacement R(Context.getSourceManager(),
- CharSourceRange::getTokenRange(Old), NewText,
- Context.getLangOpts());
-  consumeError(Replacements[std::string(R.getFilePath())].add(R));
+  addReplacement(Old, NewText.str(), Context, Replacements);
 }
 
 /// Find all member fields used in the given init-list initializer expr
@@ -194,33 +230,33 @@ static SourceRange getFullFieldSourceRange(const 
FieldDecl &Field,
 /// different accesses (p

[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-06-09 Thread Vladimir Vuksanovic via cfe-commits

vvuksanovic wrote:

@legrosbuffle 

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-05-30 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-tools-extra

Author: Vladimir Vuksanovic (vvuksanovic)


Changes

Initializer lists with designators, missing elements or omitted braces can now 
be rewritten. Any missing designators are added and they get sorted according 
to the new order.

```
struct Foo {
  int a;
  int b;
  int c;
};
struct Foo foo = { .a = 1, 2, 3 }
```

when reordering elements to "b,a,c" becomes:

```
struct Foo {
  int b;
  int a;
  int c;
};
struct Foo foo = { .b = 2, .a = 1, .c = 3 }
```

---

Patch is 34.11 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/142150.diff


5 Files Affected:

- (modified) clang-tools-extra/clang-reorder-fields/CMakeLists.txt (+1) 
- (modified) clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp 
(+253-48) 
- (added) clang-tools-extra/clang-reorder-fields/utils/Designator.cpp (+256) 
- (added) clang-tools-extra/clang-reorder-fields/utils/Designator.h (+118) 
- (added) 
clang-tools-extra/test/clang-reorder-fields/DesignatedInitializerList.c (+31) 


``diff
diff --git a/clang-tools-extra/clang-reorder-fields/CMakeLists.txt 
b/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
index 2fdeb65d89767..dfb28234fd548 100644
--- a/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
+++ b/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
 )
 
 add_clang_library(clangReorderFields STATIC
+  utils/Designator.cpp
   ReorderFieldsAction.cpp
 
   DEPENDS
diff --git a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp 
b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
index ea0207619fb2b..f5961a7dab0c9 100644
--- a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
+++ b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
@@ -13,6 +13,7 @@
 
//===--===//
 
 #include "ReorderFieldsAction.h"
+#include "utils/Designator.h"
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
@@ -23,6 +24,7 @@
 #include "clang/Tooling/Refactoring.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/Support/ErrorHandling.h"
 #include 
 
 namespace clang {
@@ -81,7 +83,44 @@ getNewFieldsOrder(const RecordDecl *Definition,
   return NewFieldsOrder;
 }
 
+struct ReorderedStruct {
+public:
+  ReorderedStruct(const RecordDecl *Decl, ArrayRef NewFieldsOrder)
+  : Definition(Decl), NewFieldsOrder(NewFieldsOrder),
+NewFieldsPositions(NewFieldsOrder.size()) {
+for (unsigned I = 0; I < NewFieldsPositions.size(); ++I)
+  NewFieldsPositions[NewFieldsOrder[I]] = I;
+  }
+
+  const RecordDecl *Definition;
+  ArrayRef NewFieldsOrder;
+  SmallVector NewFieldsPositions;
+};
+
 // FIXME: error-handling
+/// Replaces a range of source code by the specified text.
+static void
+addReplacement(SourceRange Old, StringRef New, const ASTContext &Context,
+   std::map &Replacements) {
+  tooling::Replacement R(Context.getSourceManager(),
+ CharSourceRange::getTokenRange(Old), New,
+ Context.getLangOpts());
+  consumeError(Replacements[std::string(R.getFilePath())].add(R));
+}
+
+/// Replaces one range of source code by another and adds a prefix.
+static void
+addReplacement(SourceRange Old, SourceRange New, StringRef Prefix,
+   const ASTContext &Context,
+   std::map &Replacements) {
+  std::string NewText =
+  (Prefix + Lexer::getSourceText(CharSourceRange::getTokenRange(New),
+ Context.getSourceManager(),
+ Context.getLangOpts()))
+  .str();
+  addReplacement(Old, NewText, Context, Replacements);
+}
+
 /// Replaces one range of source code by another.
 static void
 addReplacement(SourceRange Old, SourceRange New, const ASTContext &Context,
@@ -89,10 +128,7 @@ addReplacement(SourceRange Old, SourceRange New, const 
ASTContext &Context,
   StringRef NewText =
   Lexer::getSourceText(CharSourceRange::getTokenRange(New),
Context.getSourceManager(), Context.getLangOpts());
-  tooling::Replacement R(Context.getSourceManager(),
- CharSourceRange::getTokenRange(Old), NewText,
- Context.getLangOpts());
-  consumeError(Replacements[std::string(R.getFilePath())].add(R));
+  addReplacement(Old, NewText.str(), Context, Replacements);
 }
 
 /// Find all member fields used in the given init-list initializer expr
@@ -194,33 +230,33 @@ static SourceRange getFullFieldSourceRange(const 
FieldDecl &Field,
 /// different accesses (public/protected/private) is not supported.
 /// \returns true on success.
 static bool reorderFieldsInDefinition(
-const RecordDecl *Definition, ArrayRef NewFieldsOrder,
-const ASTContext &Context,
+const ReorderedStruct &RS, cons

[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-05-30 Thread via cfe-commits

github-actions[bot] wrote:



Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write 
permissions for the repository. In which case you can instead tag reviewers by 
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a 
review by "ping"ing the PR by adding a comment “Ping”. The common courtesy 
"ping" rate is once a week. Please remember that you are asking for valuable 
time from other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

https://github.com/llvm/llvm-project/pull/142150
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [clang-reorder-fields] Support designated initializers (PR #142150)

2025-05-30 Thread Vladimir Vuksanovic via cfe-commits

https://github.com/vvuksanovic created 
https://github.com/llvm/llvm-project/pull/142150

Initializer lists with designators, missing elements or omitted braces can now 
be rewritten. Any missing designators are added and they get sorted according 
to the new order.

```
struct Foo {
  int a;
  int b;
  int c;
};
struct Foo foo = { .a = 1, 2, 3 }
```

when reordering elements to "b,a,c" becomes:

```
struct Foo {
  int b;
  int a;
  int c;
};
struct Foo foo = { .b = 2, .a = 1, .c = 3 }
```

>From 67febc3e5b388d38025a87e7824f5a0e5d6adaaa Mon Sep 17 00:00:00 2001
From: Vladimir Vuksanovic 
Date: Fri, 30 May 2025 05:37:06 -0700
Subject: [PATCH] [clang-reorder-fields] Support designated initializers

Initializer lists with designators, missing elements or omitted braces can now 
be rewritten. Any missing designators are added and they get sorted according 
to the new order.

```
struct Foo {
  int a;
  int b;
  int c;
};
struct Foo foo = { .a = 1, 2, 3 }
```

when reordering elements to "b,a,c" becomes:

```
struct Foo {
  int b;
  int a;
  int c;
};
struct Foo foo = { .b = 2, .a = 1, .c = 3 }
```
---
 .../clang-reorder-fields/CMakeLists.txt   |   1 +
 .../ReorderFieldsAction.cpp   | 301 +++---
 .../clang-reorder-fields/utils/Designator.cpp | 256 +++
 .../clang-reorder-fields/utils/Designator.h   | 118 +++
 .../DesignatedInitializerList.c   |  31 ++
 5 files changed, 659 insertions(+), 48 deletions(-)
 create mode 100644 clang-tools-extra/clang-reorder-fields/utils/Designator.cpp
 create mode 100644 clang-tools-extra/clang-reorder-fields/utils/Designator.h
 create mode 100644 
clang-tools-extra/test/clang-reorder-fields/DesignatedInitializerList.c

diff --git a/clang-tools-extra/clang-reorder-fields/CMakeLists.txt 
b/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
index 2fdeb65d89767..dfb28234fd548 100644
--- a/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
+++ b/clang-tools-extra/clang-reorder-fields/CMakeLists.txt
@@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS
 )
 
 add_clang_library(clangReorderFields STATIC
+  utils/Designator.cpp
   ReorderFieldsAction.cpp
 
   DEPENDS
diff --git a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp 
b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
index ea0207619fb2b..f5961a7dab0c9 100644
--- a/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
+++ b/clang-tools-extra/clang-reorder-fields/ReorderFieldsAction.cpp
@@ -13,6 +13,7 @@
 
//===--===//
 
 #include "ReorderFieldsAction.h"
+#include "utils/Designator.h"
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
@@ -23,6 +24,7 @@
 #include "clang/Tooling/Refactoring.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/Support/ErrorHandling.h"
 #include 
 
 namespace clang {
@@ -81,7 +83,44 @@ getNewFieldsOrder(const RecordDecl *Definition,
   return NewFieldsOrder;
 }
 
+struct ReorderedStruct {
+public:
+  ReorderedStruct(const RecordDecl *Decl, ArrayRef NewFieldsOrder)
+  : Definition(Decl), NewFieldsOrder(NewFieldsOrder),
+NewFieldsPositions(NewFieldsOrder.size()) {
+for (unsigned I = 0; I < NewFieldsPositions.size(); ++I)
+  NewFieldsPositions[NewFieldsOrder[I]] = I;
+  }
+
+  const RecordDecl *Definition;
+  ArrayRef NewFieldsOrder;
+  SmallVector NewFieldsPositions;
+};
+
 // FIXME: error-handling
+/// Replaces a range of source code by the specified text.
+static void
+addReplacement(SourceRange Old, StringRef New, const ASTContext &Context,
+   std::map &Replacements) {
+  tooling::Replacement R(Context.getSourceManager(),
+ CharSourceRange::getTokenRange(Old), New,
+ Context.getLangOpts());
+  consumeError(Replacements[std::string(R.getFilePath())].add(R));
+}
+
+/// Replaces one range of source code by another and adds a prefix.
+static void
+addReplacement(SourceRange Old, SourceRange New, StringRef Prefix,
+   const ASTContext &Context,
+   std::map &Replacements) {
+  std::string NewText =
+  (Prefix + Lexer::getSourceText(CharSourceRange::getTokenRange(New),
+ Context.getSourceManager(),
+ Context.getLangOpts()))
+  .str();
+  addReplacement(Old, NewText, Context, Replacements);
+}
+
 /// Replaces one range of source code by another.
 static void
 addReplacement(SourceRange Old, SourceRange New, const ASTContext &Context,
@@ -89,10 +128,7 @@ addReplacement(SourceRange Old, SourceRange New, const 
ASTContext &Context,
   StringRef NewText =
   Lexer::getSourceText(CharSourceRange::getTokenRange(New),
Context.getSourceManager(), Context.getLangOpts());
-  tooling::Replacement R(Context.getSourceManager(),
- CharSourceRang