diff options
author | paul <paul@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2012-04-26 02:33:57 +0000 |
---|---|---|
committer | paul <paul@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2012-04-26 02:33:57 +0000 |
commit | b400e9040d316bd92c1840bffa6ade7164ad188b (patch) | |
tree | 9f7a2a4d8fdbf834ba96400c883209fbcee9fdcb /compiler | |
parent | fec0162a900502f03a10bca471130140a22e1173 (diff) | |
download | fpc-b400e9040d316bd92c1840bffa6ade7164ad188b.tar.gz |
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: http://svn.freepascal.org/svn/fpc/trunk@21057 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/defcmp.pas | 107 | ||||
-rw-r--r-- | compiler/htypechk.pas | 83 | ||||
-rw-r--r-- | compiler/nadd.pas | 8 | ||||
-rw-r--r-- | compiler/ncnv.pas | 13 | ||||
-rw-r--r-- | compiler/ncon.pas | 10 | ||||
-rw-r--r-- | compiler/ninl.pas | 2 | ||||
-rw-r--r-- | compiler/pexpr.pas | 2 | ||||
-rw-r--r-- | compiler/ptconst.pas | 6 | ||||
-rw-r--r-- | compiler/symconst.pas | 5 |
9 files changed, 117 insertions, 119 deletions
diff --git a/compiler/defcmp.pas b/compiler/defcmp.pas index 356601ef06..eba2cce186 100644 --- a/compiler/defcmp.pas +++ b/compiler/defcmp.pas @@ -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; diff --git a/compiler/htypechk.pas b/compiler/htypechk.pas index a909abfdcf..7203c94ae9 100644 --- a/compiler/htypechk.pas +++ b/compiler/htypechk.pas @@ -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; diff --git a/compiler/nadd.pas b/compiler/nadd.pas index 33f8478158..33131c9dda 100644 --- a/compiler/nadd.pas +++ b/compiler/nadd.pas @@ -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 diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas index dd989610b4..842a55fa38 100644 --- a/compiler/ncnv.pas +++ b/compiler/ncnv.pas @@ -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 } ; diff --git a/compiler/ncon.pas b/compiler/ncon.pas index e25b9ff445..a33829269a 100644 --- a/compiler/ncon.pas +++ b/compiler/ncon.pas @@ -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; diff --git a/compiler/ninl.pas b/compiler/ninl.pas index 02e45f5481..576a4fbe5a 100644 --- a/compiler/ninl.pas +++ b/compiler/ninl.pas @@ -381,7 +381,7 @@ implementation else inserttypeconv(n,getansistringdef) else if is_widechararray(n.resultdef) then - inserttypeconv(n,cwidestringtype); + inserttypeconv(n,cunicodestringtype); end; diff --git a/compiler/pexpr.pas b/compiler/pexpr.pas index ee679ac5b0..aa201432f2 100644 --- a/compiler/pexpr.pas +++ b/compiler/pexpr.pas @@ -2815,7 +2815,7 @@ implementation _CWSTRING: begin - p1:=cstringconstnode.createwstr(patternw); + p1:=cstringconstnode.createunistr(patternw); consume(_CWSTRING); end; diff --git a/compiler/ptconst.pas b/compiler/ptconst.pas index d879e42210..24a3fa5710 100644 --- a/compiler/ptconst.pas +++ b/compiler/ptconst.pas @@ -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) diff --git a/compiler/symconst.pas b/compiler/symconst.pas index eee018b495..66b134623c 100644 --- a/compiler/symconst.pas +++ b/compiler/symconst.pas @@ -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] = ( |