Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ Version 1.06.0
- #883: when mapping 32 & 64 bit functions for PALETTE [GET] USING, check the data type pointed to and choose one of LONG PTR, LONGINT PTR, INTEGER PTR
- #866: fbc was throwing lexer errors in comments stating with $. Comments are lexed for directives; allow suffixes in comments
- #858: C backend: fix internal structure size mismatch due to wrong padding when nesting packed structures
- C backend: fix array descriptor mangling to avoid naming conflicts where array data types differ only by const
- #823: Function overload resolution for [const] array() and passing non-const array argument to const array parameter


Version 1.05.0
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/parser-expr-variable.bas
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ private function hFieldAccess _
'' Dynamic array field; access the descriptor field (same offset)
desc = symbGetArrayDescriptor( fld )
varexpr = astNewBOP( AST_OP_ADD, varexpr, offsetexpr )
varexpr = astNewCONV( typeAddrOf( symbGetFullType( desc ) ), symbGetSubtype( desc ), varexpr, AST_CONVOPT_DONTCHKPTR )
varexpr = astNewCONV( typeAddrOf( symbGetFullType( desc ) ), symbGetSubtype( desc ), varexpr, AST_CONVOPT_DONTCHKPTR or AST_CONVOPT_DONTWARNCONST )

tree = NULL
if( astHasSideFx( varexpr ) ) then
Expand All @@ -190,7 +190,7 @@ private function hFieldAccess _

'' *cptr( dtype ptr, var->descriptor.data + index )
varexpr = astNewBOP( AST_OP_ADD, varexpr, astNewCONSTi( symb.fbarray_data ) )
varexpr = astNewCONV( typeMultAddrOf( dtype, 2 ), subtype, varexpr, AST_CONVOPT_DONTCHKPTR )
varexpr = astNewCONV( typeMultAddrOf( dtype, 2 ), subtype, varexpr, AST_CONVOPT_DONTCHKPTR or AST_CONVOPT_DONTWARNCONST )
varexpr = astNewDEREF( varexpr )
varexpr = astNewBOP( AST_OP_ADD, varexpr, indexexpr )
varexpr = astNewDEREF( varexpr )
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/rtl-array.bas
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@
NULL, FB_RTL_OPT_NONE, _
2, _
{ _
( FB_DATATYPE_VOID, FB_PARAMMODE_BYDESC, FALSE ), _
( typeSetIsConst( FB_DATATYPE_VOID ), FB_PARAMMODE_BYDESC, FALSE ), _
( typeSetIsConst( FB_DATATYPE_INTEGER ), FB_PARAMMODE_BYVAL, FALSE ) _
} _
), _
Expand All @@ -224,7 +224,7 @@
NULL, FB_RTL_OPT_NONE, _
2, _
{ _
( FB_DATATYPE_VOID, FB_PARAMMODE_BYDESC, FALSE ), _
( typeSetIsConst( FB_DATATYPE_VOID ), FB_PARAMMODE_BYDESC, FALSE ), _
( typeSetIsConst( FB_DATATYPE_INTEGER ), FB_PARAMMODE_BYVAL, FALSE ) _
} _
), _
Expand Down
49 changes: 23 additions & 26 deletions src/compiler/symb-mangling.bas
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ private sub hMangleUdtId( byref mangled as string, byval sym as FBSYMBOL ptr )
mangled += "I" '' begin of template argument list

symbGetDescTypeArrayDtype( sym, arraydtype, arraysubtype )
symbMangleType( mangled, arraydtype, arraysubtype )
symbMangleType( mangled, arraydtype, arraysubtype, FB_MANGLEOPT_KEEPTOPCONST )

mangled += "E" '' end of template argument list
end if
Expand Down Expand Up @@ -429,7 +429,8 @@ sub symbMangleType _
( _
byref mangled as string, _
byval dtype as integer, _
byval subtype as FBSYMBOL ptr _
byval subtype as FBSYMBOL ptr, _
byval options as FB_MANGLEOPT = FB_MANGLEOPT_NONE _
)

dim as FBSYMBOL ptr ns = any
Expand All @@ -453,36 +454,17 @@ sub symbMangleType _

'' reference?
if( typeIsRef( dtype ) ) then
'' const?
if( typeIsConst( dtype ) ) then
mangled += "RK"
else
mangled + = "R"
end if

symbMangleType( mangled, typeUnsetIsRef( dtype ), subtype )

hAbbrevAdd( dtype, subtype )
exit sub
end if

'' pointer? (must be checked/emitted before CONST)
if( typeIsPtr( dtype ) ) then
'' const?
if( typeIsConstAt( dtype, 1 ) ) then
mangled += "PK"
else
mangled += "P"
end if
mangled += "R"

symbMangleType( mangled, typeDeref( dtype ), subtype )
symbMangleType( mangled, typeUnsetIsRef( dtype ), subtype, FB_MANGLEOPT_KEEPTOPCONST )

hAbbrevAdd( dtype, subtype )
exit sub
end if

'' const?
if( typeGetConstMask( dtype ) ) then
if( typeIsConst( dtype ) ) then

'' The type has some CONST bits. For C++ mangling we remove the
'' toplevel one and recursively mangle the rest of the type.
''
Expand All @@ -491,12 +473,27 @@ sub symbMangleType _
'' difference. It's not allowed to have overloads that differ
'' only in BYVAL CONSTness. The CONST only matters if it's a
'' pointer or BYREF type.

if( (options and FB_MANGLEOPT_KEEPTOPCONST) <> 0 ) then
mangled += "K"
end if

symbMangleType( mangled, typeUnsetIsConst( dtype ), subtype )

hAbbrevAdd( dtype, subtype )
exit sub
end if

'' pointer?
if( typeIsPtr( dtype ) ) then
mangled += "P"

symbMangleType( mangled, typeDeref( dtype ), subtype, FB_MANGLEOPT_KEEPTOPCONST )

hAbbrevAdd( dtype, subtype )
exit sub
end if

''
'' Plain type without reference/pointer/const bits
''
Expand Down Expand Up @@ -573,7 +570,7 @@ sub symbMangleParam( byref mangled as string, byval param as FBSYMBOL ptr )
'' Mangling array params as 'FBARRAY[1-8]<dtype>&' because
'' that's what they really are from C++'s point of view.
assert( symbIsDescriptor( param->param.bydescrealsubtype ) )
symbMangleType( mangled, typeSetIsRef( FB_DATATYPE_STRUCT ), param->param.bydescrealsubtype )
symbMangleType( mangled, typeSetIsRef( FB_DATATYPE_STRUCT ), param->param.bydescrealsubtype, FB_MANGLEOPT_KEEPTOPCONST )

case FB_PARAMMODE_VARARG
mangled += "z"
Expand Down
17 changes: 8 additions & 9 deletions src/compiler/symb-proc.bas
Original file line number Diff line number Diff line change
Expand Up @@ -1883,19 +1883,18 @@ private function hCheckOvlParam _
return FB_OVLPROC_NO_MATCH
end if

'' not a full match?
if( param_dtype <> arg_dtype ) then
return FB_OVLPROC_NO_MATCH
end if

if( param_subtype <> arg_subtype ) then
return FB_OVLPROC_NO_MATCH
end if
var match = typeCalcMatch( param_dtype, param_subtype, symbGetParamMode( param ), arg_dtype, arg_subtype )

'' not same type?
if( match < FB_OVLPROC_TYPEMATCH ) then
return FB_OVLPROC_NO_MATCH
end if

assert( astIsVAR( arg_expr ) or astIsFIELD( arg_expr ) )
array = arg_expr->sym
assert( symbIsArray( array ) )


'' If the BYDESC parameter has unknown dimensions, any array can be passed.
'' Otherwise, only arrays with unknown or matching dimensions can be passed.
if( param->param.bydescdimensions > 0 ) then
Expand All @@ -1905,7 +1904,7 @@ private function hCheckOvlParam _
end if
end if

return FB_OVLPROC_FULLMATCH
return match

'' byref param?
case FB_PARAMMODE_BYREF
Expand Down
7 changes: 4 additions & 3 deletions src/compiler/symb-var.bas
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ sub symbGetDescTypeArrayDtype _
fld = symbUdtGetFirstField( desctype )
assert( typeIsPtr( symbGetType( fld ) ) )

arraydtype = typeDeref( symbGetType( fld ) )
arraydtype = typeDeref( symbGetFullType( fld ) )
arraysubtype = fld->subtype

end sub
Expand Down Expand Up @@ -160,10 +160,11 @@ function symbAddArrayDescriptorType _
'' Some unique internal id that allows this descriptor type to be looked
'' up later when we need one with the same dimensions & array dtype
'' again. '$' prefix ensures that there are no collisions with user's
'' ids.
'' ids. Always keep the top-level const for array datatypes to avoid
'' conflicts between types differing only by const.
id = "$" + aliasid
id += "<"
symbMangleType( id, arraydtype, arraysubtype )
symbMangleType( id, arraydtype, arraysubtype, FB_MANGLEOPT_KEEPTOPCONST )
symbMangleResetAbbrev( )
id += ">"

Expand Down
9 changes: 8 additions & 1 deletion src/compiler/symb.bi
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,12 @@ enum FB_MANGLING
FB_MANGLING_PASCAL
end enum

''
enum FB_MANGLEOPT
FB_MANGLEOPT_NONE = 0 '' no special options
FB_MANGLEOPT_KEEPTOPCONST = 1 '' keep the top-level const when mangling
end enum

type FBSYMBOL_ as FBSYMBOL

#ifndef ASTNODE_
Expand Down Expand Up @@ -1747,7 +1753,8 @@ declare sub symbMangleType _
( _
byref mangled as string, _
byval dtype as integer, _
byval subtype as FBSYMBOL ptr _
byval subtype as FBSYMBOL ptr, _
byval options as FB_MANGLEOPT = FB_MANGLEOPT_NONE _
)
declare sub symbMangleParam( byref mangled as string, byval param as FBSYMBOL ptr )

Expand Down
94 changes: 94 additions & 0 deletions tests/cpp/cpp-mangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,98 @@ namespace cpp_mangle
return a;
}

/* byval const, pointer, reference */

double cpp_byval_const_double( const double a )
{
return a;
}

double cpp_byval_double_ptr( double* a )
{
return *a;
}

double cpp_byval_const_double_ptr( double const* a )
{
return *a;
}

double cpp_byval_double_const_ptr( double* const a )
{
return *a;
}

double cpp_byval_const_double_const_ptr( double const* const a )
{
return *a;
}

double cpp_byval_double_ptr_ptr( double** a )
{
return **a;
}

double cpp_byval_const_double_ptr_ptr( double const** a )
{
return **a;
}

double cpp_byval_double_const_ptr_ptr( double* const* a )
{
return **a;
}

double cpp_byval_double_ptr_const_ptr( double** const a )
{
return **a;
}

/* byval const, pointer, reference */

double cpp_byref_const_double( double const& a )
{
return a;
}

double cpp_byref_double_ptr( double*& a )
{
return *a;
}

double cpp_byref_const_double_ptr( double const*& a )
{
return *a;
}

double cpp_byref_double_const_ptr( double* const& a )
{
return *a;
}

double cpp_byref_const_double_const_ptr( double const* const& a )
{
return *a;
}

double cpp_byref_double_ptr_ptr( double**& a )
{
return **a;
}

double cpp_byref_const_double_ptr_ptr( double const**& a )
{
return **a;
}

double cpp_byref_double_const_ptr_ptr( double* const*& a )
{
return **a;
}

double cpp_byref_double_ptr_const_ptr( double** const& a )
{
return **a;
}

}
54 changes: 54 additions & 0 deletions tests/cpp/fbc-mangle.bas
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,26 @@ namespace cpp_mangle
declare function cpp_byref_ulonglongint( byref a as unsigned longint ) as unsigned longint
declare function cpp_byref_slonglongint( byref a as longint ) as longint

declare function cpp_byval_const_double( byval a as const double ) as double
declare function cpp_byval_double_ptr( byval a as double ptr ) as double
declare function cpp_byval_const_double_ptr( byval a as const double ptr ) as double
declare function cpp_byval_double_const_ptr( byval a as double const ptr ) as double
declare function cpp_byval_const_double_const_ptr( byval a as const double const ptr ) as double
declare function cpp_byval_double_ptr_ptr( byval a as double ptr ptr ) as double
declare function cpp_byval_const_double_ptr_ptr( byval a as const double ptr ptr ) as double
declare function cpp_byval_double_const_ptr_ptr( byval a as double const ptr ptr ) as double
declare function cpp_byval_double_ptr_const_ptr( byval a as double ptr const ptr ) as double

declare function cpp_byref_const_double( byref a as const double ) as double
declare function cpp_byref_double_ptr( byref a as double ptr ) as double
declare function cpp_byref_const_double_ptr( byref a as const double ptr ) as double
declare function cpp_byref_double_const_ptr( byref a as double const ptr ) as double
declare function cpp_byref_const_double_const_ptr( byref a as const double const ptr ) as double
declare function cpp_byref_double_ptr_ptr( byref a as double ptr ptr ) as double
declare function cpp_byref_const_double_ptr_ptr( byref a as const double ptr ptr ) as double
declare function cpp_byref_double_const_ptr_ptr( byref a as double const ptr ptr ) as double
declare function cpp_byref_double_ptr_const_ptr( byref a as double ptr const ptr ) as double

end namespace

end extern
Expand Down Expand Up @@ -209,3 +229,37 @@ scope
ASSERT( cpp_byref_slonglongint(sll) = &h7fffffffffffffff )

end scope

scope
'' [const] pointers and references

dim d as double = 1
dim dp as double ptr = @d
dim dpp as double ptr ptr = @dp

ASSERT( cpp_byval_double( d ) = d )
ASSERT( cpp_byval_const_double( d ) = d )
ASSERT( cpp_byval_double_ptr( dp ) = d )
ASSERT( cpp_byval_const_double_ptr( dp ) = d )
ASSERT( cpp_byval_double_const_ptr( dp ) = d )
ASSERT( cpp_byval_const_double_const_ptr( dp ) = d )

ASSERT( cpp_byval_double_ptr_ptr( dpp ) = d )
ASSERT( cpp_byval_const_double_ptr_ptr( dpp ) = d )
ASSERT( cpp_byval_double_const_ptr_ptr( dpp ) = d )
ASSERT( cpp_byval_double_ptr_const_ptr( dpp ) = d )

ASSERT( cpp_byref_double( d ) = d )
ASSERT( cpp_byref_const_double( d ) = d )
ASSERT( cpp_byref_double_ptr( dp ) = d )
ASSERT( cpp_byref_const_double_ptr( dp ) = d )
ASSERT( cpp_byref_double_const_ptr( dp ) = d )
ASSERT( cpp_byref_const_double_const_ptr( dp ) = d )

ASSERT( cpp_byref_double_ptr_ptr( dpp ) = d )
ASSERT( cpp_byref_const_double_ptr_ptr( dpp ) = d )
ASSERT( cpp_byref_double_const_ptr_ptr( dpp ) = d )
ASSERT( cpp_byref_double_ptr_const_ptr( dpp ) = d )


end scope
Loading