@@ -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,54 @@ 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+ if (ctor->isDelegatingConstructor ()) {
531+ // This will be handled in emitCtorPrologue, but we should emit a diagnostic
532+ // rather than silently fail to delegate.
533+ cgm.errorNYI (ctor->getSourceRange (),
534+ " emitConstructorBody: delegating ctor" );
535+ return ;
536+ }
537+
538+ // TODO(cir): propagate this result via mlir::logical result. Just unreachable
539+ // now just to have it handled.
540+ if (mlir::failed (emitStmt (body, true ))) {
541+ cgm.errorNYI (ctor->getSourceRange (),
542+ " emitConstructorBody: emit body statement failed." );
543+ return ;
544+ }
545+ }
546+
499547// / Given a value of type T* that may not be to a complete object, construct
500548// / an l-vlaue withi the natural pointee alignment of T.
501549LValue CIRGenFunction::makeNaturalAlignPointeeAddrLValue (mlir::Value val,
@@ -522,16 +570,16 @@ clang::QualType CIRGenFunction::buildFunctionArgList(clang::GlobalDecl gd,
522570 cgm.getCXXABI ().buildThisParam (*this , args);
523571 }
524572
525- if (isa<CXXConstructorDecl>(fd))
526- cgm.errorNYI (fd->getSourceRange (),
527- " buildFunctionArgList: CXXConstructorDecl" );
573+ if (const auto *cd = dyn_cast<CXXConstructorDecl>(fd))
574+ if (cd->getInheritedConstructor ())
575+ cgm.errorNYI (fd->getSourceRange (),
576+ " buildFunctionArgList: inherited constructor" );
528577
529578 for (auto *param : fd->parameters ())
530579 args.push_back (param);
531580
532581 if (md && (isa<CXXConstructorDecl>(md) || isa<CXXDestructorDecl>(md)))
533- cgm.errorNYI (fd->getSourceRange (),
534- " buildFunctionArgList: implicit structor params" );
582+ assert (!cir::MissingFeatures::cxxabiStructorImplicitParam ());
535583
536584 return retTy;
537585}
0 commit comments