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