From 82913240ac908750e121f8a7bd9537eaaace1798 Mon Sep 17 00:00:00 2001 From: coderJeff Date: Thu, 29 Apr 2021 23:19:45 -0400 Subject: [PATCH 1/4] fbc: g++ ABI - prepare for addition of deleting destructor - internal changes - rename FB_PROCATTRIB_DESTRUCTOR to FB_PROCATTRIB_DESTRUCTOR1 for the complete destructor - add FB_PROCATTRIB_DESTRUCTOR0 for the deleting destructor - add mangling for complete dtor (D1) and deleting dtor (D0) --- src/compiler/ast-node-proc.bas | 4 ++-- src/compiler/error.bas | 2 +- src/compiler/parser-compound.bas | 6 +++--- src/compiler/parser-proc.bas | 8 ++++++-- src/compiler/rtl-array.bas | 2 +- src/compiler/symb-comp.bas | 6 +++--- src/compiler/symb-mangling.bas | 4 +++- src/compiler/symb-proc.bas | 18 ++++++++++-------- src/compiler/symb.bas | 3 ++- src/compiler/symb.bi | 7 +++++-- 10 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/compiler/ast-node-proc.bas b/src/compiler/ast-node-proc.bas index 9c2b9c974d..6e58111808 100644 --- a/src/compiler/ast-node-proc.bas +++ b/src/compiler/ast-node-proc.bas @@ -500,7 +500,7 @@ sub astProcBegin( byval sym as FBSYMBOL ptr, byval ismain as integer ) astNewVAR( symbGetParamVar( argv ) ) ) '' Destructor? - elseif( symbIsDestructor( sym ) and enable_implicit_code ) then + elseif( symbIsDestructor1( sym ) and enable_implicit_code ) then '' '' If the UDT has a vptr, reset it at the top of destructors, '' such that the vptr always matches the type of object that @@ -673,7 +673,7 @@ function astProcEnd( byval callrtexit as integer ) as integer if( res ) then '' Destructor? - if( symbIsDestructor( sym ) and enable_implicit_code ) then + if( symbIsDestructor1( sym ) and enable_implicit_code ) then '' Call destructors, behind the exit label, so they'll '' always be called, even with early returns. hCallDtors( sym ) diff --git a/src/compiler/error.bas b/src/compiler/error.bas index 0e8d0c4d84..b46471a7ae 100644 --- a/src/compiler/error.bas +++ b/src/compiler/error.bas @@ -878,7 +878,7 @@ private function hMakeParamDesc _ pname = strptr( s ) '' method? elseif( (proc->pattrib and (FB_PROCATTRIB_CONSTRUCTOR or _ - FB_PROCATTRIB_DESTRUCTOR or _ + FB_PROCATTRIB_DESTRUCTOR1 or FB_PROCATTRIB_DESTRUCTOR0 or _ FB_PROCATTRIB_OPERATOR)) <> 0 ) then s = symbMethodToStr( proc ) pname = strptr( s ) diff --git a/src/compiler/parser-compound.bas b/src/compiler/parser-compound.bas index 783420a602..d7a30655f2 100644 --- a/src/compiler/parser-compound.bas +++ b/src/compiler/parser-compound.bas @@ -317,7 +317,7 @@ sub cExitStatement( ) if( symbGetType( parser.currproc ) = FB_DATATYPE_VOID ) then if( (parser.currproc->pattrib and _ (FB_PROCATTRIB_PROPERTY or FB_PROCATTRIB_OPERATOR or _ - FB_PROCATTRIB_CONSTRUCTOR or FB_PROCATTRIB_DESTRUCTOR)) <> 0 ) then + FB_PROCATTRIB_CONSTRUCTOR or FB_PROCATTRIB_DESTRUCTOR1 or FB_PROCATTRIB_DESTRUCTOR0)) <> 0 ) then errnum = FB_ERRMSG_ILLEGALOUTSIDEASUB end if else @@ -328,7 +328,7 @@ sub cExitStatement( ) if( symbGetType( parser.currproc ) <> FB_DATATYPE_VOID ) then if( (parser.currproc->pattrib and _ (FB_PROCATTRIB_PROPERTY or FB_PROCATTRIB_OPERATOR or _ - FB_PROCATTRIB_CONSTRUCTOR or FB_PROCATTRIB_DESTRUCTOR)) <> 0 ) then + FB_PROCATTRIB_CONSTRUCTOR or FB_PROCATTRIB_DESTRUCTOR1 or FB_PROCATTRIB_DESTRUCTOR0)) <> 0 ) then errnum = FB_ERRMSG_ILLEGALOUTSIDEAFUNCTION else errnum = hCheckForCtorResult( ) @@ -357,7 +357,7 @@ sub cExitStatement( ) end if case FB_TK_DESTRUCTOR - if( symbIsDestructor( parser.currproc ) = FALSE ) then + if( symbIsDestructor1( parser.currproc ) = FALSE ) then errnum = FB_ERRMSG_ILLEGALOUTSIDEADTOR end if diff --git a/src/compiler/parser-proc.bas b/src/compiler/parser-proc.bas index c5a8a849ac..9d608848c4 100644 --- a/src/compiler/parser-proc.bas +++ b/src/compiler/parser-proc.bas @@ -1056,7 +1056,9 @@ function cProcHeader _ if( tk = FB_TK_CONSTRUCTOR ) then pattrib or= FB_PROCATTRIB_CONSTRUCTOR or FB_PROCATTRIB_OVERLOADED else - pattrib or= FB_PROCATTRIB_DESTRUCTOR + '' destructor defined by user source is always the complete dtor + '' the deleting dtor is implicitly defined later + pattrib or= FB_PROCATTRIB_DESTRUCTOR1 end if case FB_TK_OPERATOR @@ -1762,7 +1764,9 @@ sub cProcStmtBegin( byval attrib as FB_SYMBATTRIB, byval pattrib as FB_PROCATTRI if( fbLangOptIsSet( FB_LANG_OPT_CLASS ) = FALSE ) then errReportNotAllowed( FB_LANG_OPT_CLASS ) else - pattrib or= FB_PROCATTRIB_DESTRUCTOR + '' destructor defined by user source is always the complete dtor + '' the deleting dtor is implicitly defined later + pattrib or= FB_PROCATTRIB_DESTRUCTOR1 end if hDisallowStaticAttrib( attrib, pattrib ) diff --git a/src/compiler/rtl-array.bas b/src/compiler/rtl-array.bas index 924bf33621..b1d02227c6 100644 --- a/src/compiler/rtl-array.bas +++ b/src/compiler/rtl-array.bas @@ -331,7 +331,7 @@ private sub hCheckDtor _ if( dtor = NULL ) then exit sub - assert( symbIsDestructor( dtor ) ) + assert( symbIsDestructor1( dtor ) ) if( check_access ) then if( symbCheckAccess( dtor ) = FALSE ) then diff --git a/src/compiler/symb-comp.bas b/src/compiler/symb-comp.bas index f953de7180..5c7e57ba4d 100644 --- a/src/compiler/symb-comp.bas +++ b/src/compiler/symb-comp.bas @@ -619,8 +619,8 @@ sub symbUdtDeclareDefaultMembers _ '' no default dtor explicitly defined? if( udt->udt.ext->dtor = NULL ) then - '' Dtor - default.dtor = hDeclareProc( udt, INVALID, FB_DATATYPE_INVALID, FB_SYMBATTRIB_NONE, FB_PROCATTRIB_DESTRUCTOR ) + '' Complete Dtor + default.dtor = hDeclareProc( udt, INVALID, FB_DATATYPE_INVALID, FB_SYMBATTRIB_NONE, FB_PROCATTRIB_DESTRUCTOR1 ) '' Don't allow the implicit dtor to override a FINAL dtor from the base symbProcCheckOverridden( default.dtor, TRUE ) @@ -785,7 +785,7 @@ end sub sub symbSetCompDtor( byval sym as FBSYMBOL ptr, byval proc as FBSYMBOL ptr ) if( symbIsStruct( sym ) ) then - assert( symbIsDestructor( proc ) ) + assert( symbIsDestructor1( proc ) ) symbUdtAllocExt( sym ) if( sym->udt.ext->dtor = NULL ) then '' Add dtor diff --git a/src/compiler/symb-mangling.bas b/src/compiler/symb-mangling.bas index edad015795..a6b38dce49 100644 --- a/src/compiler/symb-mangling.bas +++ b/src/compiler/symb-mangling.bas @@ -1278,7 +1278,9 @@ private sub hMangleProc( byval sym as FBSYMBOL ptr ) end if elseif( symbIsConstructor( sym ) ) then mangled += "C1" - elseif( symbIsDestructor( sym ) ) then + elseif( symbIsDestructor0( sym ) ) then + mangled += "D0" + elseif( symbIsDestructor1( sym ) ) then mangled += "D1" else if( symbGetMangling( sym ) = FB_MANGLING_BASIC ) then diff --git a/src/compiler/symb-proc.bas b/src/compiler/symb-proc.bas index 9af62f8f2c..8b97aef6c1 100644 --- a/src/compiler/symb-proc.bas +++ b/src/compiler/symb-proc.bas @@ -716,7 +716,7 @@ private function hSetupProc _ '' ctor/dtor? if( (pattrib and (FB_PROCATTRIB_CONSTRUCTOR or _ - FB_PROCATTRIB_DESTRUCTOR)) <> 0 ) then + FB_PROCATTRIB_DESTRUCTOR1 or FB_PROCATTRIB_DESTRUCTOR0)) <> 0 ) then assert( pattrib and FB_PROCATTRIB_METHOD ) @@ -748,7 +748,7 @@ private function hSetupProc _ '' otherwise, try to overload else '' dtor? - if( (pattrib and FB_PROCATTRIB_DESTRUCTOR) <> 0 ) then + if( (pattrib and (FB_PROCATTRIB_DESTRUCTOR1 or FB_PROCATTRIB_DESTRUCTOR0)) <> 0 ) then '' can't overload return NULL end if @@ -920,8 +920,8 @@ add_proc: overridden = NULL if( parent->udt.base ) then '' Destructor? - if( symbIsDestructor( proc ) ) then - '' There can always only be one, so there is no + if( symbIsDestructor1( proc ) ) then + '' There can always only be one complete dtor, so there is no '' need to do a lookup and/or overload checks. overridden = symbGetCompDtor( parent->udt.base->subtype ) elseif( symbIsOperator( proc ) ) then @@ -1601,7 +1601,7 @@ function symbFindCtorProc _ ) as FBSYMBOL ptr '' dtor? can't overload.. - if( symbIsDestructor( ovl_head_proc ) ) then + if( symbIsDestructor1( ovl_head_proc ) ) then return ovl_head_proc else return symbFindOverloadProc( ovl_head_proc, proc ) @@ -2845,7 +2845,7 @@ sub symbProcCheckOverridden _ '' implicit dtors and LET overloads. Since they '' are not visible in the original code, '' the error message must have more info. - if( symbIsDestructor( proc ) ) then + if( symbIsDestructor1( proc ) ) then errmsg = FB_ERRMSG_IMPLICITDTOROVERRIDECALLCONVDIFFERS else errmsg = FB_ERRMSG_IMPLICITLETOVERRIDECALLCONVDIFFERS @@ -2916,7 +2916,7 @@ end sub '' Append calling convention, if it differs from the default private sub hProcModeToStr( byref s as string, byval proc as FBSYMBOL ptr ) '' Ctors/Dtors currently always default to CDECL, see cProcHeader() - if( symbIsConstructor( proc ) or symbIsDestructor( proc ) ) then + if( symbIsConstructor( proc ) or symbIsDestructor1( proc ) or symbIsDestructor0( proc ) ) then select case( symbGetProcMode( proc ) ) case FB_FUNCMODE_STDCALL, FB_FUNCMODE_STDCALL_MS s += " stdcall" @@ -3045,7 +3045,9 @@ function symbGetFullProcName( byval proc as FBSYMBOL ptr ) as zstring ptr if( symbIsConstructor( proc ) ) then res += "constructor" - elseif( symbIsDestructor( proc ) ) then + elseif( symbIsDestructor1( proc ) ) then + res += "destructor" + elseif( symbIsDestructor0( proc ) ) then res += "destructor" elseif( symbIsOperator( proc ) ) then res += "operator." diff --git a/src/compiler/symb.bas b/src/compiler/symb.bas index 751a0cee2f..5d467d3c32 100644 --- a/src/compiler/symb.bas +++ b/src/compiler/symb.bas @@ -2506,7 +2506,8 @@ function symbDumpToStr _ checkPAttrib( OVERLOADED ) checkPAttrib( METHOD ) checkPAttrib( CONSTRUCTOR ) - checkPAttrib( DESTRUCTOR ) + checkPAttrib( DESTRUCTOR1 ) + checkPAttrib( DESTRUCTOR0 ) checkPAttrib( OPERATOR ) checkPAttrib( PROPERTY ) checkPAttrib( RETURNBYREF ) diff --git a/src/compiler/symb.bi b/src/compiler/symb.bi index 7aa6d5dde2..3c8d73b4f8 100644 --- a/src/compiler/symb.bi +++ b/src/compiler/symb.bi @@ -191,7 +191,7 @@ enum FB_PROCATTRIB FB_PROCATTRIB_OVERLOADED = &h00000001 '' PROCs / METHODs only FB_PROCATTRIB_METHOD = &h00000002 '' Non-STATIC UDT member procs, i.e. procs with implicit THIS ptr FB_PROCATTRIB_CONSTRUCTOR = &h00000004 '' methods only - FB_PROCATTRIB_DESTRUCTOR = &h00000008 '' methods only + FB_PROCATTRIB_DESTRUCTOR1 = &h00000008 '' methods only FB_PROCATTRIB_OPERATOR = &h00000010 '' methods only FB_PROCATTRIB_PROPERTY = &h00000020 '' methods only FB_PROCATTRIB_STATICLOCALS = &h00000040 '' PROCs only @@ -200,6 +200,7 @@ enum FB_PROCATTRIB FB_PROCATTRIB_ABSTRACT = &h00000200 '' methods only: pure virtuals (only) FB_PROCATTRIB_NOTHISCONSTNESS = &h00000400 '' PROCs only FB_PROCATTRIB_RETURNBYREF = &h00000800 '' PROCs (functions/function pointers returning BYREF) + FB_PROCATTRIB_DESTRUCTOR0 = &h00001000 '' methods only - deleting destructor end enum '' parameter modes @@ -2498,7 +2499,9 @@ declare sub symbProcRecalcRealType( byval proc as FBSYMBOL ptr ) #define symbIsConstructor(s) ((s->pattrib and FB_PROCATTRIB_CONSTRUCTOR) <> 0) -#define symbIsDestructor(s) ((s->pattrib and FB_PROCATTRIB_DESTRUCTOR) <> 0) +#define symbIsDestructor0(s) ((s->pattrib and FB_PROCATTRIB_DESTRUCTOR0) <> 0) + +#define symbIsDestructor1(s) ((s->pattrib and FB_PROCATTRIB_DESTRUCTOR1) <> 0) #define symbIsOperator(s) ((s->pattrib and FB_PROCATTRIB_OPERATOR) <> 0) From acc219ff1ce974fea3c2be266cb99c9abcf4926a Mon Sep 17 00:00:00 2001 From: coderJeff Date: Thu, 29 Apr 2021 23:27:31 -0400 Subject: [PATCH 2/4] fbc: g++ ABI - whitespace changes before next update --- src/compiler/symb.bi | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/compiler/symb.bi b/src/compiler/symb.bi index 3c8d73b4f8..12943e6fe5 100644 --- a/src/compiler/symb.bi +++ b/src/compiler/symb.bi @@ -486,18 +486,18 @@ type FB_STRUCT_DBG end type type FB_STRUCTEXT - ctorhead as FBSYMBOL_ ptr '' ctor head (first overload proc) or NULL - defctor as FBSYMBOL_ ptr '' default ctor or NULL - copyctor as FBSYMBOL_ ptr '' copy ctor or NULL - copyctorconst as FBSYMBOL_ ptr '' copy ctor with CONST param or NULL - dtor as FBSYMBOL_ ptr '' destructor or NULL - copyletop as FBSYMBOL_ ptr '' copy LET overload proc or NULL - copyletopconst as FBSYMBOL_ ptr '' copy LET overload proc with CONST param or NULL + ctorhead as FBSYMBOL_ ptr '' ctor head (first overload proc) or NULL + defctor as FBSYMBOL_ ptr '' default ctor or NULL + copyctor as FBSYMBOL_ ptr '' copy ctor or NULL + copyctorconst as FBSYMBOL_ ptr '' copy ctor with CONST param or NULL + dtor as FBSYMBOL_ ptr '' destructor or NULL + copyletop as FBSYMBOL_ ptr '' copy LET overload proc or NULL + copyletopconst as FBSYMBOL_ ptr '' copy LET overload proc with CONST param or NULL opovlTb(0 to AST_OP_SELFOPS-1) as FBSYMBOL_ ptr - vtableelements as integer '' vtable elements counter - vtable as FBSYMBOL_ ptr '' virtual-functions table struct - rtti as FBSYMBOL_ ptr '' Run-Time Type Info struct - abstractcount as integer '' ABSTRACT method counter (to determine abstract classes, which aren't allowed to be instantiated) + vtableelements as integer '' vtable elements counter + vtable as FBSYMBOL_ ptr '' virtual-functions table struct + rtti as FBSYMBOL_ ptr '' Run-Time Type Info struct + abstractcount as integer '' ABSTRACT method counter (to determine abstract classes, which aren't allowed to be instantiated) end type type FBS_STRUCT @@ -917,11 +917,11 @@ end type '' Data passed from symbUdtDeclareDefaultMembers() to symbUdtImplementDefaultMembers() type SYMBDEFAULTMEMBERS - defctor as FBSYMBOL ptr - dtor as FBSYMBOL ptr - copyctor as FBSYMBOL ptr - copyctorconst as FBSYMBOL ptr - copyletopconst as FBSYMBOL ptr + defctor as FBSYMBOL ptr + dtor as FBSYMBOL ptr + copyctor as FBSYMBOL ptr + copyctorconst as FBSYMBOL ptr + copyletopconst as FBSYMBOL ptr end type #include once "ast.bi" From 93178357f1d3c3cacf21da3cedf5d466e6149f36 Mon Sep 17 00:00:00 2001 From: coderJeff Date: Thu, 29 Apr 2021 23:39:52 -0400 Subject: [PATCH 3/4] fbc: g++ ABI - add tracking for complete and deleting destructors - internal changes - FB_STRUCTEXT - rename dtor to dtor1 and add dtor0 - SYMBDEFAULTMEMBERS - rename dtor to dtor1 and add dtor0 - symbSetCompDtor() - rename to symbSetCompDtor1() and add symbSetCompDtor0() - symbGetCompDtor() - rename to symbGetCompDtor1() and add symbGetCompDtor0() --- src/compiler/ast-helper.bas | 4 +- src/compiler/ast-node-proc.bas | 4 +- src/compiler/parser-decl-struct.bas | 2 +- src/compiler/parser-decl-var.bas | 2 +- src/compiler/parser-expr-variable.bas | 2 +- src/compiler/parser-proc.bas | 2 +- src/compiler/parser-quirk-mem.bas | 2 +- src/compiler/rtl-array.bas | 6 +-- src/compiler/symb-comp.bas | 58 +++++++++++++++++++++------ src/compiler/symb-data.bas | 2 +- src/compiler/symb-proc.bas | 17 ++++++-- src/compiler/symb-struct.bas | 2 +- src/compiler/symb.bi | 12 ++++-- 13 files changed, 81 insertions(+), 34 deletions(-) diff --git a/src/compiler/ast-helper.bas b/src/compiler/ast-helper.bas index 3aee36492b..a0e2268a62 100644 --- a/src/compiler/ast-helper.bas +++ b/src/compiler/ast-helper.bas @@ -153,7 +153,7 @@ function astBuildVarDtorCall overload _ '' UDT var with dtor? if( symbHasDtor( s ) ) then if( check_access ) then - if( symbCheckAccess( symbGetCompDtor( symbGetSubtype( s ) ) ) = FALSE ) then + if( symbCheckAccess( symbGetCompDtor1( symbGetSubtype( s ) ) ) = FALSE ) then errReport( FB_ERRMSG_NOACCESSTODTOR ) end if end if @@ -543,7 +543,7 @@ function astBuildDtorCall _ dim as ASTNODE ptr callexpr = any '' Can be virtual - dtor = symbGetCompDtor( sym ) + dtor = symbGetCompDtor1( sym ) if( ignore_virtual ) then callexpr = astNewCALL( dtor ) else diff --git a/src/compiler/ast-node-proc.bas b/src/compiler/ast-node-proc.bas index 6e58111808..0c7079fa99 100644 --- a/src/compiler/ast-node-proc.bas +++ b/src/compiler/ast-node-proc.bas @@ -500,7 +500,7 @@ sub astProcBegin( byval sym as FBSYMBOL ptr, byval ismain as integer ) astNewVAR( symbGetParamVar( argv ) ) ) '' Destructor? - elseif( symbIsDestructor1( sym ) and enable_implicit_code ) then + elseif( (symbIsDestructor0( sym ) or symbIsDestructor1( sym )) and enable_implicit_code ) then '' '' If the UDT has a vptr, reset it at the top of destructors, '' such that the vptr always matches the type of object that @@ -1296,7 +1296,7 @@ private sub hCallBaseDtor _ '' Just like derived classes are not responsible for initializing their '' base class, they shouldn't be made responsible for cleaning it up. - dtor = symbGetCompDtor( symbGetSubtype( base_ ) ) + dtor = symbGetCompDtor1( symbGetSubtype( base_ ) ) if( dtor = NULL ) then exit sub end if diff --git a/src/compiler/parser-decl-struct.bas b/src/compiler/parser-decl-struct.bas index 3affe7e3ac..f28d1041ca 100644 --- a/src/compiler/parser-decl-struct.bas +++ b/src/compiler/parser-decl-struct.bas @@ -183,7 +183,7 @@ private sub hFieldInit _ end if '' Does it have a destructor? - defctor = symbGetCompDtor( subtype ) + defctor = symbGetCompDtor1( subtype ) if( defctor ) then '' Check whether we have access if( symbCheckAccess( defctor ) = FALSE ) then diff --git a/src/compiler/parser-decl-var.bas b/src/compiler/parser-decl-var.bas index 16733fa150..38134aec37 100644 --- a/src/compiler/parser-decl-var.bas +++ b/src/compiler/parser-decl-var.bas @@ -1189,7 +1189,7 @@ private function hFlushInitializer _ '' object? if( has_dtor and (not symbIsRef( sym )) ) then '' check visibility - if( symbCheckAccess( symbGetCompDtor( symbGetSubtype( sym ) ) ) = FALSE ) then + if( symbCheckAccess( symbGetCompDtor1( symbGetSubtype( sym ) ) ) = FALSE ) then errReport( FB_ERRMSG_NOACCESSTODTOR ) end if end if diff --git a/src/compiler/parser-expr-variable.bas b/src/compiler/parser-expr-variable.bas index ac3f94c52e..a670e9c7a7 100644 --- a/src/compiler/parser-expr-variable.bas +++ b/src/compiler/parser-expr-variable.bas @@ -246,7 +246,7 @@ private function hMemberId( byval parent as FBSYMBOL ptr ) as FBSYMBOL ptr case FB_TK_CONSTRUCTOR res = symbGetCompCtorHead( parent ) case FB_TK_DESTRUCTOR - res = symbGetCompDtor( parent ) + res = symbGetCompDtor1( parent ) end select if( res ) then diff --git a/src/compiler/parser-proc.bas b/src/compiler/parser-proc.bas index 9d608848c4..9bc470c262 100644 --- a/src/compiler/parser-proc.bas +++ b/src/compiler/parser-proc.bas @@ -1556,7 +1556,7 @@ function cProcHeader _ case FB_TK_CONSTRUCTOR head_proc = symbGetCompCtorHead( parent ) case FB_TK_DESTRUCTOR - head_proc = symbGetCompDtor( parent ) + head_proc = symbGetCompDtor1( parent ) case FB_TK_OPERATOR head_proc = symbGetCompOpOvlHead( parent, op ) end select diff --git a/src/compiler/parser-quirk-mem.bas b/src/compiler/parser-quirk-mem.bas index 678880f45f..6caa967635 100644 --- a/src/compiler/parser-quirk-mem.bas +++ b/src/compiler/parser-quirk-mem.bas @@ -260,7 +260,7 @@ sub cOperatorDelete( ) '' check visibility if( typeHasDtor( typeDeref( dtype ), subtype ) ) then - if( symbCheckAccess( symbGetCompDtor( subtype ) ) = FALSE ) then + if( symbCheckAccess( symbGetCompDtor1( subtype ) ) = FALSE ) then errReport( FB_ERRMSG_NOACCESSTODTOR ) end if end if diff --git a/src/compiler/rtl-array.bas b/src/compiler/rtl-array.bas index b1d02227c6..745f3a3e33 100644 --- a/src/compiler/rtl-array.bas +++ b/src/compiler/rtl-array.bas @@ -370,7 +370,7 @@ function rtlArrayClear( byval arrayexpr as ASTNODE ptr ) as ASTNODE ptr if( dtype = FB_DATATYPE_STRUCT ) then subtype = astGetSubtype( arrayexpr ) ctor = symbGetCompDefCtor( subtype ) - dtor = symbGetCompDtor( subtype ) + dtor = symbGetCompDtor1( subtype ) '' No default ctor, but others? Then the rtlib cannot just clear '' that array of objects. @@ -453,7 +453,7 @@ function rtlArrayErase _ if( dtype = FB_DATATYPE_STRUCT ) then subtype = astGetSubtype( arrayexpr ) ctor = symbGetCompDefCtor( subtype ) - dtor = symbGetCompDtor( subtype ) + dtor = symbGetCompDtor1( subtype ) '' No default ctor, but others? Then the rtlib cannot just clear '' that array of objects. @@ -534,7 +534,7 @@ private sub hGetCtorDtorForRedim _ if( typeGetDtAndPtrOnly( dtype ) = FB_DATATYPE_STRUCT ) then ctor = symbGetCompDefCtor( subtype ) - dtor = symbGetCompDtor( subtype ) + dtor = symbGetCompDtor1( subtype ) '' Assuming there aren't any other ctors if there is no default one, '' because if it were possible to declare such a dynamic array, diff --git a/src/compiler/symb-comp.bas b/src/compiler/symb-comp.bas index 5c7e57ba4d..ed26949bbf 100644 --- a/src/compiler/symb-comp.bas +++ b/src/compiler/symb-comp.bas @@ -559,7 +559,8 @@ sub symbUdtDeclareDefaultMembers _ default.copyctor = NULL default.copyctorconst = NULL default.copyletopconst = NULL - default.dtor = NULL + default.dtor1 = NULL + default.dtor0 = NULL '' Ctor/inited fields and no ctor yet? if( (symbGetUDTHasCtorField( udt ) or symbGetUDTHasInitedField( udt )) and _ @@ -618,12 +619,18 @@ sub symbUdtDeclareDefaultMembers _ symbUdtAllocExt( udt ) '' no default dtor explicitly defined? - if( udt->udt.ext->dtor = NULL ) then - '' Complete Dtor - default.dtor = hDeclareProc( udt, INVALID, FB_DATATYPE_INVALID, FB_SYMBATTRIB_NONE, FB_PROCATTRIB_DESTRUCTOR1 ) + if( udt->udt.ext->dtor1 = NULL ) then + + assert( udt->udt.ext->dtor0 = NULL ) + + '' Complete dtor + default.dtor1 = hDeclareProc( udt, INVALID, FB_DATATYPE_INVALID, FB_SYMBATTRIB_NONE, FB_PROCATTRIB_DESTRUCTOR1 ) + + '' Deleting dtor + default.dtor0 = hDeclareProc( udt, INVALID, FB_DATATYPE_INVALID, FB_SYMBATTRIB_NONE, FB_PROCATTRIB_DESTRUCTOR0 ) '' Don't allow the implicit dtor to override a FINAL dtor from the base - symbProcCheckOverridden( default.dtor, TRUE ) + symbProcCheckOverridden( default.dtor1, TRUE ) end if end if @@ -685,8 +692,12 @@ sub symbUdtImplementDefaultMembers _ hAddCtorBody( udt, default.copyctor, TRUE ) end if - if( default.dtor ) then - hAddCtorBody( udt, default.dtor, FALSE ) + if( default.dtor1 ) then + hAddCtorBody( udt, default.dtor1, FALSE ) + end if + + if( default.dtor0 ) then + hAddCtorBody( udt, default.dtor0, FALSE ) end if end sub @@ -733,7 +744,7 @@ end function function symbCompIsTrivial( byval sym as FBSYMBOL ptr ) as integer assert( symbIsStruct( sym ) ) function = ((symbGetCompCopyCtor( sym ) = NULL) and _ - (symbGetCompDtor( sym ) = NULL) and _ + (symbGetCompDtor1( sym ) = NULL) and _ (not symbGetHasRTTI( sym ))) end function @@ -783,13 +794,24 @@ sub symbCheckCompCtor( byval sym as FBSYMBOL ptr, byval proc as FBSYMBOL ptr ) end if end sub -sub symbSetCompDtor( byval sym as FBSYMBOL ptr, byval proc as FBSYMBOL ptr ) +sub symbSetCompDtor1( byval sym as FBSYMBOL ptr, byval proc as FBSYMBOL ptr ) if( symbIsStruct( sym ) ) then assert( symbIsDestructor1( proc ) ) symbUdtAllocExt( sym ) - if( sym->udt.ext->dtor = NULL ) then + if( sym->udt.ext->dtor1 = NULL ) then + '' Add dtor + sym->udt.ext->dtor1 = proc + end if + end if +end sub + +sub symbSetCompDtor0( byval sym as FBSYMBOL ptr, byval proc as FBSYMBOL ptr ) + if( symbIsStruct( sym ) ) then + assert( symbIsDestructor0( proc ) ) + symbUdtAllocExt( sym ) + if( sym->udt.ext->dtor0 = NULL ) then '' Add dtor - sym->udt.ext->dtor = proc + sym->udt.ext->dtor0 = proc end if end if end sub @@ -821,11 +843,21 @@ private function symbGetCompCopyCtor( byval sym as FBSYMBOL ptr ) as FBSYMBOL pt end if end function -function symbGetCompDtor( byval sym as FBSYMBOL ptr ) as FBSYMBOL ptr +function symbGetCompDtor1( byval sym as FBSYMBOL ptr ) as FBSYMBOL ptr + if( sym ) then + if( symbIsStruct( sym ) ) then + if( sym->udt.ext ) then + function = sym->udt.ext->dtor1 + end if + end if + end if +end function + +function symbGetCompDtor0( byval sym as FBSYMBOL ptr ) as FBSYMBOL ptr if( sym ) then if( symbIsStruct( sym ) ) then if( sym->udt.ext ) then - function = sym->udt.ext->dtor + function = sym->udt.ext->dtor0 end if end if end if diff --git a/src/compiler/symb-data.bas b/src/compiler/symb-data.bas index b3f54e4dc4..02c8b2f08a 100644 --- a/src/compiler/symb-data.bas +++ b/src/compiler/symb-data.bas @@ -322,7 +322,7 @@ function typeHasDtor _ select case( typeGet( dtype ) ) case FB_DATATYPE_STRUCT '', FB_DATATYPE_CLASS - function = (symbGetCompDtor( subtype ) <> NULL) + function = (symbGetCompDtor1( subtype ) <> NULL) end select end function diff --git a/src/compiler/symb-proc.bas b/src/compiler/symb-proc.bas index 8b97aef6c1..aac18f9122 100644 --- a/src/compiler/symb-proc.bas +++ b/src/compiler/symb-proc.bas @@ -729,8 +729,10 @@ private function hSetupProc _ '' ctor? if( (pattrib and FB_PROCATTRIB_CONSTRUCTOR) <> 0 ) then head_proc = symbGetCompCtorHead( parent ) + elseif( (pattrib and FB_PROCATTRIB_DESTRUCTOR1) <> 0 ) then + head_proc = symbGetCompDtor1( parent ) else - head_proc = symbGetCompDtor( parent ) + head_proc = symbGetCompDtor0( parent ) end if '' not overloaded yet? just add it @@ -739,12 +741,21 @@ private function hSetupProc _ FB_SYMBCLASS_PROC, NULL, id_alias, _ FB_DATATYPE_VOID, NULL, attrib, pattrib ) + '' ctor? if( (pattrib and FB_PROCATTRIB_CONSTRUCTOR) <> 0 ) then symbSetCompCtorHead( parent, proc ) + + '' complete dtor? + elseif( (pattrib and FB_PROCATTRIB_DESTRUCTOR1) <> 0 ) then + symbSetCompDtor1( parent, proc ) + + '' deleting dtor else - symbSetCompDtor( parent, proc ) + symbSetCompDtor0( parent, proc ) + end if + '' otherwise, try to overload else '' dtor? @@ -923,7 +934,7 @@ add_proc: if( symbIsDestructor1( proc ) ) then '' There can always only be one complete dtor, so there is no '' need to do a lookup and/or overload checks. - overridden = symbGetCompDtor( parent->udt.base->subtype ) + overridden = symbGetCompDtor1( parent->udt.base->subtype ) elseif( symbIsOperator( proc ) ) then '' Get the corresponding operator from the base '' (actually a chain of overloads for that particular operator) diff --git a/src/compiler/symb-struct.bas b/src/compiler/symb-struct.bas index ecd855b140..4eb9ed4561 100644 --- a/src/compiler/symb-struct.bas +++ b/src/compiler/symb-struct.bas @@ -502,7 +502,7 @@ function symbAddField _ end if end if - if( symbGetCompDtor( subtype ) ) then + if( symbGetCompDtor1( subtype ) ) then '' not allowed inside unions or anonymous nested structs/unions if( symbGetUDTIsUnionOrAnon( parent ) ) then errReport( FB_ERRMSG_DTORINUNION ) diff --git a/src/compiler/symb.bi b/src/compiler/symb.bi index 12943e6fe5..c958c1443c 100644 --- a/src/compiler/symb.bi +++ b/src/compiler/symb.bi @@ -490,7 +490,8 @@ type FB_STRUCTEXT defctor as FBSYMBOL_ ptr '' default ctor or NULL copyctor as FBSYMBOL_ ptr '' copy ctor or NULL copyctorconst as FBSYMBOL_ ptr '' copy ctor with CONST param or NULL - dtor as FBSYMBOL_ ptr '' destructor or NULL + dtor1 as FBSYMBOL_ ptr '' complete object destructor or NULL + dtor0 as FBSYMBOL_ ptr '' deleting destructor or NULL copyletop as FBSYMBOL_ ptr '' copy LET overload proc or NULL copyletopconst as FBSYMBOL_ ptr '' copy LET overload proc with CONST param or NULL opovlTb(0 to AST_OP_SELFOPS-1) as FBSYMBOL_ ptr @@ -918,7 +919,8 @@ end type '' Data passed from symbUdtDeclareDefaultMembers() to symbUdtImplementDefaultMembers() type SYMBDEFAULTMEMBERS defctor as FBSYMBOL ptr - dtor as FBSYMBOL ptr + dtor1 as FBSYMBOL ptr + dtor0 as FBSYMBOL ptr copyctor as FBSYMBOL ptr copyctorconst as FBSYMBOL ptr copyletopconst as FBSYMBOL ptr @@ -1885,10 +1887,12 @@ declare sub symbUdtImplementDefaultMembers _ declare function symbCompIsTrivial( byval sym as FBSYMBOL ptr ) as integer declare sub symbSetCompCtorHead( byval sym as FBSYMBOL ptr, byval proc as FBSYMBOL ptr ) declare sub symbCheckCompCtor( byval sym as FBSYMBOL ptr, byval proc as FBSYMBOL ptr ) -declare sub symbSetCompDtor( byval sym as FBSYMBOL ptr, byval proc as FBSYMBOL ptr ) +declare sub symbSetCompDtor1( byval sym as FBSYMBOL ptr, byval proc as FBSYMBOL ptr ) +declare sub symbSetCompDtor0( byval sym as FBSYMBOL ptr, byval proc as FBSYMBOL ptr ) declare function symbGetCompCtorHead( byval sym as FBSYMBOL ptr ) as FBSYMBOL ptr declare function symbGetCompDefCtor( byval sym as FBSYMBOL ptr ) as FBSYMBOL ptr -declare function symbGetCompDtor( byval sym as FBSYMBOL ptr ) as FBSYMBOL ptr +declare function symbGetCompDtor1( byval sym as FBSYMBOL ptr ) as FBSYMBOL ptr +declare function symbGetCompDtor0( byval sym as FBSYMBOL ptr ) as FBSYMBOL ptr declare sub symbCheckCompLetOp( byval sym as FBSYMBOL ptr, byval proc as FBSYMBOL ptr ) declare function symbCompHasCopyLetOps( byval udt as FBSYMBOL ptr ) as integer From 947a9f49181c16628356e2e1b6b88f07457d516f Mon Sep 17 00:00:00 2001 From: coderJeff Date: Thu, 29 Apr 2021 23:44:36 -0400 Subject: [PATCH 4/4] fbc: g++ ABI - emit the deleting destructor - emit the deleting destructor only in c++ mangling - if type is in an extern "c++" block, implicitly generate and emit the deleting destructor (D0) --- changelog.txt | 1 + src/compiler/ast-node-proc.bas | 28 +++++++++++++++++++++++++++- src/compiler/parser-proc.bas | 15 +++++++++++++++ src/compiler/symb-comp.bas | 15 +++++++++++++-- src/compiler/symb-proc.bas | 5 +---- src/compiler/symb.bi | 2 +- 6 files changed, 58 insertions(+), 8 deletions(-) diff --git a/changelog.txt b/changelog.txt index 8c11fa09e7..faff6f6dd2 100644 --- a/changelog.txt +++ b/changelog.txt @@ -46,6 +46,7 @@ Version 1.08.0 - only write debug line information for statements and don't write comments / empty lines / directives for top level source code in assembly debug ouput - optimize byref 'm += s' string concatenations to fb_StrConcatByref() which will check for same string descriptor at run-time which can't be determined at compile time for byref parameters. - github #298: allow command line options passed to as, gcc, ld to be longer than 128 characters by using string types internally +- sf.net #923: implicitly emit the deleting destrutor for extern "c++" mangling for better g++ ABI compatibility [added] - extern "rtlib": respects the parent namespace, uses default fb calling convention and C style name mangling diff --git a/src/compiler/ast-node-proc.bas b/src/compiler/ast-node-proc.bas index 0c7079fa99..f8bf326776 100644 --- a/src/compiler/ast-node-proc.bas +++ b/src/compiler/ast-node-proc.bas @@ -33,6 +33,7 @@ declare function hInitVptr _ ) as ASTNODE ptr declare sub hCallCtors( byval n as ASTNODE ptr, byval sym as FBSYMBOL ptr ) declare sub hCallDtors( byval proc as FBSYMBOL ptr ) +declare sub hCallDeleteDtor( byval proc as FBSYMBOL ptr ) declare sub hGenStaticInstancesDtors( byval proc as FBSYMBOL ptr ) declare sub hGenGlobalInstancesCtor( ) @@ -672,13 +673,18 @@ function astProcEnd( byval callrtexit as integer ) as integer res = (symbCheckLabels(symbGetProcSymbTbHead(parser.currproc)) = 0) if( res ) then - '' Destructor? + '' Complete Destructor? if( symbIsDestructor1( sym ) and enable_implicit_code ) then '' Call destructors, behind the exit label, so they'll '' always be called, even with early returns. hCallDtors( sym ) end if + '' Deleting Destructor? + if( symbIsDestructor0( sym ) and enable_implicit_code ) then + hCallDeleteDtor( sym ) + end if + '' update proc's breaks list, adding calls to destructors when needed if( n->block.breaklist.head <> NULL ) then res = astScopeUpdBreakList( n ) @@ -1272,6 +1278,26 @@ private sub hCallFieldDtors _ end sub +private sub hCallDeleteDtor _ + ( _ + byval proc as FBSYMBOL ptr _ + ) + + dim as FBSYMBOL ptr parent = any, dtor1 = any, this_ = any + dim as ASTNODE ptr thisptr = any, tree = any + + parent = symbGetNamespace( proc ) + dtor1 = symbGetCompDtor1( parent ) + if( dtor1 = NULL ) then + exit sub + end if + this_ = symbGetParamVar( symbGetProcHeadParam( proc ) ) + thisptr = astNewADDROF( astBuildVarField( this_ ) ) + tree = astBuildDeleteOp( AST_OP_DEL, thisptr ) + astAdd( tree ) + +end sub + private sub hCallBaseDtor _ ( _ byval parent as FBSYMBOL ptr, _ diff --git a/src/compiler/parser-proc.bas b/src/compiler/parser-proc.bas index 9bc470c262..ec47a82441 100644 --- a/src/compiler/parser-proc.bas +++ b/src/compiler/parser-proc.bas @@ -1466,6 +1466,21 @@ function cProcHeader _ cOverrideAttribute( proc ) end if + '' destructor? maybe implicitly declare the deleting destructor too + if( tk = FB_TK_DESTRUCTOR ) then + '' fbc won't generate any code that calls the deleting destructor + '' so don't create the deleting destructor unless we're binding to c++ + if( symbGetMangling( parent ) = FB_MANGLING_CPP ) then + '' - inherit all the attribs from the declared destructor + '' except for the destructor type + dim dtor0 as FBSYMBOL ptr = symbPreAddProc( NULL ) + symbAddProcInstanceParam( parent, dtor0 ) + pattrib and= not FB_PROCATTRIB_DESTRUCTOR1 + pattrib or= FB_PROCATTRIB_DESTRUCTOR0 + dtor0 = symbAddCtor( dtor0, NULL, attrib, pattrib, mode ) + end if + end if + if( tk = FB_TK_PROPERTY ) then hSetUdtPropertyFlags( parent, is_indexed, is_get ) end if diff --git a/src/compiler/symb-comp.bas b/src/compiler/symb-comp.bas index ed26949bbf..8d7a845424 100644 --- a/src/compiler/symb-comp.bas +++ b/src/compiler/symb-comp.bas @@ -621,19 +621,30 @@ sub symbUdtDeclareDefaultMembers _ '' no default dtor explicitly defined? if( udt->udt.ext->dtor1 = NULL ) then + '' if we didn't have the complete dtor then we shouln't have the deleting dtor either + '' because there is no way to explicitly define the deleting dtor assert( udt->udt.ext->dtor0 = NULL ) '' Complete dtor default.dtor1 = hDeclareProc( udt, INVALID, FB_DATATYPE_INVALID, FB_SYMBATTRIB_NONE, FB_PROCATTRIB_DESTRUCTOR1 ) - '' Deleting dtor - default.dtor0 = hDeclareProc( udt, INVALID, FB_DATATYPE_INVALID, FB_SYMBATTRIB_NONE, FB_PROCATTRIB_DESTRUCTOR0 ) + if( symbGetMangling( udt ) = FB_MANGLING_CPP ) then + '' Deleting dtor + default.dtor0 = hDeclareProc( udt, INVALID, FB_DATATYPE_INVALID, FB_SYMBATTRIB_NONE, FB_PROCATTRIB_DESTRUCTOR0 ) + end if '' Don't allow the implicit dtor to override a FINAL dtor from the base symbProcCheckOverridden( default.dtor1, TRUE ) end if end if + if( symbGetMangling( udt ) = FB_MANGLING_CPP ) then + if( default.dtor0 = NULL ) then + '' deleting dtor will be implicitly declared if the complete dtor was explicitly declared + default.dtor0 = symbGetCompDtor0( udt ) + end if + end if + end sub '' Implement the implicit members declared by symbUdtDeclareDefaultMembers(), diff --git a/src/compiler/symb-proc.bas b/src/compiler/symb-proc.bas index aac18f9122..a0e812c9d5 100644 --- a/src/compiler/symb-proc.bas +++ b/src/compiler/symb-proc.bas @@ -741,7 +741,6 @@ private function hSetupProc _ FB_SYMBCLASS_PROC, NULL, id_alias, _ FB_DATATYPE_VOID, NULL, attrib, pattrib ) - '' ctor? if( (pattrib and FB_PROCATTRIB_CONSTRUCTOR) <> 0 ) then symbSetCompCtorHead( parent, proc ) @@ -753,9 +752,7 @@ private function hSetupProc _ '' deleting dtor else symbSetCompDtor0( parent, proc ) - end if - '' otherwise, try to overload else '' dtor? @@ -1612,7 +1609,7 @@ function symbFindCtorProc _ ) as FBSYMBOL ptr '' dtor? can't overload.. - if( symbIsDestructor1( ovl_head_proc ) ) then + if( symbIsDestructor1( ovl_head_proc ) or symbIsDestructor0( ovl_head_proc ) ) then return ovl_head_proc else return symbFindOverloadProc( ovl_head_proc, proc ) diff --git a/src/compiler/symb.bi b/src/compiler/symb.bi index c958c1443c..575141d23f 100644 --- a/src/compiler/symb.bi +++ b/src/compiler/symb.bi @@ -191,7 +191,7 @@ enum FB_PROCATTRIB FB_PROCATTRIB_OVERLOADED = &h00000001 '' PROCs / METHODs only FB_PROCATTRIB_METHOD = &h00000002 '' Non-STATIC UDT member procs, i.e. procs with implicit THIS ptr FB_PROCATTRIB_CONSTRUCTOR = &h00000004 '' methods only - FB_PROCATTRIB_DESTRUCTOR1 = &h00000008 '' methods only + FB_PROCATTRIB_DESTRUCTOR1 = &h00000008 '' methods only - complete destructor FB_PROCATTRIB_OPERATOR = &h00000010 '' methods only FB_PROCATTRIB_PROPERTY = &h00000020 '' methods only FB_PROCATTRIB_STATICLOCALS = &h00000040 '' PROCs only