@@ -1476,6 +1476,14 @@ mlir::cir::FuncOp CIRGenModule::createCIRFunction(mlir::Location loc,
1476
1476
return f;
1477
1477
}
1478
1478
1479
+ bool isDefaultedMethod (const clang::FunctionDecl *FD) {
1480
+ if (FD->isDefaulted () && isa<CXXMethodDecl>(FD) &&
1481
+ (cast<CXXMethodDecl>(FD)->isCopyAssignmentOperator () ||
1482
+ cast<CXXMethodDecl>(FD)->isMoveAssignmentOperator ()))
1483
+ return true ;
1484
+ return false ;
1485
+ }
1486
+
1479
1487
// / If the specified mangled name is not in the module,
1480
1488
// / create and return a CIR Function with the specified type. If there is
1481
1489
// / something in the module with the specified name, return it potentially
@@ -1613,7 +1621,10 @@ mlir::cir::FuncOp CIRGenModule::GetOrCreateCIRFunction(
1613
1621
FD = FD->getPreviousDecl ()) {
1614
1622
if (isa<CXXRecordDecl>(FD->getLexicalDeclContext ())) {
1615
1623
if (FD->doesThisDeclarationHaveABody ()) {
1616
- addDeferredDeclToEmit (GD.getWithDecl (FD));
1624
+ if (isDefaultedMethod (FD))
1625
+ addDefaultMethodsToEmit (GD.getWithDecl (FD));
1626
+ else
1627
+ addDeferredDeclToEmit (GD.getWithDecl (FD));
1617
1628
break ;
1618
1629
}
1619
1630
}
@@ -1651,6 +1662,44 @@ mlir::Location CIRGenModule::getLoc(mlir::Location lhs, mlir::Location rhs) {
1651
1662
return mlir::FusedLoc::get (locs, metadata, builder.getContext ());
1652
1663
}
1653
1664
1665
+ void CIRGenModule::buildGlobalDecl (clang::GlobalDecl &D) {
1666
+ // We should call GetAddrOfGlobal with IsForDefinition set to true in order
1667
+ // to get a Value with exactly the type we need, not something that might
1668
+ // have been created for another decl with the same mangled name but
1669
+ // different type.
1670
+ auto *Op = GetAddrOfGlobal (D, ForDefinition);
1671
+
1672
+ // In case of different address spaces, we may still get a cast, even with
1673
+ // IsForDefinition equal to true. Query mangled names table to get
1674
+ // GlobalValue.
1675
+ if (!Op) {
1676
+ Op = getGlobalValue (getMangledName (D));
1677
+ }
1678
+
1679
+ // Make sure getGlobalValue returned non-null.
1680
+ assert (Op);
1681
+ assert (isa<mlir::cir::FuncOp>(Op) &&
1682
+ " not implemented, only supports FuncOp for now" );
1683
+
1684
+ // Check to see if we've already emitted this. This is necessary for a
1685
+ // couple of reasons: first, decls can end up in deferred-decls queue
1686
+ // multiple times, and second, decls can end up with definitions in unusual
1687
+ // ways (e.g. by an extern inline function acquiring a strong function
1688
+ // redefinition). Just ignore those cases.
1689
+ // TODO: Not sure what to map this to for MLIR
1690
+ if (auto Fn = cast<mlir::cir::FuncOp>(Op))
1691
+ if (!Fn.isDeclaration ())
1692
+ return ;
1693
+
1694
+ // If this is OpenMP, check if it is legal to emit this global normally.
1695
+ if (getLangOpts ().OpenMP ) {
1696
+ llvm_unreachable (" NYI" );
1697
+ }
1698
+
1699
+ // Otherwise, emit the definition and move on to the next one.
1700
+ buildGlobalDefinition (D, Op);
1701
+ }
1702
+
1654
1703
void CIRGenModule::buildDeferred () {
1655
1704
// Emit deferred declare target declarations
1656
1705
if (getLangOpts ().OpenMP && !getLangOpts ().OpenMPSimd )
@@ -1681,41 +1730,7 @@ void CIRGenModule::buildDeferred() {
1681
1730
CurDeclsToEmit.swap (DeferredDeclsToEmit);
1682
1731
1683
1732
for (auto &D : CurDeclsToEmit) {
1684
- // We should call GetAddrOfGlobal with IsForDefinition set to true in order
1685
- // to get a Value with exactly the type we need, not something that might
1686
- // have been created for another decl with the same mangled name but
1687
- // different type.
1688
- auto *Op = GetAddrOfGlobal (D, ForDefinition);
1689
-
1690
- // In case of different address spaces, we may still get a cast, even with
1691
- // IsForDefinition equal to true. Query mangled names table to get
1692
- // GlobalValue.
1693
- if (!Op) {
1694
- Op = getGlobalValue (getMangledName (D));
1695
- }
1696
-
1697
- // Make sure getGlobalValue returned non-null.
1698
- assert (Op);
1699
- assert (isa<mlir::cir::FuncOp>(Op) &&
1700
- " not implemented, only supports FuncOp for now" );
1701
-
1702
- // Check to see if we've already emitted this. This is necessary for a
1703
- // couple of reasons: first, decls can end up in deferred-decls queue
1704
- // multiple times, and second, decls can end up with definitions in unusual
1705
- // ways (e.g. by an extern inline function acquiring a strong function
1706
- // redefinition). Just ignore those cases.
1707
- // TODO: Not sure what to map this to for MLIR
1708
- if (auto Fn = cast<mlir::cir::FuncOp>(Op))
1709
- if (!Fn.isDeclaration ())
1710
- continue ;
1711
-
1712
- // If this is OpenMP, check if it is legal to emit this global normally.
1713
- if (getLangOpts ().OpenMP ) {
1714
- llvm_unreachable (" NYI" );
1715
- }
1716
-
1717
- // Otherwise, emit the definition and move on to the next one.
1718
- buildGlobalDefinition (D, Op);
1733
+ buildGlobalDecl (D);
1719
1734
1720
1735
// If we found out that we need to emit more decls, do that recursively.
1721
1736
// This has the advantage that the decls are emitted in a DFS and related
@@ -1727,6 +1742,13 @@ void CIRGenModule::buildDeferred() {
1727
1742
}
1728
1743
}
1729
1744
1745
+ void CIRGenModule::buildDefaultMethods () {
1746
+ // Differently from DeferredDeclsToEmit, there's no recurrent use of
1747
+ // DefaultMethodsToEmit, so use it directly for emission.
1748
+ for (auto &D : DefaultMethodsToEmit)
1749
+ buildGlobalDecl (D);
1750
+ }
1751
+
1730
1752
mlir::IntegerAttr CIRGenModule::getSize (CharUnits size) {
1731
1753
return mlir::IntegerAttr::get (
1732
1754
mlir::IntegerType::get (builder.getContext (), 64 ), size.getQuantity ());
0 commit comments