Skip to content

Commit adc12dd

Browse files
committed
udt-wstring: allow UDT->wstring conversions in astNewCONV
- Cxxx() conversion functions will accept UDT as Z|WSTRING
1 parent da305e5 commit adc12dd

File tree

10 files changed

+382
-18
lines changed

10 files changed

+382
-18
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Version 1.07.0
1111
- 'TYPE udt EXTENDS Z|WSTRING' allowed to specify that UDT is a kind of Z|WSTRING
1212
- LTRIM/RTRIM/TRIM will accept UDT as Z|WSTRING
1313
- LCASE/UCASE will accept UDT as Z|WSTRING
14+
- Cxxx() conversion functions will accept UDT as Z|WSTRING
1415

1516
[fixed]
1617
- sf.net #881: C backend: support for varadic function parameters in gcc using __builtin_va_list type and related macros

src/compiler/ast-node-conv.bas

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ end function
285285
proc = symbFindCastOvlProc( to_dtype, to_subtype, node, @err_num )
286286
if( proc <> NULL ) then
287287
'' build a proc call
288-
return astBuildCall( proc, l )
288+
return astBuildCall( proc, node )
289289
else
290290
if( err_num <> FB_ERRMSG_OK ) then
291291
return NULL
@@ -295,7 +295,7 @@ end function
295295
#endmacro
296296

297297
'':::::
298-
function astTryConvertUdtToWstring( byref expr as ASTNODE ptr ) as integer
298+
function astTryOvlStringCONV( byref expr as ASTNODE ptr ) as integer
299299

300300
dim as FBSYMBOL ptr proc = any, sym = any
301301
dim as FB_ERRMSG err_num = any
@@ -318,8 +318,8 @@ function astTryConvertUdtToWstring( byref expr as ASTNODE ptr ) as integer
318318
'' can cast to z|wstring?
319319
proc = symbFindCastOvlProc( dtype, NULL, expr, @err_num )
320320
if( proc ) then
321-
'' full match?
322-
if( symbGetFullType( proc ) = dtype ) then
321+
'' same type?
322+
if( symbGetType( proc ) = dtype ) then
323323
expr = astBuildCall( proc, expr )
324324
return TRUE
325325
end if
@@ -386,6 +386,44 @@ function astNewCONV _
386386
end if
387387
end if
388388

389+
'' UDT? check if it is z|wstring?
390+
'' !!! TODO !!! make this block in to a function
391+
'' re-use in astNewOvlCONV()
392+
'' rewrite hDoGlobOpOverload() as astTry* function
393+
if( typeGet( ldtype ) = FB_DATATYPE_STRUCT ) then
394+
dim as FBSYMBOL ptr subtype = astGetSubtype( l )
395+
396+
if( symbGetUdtIsZstring( subtype ) or symbGetUdtIsWstring( subtype ) ) then
397+
dim as FBSYMBOL ptr proc = NULL
398+
dim as FB_ERRMSG err_num = any
399+
400+
'' check exact casts
401+
proc = symbFindCastOvlProc( to_dtype, to_subtype, l, @err_num, TRUE )
402+
if( proc <> NULL ) then
403+
'' build a proc call
404+
return astBuildCall( proc, l )
405+
end if
406+
407+
'' check exact string pointer casts
408+
if( symbGetUdtIsZstring( subtype ) ) then
409+
proc = symbFindCastOvlProc( typeAddrof( FB_DATATYPE_CHAR ), NULL, l, @err_num, TRUE )
410+
elseif( symbGetUdtIsWstring( subtype ) ) then
411+
proc = symbFindCastOvlProc( typeAddrof( FB_DATATYPE_WCHAR ), NULL, l, @err_num, TRUE )
412+
end if
413+
if( proc <> NULL ) then
414+
'' build a proc call
415+
return astBuildCall( proc, l )
416+
end if
417+
418+
'' strings? convert.
419+
if( options and AST_CONVOPT_CHECKSTR ) then
420+
if( astTryOvlStringCONV( l ) ) then
421+
ldtype = astGetFullType( l )
422+
end if
423+
end if
424+
end if
425+
end if
426+
389427
'' try casting op overloading
390428
hDoGlobOpOverload( to_dtype, to_subtype, l )
391429

src/compiler/ast.bi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ enum AST_CONVOPT
536536
AST_CONVOPT_DONTWARNFUNCPTR = &h20
537537
end enum
538538

539-
declare function astTryConvertUdtToWstring( byref expr as ASTNODE ptr ) as integer
539+
declare function astTryOvlStringCONV( byref expr as ASTNODE ptr ) as integer
540540

541541
declare function astNewCONV _
542542
( _

src/compiler/rtl-string.bas

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3526,9 +3526,9 @@ function rtlStrTrim _
35263526

35273527
function = NULL
35283528

3529-
astTryConvertUdtToWstring( nd_text )
3529+
astTryOvlStringCONV( nd_text )
35303530
if( nd_pattern ) then
3531-
astTryConvertUdtToWstring( nd_pattern )
3531+
astTryOvlStringCONV( nd_pattern )
35323532
end if
35333533

35343534
dtype = astGetDataType( nd_text )
@@ -3584,9 +3584,9 @@ function rtlStrRTrim _
35843584

35853585
function = NULL
35863586

3587-
astTryConvertUdtToWstring( nd_text )
3587+
astTryOvlStringCONV( nd_text )
35883588
if( nd_pattern ) then
3589-
astTryConvertUdtToWstring( nd_pattern )
3589+
astTryOvlStringCONV( nd_pattern )
35903590
end if
35913591

35923592
dtype = astGetDataType( nd_text )
@@ -3642,9 +3642,9 @@ function rtlStrLTrim _
36423642

36433643
function = NULL
36443644

3645-
astTryConvertUdtToWstring( nd_text )
3645+
astTryOvlStringCONV( nd_text )
36463646
if( nd_pattern ) then
3647-
astTryConvertUdtToWstring( nd_pattern )
3647+
astTryOvlStringCONV( nd_pattern )
36483648
end if
36493649

36503650
dtype = astGetDataType( nd_text )
@@ -3791,7 +3791,7 @@ function rtlStrCase _
37913791
end if
37923792
end if
37933793

3794-
astTryConvertUdtToWstring( expr )
3794+
astTryOvlStringCONV( expr )
37953795

37963796
if( is_lcase ) then
37973797
if( astGetDataType( expr ) = FB_DATATYPE_WCHAR ) then

src/compiler/symb-proc.bas

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2366,7 +2366,8 @@ private function hCheckCastOvl _
23662366
( _
23672367
byval proc as FBSYMBOL ptr, _
23682368
byval to_dtype as integer, _
2369-
byval to_subtype as FBSYMBOL ptr _
2369+
byval to_subtype as FBSYMBOL ptr, _
2370+
byval is_explicit as integer = FALSE _
23702371
) as FB_OVLPROC_MATCH_SCORE
23712372

23722373
dim as integer proc_dtype = any
@@ -2395,6 +2396,9 @@ private function hCheckCastOvl _
23952396
end if
23962397

23972398
'' different types..
2399+
if( is_explicit ) then
2400+
return FB_OVLPROC_NO_MATCH
2401+
end if
23982402

23992403
select case typeGet( proc_dtype )
24002404
'' UDT or enum? can't be different (this is the last resource,
@@ -2427,7 +2431,8 @@ function symbFindCastOvlProc _
24272431
byval to_dtype as integer, _
24282432
byval to_subtype as FBSYMBOL ptr, _
24292433
byval l as ASTNODE ptr, _
2430-
byval err_num as FB_ERRMSG ptr _
2434+
byval err_num as FB_ERRMSG ptr, _
2435+
byval is_explicit as integer = FALSE _
24312436
) as FBSYMBOL ptr
24322437

24332438
dim as FBSYMBOL ptr proc_head = any
@@ -2470,7 +2475,7 @@ function symbFindCastOvlProc _
24702475
proc = proc_head
24712476
do while( proc <> NULL )
24722477

2473-
matchscore = hCheckCastOvl( proc, to_dtype, to_subtype )
2478+
matchscore = hCheckCastOvl( proc, to_dtype, to_subtype, is_explicit )
24742479
if( matchscore > max_matchscore ) then
24752480
closest_proc = proc
24762481
max_matchscore = matchscore

src/compiler/symb.bi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,8 @@ declare function symbFindCastOvlProc _
978978
byval to_dtype as integer, _
979979
byval to_subtype as FBSYMBOL ptr, _
980980
byval expr as ASTNODE ptr, _
981-
byval err_num as FB_ERRMSG ptr _
981+
byval err_num as FB_ERRMSG ptr, _
982+
byval is_explicit as integer = FALSE _
982983
) as FBSYMBOL ptr
983984

984985
declare function symbFindCtorOvlProc _

tests/udt-wstring/conversion.bas

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#include "fbcunit.bi"
2+
#include once "uwstring-fixed.bi"
3+
#include once "chk-wstring.bi"
4+
5+
#define ustring UWSTRING_FIXED
6+
7+
SUITE( fbc_tests.udt_wstring_.conversion )
8+
9+
#macro check( datatype, func, value )
10+
11+
scope
12+
dim t as wstring * 50 = wstr( #value )
13+
dim u as ustring = t
14+
15+
#if #datatype = "double"
16+
CU_ASSERT_DOUBLE_EQUAL( func( t ), value, 0 )
17+
CU_ASSERT_DOUBLE_EQUAL( func( u ), value, 0 )
18+
CU_ASSERT_DOUBLE_EQUAL( func( t ), func( value ), 0 )
19+
CU_ASSERT_DOUBLE_EQUAL( func( u ), func( value ), 0 )
20+
CU_ASSERT_EQUAL( func( t ), func( u ) )
21+
#elseif #datatype = "single"
22+
CU_ASSERT_SINGLE_APPROX( func( t ), value, 0 )
23+
CU_ASSERT_SINGLE_APPROX( func( u ), value, 0 )
24+
CU_ASSERT_SINGLE_APPROX( func( t ), func( value ), 0 )
25+
CU_ASSERT_SINGLE_APPROX( func( u ), func( value ), 0 )
26+
CU_ASSERT_EQUAL( func( t ), func( u ) )
27+
#else
28+
CU_ASSERT_EQUAL( func( t ), value )
29+
CU_ASSERT_EQUAL( func( u ), value )
30+
CU_ASSERT_EQUAL( func( t ), func( value ) )
31+
CU_ASSERT_EQUAL( func( u ), func( value ) )
32+
CU_ASSERT_EQUAL( func( t ), func( u ) )
33+
#endif
34+
35+
end scope
36+
37+
#endmacro
38+
39+
TEST( cbool_ )
40+
check( boolean, cbool, false )
41+
check( boolean, cbool, true )
42+
END_TEST
43+
44+
TEST( cbyte_ )
45+
check( byte, cbyte, -128 )
46+
check( byte, cbyte, -1 )
47+
check( byte, cbyte, 0 )
48+
check( byte, cbyte, 127 )
49+
END_TEST
50+
51+
TEST( cubyte_ )
52+
check( ubyte, cubyte, 0 )
53+
check( ubyte, cubyte, 127 )
54+
check( ubyte, cubyte, 128 )
55+
check( ubyte, cubyte, 255 )
56+
END_TEST
57+
58+
TEST( cshort_ )
59+
check( short, cshort, -32768 )
60+
check( short, cshort, -1 )
61+
check( short, cshort, 0 )
62+
check( short, cshort, 32767 )
63+
END_TEST
64+
65+
TEST( cushort_ )
66+
check( ushort, cushort, 0 )
67+
check( ushort, cushort, 32767 )
68+
check( ushort, cushort, 32768 )
69+
check( ushort, cushort, 65535 )
70+
END_TEST
71+
72+
TEST( clng_ )
73+
check( long, clng, -2147483648 )
74+
check( long, clng, -1 )
75+
check( long, clng, 0 )
76+
check( long, clng, 2147483647 )
77+
END_TEST
78+
79+
TEST( culng_ )
80+
check( ulong, culng, 0 )
81+
check( ulong, culng, 2147483647 )
82+
check( ulong, culng, 2147483648 )
83+
check( ulong, culng, 4294967295 )
84+
END_TEST
85+
86+
87+
#if sizeof(integer) = 4
88+
TEST( cint_ )
89+
check( integer, cint, -2147483648 )
90+
check( integer, cint, -1 )
91+
check( integer, cint, 0 )
92+
check( integer, cint, 2147483647 )
93+
END_TEST
94+
95+
TEST( cuint_ )
96+
check( uinteger, cuint, 0 )
97+
check( uinteger, cuint, 2147483647 )
98+
check( uinteger, cuint, 2147483648 )
99+
check( uinteger, cuint, 4294967295 )
100+
END_TEST
101+
#else
102+
TEST( cint_ )
103+
check( integer, cint, -9223372036854775808ll )
104+
check( integer, cint, -1 )
105+
check( integer, cint, 0 )
106+
check( integer, cint, 9223372036854775807ll )
107+
END_TEST
108+
109+
TEST( cuint_ )
110+
check( uinteger, cuint, 0 )
111+
check( uinteger, cuint, 9223372036854775807 )
112+
check( uinteger, cuint, 9223372036854775808 )
113+
check( uinteger, cuint, 18446744073709551615 )
114+
END_TEST
115+
#endif
116+
117+
TEST( clngint_ )
118+
check( longint, clngint, -9223372036854775808 )
119+
check( longint, clngint, -1 )
120+
check( longint, clngint, 0 )
121+
check( longint, clngint, 9223372036854775807 )
122+
END_TEST
123+
124+
TEST( culngint_ )
125+
check( ulongint, culngint, 0 )
126+
check( ulongint, culngint, 9223372036854775807 )
127+
check( ulongint, culngint, 9223372036854775808 )
128+
check( ulongint, culngint, 18446744073709551615 )
129+
END_TEST
130+
131+
TEST( csng_ )
132+
check( single, csng, 1.1754943508e-38! )
133+
check( single, csng, 3.4028234664e+38! )
134+
check( single, csng, 0.9999999404! )
135+
check( single, csng, 1.0000001192! )
136+
check( single, csng, -1.5! )
137+
check( single, csng, -1! )
138+
check( single, csng, -0.5! )
139+
check( single, csng, 0! )
140+
check( single, csng, 0.5! )
141+
check( single, csng, 1! )
142+
check( single, csng, 1.5! )
143+
check( single, csng, +1! )
144+
END_TEST
145+
146+
TEST( cdbl_ )
147+
check( double, cdbl, 2.2250738585072014d-308# )
148+
check( double, cdbl, 1.7976931348623157d+308# )
149+
check( double, cdbl, -1.5# )
150+
check( double, cdbl, -1# )
151+
check( double, cdbl, -0.5# )
152+
check( double, cdbl, 0# )
153+
check( double, cdbl, 0.5# )
154+
check( double, cdbl, 1# )
155+
check( double, cdbl, 1.5# )
156+
check( double, cdbl, +1# )
157+
END_TEST
158+
159+
END_SUITE
160+

tests/udt-wstring/uwstring-fixed.bas

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ constructor UWSTRING_FIXED( byval s as const zstring const ptr )
1919
end constructor
2020

2121
''
22-
operator UWSTRING_FIXED.Cast() byref as wstring
22+
operator UWSTRING_FIXED.Cast() byref as const wstring
2323
operator = *cast(wstring ptr, @_data)
2424
end operator
2525

tests/udt-wstring/uwstring-fixed.bi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ type UWSTRING_FIXED extends wstring
1111
declare constructor()
1212
declare constructor( byval rhs as const wstring const ptr )
1313
declare constructor( byval rhs as const zstring const ptr )
14-
declare operator cast() byref as wstring
14+
declare operator cast() byref as const wstring
1515
declare const function length() as integer
1616

1717
end type

0 commit comments

Comments
 (0)