Skip to content

Commit 8dade18

Browse files
committed
Add mangling modifier 'as long|ulong alias "long"' for Win64
- Name mangling of Long parameters on Win64 are mangled to C++ int by default - Add syntax to mangle to a C++ long with a modifier in the form 'as [u]long alias "long"' - The data type size is still 32bit but allows calling external C++ library expecting a C++ long.
1 parent d249ff8 commit 8dade18

File tree

5 files changed

+100
-42
lines changed

5 files changed

+100
-42
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Version 1.06.0
1010
- WSTRING can be a return type, but only for prototypes (DECLARE) and function pointers, this allows getting PROCPTR() of all fb built-in run time functions
1111

1212
[added]
13+
- Name mangling of Long parameters on Win64 are mangled to C++ int by default and to C++ long with a modifier in the form 'as [u]long alias "long"'. The data type size is still 32bit but allows calling external C++ library expecting a C++ long.
1314
- -noobjinfo option to disable the writing/reading of compile-time library and other linking options from/to .o and .a files. This also disables the use of fbextra.x (the supplemental linker script) for discarding the .fbctinf sections, which is useful when using the gold linker that doesn't support this kind of linker script.
1415
- Linux console Inkey() now recognizes F11 and F12
1516
- 2D render through OpenGL on Windows and Linux via screencontrol (angros47)

src/compiler/parser-decl-symbtype.bas

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,38 @@ function hIntegerTypeFromBitSize _
393393

394394
end function
395395

396+
private function cMangleModifier _
397+
( _
398+
) as integer
399+
400+
static as zstring * FB_MAXNAMELEN+1 aliasid
401+
function = FALSE
402+
403+
'' ALIAS?
404+
if( lexGetToken( ) = FB_TK_ALIAS ) then
405+
lexSkipToken( )
406+
407+
'' "long"
408+
if( lexGetClass( ) = FB_TKCLASS_STRLITERAL ) then
409+
aliasid = *lexGetText( )
410+
lexSkipToken( )
411+
412+
select case lcase( aliasid )
413+
case "long"
414+
function = fbIs64bit( ) and ((env.target.options and FB_TARGETOPT_UNIX) = 0)
415+
case ""
416+
errReport( FB_ERRMSG_EMPTYALIASSTRING )
417+
case else
418+
errReport( FB_ERRMSG_SYNTAXERROR )
419+
end select
420+
else
421+
errReport( FB_ERRMSG_SYNTAXERROR )
422+
end if
423+
424+
end if
425+
426+
end function
427+
396428
'':::::
397429
''SymbolType = CONST? UNSIGNED? (
398430
'' ANY
@@ -528,10 +560,16 @@ function cSymbolType _
528560
case FB_TK_LONG
529561
lexSkipToken( )
530562
dtype = FB_DATATYPE_LONG
563+
if( cMangleModifier() ) then
564+
dtype = typeSetMangleDt( dtype, FB_DATATYPE_INTEGER )
565+
end if
531566

532567
case FB_TK_ULONG
533568
lexSkipToken( )
534569
dtype = FB_DATATYPE_ULONG
570+
if( cMangleModifier() ) then
571+
dtype = typeSetMangleDt( dtype, FB_DATATYPE_UINT )
572+
end if
535573

536574
case FB_TK_LONGINT
537575
lexSkipToken( )
@@ -668,7 +706,11 @@ function cSymbolType _
668706
dtype = FB_DATATYPE_UINT
669707

670708
case FB_DATATYPE_LONG
671-
dtype = FB_DATATYPE_ULONG
709+
if( typeIsMangleDt( dtype ) ) then
710+
dtype = typeSetMangleDt( FB_DATATYPE_ULONG, FB_DATATYPE_UINT )
711+
else
712+
dtype = FB_DATATYPE_ULONG
713+
end if
672714

673715
case FB_DATATYPE_LONGINT
674716
dtype = FB_DATATYPE_ULONGINT

src/compiler/symb-mangling.bas

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ function hMangleBuiltInType _
319319
byref add_abbrev as integer _
320320
) as zstring ptr
321321

322-
assert( dtype = typeGetDtOnly( dtype ) )
322+
assert( dtype = (typeGetDtOnly( dtype ) or (dtype and FB_DT_MANGLEMASK)) )
323323

324324
''
325325
'' Plain unqualified C++ built-in types are not considered for abbreviation.
@@ -357,14 +357,31 @@ function hMangleBuiltInType _
357357
'' 64bit fbc it was reversed, allowing the same FB and C++ code to work
358358
'' together on both 32bit and 64bit.
359359
''
360+
'' - as special expection for windows 64bit, to get a 32bit type that will
361+
'' mangle to C++ long, allow 'as [u]long alias "[u]long"' declarations.
362+
'' The size of LONG/ULONG does not change, it's 32bit, only the mangling,
363+
'' so fbc programs can call C++ code requiring 'long int' arguments.
364+
360365
if( fbIs64bit( ) and ((env.target.options and FB_TARGETOPT_UNIX) = 0) ) then
361366
'' Windows 64bit
362-
'' Itanium C++ ABI compatible mangling of non-C++ built-in types (vendor extended types):
363-
'' u <length-of-id> <id>
364-
select case( dtype )
365-
case FB_DATATYPE_INTEGER : add_abbrev = TRUE : return @"u7INTEGER" '' seems like a good choice
366-
case FB_DATATYPE_UINT : add_abbrev = TRUE : return @"u8UINTEGER"
367-
end select
367+
368+
'' check for remapping of dtype mangling
369+
if( typeIsMangleDt( dtype ) ) then
370+
dtype = typeGetMangleDt( dtype )
371+
'' Windows 64bit
372+
select case( dtype )
373+
case FB_DATATYPE_INTEGER : return @"l" '' long
374+
case FB_DATATYPE_UINT : return @"m" '' unsigned long
375+
end select
376+
else
377+
'' Itanium C++ ABI compatible mangling of non-C++ built-in types (vendor extended types):
378+
'' u <length-of-id> <id>
379+
select case( dtype )
380+
case FB_DATATYPE_INTEGER : add_abbrev = TRUE : return @"u7INTEGER" '' seems like a good choice
381+
case FB_DATATYPE_UINT : add_abbrev = TRUE : return @"u8UINTEGER"
382+
end select
383+
end if
384+
368385
else
369386
'' 32bit, Unix 64bit
370387
select case( dtype )
@@ -480,7 +497,7 @@ sub symbMangleType _
480497
''
481498
'' Plain type without reference/pointer/const bits
482499
''
483-
assert( dtype = typeGetDtOnly( dtype ) )
500+
assert( dtype = (typeGetDtOnly( dtype ) or (dtype and FB_DT_MANGLEMASK)) )
484501

485502
select case( dtype )
486503
case FB_DATATYPE_STRUCT, FB_DATATYPE_ENUM

src/compiler/symb.bi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,16 @@ const FB_DT_TYPEMASK = &b00000000000000000000000000011111 '' max 32 built-in d
5757
const FB_DT_PTRMASK = &b00000000000000000000000111100000 '' level of pointer indirection
5858
const FB_DT_CONSTMASK = &b00000000000000111111111000000000 '' PTRLEVELS + 1 bit-masks
5959
const FB_DATATYPE_REFERENCE = &b00000000000010000000000000000000 '' used for mangling BYREF parameters
60+
const FB_DT_MANGLEMASK = &b00000001111100000000000000000000 '' used to modify mangling for builtin types
6061
const FB_DATATYPE_INVALID = &b10000000000000000000000000000000
6162

6263
const FB_DT_PTRLEVELS = 8 '' max levels of pointer indirection
6364

6465
const FB_DT_PTRPOS = 5
6566
const FB_DT_CONSTPOS = FB_DT_PTRPOS + 4
6667

68+
const FB_DT_MANGLEPOS = 20
69+
6770
enum FB_OVLPROC_MATCH_SCORE
6871
FB_OVLPROC_NO_MATCH = 0
6972
FB_OVLPROC_LOWEST_MATCH = 1
@@ -2492,6 +2495,10 @@ declare sub symbProcRecalcRealType( byval proc as FBSYMBOL ptr )
24922495
#define typeSetIsRef( dt ) (dt or FB_DATATYPE_REFERENCE)
24932496
#define typeUnsetIsRef( dt ) (dt and not FB_DATATYPE_REFERENCE)
24942497

2498+
#define typeIsMangleDt( dt ) (((dt and FB_DT_MANGLEMASK) <> 0))
2499+
#define typeGetMangleDt( dt ) ((dt and FB_DT_MANGLEMASK) shr FB_DT_MANGLEPOS)
2500+
#define typeSetMangleDt( dt, mangle_dt ) ((dt and not FB_DT_MANGLEMASK) or ((mangle_dt shl FB_DT_MANGLEPOS) and FB_DT_MANGLEMASK ))
2501+
24952502
declare sub symbForEachGlobal _
24962503
( _
24972504
byval symclass as integer, _

tests/cpp/fbc-mangle.bas

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,23 @@
33
'' test mapping of basic data types between fbc and g++
44
'' with c++ name mangling
55

6-
type cxxint as long
7-
type cxxlongint as integer
8-
/' !!!
9-
cxxlongint will currently fail on win64, fbc custom mangles INTEGER and there is
10-
no other data type that will return the "m" and "l" suffixes for c's long int.
11-
The specific test that fails is skipped over using and and #ifdef. To have a basic
12-
datatype on win64 that can map to g++ long int, one possible solution would be
13-
change the overloading allowed for the c++ mangled names onlym what would have to
14-
be added to fbc.
15-
'/
6+
'' by default, fbc's Long/ULong data type maps to c's int type, and since
7+
'' Integer/Uinteger are meant to be (consistently) 64bits in fbc-64bit,
8+
'' there is no other type that (by default) that can map to c's long int,
9+
'' which is 32bit even on Win64.
10+
11+
'' So, in Win64, to allow calling an external library that needs a 'long int'
12+
'' parameter there is the following, non-portable mangling modifier. It is
13+
'' ignored for all targets except for Win64
14+
15+
#if defined(__FB_64BIT__) and not defined(__FB_UNIX__)
16+
'' map fbc's 32bit 'LONG' type to Win64's 32bit 'long' type
17+
type cxxlongint as long alias "long"
18+
#else
19+
'' otherwise, integer is used on 32bit and Unix-64bit consistently to map
20+
'' fbc's 32/64bit 'INTEGER' type to the target 32/64bit 'long int' type
21+
type cxxlongint as integer
22+
#endif
1623

1724
extern "c++"
1825

@@ -37,10 +44,10 @@ namespace cpp_mangle
3744
declare function cpp_byref_ushort( byref a as unsigned short ) as unsigned short
3845
declare function cpp_byref_sshort( byref a as short ) as short
3946

40-
declare function cpp_byval_uint( byval a as unsigned cxxint ) as unsigned cxxint
41-
declare function cpp_byval_sint( byval a as cxxint ) as cxxint
42-
declare function cpp_byref_uint( byref a as unsigned cxxint ) as unsigned cxxint
43-
declare function cpp_byref_sint( byref a as cxxint ) as cxxint
47+
declare function cpp_byval_uint( byval a as unsigned long ) as unsigned long
48+
declare function cpp_byval_sint( byval a as long ) as long
49+
declare function cpp_byref_uint( byref a as unsigned long ) as unsigned long
50+
declare function cpp_byref_sint( byref a as long ) as long
4451

4552
declare function cpp_byval_ulongint( byval a as unsigned cxxlongint ) as unsigned cxxlongint
4653
declare function cpp_byval_slongint( byval a as cxxlongint ) as cxxlongint
@@ -149,8 +156,8 @@ scope
149156
ASSERT( cpp_byval_uint(&h7fffffff) = &h7fffffff )
150157
ASSERT( cpp_byval_sint(&h7fffffff) = &h7fffffff )
151158

152-
dim ui as unsigned cxxint = 0
153-
dim si as cxxint = 0
159+
dim ui as unsigned long = 0
160+
dim si as long = 0
154161
ASSERT( cpp_byref_uint(ui) = 0 )
155162
ASSERT( cpp_byref_sint(si) = 0 )
156163
ui = &h7fffffff
@@ -160,24 +167,10 @@ scope
160167

161168
end scope
162169

163-
#ifndef ENABLE_CHECK_BUGS
164-
#define ENABLE_CHECK_BUGS 0
165-
#endif
166-
#if (not defined(__FB_64BIT__)) or defined(__FB_UNIX__) or (ENABLE_CHECK_BUGS=1)
167-
168-
#print see fbc/src/compiler/symb-mangling.bas:hMangleBuiltInType()
169-
#print possibly related: https://sourceforge.net/p/fbc/bugs/828/
170-
171-
/' !!! there is no name mangling on win64 that can
172-
map to g++ long int, only allow the test on
173-
32-bit or unix or if we explicitly enable
174-
bug checks
175-
'/
176-
177170
scope
178171

179172
'' c = signed|unsigned long int
180-
'' fb = [unsigned] long|integer
173+
'' fb = [unsigned] long alias "long"
181174

182175
ASSERT( cpp_byval_ulongint(0) = 0 )
183176
ASSERT( cpp_byval_slongint(0) = 0 )
@@ -195,8 +188,6 @@ scope
195188

196189
end scope
197190

198-
#endif
199-
200191
scope
201192

202193
'' c = signed|unsigned long long int

0 commit comments

Comments
 (0)