ncal.pas 91 KB

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