================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits