mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-16 03:10:42 +01:00
compiler: change ShortString->(Some)String and AnsiString->(Some)String overload precedence both for variables and string constants, change unicode constant type from widestring to unicodestring (Delphi compatibility)
new ShortString->(Some)String precedence: ShortString, UTF8String, AnsiString, AnsiString(CodePage) and RawByteString, UnicodeString, WideString and other string types new AnsiString->(Some)String precedence: RawByteString, UTF8String, AnsiString, AnsiString(CodePage), UnicodeString, WideString, ShortString and other string types The new logic makes UTF8String more preferrable than other AnsiString types, AnsiString more preferrable than other AnsiStrings(codepage) and also makes UnicodeString more preferrable than WideString. git-svn-id: trunk@21057 -
This commit is contained in:
parent
9d1063f94c
commit
a26bc50ca6
@ -365,36 +365,10 @@ implementation
|
||||
stringdef :
|
||||
begin
|
||||
{ Constant string }
|
||||
if (fromtreetype=stringconstn) then
|
||||
begin
|
||||
if (tstringdef(def_from).stringtype=tstringdef(def_to).stringtype) and
|
||||
((tstringdef(def_from).stringtype<>st_ansistring) or
|
||||
(tstringdef(def_from).encoding=tstringdef(def_to).encoding)
|
||||
) then
|
||||
eq:=te_equal
|
||||
else
|
||||
begin
|
||||
doconv:=tc_string_2_string;
|
||||
if (tstringdef(def_from).stringtype = st_ansistring) and
|
||||
(tstringdef(def_to).stringtype = st_ansistring) then
|
||||
if (tstringdef(def_to).encoding=globals.CP_UTF8) then
|
||||
eq:=te_convert_l1
|
||||
else
|
||||
eq:=te_convert_l2
|
||||
else
|
||||
begin
|
||||
{ Don't prefer conversions from widestring to a
|
||||
normal string as we can lose information }
|
||||
if (tstringdef(def_from).stringtype in [st_widestring,st_unicodestring]) and
|
||||
not (tstringdef(def_to).stringtype in [st_widestring,st_unicodestring]) then
|
||||
eq:=te_convert_l3
|
||||
else if tstringdef(def_to).stringtype in [st_widestring,st_unicodestring] then
|
||||
eq:=te_convert_l2
|
||||
else
|
||||
eq:=te_convert_l1;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
if (fromtreetype=stringconstn) and
|
||||
is_shortstring(def_from) and
|
||||
is_shortstring(def_to) then
|
||||
eq:=te_equal
|
||||
else if (tstringdef(def_to).stringtype=st_ansistring) and
|
||||
(tstringdef(def_from).stringtype=st_ansistring) then
|
||||
begin
|
||||
@ -414,11 +388,17 @@ implementation
|
||||
else
|
||||
begin
|
||||
doconv := tc_string_2_string;
|
||||
if (tstringdef(def_to).encoding=globals.CP_UTF8) then
|
||||
|
||||
{ prefere conversion to utf8 codepage }
|
||||
if tstringdef(def_to).encoding = globals.CP_UTF8 then
|
||||
eq:=te_convert_l1
|
||||
{ else to AnsiString type }
|
||||
else if def_to=getansistringdef then
|
||||
eq:=te_convert_l2
|
||||
{ else to AnsiString with other codepage }
|
||||
else
|
||||
eq:=te_convert_l2;
|
||||
end
|
||||
eq:=te_convert_l3;
|
||||
end
|
||||
end
|
||||
else
|
||||
{ same string type ? }
|
||||
@ -436,44 +416,53 @@ implementation
|
||||
case tstringdef(def_from).stringtype of
|
||||
st_widestring :
|
||||
begin
|
||||
{ Prefer conversions to unicodestring }
|
||||
if tstringdef(def_to).stringtype=st_unicodestring then
|
||||
eq:=te_convert_l1
|
||||
{ else prefer conversions to ansistring }
|
||||
else if tstringdef(def_to).stringtype=st_ansistring then
|
||||
eq:=te_convert_l2
|
||||
else
|
||||
eq:=te_convert_l3;
|
||||
case tstringdef(def_to).stringtype of
|
||||
{ Prefer conversions to unicodestring }
|
||||
st_unicodestring: eq:=te_convert_l1;
|
||||
{ else prefer conversions to ansistring }
|
||||
st_ansistring: eq:=te_convert_l2;
|
||||
else
|
||||
eq:=te_convert_l3;
|
||||
end;
|
||||
end;
|
||||
st_unicodestring :
|
||||
begin
|
||||
{ Prefer conversions to widestring }
|
||||
if tstringdef(def_to).stringtype=st_widestring then
|
||||
eq:=te_convert_l1
|
||||
{ else prefer conversions to ansistring }
|
||||
else if tstringdef(def_to).stringtype=st_ansistring then
|
||||
eq:=te_convert_l2
|
||||
else
|
||||
eq:=te_convert_l3;
|
||||
case tstringdef(def_to).stringtype of
|
||||
{ Prefer conversions to widestring }
|
||||
st_widestring: eq:=te_convert_l1;
|
||||
{ else prefer conversions to ansistring }
|
||||
st_ansistring: eq:=te_convert_l2;
|
||||
else
|
||||
eq:=te_convert_l3;
|
||||
end;
|
||||
end;
|
||||
st_shortstring :
|
||||
begin
|
||||
{ Prefer shortstrings of different length or conversions
|
||||
from shortstring to ansistring }
|
||||
if (tstringdef(def_to).stringtype=st_shortstring) then
|
||||
eq:=te_convert_l1
|
||||
else if tstringdef(def_to).stringtype=st_ansistring then
|
||||
eq:=te_convert_l2
|
||||
else
|
||||
eq:=te_convert_l3;
|
||||
case tstringdef(def_to).stringtype of
|
||||
st_shortstring: eq:=te_convert_l1;
|
||||
st_ansistring:
|
||||
if tstringdef(def_to).encoding=globals.CP_UTF8 then
|
||||
eq:=te_convert_l2
|
||||
else if def_to=getansistringdef then
|
||||
eq:=te_convert_l3
|
||||
else
|
||||
eq:=te_convert_l4;
|
||||
st_unicodestring: eq:=te_convert_l5;
|
||||
else
|
||||
eq:=te_convert_l6;
|
||||
end;
|
||||
end;
|
||||
st_ansistring :
|
||||
begin
|
||||
{ Prefer conversion to widestrings }
|
||||
if (tstringdef(def_to).stringtype in [st_widestring,st_unicodestring]) then
|
||||
eq:=te_convert_l2
|
||||
else
|
||||
eq:=te_convert_l3;
|
||||
case tstringdef(def_to).stringtype of
|
||||
st_unicodestring: eq:=te_convert_l4;
|
||||
st_widestring: eq:=te_convert_l5;
|
||||
else
|
||||
eq:=te_convert_l6;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -51,6 +51,7 @@ interface
|
||||
cl3_count,
|
||||
cl4_count,
|
||||
cl5_count,
|
||||
cl6_count,
|
||||
coper_count : integer; { should be signed }
|
||||
ordinal_distance : double;
|
||||
invalid : boolean;
|
||||
@ -1694,7 +1695,8 @@ implementation
|
||||
{ string and string[10] are assumed as equal }
|
||||
{ when searching the correct overloaded procedure }
|
||||
if (p.resultdef.typ=stringdef) and
|
||||
(tstringdef(def_to).stringtype=tstringdef(p.resultdef).stringtype) then
|
||||
(tstringdef(def_to).stringtype=tstringdef(p.resultdef).stringtype) and
|
||||
(tstringdef(def_to).encoding=tstringdef(p.resultdef).encoding) then
|
||||
eq:=te_equal
|
||||
end;
|
||||
setdef :
|
||||
@ -2217,6 +2219,7 @@ implementation
|
||||
' l3: '+tostr(hp^.cl3_count)+
|
||||
' l4: '+tostr(hp^.cl4_count)+
|
||||
' l5: '+tostr(hp^.cl5_count)+
|
||||
' l6: '+tostr(hp^.cl6_count)+
|
||||
' oper: '+tostr(hp^.coper_count)+
|
||||
' ord: '+realtostr(hp^.ordinal_distance));
|
||||
{ Print parameters in left-right order }
|
||||
@ -2426,15 +2429,12 @@ implementation
|
||||
else
|
||||
{ generic type comparision }
|
||||
begin
|
||||
if not(po_compilerproc in hp^.data.procoptions) and
|
||||
not(po_rtlproc in hp^.data.procoptions) and
|
||||
is_ansistring(currpara.vardef) and
|
||||
is_ansistring(currpt.left.resultdef) and
|
||||
(tstringdef(currpara.vardef).encoding<>tstringdef(currpt.left.resultdef).encoding) and
|
||||
((tstringdef(currpara.vardef).encoding=globals.CP_NONE) or
|
||||
(tstringdef(currpt.left.resultdef).encoding=globals.CP_NONE)
|
||||
) then
|
||||
eq:=te_convert_l1
|
||||
if (hp^.data.procoptions*[po_rtlproc,po_compilerproc]=[]) and
|
||||
is_ansistring(def_from) and
|
||||
is_ansistring(def_to) and
|
||||
(tstringdef(def_from).encoding<>tstringdef(def_to).encoding) and
|
||||
(currpara.varspez in [vs_var,vs_out]) then
|
||||
eq:=te_convert_l1 // don't allow to pass different ansistring types to each-other
|
||||
else
|
||||
eq:=compare_defs_ext(def_from,def_to,currpt.left.nodetype,convtype,pdoper,cdoptions);
|
||||
|
||||
@ -2487,6 +2487,8 @@ implementation
|
||||
inc(hp^.cl4_count);
|
||||
te_convert_l5 :
|
||||
inc(hp^.cl5_count);
|
||||
te_convert_l6 :
|
||||
inc(hp^.cl6_count);
|
||||
te_convert_operator :
|
||||
inc(hp^.coper_count);
|
||||
te_incompatible :
|
||||
@ -2614,48 +2616,53 @@ implementation
|
||||
res:=(bestpd^.coper_count-currpd^.coper_count);
|
||||
if (res=0) then
|
||||
begin
|
||||
{ less cl5 parameters? }
|
||||
res:=(bestpd^.cl5_count-currpd^.cl5_count);
|
||||
{ less cl6 parameters? }
|
||||
res:=(bestpd^.cl6_count-currpd^.cl6_count);
|
||||
if (res=0) then
|
||||
begin
|
||||
{ less cl4 parameters? }
|
||||
res:=(bestpd^.cl4_count-currpd^.cl4_count);
|
||||
if (res=0) then
|
||||
begin
|
||||
{ less cl3 parameters? }
|
||||
res:=(bestpd^.cl3_count-currpd^.cl3_count);
|
||||
if (res=0) then
|
||||
begin
|
||||
{ less cl2 parameters? }
|
||||
res:=(bestpd^.cl2_count-currpd^.cl2_count);
|
||||
{ less cl5 parameters? }
|
||||
res:=(bestpd^.cl5_count-currpd^.cl5_count);
|
||||
if (res=0) then
|
||||
begin
|
||||
{ less cl4 parameters? }
|
||||
res:=(bestpd^.cl4_count-currpd^.cl4_count);
|
||||
if (res=0) then
|
||||
begin
|
||||
{ less cl3 parameters? }
|
||||
res:=(bestpd^.cl3_count-currpd^.cl3_count);
|
||||
if (res=0) then
|
||||
begin
|
||||
{ less cl1 parameters? }
|
||||
res:=(bestpd^.cl1_count-currpd^.cl1_count);
|
||||
{ less cl2 parameters? }
|
||||
res:=(bestpd^.cl2_count-currpd^.cl2_count);
|
||||
if (res=0) then
|
||||
begin
|
||||
{ more exact parameters? }
|
||||
res:=(currpd^.exact_count-bestpd^.exact_count);
|
||||
{ less cl1 parameters? }
|
||||
res:=(bestpd^.cl1_count-currpd^.cl1_count);
|
||||
if (res=0) then
|
||||
begin
|
||||
{ less equal parameters? }
|
||||
res:=(bestpd^.equal_count-currpd^.equal_count);
|
||||
{ more exact parameters? }
|
||||
res:=(currpd^.exact_count-bestpd^.exact_count);
|
||||
if (res=0) then
|
||||
begin
|
||||
{ smaller ordinal distance? }
|
||||
if (currpd^.ordinal_distance<bestpd^.ordinal_distance) then
|
||||
res:=1
|
||||
else
|
||||
if (currpd^.ordinal_distance>bestpd^.ordinal_distance) then
|
||||
res:=-1
|
||||
else
|
||||
res:=0;
|
||||
{ less equal parameters? }
|
||||
res:=(bestpd^.equal_count-currpd^.equal_count);
|
||||
if (res=0) then
|
||||
begin
|
||||
{ smaller ordinal distance? }
|
||||
if (currpd^.ordinal_distance<bestpd^.ordinal_distance) then
|
||||
res:=1
|
||||
else
|
||||
if (currpd^.ordinal_distance>bestpd^.ordinal_distance) then
|
||||
res:=-1
|
||||
else
|
||||
res:=0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -676,7 +676,7 @@ implementation
|
||||
addn :
|
||||
begin
|
||||
concatwidestrings(ws1,ws2);
|
||||
t:=cstringconstnode.createwstr(ws1);
|
||||
t:=cstringconstnode.createunistr(ws1);
|
||||
end;
|
||||
ltn :
|
||||
t:=cordconstnode.create(byte(comparewidestrings(ws1,ws2)<0),pasbool8type,true);
|
||||
@ -1323,13 +1323,13 @@ implementation
|
||||
{ There is a widechar? }
|
||||
else if is_widechar(rd) or is_widechar(ld) then
|
||||
begin
|
||||
{ widechar+widechar gives widestring }
|
||||
{ widechar+widechar gives unicodestring }
|
||||
if nodetype=addn then
|
||||
begin
|
||||
inserttypeconv(left,cwidestringtype);
|
||||
inserttypeconv(left,cunicodestringtype);
|
||||
if (torddef(rd).ordtype<>uwidechar) then
|
||||
inserttypeconv(right,cwidechartype);
|
||||
resultdef:=cwidestringtype;
|
||||
resultdef:=cunicodestringtype;
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
@ -995,7 +995,7 @@ implementation
|
||||
end;
|
||||
{ Convert to wide/short/ansistring and call default helper }
|
||||
if is_widechar(tarraydef(resultdef).elementdef) then
|
||||
inserttypeconv(left,cwidestringtype)
|
||||
inserttypeconv(left,cunicodestringtype)
|
||||
else
|
||||
begin
|
||||
if tstringconstnode(left).len>255 then
|
||||
@ -1046,7 +1046,7 @@ implementation
|
||||
concatwidestringchar(ws,tcompilerwidechar(tordconstnode(left).value.uvalue))
|
||||
else
|
||||
concatwidestringchar(ws,asciichar2unicode(chr(tordconstnode(left).value.uvalue)));
|
||||
hp:=cstringconstnode.createwstr(ws);
|
||||
hp:=cstringconstnode.createunistr(ws);
|
||||
hp.changestringtype(resultdef);
|
||||
donewidestring(ws);
|
||||
end
|
||||
@ -1392,9 +1392,9 @@ implementation
|
||||
begin
|
||||
result:=nil;
|
||||
if is_pwidechar(resultdef) then
|
||||
inserttypeconv(left,cwidestringtype)
|
||||
inserttypeconv(left,cunicodestringtype)
|
||||
else
|
||||
inserttypeconv(left,cshortstringtype);
|
||||
inserttypeconv(left,cshortstringtype);
|
||||
{ evaluate again, reset resultdef so the convert_typ
|
||||
will be calculated again and cstring_to_pchar will
|
||||
be used for futher conversion }
|
||||
@ -1408,7 +1408,7 @@ implementation
|
||||
begin
|
||||
result:=nil;
|
||||
if is_pwidechar(resultdef) then
|
||||
inserttypeconv(left,cwidestringtype)
|
||||
inserttypeconv(left,cunicodestringtype)
|
||||
else
|
||||
if is_pchar(resultdef) and
|
||||
(is_widestring(left.resultdef) or
|
||||
@ -1943,7 +1943,8 @@ implementation
|
||||
te_convert_l2,
|
||||
te_convert_l3,
|
||||
te_convert_l4,
|
||||
te_convert_l5:
|
||||
te_convert_l5,
|
||||
te_convert_l6:
|
||||
{ nothing to do }
|
||||
;
|
||||
|
||||
|
||||
@ -124,7 +124,7 @@ interface
|
||||
cst_type : tconststringtype;
|
||||
constructor createstr(const s : string);virtual;
|
||||
constructor createpchar(s : pchar;l : longint);virtual;
|
||||
constructor createwstr(w : pcompilerwidestring);virtual;
|
||||
constructor createunistr(w : pcompilerwidestring);virtual;
|
||||
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
|
||||
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
||||
procedure buildderefimpl;override;
|
||||
@ -254,7 +254,7 @@ implementation
|
||||
begin
|
||||
initwidestring(pWideStringVal);
|
||||
concatwidestringchar(pWideStringVal, tcompilerwidechar(tordconstnode(p).value.uvalue));
|
||||
result:=cstringconstnode.createwstr(pWideStringVal);
|
||||
result:=cstringconstnode.createunistr(pWideStringVal);
|
||||
end
|
||||
else if is_conststringnode(p) then
|
||||
result:=tstringconstnode(p.getcopy)
|
||||
@ -311,7 +311,7 @@ implementation
|
||||
p1:=cstringconstnode.createpchar(pc,len);
|
||||
end;
|
||||
constwstring :
|
||||
p1:=cstringconstnode.createwstr(pcompilerwidestring(p.value.valueptr));
|
||||
p1:=cstringconstnode.createunistr(pcompilerwidestring(p.value.valueptr));
|
||||
constreal :
|
||||
p1:=crealconstnode.create(pbestreal(p.value.valueptr)^,p.constdef);
|
||||
constset :
|
||||
@ -794,14 +794,14 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
constructor tstringconstnode.createwstr(w : pcompilerwidestring);
|
||||
constructor tstringconstnode.createunistr(w : pcompilerwidestring);
|
||||
begin
|
||||
inherited create(stringconstn);
|
||||
len:=getlengthwidestring(w);
|
||||
initwidestring(pcompilerwidestring(value_str));
|
||||
copywidestring(w,pcompilerwidestring(value_str));
|
||||
lab_str:=nil;
|
||||
cst_type:=cst_widestring;
|
||||
cst_type:=cst_unicodestring;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
@ -381,7 +381,7 @@ implementation
|
||||
else
|
||||
inserttypeconv(n,getansistringdef)
|
||||
else if is_widechararray(n.resultdef) then
|
||||
inserttypeconv(n,cwidestringtype);
|
||||
inserttypeconv(n,cunicodestringtype);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
@ -2815,7 +2815,7 @@ implementation
|
||||
|
||||
_CWSTRING:
|
||||
begin
|
||||
p1:=cstringconstnode.createwstr(patternw);
|
||||
p1:=cstringconstnode.createunistr(patternw);
|
||||
consume(_CWSTRING);
|
||||
end;
|
||||
|
||||
|
||||
@ -439,8 +439,8 @@ implementation
|
||||
current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(ll));
|
||||
if (p.nodetype in [stringconstn,ordconstn]) then
|
||||
begin
|
||||
{ convert to widestring stringconstn }
|
||||
inserttypeconv(p,cwidestringtype);
|
||||
{ convert to unicodestring stringconstn }
|
||||
inserttypeconv(p,cunicodestringtype);
|
||||
if (p.nodetype=stringconstn) and
|
||||
(tstringconstnode(p).cst_type in [cst_widestring,cst_unicodestring]) then
|
||||
begin
|
||||
@ -904,7 +904,7 @@ implementation
|
||||
end;
|
||||
2:
|
||||
begin
|
||||
inserttypeconv(n,cwidestringtype);
|
||||
inserttypeconv(n,cunicodestringtype);
|
||||
if n.nodetype<>stringconstn then
|
||||
internalerror(2010033003);
|
||||
ca:=pointer(pcompilerwidestring(tstringconstnode(n).value_str)^.data)
|
||||
|
||||
@ -547,6 +547,7 @@ type
|
||||
tequaltype = (
|
||||
te_incompatible,
|
||||
te_convert_operator,
|
||||
te_convert_l6,
|
||||
te_convert_l5, { ad infinitum... }
|
||||
te_convert_l4, { and yet even less preferred conversion }
|
||||
te_convert_l3, { even less preferred conversion (possibly with loss of data) }
|
||||
@ -615,8 +616,8 @@ const
|
||||
);
|
||||
|
||||
EqualTypeName : array[tequaltype] of string[16] = (
|
||||
'incompatible','convert_operator','convert_l5','convert_l4','convert_l3','convert_l2',
|
||||
'convert_l1','equal','exact'
|
||||
'incompatible','convert_operator','convert_l6', 'convert_l5','convert_l4','convert_l3',
|
||||
'convert_l2','convert_l1','equal','exact'
|
||||
);
|
||||
|
||||
visibilityName : array[tvisibility] of string[16] = (
|
||||
|
||||
@ -27,7 +27,7 @@ Begin
|
||||
halt(1);
|
||||
|
||||
Writeln('widestring');
|
||||
n:=pos('狃狄',cad2); //Is correct position 3
|
||||
n:=pos(WideString('狃狄'),cad2); //Is correct position 3
|
||||
|
||||
Writeln(n);
|
||||
if n<>3 then
|
||||
|
||||
Loading…
Reference in New Issue
Block a user