@@ -4733,9 +4733,8 @@ bool Compiler<Emitter>::checkLiteralType(const Expr *E) {
47334733}
47344734
47354735template <class Emitter >
4736- bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
4737- // Classify the return type.
4738- ReturnType = this ->classify (F->getReturnType ());
4736+ bool Compiler<Emitter>::compileConstructor(const CXXConstructorDecl *Ctor) {
4737+ assert (!ReturnType);
47394738
47404739 auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
47414740 const Expr *InitExpr) -> bool {
@@ -4763,102 +4762,114 @@ bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
47634762 return this ->emitFinishInitPop (InitExpr);
47644763 };
47654764
4766- // Emit custom code if this is a lambda static invoker.
4767- if ( const auto *MD = dyn_cast<CXXMethodDecl>(F );
4768- MD && MD-> isLambdaStaticInvoker () )
4769- return this -> emitLambdaStaticInvokerBody (MD) ;
4765+ const RecordDecl *RD = Ctor-> getParent ();
4766+ const Record *R = this -> getRecord (RD );
4767+ if (!R )
4768+ return false ;
47704769
4771- // Constructor. Set up field initializers.
4772- if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(F)) {
4773- const RecordDecl *RD = Ctor->getParent ();
4774- const Record *R = this ->getRecord (RD);
4775- if (!R)
4770+ if (R->isUnion () && Ctor->isCopyOrMoveConstructor ()) {
4771+ // union copy and move ctors are special.
4772+ assert (cast<CompoundStmt>(Ctor->getBody ())->body_empty ());
4773+ if (!this ->emitThis (Ctor))
47764774 return false ;
47774775
4778- if (R->isUnion () && Ctor->isCopyOrMoveConstructor ()) {
4779- // union copy and move ctors are special.
4780- assert (cast<CompoundStmt>(Ctor->getBody ())->body_empty ());
4781- if (!this ->emitThis (Ctor))
4782- return false ;
4776+ auto PVD = Ctor->getParamDecl (0 );
4777+ ParamOffset PO = this ->Params [PVD]; // Must exist.
47834778
4784- auto PVD = Ctor-> getParamDecl ( 0 );
4785- ParamOffset PO = this -> Params [PVD]; // Must exist.
4779+ if (! this -> emitGetParam (PT_Ptr, PO. Offset , Ctor))
4780+ return false ;
47864781
4787- if (!this ->emitGetParam (PT_Ptr, PO.Offset , Ctor))
4788- return false ;
4782+ return this ->emitMemcpy (Ctor) && this ->emitPopPtr (Ctor) &&
4783+ this ->emitRetVoid (Ctor);
4784+ }
47894785
4790- return this ->emitMemcpy (Ctor) && this ->emitPopPtr (Ctor) &&
4791- this ->emitRetVoid (Ctor);
4792- }
4786+ InitLinkScope<Emitter> InitScope (this , InitLink::This ());
4787+ for (const auto *Init : Ctor->inits ()) {
4788+ // Scope needed for the initializers.
4789+ BlockScope<Emitter> Scope (this );
47934790
4794- InitLinkScope<Emitter> InitScope (this , InitLink::This ());
4795- for (const auto *Init : Ctor->inits ()) {
4796- // Scope needed for the initializers.
4797- BlockScope<Emitter> Scope (this );
4791+ const Expr *InitExpr = Init->getInit ();
4792+ if (const FieldDecl *Member = Init->getMember ()) {
4793+ const Record::Field *F = R->getField (Member);
47984794
4799- const Expr *InitExpr = Init->getInit ();
4800- if (const FieldDecl *Member = Init->getMember ()) {
4801- const Record::Field *F = R->getField (Member);
4795+ if (!emitFieldInitializer (F, F->Offset , InitExpr))
4796+ return false ;
4797+ } else if (const Type *Base = Init->getBaseClass ()) {
4798+ const auto *BaseDecl = Base->getAsCXXRecordDecl ();
4799+ assert (BaseDecl);
48024800
4803- if (!emitFieldInitializer (F, F->Offset , InitExpr))
4801+ if (Init->isBaseVirtual ()) {
4802+ assert (R->getVirtualBase (BaseDecl));
4803+ if (!this ->emitGetPtrThisVirtBase (BaseDecl, InitExpr))
48044804 return false ;
4805- } else if (const Type *Base = Init->getBaseClass ()) {
4806- const auto *BaseDecl = Base->getAsCXXRecordDecl ();
4807- assert (BaseDecl);
4808-
4809- if (Init->isBaseVirtual ()) {
4810- assert (R->getVirtualBase (BaseDecl));
4811- if (!this ->emitGetPtrThisVirtBase (BaseDecl, InitExpr))
4812- return false ;
4813-
4814- } else {
4815- // Base class initializer.
4816- // Get This Base and call initializer on it.
4817- const Record::Base *B = R->getBase (BaseDecl);
4818- assert (B);
4819- if (!this ->emitGetPtrThisBase (B->Offset , InitExpr))
4820- return false ;
4821- }
48224805
4823- if (!this ->visitInitializer (InitExpr))
4824- return false ;
4825- if (!this ->emitFinishInitPop (InitExpr))
4806+ } else {
4807+ // Base class initializer.
4808+ // Get This Base and call initializer on it.
4809+ const Record::Base *B = R->getBase (BaseDecl);
4810+ assert (B);
4811+ if (!this ->emitGetPtrThisBase (B->Offset , InitExpr))
48264812 return false ;
4827- } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember ()) {
4828- assert (IFD->getChainingSize () >= 2 );
4813+ }
48294814
4830- unsigned NestedFieldOffset = 0 ;
4831- const Record::Field *NestedField = nullptr ;
4832- for (const NamedDecl *ND : IFD->chain ()) {
4833- const auto *FD = cast<FieldDecl>(ND);
4834- const Record *FieldRecord =
4835- this ->P .getOrCreateRecord (FD->getParent ());
4836- assert (FieldRecord);
4815+ if (!this ->visitInitializer (InitExpr))
4816+ return false ;
4817+ if (!this ->emitFinishInitPop (InitExpr))
4818+ return false ;
4819+ } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember ()) {
4820+ assert (IFD->getChainingSize () >= 2 );
48374821
4838- NestedField = FieldRecord->getField (FD);
4839- assert (NestedField);
4822+ unsigned NestedFieldOffset = 0 ;
4823+ const Record::Field *NestedField = nullptr ;
4824+ for (const NamedDecl *ND : IFD->chain ()) {
4825+ const auto *FD = cast<FieldDecl>(ND);
4826+ const Record *FieldRecord = this ->P .getOrCreateRecord (FD->getParent ());
4827+ assert (FieldRecord);
48404828
4841- NestedFieldOffset += NestedField->Offset ;
4842- }
4829+ NestedField = FieldRecord->getField (FD);
48434830 assert (NestedField);
48444831
4845- if (!emitFieldInitializer (NestedField, NestedFieldOffset, InitExpr))
4846- return false ;
4847- } else {
4848- assert (Init->isDelegatingInitializer ());
4849- if (!this ->emitThis (InitExpr))
4850- return false ;
4851- if (!this ->visitInitializer (Init->getInit ()))
4852- return false ;
4853- if (!this ->emitPopPtr (InitExpr))
4854- return false ;
4832+ NestedFieldOffset += NestedField->Offset ;
48554833 }
4834+ assert (NestedField);
48564835
4857- if (!Scope.destroyLocals ())
4836+ if (!emitFieldInitializer (NestedField, NestedFieldOffset, InitExpr))
4837+ return false ;
4838+ } else {
4839+ assert (Init->isDelegatingInitializer ());
4840+ if (!this ->emitThis (InitExpr))
4841+ return false ;
4842+ if (!this ->visitInitializer (Init->getInit ()))
4843+ return false ;
4844+ if (!this ->emitPopPtr (InitExpr))
48584845 return false ;
48594846 }
4847+
4848+ if (!Scope.destroyLocals ())
4849+ return false ;
48604850 }
48614851
4852+ if (const auto *Body = Ctor->getBody ())
4853+ if (!visitStmt (Body))
4854+ return false ;
4855+
4856+ return this ->emitRetVoid (SourceInfo{});
4857+ }
4858+
4859+ template <class Emitter >
4860+ bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
4861+ // Classify the return type.
4862+ ReturnType = this ->classify (F->getReturnType ());
4863+
4864+ if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(F))
4865+ return this ->compileConstructor (Ctor);
4866+
4867+ // Emit custom code if this is a lambda static invoker.
4868+ if (const auto *MD = dyn_cast<CXXMethodDecl>(F);
4869+ MD && MD->isLambdaStaticInvoker ())
4870+ return this ->emitLambdaStaticInvokerBody (MD);
4871+
4872+ // Regular functions.
48624873 if (const auto *Body = F->getBody ())
48634874 if (!visitStmt (Body))
48644875 return false ;
0 commit comments