ncal.pas 93 KB

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