From 69abbba6bbbf5f0cb64b07acc06a78f930f4c8c6 Mon Sep 17 00:00:00 2001 From: Jonas Maebe <jonas@freepascal.org> Date: Sat, 20 Aug 2011 08:24:40 +0000 Subject: [PATCH] * split several parameter insertion helpers out from pdecsub for easier reuse elsewhere git-svn-id: branches/jvmbackend@18687 - --- .gitattributes | 1 + compiler/pdecsub.pas | 320 +------------------------------------ compiler/pparautl.pas | 362 ++++++++++++++++++++++++++++++++++++++++++ compiler/psub.pas | 2 +- 4 files changed, 365 insertions(+), 320 deletions(-) create mode 100644 compiler/pparautl.pas diff --git a/.gitattributes b/.gitattributes index 14ad7ecf73..31e2f7e303 100644 --- a/.gitattributes +++ b/.gitattributes @@ -484,6 +484,7 @@ compiler/powerpc64/rppcstd.inc svneol=native#text/plain compiler/powerpc64/rppcsup.inc svneol=native#text/plain compiler/pp.lpi svneol=native#text/plain compiler/pp.pas svneol=native#text/plain +compiler/pparautl.pas svneol=native#text/plain compiler/ppc.cfg -text compiler/ppc.conf -text compiler/ppc.dof -text diff --git a/compiler/pdecsub.pas b/compiler/pdecsub.pas index e4e0ee97dc..bdd69561b5 100644 --- a/compiler/pdecsub.pas +++ b/compiler/pdecsub.pas @@ -52,8 +52,6 @@ interface function check_proc_directive(isprocvar:boolean):boolean; - procedure insert_funcret_local(pd:tprocdef); - function proc_add_definition(var currpd:tprocdef):boolean; function proc_get_importname(pd:tprocdef):string; procedure proc_set_mangledname(pd:tprocdef); @@ -94,7 +92,7 @@ implementation objcutil, { parser } scanner, - pbase,pexpr,ptype,pdecl + pbase,pexpr,ptype,pdecl,pparautl ; const @@ -161,322 +159,6 @@ implementation inc(result,pop_nested_hierarchy(tabstractrecorddef(obj.owner.defowner))); end; - procedure insert_funcret_para(pd:tabstractprocdef); - var - storepos : tfileposinfo; - vs : tparavarsym; - paranr : word; - begin - if not(pd.proctypeoption in [potype_constructor,potype_destructor]) and - not is_void(pd.returndef) and - paramanager.ret_in_param(pd.returndef,pd.proccalloption) then - begin - storepos:=current_tokenpos; - if pd.typ=procdef then - current_tokenpos:=tprocdef(pd).fileinfo; - -{$if defined(i386)} - { For left to right add it at the end to be delphi compatible. - In the case of safecalls with safecal-exceptions support the - funcret-para is (from the 'c'-point of view) a normal parameter - which has to be added to the end of the parameter-list } - if (pd.proccalloption in (pushleftright_pocalls)) or - ((tf_safecall_exceptions in target_info.flags) and - (pd.proccalloption=pocall_safecall)) then - paranr:=paranr_result_leftright - else -{$elseif defined(x86) or defined(arm)} - if (tf_safecall_exceptions in target_info.flags) and - (pd.proccalloption = pocall_safecall) then - paranr:=paranr_result_leftright - else -{$endif} - paranr:=paranr_result; - { Generate result variable accessing function result } - vs:=tparavarsym.create('$result',paranr,vs_var,pd.returndef,[vo_is_funcret,vo_is_hidden_para]); - pd.parast.insert(vs); - { Store the this symbol as funcretsym for procedures } - if pd.typ=procdef then - tprocdef(pd).funcretsym:=vs; - - current_tokenpos:=storepos; - end; - end; - - - procedure insert_parentfp_para(pd:tabstractprocdef); - var - storepos : tfileposinfo; - vs : tparavarsym; - paranr : longint; - begin - if pd.parast.symtablelevel>normal_function_level then - begin - storepos:=current_tokenpos; - if pd.typ=procdef then - current_tokenpos:=tprocdef(pd).fileinfo; - - { if no support for nested procvars is activated, use the old - calling convention to pass the parent frame pointer for backwards - compatibility } - if not(m_nested_procvars in current_settings.modeswitches) then - paranr:=paranr_parentfp - { nested procvars require Delphi-style parentfp passing, see - po_delphi_nested_cc declaration for more info } -{$ifdef i386} - else if (pd.proccalloption in pushleftright_pocalls) then - paranr:=paranr_parentfp_delphi_cc_leftright -{$endif i386} - else - paranr:=paranr_parentfp_delphi_cc; - { Generate frame pointer. It can't be put in a register since it - must be accessable from nested routines } - if not(target_info.system in systems_fpnestedstruct) then - begin - vs:=tparavarsym.create('$parentfp',paranr,vs_value - ,voidpointertype,[vo_is_parentfp,vo_is_hidden_para]); - vs.varregable:=vr_none; - end - else - begin - if not assigned(tprocdef(pd.owner.defowner).parentfpstruct) then - build_parentfpstruct(tprocdef(pd.owner.defowner)); - vs:=tparavarsym.create('$parentfp',paranr,vs_value - ,tprocdef(pd.owner.defowner).parentfpstructptrtype,[vo_is_parentfp,vo_is_hidden_para]); - end; - pd.parast.insert(vs); - - current_tokenpos:=storepos; - end; - end; - - - procedure insert_self_and_vmt_para(pd:tabstractprocdef); - var - storepos : tfileposinfo; - vs : tparavarsym; - hdef : tdef; - selfdef : tabstractrecorddef; - vsp : tvarspez; - aliasvs : tabsolutevarsym; - sl : tpropaccesslist; - begin - if (pd.typ=procdef) and - is_objc_class_or_protocol(tprocdef(pd).struct) and - (pd.parast.symtablelevel=normal_function_level) then - begin - { insert Objective-C self and selector parameters } - vs:=tparavarsym.create('$_cmd',paranr_objc_cmd,vs_value,objc_seltype,[vo_is_msgsel,vo_is_hidden_para]); - pd.parast.insert(vs); - { make accessible to code } - sl:=tpropaccesslist.create; - sl.addsym(sl_load,vs); - aliasvs:=tabsolutevarsym.create_ref('_CMD',objc_seltype,sl); - include(aliasvs.varoptions,vo_is_msgsel); - tlocalsymtable(tprocdef(pd).localst).insert(aliasvs); - - if (po_classmethod in pd.procoptions) then - { compatible with what gcc does } - hdef:=objc_idtype - else - hdef:=tprocdef(pd).struct; - - vs:=tparavarsym.create('$self',paranr_objc_self,vs_value,hdef,[vo_is_self,vo_is_hidden_para]); - pd.parast.insert(vs); - end - else if (pd.typ=procvardef) and - pd.is_methodpointer then - begin - { Generate self variable } - vs:=tparavarsym.create('$self',paranr_self,vs_value,voidpointertype,[vo_is_self,vo_is_hidden_para]); - pd.parast.insert(vs); - end - else - begin - if (pd.typ=procdef) and - assigned(tprocdef(pd).struct) and - (pd.parast.symtablelevel=normal_function_level) then - begin - { static class methods have no hidden self/vmt pointer } - if pd.no_self_node then - exit; - - storepos:=current_tokenpos; - current_tokenpos:=tprocdef(pd).fileinfo; - - { Generate VMT variable for constructor/destructor } - if (pd.proctypeoption in [potype_constructor,potype_destructor]) and - not(is_cppclass(tprocdef(pd).struct) or - is_record(tprocdef(pd).struct) or - is_javaclass(tprocdef(pd).struct)) then - begin - { can't use classrefdef as type because inheriting - will then always file because of a type mismatch } - vs:=tparavarsym.create('$vmt',paranr_vmt,vs_value,voidpointertype,[vo_is_vmt,vo_is_hidden_para]); - pd.parast.insert(vs); - end; - - { for helpers the type of Self is equivalent to the extended - type or equal to an instance of it } - if is_objectpascal_helper(tprocdef(pd).struct) then - selfdef:=tobjectdef(tprocdef(pd).struct).extendeddef - else - selfdef:=tprocdef(pd).struct; - { Generate self variable, for classes we need - to use the generic voidpointer to be compatible with - methodpointers } - vsp:=vs_value; - if (po_staticmethod in pd.procoptions) or - (po_classmethod in pd.procoptions) then - hdef:=tclassrefdef.create(selfdef) - else - begin - if is_object(selfdef) or is_record(selfdef) then - vsp:=vs_var; - hdef:=selfdef; - end; - vs:=tparavarsym.create('$self',paranr_self,vsp,hdef,[vo_is_self,vo_is_hidden_para]); - pd.parast.insert(vs); - - current_tokenpos:=storepos; - end; - end; - end; - - - procedure insert_funcret_local(pd:tprocdef); - var - storepos : tfileposinfo; - vs : tlocalvarsym; - aliasvs : tabsolutevarsym; - sl : tpropaccesslist; - hs : string; - begin - { The result from constructors and destructors can't be accessed directly } - if not(pd.proctypeoption in [potype_constructor,potype_destructor]) and - not is_void(pd.returndef) then - begin - storepos:=current_tokenpos; - current_tokenpos:=pd.fileinfo; - - { We need to insert a varsym for the result in the localst - when it is returning in a register } - if not paramanager.ret_in_param(pd.returndef,pd.proccalloption) then - begin - vs:=tlocalvarsym.create('$result',vs_value,pd.returndef,[vo_is_funcret]); - pd.localst.insert(vs); - pd.funcretsym:=vs; - end; - - { insert the name of the procedure as alias for the function result, - we can't use realname because that will not work for compilerprocs - as the name is lowercase and unreachable from the code } - if assigned(pd.resultname) then - hs:=pd.resultname^ - else - hs:=pd.procsym.name; - sl:=tpropaccesslist.create; - sl.addsym(sl_load,pd.funcretsym); - aliasvs:=tabsolutevarsym.create_ref(hs,pd.returndef,sl); - include(aliasvs.varoptions,vo_is_funcret); - tlocalsymtable(pd.localst).insert(aliasvs); - - { insert result also if support is on } - if (m_result in current_settings.modeswitches) then - begin - sl:=tpropaccesslist.create; - sl.addsym(sl_load,pd.funcretsym); - aliasvs:=tabsolutevarsym.create_ref('RESULT',pd.returndef,sl); - include(aliasvs.varoptions,vo_is_funcret); - include(aliasvs.varoptions,vo_is_result); - tlocalsymtable(pd.localst).insert(aliasvs); - end; - - current_tokenpos:=storepos; - end; - end; - - - procedure insert_hidden_para(p:TObject;arg:pointer); - var - hvs : tparavarsym; - pd : tabstractprocdef absolute arg; - begin - if (tsym(p).typ<>paravarsym) then - exit; - with tparavarsym(p) do - begin - { We need a local copy for a value parameter when only the - address is pushed. Open arrays and Array of Const are - an exception because they are allocated at runtime and the - address that is pushed is patched } - if (varspez=vs_value) and - paramanager.push_addr_param(varspez,vardef,pd.proccalloption) and - not(is_open_array(vardef) or - is_array_of_const(vardef)) then - include(varoptions,vo_has_local_copy); - - { needs high parameter ? } - if paramanager.push_high_param(varspez,vardef,pd.proccalloption) then - begin - hvs:=tparavarsym.create('$high'+name,paranr+1,vs_const,sinttype,[vo_is_high_para,vo_is_hidden_para]); - hvs.symoptions:=[]; - owner.insert(hvs); - end - else - begin - { Give a warning that cdecl routines does not include high() - support } - if (pd.proccalloption in cdecl_pocalls) and - paramanager.push_high_param(varspez,vardef,pocall_default) then - begin - if is_open_string(vardef) then - MessagePos(fileinfo,parser_w_cdecl_no_openstring); - if not(po_external in pd.procoptions) and - (pd.typ<>procvardef) and - not is_objc_class_or_protocol(tprocdef(pd).struct) then - if is_array_of_const(vardef) then - MessagePos(fileinfo,parser_e_varargs_need_cdecl_and_external) - else - MessagePos(fileinfo,parser_w_cdecl_has_no_high); - end; - if (vardef.typ=formaldef) and (Tformaldef(vardef).typed) then - begin - hvs:=tparavarsym.create('$typinfo'+name,paranr+1,vs_const,voidpointertype, - [vo_is_typinfo_para,vo_is_hidden_para]); - owner.insert(hvs); - end; - end; - end; - end; - - - procedure check_c_para(pd:Tabstractprocdef); - var - i, - lastparaidx : longint; - sym : TSym; - begin - lastparaidx:=pd.parast.SymList.Count-1; - for i:=0 to pd.parast.SymList.Count-1 do - begin - sym:=tsym(pd.parast.SymList[i]); - if (sym.typ=paravarsym) and - (tparavarsym(sym).vardef.typ=arraydef) then - begin - if not is_variant_array(tparavarsym(sym).vardef) and - not is_array_of_const(tparavarsym(sym).vardef) and - (tparavarsym(sym).varspez<>vs_var) then - MessagePos(tparavarsym(sym).fileinfo,parser_h_c_arrays_are_references); - if is_array_of_const(tparavarsym(sym).vardef) and - (i<lastparaidx) and - (tsym(pd.parast.SymList[i+1]).typ=paravarsym) and - not(vo_is_high_para in tparavarsym(pd.parast.SymList[i+1]).varoptions) then - MessagePos(tparavarsym(sym).fileinfo,parser_e_C_array_of_const_must_be_last); - end; - end; - end; - procedure check_msg_para(p:TObject;arg:pointer); begin diff --git a/compiler/pparautl.pas b/compiler/pparautl.pas new file mode 100644 index 0000000000..57297137e2 --- /dev/null +++ b/compiler/pparautl.pas @@ -0,0 +1,362 @@ +{ + Copyright (c) 1998-2002 by Florian Klaempfl, Daniel Mantione + + Helpers for dealing with subroutine parameters during parsing + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + **************************************************************************** +} +unit pparautl; + + +interface + + uses + symdef; + + procedure insert_funcret_para(pd:tabstractprocdef); + procedure insert_parentfp_para(pd:tabstractprocdef); + procedure insert_self_and_vmt_para(pd:tabstractprocdef); + procedure insert_funcret_local(pd:tprocdef); + procedure insert_hidden_para(p:TObject;arg:pointer); + procedure check_c_para(pd:Tabstractprocdef); + +implementation + + uses + globals,globtype,verbose,systems, + symconst,symtype,symbase,symsym,symtable,symcreat,defutil, + paramgr; + + + procedure insert_funcret_para(pd:tabstractprocdef); + var + storepos : tfileposinfo; + vs : tparavarsym; + paranr : word; + begin + if not(pd.proctypeoption in [potype_constructor,potype_destructor]) and + not is_void(pd.returndef) and + paramanager.ret_in_param(pd.returndef,pd.proccalloption) then + begin + storepos:=current_tokenpos; + if pd.typ=procdef then + current_tokenpos:=tprocdef(pd).fileinfo; + +{$if defined(i386)} + { For left to right add it at the end to be delphi compatible. + In the case of safecalls with safecal-exceptions support the + funcret-para is (from the 'c'-point of view) a normal parameter + which has to be added to the end of the parameter-list } + if (pd.proccalloption in (pushleftright_pocalls)) or + ((tf_safecall_exceptions in target_info.flags) and + (pd.proccalloption=pocall_safecall)) then + paranr:=paranr_result_leftright + else +{$elseif defined(x86) or defined(arm)} + if (tf_safecall_exceptions in target_info.flags) and + (pd.proccalloption = pocall_safecall) then + paranr:=paranr_result_leftright + else +{$endif} + paranr:=paranr_result; + { Generate result variable accessing function result } + vs:=tparavarsym.create('$result',paranr,vs_var,pd.returndef,[vo_is_funcret,vo_is_hidden_para]); + pd.parast.insert(vs); + { Store the this symbol as funcretsym for procedures } + if pd.typ=procdef then + tprocdef(pd).funcretsym:=vs; + + current_tokenpos:=storepos; + end; + end; + + + procedure insert_parentfp_para(pd:tabstractprocdef); + var + storepos : tfileposinfo; + vs : tparavarsym; + paranr : longint; + begin + if pd.parast.symtablelevel>normal_function_level then + begin + storepos:=current_tokenpos; + if pd.typ=procdef then + current_tokenpos:=tprocdef(pd).fileinfo; + + { if no support for nested procvars is activated, use the old + calling convention to pass the parent frame pointer for backwards + compatibility } + if not(m_nested_procvars in current_settings.modeswitches) then + paranr:=paranr_parentfp + { nested procvars require Delphi-style parentfp passing, see + po_delphi_nested_cc declaration for more info } +{$ifdef i386} + else if (pd.proccalloption in pushleftright_pocalls) then + paranr:=paranr_parentfp_delphi_cc_leftright +{$endif i386} + else + paranr:=paranr_parentfp_delphi_cc; + { Generate frame pointer. It can't be put in a register since it + must be accessable from nested routines } + if not(target_info.system in systems_fpnestedstruct) then + begin + vs:=tparavarsym.create('$parentfp',paranr,vs_value + ,voidpointertype,[vo_is_parentfp,vo_is_hidden_para]); + vs.varregable:=vr_none; + end + else + begin + if not assigned(tprocdef(pd.owner.defowner).parentfpstruct) then + build_parentfpstruct(tprocdef(pd.owner.defowner)); + vs:=tparavarsym.create('$parentfp',paranr,vs_value + ,tprocdef(pd.owner.defowner).parentfpstructptrtype,[vo_is_parentfp,vo_is_hidden_para]); + end; + pd.parast.insert(vs); + + current_tokenpos:=storepos; + end; + end; + + + procedure insert_self_and_vmt_para(pd:tabstractprocdef); + var + storepos : tfileposinfo; + vs : tparavarsym; + hdef : tdef; + selfdef : tabstractrecorddef; + vsp : tvarspez; + aliasvs : tabsolutevarsym; + sl : tpropaccesslist; + begin + if (pd.typ=procdef) and + is_objc_class_or_protocol(tprocdef(pd).struct) and + (pd.parast.symtablelevel=normal_function_level) then + begin + { insert Objective-C self and selector parameters } + vs:=tparavarsym.create('$_cmd',paranr_objc_cmd,vs_value,objc_seltype,[vo_is_msgsel,vo_is_hidden_para]); + pd.parast.insert(vs); + { make accessible to code } + sl:=tpropaccesslist.create; + sl.addsym(sl_load,vs); + aliasvs:=tabsolutevarsym.create_ref('_CMD',objc_seltype,sl); + include(aliasvs.varoptions,vo_is_msgsel); + tlocalsymtable(tprocdef(pd).localst).insert(aliasvs); + + if (po_classmethod in pd.procoptions) then + { compatible with what gcc does } + hdef:=objc_idtype + else + hdef:=tprocdef(pd).struct; + + vs:=tparavarsym.create('$self',paranr_objc_self,vs_value,hdef,[vo_is_self,vo_is_hidden_para]); + pd.parast.insert(vs); + end + else if (pd.typ=procvardef) and + pd.is_methodpointer then + begin + { Generate self variable } + vs:=tparavarsym.create('$self',paranr_self,vs_value,voidpointertype,[vo_is_self,vo_is_hidden_para]); + pd.parast.insert(vs); + end + else + begin + if (pd.typ=procdef) and + assigned(tprocdef(pd).struct) and + (pd.parast.symtablelevel=normal_function_level) then + begin + { static class methods have no hidden self/vmt pointer } + if pd.no_self_node then + exit; + + storepos:=current_tokenpos; + current_tokenpos:=tprocdef(pd).fileinfo; + + { Generate VMT variable for constructor/destructor } + if (pd.proctypeoption in [potype_constructor,potype_destructor]) and + not(is_cppclass(tprocdef(pd).struct) or + is_record(tprocdef(pd).struct) or + is_javaclass(tprocdef(pd).struct)) then + begin + { can't use classrefdef as type because inheriting + will then always file because of a type mismatch } + vs:=tparavarsym.create('$vmt',paranr_vmt,vs_value,voidpointertype,[vo_is_vmt,vo_is_hidden_para]); + pd.parast.insert(vs); + end; + + { for helpers the type of Self is equivalent to the extended + type or equal to an instance of it } + if is_objectpascal_helper(tprocdef(pd).struct) then + selfdef:=tobjectdef(tprocdef(pd).struct).extendeddef + else + selfdef:=tprocdef(pd).struct; + { Generate self variable, for classes we need + to use the generic voidpointer to be compatible with + methodpointers } + vsp:=vs_value; + if (po_staticmethod in pd.procoptions) or + (po_classmethod in pd.procoptions) then + hdef:=tclassrefdef.create(selfdef) + else + begin + if is_object(selfdef) or is_record(selfdef) then + vsp:=vs_var; + hdef:=selfdef; + end; + vs:=tparavarsym.create('$self',paranr_self,vsp,hdef,[vo_is_self,vo_is_hidden_para]); + pd.parast.insert(vs); + + current_tokenpos:=storepos; + end; + end; + end; + + + procedure insert_funcret_local(pd:tprocdef); + var + storepos : tfileposinfo; + vs : tlocalvarsym; + aliasvs : tabsolutevarsym; + sl : tpropaccesslist; + hs : string; + begin + { The result from constructors and destructors can't be accessed directly } + if not(pd.proctypeoption in [potype_constructor,potype_destructor]) and + not is_void(pd.returndef) then + begin + storepos:=current_tokenpos; + current_tokenpos:=pd.fileinfo; + + { We need to insert a varsym for the result in the localst + when it is returning in a register } + if not paramanager.ret_in_param(pd.returndef,pd.proccalloption) then + begin + vs:=tlocalvarsym.create('$result',vs_value,pd.returndef,[vo_is_funcret]); + pd.localst.insert(vs); + pd.funcretsym:=vs; + end; + + { insert the name of the procedure as alias for the function result, + we can't use realname because that will not work for compilerprocs + as the name is lowercase and unreachable from the code } + if assigned(pd.resultname) then + hs:=pd.resultname^ + else + hs:=pd.procsym.name; + sl:=tpropaccesslist.create; + sl.addsym(sl_load,pd.funcretsym); + aliasvs:=tabsolutevarsym.create_ref(hs,pd.returndef,sl); + include(aliasvs.varoptions,vo_is_funcret); + tlocalsymtable(pd.localst).insert(aliasvs); + + { insert result also if support is on } + if (m_result in current_settings.modeswitches) then + begin + sl:=tpropaccesslist.create; + sl.addsym(sl_load,pd.funcretsym); + aliasvs:=tabsolutevarsym.create_ref('RESULT',pd.returndef,sl); + include(aliasvs.varoptions,vo_is_funcret); + include(aliasvs.varoptions,vo_is_result); + tlocalsymtable(pd.localst).insert(aliasvs); + end; + + current_tokenpos:=storepos; + end; + end; + + + procedure insert_hidden_para(p:TObject;arg:pointer); + var + hvs : tparavarsym; + pd : tabstractprocdef absolute arg; + begin + if (tsym(p).typ<>paravarsym) then + exit; + with tparavarsym(p) do + begin + { We need a local copy for a value parameter when only the + address is pushed. Open arrays and Array of Const are + an exception because they are allocated at runtime and the + address that is pushed is patched } + if (varspez=vs_value) and + paramanager.push_addr_param(varspez,vardef,pd.proccalloption) and + not(is_open_array(vardef) or + is_array_of_const(vardef)) then + include(varoptions,vo_has_local_copy); + + { needs high parameter ? } + if paramanager.push_high_param(varspez,vardef,pd.proccalloption) then + begin + hvs:=tparavarsym.create('$high'+name,paranr+1,vs_const,sinttype,[vo_is_high_para,vo_is_hidden_para]); + hvs.symoptions:=[]; + owner.insert(hvs); + end + else + begin + { Give a warning that cdecl routines does not include high() + support } + if (pd.proccalloption in cdecl_pocalls) and + paramanager.push_high_param(varspez,vardef,pocall_default) then + begin + if is_open_string(vardef) then + MessagePos(fileinfo,parser_w_cdecl_no_openstring); + if not(po_external in pd.procoptions) and + (pd.typ<>procvardef) and + not is_objc_class_or_protocol(tprocdef(pd).struct) then + if is_array_of_const(vardef) then + MessagePos(fileinfo,parser_e_varargs_need_cdecl_and_external) + else + MessagePos(fileinfo,parser_w_cdecl_has_no_high); + end; + if (vardef.typ=formaldef) and (Tformaldef(vardef).typed) then + begin + hvs:=tparavarsym.create('$typinfo'+name,paranr+1,vs_const,voidpointertype, + [vo_is_typinfo_para,vo_is_hidden_para]); + owner.insert(hvs); + end; + end; + end; + end; + + + procedure check_c_para(pd:Tabstractprocdef); + var + i, + lastparaidx : longint; + sym : TSym; + begin + lastparaidx:=pd.parast.SymList.Count-1; + for i:=0 to pd.parast.SymList.Count-1 do + begin + sym:=tsym(pd.parast.SymList[i]); + if (sym.typ=paravarsym) and + (tparavarsym(sym).vardef.typ=arraydef) then + begin + if not is_variant_array(tparavarsym(sym).vardef) and + not is_array_of_const(tparavarsym(sym).vardef) and + (tparavarsym(sym).varspez<>vs_var) then + MessagePos(tparavarsym(sym).fileinfo,parser_h_c_arrays_are_references); + if is_array_of_const(tparavarsym(sym).vardef) and + (i<lastparaidx) and + (tsym(pd.parast.SymList[i+1]).typ=paravarsym) and + not(vo_is_high_para in tparavarsym(pd.parast.SymList[i+1]).varoptions) then + MessagePos(tparavarsym(sym).fileinfo,parser_e_C_array_of_const_must_be_last); + end; + end; + end; + + +end. diff --git a/compiler/psub.pas b/compiler/psub.pas index 013b9e7c5f..69c2acfa22 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -101,7 +101,7 @@ implementation {$endif} { parser } scanner,import,gendef, - pbase,pstatmnt,pdecl,pdecsub,pexports, + pbase,pstatmnt,pdecl,pdecsub,pexports,pparautl, { codegen } tgobj,cgbase,cgobj,cgcpu,hlcgobj,hlcgcpu,dbgbase, ncgutil,regvars,