[clang] [C23] Implement WG14 N3037 (PR #132939)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 25 08:08:57 PDT 2025
================
@@ -1905,54 +2073,84 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
// Compare the definitions of these two enums. If either or both are
// incomplete (i.e. forward declared), we assume that they are equivalent.
+ // In C23, the order of the enumerations does not matter, only the names and
+ // values do.
D1 = D1->getDefinition();
D2 = D2->getDefinition();
if (!D1 || !D2)
return true;
- EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
- EC2End = D2->enumerator_end();
- for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
- EC1End = D1->enumerator_end();
- EC1 != EC1End; ++EC1, ++EC2) {
+ if (Context.LangOpts.C23 &&
+ !CheckStructurallyEquivalentAttributes(Context, D1, D2))
+ return false;
+
+ llvm::SmallVector<const EnumConstantDecl *, 8> D1Enums, D2Enums;
+ auto CopyEnumerators =
+ [](auto &&Range, llvm::SmallVectorImpl<const EnumConstantDecl *> &Cont) {
+ for (const EnumConstantDecl *ECD : Range)
+ Cont.push_back(ECD);
+ };
+ CopyEnumerators(D1->enumerators(), D1Enums);
+ CopyEnumerators(D2->enumerators(), D2Enums);
+
+ // In C23 mode, the order of the enumerations does not matter, so sort them
+ // by name to get them both into a consistent ordering.
+ if (Context.LangOpts.C23) {
+ auto Sorter = [](const EnumConstantDecl *LHS, const EnumConstantDecl *RHS) {
+ return LHS->getName() < RHS->getName();
+ };
+ llvm::sort(D1Enums, Sorter);
+ llvm::sort(D2Enums, Sorter);
+ }
+
+ auto EC2 = D2Enums.begin(), EC2End = D2Enums.end();
+ for (auto EC1 = D1Enums.begin(), EC1End = D1Enums.end(); EC1 != EC1End;
+ ++EC1, ++EC2) {
if (EC2 == EC2End) {
----------------
Sirraide wrote:
Here too perhaps?
https://github.com/llvm/llvm-project/pull/132939
More information about the cfe-commits
mailing list