ncal.pas 91 KB

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