[clang] [CIR] Handle expression with cleanups (PR #151600)

Henrich Lauko via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 1 07:52:50 PDT 2025


================
@@ -1096,6 +1096,154 @@ void CIRGenFunction::emitAnyExprToMem(const Expr *e, Address location,
   llvm_unreachable("bad evaluation kind");
 }
 
+static Address createReferenceTemporary(CIRGenFunction &cgf,
+                                        const MaterializeTemporaryExpr *m,
+                                        const Expr *inner) {
+  // TODO(cir): cgf.getTargetHooks();
+  switch (m->getStorageDuration()) {
+  case SD_FullExpression:
+  case SD_Automatic: {
+    QualType ty = inner->getType();
+
+    assert(!cir::MissingFeatures::mergeAllConstants());
+
+    // The temporary memory should be created in the same scope as the extending
+    // declaration of the temporary materialization expression.
+    cir::AllocaOp extDeclAlloca;
+    if (const clang::ValueDecl *extDecl = m->getExtendingDecl()) {
+      auto extDeclAddrIter = cgf.localDeclMap.find(extDecl);
+      if (extDeclAddrIter != cgf.localDeclMap.end()) {
+        extDeclAlloca = mlir::dyn_cast_if_present<cir::AllocaOp>(
+            extDeclAddrIter->second.getDefiningOp());
+      }
+    }
+    mlir::OpBuilder::InsertPoint ip;
+    if (extDeclAlloca)
+      ip = {extDeclAlloca->getBlock(), extDeclAlloca->getIterator()};
+    return cgf.createMemTemp(ty, cgf.getLoc(m->getSourceRange()),
+                             cgf.getCounterRefTmpAsString(), /*alloca=*/nullptr,
+                             ip);
+  }
+  case SD_Thread:
+  case SD_Static: {
+    cgf.cgm.errorNYI(
+        m->getSourceRange(),
+        "createReferenceTemporary: static/thread storage duration");
+    return Address::invalid();
+  }
+
+  case SD_Dynamic:
+    llvm_unreachable("temporary can't have dynamic storage duration");
+  }
+  llvm_unreachable("unknown storage duration");
+}
+
+static void pushTemporaryCleanup(CIRGenFunction &cgf,
+                                 const MaterializeTemporaryExpr *m,
+                                 const Expr *e, Address referenceTemporary) {
+  // Objective-C++ ARC:
+  //   If we are binding a reference to a temporary that has ownership, we
+  //   need to perform retain/release operations on the temporary.
+  //
+  // FIXME(ogcg): This should be looking at e, not m.
+  if (m->getType().getObjCLifetime()) {
+    cgf.cgm.errorNYI(e->getSourceRange(), "pushTemporaryCleanup: ObjCLifetime");
+    return;
+  }
+
+  clang::CXXDestructorDecl *referenceTemporaryDtor = nullptr;
+  if (const clang::RecordType *rt = e->getType()
+                                        ->getBaseElementTypeUnsafe()
+                                        ->getAs<clang::RecordType>()) {
+    // Get the destructor for the reference temporary.
+    auto *classDecl = cast<clang::CXXRecordDecl>(rt->getDecl());
----------------
xlauko wrote:

```suggestion
  if (const RecordType *rt = e->getType()
                                        ->getBaseElementTypeUnsafe()
                                        ->getAs<clang::RecordType>()) {
    // Get the destructor for the reference temporary.
    auto *classDecl = cast<CXXRecordDecl>(rt->getDecl());
```

https://github.com/llvm/llvm-project/pull/151600


More information about the cfe-commits mailing list