diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenClass.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenCleanup.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp | 30 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 16 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenFunction.h | 3 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenValue.h | 7 |
6 files changed, 51 insertions, 13 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index 9d12a13..8f4377b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -690,7 +690,7 @@ void CIRGenFunction::emitCXXAggrConstructorCall( // every temporary created in a default argument expression is sequenced // before the construction of the next array element, if any. { - assert(!cir::MissingFeatures::runCleanupsScope()); + RunCleanupsScope scope(*this); // Evaluate the constructor and its arguments in a regular // partial-destroy cleanup. diff --git a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp index 4d4d10b..8700697 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCleanup.cpp @@ -28,6 +28,12 @@ using namespace clang::CIRGen; // CIRGenFunction cleanup related //===----------------------------------------------------------------------===// +/// Emits all the code to cause the given temporary to be cleaned up. +void CIRGenFunction::emitCXXTemporary(const CXXTemporary *temporary, + QualType tempType, Address ptr) { + pushDestroy(NormalAndEHCleanup, ptr, tempType, destroyCXXObject); +} + //===----------------------------------------------------------------------===// // EHScopeStack //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp index 60ccf18..901b937 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp @@ -46,6 +46,12 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> { return dest; } + void ensureDest(mlir::Location loc, QualType ty) { + if (!dest.isIgnored()) + return; + dest = cgf.createAggTemp(ty, loc, "agg.tmp.ensured"); + } + public: AggExprEmitter(CIRGenFunction &cgf, AggValueSlot dest) : cgf(cgf), dest(dest) {} @@ -96,10 +102,22 @@ public: Visit(die->getExpr()); } void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *e) { - assert(!cir::MissingFeatures::aggValueSlotDestructedFlag()); + // Ensure that we have a slot, but if we already do, remember + // whether it was externally destructed. + bool wasExternallyDestructed = dest.isExternallyDestructed(); + ensureDest(cgf.getLoc(e->getSourceRange()), e->getType()); + + // We're going to push a destructor if there isn't already one. + dest.setExternallyDestructed(); + Visit(e->getSubExpr()); + + // Push that destructor we promised. + if (!wasExternallyDestructed) + cgf.emitCXXTemporary(e->getTemporary(), e->getType(), dest.getAddress()); } void VisitLambdaExpr(LambdaExpr *e); + void VisitExprWithCleanups(ExprWithCleanups *e); // Stubs -- These should be moved up when they are implemented. void VisitCastExpr(CastExpr *e) { @@ -241,11 +259,6 @@ public: cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitCXXStdInitializerListExpr"); } - - void VisitExprWithCleanups(ExprWithCleanups *e) { - cgf.cgm.errorNYI(e->getSourceRange(), - "AggExprEmitter: VisitExprWithCleanups"); - } void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *e) { cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitCXXScalarValueInitExpr"); @@ -588,6 +601,11 @@ void AggExprEmitter::VisitLambdaExpr(LambdaExpr *e) { } } +void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *e) { + CIRGenFunction::RunCleanupsScope cleanups(cgf); + Visit(e->getSubExpr()); +} + void AggExprEmitter::VisitCallExpr(const CallExpr *e) { if (e->getCallReturnType(cgf.getContext())->isReferenceType()) { cgf.cgm.errorNYI(e->getSourceRange(), "reference return type"); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 768d75d..5d3496a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -1099,15 +1099,17 @@ public: CIRGenFunction::LexicalScope lexScope{cgf, loc, b.getInsertionBlock()}; cgf.curLexScope->setAsTernary(); - b.create<cir::YieldOp>(loc, cgf.evaluateExprAsBool(e->getRHS())); + mlir::Value res = cgf.evaluateExprAsBool(e->getRHS()); + lexScope.forceCleanup(); + cir::YieldOp::create(b, loc, res); }, /*falseBuilder*/ [&](mlir::OpBuilder &b, mlir::Location loc) { CIRGenFunction::LexicalScope lexScope{cgf, loc, b.getInsertionBlock()}; cgf.curLexScope->setAsTernary(); - auto res = b.create<cir::ConstantOp>(loc, builder.getFalseAttr()); - b.create<cir::YieldOp>(loc, res.getRes()); + auto res = cir::ConstantOp::create(b, loc, builder.getFalseAttr()); + cir::YieldOp::create(b, loc, res.getRes()); }); return maybePromoteBoolResult(resOp.getResult(), resTy); } @@ -1143,15 +1145,17 @@ public: CIRGenFunction::LexicalScope lexScope{cgf, loc, b.getInsertionBlock()}; cgf.curLexScope->setAsTernary(); - auto res = b.create<cir::ConstantOp>(loc, builder.getTrueAttr()); - b.create<cir::YieldOp>(loc, res.getRes()); + auto res = cir::ConstantOp::create(b, loc, builder.getTrueAttr()); + cir::YieldOp::create(b, loc, res.getRes()); }, /*falseBuilder*/ [&](mlir::OpBuilder &b, mlir::Location loc) { CIRGenFunction::LexicalScope lexScope{cgf, loc, b.getInsertionBlock()}; cgf.curLexScope->setAsTernary(); - b.create<cir::YieldOp>(loc, cgf.evaluateExprAsBool(e->getRHS())); + mlir::Value res = cgf.evaluateExprAsBool(e->getRHS()); + lexScope.forceCleanup(); + cir::YieldOp::create(b, loc, res); }); return maybePromoteBoolResult(resOp.getResult(), resTy); diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index dfd9d2c..cbc0f4a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -1258,6 +1258,9 @@ public: RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr); + void emitCXXTemporary(const CXXTemporary *temporary, QualType tempType, + Address ptr); + void emitCXXThrowExpr(const CXXThrowExpr *e); void emitCtorPrologue(const clang::CXXConstructorDecl *ctor, diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h b/clang/lib/CIR/CodeGen/CIRGenValue.h index ea8625a..25b6ecb 100644 --- a/clang/lib/CIR/CodeGen/CIRGenValue.h +++ b/clang/lib/CIR/CodeGen/CIRGenValue.h @@ -371,6 +371,13 @@ public: mayOverlap, isZeroed); } + IsDestructed_t isExternallyDestructed() const { + return IsDestructed_t(destructedFlag); + } + void setExternallyDestructed(bool destructed = true) { + destructedFlag = destructed; + } + clang::Qualifiers getQualifiers() const { return quals; } Address getAddress() const { return addr; } |