@@ -4733,9 +4733,8 @@ bool Compiler<Emitter>::checkLiteralType(const Expr *E) {
4733
4733
}
4734
4734
4735
4735
template <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);
4739
4738
4740
4739
auto emitFieldInitializer = [&](const Record::Field *F, unsigned FieldOffset,
4741
4740
const Expr *InitExpr) -> bool {
@@ -4763,102 +4762,114 @@ bool Compiler<Emitter>::visitFunc(const FunctionDecl *F) {
4763
4762
return this ->emitFinishInitPop (InitExpr);
4764
4763
};
4765
4764
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 ;
4770
4769
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))
4776
4774
return false ;
4777
4775
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.
4783
4778
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 ;
4786
4781
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
+ }
4789
4785
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 );
4793
4790
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);
4798
4794
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);
4802
4800
4803
- if (!emitFieldInitializer (F, F->Offset , InitExpr))
4801
+ if (Init->isBaseVirtual ()) {
4802
+ assert (R->getVirtualBase (BaseDecl));
4803
+ if (!this ->emitGetPtrThisVirtBase (BaseDecl, InitExpr))
4804
4804
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
- }
4822
4805
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))
4826
4812
return false ;
4827
- } else if (const IndirectFieldDecl *IFD = Init->getIndirectMember ()) {
4828
- assert (IFD->getChainingSize () >= 2 );
4813
+ }
4829
4814
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 );
4837
4821
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);
4840
4828
4841
- NestedFieldOffset += NestedField->Offset ;
4842
- }
4829
+ NestedField = FieldRecord->getField (FD);
4843
4830
assert (NestedField);
4844
4831
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 ;
4855
4833
}
4834
+ assert (NestedField);
4856
4835
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))
4858
4845
return false ;
4859
4846
}
4847
+
4848
+ if (!Scope.destroyLocals ())
4849
+ return false ;
4860
4850
}
4861
4851
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.
4862
4873
if (const auto *Body = F->getBody ())
4863
4874
if (!visitStmt (Body))
4864
4875
return false ;
0 commit comments