@@ -465,7 +465,7 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
465465 if (isa<CXXDestructorDecl>(funcDecl))
466466 getCIRGenModule ().errorNYI (bodyRange, " C++ destructor definition" );
467467 else if (isa<CXXConstructorDecl>(funcDecl))
468- getCIRGenModule (). errorNYI (bodyRange, " C++ constructor definition " );
468+ emitConstructorBody (args );
469469 else if (getLangOpts ().CUDA && !getLangOpts ().CUDAIsDevice &&
470470 funcDecl->hasAttr <CUDAGlobalAttr>())
471471 getCIRGenModule ().errorNYI (bodyRange, " CUDA kernel" );
@@ -496,6 +496,47 @@ cir::FuncOp CIRGenFunction::generateCode(clang::GlobalDecl gd, cir::FuncOp fn,
496496 return fn;
497497}
498498
499+ void CIRGenFunction::emitConstructorBody (FunctionArgList &args) {
500+ assert (!cir::MissingFeatures::sanitizers ());
501+ const auto *ctor = cast<CXXConstructorDecl>(curGD.getDecl ());
502+ CXXCtorType ctorType = curGD.getCtorType ();
503+
504+ assert ((cgm.getTarget ().getCXXABI ().hasConstructorVariants () ||
505+ ctorType == Ctor_Complete) &&
506+ " can only generate complete ctor for this ABI" );
507+
508+ if (ctorType == Ctor_Complete && isConstructorDelegationValid (ctor) &&
509+ cgm.getTarget ().getCXXABI ().hasConstructorVariants ()) {
510+ emitDelegateCXXConstructorCall (ctor, Ctor_Base, args, ctor->getEndLoc ());
511+ return ;
512+ }
513+
514+ const FunctionDecl *definition = nullptr ;
515+ Stmt *body = ctor->getBody (definition);
516+ assert (definition == ctor && " emitting wrong constructor body" );
517+
518+ if (isa_and_nonnull<CXXTryStmt>(body)) {
519+ cgm.errorNYI (ctor->getSourceRange (), " emitConstructorBody: try body" );
520+ return ;
521+ }
522+
523+ assert (!cir::MissingFeatures::incrementProfileCounter ());
524+ assert (!cir::MissingFeatures::runCleanupsScope ());
525+
526+ // TODO: in restricted cases, we can emit the vbase initializers of a
527+ // complete ctor and then delegate to the base ctor.
528+
529+ assert (!cir::MissingFeatures::emitCtorPrologue ());
530+
531+ // TODO(cir): propagate this result via mlir::logical result. Just unreachable
532+ // now just to have it handled.
533+ if (mlir::failed (emitStmt (body, true ))) {
534+ cgm.errorNYI (ctor->getSourceRange (),
535+ " emitConstructorBody: emit body statement failed." );
536+ return ;
537+ }
538+ }
539+
499540// / Given a value of type T* that may not be to a complete object, construct
500541// / an l-vlaue withi the natural pointee alignment of T.
501542LValue CIRGenFunction::makeNaturalAlignPointeeAddrLValue (mlir::Value val,
@@ -522,16 +563,16 @@ clang::QualType CIRGenFunction::buildFunctionArgList(clang::GlobalDecl gd,
522563 cgm.getCXXABI ().buildThisParam (*this , args);
523564 }
524565
525- if (isa<CXXConstructorDecl>(fd))
526- cgm.errorNYI (fd->getSourceRange (),
527- " buildFunctionArgList: CXXConstructorDecl" );
566+ if (const auto *cd = dyn_cast<CXXConstructorDecl>(fd))
567+ if (cd->getInheritedConstructor ())
568+ cgm.errorNYI (fd->getSourceRange (),
569+ " buildFunctionArgList: inherited constructor" );
528570
529571 for (auto *param : fd->parameters ())
530572 args.push_back (param);
531573
532574 if (md && (isa<CXXConstructorDecl>(md) || isa<CXXDestructorDecl>(md)))
533- cgm.errorNYI (fd->getSourceRange (),
534- " buildFunctionArgList: implicit structor params" );
575+ cgm.getCXXABI ().addImplicitStructorParams (*this , retTy, args);
535576
536577 return retTy;
537578}
0 commit comments