@@ -1474,11 +1474,11 @@ void ItaniumVTableBuilder::AddMethods(
1474
1474
llvm_unreachable (" Found a duplicate primary base!" );
1475
1475
}
1476
1476
1477
+ const CXXDestructorDecl *ImplicitVirtualDtor = nullptr ;
1478
+
1477
1479
typedef llvm::SmallVector<const CXXMethodDecl *, 8 > NewVirtualFunctionsTy;
1478
1480
NewVirtualFunctionsTy NewVirtualFunctions;
1479
1481
1480
- llvm::SmallVector<const CXXMethodDecl*, 4 > NewImplicitVirtualFunctions;
1481
-
1482
1482
// Now go through all virtual member functions and add them.
1483
1483
for (const auto *MD : RD->methods ()) {
1484
1484
if (!MD->isVirtual ())
@@ -1542,30 +1542,24 @@ void ItaniumVTableBuilder::AddMethods(
1542
1542
}
1543
1543
}
1544
1544
1545
- if (MD->isImplicit ())
1546
- NewImplicitVirtualFunctions.push_back (MD);
1547
- else
1548
- NewVirtualFunctions.push_back (MD);
1549
- }
1550
-
1551
- std::stable_sort (
1552
- NewImplicitVirtualFunctions.begin (), NewImplicitVirtualFunctions.end (),
1553
- [](const CXXMethodDecl *A, const CXXMethodDecl *B) {
1554
- if (A->isCopyAssignmentOperator () != B->isCopyAssignmentOperator ())
1555
- return A->isCopyAssignmentOperator ();
1556
- if (A->isMoveAssignmentOperator () != B->isMoveAssignmentOperator ())
1557
- return A->isMoveAssignmentOperator ();
1558
- if (isa<CXXDestructorDecl>(A) != isa<CXXDestructorDecl>(B))
1559
- return isa<CXXDestructorDecl>(A);
1560
- assert (A->getOverloadedOperator () == OO_EqualEqual &&
1561
- B->getOverloadedOperator () == OO_EqualEqual &&
1562
- " unexpected or duplicate implicit virtual function" );
1563
- // We rely on Sema to have declared the operator== members in the
1564
- // same order as the corresponding operator<=> members.
1565
- return false ;
1566
- });
1567
- NewVirtualFunctions.append (NewImplicitVirtualFunctions.begin (),
1568
- NewImplicitVirtualFunctions.end ());
1545
+ if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) {
1546
+ if (MD->isImplicit ()) {
1547
+ // Itanium C++ ABI 2.5.2:
1548
+ // If a class has an implicitly-defined virtual destructor,
1549
+ // its entries come after the declared virtual function pointers.
1550
+
1551
+ assert (!ImplicitVirtualDtor &&
1552
+ " Did already see an implicit virtual dtor!" );
1553
+ ImplicitVirtualDtor = DD;
1554
+ continue ;
1555
+ }
1556
+ }
1557
+
1558
+ NewVirtualFunctions.push_back (MD);
1559
+ }
1560
+
1561
+ if (ImplicitVirtualDtor)
1562
+ NewVirtualFunctions.push_back (ImplicitVirtualDtor);
1569
1563
1570
1564
for (const CXXMethodDecl *MD : NewVirtualFunctions) {
1571
1565
// Get the final overrider.
0 commit comments