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