ncal.pas 82 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047
  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. interface
  21. uses
  22. node,
  23. {$ifdef state_tracking}
  24. nstate,
  25. {$endif state_tracking}
  26. symbase,symtype,symsym,symdef,symtable;
  27. type
  28. tcallnode = class(tbinarynode)
  29. { the symbol containing the definition of the procedure }
  30. { to call }
  31. symtableprocentry : tprocsym;
  32. { the symtable containing symtableprocentry }
  33. symtableproc : tsymtable;
  34. { the definition of the procedure to call }
  35. procdefinition : tabstractprocdef;
  36. methodpointer : tnode;
  37. { separately specified resulttype for some compilerprocs (e.g. }
  38. { you can't have a function with an "array of char" resulttype }
  39. { the RTL) (JM) }
  40. restype: ttype;
  41. restypeset: boolean;
  42. { function return reference node, this is used to pass an already
  43. allocated reference for a ret_in_param return value }
  44. funcretrefnode : tnode;
  45. { only the processor specific nodes need to override this }
  46. { constructor }
  47. constructor create(l:tnode; v : tprocsym;st : tsymtable; mp : tnode);virtual;
  48. constructor createintern(const name: string; params: tnode);
  49. constructor createinternres(const name: string; params: tnode; const res: ttype);
  50. constructor createinternreturn(const name: string; params: tnode; returnnode : tnode);
  51. destructor destroy;override;
  52. function getcopy : tnode;override;
  53. procedure insertintolist(l : tnodelist);override;
  54. function pass_1 : tnode;override;
  55. function det_resulttype:tnode;override;
  56. {$ifdef state_tracking}
  57. function track_state_pass(exec_known:boolean):boolean;override;
  58. {$endif state_tracking}
  59. function docompare(p: tnode): boolean; override;
  60. procedure set_procvar(procvar:tnode);
  61. end;
  62. tcallnodeclass = class of tcallnode;
  63. tcallparaflags = (
  64. { flags used by tcallparanode }
  65. cpf_exact_match_found,
  66. cpf_convlevel1found,
  67. cpf_convlevel2found,
  68. cpf_is_colon_para
  69. );
  70. tcallparanode = class(tbinarynode)
  71. callparaflags : set of tcallparaflags;
  72. hightree : tnode;
  73. { only the processor specific nodes need to override this }
  74. { constructor }
  75. constructor create(expr,next : tnode);virtual;
  76. destructor destroy;override;
  77. function getcopy : tnode;override;
  78. procedure insertintolist(l : tnodelist);override;
  79. procedure gen_high_tree(openstring:boolean);
  80. procedure get_paratype;
  81. procedure insert_typeconv(defcoll : tparaitem;do_count : boolean);
  82. procedure det_registers;
  83. procedure firstcallparan(defcoll : tparaitem;do_count : boolean);
  84. procedure secondcallparan(defcoll : tparaitem;
  85. push_from_left_to_right,inlined,is_cdecl : boolean;
  86. para_alignment,para_offset : longint);virtual;abstract;
  87. function docompare(p: tnode): boolean; override;
  88. end;
  89. tcallparanodeclass = class of tcallparanode;
  90. tprocinlinenode = class(tnode)
  91. inlinetree : tnode;
  92. inlineprocdef : tprocdef;
  93. retoffset,para_offset,para_size : longint;
  94. constructor create(callp,code : tnode);virtual;
  95. destructor destroy;override;
  96. function getcopy : tnode;override;
  97. procedure insertintolist(l : tnodelist);override;
  98. function pass_1 : tnode;override;
  99. function docompare(p: tnode): boolean; override;
  100. end;
  101. tprocinlinenodeclass = class of tprocinlinenode;
  102. function reverseparameters(p: tcallparanode): tcallparanode;
  103. var
  104. ccallnode : tcallnodeclass;
  105. ccallparanode : tcallparanodeclass;
  106. cprocinlinenode : tprocinlinenodeclass;
  107. implementation
  108. uses
  109. cutils,globtype,systems,
  110. verbose,globals,
  111. symconst,paramgr,defbase,
  112. htypechk,pass_1,cpuinfo,cpubase,
  113. ncnv,nld,ninl,nadd,ncon,
  114. rgobj,cgbase
  115. ;
  116. {****************************************************************************
  117. HELPERS
  118. ****************************************************************************}
  119. function reverseparameters(p: tcallparanode): tcallparanode;
  120. var
  121. hp1, hp2: tcallparanode;
  122. begin
  123. hp1:=nil;
  124. while assigned(p) do
  125. begin
  126. { pull out }
  127. hp2:=p;
  128. p:=tcallparanode(p.right);
  129. { pull in }
  130. hp2.right:=hp1;
  131. hp1:=hp2;
  132. end;
  133. reverseparameters:=hp1;
  134. end;
  135. procedure search_class_overloads(aprocsym : tprocsym);
  136. { searches n in symtable of pd and all anchestors }
  137. var
  138. speedvalue : cardinal;
  139. srsym : tprocsym;
  140. s : string;
  141. found : boolean;
  142. srpdl,pdl : pprocdeflist;
  143. objdef : tobjectdef;
  144. begin
  145. if aprocsym.overloadchecked then
  146. exit;
  147. aprocsym.overloadchecked:=true;
  148. if (aprocsym.owner.symtabletype<>objectsymtable) then
  149. internalerror(200111021);
  150. objdef:=tobjectdef(aprocsym.owner.defowner);
  151. { we start in the parent }
  152. if not assigned(objdef.childof) then
  153. exit;
  154. objdef:=objdef.childof;
  155. s:=aprocsym.name;
  156. speedvalue:=getspeedvalue(s);
  157. while assigned(objdef) do
  158. begin
  159. srsym:=tprocsym(objdef.symtable.speedsearch(s,speedvalue));
  160. if assigned(srsym) then
  161. begin
  162. if (srsym.typ<>procsym) then
  163. internalerror(200111022);
  164. if srsym.is_visible_for_proc(aktprocdef) then
  165. begin
  166. srpdl:=srsym.defs;
  167. while assigned(srpdl) do
  168. begin
  169. found:=false;
  170. pdl:=aprocsym.defs;
  171. while assigned(pdl) do
  172. begin
  173. if equal_paras(pdl^.def.para,srpdl^.def.para,cp_value_equal_const) then
  174. begin
  175. found:=true;
  176. break;
  177. end;
  178. pdl:=pdl^.next;
  179. end;
  180. if not found then
  181. aprocsym.addprocdef(srpdl^.def);
  182. srpdl:=srpdl^.next;
  183. end;
  184. { we can stop if the overloads were already added
  185. for the found symbol }
  186. if srsym.overloadchecked then
  187. break;
  188. end;
  189. end;
  190. { next parent }
  191. objdef:=objdef.childof;
  192. end;
  193. end;
  194. {****************************************************************************
  195. TCALLPARANODE
  196. ****************************************************************************}
  197. constructor tcallparanode.create(expr,next : tnode);
  198. begin
  199. inherited create(callparan,expr,next);
  200. hightree:=nil;
  201. if assigned(expr) then
  202. expr.set_file_line(self);
  203. callparaflags:=[];
  204. end;
  205. destructor tcallparanode.destroy;
  206. begin
  207. hightree.free;
  208. inherited destroy;
  209. end;
  210. function tcallparanode.getcopy : tnode;
  211. var
  212. n : tcallparanode;
  213. begin
  214. n:=tcallparanode(inherited getcopy);
  215. n.callparaflags:=callparaflags;
  216. if assigned(hightree) then
  217. n.hightree:=hightree.getcopy
  218. else
  219. n.hightree:=nil;
  220. result:=n;
  221. end;
  222. procedure tcallparanode.insertintolist(l : tnodelist);
  223. begin
  224. end;
  225. procedure tcallparanode.get_paratype;
  226. var
  227. old_get_para_resulttype : boolean;
  228. old_array_constructor : boolean;
  229. begin
  230. inc(parsing_para_level);
  231. if assigned(right) then
  232. tcallparanode(right).get_paratype;
  233. old_array_constructor:=allow_array_constructor;
  234. old_get_para_resulttype:=get_para_resulttype;
  235. get_para_resulttype:=true;
  236. allow_array_constructor:=true;
  237. resulttypepass(left);
  238. get_para_resulttype:=old_get_para_resulttype;
  239. allow_array_constructor:=old_array_constructor;
  240. if codegenerror then
  241. resulttype:=generrortype
  242. else
  243. resulttype:=left.resulttype;
  244. dec(parsing_para_level);
  245. end;
  246. procedure tcallparanode.insert_typeconv(defcoll : tparaitem;do_count : boolean);
  247. var
  248. oldtype : ttype;
  249. {$ifdef extdebug}
  250. store_count_ref : boolean;
  251. {$endif def extdebug}
  252. p1 : tnode;
  253. begin
  254. inc(parsing_para_level);
  255. if not assigned(defcoll) then
  256. internalerror(200104261);
  257. {$ifdef extdebug}
  258. if do_count then
  259. begin
  260. store_count_ref:=count_ref;
  261. count_ref:=true;
  262. end;
  263. {$endif def extdebug}
  264. if assigned(right) then
  265. begin
  266. { if we are a para that belongs to varargs then keep
  267. the current defcoll }
  268. if (nf_varargs_para in flags) then
  269. tcallparanode(right).insert_typeconv(defcoll,do_count)
  270. else
  271. tcallparanode(right).insert_typeconv(tparaitem(defcoll.next),do_count);
  272. end;
  273. { Be sure to have the resulttype }
  274. if not assigned(left.resulttype.def) then
  275. resulttypepass(left);
  276. { Handle varargs directly, no typeconvs or typechecking needed }
  277. if (nf_varargs_para in flags) then
  278. begin
  279. { convert pascal to C types }
  280. case left.resulttype.def.deftype of
  281. stringdef :
  282. inserttypeconv(left,charpointertype);
  283. floatdef :
  284. inserttypeconv(left,s64floattype);
  285. end;
  286. set_varstate(left,true);
  287. resulttype:=left.resulttype;
  288. dec(parsing_para_level);
  289. exit;
  290. end;
  291. { Do we need arrayconstructor -> set conversion, then insert
  292. it here before the arrayconstructor node breaks the tree
  293. with its conversions of enum->ord }
  294. if (left.nodetype=arrayconstructorn) and
  295. (defcoll.paratype.def.deftype=setdef) then
  296. inserttypeconv(left,defcoll.paratype);
  297. { set some settings needed for arrayconstructor }
  298. if is_array_constructor(left.resulttype.def) then
  299. begin
  300. if is_array_of_const(defcoll.paratype.def) then
  301. begin
  302. if assigned(aktcallprocdef) and
  303. (aktcallprocdef.proccalloption in [pocall_cppdecl,pocall_cdecl]) and
  304. (po_external in aktcallprocdef.procoptions) then
  305. include(left.flags,nf_cargs);
  306. { force variant array }
  307. include(left.flags,nf_forcevaria);
  308. end
  309. else
  310. begin
  311. include(left.flags,nf_novariaallowed);
  312. { now that the resultting type is know we can insert the required
  313. typeconvs for the array constructor }
  314. tarrayconstructornode(left).force_type(tarraydef(defcoll.paratype.def).elementtype);
  315. end;
  316. end;
  317. { check if local proc/func is assigned to procvar }
  318. if left.resulttype.def.deftype=procvardef then
  319. test_local_to_procvar(tprocvardef(left.resulttype.def),defcoll.paratype.def);
  320. { generate the high() value tree }
  321. if not(assigned(aktcallprocdef) and
  322. (aktcallprocdef.proccalloption in [pocall_cppdecl,pocall_cdecl]) and
  323. (po_external in aktcallprocdef.procoptions)) and
  324. paramanager.push_high_param(defcoll.paratype.def) then
  325. gen_high_tree(is_open_string(defcoll.paratype.def));
  326. { test conversions }
  327. if not(is_shortstring(left.resulttype.def) and
  328. is_shortstring(defcoll.paratype.def)) and
  329. (defcoll.paratype.def.deftype<>formaldef) then
  330. begin
  331. if (defcoll.paratyp in [vs_var,vs_out]) and
  332. { allows conversion from word to integer and
  333. byte to shortint, but only for TP7 compatibility }
  334. (not(
  335. (m_tp7 in aktmodeswitches) and
  336. (left.resulttype.def.deftype=orddef) and
  337. (defcoll.paratype.def.deftype=orddef) and
  338. (left.resulttype.def.size=defcoll.paratype.def.size)
  339. ) and
  340. { an implicit pointer conversion is allowed }
  341. not(
  342. (left.resulttype.def.deftype=pointerdef) and
  343. (defcoll.paratype.def.deftype=pointerdef)
  344. ) and
  345. { child classes can be also passed }
  346. not(
  347. (left.resulttype.def.deftype=objectdef) and
  348. (defcoll.paratype.def.deftype=objectdef) and
  349. tobjectdef(left.resulttype.def).is_related(tobjectdef(defcoll.paratype.def))
  350. ) and
  351. { passing a single element to a openarray of the same type }
  352. not(
  353. (is_open_array(defcoll.paratype.def) and
  354. is_equal(tarraydef(defcoll.paratype.def).elementtype.def,left.resulttype.def))
  355. ) and
  356. { an implicit file conversion is also allowed }
  357. { from a typed file to an untyped one }
  358. not(
  359. (left.resulttype.def.deftype=filedef) and
  360. (defcoll.paratype.def.deftype=filedef) and
  361. (tfiledef(defcoll.paratype.def).filetyp = ft_untyped) and
  362. (tfiledef(left.resulttype.def).filetyp = ft_typed)
  363. ) and
  364. not(is_equal(left.resulttype.def,defcoll.paratype.def))) then
  365. begin
  366. CGMessagePos2(left.fileinfo,parser_e_call_by_ref_without_typeconv,
  367. left.resulttype.def.typename,defcoll.paratype.def.typename);
  368. end;
  369. { Process open parameters }
  370. if paramanager.push_high_param(defcoll.paratype.def) then
  371. begin
  372. { insert type conv but hold the ranges of the array }
  373. oldtype:=left.resulttype;
  374. inserttypeconv(left,defcoll.paratype);
  375. left.resulttype:=oldtype;
  376. end
  377. else
  378. begin
  379. inserttypeconv(left,defcoll.paratype);
  380. end;
  381. if codegenerror then
  382. begin
  383. dec(parsing_para_level);
  384. exit;
  385. end;
  386. end;
  387. { check var strings }
  388. if (cs_strict_var_strings in aktlocalswitches) and
  389. is_shortstring(left.resulttype.def) and
  390. is_shortstring(defcoll.paratype.def) and
  391. (defcoll.paratyp in [vs_out,vs_var]) and
  392. not(is_open_string(defcoll.paratype.def)) and
  393. not(is_equal(left.resulttype.def,defcoll.paratype.def)) then
  394. begin
  395. aktfilepos:=left.fileinfo;
  396. CGMessage(type_e_strict_var_string_violation);
  397. end;
  398. { Handle formal parameters separate }
  399. if (defcoll.paratype.def.deftype=formaldef) then
  400. begin
  401. { load procvar if a procedure is passed }
  402. if (m_tp_procvar in aktmodeswitches) and
  403. (left.nodetype=calln) and
  404. (is_void(left.resulttype.def)) then
  405. begin
  406. p1:=cloadnode.create_procvar(tcallnode(left).symtableprocentry,
  407. tprocdef(tcallnode(left).procdefinition),tcallnode(left).symtableproc);
  408. if assigned(tcallnode(left).right) then
  409. tloadnode(p1).set_mp(tcallnode(left).right);
  410. left.free;
  411. left:=p1;
  412. resulttypepass(left);
  413. end;
  414. case defcoll.paratyp of
  415. vs_var,
  416. vs_out :
  417. begin
  418. if not valid_for_formal_var(left) then
  419. CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
  420. end;
  421. vs_const :
  422. begin
  423. if not valid_for_formal_const(left) then
  424. CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
  425. end;
  426. end;
  427. end
  428. else
  429. begin
  430. { check if the argument is allowed }
  431. if (defcoll.paratyp in [vs_out,vs_var]) then
  432. valid_for_var(left);
  433. end;
  434. if defcoll.paratyp in [vs_var,vs_const] then
  435. begin
  436. { Causes problems with const ansistrings if also }
  437. { done for vs_const (JM) }
  438. if defcoll.paratyp = vs_var then
  439. set_unique(left);
  440. make_not_regable(left);
  441. end;
  442. { ansistrings out paramaters doesn't need to be }
  443. { unique, they are finalized }
  444. if defcoll.paratyp=vs_out then
  445. make_not_regable(left);
  446. if do_count then
  447. begin
  448. { not completly proper, but avoids some warnings }
  449. if (defcoll.paratyp in [vs_var,vs_out]) then
  450. set_funcret_is_valid(left);
  451. set_varstate(left,not(defcoll.paratyp in [vs_var,vs_out]));
  452. end;
  453. { must only be done after typeconv PM }
  454. resulttype:=defcoll.paratype;
  455. dec(parsing_para_level);
  456. {$ifdef extdebug}
  457. if do_count then
  458. count_ref:=store_count_ref;
  459. {$endif def extdebug}
  460. end;
  461. procedure tcallparanode.det_registers;
  462. var
  463. old_get_para_resulttype : boolean;
  464. old_array_constructor : boolean;
  465. begin
  466. if assigned(right) then
  467. begin
  468. tcallparanode(right).det_registers;
  469. registers32:=right.registers32;
  470. registersfpu:=right.registersfpu;
  471. {$ifdef SUPPORT_MMX}
  472. registersmmx:=right.registersmmx;
  473. {$endif}
  474. end;
  475. old_array_constructor:=allow_array_constructor;
  476. old_get_para_resulttype:=get_para_resulttype;
  477. get_para_resulttype:=true;
  478. allow_array_constructor:=true;
  479. firstpass(left);
  480. get_para_resulttype:=old_get_para_resulttype;
  481. allow_array_constructor:=old_array_constructor;
  482. if left.registers32>registers32 then
  483. registers32:=left.registers32;
  484. if left.registersfpu>registersfpu then
  485. registersfpu:=left.registersfpu;
  486. {$ifdef SUPPORT_MMX}
  487. if left.registersmmx>registersmmx then
  488. registersmmx:=left.registersmmx;
  489. {$endif SUPPORT_MMX}
  490. end;
  491. procedure tcallparanode.firstcallparan(defcoll : tparaitem;do_count : boolean);
  492. begin
  493. if not assigned(left.resulttype.def) then
  494. begin
  495. get_paratype;
  496. if assigned(defcoll) then
  497. insert_typeconv(defcoll,do_count);
  498. end;
  499. det_registers;
  500. end;
  501. procedure tcallparanode.gen_high_tree(openstring:boolean);
  502. var
  503. temp: tnode;
  504. len : integer;
  505. loadconst : boolean;
  506. begin
  507. if assigned(hightree) then
  508. exit;
  509. len:=-1;
  510. loadconst:=true;
  511. case left.resulttype.def.deftype of
  512. arraydef :
  513. begin
  514. { handle via a normal inline in_high_x node }
  515. loadconst := false;
  516. hightree := geninlinenode(in_high_x,false,left.getcopy);
  517. { only substract low(array) if it's <> 0 }
  518. temp := geninlinenode(in_low_x,false,left.getcopy);
  519. firstpass(temp);
  520. if (temp.nodetype <> ordconstn) or
  521. (tordconstnode(temp).value <> 0) then
  522. hightree := caddnode.create(subn,hightree,temp)
  523. else
  524. temp.free;
  525. end;
  526. stringdef :
  527. begin
  528. if openstring then
  529. begin
  530. { handle via a normal inline in_high_x node }
  531. loadconst := false;
  532. hightree := geninlinenode(in_high_x,false,left.getcopy);
  533. end
  534. else
  535. { passing a string to an array of char }
  536. begin
  537. if (left.nodetype=stringconstn) then
  538. begin
  539. len:=str_length(left);
  540. if len>0 then
  541. dec(len);
  542. end
  543. else
  544. begin
  545. hightree:=caddnode.create(subn,geninlinenode(in_length_x,false,left.getcopy),
  546. cordconstnode.create(1,s32bittype));
  547. loadconst:=false;
  548. end;
  549. end;
  550. end;
  551. else
  552. len:=0;
  553. end;
  554. if loadconst then
  555. hightree:=cordconstnode.create(len,s32bittype)
  556. else
  557. hightree:=ctypeconvnode.create(hightree,s32bittype);
  558. firstpass(hightree);
  559. end;
  560. function tcallparanode.docompare(p: tnode): boolean;
  561. begin
  562. docompare :=
  563. inherited docompare(p) and
  564. (callparaflags = tcallparanode(p).callparaflags) and
  565. hightree.isequal(tcallparanode(p).hightree);
  566. end;
  567. {****************************************************************************
  568. TCALLNODE
  569. ****************************************************************************}
  570. constructor tcallnode.create(l:tnode;v : tprocsym;st : tsymtable; mp : tnode);
  571. begin
  572. inherited create(calln,l,nil);
  573. symtableprocentry:=v;
  574. symtableproc:=st;
  575. include(flags,nf_return_value_used);
  576. methodpointer:=mp;
  577. procdefinition:=nil;
  578. restypeset := false;
  579. funcretrefnode:=nil;
  580. end;
  581. constructor tcallnode.createintern(const name: string; params: tnode);
  582. var
  583. srsym: tsym;
  584. symowner: tsymtable;
  585. begin
  586. if not (cs_compilesystem in aktmoduleswitches) then
  587. begin
  588. srsym := searchsymonlyin(systemunit,name);
  589. symowner := systemunit;
  590. end
  591. else
  592. begin
  593. searchsym(name,srsym,symowner);
  594. if not assigned(srsym) then
  595. searchsym(upper(name),srsym,symowner);
  596. end;
  597. if not assigned(srsym) or
  598. (srsym.typ <> procsym) then
  599. begin
  600. writeln('unknown compilerproc ',name);
  601. internalerror(200107271);
  602. end;
  603. self.create(params,tprocsym(srsym),symowner,nil);
  604. end;
  605. constructor tcallnode.createinternres(const name: string; params: tnode; const res: ttype);
  606. begin
  607. self.createintern(name,params);
  608. restype := res;
  609. restypeset := true;
  610. { both the normal and specified resulttype either have to be returned via a }
  611. { parameter or not, but no mixing (JM) }
  612. if paramanager.ret_in_param(restype.def) xor paramanager.ret_in_param(symtableprocentry.defs^.def.rettype.def) then
  613. internalerror(200108291);
  614. end;
  615. constructor tcallnode.createinternreturn(const name: string; params: tnode; returnnode : tnode);
  616. begin
  617. self.createintern(name,params);
  618. funcretrefnode:=returnnode;
  619. if not paramanager.ret_in_param(symtableprocentry.defs^.def.rettype.def) then
  620. internalerror(200204247);
  621. end;
  622. destructor tcallnode.destroy;
  623. begin
  624. methodpointer.free;
  625. funcretrefnode.free;
  626. inherited destroy;
  627. end;
  628. procedure tcallnode.set_procvar(procvar:tnode);
  629. begin
  630. right:=procvar;
  631. end;
  632. function tcallnode.getcopy : tnode;
  633. var
  634. n : tcallnode;
  635. begin
  636. n:=tcallnode(inherited getcopy);
  637. n.symtableprocentry:=symtableprocentry;
  638. n.symtableproc:=symtableproc;
  639. n.procdefinition:=procdefinition;
  640. n.restype := restype;
  641. n.restypeset := restypeset;
  642. if assigned(methodpointer) then
  643. n.methodpointer:=methodpointer.getcopy
  644. else
  645. n.methodpointer:=nil;
  646. if assigned(funcretrefnode) then
  647. n.funcretrefnode:=funcretrefnode.getcopy
  648. else
  649. n.funcretrefnode:=nil;
  650. result:=n;
  651. end;
  652. procedure tcallnode.insertintolist(l : tnodelist);
  653. begin
  654. end;
  655. function tcallnode.det_resulttype:tnode;
  656. type
  657. pprocdefcoll = ^tprocdefcoll;
  658. tprocdefcoll = record
  659. data : tprocdef;
  660. nextpara : tparaitem;
  661. firstpara : tparaitem;
  662. next : pprocdefcoll;
  663. end;
  664. var
  665. hp,procs,hp2 : pprocdefcoll;
  666. pd : pprocdeflist;
  667. oldcallprocdef : tabstractprocdef;
  668. def_from,def_to,conv_to : tdef;
  669. hpt : tnode;
  670. pt : tcallparanode;
  671. exactmatch : boolean;
  672. paralength,lastpara : longint;
  673. lastparatype : tdef;
  674. pdc : tparaitem;
  675. { only Dummy }
  676. hcvt : tconverttype;
  677. label
  678. errorexit;
  679. { check if the resulttype.def from tree p is equal with def, needed
  680. for stringconstn and formaldef }
  681. function is_equal(p:tcallparanode;def:tdef) : boolean;
  682. begin
  683. { safety check }
  684. if not (assigned(def) or assigned(p.resulttype.def)) then
  685. begin
  686. is_equal:=false;
  687. exit;
  688. end;
  689. { all types can be passed to a formaldef }
  690. is_equal:=(def.deftype=formaldef) or
  691. (defbase.is_equal(p.resulttype.def,def))
  692. { integer constants are compatible with all integer parameters if
  693. the specified value matches the range }
  694. or
  695. (
  696. (tbinarynode(p).left.nodetype=ordconstn) and
  697. is_integer(p.resulttype.def) and
  698. is_integer(def) and
  699. (tordconstnode(p.left).value>=torddef(def).low) and
  700. (tordconstnode(p.left).value<=torddef(def).high)
  701. )
  702. { to support ansi/long/wide strings in a proper way }
  703. { string and string[10] are assumed as equal }
  704. { when searching the correct overloaded procedure }
  705. or
  706. (
  707. (def.deftype=stringdef) and (p.resulttype.def.deftype=stringdef) and
  708. (tstringdef(def).string_typ=tstringdef(p.resulttype.def).string_typ)
  709. )
  710. or
  711. (
  712. (p.left.nodetype=stringconstn) and
  713. (is_ansistring(p.resulttype.def) and is_pchar(def))
  714. )
  715. or
  716. (
  717. (p.left.nodetype=ordconstn) and
  718. (is_char(p.resulttype.def) and (is_shortstring(def) or is_ansistring(def)))
  719. )
  720. { set can also be a not yet converted array constructor }
  721. or
  722. (
  723. (def.deftype=setdef) and (p.resulttype.def.deftype=arraydef) and
  724. (tarraydef(p.resulttype.def).IsConstructor) and not(tarraydef(p.resulttype.def).IsVariant)
  725. )
  726. { in tp7 mode proc -> procvar is allowed }
  727. or
  728. (
  729. (m_tp_procvar in aktmodeswitches) and
  730. (def.deftype=procvardef) and (p.left.nodetype=calln) and
  731. (proc_to_procvar_equal(tprocdef(tcallnode(p.left).procdefinition),tprocvardef(def),false))
  732. )
  733. ;
  734. end;
  735. var
  736. i : longint;
  737. found,
  738. is_const : boolean;
  739. bestord : torddef;
  740. srprocsym : tprocsym;
  741. srsymtable : tsymtable;
  742. begin
  743. result:=nil;
  744. procs:=nil;
  745. oldcallprocdef:=aktcallprocdef;
  746. aktcallprocdef:=nil;
  747. { determine length of parameter list }
  748. pt:=tcallparanode(left);
  749. paralength:=0;
  750. while assigned(pt) do
  751. begin
  752. inc(paralength);
  753. pt:=tcallparanode(pt.right);
  754. end;
  755. { determine the type of the parameters }
  756. if assigned(left) then
  757. begin
  758. tcallparanode(left).get_paratype;
  759. if codegenerror then
  760. goto errorexit;
  761. end;
  762. { procedure variable ? }
  763. if assigned(right) then
  764. begin
  765. set_varstate(right,true);
  766. resulttypepass(right);
  767. if codegenerror then
  768. exit;
  769. procdefinition:=tabstractprocdef(right.resulttype.def);
  770. { check the amount of parameters }
  771. pdc:=tparaitem(procdefinition.Para.first);
  772. pt:=tcallparanode(left);
  773. lastpara:=paralength;
  774. while assigned(pdc) and assigned(pt) do
  775. begin
  776. { only goto next para if we're out of the varargs }
  777. if not(po_varargs in procdefinition.procoptions) or
  778. (lastpara<=procdefinition.maxparacount) then
  779. pdc:=tparaitem(pdc.next);
  780. pt:=tcallparanode(pt.right);
  781. dec(lastpara);
  782. end;
  783. if assigned(pt) or assigned(pdc) then
  784. begin
  785. if assigned(pt) then
  786. aktfilepos:=pt.fileinfo;
  787. CGMessage(parser_e_wrong_parameter_size);
  788. end;
  789. end
  790. else
  791. { not a procedure variable }
  792. begin
  793. { do we know the procedure to call ? }
  794. if not(assigned(procdefinition)) then
  795. begin
  796. { when the definition has overload directive set, we search for
  797. overloaded definitions in the class, this only needs to be done once
  798. for class entries as the tree keeps always the same }
  799. if (not symtableprocentry.overloadchecked) and
  800. (po_overload in symtableprocentry.defs^.def.procoptions) and
  801. (symtableprocentry.owner.symtabletype=objectsymtable) then
  802. search_class_overloads(symtableprocentry);
  803. { link all procedures which have the same # of parameters }
  804. pd:=symtableprocentry.defs;
  805. while assigned(pd) do
  806. begin
  807. { only when the # of parameter are supported by the
  808. procedure }
  809. if (paralength>=pd^.def.minparacount) and
  810. ((po_varargs in pd^.def.procoptions) or { varargs }
  811. (paralength<=pd^.def.maxparacount)) then
  812. begin
  813. new(hp);
  814. hp^.data:=pd^.def;
  815. hp^.next:=procs;
  816. hp^.firstpara:=tparaitem(pd^.def.Para.first);
  817. if not(po_varargs in pd^.def.procoptions) then
  818. begin
  819. { if not all parameters are given, then skip the
  820. default parameters }
  821. for i:=1 to pd^.def.maxparacount-paralength do
  822. hp^.firstpara:=tparaitem(hp^.firstPara.next);
  823. end;
  824. hp^.nextpara:=hp^.firstpara;
  825. procs:=hp;
  826. end;
  827. pd:=pd^.next;
  828. end;
  829. { when the definition has overload directive set, we search for
  830. overloaded definitions in the symtablestack. The found
  831. entries are only added to the procs list and not the procsym, because
  832. the list can change in every situation }
  833. if (po_overload in symtableprocentry.defs^.def.procoptions) and
  834. (symtableprocentry.owner.symtabletype<>objectsymtable) then
  835. begin
  836. srsymtable:=symtableprocentry.owner.next;
  837. while assigned(srsymtable) do
  838. begin
  839. if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
  840. begin
  841. srprocsym:=tprocsym(srsymtable.speedsearch(symtableprocentry.name,symtableprocentry.speedvalue));
  842. { process only visible procsyms }
  843. if assigned(srprocsym) and
  844. (srprocsym.typ=procsym) and
  845. srprocsym.is_visible_for_proc(aktprocdef) then
  846. begin
  847. { if this procedure doesn't have overload we can stop
  848. searching }
  849. if not(po_overload in srprocsym.defs^.def.procoptions) then
  850. break;
  851. { process all overloaded definitions }
  852. pd:=srprocsym.defs;
  853. while assigned(pd) do
  854. begin
  855. { only when the # of parameter are supported by the
  856. procedure }
  857. if (paralength>=pd^.def.minparacount) and
  858. ((po_varargs in pd^.def.procoptions) or { varargs }
  859. (paralength<=pd^.def.maxparacount)) then
  860. begin
  861. found:=false;
  862. hp:=procs;
  863. while assigned(hp) do
  864. begin
  865. if equal_paras(hp^.data.para,pd^.def.para,cp_value_equal_const) then
  866. begin
  867. found:=true;
  868. break;
  869. end;
  870. hp:=hp^.next;
  871. end;
  872. if not found then
  873. begin
  874. new(hp);
  875. hp^.data:=pd^.def;
  876. hp^.next:=procs;
  877. hp^.firstpara:=tparaitem(pd^.def.Para.first);
  878. if not(po_varargs in pd^.def.procoptions) then
  879. begin
  880. { if not all parameters are given, then skip the
  881. default parameters }
  882. for i:=1 to pd^.def.maxparacount-paralength do
  883. hp^.firstpara:=tparaitem(hp^.firstPara.next);
  884. end;
  885. hp^.nextpara:=hp^.firstpara;
  886. procs:=hp;
  887. end;
  888. end;
  889. pd:=pd^.next;
  890. end;
  891. end;
  892. end;
  893. srsymtable:=srsymtable.next;
  894. end;
  895. end;
  896. { no procedures found? then there is something wrong
  897. with the parameter size }
  898. if not assigned(procs) then
  899. begin
  900. { in tp mode we can try to convert to procvar if
  901. there are no parameters specified }
  902. if not(assigned(left)) and
  903. (m_tp_procvar in aktmodeswitches) then
  904. begin
  905. hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc);
  906. if (symtableprocentry.owner.symtabletype=objectsymtable) and
  907. assigned(methodpointer) then
  908. tloadnode(hpt).set_mp(methodpointer.getcopy);
  909. resulttypepass(hpt);
  910. result:=hpt;
  911. end
  912. else
  913. begin
  914. if assigned(left) then
  915. aktfilepos:=left.fileinfo;
  916. CGMessage(parser_e_wrong_parameter_size);
  917. symtableprocentry.write_parameter_lists(nil);
  918. end;
  919. goto errorexit;
  920. end;
  921. { now we can compare parameter after parameter }
  922. pt:=tcallparanode(left);
  923. { we start with the last parameter }
  924. lastpara:=paralength+1;
  925. lastparatype:=nil;
  926. while assigned(pt) do
  927. begin
  928. dec(lastpara);
  929. { walk all procedures and determine how this parameter matches and set:
  930. 1. pt.exact_match_found if one parameter has an exact match
  931. 2. exactmatch if an equal or exact match is found
  932. 3. Para.argconvtyp to exact,equal or convertable
  933. (when convertable then also convertlevel is set)
  934. 4. pt.convlevel1found if there is a convertlevel=1
  935. 5. pt.convlevel2found if there is a convertlevel=2
  936. }
  937. exactmatch:=false;
  938. hp:=procs;
  939. while assigned(hp) do
  940. begin
  941. { varargs are always equal, but not exact }
  942. if (po_varargs in hp^.data.procoptions) and
  943. (lastpara>hp^.data.minparacount) then
  944. begin
  945. hp^.nextPara.argconvtyp:=act_equal;
  946. exactmatch:=true;
  947. end
  948. else
  949. begin
  950. if is_equal(pt,hp^.nextPara.paratype.def) then
  951. begin
  952. if hp^.nextPara.paratype.def=pt.resulttype.def then
  953. begin
  954. include(pt.callparaflags,cpf_exact_match_found);
  955. hp^.nextPara.argconvtyp:=act_exact;
  956. end
  957. else
  958. hp^.nextPara.argconvtyp:=act_equal;
  959. exactmatch:=true;
  960. end
  961. else
  962. begin
  963. hp^.nextPara.argconvtyp:=act_convertable;
  964. hp^.nextPara.convertlevel:=isconvertable(pt.resulttype.def,hp^.nextPara.paratype.def,
  965. hcvt,pt.left.nodetype,false);
  966. case hp^.nextPara.convertlevel of
  967. 1 : include(pt.callparaflags,cpf_convlevel1found);
  968. 2 : include(pt.callparaflags,cpf_convlevel2found);
  969. end;
  970. end;
  971. end;
  972. hp:=hp^.next;
  973. end;
  974. { If there was an exactmatch then delete all convertables }
  975. if exactmatch then
  976. begin
  977. hp:=procs;
  978. procs:=nil;
  979. while assigned(hp) do
  980. begin
  981. hp2:=hp^.next;
  982. { keep if not convertable }
  983. if (hp^.nextPara.argconvtyp<>act_convertable) then
  984. begin
  985. hp^.next:=procs;
  986. procs:=hp;
  987. end
  988. else
  989. dispose(hp);
  990. hp:=hp2;
  991. end;
  992. end
  993. else
  994. { No exact match was found, remove all procedures that are
  995. not convertable (convertlevel=0) }
  996. begin
  997. hp:=procs;
  998. procs:=nil;
  999. while assigned(hp) do
  1000. begin
  1001. hp2:=hp^.next;
  1002. { keep if not convertable }
  1003. if (hp^.nextPara.convertlevel<>0) then
  1004. begin
  1005. hp^.next:=procs;
  1006. procs:=hp;
  1007. end
  1008. else
  1009. begin
  1010. { save the type for nice error message }
  1011. lastparatype:=hp^.nextPara.paratype.def;
  1012. dispose(hp);
  1013. end;
  1014. hp:=hp2;
  1015. end;
  1016. end;
  1017. { update nextpara for all procedures }
  1018. hp:=procs;
  1019. while assigned(hp) do
  1020. begin
  1021. { only goto next para if we're out of the varargs }
  1022. if not(po_varargs in hp^.data.procoptions) or
  1023. (lastpara<=hp^.data.maxparacount) then
  1024. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1025. hp:=hp^.next;
  1026. end;
  1027. { load next parameter or quit loop if no procs left }
  1028. if assigned(procs) then
  1029. pt:=tcallparanode(pt.right)
  1030. else
  1031. break;
  1032. end;
  1033. { All parameters are checked, check if there are any
  1034. procedures left }
  1035. if not assigned(procs) then
  1036. begin
  1037. { there is an error, must be wrong type, because
  1038. wrong size is already checked (PFV) }
  1039. if (not assigned(lastparatype)) or
  1040. (not assigned(pt)) or
  1041. (not assigned(pt.resulttype.def)) then
  1042. internalerror(39393)
  1043. else
  1044. begin
  1045. aktfilepos:=pt.fileinfo;
  1046. CGMessage3(type_e_wrong_parameter_type,tostr(lastpara),
  1047. pt.resulttype.def.typename,lastparatype.typename);
  1048. end;
  1049. symtableprocentry.write_parameter_lists(nil);
  1050. goto errorexit;
  1051. end;
  1052. { if there are several choices left then for orddef }
  1053. { if a type is totally included in the other }
  1054. { we don't fear an overflow , }
  1055. { so we can do as if it is an exact match }
  1056. { this will convert integer to longint }
  1057. { rather than to words }
  1058. { conversion of byte to integer or longint }
  1059. { would still not be solved }
  1060. if assigned(procs) and assigned(procs^.next) then
  1061. begin
  1062. hp:=procs;
  1063. while assigned(hp) do
  1064. begin
  1065. hp^.nextpara:=hp^.firstpara;
  1066. hp:=hp^.next;
  1067. end;
  1068. pt:=tcallparanode(left);
  1069. while assigned(pt) do
  1070. begin
  1071. { matches a parameter of one procedure exact ? }
  1072. exactmatch:=false;
  1073. def_from:=pt.resulttype.def;
  1074. hp:=procs;
  1075. while assigned(hp) do
  1076. begin
  1077. if not is_equal(pt,hp^.nextPara.paratype.def) then
  1078. begin
  1079. def_to:=hp^.nextPara.paratype.def;
  1080. if ((def_from.deftype=orddef) and (def_to.deftype=orddef)) and
  1081. (is_in_limit(def_from,def_to) or
  1082. ((hp^.nextPara.paratyp in [vs_var,vs_out]) and
  1083. (def_from.size=def_to.size))) then
  1084. begin
  1085. exactmatch:=true;
  1086. conv_to:=def_to;
  1087. { there's no use in continuing the search, it will }
  1088. { only result in conv_to being overwritten }
  1089. break;
  1090. end;
  1091. end;
  1092. hp:=hp^.next;
  1093. end;
  1094. { .... if yes, del all the other procedures }
  1095. if exactmatch then
  1096. begin
  1097. { the first .... }
  1098. while (assigned(procs)) and not(is_in_limit(def_from,procs^.nextPara.paratype.def)) do
  1099. begin
  1100. hp:=procs^.next;
  1101. dispose(procs);
  1102. procs:=hp;
  1103. end;
  1104. { and the others }
  1105. hp:=procs;
  1106. while (assigned(hp)) and assigned(hp^.next) do
  1107. begin
  1108. def_to:=hp^.next^.nextPara.paratype.def;
  1109. if not(is_in_limit(def_from,def_to)) then
  1110. begin
  1111. hp2:=hp^.next^.next;
  1112. dispose(hp^.next);
  1113. hp^.next:=hp2;
  1114. end
  1115. else
  1116. begin
  1117. { did we possibly find a better match? }
  1118. if (conv_to.size>def_to.size) or
  1119. is_in_limit(def_to,conv_to) then
  1120. begin
  1121. { is it the same as the previous best? }
  1122. if not defbase.is_equal(def_to,conv_to) then
  1123. begin
  1124. { no -> remove all previous best matches }
  1125. hp := hp^.next;
  1126. while procs <> hp do
  1127. begin
  1128. hp2 := procs;
  1129. procs := procs^.next;
  1130. dispose(hp2);
  1131. end;
  1132. { set new match type }
  1133. conv_to:=def_to;
  1134. end
  1135. { the new one matches just as well as the }
  1136. { old one -> keep both }
  1137. else
  1138. hp := hp^.next;
  1139. end
  1140. { not a better match -> remove }
  1141. else
  1142. begin
  1143. hp2 := hp^.next^.next;
  1144. dispose(hp^.next);
  1145. hp^.next:=hp2;
  1146. end;
  1147. end;
  1148. end;
  1149. end;
  1150. { update nextpara for all procedures }
  1151. hp:=procs;
  1152. while assigned(hp) do
  1153. begin
  1154. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1155. hp:=hp^.next;
  1156. end;
  1157. pt:=tcallparanode(pt.right);
  1158. end;
  1159. end;
  1160. { let's try to eliminate equal if there is an exact match
  1161. is there }
  1162. if assigned(procs) and assigned(procs^.next) then
  1163. begin
  1164. { reset nextpara for all procs left }
  1165. hp:=procs;
  1166. while assigned(hp) do
  1167. begin
  1168. hp^.nextpara:=hp^.firstpara;
  1169. hp:=hp^.next;
  1170. end;
  1171. pt:=tcallparanode(left);
  1172. while assigned(pt) do
  1173. begin
  1174. if cpf_exact_match_found in pt.callparaflags then
  1175. begin
  1176. hp:=procs;
  1177. procs:=nil;
  1178. while assigned(hp) do
  1179. begin
  1180. hp2:=hp^.next;
  1181. { keep the exact matches, dispose the others }
  1182. if (hp^.nextPara.argconvtyp=act_exact) then
  1183. begin
  1184. hp^.next:=procs;
  1185. procs:=hp;
  1186. end
  1187. else
  1188. dispose(hp);
  1189. hp:=hp2;
  1190. end;
  1191. end;
  1192. { update nextpara for all procedures }
  1193. hp:=procs;
  1194. while assigned(hp) do
  1195. begin
  1196. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1197. hp:=hp^.next;
  1198. end;
  1199. pt:=tcallparanode(pt.right);
  1200. end;
  1201. end;
  1202. { Check if there are integer constant to integer
  1203. parameters then choose the best matching integer
  1204. parameter and remove the others, this is Delphi
  1205. compatible. 1 = byte, 256 = word, etc. }
  1206. if assigned(procs) and assigned(procs^.next) then
  1207. begin
  1208. { reset nextpara for all procs left }
  1209. hp:=procs;
  1210. while assigned(hp) do
  1211. begin
  1212. hp^.nextpara:=hp^.firstpara;
  1213. hp:=hp^.next;
  1214. end;
  1215. pt:=tcallparanode(left);
  1216. while assigned(pt) do
  1217. begin
  1218. bestord:=nil;
  1219. if (pt.left.nodetype=ordconstn) and
  1220. is_integer(pt.resulttype.def) then
  1221. begin
  1222. hp:=procs;
  1223. while assigned(hp) do
  1224. begin
  1225. def_to:=hp^.nextPara.paratype.def;
  1226. { to be sure, it couldn't be something else,
  1227. also the defs here are all in the range
  1228. so now find the closest range }
  1229. if not is_integer(def_to) then
  1230. internalerror(43297815);
  1231. if (not assigned(bestord)) or
  1232. ((torddef(def_to).low>bestord.low) or
  1233. (torddef(def_to).high<bestord.high)) then
  1234. bestord:=torddef(def_to);
  1235. hp:=hp^.next;
  1236. end;
  1237. end;
  1238. { if a bestmatch is found then remove the other
  1239. procs which don't match the bestord }
  1240. if assigned(bestord) then
  1241. begin
  1242. hp:=procs;
  1243. procs:=nil;
  1244. while assigned(hp) do
  1245. begin
  1246. hp2:=hp^.next;
  1247. { keep matching bestord, dispose the others }
  1248. if (torddef(hp^.nextPara.paratype.def)=bestord) then
  1249. begin
  1250. hp^.next:=procs;
  1251. procs:=hp;
  1252. end
  1253. else
  1254. dispose(hp);
  1255. hp:=hp2;
  1256. end;
  1257. end;
  1258. { update nextpara for all procedures }
  1259. hp:=procs;
  1260. while assigned(hp) do
  1261. begin
  1262. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1263. hp:=hp^.next;
  1264. end;
  1265. pt:=tcallparanode(pt.right);
  1266. end;
  1267. end;
  1268. { Check if there are convertlevel 1 and 2 differences
  1269. left for the parameters, then discard all convertlevel
  1270. 2 procedures. The value of convlevelXfound can still
  1271. be used, because all convertables are still here or
  1272. not }
  1273. if assigned(procs) and assigned(procs^.next) then
  1274. begin
  1275. { reset nextpara for all procs left }
  1276. hp:=procs;
  1277. while assigned(hp) do
  1278. begin
  1279. hp^.nextpara:=hp^.firstpara;
  1280. hp:=hp^.next;
  1281. end;
  1282. pt:=tcallparanode(left);
  1283. while assigned(pt) do
  1284. begin
  1285. if (cpf_convlevel1found in pt.callparaflags) and
  1286. (cpf_convlevel2found in pt.callparaflags) then
  1287. begin
  1288. hp:=procs;
  1289. procs:=nil;
  1290. while assigned(hp) do
  1291. begin
  1292. hp2:=hp^.next;
  1293. { keep all not act_convertable and all convertlevels=1 }
  1294. if (hp^.nextPara.argconvtyp<>act_convertable) or
  1295. (hp^.nextPara.convertlevel=1) then
  1296. begin
  1297. hp^.next:=procs;
  1298. procs:=hp;
  1299. end
  1300. else
  1301. dispose(hp);
  1302. hp:=hp2;
  1303. end;
  1304. end;
  1305. { update nextpara for all procedures }
  1306. hp:=procs;
  1307. while assigned(hp) do
  1308. begin
  1309. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1310. hp:=hp^.next;
  1311. end;
  1312. pt:=tcallparanode(pt.right);
  1313. end;
  1314. end;
  1315. if not(assigned(procs)) or assigned(procs^.next) then
  1316. begin
  1317. CGMessage(cg_e_cant_choose_overload_function);
  1318. symtableprocentry.write_parameter_lists(nil);
  1319. goto errorexit;
  1320. end;
  1321. if make_ref then
  1322. begin
  1323. procs^.data.lastref:=tref.create(procs^.data.lastref,@fileinfo);
  1324. inc(procs^.data.refcount);
  1325. if procs^.data.defref=nil then
  1326. procs^.data.defref:=procs^.data.lastref;
  1327. end;
  1328. procdefinition:=procs^.data;
  1329. { big error for with statements
  1330. symtableproc:=procdefinition.owner;
  1331. but neede for overloaded operators !! }
  1332. if symtableproc=nil then
  1333. symtableproc:=procdefinition.owner;
  1334. end; { end of procedure to call determination }
  1335. { add needed default parameters }
  1336. if assigned(procs) and
  1337. (paralength<procdefinition.maxparacount) then
  1338. begin
  1339. { add default parameters, just read back the skipped
  1340. paras starting from firstPara.previous, when not available
  1341. (all parameters are default) then start with the last
  1342. parameter and read backward (PFV) }
  1343. if not assigned(procs^.firstpara) then
  1344. pdc:=tparaitem(procs^.data.Para.last)
  1345. else
  1346. pdc:=tparaitem(procs^.firstPara.previous);
  1347. while assigned(pdc) do
  1348. begin
  1349. if not assigned(pdc.defaultvalue) then
  1350. internalerror(751349858);
  1351. left:=ccallparanode.create(genconstsymtree(tconstsym(pdc.defaultvalue)),left);
  1352. pdc:=tparaitem(pdc.previous);
  1353. end;
  1354. end;
  1355. end;
  1356. { handle predefined procedures }
  1357. is_const:=(procdefinition.proccalloption=pocall_internconst) and
  1358. ((block_type in [bt_const,bt_type]) or
  1359. (assigned(left) and (tcallparanode(left).left.nodetype in [realconstn,ordconstn])));
  1360. if (procdefinition.proccalloption=pocall_internproc) or is_const then
  1361. begin
  1362. if assigned(left) then
  1363. begin
  1364. { ptr and settextbuf needs two args }
  1365. if assigned(tcallparanode(left).right) then
  1366. begin
  1367. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,left);
  1368. left:=nil;
  1369. end
  1370. else
  1371. begin
  1372. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,tcallparanode(left).left);
  1373. tcallparanode(left).left:=nil;
  1374. end;
  1375. end
  1376. else
  1377. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,nil);
  1378. result:=hpt;
  1379. goto errorexit;
  1380. end;
  1381. { Calling a message method directly ? }
  1382. if assigned(procdefinition) and
  1383. (po_containsself in procdefinition.procoptions) then
  1384. message(cg_e_cannot_call_message_direct);
  1385. { ensure that the result type is set }
  1386. if not restypeset then
  1387. resulttype:=procdefinition.rettype
  1388. else
  1389. resulttype:=restype;
  1390. { get a register for the return value }
  1391. if (not is_void(resulttype.def)) then
  1392. begin
  1393. if paramanager.ret_in_acc(resulttype.def) then
  1394. begin
  1395. { wide- and ansistrings are returned in EAX }
  1396. { but they are imm. moved to a memory location }
  1397. if is_widestring(resulttype.def) or
  1398. is_ansistring(resulttype.def) then
  1399. begin
  1400. { we use ansistrings so no fast exit here }
  1401. if assigned(procinfo) then
  1402. procinfo^.no_fast_exit:=true;
  1403. end;
  1404. end;
  1405. end;
  1406. { constructors return their current class type, not the type where the
  1407. constructor is declared, this can be different because of inheritance }
  1408. if (procdefinition.proctypeoption=potype_constructor) then
  1409. begin
  1410. if assigned(methodpointer) and
  1411. assigned(methodpointer.resulttype.def) and
  1412. (methodpointer.resulttype.def.deftype=classrefdef) then
  1413. resulttype:=tclassrefdef(methodpointer.resulttype.def).pointertype;
  1414. end;
  1415. { flag all callparanodes that belong to the varargs }
  1416. if (po_varargs in procdefinition.procoptions) then
  1417. begin
  1418. pt:=tcallparanode(left);
  1419. i:=paralength;
  1420. while (i>procdefinition.maxparacount) do
  1421. begin
  1422. include(tcallparanode(pt).flags,nf_varargs_para);
  1423. pt:=tcallparanode(pt.right);
  1424. dec(i);
  1425. end;
  1426. end;
  1427. { insert type conversions }
  1428. if assigned(left) then
  1429. begin
  1430. aktcallprocdef:=procdefinition;
  1431. tcallparanode(left).insert_typeconv(tparaitem(procdefinition.Para.first),true);
  1432. end;
  1433. errorexit:
  1434. { Reset some settings back }
  1435. if assigned(procs) then
  1436. dispose(procs);
  1437. aktcallprocdef:=oldcallprocdef;
  1438. end;
  1439. function tcallnode.pass_1 : tnode;
  1440. var
  1441. inlinecode : tnode;
  1442. inlined : boolean;
  1443. {$ifdef m68k}
  1444. regi : tregister;
  1445. {$endif}
  1446. method_must_be_valid : boolean;
  1447. label
  1448. errorexit;
  1449. begin
  1450. { the default is nothing to return }
  1451. location.loc:=LOC_INVALID;
  1452. result:=nil;
  1453. inlined:=false;
  1454. inlinecode := nil;
  1455. { work trough all parameters to get the register requirements }
  1456. if assigned(left) then
  1457. tcallparanode(left).det_registers;
  1458. if assigned(procdefinition) and
  1459. (procdefinition.proccalloption=pocall_inline) then
  1460. begin
  1461. inlinecode:=right;
  1462. if assigned(inlinecode) then
  1463. inlined:=true;
  1464. right:=nil;
  1465. end;
  1466. { procedure variable ? }
  1467. if assigned(right) then
  1468. begin
  1469. firstpass(right);
  1470. { procedure does a call }
  1471. if not (block_type in [bt_const,bt_type]) then
  1472. procinfo^.flags:=procinfo^.flags or pi_do_call;
  1473. rg.incrementregisterpushed(all_registers);
  1474. end
  1475. else
  1476. { not a procedure variable }
  1477. begin
  1478. { calc the correture value for the register }
  1479. { handle predefined procedures }
  1480. if (procdefinition.proccalloption=pocall_inline) then
  1481. begin
  1482. if assigned(methodpointer) then
  1483. CGMessage(cg_e_unable_inline_object_methods);
  1484. if assigned(right) and (right.nodetype<>procinlinen) then
  1485. CGMessage(cg_e_unable_inline_procvar);
  1486. { nodetype:=procinlinen; }
  1487. if not assigned(right) then
  1488. begin
  1489. if assigned(tprocdef(procdefinition).code) then
  1490. inlinecode:=cprocinlinenode.create(self,tnode(tprocdef(procdefinition).code))
  1491. else
  1492. CGMessage(cg_e_no_code_for_inline_stored);
  1493. if assigned(inlinecode) then
  1494. begin
  1495. { consider it has not inlined if called
  1496. again inside the args }
  1497. procdefinition.proccalloption:=pocall_fpccall;
  1498. firstpass(inlinecode);
  1499. inlined:=true;
  1500. end;
  1501. end;
  1502. end
  1503. else
  1504. begin
  1505. if not (block_type in [bt_const,bt_type]) then
  1506. procinfo^.flags:=procinfo^.flags or pi_do_call;
  1507. end;
  1508. { It doesn't hurt to calculate it already though :) (JM) }
  1509. rg.incrementregisterpushed(tprocdef(procdefinition).usedregisters);
  1510. end;
  1511. { get a register for the return value }
  1512. if (not is_void(resulttype.def)) then
  1513. begin
  1514. if paramanager.ret_in_param(resulttype.def) then
  1515. begin
  1516. location.loc:=LOC_CREFERENCE;
  1517. end
  1518. else
  1519. { ansi/widestrings must be registered, so we can dispose them }
  1520. if is_ansistring(resulttype.def) or
  1521. is_widestring(resulttype.def) then
  1522. begin
  1523. location.loc:=LOC_CREFERENCE;
  1524. registers32:=1;
  1525. end
  1526. else
  1527. { we have only to handle the result if it is used }
  1528. if (nf_return_value_used in flags) then
  1529. begin
  1530. case resulttype.def.deftype of
  1531. enumdef,
  1532. orddef :
  1533. begin
  1534. if (procdefinition.proctypeoption=potype_constructor) then
  1535. begin
  1536. if assigned(methodpointer) and
  1537. (methodpointer.resulttype.def.deftype=classrefdef) then
  1538. begin
  1539. location.loc:=LOC_REGISTER;
  1540. registers32:=1;
  1541. end
  1542. else
  1543. location.loc:=LOC_FLAGS;
  1544. end
  1545. else
  1546. begin
  1547. location.loc:=LOC_REGISTER;
  1548. if is_64bitint(resulttype.def) then
  1549. registers32:=2
  1550. else
  1551. registers32:=1;
  1552. end;
  1553. end;
  1554. floatdef :
  1555. begin
  1556. location.loc:=LOC_FPUREGISTER;
  1557. {$ifdef m68k}
  1558. if (cs_fp_emulation in aktmoduleswitches) or
  1559. (tfloatdef(resulttype.def).typ=s32real) then
  1560. registers32:=1
  1561. else
  1562. registersfpu:=1;
  1563. {$else not m68k}
  1564. registersfpu:=1;
  1565. {$endif not m68k}
  1566. end;
  1567. else
  1568. begin
  1569. location.loc:=LOC_REGISTER;
  1570. registers32:=1;
  1571. end;
  1572. end;
  1573. end;
  1574. end;
  1575. { a fpu can be used in any procedure !! }
  1576. registersfpu:=procdefinition.fpu_used;
  1577. { if this is a call to a method calc the registers }
  1578. if (methodpointer<>nil) then
  1579. begin
  1580. case methodpointer.nodetype of
  1581. { but only, if this is not a supporting node }
  1582. typen: ;
  1583. { we need one register for new return value PM }
  1584. hnewn : if registers32=0 then
  1585. registers32:=1;
  1586. else
  1587. begin
  1588. if (procdefinition.proctypeoption in [potype_constructor,potype_destructor]) and
  1589. assigned(symtableproc) and (symtableproc.symtabletype=withsymtable) and
  1590. not twithsymtable(symtableproc).direct_with then
  1591. begin
  1592. CGmessage(cg_e_cannot_call_cons_dest_inside_with);
  1593. end; { Is accepted by Delphi !! }
  1594. { this is not a good reason to accept it in FPC if we produce
  1595. wrong code for it !!! (PM) }
  1596. { R.Assign is not a constructor !!! }
  1597. { but for R^.Assign, R must be valid !! }
  1598. if (procdefinition.proctypeoption=potype_constructor) or
  1599. ((methodpointer.nodetype=loadn) and
  1600. ((methodpointer.resulttype.def.deftype=classrefdef) or
  1601. ((methodpointer.resulttype.def.deftype=objectdef) and
  1602. not(oo_has_virtual in tobjectdef(methodpointer.resulttype.def).objectoptions)
  1603. )
  1604. )
  1605. ) then
  1606. method_must_be_valid:=false
  1607. else
  1608. method_must_be_valid:=true;
  1609. firstpass(methodpointer);
  1610. set_varstate(methodpointer,method_must_be_valid);
  1611. { The object is already used ven if it is called once }
  1612. if (methodpointer.nodetype=loadn) and
  1613. (tloadnode(methodpointer).symtableentry.typ=varsym) then
  1614. tvarsym(tloadnode(methodpointer).symtableentry).varstate:=vs_used;
  1615. registersfpu:=max(methodpointer.registersfpu,registersfpu);
  1616. registers32:=max(methodpointer.registers32,registers32);
  1617. {$ifdef SUPPORT_MMX }
  1618. registersmmx:=max(methodpointer.registersmmx,registersmmx);
  1619. {$endif SUPPORT_MMX}
  1620. end;
  1621. end;
  1622. end;
  1623. if inlined then
  1624. right:=inlinecode;
  1625. { determine the registers of the procedure variable }
  1626. { is this OK for inlined procs also ?? (PM) }
  1627. if assigned(right) then
  1628. begin
  1629. registersfpu:=max(right.registersfpu,registersfpu);
  1630. registers32:=max(right.registers32,registers32);
  1631. {$ifdef SUPPORT_MMX}
  1632. registersmmx:=max(right.registersmmx,registersmmx);
  1633. {$endif SUPPORT_MMX}
  1634. end;
  1635. { determine the registers of the procedure }
  1636. if assigned(left) then
  1637. begin
  1638. registersfpu:=max(left.registersfpu,registersfpu);
  1639. registers32:=max(left.registers32,registers32);
  1640. {$ifdef SUPPORT_MMX}
  1641. registersmmx:=max(left.registersmmx,registersmmx);
  1642. {$endif SUPPORT_MMX}
  1643. end;
  1644. errorexit:
  1645. if inlined then
  1646. procdefinition.proccalloption:=pocall_inline;
  1647. end;
  1648. {$ifdef state_tracking}
  1649. function Tcallnode.track_state_pass(exec_known:boolean):boolean;
  1650. var hp:Tcallparanode;
  1651. value:Tnode;
  1652. begin
  1653. track_state_pass:=false;
  1654. hp:=Tcallparanode(left);
  1655. while assigned(hp) do
  1656. begin
  1657. if left.track_state_pass(exec_known) then
  1658. begin
  1659. left.resulttype.def:=nil;
  1660. do_resulttypepass(left);
  1661. end;
  1662. value:=aktstate.find_fact(hp.left);
  1663. if value<>nil then
  1664. begin
  1665. track_state_pass:=true;
  1666. hp.left.destroy;
  1667. hp.left:=value.getcopy;
  1668. do_resulttypepass(hp.left);
  1669. end;
  1670. hp:=Tcallparanode(hp.right);
  1671. end;
  1672. end;
  1673. {$endif}
  1674. function tcallnode.docompare(p: tnode): boolean;
  1675. begin
  1676. docompare :=
  1677. inherited docompare(p) and
  1678. (symtableprocentry = tcallnode(p).symtableprocentry) and
  1679. (symtableproc = tcallnode(p).symtableproc) and
  1680. (procdefinition = tcallnode(p).procdefinition) and
  1681. (methodpointer.isequal(tcallnode(p).methodpointer)) and
  1682. ((restypeset and tcallnode(p).restypeset and
  1683. (is_equal(restype.def,tcallnode(p).restype.def))) or
  1684. (not restypeset and not tcallnode(p).restypeset));
  1685. end;
  1686. {****************************************************************************
  1687. TPROCINLINENODE
  1688. ****************************************************************************}
  1689. constructor tprocinlinenode.create(callp,code : tnode);
  1690. begin
  1691. inherited create(procinlinen);
  1692. inlineprocdef:=tcallnode(callp).symtableprocentry.defs^.def;
  1693. retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
  1694. para_offset:=0;
  1695. para_size:=inlineprocdef.para_size(target_info.alignment.paraalign);
  1696. if paramanager.ret_in_param(inlineprocdef.rettype.def) then
  1697. inc(para_size,POINTER_SIZE);
  1698. { copy args }
  1699. if assigned(code) then
  1700. inlinetree:=code.getcopy
  1701. else inlinetree := nil;
  1702. registers32:=code.registers32;
  1703. registersfpu:=code.registersfpu;
  1704. {$ifdef SUPPORT_MMX}
  1705. registersmmx:=code.registersmmx;
  1706. {$endif SUPPORT_MMX}
  1707. resulttype:=inlineprocdef.rettype;
  1708. end;
  1709. destructor tprocinlinenode.destroy;
  1710. begin
  1711. if assigned(inlinetree) then
  1712. inlinetree.free;
  1713. inherited destroy;
  1714. end;
  1715. function tprocinlinenode.getcopy : tnode;
  1716. var
  1717. n : tprocinlinenode;
  1718. begin
  1719. n:=tprocinlinenode(inherited getcopy);
  1720. if assigned(inlinetree) then
  1721. n.inlinetree:=inlinetree.getcopy
  1722. else
  1723. n.inlinetree:=nil;
  1724. n.inlineprocdef:=inlineprocdef;
  1725. n.retoffset:=retoffset;
  1726. n.para_offset:=para_offset;
  1727. n.para_size:=para_size;
  1728. getcopy:=n;
  1729. end;
  1730. procedure tprocinlinenode.insertintolist(l : tnodelist);
  1731. begin
  1732. end;
  1733. function tprocinlinenode.pass_1 : tnode;
  1734. begin
  1735. result:=nil;
  1736. { left contains the code in tree form }
  1737. { but it has already been firstpassed }
  1738. { so firstpass(left); does not seem required }
  1739. { might be required later if we change the arg handling !! }
  1740. end;
  1741. function tprocinlinenode.docompare(p: tnode): boolean;
  1742. begin
  1743. docompare :=
  1744. inherited docompare(p) and
  1745. inlinetree.isequal(tprocinlinenode(p).inlinetree) and
  1746. (inlineprocdef = tprocinlinenode(p).inlineprocdef);
  1747. end;
  1748. begin
  1749. ccallnode:=tcallnode;
  1750. ccallparanode:=tcallparanode;
  1751. cprocinlinenode:=tprocinlinenode;
  1752. end.
  1753. {
  1754. $Log$
  1755. Revision 1.83 2002-07-20 11:57:53 florian
  1756. * types.pas renamed to defbase.pas because D6 contains a types
  1757. unit so this would conflicts if D6 programms are compiled
  1758. + Willamette/SSE2 instructions to assembler added
  1759. Revision 1.82 2002/07/19 11:41:35 daniel
  1760. * State tracker work
  1761. * The whilen and repeatn are now completely unified into whilerepeatn. This
  1762. allows the state tracker to change while nodes automatically into
  1763. repeat nodes.
  1764. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  1765. 'not(a>b)' is optimized into 'a<=b'.
  1766. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  1767. by removing the notn and later switchting the true and falselabels. The
  1768. same is done with 'repeat until not a'.
  1769. Revision 1.81 2002/07/15 18:03:14 florian
  1770. * readded removed changes
  1771. Revision 1.79 2002/07/11 14:41:27 florian
  1772. * start of the new generic parameter handling
  1773. Revision 1.80 2002/07/14 18:00:43 daniel
  1774. + Added the beginning of a state tracker. This will track the values of
  1775. variables through procedures and optimize things away.
  1776. Revision 1.78 2002/07/04 20:43:00 florian
  1777. * first x86-64 patches
  1778. Revision 1.77 2002/07/01 16:23:52 peter
  1779. * cg64 patch
  1780. * basics for currency
  1781. * asnode updates for class and interface (not finished)
  1782. Revision 1.76 2002/05/18 13:34:09 peter
  1783. * readded missing revisions
  1784. Revision 1.75 2002/05/16 19:46:37 carl
  1785. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  1786. + try to fix temp allocation (still in ifdef)
  1787. + generic constructor calls
  1788. + start of tassembler / tmodulebase class cleanup
  1789. Revision 1.73 2002/05/12 16:53:06 peter
  1790. * moved entry and exitcode to ncgutil and cgobj
  1791. * foreach gets extra argument for passing local data to the
  1792. iterator function
  1793. * -CR checks also class typecasts at runtime by changing them
  1794. into as
  1795. * fixed compiler to cycle with the -CR option
  1796. * fixed stabs with elf writer, finally the global variables can
  1797. be watched
  1798. * removed a lot of routines from cga unit and replaced them by
  1799. calls to cgobj
  1800. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  1801. u32bit then the other is typecasted also to u32bit without giving
  1802. a rangecheck warning/error.
  1803. * fixed pascal calling method with reversing also the high tree in
  1804. the parast, detected by tcalcst3 test
  1805. Revision 1.72 2002/04/25 20:16:38 peter
  1806. * moved more routines from cga/n386util
  1807. Revision 1.71 2002/04/20 21:32:23 carl
  1808. + generic FPC_CHECKPOINTER
  1809. + first parameter offset in stack now portable
  1810. * rename some constants
  1811. + move some cpu stuff to other units
  1812. - remove unused constents
  1813. * fix stacksize for some targets
  1814. * fix generic size problems which depend now on EXTEND_SIZE constant
  1815. Revision 1.70 2002/04/16 16:09:08 peter
  1816. * allow passing the address of a procedure to a formal parameter
  1817. in delphi mode
  1818. Revision 1.69 2002/04/15 19:44:19 peter
  1819. * fixed stackcheck that would be called recursively when a stack
  1820. error was found
  1821. * generic changeregsize(reg,size) for i386 register resizing
  1822. * removed some more routines from cga unit
  1823. * fixed returnvalue handling
  1824. * fixed default stacksize of linux and go32v2, 8kb was a bit small :-)
  1825. Revision 1.68 2002/04/15 18:57:22 carl
  1826. + target_info.size_of_pointer -> POINTER_SIZE
  1827. Revision 1.67 2002/04/02 17:11:28 peter
  1828. * tlocation,treference update
  1829. * LOC_CONSTANT added for better constant handling
  1830. * secondadd splitted in multiple routines
  1831. * location_force_reg added for loading a location to a register
  1832. of a specified size
  1833. * secondassignment parses now first the right and then the left node
  1834. (this is compatible with Kylix). This saves a lot of push/pop especially
  1835. with string operations
  1836. * adapted some routines to use the new cg methods
  1837. Revision 1.66 2002/03/31 20:26:33 jonas
  1838. + a_loadfpu_* and a_loadmm_* methods in tcg
  1839. * register allocation is now handled by a class and is mostly processor
  1840. independent (+rgobj.pas and i386/rgcpu.pas)
  1841. * temp allocation is now handled by a class (+tgobj.pas, -i386\tgcpu.pas)
  1842. * some small improvements and fixes to the optimizer
  1843. * some register allocation fixes
  1844. * some fpuvaroffset fixes in the unary minus node
  1845. * push/popusedregisters is now called rg.save/restoreusedregisters and
  1846. (for i386) uses temps instead of push/pop's when using -Op3 (that code is
  1847. also better optimizable)
  1848. * fixed and optimized register saving/restoring for new/dispose nodes
  1849. * LOC_FPU locations now also require their "register" field to be set to
  1850. R_ST, not R_ST0 (the latter is used for LOC_CFPUREGISTER locations only)
  1851. - list field removed of the tnode class because it's not used currently
  1852. and can cause hard-to-find bugs
  1853. Revision 1.65 2002/03/30 23:02:42 carl
  1854. * avoid crash with inline routines
  1855. Revision 1.64 2002/01/24 18:25:48 peter
  1856. * implicit result variable generation for assembler routines
  1857. * removed m_tp modeswitch, use m_tp7 or not(m_fpc) instead
  1858. Revision 1.63 2002/01/24 12:33:52 jonas
  1859. * adapted ranges of native types to int64 (e.g. high cardinal is no
  1860. longer longint($ffffffff), but just $fffffff in psystem)
  1861. * small additional fix in 64bit rangecheck code generation for 32 bit
  1862. processors
  1863. * adaption of ranges required the matching talgorithm used for selecting
  1864. which overloaded procedure to call to be adapted. It should now always
  1865. select the closest match for ordinal parameters.
  1866. + inttostr(qword) in sysstr.inc/sysstrh.inc
  1867. + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
  1868. fixes were required to be able to add them)
  1869. * is_in_limit() moved from ncal to types unit, should always be used
  1870. instead of direct comparisons of low/high values of orddefs because
  1871. qword is a special case
  1872. Revision 1.62 2002/01/19 11:57:05 peter
  1873. * fixed path appending for lib
  1874. }