diff options
Diffstat (limited to 'clang/lib/CIR')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp | 37 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenClass.cpp | 25 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 24 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenFunction.h | 2 | ||||
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenModule.cpp | 6 |
5 files changed, 54 insertions, 40 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp index e0d30ad..8da832d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCXXExpr.cpp @@ -85,13 +85,13 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr( return RValue::get(nullptr); } - bool trivialForCodegen = - md->isTrivial() || (md->isDefaulted() && md->getParent()->isUnion()); - bool trivialAssignment = - trivialForCodegen && - (md->isCopyAssignmentOperator() || md->isMoveAssignmentOperator()) && - !md->getParent()->mayInsertExtraPadding(); - (void)trivialAssignment; + // Note on trivial assignment + // -------------------------- + // Classic codegen avoids generating the trivial copy/move assignment operator + // when it isn't necessary, choosing instead to just produce IR with an + // equivalent effect. We have chosen not to do that in CIR, instead emitting + // trivial copy/move assignment operators and allowing later transformations + // to optimize them away if appropriate. // C++17 demands that we evaluate the RHS of a (possibly-compound) assignment // operator before the LHS. @@ -99,9 +99,10 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr( CallArgList *rtlArgs = nullptr; if (auto *oce = dyn_cast<CXXOperatorCallExpr>(ce)) { if (oce->isAssignmentOp()) { - cgm.errorNYI( - oce->getSourceRange(), - "emitCXXMemberOrOperatorMemberCallExpr: assignment operator"); + rtlArgs = &rtlArgStorage; + emitCallArgs(*rtlArgs, md->getType()->castAs<FunctionProtoType>(), + drop_begin(ce->arguments(), 1), ce->getDirectCallee(), + /*ParamsToSkip*/ 0); } } @@ -121,19 +122,9 @@ RValue CIRGenFunction::emitCXXMemberOrOperatorMemberCallExpr( return RValue::get(nullptr); } - if (trivialForCodegen) { - if (isa<CXXDestructorDecl>(md)) - return RValue::get(nullptr); - - if (trivialAssignment) { - cgm.errorNYI(ce->getSourceRange(), - "emitCXXMemberOrOperatorMemberCallExpr: trivial assignment"); - return RValue::get(nullptr); - } - - assert(md->getParent()->mayInsertExtraPadding() && - "unknown trivial member function"); - } + if ((md->isTrivial() || (md->isDefaulted() && md->getParent()->isUnion())) && + isa<CXXDestructorDecl>(md)) + return RValue::get(nullptr); // Compute the function type we're calling const CXXMethodDecl *calleeDecl = md; diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index 278cc893..da8166a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -258,6 +258,31 @@ void CIRGenFunction::emitDelegateCXXConstructorCall( /*Delegating=*/true, thisAddr, delegateArgs, loc); } +void CIRGenFunction::emitImplicitAssignmentOperatorBody(FunctionArgList &args) { + const auto *assignOp = cast<CXXMethodDecl>(curGD.getDecl()); + assert(assignOp->isCopyAssignmentOperator() || + assignOp->isMoveAssignmentOperator()); + const Stmt *rootS = assignOp->getBody(); + assert(isa<CompoundStmt>(rootS) && + "Body of an implicit assignment operator should be compound stmt."); + const auto *rootCS = cast<CompoundStmt>(rootS); + + assert(!cir::MissingFeatures::incrementProfileCounter()); + assert(!cir::MissingFeatures::runCleanupsScope()); + + // Classic codegen uses a special class to attempt to replace member + // initializers with memcpy. We could possibly defer that to the + // lowering or optimization phases to keep the memory accesses more + // explicit. For now, we don't insert memcpy at all, though in some + // cases the AST contains a call to memcpy. + assert(!cir::MissingFeatures::assignMemcpyizer()); + for (Stmt *s : rootCS->body()) + if (emitStmt(s, /*useCurrentScope=*/true).failed()) + cgm.errorNYI(s->getSourceRange(), + std::string("emitImplicitAssignmentOperatorBody: ") + + s->getStmtClassName()); +} + void CIRGenFunction::emitDelegatingCXXConstructorCall( const CXXConstructorDecl *ctor, const FunctionArgList &args) { assert(ctor->isDelegatingConstructor()); diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp index c029853..c4efabd 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp @@ -462,21 +462,23 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn, startFunction(gd, retTy, fn, funcType, args, loc, bodyRange.getBegin()); - if (isa<CXXDestructorDecl>(funcDecl)) + if (isa<CXXDestructorDecl>(funcDecl)) { getCIRGenModule().errorNYI(bodyRange, "C++ destructor definition"); - else if (isa<CXXConstructorDecl>(funcDecl)) + } else if (isa<CXXConstructorDecl>(funcDecl)) { emitConstructorBody(args); - else if (getLangOpts().CUDA && !getLangOpts().CUDAIsDevice && - funcDecl->hasAttr<CUDAGlobalAttr>()) + } else if (getLangOpts().CUDA && !getLangOpts().CUDAIsDevice && + funcDecl->hasAttr<CUDAGlobalAttr>()) { getCIRGenModule().errorNYI(bodyRange, "CUDA kernel"); - else if (isa<CXXMethodDecl>(funcDecl) && - cast<CXXMethodDecl>(funcDecl)->isLambdaStaticInvoker()) + } else if (isa<CXXMethodDecl>(funcDecl) && + cast<CXXMethodDecl>(funcDecl)->isLambdaStaticInvoker()) { getCIRGenModule().errorNYI(bodyRange, "Lambda static invoker"); - else if (funcDecl->isDefaulted() && isa<CXXMethodDecl>(funcDecl) && - (cast<CXXMethodDecl>(funcDecl)->isCopyAssignmentOperator() || - cast<CXXMethodDecl>(funcDecl)->isMoveAssignmentOperator())) - getCIRGenModule().errorNYI(bodyRange, "Default assignment operator"); - else if (body) { + } else if (funcDecl->isDefaulted() && isa<CXXMethodDecl>(funcDecl) && + (cast<CXXMethodDecl>(funcDecl)->isCopyAssignmentOperator() || + cast<CXXMethodDecl>(funcDecl)->isMoveAssignmentOperator())) { + // Implicit copy-assignment gets the same special treatment as implicit + // copy-constructors. + emitImplicitAssignmentOperatorBody(args); + } else if (body) { if (mlir::failed(emitFunctionBody(body))) { fn.erase(); return nullptr; diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 759b83c..c2a7315 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -878,6 +878,8 @@ public: mlir::LogicalResult emitFunctionBody(const clang::Stmt *body); + void emitImplicitAssignmentOperatorBody(FunctionArgList &args); + void emitInitializerForField(clang::FieldDecl *field, LValue lhs, clang::Expr *init); diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 0f38d9a..7198b23 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -393,12 +393,6 @@ void CIRGenModule::emitGlobal(clang::GlobalDecl gd) { void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op) { auto const *funcDecl = cast<FunctionDecl>(gd.getDecl()); - if (funcDecl->getIdentifier() == nullptr) { - errorNYI(funcDecl->getSourceRange().getBegin(), - "function definition with a non-identifier for a name"); - return; - } - const CIRGenFunctionInfo &fi = getTypes().arrangeGlobalDeclaration(gd); cir::FuncType funcType = getTypes().getFunctionType(fi); cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op); |