Skip to content

Commit 947a9f4

Browse files
committed
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)
1 parent 9317835 commit 947a9f4

File tree

6 files changed

+58
-8
lines changed

6 files changed

+58
-8
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Version 1.08.0
4646
- only write debug line information for statements and don't write comments / empty lines / directives for top level source code in assembly debug ouput
4747
- 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.
4848
- github #298: allow command line options passed to as, gcc, ld to be longer than 128 characters by using string types internally
49+
- sf.net #923: implicitly emit the deleting destrutor for extern "c++" mangling for better g++ ABI compatibility
4950

5051
[added]
5152
- extern "rtlib": respects the parent namespace, uses default fb calling convention and C style name mangling

src/compiler/ast-node-proc.bas

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ declare function hInitVptr _
3333
) as ASTNODE ptr
3434
declare sub hCallCtors( byval n as ASTNODE ptr, byval sym as FBSYMBOL ptr )
3535
declare sub hCallDtors( byval proc as FBSYMBOL ptr )
36+
declare sub hCallDeleteDtor( byval proc as FBSYMBOL ptr )
3637
declare sub hGenStaticInstancesDtors( byval proc as FBSYMBOL ptr )
3738
declare sub hGenGlobalInstancesCtor( )
3839

@@ -672,13 +673,18 @@ function astProcEnd( byval callrtexit as integer ) as integer
672673
res = (symbCheckLabels(symbGetProcSymbTbHead(parser.currproc)) = 0)
673674

674675
if( res ) then
675-
'' Destructor?
676+
'' Complete Destructor?
676677
if( symbIsDestructor1( sym ) and enable_implicit_code ) then
677678
'' Call destructors, behind the exit label, so they'll
678679
'' always be called, even with early returns.
679680
hCallDtors( sym )
680681
end if
681682

683+
'' Deleting Destructor?
684+
if( symbIsDestructor0( sym ) and enable_implicit_code ) then
685+
hCallDeleteDtor( sym )
686+
end if
687+
682688
'' update proc's breaks list, adding calls to destructors when needed
683689
if( n->block.breaklist.head <> NULL ) then
684690
res = astScopeUpdBreakList( n )
@@ -1272,6 +1278,26 @@ private sub hCallFieldDtors _
12721278

12731279
end sub
12741280

1281+
private sub hCallDeleteDtor _
1282+
( _
1283+
byval proc as FBSYMBOL ptr _
1284+
)
1285+
1286+
dim as FBSYMBOL ptr parent = any, dtor1 = any, this_ = any
1287+
dim as ASTNODE ptr thisptr = any, tree = any
1288+
1289+
parent = symbGetNamespace( proc )
1290+
dtor1 = symbGetCompDtor1( parent )
1291+
if( dtor1 = NULL ) then
1292+
exit sub
1293+
end if
1294+
this_ = symbGetParamVar( symbGetProcHeadParam( proc ) )
1295+
thisptr = astNewADDROF( astBuildVarField( this_ ) )
1296+
tree = astBuildDeleteOp( AST_OP_DEL, thisptr )
1297+
astAdd( tree )
1298+
1299+
end sub
1300+
12751301
private sub hCallBaseDtor _
12761302
( _
12771303
byval parent as FBSYMBOL ptr, _

src/compiler/parser-proc.bas

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,21 @@ function cProcHeader _
14661466
cOverrideAttribute( proc )
14671467
end if
14681468

1469+
'' destructor? maybe implicitly declare the deleting destructor too
1470+
if( tk = FB_TK_DESTRUCTOR ) then
1471+
'' fbc won't generate any code that calls the deleting destructor
1472+
'' so don't create the deleting destructor unless we're binding to c++
1473+
if( symbGetMangling( parent ) = FB_MANGLING_CPP ) then
1474+
'' - inherit all the attribs from the declared destructor
1475+
'' except for the destructor type
1476+
dim dtor0 as FBSYMBOL ptr = symbPreAddProc( NULL )
1477+
symbAddProcInstanceParam( parent, dtor0 )
1478+
pattrib and= not FB_PROCATTRIB_DESTRUCTOR1
1479+
pattrib or= FB_PROCATTRIB_DESTRUCTOR0
1480+
dtor0 = symbAddCtor( dtor0, NULL, attrib, pattrib, mode )
1481+
end if
1482+
end if
1483+
14691484
if( tk = FB_TK_PROPERTY ) then
14701485
hSetUdtPropertyFlags( parent, is_indexed, is_get )
14711486
end if

src/compiler/symb-comp.bas

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,19 +621,30 @@ sub symbUdtDeclareDefaultMembers _
621621
'' no default dtor explicitly defined?
622622
if( udt->udt.ext->dtor1 = NULL ) then
623623

624+
'' if we didn't have the complete dtor then we shouln't have the deleting dtor either
625+
'' because there is no way to explicitly define the deleting dtor
624626
assert( udt->udt.ext->dtor0 = NULL )
625627

626628
'' Complete dtor
627629
default.dtor1 = hDeclareProc( udt, INVALID, FB_DATATYPE_INVALID, FB_SYMBATTRIB_NONE, FB_PROCATTRIB_DESTRUCTOR1 )
628630

629-
'' Deleting dtor
630-
default.dtor0 = hDeclareProc( udt, INVALID, FB_DATATYPE_INVALID, FB_SYMBATTRIB_NONE, FB_PROCATTRIB_DESTRUCTOR0 )
631+
if( symbGetMangling( udt ) = FB_MANGLING_CPP ) then
632+
'' Deleting dtor
633+
default.dtor0 = hDeclareProc( udt, INVALID, FB_DATATYPE_INVALID, FB_SYMBATTRIB_NONE, FB_PROCATTRIB_DESTRUCTOR0 )
634+
end if
631635

632636
'' Don't allow the implicit dtor to override a FINAL dtor from the base
633637
symbProcCheckOverridden( default.dtor1, TRUE )
634638
end if
635639
end if
636640

641+
if( symbGetMangling( udt ) = FB_MANGLING_CPP ) then
642+
if( default.dtor0 = NULL ) then
643+
'' deleting dtor will be implicitly declared if the complete dtor was explicitly declared
644+
default.dtor0 = symbGetCompDtor0( udt )
645+
end if
646+
end if
647+
637648
end sub
638649

639650
'' Implement the implicit members declared by symbUdtDeclareDefaultMembers(),

src/compiler/symb-proc.bas

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,6 @@ private function hSetupProc _
741741
FB_SYMBCLASS_PROC, NULL, id_alias, _
742742
FB_DATATYPE_VOID, NULL, attrib, pattrib )
743743

744-
745744
'' ctor?
746745
if( (pattrib and FB_PROCATTRIB_CONSTRUCTOR) <> 0 ) then
747746
symbSetCompCtorHead( parent, proc )
@@ -753,9 +752,7 @@ private function hSetupProc _
753752
'' deleting dtor
754753
else
755754
symbSetCompDtor0( parent, proc )
756-
757755
end if
758-
759756
'' otherwise, try to overload
760757
else
761758
'' dtor?
@@ -1612,7 +1609,7 @@ function symbFindCtorProc _
16121609
) as FBSYMBOL ptr
16131610

16141611
'' dtor? can't overload..
1615-
if( symbIsDestructor1( ovl_head_proc ) ) then
1612+
if( symbIsDestructor1( ovl_head_proc ) or symbIsDestructor0( ovl_head_proc ) ) then
16161613
return ovl_head_proc
16171614
else
16181615
return symbFindOverloadProc( ovl_head_proc, proc )

src/compiler/symb.bi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ enum FB_PROCATTRIB
191191
FB_PROCATTRIB_OVERLOADED = &h00000001 '' PROCs / METHODs only
192192
FB_PROCATTRIB_METHOD = &h00000002 '' Non-STATIC UDT member procs, i.e. procs with implicit THIS ptr
193193
FB_PROCATTRIB_CONSTRUCTOR = &h00000004 '' methods only
194-
FB_PROCATTRIB_DESTRUCTOR1 = &h00000008 '' methods only
194+
FB_PROCATTRIB_DESTRUCTOR1 = &h00000008 '' methods only - complete destructor
195195
FB_PROCATTRIB_OPERATOR = &h00000010 '' methods only
196196
FB_PROCATTRIB_PROPERTY = &h00000020 '' methods only
197197
FB_PROCATTRIB_STATICLOCALS = &h00000040 '' PROCs only

0 commit comments

Comments
 (0)