ncal.pas 110 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl
  4. This file implements the node for sub procedure calling
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit ncal;
  19. {$i fpcdefs.inc}
  20. { define nice_ncal}
  21. interface
  22. uses
  23. node,
  24. {$ifdef state_tracking}
  25. nstate,
  26. {$endif state_tracking}
  27. symbase,symtype,symppu,symsym,symdef,symtable;
  28. type
  29. tcallnode = class(tbinarynode)
  30. { the symbol containing the definition of the procedure }
  31. { to call }
  32. symtableprocentry : tprocsym;
  33. { the symtable containing symtableprocentry }
  34. symtableproc : tsymtable;
  35. { the definition of the procedure to call }
  36. procdefinition : tabstractprocdef;
  37. methodpointer : tnode;
  38. { separately specified resulttype for some compilerprocs (e.g. }
  39. { you can't have a function with an "array of char" resulttype }
  40. { the RTL) (JM) }
  41. restype: ttype;
  42. restypeset: boolean;
  43. { function return reference node, this is used to pass an already
  44. allocated reference for a ret_in_param return value }
  45. funcretrefnode : tnode;
  46. { only the processor specific nodes need to override this }
  47. { constructor }
  48. constructor create(l:tnode; v : tprocsym;st : tsymtable; mp : tnode);virtual;
  49. constructor createintern(const name: string; params: tnode);
  50. constructor createinternres(const name: string; params: tnode; const res: ttype);
  51. constructor createinternreturn(const name: string; params: tnode; returnnode : tnode);
  52. destructor destroy;override;
  53. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  54. procedure ppuwrite(ppufile:tcompilerppufile);override;
  55. procedure derefimpl;override;
  56. function getcopy : tnode;override;
  57. procedure insertintolist(l : tnodelist);override;
  58. function pass_1 : tnode;override;
  59. {$ifdef nice_ncal}
  60. function choose_definition_to_call(paralength:byte;var errorexit:boolean):Tnode;
  61. {$endif}
  62. function det_resulttype:tnode;override;
  63. {$ifdef state_tracking}
  64. function track_state_pass(exec_known:boolean):boolean;override;
  65. {$endif state_tracking}
  66. function docompare(p: tnode): boolean; override;
  67. procedure set_procvar(procvar:tnode);
  68. end;
  69. tcallnodeclass = class of tcallnode;
  70. tcallparaflags = (
  71. { flags used by tcallparanode }
  72. cpf_exact_match_found,
  73. cpf_convlevel1found,
  74. cpf_convlevel2found,
  75. cpf_is_colon_para
  76. {$ifdef nice_ncal}
  77. ,cpf_nomatchfound
  78. {$endif}
  79. );
  80. tcallparanode = class(tbinarynode)
  81. callparaflags : set of tcallparaflags;
  82. hightree : tnode;
  83. { only the processor specific nodes need to override this }
  84. { constructor }
  85. constructor create(expr,next : tnode);virtual;
  86. destructor destroy;override;
  87. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  88. procedure ppuwrite(ppufile:tcompilerppufile);override;
  89. procedure derefimpl;override;
  90. function getcopy : tnode;override;
  91. procedure insertintolist(l : tnodelist);override;
  92. procedure gen_high_tree(openstring:boolean);
  93. procedure get_paratype;
  94. procedure insert_typeconv(defcoll : tparaitem;do_count : boolean);
  95. procedure det_registers;
  96. procedure firstcallparan(defcoll : tparaitem;do_count : boolean);
  97. procedure secondcallparan(defcoll : tparaitem;
  98. push_from_left_to_right,inlined,is_cdecl : boolean;
  99. para_alignment,para_offset : longint);virtual;abstract;
  100. function docompare(p: tnode): boolean; override;
  101. end;
  102. tcallparanodeclass = class of tcallparanode;
  103. tprocinlinenode = class(tnode)
  104. inlinetree : tnode;
  105. inlineprocdef : tprocdef;
  106. retoffset,para_offset,para_size : longint;
  107. constructor create(p:tprocdef);virtual;
  108. destructor destroy;override;
  109. constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
  110. procedure ppuwrite(ppufile:tcompilerppufile);override;
  111. procedure derefimpl;override;
  112. function getcopy : tnode;override;
  113. function det_resulttype : tnode;override;
  114. procedure insertintolist(l : tnodelist);override;
  115. function pass_1 : tnode;override;
  116. function docompare(p: tnode): boolean; override;
  117. end;
  118. tprocinlinenodeclass = class of tprocinlinenode;
  119. function reverseparameters(p: tcallparanode): tcallparanode;
  120. var
  121. ccallnode : tcallnodeclass;
  122. ccallparanode : tcallparanodeclass;
  123. cprocinlinenode : tprocinlinenodeclass;
  124. implementation
  125. uses
  126. cutils,globtype,systems,
  127. verbose,globals,
  128. symconst,paramgr,defbase,
  129. htypechk,pass_1,cpuinfo,cpubase,
  130. nbas,ncnv,nld,ninl,nadd,ncon,
  131. rgobj,cgbase
  132. ;
  133. {****************************************************************************
  134. HELPERS
  135. ****************************************************************************}
  136. function reverseparameters(p: tcallparanode): tcallparanode;
  137. var
  138. hp1, hp2: tcallparanode;
  139. begin
  140. hp1:=nil;
  141. while assigned(p) do
  142. begin
  143. { pull out }
  144. hp2:=p;
  145. p:=tcallparanode(p.right);
  146. { pull in }
  147. hp2.right:=hp1;
  148. hp1:=hp2;
  149. end;
  150. reverseparameters:=hp1;
  151. end;
  152. procedure search_class_overloads(aprocsym : tprocsym);
  153. { searches n in symtable of pd and all anchestors }
  154. var
  155. speedvalue : cardinal;
  156. srsym : tprocsym;
  157. s : string;
  158. srpdl : pprocdeflist;
  159. objdef : tobjectdef;
  160. begin
  161. if aprocsym.overloadchecked then
  162. exit;
  163. aprocsym.overloadchecked:=true;
  164. if (aprocsym.owner.symtabletype<>objectsymtable) then
  165. internalerror(200111021);
  166. objdef:=tobjectdef(aprocsym.owner.defowner);
  167. { we start in the parent }
  168. if not assigned(objdef.childof) then
  169. exit;
  170. objdef:=objdef.childof;
  171. s:=aprocsym.name;
  172. speedvalue:=getspeedvalue(s);
  173. while assigned(objdef) do
  174. begin
  175. srsym:=tprocsym(objdef.symtable.speedsearch(s,speedvalue));
  176. if assigned(srsym) then
  177. begin
  178. if (srsym.typ<>procsym) then
  179. internalerror(200111022);
  180. if srsym.is_visible_for_proc(aktprocdef) then
  181. begin
  182. srsym.add_para_match_to(Aprocsym);
  183. { we can stop if the overloads were already added
  184. for the found symbol }
  185. if srsym.overloadchecked then
  186. break;
  187. end;
  188. end;
  189. { next parent }
  190. objdef:=objdef.childof;
  191. end;
  192. end;
  193. {****************************************************************************
  194. TCALLPARANODE
  195. ****************************************************************************}
  196. constructor tcallparanode.create(expr,next : tnode);
  197. begin
  198. inherited create(callparan,expr,next);
  199. hightree:=nil;
  200. if assigned(expr) then
  201. expr.set_file_line(self);
  202. callparaflags:=[];
  203. end;
  204. destructor tcallparanode.destroy;
  205. begin
  206. hightree.free;
  207. inherited destroy;
  208. end;
  209. constructor tcallparanode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  210. begin
  211. inherited ppuload(t,ppufile);
  212. ppufile.getsmallset(callparaflags);
  213. hightree:=ppuloadnode(ppufile);
  214. end;
  215. procedure tcallparanode.ppuwrite(ppufile:tcompilerppufile);
  216. begin
  217. inherited ppuwrite(ppufile);
  218. ppufile.putsmallset(callparaflags);
  219. ppuwritenode(ppufile,hightree);
  220. end;
  221. procedure tcallparanode.derefimpl;
  222. begin
  223. inherited derefimpl;
  224. if assigned(hightree) then
  225. hightree.derefimpl;
  226. end;
  227. function tcallparanode.getcopy : tnode;
  228. var
  229. n : tcallparanode;
  230. begin
  231. n:=tcallparanode(inherited getcopy);
  232. n.callparaflags:=callparaflags;
  233. if assigned(hightree) then
  234. n.hightree:=hightree.getcopy
  235. else
  236. n.hightree:=nil;
  237. result:=n;
  238. end;
  239. procedure tcallparanode.insertintolist(l : tnodelist);
  240. begin
  241. end;
  242. procedure tcallparanode.get_paratype;
  243. var
  244. old_get_para_resulttype : boolean;
  245. old_array_constructor : boolean;
  246. begin
  247. inc(parsing_para_level);
  248. if assigned(right) then
  249. tcallparanode(right).get_paratype;
  250. old_array_constructor:=allow_array_constructor;
  251. old_get_para_resulttype:=get_para_resulttype;
  252. get_para_resulttype:=true;
  253. allow_array_constructor:=true;
  254. resulttypepass(left);
  255. get_para_resulttype:=old_get_para_resulttype;
  256. allow_array_constructor:=old_array_constructor;
  257. if codegenerror then
  258. resulttype:=generrortype
  259. else
  260. resulttype:=left.resulttype;
  261. dec(parsing_para_level);
  262. end;
  263. function is_var_para_incompatible(from_def,to_def:Tdef):boolean;
  264. {Might be an idea to move this to defbase...}
  265. begin
  266. is_var_para_incompatible:=
  267. { allows conversion from word to integer and
  268. byte to shortint, but only for TP7 compatibility }
  269. (not(
  270. (m_tp7 in aktmodeswitches) and
  271. (from_def.deftype=orddef) and
  272. (to_def.deftype=orddef) and
  273. (from_def.size=to_def.size)
  274. ) and
  275. { an implicit pointer conversion is allowed }
  276. not(
  277. (from_def.deftype=pointerdef) and
  278. (to_def.deftype=pointerdef)
  279. ) and
  280. { child classes can be also passed }
  281. not(
  282. (from_def.deftype=objectdef) and
  283. (to_def.deftype=objectdef) and
  284. tobjectdef(from_def).is_related(tobjectdef(to_def))
  285. ) and
  286. { passing a single element to a openarray of the same type }
  287. not(
  288. (is_open_array(to_def) and
  289. is_equal(tarraydef(to_def).elementtype.def,from_def))
  290. ) and
  291. { an implicit file conversion is also allowed }
  292. { from a typed file to an untyped one }
  293. not(
  294. (from_def.deftype=filedef) and
  295. (to_def.deftype=filedef) and
  296. (tfiledef(to_def).filetyp = ft_untyped) and
  297. (tfiledef(from_def).filetyp = ft_typed)
  298. ) and
  299. not(is_equal(from_def,to_def)));
  300. end;
  301. procedure tcallparanode.insert_typeconv(defcoll : tparaitem;do_count : boolean);
  302. var
  303. oldtype : ttype;
  304. {$ifdef extdebug}
  305. store_count_ref : boolean;
  306. {$endif def extdebug}
  307. p1 : tnode;
  308. begin
  309. inc(parsing_para_level);
  310. if not assigned(defcoll) then
  311. internalerror(200104261);
  312. {$ifdef extdebug}
  313. if do_count then
  314. begin
  315. store_count_ref:=count_ref;
  316. count_ref:=true;
  317. end;
  318. {$endif def extdebug}
  319. if assigned(right) then
  320. begin
  321. { if we are a para that belongs to varargs then keep
  322. the current defcoll }
  323. if (nf_varargs_para in flags) then
  324. tcallparanode(right).insert_typeconv(defcoll,do_count)
  325. else
  326. tcallparanode(right).insert_typeconv(tparaitem(defcoll.next),do_count);
  327. end;
  328. { Be sure to have the resulttype }
  329. if not assigned(left.resulttype.def) then
  330. resulttypepass(left);
  331. { Handle varargs directly, no typeconvs or typechecking needed }
  332. if (nf_varargs_para in flags) then
  333. begin
  334. { convert pascal to C types }
  335. case left.resulttype.def.deftype of
  336. stringdef :
  337. inserttypeconv(left,charpointertype);
  338. floatdef :
  339. inserttypeconv(left,s64floattype);
  340. end;
  341. set_varstate(left,true);
  342. resulttype:=left.resulttype;
  343. dec(parsing_para_level);
  344. exit;
  345. end;
  346. { Do we need arrayconstructor -> set conversion, then insert
  347. it here before the arrayconstructor node breaks the tree
  348. with its conversions of enum->ord }
  349. if (left.nodetype=arrayconstructorn) and
  350. (defcoll.paratype.def.deftype=setdef) then
  351. inserttypeconv(left,defcoll.paratype);
  352. { set some settings needed for arrayconstructor }
  353. if is_array_constructor(left.resulttype.def) then
  354. begin
  355. if is_array_of_const(defcoll.paratype.def) then
  356. begin
  357. if assigned(aktcallprocdef) and
  358. (aktcallprocdef.proccalloption in [pocall_cppdecl,pocall_cdecl]) and
  359. (po_external in aktcallprocdef.procoptions) then
  360. include(left.flags,nf_cargs);
  361. { force variant array }
  362. include(left.flags,nf_forcevaria);
  363. end
  364. else
  365. begin
  366. include(left.flags,nf_novariaallowed);
  367. { now that the resultting type is know we can insert the required
  368. typeconvs for the array constructor }
  369. tarrayconstructornode(left).force_type(tarraydef(defcoll.paratype.def).elementtype);
  370. end;
  371. end;
  372. { check if local proc/func is assigned to procvar }
  373. if left.resulttype.def.deftype=procvardef then
  374. test_local_to_procvar(tprocvardef(left.resulttype.def),defcoll.paratype.def);
  375. { generate the high() value tree }
  376. if not(assigned(aktcallprocdef) and
  377. (aktcallprocdef.proccalloption in [pocall_cppdecl,pocall_cdecl]) and
  378. (po_external in aktcallprocdef.procoptions)) and
  379. paramanager.push_high_param(defcoll.paratype.def) then
  380. gen_high_tree(is_open_string(defcoll.paratype.def));
  381. { test conversions }
  382. if not(is_shortstring(left.resulttype.def) and
  383. is_shortstring(defcoll.paratype.def)) and
  384. (defcoll.paratype.def.deftype<>formaldef) then
  385. begin
  386. if (defcoll.paratyp in [vs_var,vs_out]) and
  387. is_var_para_incompatible(left.resulttype.def,defcoll.paratype.def) then
  388. begin
  389. CGMessagePos2(left.fileinfo,parser_e_call_by_ref_without_typeconv,
  390. left.resulttype.def.typename,defcoll.paratype.def.typename);
  391. end;
  392. { Process open parameters }
  393. if paramanager.push_high_param(defcoll.paratype.def) then
  394. begin
  395. { insert type conv but hold the ranges of the array }
  396. oldtype:=left.resulttype;
  397. inserttypeconv(left,defcoll.paratype);
  398. left.resulttype:=oldtype;
  399. end
  400. else
  401. begin
  402. inserttypeconv(left,defcoll.paratype);
  403. end;
  404. if codegenerror then
  405. begin
  406. dec(parsing_para_level);
  407. exit;
  408. end;
  409. end;
  410. { check var strings }
  411. if (cs_strict_var_strings in aktlocalswitches) and
  412. is_shortstring(left.resulttype.def) and
  413. is_shortstring(defcoll.paratype.def) and
  414. (defcoll.paratyp in [vs_out,vs_var]) and
  415. not(is_open_string(defcoll.paratype.def)) and
  416. not(is_equal(left.resulttype.def,defcoll.paratype.def)) then
  417. begin
  418. aktfilepos:=left.fileinfo;
  419. CGMessage(type_e_strict_var_string_violation);
  420. end;
  421. { Handle formal parameters separate }
  422. if (defcoll.paratype.def.deftype=formaldef) then
  423. begin
  424. { load procvar if a procedure is passed }
  425. if (m_tp_procvar in aktmodeswitches) and
  426. (left.nodetype=calln) and
  427. (is_void(left.resulttype.def)) then
  428. begin
  429. p1:=cloadnode.create_procvar(tcallnode(left).symtableprocentry,
  430. tprocdef(tcallnode(left).procdefinition),tcallnode(left).symtableproc);
  431. if assigned(tcallnode(left).right) then
  432. tloadnode(p1).set_mp(tcallnode(left).right);
  433. left.free;
  434. left:=p1;
  435. resulttypepass(left);
  436. end;
  437. case defcoll.paratyp of
  438. vs_var,
  439. vs_out :
  440. begin
  441. if not valid_for_formal_var(left) then
  442. CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
  443. end;
  444. vs_const :
  445. begin
  446. if not valid_for_formal_const(left) then
  447. CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
  448. end;
  449. end;
  450. end
  451. else
  452. begin
  453. { check if the argument is allowed }
  454. if (defcoll.paratyp in [vs_out,vs_var]) then
  455. valid_for_var(left);
  456. end;
  457. if defcoll.paratyp in [vs_var,vs_const] then
  458. begin
  459. { Causes problems with const ansistrings if also }
  460. { done for vs_const (JM) }
  461. if defcoll.paratyp = vs_var then
  462. set_unique(left);
  463. make_not_regable(left);
  464. end;
  465. { ansistrings out paramaters doesn't need to be }
  466. { unique, they are finalized }
  467. if defcoll.paratyp=vs_out then
  468. make_not_regable(left);
  469. if do_count then
  470. begin
  471. { not completly proper, but avoids some warnings }
  472. if (defcoll.paratyp in [vs_var,vs_out]) then
  473. set_funcret_is_valid(left);
  474. set_varstate(left,not(defcoll.paratyp in [vs_var,vs_out]));
  475. end;
  476. { must only be done after typeconv PM }
  477. resulttype:=defcoll.paratype;
  478. dec(parsing_para_level);
  479. {$ifdef extdebug}
  480. if do_count then
  481. count_ref:=store_count_ref;
  482. {$endif def extdebug}
  483. end;
  484. procedure tcallparanode.det_registers;
  485. var
  486. old_get_para_resulttype : boolean;
  487. old_array_constructor : boolean;
  488. begin
  489. if assigned(right) then
  490. begin
  491. tcallparanode(right).det_registers;
  492. registers32:=right.registers32;
  493. registersfpu:=right.registersfpu;
  494. {$ifdef SUPPORT_MMX}
  495. registersmmx:=right.registersmmx;
  496. {$endif}
  497. end;
  498. old_array_constructor:=allow_array_constructor;
  499. old_get_para_resulttype:=get_para_resulttype;
  500. get_para_resulttype:=true;
  501. allow_array_constructor:=true;
  502. firstpass(left);
  503. get_para_resulttype:=old_get_para_resulttype;
  504. allow_array_constructor:=old_array_constructor;
  505. if left.registers32>registers32 then
  506. registers32:=left.registers32;
  507. if left.registersfpu>registersfpu then
  508. registersfpu:=left.registersfpu;
  509. {$ifdef SUPPORT_MMX}
  510. if left.registersmmx>registersmmx then
  511. registersmmx:=left.registersmmx;
  512. {$endif SUPPORT_MMX}
  513. end;
  514. procedure tcallparanode.firstcallparan(defcoll : tparaitem;do_count : boolean);
  515. begin
  516. if not assigned(left.resulttype.def) then
  517. begin
  518. get_paratype;
  519. if assigned(defcoll) then
  520. insert_typeconv(defcoll,do_count);
  521. end;
  522. det_registers;
  523. end;
  524. procedure tcallparanode.gen_high_tree(openstring:boolean);
  525. var
  526. temp: tnode;
  527. len : integer;
  528. loadconst : boolean;
  529. begin
  530. if assigned(hightree) then
  531. exit;
  532. len:=-1;
  533. loadconst:=true;
  534. case left.resulttype.def.deftype of
  535. arraydef :
  536. begin
  537. { handle via a normal inline in_high_x node }
  538. loadconst := false;
  539. hightree := geninlinenode(in_high_x,false,left.getcopy);
  540. { only substract low(array) if it's <> 0 }
  541. temp := geninlinenode(in_low_x,false,left.getcopy);
  542. firstpass(temp);
  543. if (temp.nodetype <> ordconstn) or
  544. (tordconstnode(temp).value <> 0) then
  545. hightree := caddnode.create(subn,hightree,temp)
  546. else
  547. temp.free;
  548. end;
  549. stringdef :
  550. begin
  551. if openstring then
  552. begin
  553. { handle via a normal inline in_high_x node }
  554. loadconst := false;
  555. hightree := geninlinenode(in_high_x,false,left.getcopy);
  556. end
  557. else
  558. { passing a string to an array of char }
  559. begin
  560. if (left.nodetype=stringconstn) then
  561. begin
  562. len:=str_length(left);
  563. if len>0 then
  564. dec(len);
  565. end
  566. else
  567. begin
  568. hightree:=caddnode.create(subn,geninlinenode(in_length_x,false,left.getcopy),
  569. cordconstnode.create(1,s32bittype,false));
  570. loadconst:=false;
  571. end;
  572. end;
  573. end;
  574. else
  575. len:=0;
  576. end;
  577. if loadconst then
  578. hightree:=cordconstnode.create(len,s32bittype,true)
  579. else
  580. hightree:=ctypeconvnode.create(hightree,s32bittype);
  581. firstpass(hightree);
  582. end;
  583. function tcallparanode.docompare(p: tnode): boolean;
  584. begin
  585. docompare :=
  586. inherited docompare(p) and
  587. (callparaflags = tcallparanode(p).callparaflags) and
  588. hightree.isequal(tcallparanode(p).hightree);
  589. end;
  590. {****************************************************************************
  591. TCALLNODE
  592. ****************************************************************************}
  593. constructor tcallnode.create(l:tnode;v : tprocsym;st : tsymtable; mp : tnode);
  594. begin
  595. inherited create(calln,l,nil);
  596. symtableprocentry:=v;
  597. symtableproc:=st;
  598. include(flags,nf_return_value_used);
  599. methodpointer:=mp;
  600. procdefinition:=nil;
  601. restypeset := false;
  602. funcretrefnode:=nil;
  603. end;
  604. constructor tcallnode.createintern(const name: string; params: tnode);
  605. var
  606. srsym: tsym;
  607. symowner: tsymtable;
  608. begin
  609. if not (cs_compilesystem in aktmoduleswitches) then
  610. begin
  611. srsym := searchsymonlyin(systemunit,name);
  612. symowner := systemunit;
  613. end
  614. else
  615. begin
  616. searchsym(name,srsym,symowner);
  617. if not assigned(srsym) then
  618. searchsym(upper(name),srsym,symowner);
  619. end;
  620. if not assigned(srsym) or
  621. (srsym.typ <> procsym) then
  622. begin
  623. writeln('unknown compilerproc ',name);
  624. internalerror(200107271);
  625. end;
  626. self.create(params,tprocsym(srsym),symowner,nil);
  627. end;
  628. constructor tcallnode.createinternres(const name: string; params: tnode; const res: ttype);
  629. begin
  630. self.createintern(name,params);
  631. restype := res;
  632. restypeset := true;
  633. { both the normal and specified resulttype either have to be returned via a }
  634. { parameter or not, but no mixing (JM) }
  635. if paramanager.ret_in_param(restype.def) xor paramanager.ret_in_param(symtableprocentry.first_procdef.rettype.def) then
  636. internalerror(200108291);
  637. end;
  638. constructor tcallnode.createinternreturn(const name: string; params: tnode; returnnode : tnode);
  639. begin
  640. self.createintern(name,params);
  641. funcretrefnode:=returnnode;
  642. if not paramanager.ret_in_param(symtableprocentry.first_procdef.rettype.def) then
  643. internalerror(200204247);
  644. end;
  645. destructor tcallnode.destroy;
  646. begin
  647. methodpointer.free;
  648. funcretrefnode.free;
  649. inherited destroy;
  650. end;
  651. constructor tcallnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  652. begin
  653. inherited ppuload(t,ppufile);
  654. symtableprocentry:=tprocsym(ppufile.getderef);
  655. {$warning FIXME: No withsymtable support}
  656. symtableproc:=nil;
  657. procdefinition:=tprocdef(ppufile.getderef);
  658. restypeset:=boolean(ppufile.getbyte);
  659. methodpointer:=ppuloadnode(ppufile);
  660. funcretrefnode:=ppuloadnode(ppufile);
  661. end;
  662. procedure tcallnode.ppuwrite(ppufile:tcompilerppufile);
  663. begin
  664. inherited ppuwrite(ppufile);
  665. ppufile.putderef(symtableprocentry);
  666. ppufile.putderef(procdefinition);
  667. ppufile.putbyte(byte(restypeset));
  668. ppuwritenode(ppufile,methodpointer);
  669. ppuwritenode(ppufile,funcretrefnode);
  670. end;
  671. procedure tcallnode.derefimpl;
  672. begin
  673. inherited derefimpl;
  674. resolvesym(pointer(symtableprocentry));
  675. symtableproc:=symtableprocentry.owner;
  676. resolvedef(pointer(procdefinition));
  677. if assigned(methodpointer) then
  678. methodpointer.derefimpl;
  679. if assigned(funcretrefnode) then
  680. funcretrefnode.derefimpl;
  681. end;
  682. procedure tcallnode.set_procvar(procvar:tnode);
  683. begin
  684. right:=procvar;
  685. end;
  686. function tcallnode.getcopy : tnode;
  687. var
  688. n : tcallnode;
  689. begin
  690. n:=tcallnode(inherited getcopy);
  691. n.symtableprocentry:=symtableprocentry;
  692. n.symtableproc:=symtableproc;
  693. n.procdefinition:=procdefinition;
  694. n.restype := restype;
  695. n.restypeset := restypeset;
  696. if assigned(methodpointer) then
  697. n.methodpointer:=methodpointer.getcopy
  698. else
  699. n.methodpointer:=nil;
  700. if assigned(funcretrefnode) then
  701. n.funcretrefnode:=funcretrefnode.getcopy
  702. else
  703. n.funcretrefnode:=nil;
  704. result:=n;
  705. end;
  706. procedure tcallnode.insertintolist(l : tnodelist);
  707. begin
  708. end;
  709. {$ifdef nice_ncal}
  710. function Tcallnode.choose_definition_to_call(paralength:byte;var errorexit:boolean):Tnode;
  711. { check if the resulttype.def from tree p is equal with def, needed
  712. for stringconstn and formaldef }
  713. function is_equal(p:tcallparanode;def:tdef) : boolean;
  714. begin
  715. { safety check }
  716. if not (assigned(def) or assigned(p.resulttype.def)) then
  717. begin
  718. is_equal:=false;
  719. exit;
  720. end;
  721. { all types can be passed to a formaldef }
  722. is_equal:=(def.deftype=formaldef) or
  723. (defbase.is_equal(p.resulttype.def,def))
  724. { integer constants are compatible with all integer parameters if
  725. the specified value matches the range }
  726. or
  727. (
  728. (tbinarynode(p).left.nodetype=ordconstn) and
  729. is_integer(p.resulttype.def) and
  730. is_integer(def) and
  731. (tordconstnode(p.left).value>=torddef(def).low) and
  732. (tordconstnode(p.left).value<=torddef(def).high)
  733. )
  734. { to support ansi/long/wide strings in a proper way }
  735. { string and string[10] are assumed as equal }
  736. { when searching the correct overloaded procedure }
  737. or
  738. (
  739. (def.deftype=stringdef) and (p.resulttype.def.deftype=stringdef) and
  740. (tstringdef(def).string_typ=tstringdef(p.resulttype.def).string_typ)
  741. )
  742. or
  743. (
  744. (p.left.nodetype=stringconstn) and
  745. (is_ansistring(p.resulttype.def) and is_pchar(def))
  746. )
  747. or
  748. (
  749. (p.left.nodetype=ordconstn) and
  750. (is_char(p.resulttype.def) and (is_shortstring(def) or is_ansistring(def)))
  751. )
  752. { set can also be a not yet converted array constructor }
  753. or
  754. (
  755. (def.deftype=setdef) and (p.resulttype.def.deftype=arraydef) and
  756. (tarraydef(p.resulttype.def).IsConstructor) and not(tarraydef(p.resulttype.def).IsVariant)
  757. )
  758. { in tp7 mode proc -> procvar is allowed }
  759. or
  760. (
  761. (m_tp_procvar in aktmodeswitches) and
  762. (def.deftype=procvardef) and (p.left.nodetype=calln) and
  763. (proc_to_procvar_equal(tprocdef(tcallnode(p.left).procdefinition),tprocvardef(def),false))
  764. )
  765. ;
  766. end;
  767. procedure get_candidate_information(var cl2_count,cl1_count,equal_count,exact_count:byte;
  768. var ordspace:double;
  769. treeparas:Tcallparanode;candparas:Tparaitem);
  770. {Gets information how the parameters would be converted to the candidate.}
  771. var hcvt:Tconverttype;
  772. from_def,to_def:Tdef;
  773. begin
  774. cl2_count:=0;
  775. cl1_count:=0;
  776. equal_count:=0;
  777. exact_count:=0;
  778. ordspace:=0;
  779. while candparas<>nil do
  780. begin
  781. from_def:=treeparas.resulttype.def;
  782. to_def:=candparas.paratype.def;
  783. if to_def=from_def then
  784. inc(exact_count)
  785. { if a type is totally included in the other }
  786. { we don't fear an overflow , }
  787. { so we can do as if it is an equal match }
  788. else if (treeparas.left.nodetype=ordconstn) and is_integer(to_def) then
  789. begin
  790. inc(equal_count);
  791. ordspace:=ordspace+(double(Torddef(from_def).low)-Torddef(to_def).low)+
  792. (double(Torddef(to_def).high)-Torddef(from_def).high);
  793. end
  794. else if ((from_def.deftype=orddef) and (to_def.deftype=orddef)) and
  795. (is_in_limit(from_def,to_def) or
  796. ((candparas.paratyp in [vs_var,vs_out]) and (from_def.size=to_def.size))
  797. ) then
  798. begin
  799. ordspace:=ordspace+Torddef(to_def).high;
  800. ordspace:=ordspace-Torddef(to_def).low;
  801. inc(equal_count);
  802. end
  803. else if is_equal(treeparas,to_def) then
  804. inc(equal_count)
  805. else
  806. case isconvertable(from_def,to_def,
  807. hcvt,treeparas.left.nodetype,false) of
  808. 0:
  809. internalerror(200208021);
  810. 1:
  811. inc(cl1_count);
  812. 2:
  813. inc(cl2_count);
  814. end;
  815. treeparas:=Tcallparanode(treeparas.right);
  816. candparas:=Tparaitem(candparas.next);
  817. end;
  818. end;
  819. type Tcandidate_array=array[1..$ffff] of Tprocdef;
  820. Pcandidate_array=^Tcandidate_array;
  821. var candidate_alloc,candidates_left,candidate_count:cardinal;
  822. c1,c2,delete_start:cardinal;
  823. cl2_count1,cl1_count1,equal_count1,exact_count1:byte;
  824. ordspace1:double;
  825. cl2_count2,cl1_count2,equal_count2,exact_count2:byte;
  826. ordspace2:double;
  827. i,n:cardinal;
  828. pt:Tcallparanode;
  829. def:Tprocdef;
  830. hcvt:Tconverttype;
  831. pdc:Tparaitem;
  832. hpt:Tnode;
  833. srprocsym:Tprocsym;
  834. srsymtable:Tsymtable;
  835. candidate_defs:Pcandidate_array;
  836. begin
  837. if fileinfo.line=398 then
  838. i:=0;
  839. choose_definition_to_call:=nil;
  840. errorexit:=true;
  841. { when the definition has overload directive set, we search for
  842. overloaded definitions in the class, this only needs to be done once
  843. for class entries as the tree keeps always the same }
  844. if (not symtableprocentry.overloadchecked) and
  845. (po_overload in symtableprocentry.first_procdef.procoptions) and
  846. (symtableprocentry.owner.symtabletype=objectsymtable) then
  847. search_class_overloads(symtableprocentry);
  848. {Collect all procedures which have the same # of parameters }
  849. candidates_left:=0;
  850. candidate_count:=0;
  851. candidate_alloc:=32;
  852. getmem(candidate_defs,candidate_alloc*sizeof(Tprocdef));
  853. srprocsym:=symtableprocentry;
  854. srsymtable:=symtableprocentry.owner;
  855. repeat
  856. for i:=1 to srprocsym.procdef_count do
  857. begin
  858. def:=srprocsym.procdef[i];
  859. { only when the # of parameters are supported by the procedure }
  860. if (paralength>=def.minparacount) and
  861. ((po_varargs in def.procoptions) or (paralength<=def.maxparacount)) then
  862. begin
  863. candidate_defs^[i]:=def;
  864. inc(candidates_left);
  865. end
  866. else
  867. candidate_defs^[i]:=nil;
  868. inc(candidate_count);
  869. if candidate_alloc=candidate_count then
  870. begin
  871. candidate_alloc:=candidate_alloc*2;
  872. reallocmem(candidate_defs,candidate_alloc*sizeof(Tprocdef));
  873. end;
  874. end;
  875. if po_overload in srprocsym.first_procdef.procoptions then
  876. begin
  877. repeat
  878. srprocsym:=nil;
  879. repeat
  880. srsymtable:=srsymtable.next;
  881. until (srsymtable=nil) or (srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable]);
  882. if assigned(srsymtable) then
  883. srprocsym:=Tprocsym(srsymtable.speedsearch(symtableprocentry.name,symtableprocentry.speedvalue));
  884. until (srsymtable=nil) or (srprocsym<>nil);
  885. if not assigned(srprocsym) then
  886. break;
  887. end
  888. else
  889. break;
  890. until false;
  891. { no procedures found? then there is something wrong
  892. with the parameter size }
  893. if candidates_left=0 then
  894. begin
  895. { in tp mode we can try to convert to procvar if
  896. there are no parameters specified }
  897. if not(assigned(left)) and
  898. (m_tp_procvar in aktmodeswitches) then
  899. begin
  900. hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc);
  901. if (symtableprocentry.owner.symtabletype=objectsymtable) and
  902. assigned(methodpointer) then
  903. tloadnode(hpt).set_mp(methodpointer.getcopy);
  904. resulttypepass(hpt);
  905. choose_definition_to_call:=hpt;
  906. end
  907. else
  908. begin
  909. if assigned(left) then
  910. aktfilepos:=left.fileinfo;
  911. cgmessage(parser_e_wrong_parameter_size);
  912. symtableprocentry.write_parameter_lists(nil);
  913. end;
  914. exit;
  915. end;
  916. {Walk through all candidates and remove the ones
  917. that have incompatible parameters.}
  918. for i:=1 to candidate_count do
  919. if assigned(candidate_defs^[i]) then
  920. begin
  921. def:=candidate_defs^[i];
  922. {Walk through all parameters.}
  923. pdc:=Tparaitem(def.para.first);
  924. pt:=Tcallparanode(left);
  925. while assigned(pdc) do
  926. begin
  927. if pdc.paratyp in [vs_var,vs_out] then
  928. if is_var_para_incompatible(pt.resulttype.def,pdc.paratype.def) and
  929. not(is_shortstring(pt.resulttype.def) and is_shortstring(pdc.paratype.def)) and
  930. (pdc.paratype.def.deftype<>formaldef) then
  931. begin
  932. {Not convertable, def is no longer a candidate.}
  933. candidate_defs^[i]:=nil;
  934. dec(candidates_left);
  935. break;
  936. end
  937. else
  938. exclude(pt.callparaflags,cpf_nomatchfound)
  939. else
  940. if (pt.resulttype.def<>pdc.paratype.def) and
  941. ((isconvertable(pt.resulttype.def,pdc.paratype.def,
  942. hcvt,pt.left.nodetype,false)=0) and
  943. not is_equal(pt,pdc.paratype.def)) then
  944. begin
  945. {Not convertable, def is no longer a candidate.}
  946. candidate_defs^[i]:=nil;
  947. dec(candidates_left);
  948. break;
  949. end
  950. else
  951. exclude(pt.callparaflags,cpf_nomatchfound);
  952. pdc:=Tparaitem(pdc.next);
  953. pt:=Tcallparanode(pt.right);
  954. end;
  955. end;
  956. {Are there any candidates left?}
  957. if candidates_left=0 then
  958. begin
  959. {There is an error, must be wrong type, because
  960. wrong size is already checked (PFV) }
  961. pt:=Tcallparanode(left);
  962. n:=0;
  963. while assigned(pt) do
  964. if cpf_nomatchfound in pt.callparaflags then
  965. break
  966. else
  967. begin
  968. pt:=tcallparanode(pt.right);
  969. inc(n);
  970. end;
  971. if not(assigned(pt) and assigned(pt.resulttype.def)) then
  972. internalerror(39393);
  973. {Def contains the last candidate tested.}
  974. pdc:=Tparaitem(def.para.first);
  975. for i:=1 to n do
  976. pdc:=Tparaitem(pdc.next);
  977. aktfilepos:=pt.fileinfo;
  978. cgmessage3(type_e_wrong_parameter_type,tostr(n+1),
  979. pt.resulttype.def.typename,pdc.paratype.def.typename);
  980. symtableprocentry.write_parameter_lists(nil);
  981. exit;
  982. end;
  983. {If there is more candidate that can be called, we have to
  984. find the most suitable one. We collect the following
  985. information:
  986. - Amount of convertlevel 2 parameters.
  987. - Amount of convertlevel 1 parameters.
  988. - Amount of equal parameters.
  989. - Amount of exact parameters.
  990. - Amount of ordinal space the destination parameters
  991. provide. For exampe, a word provides 65535-255=65280
  992. of ordinal space above a byte.
  993. The first criterium is the candidate that has the least
  994. convertlevel 2 parameters. The next criterium is
  995. the candidate that has the most exact parameters, next
  996. criterium is the least ordinal space and
  997. the last criterium is the most equal parameters. (DM)}
  998. if candidates_left>1 then
  999. begin
  1000. {Find the first candidate.}
  1001. c1:=1;
  1002. while c1<=candidate_count do
  1003. if assigned(candidate_defs^[c1]) then
  1004. break
  1005. else
  1006. inc(c1);
  1007. delete_start:=c1;
  1008. {Get information about candidate c1.}
  1009. get_candidate_information(cl2_count1,cl1_count1,equal_count1,
  1010. exact_count1,ordspace1,Tcallparanode(left),
  1011. Tparaitem(candidate_defs^[c1].para.first));
  1012. {Find the other candidates and eliminate the lesser ones.}
  1013. c2:=c1+1;
  1014. while c2<=candidate_count do
  1015. if assigned(candidate_defs^[c2]) then
  1016. begin
  1017. {Candidate found, get information on it.}
  1018. get_candidate_information(cl2_count2,cl1_count2,equal_count2,
  1019. exact_count2,ordspace2,Tcallparanode(left),
  1020. Tparaitem(candidate_defs^[c2].para.first));
  1021. {Is c1 the better candidate?}
  1022. if (cl2_count1<cl2_count2) or
  1023. ((cl2_count1=cl2_count2) and (exact_count1>exact_count2)) or
  1024. ((cl2_count1=cl2_count2) and (exact_count1=exact_count2) and (equal_count1>equal_count2)) or
  1025. ((cl2_count1=cl2_count2) and (exact_count1=exact_count2) and (equal_count1=equal_count2) and (ordspace1<ordspace2)) then
  1026. {C1 is better, drop c2.}
  1027. candidate_defs^[c2]:=nil
  1028. {Is c2 the better candidate?}
  1029. else if (cl2_count2<cl2_count1) or
  1030. ((cl2_count2=cl2_count1) and (exact_count2>exact_count1)) or
  1031. ((cl2_count2=cl2_count1) and (exact_count2=exact_count1) and (equal_count2>equal_count1)) or
  1032. ((cl2_count2=cl2_count1) and (exact_count2=exact_count1) and (equal_count2=equal_count1) and (ordspace2<ordspace1)) then
  1033. begin
  1034. {C2 is better, drop all previous
  1035. candidates.}
  1036. for i:=delete_start to c2-1 do
  1037. candidate_defs^[i]:=nil;
  1038. delete_start:=c2;
  1039. c1:=c2;
  1040. cl2_count1:=cl2_count2;
  1041. cl1_count1:=cl1_count2;
  1042. equal_count1:=equal_count2;
  1043. exact_count1:=exact_count2;
  1044. ordspace1:=ordspace2;
  1045. end;
  1046. {else the candidates have no advantage over each other,
  1047. do nothing}
  1048. inc(c2);
  1049. end
  1050. else
  1051. inc(c2);
  1052. end;
  1053. {Count the candidates that are left.}
  1054. candidates_left:=0;
  1055. for i:=1 to candidate_count do
  1056. if assigned(candidate_defs^[i]) then
  1057. begin
  1058. inc(candidates_left);
  1059. procdefinition:=candidate_defs^[i];
  1060. end;
  1061. if candidates_left>1 then
  1062. begin
  1063. cgmessage(cg_e_cant_choose_overload_function);
  1064. symtableprocentry.write_parameter_lists(nil);
  1065. exit;
  1066. end;
  1067. freemem(candidate_defs,candidate_alloc*sizeof(Tprocdef));
  1068. if make_ref then
  1069. begin
  1070. Tprocdef(procdefinition).lastref:=Tref.create(Tprocdef(procdefinition).lastref,@fileinfo);
  1071. inc(Tprocdef(procdefinition).refcount);
  1072. if Tprocdef(procdefinition).defref=nil then
  1073. Tprocdef(procdefinition).defref:=Tprocdef(procdefinition).lastref;
  1074. end;
  1075. { big error for with statements
  1076. symtableproc:=procdefinition.owner;
  1077. but neede for overloaded operators !! }
  1078. if symtableproc=nil then
  1079. symtableproc:=procdefinition.owner;
  1080. errorexit:=false;
  1081. end;
  1082. function tcallnode.det_resulttype:tnode;
  1083. var lastpara,paralength:byte;
  1084. oldcallprocdef:Tabstractprocdef;
  1085. pt:Tcallparanode;
  1086. i,n:byte;
  1087. e,is_const:boolean;
  1088. pdc:Tparaitem;
  1089. hpt:Tnode;
  1090. label errorexit;
  1091. begin
  1092. result:=nil;
  1093. oldcallprocdef:=aktcallprocdef;
  1094. aktcallprocdef:=nil;
  1095. { determine length of parameter list }
  1096. pt:=tcallparanode(left);
  1097. paralength:=0;
  1098. while assigned(pt) do
  1099. begin
  1100. include(pt.callparaflags,cpf_nomatchfound);
  1101. inc(paralength);
  1102. pt:=tcallparanode(pt.right);
  1103. end;
  1104. { determine the type of the parameters }
  1105. if assigned(left) then
  1106. begin
  1107. tcallparanode(left).get_paratype;
  1108. if codegenerror then
  1109. goto errorexit;
  1110. end;
  1111. { procedure variable ? }
  1112. if assigned(right) then
  1113. begin
  1114. set_varstate(right,true);
  1115. resulttypepass(right);
  1116. if codegenerror then
  1117. exit;
  1118. procdefinition:=tabstractprocdef(right.resulttype.def);
  1119. { check the amount of parameters }
  1120. pdc:=tparaitem(procdefinition.Para.first);
  1121. pt:=tcallparanode(left);
  1122. lastpara:=paralength;
  1123. while assigned(pdc) and assigned(pt) do
  1124. begin
  1125. { only goto next para if we're out of the varargs }
  1126. if not(po_varargs in procdefinition.procoptions) or
  1127. (lastpara<=procdefinition.maxparacount) then
  1128. pdc:=tparaitem(pdc.next);
  1129. pt:=tcallparanode(pt.right);
  1130. dec(lastpara);
  1131. end;
  1132. if assigned(pt) or assigned(pdc) then
  1133. begin
  1134. if assigned(pt) then
  1135. aktfilepos:=pt.fileinfo;
  1136. CGMessage(parser_e_wrong_parameter_size);
  1137. end;
  1138. end
  1139. else
  1140. { not a procedure variable }
  1141. begin
  1142. { do we know the procedure to call ? }
  1143. if not(assigned(procdefinition)) then
  1144. begin
  1145. result:=choose_definition_to_call(paralength,e);
  1146. if e then
  1147. goto errorexit;
  1148. end;
  1149. (* To do!!!
  1150. { add needed default parameters }
  1151. if assigned(procdefinition) and
  1152. (paralength<procdefinition.maxparacount) then
  1153. begin
  1154. { add default parameters, just read back the skipped
  1155. paras starting from firstPara.previous, when not available
  1156. (all parameters are default) then start with the last
  1157. parameter and read backward (PFV) }
  1158. if not assigned(procs^.firstpara) then
  1159. pdc:=tparaitem(procs^.data.Para.last)
  1160. else
  1161. pdc:=tparaitem(procs^.firstPara.previous);
  1162. while assigned(pdc) do
  1163. begin
  1164. if not assigned(pdc.defaultvalue) then
  1165. internalerror(751349858);
  1166. left:=ccallparanode.create(genconstsymtree(tconstsym(pdc.defaultvalue)),left);
  1167. pdc:=tparaitem(pdc.previous);
  1168. end;
  1169. end;
  1170. *)
  1171. end;
  1172. { handle predefined procedures }
  1173. is_const:=(po_internconst in procdefinition.procoptions) and
  1174. ((block_type in [bt_const,bt_type]) or
  1175. (assigned(left) and (tcallparanode(left).left.nodetype in [realconstn,ordconstn])));
  1176. if (procdefinition.proccalloption=pocall_internproc) or is_const then
  1177. begin
  1178. if assigned(left) then
  1179. begin
  1180. { ptr and settextbuf needs two args }
  1181. if assigned(tcallparanode(left).right) then
  1182. begin
  1183. hpt:=geninlinenode(Tprocdef(procdefinition).extnumber,is_const,left);
  1184. left:=nil;
  1185. end
  1186. else
  1187. begin
  1188. hpt:=geninlinenode(Tprocdef(procdefinition).extnumber,is_const,Tcallparanode(left).left);
  1189. Tcallparanode(left).left:=nil;
  1190. end;
  1191. end
  1192. else
  1193. hpt:=geninlinenode(Tprocdef(procdefinition).extnumber,is_const,nil);
  1194. result:=hpt;
  1195. goto errorexit;
  1196. end;
  1197. {$ifdef dummy}
  1198. { Calling a message method directly ? }
  1199. if assigned(procdefinition) and
  1200. (po_containsself in procdefinition.procoptions) then
  1201. message(cg_e_cannot_call_message_direct);
  1202. {$endif}
  1203. { ensure that the result type is set }
  1204. if not restypeset then
  1205. resulttype:=procdefinition.rettype
  1206. else
  1207. resulttype:=restype;
  1208. { modify the exit code, in case of special cases }
  1209. if (not is_void(resulttype.def)) then
  1210. begin
  1211. if paramanager.ret_in_acc(resulttype.def) then
  1212. begin
  1213. { wide- and ansistrings are returned in EAX }
  1214. { but they are imm. moved to a memory location }
  1215. if is_widestring(resulttype.def) or
  1216. is_ansistring(resulttype.def) then
  1217. begin
  1218. { we use ansistrings so no fast exit here }
  1219. if assigned(procinfo) then
  1220. procinfo.no_fast_exit:=true;
  1221. end;
  1222. end;
  1223. end;
  1224. { constructors return their current class type, not the type where the
  1225. constructor is declared, this can be different because of inheritance }
  1226. if (procdefinition.proctypeoption=potype_constructor) then
  1227. begin
  1228. if assigned(methodpointer) and
  1229. assigned(methodpointer.resulttype.def) and
  1230. (methodpointer.resulttype.def.deftype=classrefdef) then
  1231. resulttype:=tclassrefdef(methodpointer.resulttype.def).pointertype;
  1232. end;
  1233. { flag all callparanodes that belong to the varargs }
  1234. if (po_varargs in procdefinition.procoptions) then
  1235. begin
  1236. pt:=tcallparanode(left);
  1237. i:=paralength;
  1238. while (i>procdefinition.maxparacount) do
  1239. begin
  1240. include(tcallparanode(pt).flags,nf_varargs_para);
  1241. pt:=tcallparanode(pt.right);
  1242. dec(i);
  1243. end;
  1244. end;
  1245. { insert type conversions }
  1246. if assigned(left) then
  1247. begin
  1248. aktcallprocdef:=procdefinition;
  1249. tcallparanode(left).insert_typeconv(tparaitem(procdefinition.Para.first),true);
  1250. end;
  1251. errorexit:
  1252. { Reset some settings back }
  1253. aktcallprocdef:=oldcallprocdef;
  1254. end;
  1255. {$else}
  1256. function tcallnode.det_resulttype:tnode;
  1257. type
  1258. pprocdefcoll = ^tprocdefcoll;
  1259. tprocdefcoll = record
  1260. data : tprocdef;
  1261. nextpara : tparaitem;
  1262. firstpara : tparaitem;
  1263. next : pprocdefcoll;
  1264. end;
  1265. var
  1266. hp,procs,hp2 : pprocdefcoll;
  1267. pd : tprocdef;
  1268. oldcallprocdef : tabstractprocdef;
  1269. def_from,def_to,conv_to : tdef;
  1270. hpt : tnode;
  1271. pt : tcallparanode;
  1272. exactmatch : boolean;
  1273. paralength,lastpara : longint;
  1274. lastparatype : tdef;
  1275. pdc : tparaitem;
  1276. { only Dummy }
  1277. hcvt : tconverttype;
  1278. label
  1279. errorexit;
  1280. { check if the resulttype.def from tree p is equal with def, needed
  1281. for stringconstn and formaldef }
  1282. function is_equal(p:tcallparanode;def:tdef) : boolean;
  1283. begin
  1284. { safety check }
  1285. if not (assigned(def) or assigned(p.resulttype.def)) then
  1286. begin
  1287. is_equal:=false;
  1288. exit;
  1289. end;
  1290. { all types can be passed to a formaldef }
  1291. is_equal:=(def.deftype=formaldef) or
  1292. (defbase.is_equal(p.resulttype.def,def))
  1293. { integer constants are compatible with all integer parameters if
  1294. the specified value matches the range }
  1295. or
  1296. (
  1297. (tbinarynode(p).left.nodetype=ordconstn) and
  1298. is_integer(p.resulttype.def) and
  1299. is_integer(def) and
  1300. (tordconstnode(p.left).value>=torddef(def).low) and
  1301. (tordconstnode(p.left).value<=torddef(def).high)
  1302. )
  1303. { to support ansi/long/wide strings in a proper way }
  1304. { string and string[10] are assumed as equal }
  1305. { when searching the correct overloaded procedure }
  1306. or
  1307. (
  1308. (def.deftype=stringdef) and (p.resulttype.def.deftype=stringdef) and
  1309. (tstringdef(def).string_typ=tstringdef(p.resulttype.def).string_typ)
  1310. )
  1311. or
  1312. (
  1313. (p.left.nodetype=stringconstn) and
  1314. (is_ansistring(p.resulttype.def) and is_pchar(def))
  1315. )
  1316. or
  1317. (
  1318. (p.left.nodetype=ordconstn) and
  1319. (is_char(p.resulttype.def) and (is_shortstring(def) or is_ansistring(def)))
  1320. )
  1321. { set can also be a not yet converted array constructor }
  1322. or
  1323. (
  1324. (def.deftype=setdef) and (p.resulttype.def.deftype=arraydef) and
  1325. (tarraydef(p.resulttype.def).IsConstructor) and not(tarraydef(p.resulttype.def).IsVariant)
  1326. )
  1327. { in tp7 mode proc -> procvar is allowed }
  1328. or
  1329. (
  1330. (m_tp_procvar in aktmodeswitches) and
  1331. (def.deftype=procvardef) and (p.left.nodetype=calln) and
  1332. (proc_to_procvar_equal(tprocdef(tcallnode(p.left).procdefinition),tprocvardef(def),false))
  1333. )
  1334. ;
  1335. end;
  1336. var
  1337. i,j : longint;
  1338. has_overload_directive,
  1339. found,
  1340. is_const : boolean;
  1341. bestord : torddef;
  1342. srprocsym : tprocsym;
  1343. srsymtable : tsymtable;
  1344. begin
  1345. result:=nil;
  1346. procs:=nil;
  1347. has_overload_directive:=false;
  1348. oldcallprocdef:=aktcallprocdef;
  1349. aktcallprocdef:=nil;
  1350. { determine length of parameter list }
  1351. pt:=tcallparanode(left);
  1352. paralength:=0;
  1353. while assigned(pt) do
  1354. begin
  1355. inc(paralength);
  1356. pt:=tcallparanode(pt.right);
  1357. end;
  1358. { determine the type of the parameters }
  1359. if assigned(left) then
  1360. begin
  1361. tcallparanode(left).get_paratype;
  1362. if codegenerror then
  1363. goto errorexit;
  1364. end;
  1365. { procedure variable ? }
  1366. if assigned(right) then
  1367. begin
  1368. set_varstate(right,true);
  1369. resulttypepass(right);
  1370. if codegenerror then
  1371. exit;
  1372. procdefinition:=tabstractprocdef(right.resulttype.def);
  1373. { check the amount of parameters }
  1374. pdc:=tparaitem(procdefinition.Para.first);
  1375. pt:=tcallparanode(left);
  1376. lastpara:=paralength;
  1377. while assigned(pdc) and assigned(pt) do
  1378. begin
  1379. { only goto next para if we're out of the varargs }
  1380. if not(po_varargs in procdefinition.procoptions) or
  1381. (lastpara<=procdefinition.maxparacount) then
  1382. pdc:=tparaitem(pdc.next);
  1383. pt:=tcallparanode(pt.right);
  1384. dec(lastpara);
  1385. end;
  1386. if assigned(pt) or assigned(pdc) then
  1387. begin
  1388. if assigned(pt) then
  1389. aktfilepos:=pt.fileinfo;
  1390. CGMessage(parser_e_wrong_parameter_size);
  1391. end;
  1392. end
  1393. else
  1394. { not a procedure variable }
  1395. begin
  1396. { do we know the procedure to call ? }
  1397. if not(assigned(procdefinition)) then
  1398. begin
  1399. { when the definition has overload directive set, we search for
  1400. overloaded definitions in the class, this only needs to be done once
  1401. for class entries as the tree keeps always the same }
  1402. if (not symtableprocentry.overloadchecked) and
  1403. (po_overload in symtableprocentry.first_procdef.procoptions) and
  1404. (symtableprocentry.owner.symtabletype=objectsymtable) then
  1405. search_class_overloads(symtableprocentry);
  1406. { link all procedures which have the same # of parameters }
  1407. for j:=1 to symtableprocentry.procdef_count do
  1408. begin
  1409. pd:=symtableprocentry.procdef[j];
  1410. { only when the # of parameter are supported by the
  1411. procedure }
  1412. if (paralength>=pd.minparacount) and
  1413. ((po_varargs in pd.procoptions) or { varargs }
  1414. (paralength<=pd.maxparacount)) then
  1415. begin
  1416. new(hp);
  1417. hp^.data:=pd;
  1418. hp^.next:=procs;
  1419. hp^.firstpara:=tparaitem(pd.Para.first);
  1420. if not(po_varargs in pd.procoptions) then
  1421. begin
  1422. { if not all parameters are given, then skip the
  1423. default parameters }
  1424. for i:=1 to pd.maxparacount-paralength do
  1425. hp^.firstpara:=tparaitem(hp^.firstPara.next);
  1426. end;
  1427. hp^.nextpara:=hp^.firstpara;
  1428. procs:=hp;
  1429. end;
  1430. end;
  1431. { remember if the procedure is declared with the overload directive,
  1432. it's information is still needed also after all procs are removed }
  1433. has_overload_directive:=(po_overload in symtableprocentry.first_procdef.procoptions);
  1434. { when the definition has overload directive set, we search for
  1435. overloaded definitions in the symtablestack. The found
  1436. entries are only added to the procs list and not the procsym, because
  1437. the list can change in every situation }
  1438. if has_overload_directive and
  1439. (symtableprocentry.owner.symtabletype<>objectsymtable) then
  1440. begin
  1441. srsymtable:=symtableprocentry.owner.next;
  1442. while assigned(srsymtable) do
  1443. begin
  1444. if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
  1445. begin
  1446. srprocsym:=tprocsym(srsymtable.speedsearch(symtableprocentry.name,symtableprocentry.speedvalue));
  1447. { process only visible procsyms }
  1448. if assigned(srprocsym) and
  1449. (srprocsym.typ=procsym) and
  1450. srprocsym.is_visible_for_proc(aktprocdef) then
  1451. begin
  1452. { if this procedure doesn't have overload we can stop
  1453. searching }
  1454. if not(po_overload in srprocsym.first_procdef.procoptions) then
  1455. break;
  1456. { process all overloaded definitions }
  1457. for j:=1 to srprocsym.procdef_count do
  1458. begin
  1459. pd:=srprocsym.procdef[j];
  1460. { only when the # of parameter are supported by the
  1461. procedure }
  1462. if (paralength>=pd.minparacount) and
  1463. ((po_varargs in pd.procoptions) or { varargs }
  1464. (paralength<=pd.maxparacount)) then
  1465. begin
  1466. found:=false;
  1467. hp:=procs;
  1468. while assigned(hp) do
  1469. begin
  1470. if equal_paras(hp^.data.para,pd.para,cp_value_equal_const,false) then
  1471. begin
  1472. found:=true;
  1473. break;
  1474. end;
  1475. hp:=hp^.next;
  1476. end;
  1477. if not found then
  1478. begin
  1479. new(hp);
  1480. hp^.data:=pd;
  1481. hp^.next:=procs;
  1482. hp^.firstpara:=tparaitem(pd.Para.first);
  1483. if not(po_varargs in pd.procoptions) then
  1484. begin
  1485. { if not all parameters are given, then skip the
  1486. default parameters }
  1487. for i:=1 to pd.maxparacount-paralength do
  1488. hp^.firstpara:=tparaitem(hp^.firstPara.next);
  1489. end;
  1490. hp^.nextpara:=hp^.firstpara;
  1491. procs:=hp;
  1492. end;
  1493. end;
  1494. end;
  1495. end;
  1496. end;
  1497. srsymtable:=srsymtable.next;
  1498. end;
  1499. end;
  1500. { no procedures found? then there is something wrong
  1501. with the parameter size }
  1502. if not assigned(procs) then
  1503. begin
  1504. { when it's an auto inherited call and there
  1505. is no procedure found, but the procedures
  1506. were defined with overload directive and at
  1507. least two procedures are defined then we ignore
  1508. this inherited by inserting a nothingn. Only
  1509. do this ugly hack in Delphi mode as it looks more
  1510. like a bug. It's also not documented }
  1511. if (m_delphi in aktmodeswitches) and
  1512. (nf_auto_inherited in flags) and
  1513. (has_overload_directive) and
  1514. (symtableprocentry.procdef_count>=2) then
  1515. result:=cnothingnode.create
  1516. else
  1517. begin
  1518. { in tp mode we can try to convert to procvar if
  1519. there are no parameters specified. Only try it
  1520. when there is only one proc definition, else the
  1521. loadnode will give a strange error }
  1522. if not(assigned(left)) and
  1523. (m_tp_procvar in aktmodeswitches) and
  1524. (symtableprocentry.procdef_count=1) then
  1525. begin
  1526. hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc);
  1527. if (symtableprocentry.owner.symtabletype=objectsymtable) and
  1528. assigned(methodpointer) then
  1529. tloadnode(hpt).set_mp(methodpointer.getcopy);
  1530. resulttypepass(hpt);
  1531. result:=hpt;
  1532. end
  1533. else
  1534. begin
  1535. if assigned(left) then
  1536. aktfilepos:=left.fileinfo;
  1537. CGMessage(parser_e_wrong_parameter_size);
  1538. symtableprocentry.write_parameter_lists(nil);
  1539. end;
  1540. end;
  1541. goto errorexit;
  1542. end;
  1543. { now we can compare parameter after parameter }
  1544. pt:=tcallparanode(left);
  1545. { we start with the last parameter }
  1546. lastpara:=paralength+1;
  1547. lastparatype:=nil;
  1548. while assigned(pt) do
  1549. begin
  1550. dec(lastpara);
  1551. { walk all procedures and determine how this parameter matches and set:
  1552. 1. pt.exact_match_found if one parameter has an exact match
  1553. 2. exactmatch if an equal or exact match is found
  1554. 3. Para.argconvtyp to exact,equal or convertable
  1555. (when convertable then also convertlevel is set)
  1556. 4. pt.convlevel1found if there is a convertlevel=1
  1557. 5. pt.convlevel2found if there is a convertlevel=2
  1558. }
  1559. exactmatch:=false;
  1560. hp:=procs;
  1561. while assigned(hp) do
  1562. begin
  1563. { varargs are always equal, but not exact }
  1564. if (po_varargs in hp^.data.procoptions) and
  1565. (lastpara>hp^.data.minparacount) then
  1566. begin
  1567. hp^.nextPara.argconvtyp:=act_equal;
  1568. exactmatch:=true;
  1569. end
  1570. else
  1571. begin
  1572. if is_equal(pt,hp^.nextPara.paratype.def) then
  1573. begin
  1574. if hp^.nextPara.paratype.def=pt.resulttype.def then
  1575. begin
  1576. include(pt.callparaflags,cpf_exact_match_found);
  1577. hp^.nextPara.argconvtyp:=act_exact;
  1578. end
  1579. else
  1580. hp^.nextPara.argconvtyp:=act_equal;
  1581. exactmatch:=true;
  1582. end
  1583. else
  1584. begin
  1585. hp^.nextPara.argconvtyp:=act_convertable;
  1586. { var and out parameters are not be convertable
  1587. in Delphi/tp mode. The only exception is when the
  1588. procedure is defined in the system unit }
  1589. if (hp^.nextPara.paratyp in [vs_var,vs_out]) and
  1590. (procs^.data.owner.unitid<>1) and
  1591. ((m_delphi in aktmodeswitches) or
  1592. (m_tp7 in aktmodeswitches)) then
  1593. hp^.nextPara.convertlevel:=0
  1594. else
  1595. hp^.nextPara.convertlevel:=isconvertable(pt.resulttype.def,hp^.nextPara.paratype.def,
  1596. hcvt,pt.left.nodetype,false);
  1597. case hp^.nextPara.convertlevel of
  1598. 1 : include(pt.callparaflags,cpf_convlevel1found);
  1599. 2 : include(pt.callparaflags,cpf_convlevel2found);
  1600. end;
  1601. end;
  1602. end;
  1603. hp:=hp^.next;
  1604. end;
  1605. { If there was an exactmatch then delete all convertables }
  1606. if exactmatch then
  1607. begin
  1608. hp:=procs;
  1609. procs:=nil;
  1610. while assigned(hp) do
  1611. begin
  1612. hp2:=hp^.next;
  1613. { keep if not convertable }
  1614. if (hp^.nextPara.argconvtyp<>act_convertable) then
  1615. begin
  1616. hp^.next:=procs;
  1617. procs:=hp;
  1618. end
  1619. else
  1620. dispose(hp);
  1621. hp:=hp2;
  1622. end;
  1623. end
  1624. else
  1625. { No exact match was found, remove all procedures that are
  1626. not convertable (convertlevel=0) }
  1627. begin
  1628. hp:=procs;
  1629. procs:=nil;
  1630. while assigned(hp) do
  1631. begin
  1632. hp2:=hp^.next;
  1633. { keep if not convertable }
  1634. if (hp^.nextPara.convertlevel<>0) then
  1635. begin
  1636. hp^.next:=procs;
  1637. procs:=hp;
  1638. end
  1639. else
  1640. begin
  1641. { save the type for nice error message }
  1642. lastparatype:=hp^.nextPara.paratype.def;
  1643. dispose(hp);
  1644. end;
  1645. hp:=hp2;
  1646. end;
  1647. end;
  1648. { update nextpara for all procedures }
  1649. hp:=procs;
  1650. while assigned(hp) do
  1651. begin
  1652. { only goto next para if we're out of the varargs }
  1653. if not(po_varargs in hp^.data.procoptions) or
  1654. (lastpara<=hp^.data.maxparacount) then
  1655. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1656. hp:=hp^.next;
  1657. end;
  1658. { load next parameter or quit loop if no procs left }
  1659. if assigned(procs) then
  1660. pt:=tcallparanode(pt.right)
  1661. else
  1662. break;
  1663. end;
  1664. { All parameters are checked, check if there are any
  1665. procedures left }
  1666. if not assigned(procs) then
  1667. begin
  1668. { there is an error, must be wrong type, because
  1669. wrong size is already checked (PFV) }
  1670. if (not assigned(lastparatype)) or
  1671. (not assigned(pt)) or
  1672. (not assigned(pt.resulttype.def)) then
  1673. internalerror(39393)
  1674. else
  1675. begin
  1676. aktfilepos:=pt.fileinfo;
  1677. CGMessage3(type_e_wrong_parameter_type,tostr(lastpara),
  1678. pt.resulttype.def.typename,lastparatype.typename);
  1679. end;
  1680. symtableprocentry.write_parameter_lists(nil);
  1681. goto errorexit;
  1682. end;
  1683. { if there are several choices left then for orddef }
  1684. { if a type is totally included in the other }
  1685. { we don't fear an overflow , }
  1686. { so we can do as if it is an exact match }
  1687. { this will convert integer to longint }
  1688. { rather than to words }
  1689. { conversion of byte to integer or longint }
  1690. { would still not be solved }
  1691. if assigned(procs) and assigned(procs^.next) then
  1692. begin
  1693. hp:=procs;
  1694. while assigned(hp) do
  1695. begin
  1696. hp^.nextpara:=hp^.firstpara;
  1697. hp:=hp^.next;
  1698. end;
  1699. pt:=tcallparanode(left);
  1700. while assigned(pt) do
  1701. begin
  1702. { matches a parameter of one procedure exact ? }
  1703. exactmatch:=false;
  1704. def_from:=pt.resulttype.def;
  1705. hp:=procs;
  1706. while assigned(hp) do
  1707. begin
  1708. if not is_equal(pt,hp^.nextPara.paratype.def) then
  1709. begin
  1710. def_to:=hp^.nextPara.paratype.def;
  1711. if ((def_from.deftype=orddef) and (def_to.deftype=orddef)) and
  1712. (is_in_limit(def_from,def_to) or
  1713. ((hp^.nextPara.paratyp in [vs_var,vs_out]) and
  1714. (def_from.size=def_to.size))) then
  1715. begin
  1716. exactmatch:=true;
  1717. conv_to:=def_to;
  1718. { there's no use in continuing the search, it will }
  1719. { only result in conv_to being overwritten }
  1720. break;
  1721. end;
  1722. end;
  1723. hp:=hp^.next;
  1724. end;
  1725. { .... if yes, del all the other procedures }
  1726. if exactmatch then
  1727. begin
  1728. { the first .... }
  1729. while (assigned(procs)) and not(is_in_limit(def_from,procs^.nextPara.paratype.def)) do
  1730. begin
  1731. hp:=procs^.next;
  1732. dispose(procs);
  1733. procs:=hp;
  1734. end;
  1735. { and the others }
  1736. hp:=procs;
  1737. while (assigned(hp)) and assigned(hp^.next) do
  1738. begin
  1739. def_to:=hp^.next^.nextPara.paratype.def;
  1740. if not(is_in_limit(def_from,def_to)) then
  1741. begin
  1742. hp2:=hp^.next^.next;
  1743. dispose(hp^.next);
  1744. hp^.next:=hp2;
  1745. end
  1746. else
  1747. begin
  1748. { did we possibly find a better match? }
  1749. if (conv_to.size>def_to.size) or
  1750. is_in_limit(def_to,conv_to) then
  1751. begin
  1752. { is it the same as the previous best? }
  1753. if not defbase.is_equal(def_to,conv_to) then
  1754. begin
  1755. { no -> remove all previous best matches }
  1756. hp := hp^.next;
  1757. while procs <> hp do
  1758. begin
  1759. hp2 := procs;
  1760. procs := procs^.next;
  1761. dispose(hp2);
  1762. end;
  1763. { set new match type }
  1764. conv_to:=def_to;
  1765. end
  1766. { the new one matches just as well as the }
  1767. { old one -> keep both }
  1768. else
  1769. hp := hp^.next;
  1770. end
  1771. { not a better match -> remove }
  1772. else
  1773. begin
  1774. hp2 := hp^.next^.next;
  1775. dispose(hp^.next);
  1776. hp^.next:=hp2;
  1777. end;
  1778. end;
  1779. end;
  1780. end;
  1781. { update nextpara for all procedures }
  1782. hp:=procs;
  1783. while assigned(hp) do
  1784. begin
  1785. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1786. hp:=hp^.next;
  1787. end;
  1788. pt:=tcallparanode(pt.right);
  1789. end;
  1790. end;
  1791. { let's try to eliminate equal if there is an exact match
  1792. is there }
  1793. if assigned(procs) and assigned(procs^.next) then
  1794. begin
  1795. { reset nextpara for all procs left }
  1796. hp:=procs;
  1797. while assigned(hp) do
  1798. begin
  1799. hp^.nextpara:=hp^.firstpara;
  1800. hp:=hp^.next;
  1801. end;
  1802. pt:=tcallparanode(left);
  1803. while assigned(pt) do
  1804. begin
  1805. if cpf_exact_match_found in pt.callparaflags then
  1806. begin
  1807. hp:=procs;
  1808. procs:=nil;
  1809. while assigned(hp) do
  1810. begin
  1811. hp2:=hp^.next;
  1812. { keep the exact matches, dispose the others }
  1813. if (hp^.nextPara.argconvtyp=act_exact) then
  1814. begin
  1815. hp^.next:=procs;
  1816. procs:=hp;
  1817. end
  1818. else
  1819. dispose(hp);
  1820. hp:=hp2;
  1821. end;
  1822. end;
  1823. { update nextpara for all procedures }
  1824. hp:=procs;
  1825. while assigned(hp) do
  1826. begin
  1827. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1828. hp:=hp^.next;
  1829. end;
  1830. pt:=tcallparanode(pt.right);
  1831. end;
  1832. end;
  1833. { Check if there are integer constant to integer
  1834. parameters then choose the best matching integer
  1835. parameter and remove the others, this is Delphi
  1836. compatible. 1 = byte, 256 = word, etc. }
  1837. if assigned(procs) and assigned(procs^.next) then
  1838. begin
  1839. { reset nextpara for all procs left }
  1840. hp:=procs;
  1841. while assigned(hp) do
  1842. begin
  1843. hp^.nextpara:=hp^.firstpara;
  1844. hp:=hp^.next;
  1845. end;
  1846. pt:=tcallparanode(left);
  1847. while assigned(pt) do
  1848. begin
  1849. bestord:=nil;
  1850. if (pt.left.nodetype=ordconstn) and
  1851. is_integer(pt.resulttype.def) then
  1852. begin
  1853. hp:=procs;
  1854. while assigned(hp) do
  1855. begin
  1856. def_to:=hp^.nextPara.paratype.def;
  1857. { to be sure, it couldn't be something else,
  1858. also the defs here are all in the range
  1859. so now find the closest range }
  1860. if not is_integer(def_to) then
  1861. internalerror(43297815);
  1862. if (not assigned(bestord)) or
  1863. ((torddef(def_to).low>bestord.low) or
  1864. (torddef(def_to).high<bestord.high)) then
  1865. bestord:=torddef(def_to);
  1866. hp:=hp^.next;
  1867. end;
  1868. end;
  1869. { if a bestmatch is found then remove the other
  1870. procs which don't match the bestord }
  1871. if assigned(bestord) then
  1872. begin
  1873. hp:=procs;
  1874. procs:=nil;
  1875. while assigned(hp) do
  1876. begin
  1877. hp2:=hp^.next;
  1878. { keep matching bestord, dispose the others }
  1879. if (torddef(hp^.nextPara.paratype.def)=bestord) then
  1880. begin
  1881. hp^.next:=procs;
  1882. procs:=hp;
  1883. end
  1884. else
  1885. dispose(hp);
  1886. hp:=hp2;
  1887. end;
  1888. end;
  1889. { update nextpara for all procedures }
  1890. hp:=procs;
  1891. while assigned(hp) do
  1892. begin
  1893. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1894. hp:=hp^.next;
  1895. end;
  1896. pt:=tcallparanode(pt.right);
  1897. end;
  1898. end;
  1899. { Check if there are convertlevel 1 and 2 differences
  1900. left for the parameters, then discard all convertlevel
  1901. 2 procedures. The value of convlevelXfound can still
  1902. be used, because all convertables are still here or
  1903. not }
  1904. if assigned(procs) and assigned(procs^.next) then
  1905. begin
  1906. { reset nextpara for all procs left }
  1907. hp:=procs;
  1908. while assigned(hp) do
  1909. begin
  1910. hp^.nextpara:=hp^.firstpara;
  1911. hp:=hp^.next;
  1912. end;
  1913. pt:=tcallparanode(left);
  1914. while assigned(pt) do
  1915. begin
  1916. if (cpf_convlevel1found in pt.callparaflags) and
  1917. (cpf_convlevel2found in pt.callparaflags) then
  1918. begin
  1919. hp:=procs;
  1920. procs:=nil;
  1921. while assigned(hp) do
  1922. begin
  1923. hp2:=hp^.next;
  1924. { keep all not act_convertable and all convertlevels=1 }
  1925. if (hp^.nextPara.argconvtyp<>act_convertable) or
  1926. (hp^.nextPara.convertlevel=1) then
  1927. begin
  1928. hp^.next:=procs;
  1929. procs:=hp;
  1930. end
  1931. else
  1932. dispose(hp);
  1933. hp:=hp2;
  1934. end;
  1935. end;
  1936. { update nextpara for all procedures }
  1937. hp:=procs;
  1938. while assigned(hp) do
  1939. begin
  1940. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1941. hp:=hp^.next;
  1942. end;
  1943. pt:=tcallparanode(pt.right);
  1944. end;
  1945. end;
  1946. if not(assigned(procs)) or assigned(procs^.next) then
  1947. begin
  1948. CGMessage(cg_e_cant_choose_overload_function);
  1949. symtableprocentry.write_parameter_lists(nil);
  1950. goto errorexit;
  1951. end;
  1952. if make_ref then
  1953. begin
  1954. procs^.data.lastref:=tref.create(procs^.data.lastref,@fileinfo);
  1955. inc(procs^.data.refcount);
  1956. if procs^.data.defref=nil then
  1957. procs^.data.defref:=procs^.data.lastref;
  1958. end;
  1959. procdefinition:=procs^.data;
  1960. { big error for with statements
  1961. symtableproc:=procdefinition.owner;
  1962. but neede for overloaded operators !! }
  1963. if symtableproc=nil then
  1964. symtableproc:=procdefinition.owner;
  1965. end; { end of procedure to call determination }
  1966. { add needed default parameters }
  1967. if assigned(procs) and
  1968. (paralength<procdefinition.maxparacount) then
  1969. begin
  1970. { add default parameters, just read back the skipped
  1971. paras starting from firstPara.previous, when not available
  1972. (all parameters are default) then start with the last
  1973. parameter and read backward (PFV) }
  1974. if not assigned(procs^.firstpara) then
  1975. pdc:=tparaitem(procs^.data.Para.last)
  1976. else
  1977. pdc:=tparaitem(procs^.firstPara.previous);
  1978. while assigned(pdc) do
  1979. begin
  1980. if not assigned(pdc.defaultvalue) then
  1981. internalerror(751349858);
  1982. left:=ccallparanode.create(genconstsymtree(tconstsym(pdc.defaultvalue)),left);
  1983. pdc:=tparaitem(pdc.previous);
  1984. end;
  1985. end;
  1986. end;
  1987. { handle predefined procedures }
  1988. is_const:=(po_internconst in procdefinition.procoptions) and
  1989. ((block_type in [bt_const,bt_type]) or
  1990. (assigned(left) and (tcallparanode(left).left.nodetype in [realconstn,ordconstn])));
  1991. if (procdefinition.proccalloption=pocall_internproc) or is_const then
  1992. begin
  1993. if assigned(left) then
  1994. begin
  1995. { ptr and settextbuf needs two args }
  1996. if assigned(tcallparanode(left).right) then
  1997. begin
  1998. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,left);
  1999. left:=nil;
  2000. end
  2001. else
  2002. begin
  2003. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,tcallparanode(left).left);
  2004. tcallparanode(left).left:=nil;
  2005. end;
  2006. end
  2007. else
  2008. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,nil);
  2009. result:=hpt;
  2010. goto errorexit;
  2011. end;
  2012. {$ifdef dummy}
  2013. { Calling a message method directly ? }
  2014. if assigned(procdefinition) and
  2015. (po_containsself in procdefinition.procoptions) then
  2016. message(cg_e_cannot_call_message_direct);
  2017. {$endif}
  2018. { ensure that the result type is set }
  2019. if not restypeset then
  2020. resulttype:=procdefinition.rettype
  2021. else
  2022. resulttype:=restype;
  2023. { modify the exit code, in case of special cases }
  2024. if (not is_void(resulttype.def)) then
  2025. begin
  2026. if paramanager.ret_in_reg(resulttype.def) then
  2027. begin
  2028. { wide- and ansistrings are returned in EAX }
  2029. { but they are imm. moved to a memory location }
  2030. if is_widestring(resulttype.def) or
  2031. is_ansistring(resulttype.def) then
  2032. begin
  2033. { we use ansistrings so no fast exit here }
  2034. if assigned(procinfo) then
  2035. procinfo.no_fast_exit:=true;
  2036. end;
  2037. end;
  2038. end;
  2039. { constructors return their current class type, not the type where the
  2040. constructor is declared, this can be different because of inheritance }
  2041. if (procdefinition.proctypeoption=potype_constructor) then
  2042. begin
  2043. if assigned(methodpointer) and
  2044. assigned(methodpointer.resulttype.def) and
  2045. (methodpointer.resulttype.def.deftype=classrefdef) then
  2046. resulttype:=tclassrefdef(methodpointer.resulttype.def).pointertype;
  2047. end;
  2048. { flag all callparanodes that belong to the varargs }
  2049. if (po_varargs in procdefinition.procoptions) then
  2050. begin
  2051. pt:=tcallparanode(left);
  2052. i:=paralength;
  2053. while (i>procdefinition.maxparacount) do
  2054. begin
  2055. include(tcallparanode(pt).flags,nf_varargs_para);
  2056. pt:=tcallparanode(pt.right);
  2057. dec(i);
  2058. end;
  2059. end;
  2060. { insert type conversions }
  2061. if assigned(left) then
  2062. begin
  2063. aktcallprocdef:=procdefinition;
  2064. tcallparanode(left).insert_typeconv(tparaitem(procdefinition.Para.first),true);
  2065. end;
  2066. errorexit:
  2067. { Reset some settings back }
  2068. if assigned(procs) then
  2069. dispose(procs);
  2070. aktcallprocdef:=oldcallprocdef;
  2071. end;
  2072. {$endif}
  2073. function tcallnode.pass_1 : tnode;
  2074. var
  2075. inlinecode : tnode;
  2076. inlined : boolean;
  2077. {$ifdef m68k}
  2078. regi : tregister;
  2079. {$endif}
  2080. method_must_be_valid : boolean;
  2081. label
  2082. errorexit;
  2083. begin
  2084. { the default is nothing to return }
  2085. location.loc:=LOC_INVALID;
  2086. result:=nil;
  2087. inlined:=false;
  2088. inlinecode := nil;
  2089. { work trough all parameters to get the register requirements }
  2090. if assigned(left) then
  2091. tcallparanode(left).det_registers;
  2092. { return node }
  2093. if assigned(funcretrefnode) then
  2094. firstpass(funcretrefnode);
  2095. if assigned(procdefinition) and
  2096. (procdefinition.proccalloption=pocall_inline) then
  2097. begin
  2098. inlinecode:=right;
  2099. if assigned(inlinecode) then
  2100. inlined:=true;
  2101. right:=nil;
  2102. end;
  2103. { procedure variable ? }
  2104. if assigned(right) then
  2105. begin
  2106. firstpass(right);
  2107. { procedure does a call }
  2108. if not (block_type in [bt_const,bt_type]) then
  2109. procinfo.flags:=procinfo.flags or pi_do_call;
  2110. rg.incrementregisterpushed(all_registers);
  2111. end
  2112. else
  2113. { not a procedure variable }
  2114. begin
  2115. { calc the correture value for the register }
  2116. { handle predefined procedures }
  2117. if (procdefinition.proccalloption=pocall_inline) then
  2118. begin
  2119. if assigned(methodpointer) then
  2120. CGMessage(cg_e_unable_inline_object_methods);
  2121. if assigned(right) and (right.nodetype<>procinlinen) then
  2122. CGMessage(cg_e_unable_inline_procvar);
  2123. { nodetype:=procinlinen; }
  2124. if not assigned(right) then
  2125. begin
  2126. if assigned(tprocdef(procdefinition).code) then
  2127. inlinecode:=cprocinlinenode.create(tprocdef(procdefinition))
  2128. else
  2129. CGMessage(cg_e_no_code_for_inline_stored);
  2130. if assigned(inlinecode) then
  2131. begin
  2132. { consider it has not inlined if called
  2133. again inside the args }
  2134. procdefinition.proccalloption:=pocall_fpccall;
  2135. firstpass(inlinecode);
  2136. inlined:=true;
  2137. end;
  2138. end;
  2139. end
  2140. else
  2141. begin
  2142. if not (block_type in [bt_const,bt_type]) then
  2143. procinfo.flags:=procinfo.flags or pi_do_call;
  2144. end;
  2145. { It doesn't hurt to calculate it already though :) (JM) }
  2146. rg.incrementregisterpushed(tprocdef(procdefinition).usedregisters);
  2147. end;
  2148. { get a register for the return value }
  2149. if (not is_void(resulttype.def)) then
  2150. begin
  2151. if paramanager.ret_in_param(resulttype.def) then
  2152. begin
  2153. location.loc:=LOC_CREFERENCE;
  2154. end
  2155. else
  2156. { ansi/widestrings must be registered, so we can dispose them }
  2157. if is_ansistring(resulttype.def) or
  2158. is_widestring(resulttype.def) then
  2159. begin
  2160. location.loc:=LOC_CREFERENCE;
  2161. registers32:=1;
  2162. end
  2163. else
  2164. { we have only to handle the result if it is used }
  2165. if (nf_return_value_used in flags) then
  2166. begin
  2167. case resulttype.def.deftype of
  2168. enumdef,
  2169. orddef :
  2170. begin
  2171. if (procdefinition.proctypeoption=potype_constructor) then
  2172. begin
  2173. if assigned(methodpointer) and
  2174. (methodpointer.resulttype.def.deftype=classrefdef) then
  2175. begin
  2176. location.loc:=LOC_REGISTER;
  2177. registers32:=1;
  2178. end
  2179. else
  2180. location.loc:=LOC_FLAGS;
  2181. end
  2182. else
  2183. begin
  2184. location.loc:=LOC_REGISTER;
  2185. if is_64bitint(resulttype.def) then
  2186. registers32:=2
  2187. else
  2188. registers32:=1;
  2189. end;
  2190. end;
  2191. floatdef :
  2192. begin
  2193. location.loc:=LOC_FPUREGISTER;
  2194. {$ifdef m68k}
  2195. if (cs_fp_emulation in aktmoduleswitches) or
  2196. (tfloatdef(resulttype.def).typ=s32real) then
  2197. registers32:=1
  2198. else
  2199. registersfpu:=1;
  2200. {$else not m68k}
  2201. registersfpu:=1;
  2202. {$endif not m68k}
  2203. end;
  2204. else
  2205. begin
  2206. location.loc:=LOC_REGISTER;
  2207. registers32:=1;
  2208. end;
  2209. end;
  2210. end;
  2211. end;
  2212. { a fpu can be used in any procedure !! }
  2213. {$ifdef i386}
  2214. registersfpu:=procdefinition.fpu_used;
  2215. {$endif i386}
  2216. { if this is a call to a method calc the registers }
  2217. if (methodpointer<>nil) then
  2218. begin
  2219. case methodpointer.nodetype of
  2220. { but only, if this is not a supporting node }
  2221. typen: ;
  2222. { we need one register for new return value PM }
  2223. hnewn : if registers32=0 then
  2224. registers32:=1;
  2225. else
  2226. begin
  2227. if (procdefinition.proctypeoption in [potype_constructor,potype_destructor]) and
  2228. assigned(symtableproc) and (symtableproc.symtabletype=withsymtable) and
  2229. not twithsymtable(symtableproc).direct_with then
  2230. begin
  2231. CGmessage(cg_e_cannot_call_cons_dest_inside_with);
  2232. end; { Is accepted by Delphi !! }
  2233. { this is not a good reason to accept it in FPC if we produce
  2234. wrong code for it !!! (PM) }
  2235. { R.Assign is not a constructor !!! }
  2236. { but for R^.Assign, R must be valid !! }
  2237. if (procdefinition.proctypeoption=potype_constructor) or
  2238. ((methodpointer.nodetype=loadn) and
  2239. ((methodpointer.resulttype.def.deftype=classrefdef) or
  2240. ((methodpointer.resulttype.def.deftype=objectdef) and
  2241. not(oo_has_virtual in tobjectdef(methodpointer.resulttype.def).objectoptions)
  2242. )
  2243. )
  2244. ) then
  2245. method_must_be_valid:=false
  2246. else
  2247. method_must_be_valid:=true;
  2248. firstpass(methodpointer);
  2249. set_varstate(methodpointer,method_must_be_valid);
  2250. { The object is already used ven if it is called once }
  2251. if (methodpointer.nodetype=loadn) and
  2252. (tloadnode(methodpointer).symtableentry.typ=varsym) then
  2253. tvarsym(tloadnode(methodpointer).symtableentry).varstate:=vs_used;
  2254. registersfpu:=max(methodpointer.registersfpu,registersfpu);
  2255. registers32:=max(methodpointer.registers32,registers32);
  2256. {$ifdef SUPPORT_MMX }
  2257. registersmmx:=max(methodpointer.registersmmx,registersmmx);
  2258. {$endif SUPPORT_MMX}
  2259. end;
  2260. end;
  2261. end;
  2262. if inlined then
  2263. right:=inlinecode;
  2264. { determine the registers of the procedure variable }
  2265. { is this OK for inlined procs also ?? (PM) }
  2266. if assigned(right) then
  2267. begin
  2268. registersfpu:=max(right.registersfpu,registersfpu);
  2269. registers32:=max(right.registers32,registers32);
  2270. {$ifdef SUPPORT_MMX}
  2271. registersmmx:=max(right.registersmmx,registersmmx);
  2272. {$endif SUPPORT_MMX}
  2273. end;
  2274. { determine the registers of the procedure }
  2275. if assigned(left) then
  2276. begin
  2277. registersfpu:=max(left.registersfpu,registersfpu);
  2278. registers32:=max(left.registers32,registers32);
  2279. {$ifdef SUPPORT_MMX}
  2280. registersmmx:=max(left.registersmmx,registersmmx);
  2281. {$endif SUPPORT_MMX}
  2282. end;
  2283. errorexit:
  2284. if inlined then
  2285. procdefinition.proccalloption:=pocall_inline;
  2286. end;
  2287. {$ifdef state_tracking}
  2288. function Tcallnode.track_state_pass(exec_known:boolean):boolean;
  2289. var hp:Tcallparanode;
  2290. value:Tnode;
  2291. begin
  2292. track_state_pass:=false;
  2293. hp:=Tcallparanode(left);
  2294. while assigned(hp) do
  2295. begin
  2296. if left.track_state_pass(exec_known) then
  2297. begin
  2298. left.resulttype.def:=nil;
  2299. do_resulttypepass(left);
  2300. end;
  2301. value:=aktstate.find_fact(hp.left);
  2302. if value<>nil then
  2303. begin
  2304. track_state_pass:=true;
  2305. hp.left.destroy;
  2306. hp.left:=value.getcopy;
  2307. do_resulttypepass(hp.left);
  2308. end;
  2309. hp:=Tcallparanode(hp.right);
  2310. end;
  2311. end;
  2312. {$endif}
  2313. function tcallnode.docompare(p: tnode): boolean;
  2314. begin
  2315. docompare :=
  2316. inherited docompare(p) and
  2317. (symtableprocentry = tcallnode(p).symtableprocentry) and
  2318. (symtableproc = tcallnode(p).symtableproc) and
  2319. (procdefinition = tcallnode(p).procdefinition) and
  2320. (methodpointer.isequal(tcallnode(p).methodpointer)) and
  2321. ((restypeset and tcallnode(p).restypeset and
  2322. (is_equal(restype.def,tcallnode(p).restype.def))) or
  2323. (not restypeset and not tcallnode(p).restypeset));
  2324. end;
  2325. {****************************************************************************
  2326. TPROCINLINENODE
  2327. ****************************************************************************}
  2328. constructor tprocinlinenode.create(p:tprocdef);
  2329. begin
  2330. inherited create(procinlinen);
  2331. inlineprocdef:=p;
  2332. retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
  2333. para_offset:=0;
  2334. para_size:=0;
  2335. { copy inlinetree }
  2336. if assigned(p.code) then
  2337. inlinetree:=p.code.getcopy
  2338. else
  2339. inlinetree:=nil;
  2340. end;
  2341. destructor tprocinlinenode.destroy;
  2342. begin
  2343. if assigned(inlinetree) then
  2344. inlinetree.free;
  2345. inherited destroy;
  2346. end;
  2347. constructor tprocinlinenode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  2348. begin
  2349. inherited ppuload(t,ppufile);
  2350. inlineprocdef:=tprocdef(ppufile.getderef);
  2351. inlinetree:=ppuloadnode(ppufile);
  2352. retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
  2353. para_offset:=0;
  2354. para_size:=0;
  2355. end;
  2356. procedure tprocinlinenode.ppuwrite(ppufile:tcompilerppufile);
  2357. begin
  2358. inherited ppuwrite(ppufile);
  2359. ppufile.putderef(inlineprocdef);
  2360. ppuwritenode(ppufile,inlinetree);
  2361. end;
  2362. procedure tprocinlinenode.derefimpl;
  2363. begin
  2364. inherited derefimpl;
  2365. if assigned(inlinetree) then
  2366. inlinetree.derefimpl;
  2367. resolvedef(pointer(inlineprocdef));
  2368. end;
  2369. function tprocinlinenode.getcopy : tnode;
  2370. var
  2371. n : tprocinlinenode;
  2372. begin
  2373. n:=tprocinlinenode(inherited getcopy);
  2374. n.inlineprocdef:=inlineprocdef;
  2375. if assigned(inlinetree) then
  2376. n.inlinetree:=inlinetree.getcopy
  2377. else
  2378. n.inlinetree:=nil;
  2379. n.retoffset:=retoffset;
  2380. n.para_offset:=para_offset;
  2381. n.para_size:=para_size;
  2382. getcopy:=n;
  2383. end;
  2384. procedure tprocinlinenode.insertintolist(l : tnodelist);
  2385. begin
  2386. end;
  2387. function tprocinlinenode.det_resulttype : tnode;
  2388. begin
  2389. resulttype:=inlineprocdef.rettype;
  2390. { retrieve info from inlineprocdef }
  2391. retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
  2392. para_offset:=0;
  2393. para_size:=inlineprocdef.para_size(target_info.alignment.paraalign);
  2394. if paramanager.ret_in_param(inlineprocdef.rettype.def) then
  2395. inc(para_size,POINTER_SIZE);
  2396. result:=nil;
  2397. end;
  2398. function tprocinlinenode.pass_1 : tnode;
  2399. begin
  2400. firstpass(inlinetree);
  2401. registers32:=inlinetree.registers32;
  2402. registersfpu:=inlinetree.registersfpu;
  2403. {$ifdef SUPPORT_MMX}
  2404. registersmmx:=inlinetree.registersmmx;
  2405. {$endif SUPPORT_MMX}
  2406. result:=nil;
  2407. end;
  2408. function tprocinlinenode.docompare(p: tnode): boolean;
  2409. begin
  2410. docompare :=
  2411. inherited docompare(p) and
  2412. inlinetree.isequal(tprocinlinenode(p).inlinetree) and
  2413. (inlineprocdef = tprocinlinenode(p).inlineprocdef);
  2414. end;
  2415. begin
  2416. ccallnode:=tcallnode;
  2417. ccallparanode:=tcallparanode;
  2418. cprocinlinenode:=tprocinlinenode;
  2419. end.
  2420. {
  2421. $Log$
  2422. Revision 1.102 2002-10-05 00:48:57 peter
  2423. * support inherited; support for overload as it is handled by
  2424. delphi. This is only for delphi mode as it is working is
  2425. undocumented and hard to predict what is done
  2426. Revision 1.101 2002/09/16 14:11:12 peter
  2427. * add argument to equal_paras() to support default values or not
  2428. Revision 1.100 2002/09/15 17:49:59 peter
  2429. * don't have strict var parameter checking for procedures in the
  2430. system unit
  2431. Revision 1.99 2002/09/09 19:30:34 peter
  2432. * don't allow convertable parameters for var and out parameters in
  2433. delphi and tp mode
  2434. Revision 1.98 2002/09/07 15:25:02 peter
  2435. * old logs removed and tabs fixed
  2436. Revision 1.97 2002/09/07 12:16:05 carl
  2437. * second part bug report 1996 fix, testrange in cordconstnode
  2438. only called if option is set (also make parsing a tiny faster)
  2439. Revision 1.96 2002/09/05 14:53:41 peter
  2440. * fixed old callnode.det_resulttype code
  2441. * old ncal code is default again
  2442. Revision 1.95 2002/09/03 21:32:49 daniel
  2443. * Small bugfix for procdef selection
  2444. Revision 1.94 2002/09/03 19:27:22 daniel
  2445. * Activated new ncal code
  2446. Revision 1.93 2002/09/03 16:26:26 daniel
  2447. * Make Tprocdef.defs protected
  2448. Revision 1.92 2002/09/01 13:28:37 daniel
  2449. - write_access fields removed in favor of a flag
  2450. Revision 1.91 2002/09/01 12:14:15 peter
  2451. * remove debug line
  2452. * containself methods can be called directly
  2453. Revision 1.90 2002/09/01 08:01:16 daniel
  2454. * Removed sets from Tcallnode.det_resulttype
  2455. + Added read/write notifications of variables. These will be usefull
  2456. for providing information for several optimizations. For example
  2457. the value of the loop variable of a for loop does matter is the
  2458. variable is read after the for loop, but if it's no longer used
  2459. or written, it doesn't matter and this can be used to optimize
  2460. the loop code generation.
  2461. Revision 1.89 2002/08/23 16:13:16 peter
  2462. * also firstpass funcretrefnode if available. This was breaking the
  2463. asnode compilerproc code
  2464. Revision 1.88 2002/08/20 10:31:26 daniel
  2465. * Tcallnode.det_resulttype rewritten
  2466. Revision 1.87 2002/08/19 19:36:42 peter
  2467. * More fixes for cross unit inlining, all tnodes are now implemented
  2468. * Moved pocall_internconst to po_internconst because it is not a
  2469. calling type at all and it conflicted when inlining of these small
  2470. functions was requested
  2471. Revision 1.86 2002/08/17 22:09:44 florian
  2472. * result type handling in tcgcal.pass_2 overhauled
  2473. * better tnode.dowrite
  2474. * some ppc stuff fixed
  2475. Revision 1.85 2002/08/17 09:23:34 florian
  2476. * first part of procinfo rewrite
  2477. Revision 1.84 2002/08/16 14:24:57 carl
  2478. * issameref() to test if two references are the same (then emit no opcodes)
  2479. + ret_in_reg to replace ret_in_acc
  2480. (fix some register allocation bugs at the same time)
  2481. + save_std_register now has an extra parameter which is the
  2482. usedinproc registers
  2483. Revision 1.83 2002/07/20 11:57:53 florian
  2484. * types.pas renamed to defbase.pas because D6 contains a types
  2485. unit so this would conflicts if D6 programms are compiled
  2486. + Willamette/SSE2 instructions to assembler added
  2487. Revision 1.82 2002/07/19 11:41:35 daniel
  2488. * State tracker work
  2489. * The whilen and repeatn are now completely unified into whilerepeatn. This
  2490. allows the state tracker to change while nodes automatically into
  2491. repeat nodes.
  2492. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  2493. 'not(a>b)' is optimized into 'a<=b'.
  2494. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  2495. by removing the notn and later switchting the true and falselabels. The
  2496. same is done with 'repeat until not a'.
  2497. Revision 1.81 2002/07/15 18:03:14 florian
  2498. * readded removed changes
  2499. Revision 1.79 2002/07/11 14:41:27 florian
  2500. * start of the new generic parameter handling
  2501. Revision 1.80 2002/07/14 18:00:43 daniel
  2502. + Added the beginning of a state tracker. This will track the values of
  2503. variables through procedures and optimize things away.
  2504. Revision 1.78 2002/07/04 20:43:00 florian
  2505. * first x86-64 patches
  2506. }