ncal.pas 95 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648
  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,cginfo,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. {$ifdef extdebug}
  550. if do_count then
  551. begin
  552. store_count_ref:=count_ref;
  553. count_ref:=true;
  554. end;
  555. {$endif def extdebug}
  556. { Be sure to have the resulttype }
  557. if not assigned(left.resulttype.def) then
  558. resulttypepass(left);
  559. { Handle varargs and hidden paras directly, no typeconvs or }
  560. { typechecking needed }
  561. if (nf_varargs_para in flags) then
  562. begin
  563. { convert pascal to C types }
  564. case left.resulttype.def.deftype of
  565. stringdef :
  566. inserttypeconv(left,charpointertype);
  567. floatdef :
  568. inserttypeconv(left,s64floattype);
  569. end;
  570. set_varstate(left,true);
  571. resulttype:=left.resulttype;
  572. end
  573. else
  574. if (paraitem.paratyp = vs_hidden) then
  575. begin
  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. { File types are only allowed for var parameters }
  657. if (paraitem.paratype.def.deftype=filedef) and
  658. (paraitem.paratyp<>vs_var) then
  659. CGMessage(cg_e_file_must_call_by_reference);
  660. { Handle formal parameters separate }
  661. if (paraitem.paratype.def.deftype=formaldef) then
  662. begin
  663. { load procvar if a procedure is passed }
  664. if (m_tp_procvar in aktmodeswitches) and
  665. (left.nodetype=calln) and
  666. (is_void(left.resulttype.def)) then
  667. load_procvar_from_calln(left);
  668. case paraitem.paratyp of
  669. vs_var,
  670. vs_out :
  671. begin
  672. if not valid_for_formal_var(left) then
  673. CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
  674. end;
  675. vs_const :
  676. begin
  677. if not valid_for_formal_const(left) then
  678. CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
  679. end;
  680. end;
  681. end
  682. else
  683. begin
  684. { check if the argument is allowed }
  685. if (paraitem.paratyp in [vs_out,vs_var]) then
  686. valid_for_var(left);
  687. end;
  688. if paraitem.paratyp in [vs_var,vs_const] then
  689. begin
  690. { Causes problems with const ansistrings if also }
  691. { done for vs_const (JM) }
  692. if paraitem.paratyp = vs_var then
  693. set_unique(left);
  694. make_not_regable(left);
  695. end;
  696. { ansistrings out paramaters doesn't need to be }
  697. { unique, they are finalized }
  698. if paraitem.paratyp=vs_out then
  699. make_not_regable(left);
  700. if do_count then
  701. begin
  702. { not completly proper, but avoids some warnings }
  703. if (paraitem.paratyp in [vs_var,vs_out]) then
  704. set_funcret_is_valid(left);
  705. set_varstate(left,not(paraitem.paratyp in [vs_var,vs_out]));
  706. end;
  707. { must only be done after typeconv PM }
  708. resulttype:=paraitem.paratype;
  709. end;
  710. { process next node }
  711. if assigned(right) then
  712. tcallparanode(right).insert_typeconv(do_count);
  713. dec(parsing_para_level);
  714. {$ifdef extdebug}
  715. if do_count then
  716. count_ref:=store_count_ref;
  717. {$endif def extdebug}
  718. end;
  719. procedure tcallparanode.det_registers;
  720. var
  721. old_get_para_resulttype : boolean;
  722. old_array_constructor : boolean;
  723. begin
  724. if assigned(right) then
  725. begin
  726. tcallparanode(right).det_registers;
  727. registers32:=right.registers32;
  728. registersfpu:=right.registersfpu;
  729. {$ifdef SUPPORT_MMX}
  730. registersmmx:=right.registersmmx;
  731. {$endif}
  732. end;
  733. old_array_constructor:=allow_array_constructor;
  734. old_get_para_resulttype:=get_para_resulttype;
  735. get_para_resulttype:=true;
  736. allow_array_constructor:=true;
  737. firstpass(left);
  738. get_para_resulttype:=old_get_para_resulttype;
  739. allow_array_constructor:=old_array_constructor;
  740. if left.registers32>registers32 then
  741. registers32:=left.registers32;
  742. if left.registersfpu>registersfpu then
  743. registersfpu:=left.registersfpu;
  744. {$ifdef SUPPORT_MMX}
  745. if left.registersmmx>registersmmx then
  746. registersmmx:=left.registersmmx;
  747. {$endif SUPPORT_MMX}
  748. end;
  749. procedure tcallparanode.firstcallparan(do_count : boolean);
  750. begin
  751. if not assigned(left.resulttype.def) then
  752. begin
  753. get_paratype;
  754. {
  755. if assigned(defcoll) then
  756. insert_typeconv(defcoll,do_count);
  757. }
  758. end;
  759. det_registers;
  760. end;
  761. function tcallparanode.docompare(p: tnode): boolean;
  762. begin
  763. docompare :=
  764. inherited docompare(p) and
  765. (callparaflags = tcallparanode(p).callparaflags)
  766. ;
  767. end;
  768. {****************************************************************************
  769. TCALLNODE
  770. ****************************************************************************}
  771. constructor tcallnode.create(l:tnode;v : tprocsym;st : tsymtable; mp : tnode);
  772. begin
  773. inherited create(calln,l,nil);
  774. symtableprocentry:=v;
  775. symtableproc:=st;
  776. include(flags,nf_return_value_used);
  777. methodpointer:=mp;
  778. procdefinition:=nil;
  779. restypeset := false;
  780. funcretrefnode:=nil;
  781. paralength:=-1;
  782. end;
  783. constructor tcallnode.createintern(const name: string; params: tnode);
  784. var
  785. srsym: tsym;
  786. symowner: tsymtable;
  787. begin
  788. if not (cs_compilesystem in aktmoduleswitches) then
  789. begin
  790. srsym := searchsymonlyin(systemunit,name);
  791. symowner := systemunit;
  792. end
  793. else
  794. begin
  795. searchsym(name,srsym,symowner);
  796. if not assigned(srsym) then
  797. searchsym(upper(name),srsym,symowner);
  798. end;
  799. if not assigned(srsym) or
  800. (srsym.typ <> procsym) then
  801. begin
  802. {$ifdef EXTDEBUG}
  803. Comment(V_Error,'unknown compilerproc '+name);
  804. {$endif EXTDEBUG}
  805. internalerror(200107271);
  806. end;
  807. self.create(params,tprocsym(srsym),symowner,nil);
  808. end;
  809. constructor tcallnode.createinternres(const name: string; params: tnode; const res: ttype);
  810. begin
  811. self.createintern(name,params);
  812. restype := res;
  813. restypeset := true;
  814. { both the normal and specified resulttype either have to be returned via a }
  815. { parameter or not, but no mixing (JM) }
  816. if paramanager.ret_in_param(restype.def,pocall_compilerproc) xor
  817. paramanager.ret_in_param(symtableprocentry.first_procdef.rettype.def,symtableprocentry.first_procdef.proccalloption) then
  818. internalerror(200108291);
  819. end;
  820. constructor tcallnode.createinternreturn(const name: string; params: tnode; returnnode : tnode);
  821. begin
  822. self.createintern(name,params);
  823. funcretrefnode:=returnnode;
  824. if not paramanager.ret_in_param(symtableprocentry.first_procdef.rettype.def,symtableprocentry.first_procdef.proccalloption) then
  825. internalerror(200204247);
  826. end;
  827. destructor tcallnode.destroy;
  828. begin
  829. methodpointer.free;
  830. funcretrefnode.free;
  831. inherited destroy;
  832. end;
  833. constructor tcallnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  834. begin
  835. inherited ppuload(t,ppufile);
  836. symtableprocentry:=tprocsym(ppufile.getderef);
  837. {$ifdef fpc}
  838. {$warning FIXME: No withsymtable support}
  839. {$endif}
  840. symtableproc:=nil;
  841. procdefinition:=tprocdef(ppufile.getderef);
  842. restypeset:=boolean(ppufile.getbyte);
  843. methodpointer:=ppuloadnode(ppufile);
  844. funcretrefnode:=ppuloadnode(ppufile);
  845. end;
  846. procedure tcallnode.ppuwrite(ppufile:tcompilerppufile);
  847. begin
  848. inherited ppuwrite(ppufile);
  849. ppufile.putderef(symtableprocentry);
  850. ppufile.putderef(procdefinition);
  851. ppufile.putbyte(byte(restypeset));
  852. ppuwritenode(ppufile,methodpointer);
  853. ppuwritenode(ppufile,funcretrefnode);
  854. end;
  855. procedure tcallnode.derefimpl;
  856. begin
  857. inherited derefimpl;
  858. resolvesym(pointer(symtableprocentry));
  859. symtableproc:=symtableprocentry.owner;
  860. resolvedef(pointer(procdefinition));
  861. if assigned(methodpointer) then
  862. methodpointer.derefimpl;
  863. if assigned(funcretrefnode) then
  864. funcretrefnode.derefimpl;
  865. end;
  866. procedure tcallnode.set_procvar(procvar:tnode);
  867. begin
  868. right:=procvar;
  869. end;
  870. function tcallnode.getcopy : tnode;
  871. var
  872. n : tcallnode;
  873. begin
  874. n:=tcallnode(inherited getcopy);
  875. n.symtableprocentry:=symtableprocentry;
  876. n.symtableproc:=symtableproc;
  877. n.procdefinition:=procdefinition;
  878. n.restype := restype;
  879. n.restypeset := restypeset;
  880. if assigned(methodpointer) then
  881. n.methodpointer:=methodpointer.getcopy
  882. else
  883. n.methodpointer:=nil;
  884. if assigned(funcretrefnode) then
  885. n.funcretrefnode:=funcretrefnode.getcopy
  886. else
  887. n.funcretrefnode:=nil;
  888. result:=n;
  889. end;
  890. procedure tcallnode.insertintolist(l : tnodelist);
  891. begin
  892. end;
  893. procedure tcallnode.verifyabstract(p : tnamedindexitem;arg:pointer);
  894. var
  895. hp : tprocdef;
  896. j: integer;
  897. begin
  898. if (tsym(p).typ=procsym) then
  899. begin
  900. for j:=1 to tprocsym(p).procdef_count do
  901. begin
  902. { index starts at 1 }
  903. hp:=tprocsym(p).procdef[j];
  904. { If this is an abstract method insert into the list }
  905. if (po_abstractmethod in hp.procoptions) then
  906. AbstractMethodsList.Insert(hp.procsym.name)
  907. else
  908. { If this symbol is already in the list, and it is
  909. an overriding method or dynamic, then remove it from the list
  910. }
  911. begin
  912. { symbol was found }
  913. if AbstractMethodsList.Find(hp.procsym.name) <> nil then
  914. begin
  915. if po_overridingmethod in hp.procoptions then
  916. AbstractMethodsList.Remove(hp.procsym.name);
  917. end;
  918. end;
  919. end;
  920. end;
  921. end;
  922. procedure tcallnode.verifyabstractcalls;
  923. var
  924. objectdf : tobjectdef;
  925. parents : tlinkedlist;
  926. objectinfo : tobjectinfoitem;
  927. stritem : tstringlistitem;
  928. _classname : string;
  929. begin
  930. objectdf := nil;
  931. { verify if trying to create an instance of a class which contains
  932. non-implemented abstract methods }
  933. { first verify this class type, no class than exit }
  934. { also, this checking can only be done if the constructor is directly
  935. called, indirect constructor calls cannot be checked.
  936. }
  937. if assigned(methodpointer) and assigned(methodpointer.resulttype.def) then
  938. if (methodpointer.resulttype.def.deftype = classrefdef) and
  939. (methodpointer.nodetype in [typen,loadvmtn]) then
  940. begin
  941. if (tclassrefdef(methodpointer.resulttype.def).pointertype.def.deftype = objectdef) then
  942. objectdf := tobjectdef(tclassrefdef(methodpointer.resulttype.def).pointertype.def);
  943. end;
  944. if not assigned(objectdf) then exit;
  945. if assigned(objectdf.symtable.name) then
  946. _classname := objectdf.symtable.name^
  947. else
  948. _classname := '';
  949. parents := tlinkedlist.create;
  950. AbstractMethodsList := tstringlist.create;
  951. { insert all parents in this class : the first item in the
  952. list will be the base parent of the class .
  953. }
  954. while assigned(objectdf) do
  955. begin
  956. objectinfo:=tobjectinfoitem.create(objectdf);
  957. parents.insert(objectinfo);
  958. objectdf := objectdf.childof;
  959. end;
  960. { now all parents are in the correct order
  961. insert all abstract methods in the list, and remove
  962. those which are overriden by parent classes.
  963. }
  964. objectinfo:=tobjectinfoitem(parents.first);
  965. while assigned(objectinfo) do
  966. begin
  967. objectdf := objectinfo.objinfo;
  968. if assigned(objectdf.symtable) then
  969. objectdf.symtable.foreach({$ifdef FPCPROCVAR}@{$endif}verifyabstract,nil);
  970. objectinfo:=tobjectinfoitem(objectinfo.next);
  971. end;
  972. if assigned(parents) then
  973. parents.free;
  974. { Finally give out a warning for each abstract method still in the list }
  975. stritem := tstringlistitem(AbstractMethodsList.first);
  976. while assigned(stritem) do
  977. begin
  978. if assigned(stritem.fpstr) then
  979. Message2(type_w_instance_with_abstract,lower(_classname),lower(stritem.fpstr^));
  980. stritem := tstringlistitem(stritem.next);
  981. end;
  982. if assigned(AbstractMethodsList) then
  983. AbstractMethodsList.Free;
  984. end;
  985. function Tcallnode.candidates_find:pcandidate;
  986. var
  987. j : integer;
  988. pd : tprocdef;
  989. procs,hp : pcandidate;
  990. found,
  991. has_overload_directive : boolean;
  992. srsymtable : tsymtable;
  993. srprocsym : tprocsym;
  994. procedure proc_add(pd:tprocdef);
  995. var
  996. i : integer;
  997. begin
  998. { generate new candidate entry }
  999. new(hp);
  1000. fillchar(hp^,sizeof(tcandidate),0);
  1001. hp^.data:=pd;
  1002. hp^.next:=procs;
  1003. procs:=hp;
  1004. { Find last parameter, skip all default parameters
  1005. that are not passed. Ignore this skipping for varargs }
  1006. hp^.firstpara:=tparaitem(pd.Para.last);
  1007. if not(po_varargs in pd.procoptions) then
  1008. begin
  1009. for i:=1 to pd.maxparacount-paralength do
  1010. hp^.firstpara:=tparaitem(hp^.firstPara.previous);
  1011. end;
  1012. end;
  1013. begin
  1014. procs:=nil;
  1015. { when the definition has overload directive set, we search for
  1016. overloaded definitions in the class, this only needs to be done once
  1017. for class entries as the tree keeps always the same }
  1018. if (not symtableprocentry.overloadchecked) and
  1019. (po_overload in symtableprocentry.first_procdef.procoptions) and
  1020. (symtableprocentry.owner.symtabletype=objectsymtable) then
  1021. search_class_overloads(symtableprocentry);
  1022. { link all procedures which have the same # of parameters }
  1023. for j:=1 to symtableprocentry.procdef_count do
  1024. begin
  1025. pd:=symtableprocentry.procdef[j];
  1026. { Is the procdef visible? This needs to be checked on
  1027. procdef level since a symbol can contain both private and
  1028. public declarations. But the check should not be done
  1029. when the callnode is generated by a property }
  1030. if (nf_isproperty in flags) or
  1031. (pd.owner.symtabletype<>objectsymtable) or
  1032. pd.is_visible_for_proc(aktprocdef) then
  1033. begin
  1034. { only when the # of parameter are supported by the
  1035. procedure }
  1036. if (paralength>=pd.minparacount) and
  1037. ((po_varargs in pd.procoptions) or { varargs }
  1038. (paralength<=pd.maxparacount)) then
  1039. proc_add(pd);
  1040. end;
  1041. end;
  1042. { remember if the procedure is declared with the overload directive,
  1043. it's information is still needed also after all procs are removed }
  1044. has_overload_directive:=(po_overload in symtableprocentry.first_procdef.procoptions);
  1045. { when the definition has overload directive set, we search for
  1046. overloaded definitions in the symtablestack. The found
  1047. entries are only added to the procs list and not the procsym, because
  1048. the list can change in every situation }
  1049. if has_overload_directive and
  1050. (symtableprocentry.owner.symtabletype<>objectsymtable) then
  1051. begin
  1052. srsymtable:=symtableprocentry.owner.next;
  1053. while assigned(srsymtable) do
  1054. begin
  1055. if srsymtable.symtabletype in [localsymtable,staticsymtable,globalsymtable] then
  1056. begin
  1057. srprocsym:=tprocsym(srsymtable.speedsearch(symtableprocentry.name,symtableprocentry.speedvalue));
  1058. { process only visible procsyms }
  1059. if assigned(srprocsym) and
  1060. (srprocsym.typ=procsym) and
  1061. srprocsym.is_visible_for_proc(aktprocdef) then
  1062. begin
  1063. { if this procedure doesn't have overload we can stop
  1064. searching }
  1065. if not(po_overload in srprocsym.first_procdef.procoptions) then
  1066. break;
  1067. { process all overloaded definitions }
  1068. for j:=1 to srprocsym.procdef_count do
  1069. begin
  1070. pd:=srprocsym.procdef[j];
  1071. { only when the # of parameter are supported by the
  1072. procedure }
  1073. if (paralength>=pd.minparacount) and
  1074. ((po_varargs in pd.procoptions) or { varargs }
  1075. (paralength<=pd.maxparacount)) then
  1076. begin
  1077. found:=false;
  1078. hp:=procs;
  1079. while assigned(hp) do
  1080. begin
  1081. if compare_paras(hp^.data.para,pd.para,cp_value_equal_const,false)>=te_equal then
  1082. begin
  1083. found:=true;
  1084. break;
  1085. end;
  1086. hp:=hp^.next;
  1087. end;
  1088. if not found then
  1089. proc_add(pd);
  1090. end;
  1091. end;
  1092. end;
  1093. end;
  1094. srsymtable:=srsymtable.next;
  1095. end;
  1096. end;
  1097. candidates_find:=procs;
  1098. end;
  1099. procedure tcallnode.candidates_free(procs:pcandidate);
  1100. var
  1101. hpnext,
  1102. hp : pcandidate;
  1103. begin
  1104. hp:=procs;
  1105. while assigned(hp) do
  1106. begin
  1107. hpnext:=hp^.next;
  1108. dispose(hp);
  1109. hp:=hpnext;
  1110. end;
  1111. end;
  1112. procedure tcallnode.candidates_list(procs:pcandidate;all:boolean);
  1113. var
  1114. hp : pcandidate;
  1115. begin
  1116. hp:=procs;
  1117. while assigned(hp) do
  1118. begin
  1119. if all or
  1120. (not hp^.invalid) then
  1121. MessagePos1(hp^.data.fileinfo,sym_h_param_list,hp^.data.fullprocname);
  1122. hp:=hp^.next;
  1123. end;
  1124. end;
  1125. {$ifdef EXTDEBUG}
  1126. procedure Tcallnode.candidates_dump_info(lvl:longint;procs:pcandidate);
  1127. function ParaTreeStr(p:tcallparanode):string;
  1128. begin
  1129. result:='';
  1130. while assigned(p) do
  1131. begin
  1132. if result<>'' then
  1133. result:=result+',';
  1134. result:=result+p.resulttype.def.typename;
  1135. p:=tcallparanode(p.right);
  1136. end;
  1137. end;
  1138. var
  1139. hp : pcandidate;
  1140. currpara : tparaitem;
  1141. begin
  1142. if not CheckVerbosity(lvl) then
  1143. exit;
  1144. Comment(lvl+V_LineInfo,'Overloaded callnode: '+symtableprocentry.name+'('+ParaTreeStr(tcallparanode(left))+')');
  1145. hp:=procs;
  1146. while assigned(hp) do
  1147. begin
  1148. Comment(lvl,' '+hp^.data.fullprocname);
  1149. if (hp^.invalid) then
  1150. Comment(lvl,' invalid')
  1151. else
  1152. begin
  1153. Comment(lvl,' ex: '+tostr(hp^.exact_count)+
  1154. ' eq: '+tostr(hp^.equal_count)+
  1155. ' l1: '+tostr(hp^.cl1_count)+
  1156. ' l2: '+tostr(hp^.cl2_count)+
  1157. ' l3: '+tostr(hp^.cl3_count)+
  1158. ' oper: '+tostr(hp^.coper_count)+
  1159. ' ord: '+realtostr(hp^.exact_count));
  1160. { Print parameters in left-right order }
  1161. currpara:=hp^.firstpara;
  1162. if assigned(currpara) then
  1163. begin
  1164. while assigned(currpara.next) do
  1165. currpara:=tparaitem(currpara.next);
  1166. end;
  1167. while assigned(currpara) do
  1168. begin
  1169. if (currpara.paratyp<>vs_hidden) then
  1170. Comment(lvl,' - '+currpara.paratype.def.typename+' : '+EqualTypeName[currpara.eqval]);
  1171. currpara:=tparaitem(currpara.previous);
  1172. end;
  1173. end;
  1174. hp:=hp^.next;
  1175. end;
  1176. end;
  1177. {$endif EXTDEBUG}
  1178. procedure Tcallnode.candidates_get_information(procs:pcandidate);
  1179. var
  1180. hp : pcandidate;
  1181. currpara : tparaitem;
  1182. currparanr : byte;
  1183. def_from,
  1184. def_to : tdef;
  1185. pt : tcallparanode;
  1186. eq : tequaltype;
  1187. convtype : tconverttype;
  1188. pdoper : tprocdef;
  1189. begin
  1190. { process all procs }
  1191. hp:=procs;
  1192. while assigned(hp) do
  1193. begin
  1194. { We compare parameters in reverse order (right to left),
  1195. the firstpara is already pointing to the last parameter
  1196. were we need to start comparing }
  1197. currparanr:=paralength;
  1198. currpara:=hp^.firstpara;
  1199. while assigned(currpara) and (currpara.paratyp=vs_hidden) do
  1200. currpara:=tparaitem(currpara.previous);
  1201. pt:=tcallparanode(left);
  1202. while assigned(pt) and assigned(currpara) do
  1203. begin
  1204. { retrieve current parameter definitions to compares }
  1205. eq:=te_incompatible;
  1206. def_from:=pt.resulttype.def;
  1207. def_to:=currpara.paratype.def;
  1208. if not(assigned(def_from)) then
  1209. internalerror(200212091);
  1210. if not(
  1211. assigned(def_to) or
  1212. ((po_varargs in hp^.data.procoptions) and
  1213. (currparanr>hp^.data.minparacount))
  1214. ) then
  1215. internalerror(200212092);
  1216. { varargs are always equal, but not exact }
  1217. if (po_varargs in hp^.data.procoptions) and
  1218. (currparanr>hp^.data.minparacount) then
  1219. begin
  1220. inc(hp^.equal_count);
  1221. eq:=te_equal;
  1222. end
  1223. else
  1224. { same definition -> exact }
  1225. if (def_from=def_to) then
  1226. begin
  1227. inc(hp^.exact_count);
  1228. eq:=te_exact;
  1229. end
  1230. else
  1231. { for value and const parameters check if a integer is constant or
  1232. included in other integer -> equal and calc ordinal_distance }
  1233. if not(currpara.paratyp in [vs_var,vs_out]) and
  1234. is_integer(def_from) and
  1235. is_integer(def_to) and
  1236. is_in_limit(def_from,def_to) then
  1237. begin
  1238. inc(hp^.equal_count);
  1239. eq:=te_equal;
  1240. hp^.ordinal_distance:=hp^.ordinal_distance+
  1241. abs(bestreal(torddef(def_from).low)-bestreal(torddef(def_to).low));
  1242. hp^.ordinal_distance:=hp^.ordinal_distance+
  1243. abs(bestreal(torddef(def_to).high)-bestreal(torddef(def_from).high));
  1244. { Give wrong sign a small penalty, this is need to get a diffrence
  1245. from word->[longword,longint] }
  1246. if is_signed(def_from)<>is_signed(def_to) then
  1247. hp^.ordinal_distance:=hp^.ordinal_distance+1.0;
  1248. end
  1249. else
  1250. { generic type comparision }
  1251. begin
  1252. eq:=compare_defs_ext(def_from,def_to,pt.left.nodetype,
  1253. false,true,convtype,pdoper);
  1254. { when the types are not equal we need to check
  1255. some special case for parameter passing }
  1256. if (eq<te_equal) then
  1257. begin
  1258. if currpara.paratyp in [vs_var,vs_out] then
  1259. begin
  1260. { para requires an equal type so the previous found
  1261. match was not good enough, reset to incompatible }
  1262. eq:=te_incompatible;
  1263. { var_para_allowed will return te_equal and te_convert_l1 to
  1264. make a difference for best matching }
  1265. var_para_allowed(eq,pt.resulttype.def,currpara.paratype.def)
  1266. end
  1267. else
  1268. para_allowed(eq,pt,def_to);
  1269. end;
  1270. case eq of
  1271. te_exact :
  1272. internalerror(200212071); { already checked }
  1273. te_equal :
  1274. inc(hp^.equal_count);
  1275. te_convert_l1 :
  1276. inc(hp^.cl1_count);
  1277. te_convert_l2 :
  1278. inc(hp^.cl2_count);
  1279. te_convert_l3 :
  1280. inc(hp^.cl3_count);
  1281. te_convert_operator :
  1282. inc(hp^.coper_count);
  1283. te_incompatible :
  1284. hp^.invalid:=true;
  1285. else
  1286. internalerror(200212072);
  1287. end;
  1288. end;
  1289. { stop checking when an incompatible parameter is found }
  1290. if hp^.invalid then
  1291. begin
  1292. { store the current parameter info for
  1293. a nice error message when no procedure is found }
  1294. hp^.wrongpara:=currpara;
  1295. hp^.wrongparanr:=currparanr;
  1296. break;
  1297. end;
  1298. {$ifdef EXTDEBUG}
  1299. { store equal in node tree for dump }
  1300. currpara.eqval:=eq;
  1301. {$endif EXTDEBUG}
  1302. { next parameter in the call tree }
  1303. pt:=tcallparanode(pt.right);
  1304. { next parameter for definition, only goto next para
  1305. if we're out of the varargs }
  1306. if not(po_varargs in hp^.data.procoptions) or
  1307. (currparanr<=hp^.data.maxparacount) then
  1308. begin
  1309. { Ignore vs_hidden parameters }
  1310. repeat
  1311. currpara:=tparaitem(currpara.previous);
  1312. until (not assigned(currpara)) or (currpara.paratyp<>vs_hidden);
  1313. end;
  1314. dec(currparanr);
  1315. end;
  1316. if not(hp^.invalid) and
  1317. (assigned(pt) or assigned(currpara) or (currparanr<>0)) then
  1318. internalerror(200212141);
  1319. { next candidate }
  1320. hp:=hp^.next;
  1321. end;
  1322. end;
  1323. function Tcallnode.candidates_choose_best(procs:pcandidate;var bestpd:tprocdef):integer;
  1324. var
  1325. besthpstart,
  1326. hp : pcandidate;
  1327. cntpd,
  1328. res : integer;
  1329. begin
  1330. {
  1331. Returns the number of candidates left and the
  1332. first candidate is returned in pdbest
  1333. }
  1334. { Setup the first procdef as best, only count it as a result
  1335. when it is valid }
  1336. bestpd:=procs^.data;
  1337. if procs^.invalid then
  1338. cntpd:=0
  1339. else
  1340. cntpd:=1;
  1341. if assigned(procs^.next) then
  1342. begin
  1343. besthpstart:=procs;
  1344. hp:=procs^.next;
  1345. while assigned(hp) do
  1346. begin
  1347. res:=is_better_candidate(hp,besthpstart);
  1348. if (res>0) then
  1349. begin
  1350. { hp is better, flag all procs to be incompatible }
  1351. while (besthpstart<>hp) do
  1352. begin
  1353. besthpstart^.invalid:=true;
  1354. besthpstart:=besthpstart^.next;
  1355. end;
  1356. { besthpstart is already set to hp }
  1357. bestpd:=besthpstart^.data;
  1358. cntpd:=1;
  1359. end
  1360. else
  1361. if (res<0) then
  1362. begin
  1363. { besthpstart is better, flag current hp to be incompatible }
  1364. hp^.invalid:=true;
  1365. end
  1366. else
  1367. begin
  1368. { res=0, both are valid }
  1369. if not hp^.invalid then
  1370. inc(cntpd);
  1371. end;
  1372. hp:=hp^.next;
  1373. end;
  1374. end;
  1375. candidates_choose_best:=cntpd;
  1376. end;
  1377. procedure tcallnode.candidates_find_wrong_para(procs:pcandidate);
  1378. var
  1379. currparanr : smallint;
  1380. hp : pcandidate;
  1381. pt : tcallparanode;
  1382. begin
  1383. { Only process the first overloaded procdef }
  1384. hp:=procs;
  1385. { Find callparanode corresponding to the argument }
  1386. pt:=tcallparanode(left);
  1387. currparanr:=paralength;
  1388. while assigned(pt) and
  1389. (currparanr>hp^.wrongparanr) do
  1390. begin
  1391. pt:=tcallparanode(pt.right);
  1392. dec(currparanr);
  1393. end;
  1394. if (currparanr<>hp^.wrongparanr) or
  1395. not assigned(pt) then
  1396. internalerror(200212094);
  1397. { Show error message, when it was a var or out parameter
  1398. guess that it is a missing typeconv }
  1399. if hp^.wrongpara.paratyp in [vs_var,vs_out] then
  1400. CGMessagePos2(left.fileinfo,parser_e_call_by_ref_without_typeconv,
  1401. pt.resulttype.def.typename,hp^.wrongpara.paratype.def.typename)
  1402. else
  1403. CGMessagePos3(pt.fileinfo,type_e_wrong_parameter_type,
  1404. tostr(hp^.wrongparanr),pt.resulttype.def.typename,hp^.wrongpara.paratype.def.typename);
  1405. end;
  1406. procedure tcallnode.bind_paraitem;
  1407. var
  1408. i : integer;
  1409. pt : tcallparanode;
  1410. oldppt : ^tcallparanode;
  1411. currpara : tparaitem;
  1412. hiddentree : tnode;
  1413. begin
  1414. pt:=tcallparanode(left);
  1415. oldppt:=@left;
  1416. { flag all callparanodes that belong to the varargs }
  1417. if (po_varargs in procdefinition.procoptions) then
  1418. begin
  1419. i:=paralength;
  1420. while (i>procdefinition.maxparacount) do
  1421. begin
  1422. include(tcallparanode(pt).flags,nf_varargs_para);
  1423. oldppt:[email protected];
  1424. pt:=tcallparanode(pt.right);
  1425. dec(i);
  1426. end;
  1427. end;
  1428. { insert hidden parameters }
  1429. currpara:=tparaitem(procdefinition.Para.last);
  1430. while assigned(currpara) do
  1431. begin
  1432. if not assigned(pt) then
  1433. internalerror(200304082);
  1434. if (currpara.paratyp=vs_hidden) then
  1435. begin
  1436. hiddentree:=nil;
  1437. if assigned(currpara.previous) and
  1438. paramanager.push_high_param(tparaitem(currpara.previous).paratype.def,procdefinition.proccalloption) then
  1439. // if vo_is_high_value in tvarsym(currpara.parasym).varoptions then
  1440. begin
  1441. { we need the information of the next parameter }
  1442. hiddentree:=gen_high_tree(pt.left,is_open_string(tparaitem(currpara.previous).paratype.def));
  1443. end;
  1444. { add a callparanode for the hidden parameter and
  1445. let the previous node point to this new node }
  1446. if not assigned(hiddentree) then
  1447. internalerror(200304073);
  1448. pt:=ccallparanode.create(hiddentree,oldppt^);
  1449. oldppt^:=pt;
  1450. end;
  1451. { Bind paraitem to this node }
  1452. pt.paraitem:=currpara;
  1453. { Next node and paraitem }
  1454. oldppt:[email protected];
  1455. pt:=tcallparanode(pt.right);
  1456. currpara:=tparaitem(currpara.previous);
  1457. end;
  1458. end;
  1459. function tcallnode.det_resulttype:tnode;
  1460. var
  1461. procs : pcandidate;
  1462. oldcallprocdef : tabstractprocdef;
  1463. hpt : tnode;
  1464. pt : tcallparanode;
  1465. lastpara : longint;
  1466. currpara : tparaitem;
  1467. cand_cnt : integer;
  1468. i : longint;
  1469. method_must_be_valid,
  1470. is_const : boolean;
  1471. label
  1472. errorexit;
  1473. begin
  1474. result:=nil;
  1475. procs:=nil;
  1476. oldcallprocdef:=aktcallprocdef;
  1477. aktcallprocdef:=nil;
  1478. { determine length of parameter list }
  1479. pt:=tcallparanode(left);
  1480. paralength:=0;
  1481. while assigned(pt) do
  1482. begin
  1483. inc(paralength);
  1484. pt:=tcallparanode(pt.right);
  1485. end;
  1486. { determine the type of the parameters }
  1487. if assigned(left) then
  1488. begin
  1489. tcallparanode(left).get_paratype;
  1490. if codegenerror then
  1491. goto errorexit;
  1492. end;
  1493. { procedure variable ? }
  1494. if assigned(right) then
  1495. begin
  1496. set_varstate(right,true);
  1497. resulttypepass(right);
  1498. if codegenerror then
  1499. exit;
  1500. procdefinition:=tabstractprocdef(right.resulttype.def);
  1501. { Compare parameters from right to left }
  1502. currpara:=tparaitem(procdefinition.Para.last);
  1503. while assigned(currpara) and (currpara.paratyp=vs_hidden) do
  1504. currpara:=tparaitem(currpara.previous);
  1505. pt:=tcallparanode(left);
  1506. lastpara:=paralength;
  1507. while assigned(currpara) and assigned(pt) do
  1508. begin
  1509. { only goto next para if we're out of the varargs }
  1510. if not(po_varargs in procdefinition.procoptions) or
  1511. (lastpara<=procdefinition.maxparacount) then
  1512. begin
  1513. repeat
  1514. currpara:=tparaitem(currpara.previous);
  1515. until (not assigned(currpara)) or (currpara.paratyp<>vs_hidden);
  1516. end;
  1517. pt:=tcallparanode(pt.right);
  1518. dec(lastpara);
  1519. end;
  1520. if assigned(pt) or assigned(currpara) then
  1521. begin
  1522. if assigned(pt) then
  1523. aktfilepos:=pt.fileinfo;
  1524. CGMessage(parser_e_wrong_parameter_size);
  1525. goto errorexit;
  1526. end;
  1527. end
  1528. else
  1529. { not a procedure variable }
  1530. begin
  1531. { do we know the procedure to call ? }
  1532. if not(assigned(procdefinition)) then
  1533. begin
  1534. procs:=candidates_find;
  1535. { no procedures found? then there is something wrong
  1536. with the parameter size }
  1537. if not assigned(procs) then
  1538. begin
  1539. { when it's an auto inherited call and there
  1540. is no procedure found, but the procedures
  1541. were defined with overload directive and at
  1542. least two procedures are defined then we ignore
  1543. this inherited by inserting a nothingn. Only
  1544. do this ugly hack in Delphi mode as it looks more
  1545. like a bug. It's also not documented }
  1546. if (m_delphi in aktmodeswitches) and
  1547. (nf_anon_inherited in flags) and
  1548. (symtableprocentry.owner.symtabletype=objectsymtable) and
  1549. (po_overload in symtableprocentry.first_procdef.procoptions) and
  1550. (symtableprocentry.procdef_count>=2) then
  1551. result:=cnothingnode.create
  1552. else
  1553. begin
  1554. { in tp mode we can try to convert to procvar if
  1555. there are no parameters specified. Only try it
  1556. when there is only one proc definition, else the
  1557. loadnode will give a strange error }
  1558. if not(assigned(left)) and
  1559. (m_tp_procvar in aktmodeswitches) and
  1560. (symtableprocentry.procdef_count=1) then
  1561. begin
  1562. hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc);
  1563. if (symtableprocentry.owner.symtabletype=objectsymtable) then
  1564. begin
  1565. if assigned(methodpointer) then
  1566. tloadnode(hpt).set_mp(methodpointer.getcopy)
  1567. else
  1568. tloadnode(hpt).set_mp(cselfnode.create(tobjectdef(symtableprocentry.owner.defowner)));
  1569. end;
  1570. resulttypepass(hpt);
  1571. result:=hpt;
  1572. end
  1573. else
  1574. begin
  1575. if assigned(left) then
  1576. aktfilepos:=left.fileinfo;
  1577. CGMessage(parser_e_wrong_parameter_size);
  1578. symtableprocentry.write_parameter_lists(nil);
  1579. end;
  1580. end;
  1581. goto errorexit;
  1582. end;
  1583. { Retrieve information about the candidates }
  1584. candidates_get_information(procs);
  1585. {$ifdef EXTDEBUG}
  1586. { Display info when multiple candidates are found }
  1587. if assigned(procs^.next) then
  1588. candidates_dump_info(V_Debug,procs);
  1589. {$endif EXTDEBUG}
  1590. { Choose the best candidate and count the number of
  1591. candidates left }
  1592. cand_cnt:=candidates_choose_best(procs,tprocdef(procdefinition));
  1593. { All parameters are checked, check if there are any
  1594. procedures left }
  1595. if cand_cnt>0 then
  1596. begin
  1597. { Multiple candidates left? }
  1598. if cand_cnt>1 then
  1599. begin
  1600. CGMessage(cg_e_cant_choose_overload_function);
  1601. {$ifdef EXTDEBUG}
  1602. candidates_dump_info(V_Hint,procs);
  1603. {$else}
  1604. candidates_list(procs,false);
  1605. {$endif EXTDEBUG}
  1606. { we'll just use the first candidate to make the
  1607. call }
  1608. end;
  1609. { assign procdefinition }
  1610. if symtableproc=nil then
  1611. symtableproc:=procdefinition.owner;
  1612. { update browser information }
  1613. if make_ref then
  1614. begin
  1615. tprocdef(procdefinition).lastref:=tref.create(tprocdef(procdefinition).lastref,@fileinfo);
  1616. inc(tprocdef(procdefinition).refcount);
  1617. if tprocdef(procdefinition).defref=nil then
  1618. tprocdef(procdefinition).defref:=tprocdef(procdefinition).lastref;
  1619. end;
  1620. end
  1621. else
  1622. begin
  1623. { No candidates left, this must be a type error,
  1624. because wrong size is already checked. procdefinition
  1625. is filled with the first (random) definition that is
  1626. found. We use this definition to display a nice error
  1627. message that the wrong type is passed }
  1628. candidates_find_wrong_para(procs);
  1629. candidates_list(procs,true);
  1630. {$ifdef EXTDEBUG}
  1631. candidates_dump_info(V_Hint,procs);
  1632. {$endif EXTDEBUG}
  1633. { We can not proceed, release all procs and exit }
  1634. candidates_free(procs);
  1635. goto errorexit;
  1636. end;
  1637. candidates_free(procs);
  1638. end; { end of procedure to call determination }
  1639. { add needed default parameters }
  1640. if assigned(procdefinition) and
  1641. (paralength<procdefinition.maxparacount) then
  1642. begin
  1643. currpara:=tparaitem(procdefinition.Para.first);
  1644. for i:=1 to paralength do
  1645. currpara:=tparaitem(currpara.next);
  1646. while assigned(currpara) do
  1647. begin
  1648. if not assigned(currpara.defaultvalue) then
  1649. internalerror(200212142);
  1650. left:=ccallparanode.create(genconstsymtree(tconstsym(currpara.defaultvalue)),left);
  1651. currpara:=tparaitem(currpara.next);
  1652. end;
  1653. end;
  1654. end;
  1655. { handle predefined procedures }
  1656. is_const:=(po_internconst in procdefinition.procoptions) and
  1657. ((block_type in [bt_const,bt_type]) or
  1658. (assigned(left) and (tcallparanode(left).left.nodetype in [realconstn,ordconstn])));
  1659. if (procdefinition.proccalloption=pocall_internproc) or is_const then
  1660. begin
  1661. if assigned(left) then
  1662. begin
  1663. { ptr and settextbuf needs two args }
  1664. if assigned(tcallparanode(left).right) then
  1665. begin
  1666. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,left);
  1667. left:=nil;
  1668. end
  1669. else
  1670. begin
  1671. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,tcallparanode(left).left);
  1672. tcallparanode(left).left:=nil;
  1673. end;
  1674. end
  1675. else
  1676. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,nil);
  1677. result:=hpt;
  1678. goto errorexit;
  1679. end;
  1680. { ensure that the result type is set }
  1681. if not restypeset then
  1682. resulttype:=procdefinition.rettype
  1683. else
  1684. resulttype:=restype;
  1685. { modify the exit code, in case of special cases }
  1686. if (not is_void(resulttype.def)) then
  1687. begin
  1688. if paramanager.ret_in_reg(resulttype.def,procdefinition.proccalloption) then
  1689. begin
  1690. { wide- and ansistrings are returned in EAX }
  1691. { but they are imm. moved to a memory location }
  1692. if is_widestring(resulttype.def) or
  1693. is_ansistring(resulttype.def) then
  1694. begin
  1695. { we use ansistrings so no fast exit here }
  1696. if assigned(procinfo) then
  1697. procinfo.no_fast_exit:=true;
  1698. end;
  1699. end;
  1700. end;
  1701. { constructors return their current class type, not the type where the
  1702. constructor is declared, this can be different because of inheritance }
  1703. if (procdefinition.proctypeoption=potype_constructor) then
  1704. begin
  1705. if assigned(methodpointer) and
  1706. assigned(methodpointer.resulttype.def) and
  1707. (methodpointer.resulttype.def.deftype=classrefdef) then
  1708. resulttype:=tclassrefdef(methodpointer.resulttype.def).pointertype;
  1709. end;
  1710. if assigned(methodpointer) then
  1711. begin
  1712. resulttypepass(methodpointer);
  1713. if not(methodpointer.nodetype in [typen,hnewn]) then
  1714. begin
  1715. hpt:=methodpointer;
  1716. while assigned(hpt) and (hpt.nodetype in [subscriptn,vecn]) do
  1717. hpt:=tunarynode(hpt).left;
  1718. if (procdefinition.proctypeoption in [potype_constructor,potype_destructor]) then
  1719. begin
  1720. { if an inherited con- or destructor should be }
  1721. { called in a con- or destructor then a warning }
  1722. { will be made }
  1723. { con- and destructors need a pointer to the vmt }
  1724. if is_object(methodpointer.resulttype.def) and
  1725. not(aktprocdef.proctypeoption in
  1726. [potype_constructor,potype_destructor]) then
  1727. CGMessage(cg_w_member_cd_call_from_method);
  1728. if assigned(symtableproc) and
  1729. (symtableproc.symtabletype=withsymtable) and
  1730. (not twithsymtable(symtableproc).direct_with) then
  1731. begin
  1732. CGmessage(cg_e_cannot_call_cons_dest_inside_with);
  1733. end; { Is accepted by Delphi !! }
  1734. end;
  1735. { R.Init then R will be initialized by the constructor,
  1736. Also allow it for simple loads }
  1737. if (procdefinition.proctypeoption=potype_constructor) or
  1738. ((hpt.nodetype=loadn) and
  1739. (
  1740. (methodpointer.resulttype.def.deftype=classrefdef) or
  1741. (
  1742. (methodpointer.resulttype.def.deftype=objectdef) and
  1743. not(oo_has_virtual in tobjectdef(methodpointer.resulttype.def).objectoptions)
  1744. )
  1745. )
  1746. ) then
  1747. method_must_be_valid:=false
  1748. else
  1749. method_must_be_valid:=true;
  1750. set_varstate(methodpointer,method_must_be_valid);
  1751. { The object is already used if it is called once }
  1752. if (hpt.nodetype=loadn) and
  1753. (tloadnode(hpt).symtableentry.typ=varsym) then
  1754. tvarsym(tloadnode(hpt).symtableentry).varstate:=vs_used;
  1755. end;
  1756. end;
  1757. { bind paraitems to the callparanodes and insert hidden parameters }
  1758. aktcallprocdef:=procdefinition;
  1759. bind_paraitem;
  1760. { insert type conversions for parameters }
  1761. if assigned(left) then
  1762. tcallparanode(left).insert_typeconv(true);
  1763. { direct call to inherited abstract method, then we
  1764. can already give a error in the compiler instead
  1765. of a runtime error }
  1766. if assigned(methodpointer) and
  1767. (methodpointer.nodetype=typen) and
  1768. (po_abstractmethod in procdefinition.procoptions) then
  1769. CGMessage(cg_e_cant_call_abstract_method);
  1770. errorexit:
  1771. aktcallprocdef:=oldcallprocdef;
  1772. end;
  1773. function tcallnode.pass_1 : tnode;
  1774. var
  1775. inlinecode : tnode;
  1776. inlined : boolean;
  1777. {$ifdef m68k}
  1778. regi : tregister;
  1779. {$endif}
  1780. label
  1781. errorexit;
  1782. begin
  1783. result:=nil;
  1784. inlined:=false;
  1785. inlinecode := nil;
  1786. { work trough all parameters to get the register requirements }
  1787. if assigned(left) then
  1788. tcallparanode(left).det_registers;
  1789. { return node }
  1790. if assigned(funcretrefnode) then
  1791. firstpass(funcretrefnode);
  1792. if assigned(procdefinition) and
  1793. (procdefinition.proccalloption=pocall_inline) then
  1794. begin
  1795. inlinecode:=right;
  1796. if assigned(inlinecode) then
  1797. inlined:=true;
  1798. right:=nil;
  1799. end;
  1800. { procedure variable ? }
  1801. if assigned(right) then
  1802. begin
  1803. firstpass(right);
  1804. { procedure does a call }
  1805. if not (block_type in [bt_const,bt_type]) then
  1806. procinfo.flags:=procinfo.flags or pi_do_call;
  1807. rg.incrementintregisterpushed(all_intregisters);
  1808. rg.incrementotherregisterpushed(all_registers);
  1809. end
  1810. else
  1811. { not a procedure variable }
  1812. begin
  1813. { calc the correture value for the register }
  1814. { handle predefined procedures }
  1815. if (procdefinition.proccalloption=pocall_inline) then
  1816. begin
  1817. if assigned(methodpointer) then
  1818. CGMessage(cg_e_unable_inline_object_methods);
  1819. if assigned(right) and (right.nodetype<>procinlinen) then
  1820. CGMessage(cg_e_unable_inline_procvar);
  1821. if not assigned(inlinecode) then
  1822. begin
  1823. if assigned(tprocdef(procdefinition).code) then
  1824. inlinecode:=cprocinlinenode.create(tprocdef(procdefinition))
  1825. else
  1826. CGMessage(cg_e_no_code_for_inline_stored);
  1827. if assigned(inlinecode) then
  1828. begin
  1829. { consider it has not inlined if called
  1830. again inside the args }
  1831. procdefinition.proccalloption:=pocall_fpccall;
  1832. firstpass(inlinecode);
  1833. inlined:=true;
  1834. end;
  1835. end;
  1836. end
  1837. else
  1838. begin
  1839. if not (block_type in [bt_const,bt_type]) then
  1840. procinfo.flags:=procinfo.flags or pi_do_call;
  1841. end;
  1842. { It doesn't hurt to calculate it already though :) (JM) }
  1843. rg.incrementintregisterpushed(tprocdef(procdefinition).usedintregisters);
  1844. rg.incrementotherregisterpushed(tprocdef(procdefinition).usedotherregisters);
  1845. end;
  1846. { get a register for the return value }
  1847. if (not is_void(resulttype.def)) then
  1848. begin
  1849. { for win32 records returned in EDX:EAX, we
  1850. move them to memory after ... }
  1851. if (resulttype.def.deftype=recorddef) then
  1852. begin
  1853. expectloc:=LOC_CREFERENCE;
  1854. end
  1855. else
  1856. if paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption) then
  1857. begin
  1858. expectloc:=LOC_CREFERENCE;
  1859. end
  1860. else
  1861. { ansi/widestrings must be registered, so we can dispose them }
  1862. if is_ansistring(resulttype.def) or
  1863. is_widestring(resulttype.def) then
  1864. begin
  1865. expectloc:=LOC_CREFERENCE;
  1866. registers32:=1;
  1867. end
  1868. else
  1869. { we have only to handle the result if it is used }
  1870. if (nf_return_value_used in flags) then
  1871. begin
  1872. case resulttype.def.deftype of
  1873. enumdef,
  1874. orddef :
  1875. begin
  1876. if (procdefinition.proctypeoption=potype_constructor) then
  1877. begin
  1878. if assigned(methodpointer) and
  1879. (methodpointer.resulttype.def.deftype=classrefdef) then
  1880. begin
  1881. expectloc:=LOC_REGISTER;
  1882. registers32:=1;
  1883. end
  1884. else
  1885. expectloc:=LOC_FLAGS;
  1886. end
  1887. else
  1888. begin
  1889. expectloc:=LOC_REGISTER;
  1890. if is_64bitint(resulttype.def) then
  1891. registers32:=2
  1892. else
  1893. registers32:=1;
  1894. end;
  1895. end;
  1896. floatdef :
  1897. begin
  1898. expectloc:=LOC_FPUREGISTER;
  1899. {$ifdef cpufpemu}
  1900. if (cs_fp_emulation in aktmoduleswitches) then
  1901. registers32:=1
  1902. else
  1903. {$endif cpufpemu}
  1904. {$ifdef m68k}
  1905. if (tfloatdef(resulttype.def).typ=s32real) then
  1906. registers32:=1
  1907. else
  1908. {$endif m68k}
  1909. registersfpu:=1;
  1910. end;
  1911. else
  1912. begin
  1913. expectloc:=LOC_REGISTER;
  1914. registers32:=1;
  1915. end;
  1916. end;
  1917. end
  1918. else
  1919. expectloc:=LOC_VOID;
  1920. end
  1921. else
  1922. expectloc:=LOC_VOID;
  1923. {$ifdef m68k}
  1924. { we need one more address register for virtual calls on m68k }
  1925. if (po_virtualmethod in procdefinition.procoptions) then
  1926. inc(registers32);
  1927. {$endif m68k}
  1928. { a fpu can be used in any procedure !! }
  1929. {$ifdef i386}
  1930. registersfpu:=procdefinition.fpu_used;
  1931. {$endif i386}
  1932. { if this is a call to a method calc the registers }
  1933. if (methodpointer<>nil) then
  1934. begin
  1935. if methodpointer.nodetype<>typen then
  1936. firstpass(methodpointer);
  1937. { if we are calling the constructor }
  1938. if procdefinition.proctypeoption in [potype_constructor] then
  1939. verifyabstractcalls;
  1940. case methodpointer.nodetype of
  1941. { but only, if this is not a supporting node }
  1942. typen: ;
  1943. { we need one register for new return value PM }
  1944. hnewn : if registers32=0 then
  1945. registers32:=1;
  1946. else
  1947. begin
  1948. { this is not a good reason to accept it in FPC if we produce
  1949. wrong code for it !!! (PM) }
  1950. registersfpu:=max(methodpointer.registersfpu,registersfpu);
  1951. registers32:=max(methodpointer.registers32,registers32);
  1952. {$ifdef SUPPORT_MMX }
  1953. registersmmx:=max(methodpointer.registersmmx,registersmmx);
  1954. {$endif SUPPORT_MMX}
  1955. end;
  1956. end;
  1957. end;
  1958. if inlined then
  1959. right:=inlinecode;
  1960. { determine the registers of the procedure variable }
  1961. { is this OK for inlined procs also ?? (PM) }
  1962. if assigned(right) then
  1963. begin
  1964. registersfpu:=max(right.registersfpu,registersfpu);
  1965. registers32:=max(right.registers32,registers32);
  1966. {$ifdef SUPPORT_MMX}
  1967. registersmmx:=max(right.registersmmx,registersmmx);
  1968. {$endif SUPPORT_MMX}
  1969. end;
  1970. { determine the registers of the procedure }
  1971. if assigned(left) then
  1972. begin
  1973. registersfpu:=max(left.registersfpu,registersfpu);
  1974. registers32:=max(left.registers32,registers32);
  1975. {$ifdef SUPPORT_MMX}
  1976. registersmmx:=max(left.registersmmx,registersmmx);
  1977. {$endif SUPPORT_MMX}
  1978. end;
  1979. errorexit:
  1980. if inlined then
  1981. procdefinition.proccalloption:=pocall_inline;
  1982. end;
  1983. {$ifdef state_tracking}
  1984. function Tcallnode.track_state_pass(exec_known:boolean):boolean;
  1985. var hp:Tcallparanode;
  1986. value:Tnode;
  1987. begin
  1988. track_state_pass:=false;
  1989. hp:=Tcallparanode(left);
  1990. while assigned(hp) do
  1991. begin
  1992. if left.track_state_pass(exec_known) then
  1993. begin
  1994. left.resulttype.def:=nil;
  1995. do_resulttypepass(left);
  1996. end;
  1997. value:=aktstate.find_fact(hp.left);
  1998. if value<>nil then
  1999. begin
  2000. track_state_pass:=true;
  2001. hp.left.destroy;
  2002. hp.left:=value.getcopy;
  2003. do_resulttypepass(hp.left);
  2004. end;
  2005. hp:=Tcallparanode(hp.right);
  2006. end;
  2007. end;
  2008. {$endif}
  2009. function tcallnode.docompare(p: tnode): boolean;
  2010. begin
  2011. docompare :=
  2012. inherited docompare(p) and
  2013. (symtableprocentry = tcallnode(p).symtableprocentry) and
  2014. (procdefinition = tcallnode(p).procdefinition) and
  2015. (methodpointer.isequal(tcallnode(p).methodpointer)) and
  2016. ((restypeset and tcallnode(p).restypeset and
  2017. (equal_defs(restype.def,tcallnode(p).restype.def))) or
  2018. (not restypeset and not tcallnode(p).restypeset));
  2019. end;
  2020. {****************************************************************************
  2021. TPROCINLINENODE
  2022. ****************************************************************************}
  2023. constructor tprocinlinenode.create(p:tprocdef);
  2024. begin
  2025. inherited create(procinlinen);
  2026. inlineprocdef:=p;
  2027. retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
  2028. para_offset:=0;
  2029. para_size:=0;
  2030. { copy inlinetree }
  2031. if assigned(p.code) then
  2032. inlinetree:=p.code.getcopy
  2033. else
  2034. inlinetree:=nil;
  2035. end;
  2036. destructor tprocinlinenode.destroy;
  2037. begin
  2038. if assigned(inlinetree) then
  2039. inlinetree.free;
  2040. inherited destroy;
  2041. end;
  2042. constructor tprocinlinenode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
  2043. begin
  2044. inherited ppuload(t,ppufile);
  2045. inlineprocdef:=tprocdef(ppufile.getderef);
  2046. inlinetree:=ppuloadnode(ppufile);
  2047. retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
  2048. para_offset:=0;
  2049. para_size:=0;
  2050. end;
  2051. procedure tprocinlinenode.ppuwrite(ppufile:tcompilerppufile);
  2052. begin
  2053. inherited ppuwrite(ppufile);
  2054. ppufile.putderef(inlineprocdef);
  2055. ppuwritenode(ppufile,inlinetree);
  2056. end;
  2057. procedure tprocinlinenode.derefimpl;
  2058. begin
  2059. inherited derefimpl;
  2060. if assigned(inlinetree) then
  2061. inlinetree.derefimpl;
  2062. resolvedef(pointer(inlineprocdef));
  2063. end;
  2064. function tprocinlinenode.getcopy : tnode;
  2065. var
  2066. n : tprocinlinenode;
  2067. begin
  2068. n:=tprocinlinenode(inherited getcopy);
  2069. n.inlineprocdef:=inlineprocdef;
  2070. if assigned(inlinetree) then
  2071. n.inlinetree:=inlinetree.getcopy
  2072. else
  2073. n.inlinetree:=nil;
  2074. n.retoffset:=retoffset;
  2075. n.para_offset:=para_offset;
  2076. n.para_size:=para_size;
  2077. getcopy:=n;
  2078. end;
  2079. procedure tprocinlinenode.insertintolist(l : tnodelist);
  2080. begin
  2081. end;
  2082. function tprocinlinenode.det_resulttype : tnode;
  2083. var
  2084. storesymtablelevel : longint;
  2085. storeparasymtable,
  2086. storelocalsymtable : tsymtabletype;
  2087. oldprocdef : tprocdef;
  2088. oldprocinfo : tprocinfo;
  2089. oldinlining_procedure : boolean;
  2090. begin
  2091. result:=nil;
  2092. oldinlining_procedure:=inlining_procedure;
  2093. oldprocdef:=aktprocdef;
  2094. oldprocinfo:=procinfo;
  2095. { we're inlining a procedure }
  2096. inlining_procedure:=true;
  2097. aktprocdef:=inlineprocdef;
  2098. { clone procinfo, but not the asmlists }
  2099. procinfo:=tprocinfo(cprocinfo.newinstance);
  2100. move(pointer(oldprocinfo)^,pointer(procinfo)^,cprocinfo.InstanceSize);
  2101. procinfo.aktentrycode:=nil;
  2102. procinfo.aktexitcode:=nil;
  2103. procinfo.aktproccode:=nil;
  2104. procinfo.aktlocaldata:=nil;
  2105. { set new procinfo }
  2106. procinfo.return_offset:=retoffset;
  2107. procinfo.para_offset:=para_offset;
  2108. procinfo.no_fast_exit:=false;
  2109. { set it to the same lexical level }
  2110. storesymtablelevel:=aktprocdef.localst.symtablelevel;
  2111. storelocalsymtable:=aktprocdef.localst.symtabletype;
  2112. storeparasymtable:=aktprocdef.parast.symtabletype;
  2113. aktprocdef.localst.symtablelevel:=oldprocdef.localst.symtablelevel;
  2114. aktprocdef.localst.symtabletype:=inlinelocalsymtable;
  2115. aktprocdef.parast.symtabletype:=inlineparasymtable;
  2116. { pass inlinetree }
  2117. resulttypepass(inlinetree);
  2118. resulttype:=inlineprocdef.rettype;
  2119. { retrieve info from inlineprocdef }
  2120. retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
  2121. para_offset:=0;
  2122. para_size:=inlineprocdef.para_size(target_info.alignment.paraalign);
  2123. if paramanager.ret_in_param(inlineprocdef.rettype.def,inlineprocdef.proccalloption) then
  2124. inc(para_size,POINTER_SIZE);
  2125. { restore procinfo }
  2126. procinfo.free;
  2127. procinfo:=oldprocinfo;
  2128. { restore symtable }
  2129. aktprocdef.localst.symtablelevel:=storesymtablelevel;
  2130. aktprocdef.localst.symtabletype:=storelocalsymtable;
  2131. aktprocdef.parast.symtabletype:=storeparasymtable;
  2132. { restore }
  2133. aktprocdef:=oldprocdef;
  2134. inlining_procedure:=oldinlining_procedure;
  2135. end;
  2136. function tprocinlinenode.pass_1 : tnode;
  2137. begin
  2138. firstpass(inlinetree);
  2139. registers32:=inlinetree.registers32;
  2140. registersfpu:=inlinetree.registersfpu;
  2141. {$ifdef SUPPORT_MMX}
  2142. registersmmx:=inlinetree.registersmmx;
  2143. {$endif SUPPORT_MMX}
  2144. result:=nil;
  2145. end;
  2146. function tprocinlinenode.docompare(p: tnode): boolean;
  2147. begin
  2148. docompare :=
  2149. inherited docompare(p) and
  2150. inlinetree.isequal(tprocinlinenode(p).inlinetree) and
  2151. (inlineprocdef = tprocinlinenode(p).inlineprocdef);
  2152. end;
  2153. begin
  2154. ccallnode:=tcallnode;
  2155. ccallparanode:=tcallparanode;
  2156. cprocinlinenode:=tprocinlinenode;
  2157. end.
  2158. {
  2159. $Log$
  2160. Revision 1.139 2003-04-22 23:50:22 peter
  2161. * firstpass uses expectloc
  2162. * checks if there are differences between the expectloc and
  2163. location.loc from secondpass in EXTDEBUG
  2164. Revision 1.138 2003/04/22 09:53:33 peter
  2165. * fix insert_typeconv to handle new varargs which don't have a
  2166. paraitem set
  2167. Revision 1.137 2003/04/11 16:02:05 peter
  2168. * don't firstpass typen
  2169. Revision 1.136 2003/04/11 15:51:04 peter
  2170. * support subscript,vec for setting methodpointer varstate
  2171. Revision 1.135 2003/04/10 17:57:52 peter
  2172. * vs_hidden released
  2173. Revision 1.134 2003/04/07 11:58:22 jonas
  2174. * more vs_invisible fixes
  2175. Revision 1.133 2003/04/07 10:40:21 jonas
  2176. * fixed VS_HIDDEN for high parameter so it works again
  2177. Revision 1.132 2003/04/04 15:38:56 peter
  2178. * moved generic code from n386cal to ncgcal, i386 now also
  2179. uses the generic ncgcal
  2180. Revision 1.131 2003/03/17 18:54:23 peter
  2181. * fix missing self setting for method to procvar conversion in
  2182. tp_procvar mode
  2183. Revision 1.130 2003/03/17 16:54:41 peter
  2184. * support DefaultHandler and anonymous inheritance fixed
  2185. for message methods
  2186. Revision 1.129 2003/03/17 15:54:22 peter
  2187. * store symoptions also for procdef
  2188. * check symoptions (private,public) when calculating possible
  2189. overload candidates
  2190. Revision 1.128 2003/02/19 22:00:14 daniel
  2191. * Code generator converted to new register notation
  2192. - Horribily outdated todo.txt removed
  2193. Revision 1.127 2003/01/16 22:13:52 peter
  2194. * convert_l3 convertlevel added. This level is used for conversions
  2195. where information can be lost like converting widestring->ansistring
  2196. or dword->byte
  2197. Revision 1.126 2003/01/15 01:44:32 peter
  2198. * merged methodpointer fixes from 1.0.x
  2199. Revision 1.125 2003/01/12 17:52:07 peter
  2200. * only check for auto inherited in objectsymtable
  2201. Revision 1.124 2003/01/09 21:45:46 peter
  2202. * extended information about overloaded candidates when compiled
  2203. with EXTDEBUG
  2204. Revision 1.123 2002/12/26 18:24:33 jonas
  2205. * fixed check for whether or not a high parameter was already generated
  2206. * no type checking/conversions for invisible parameters
  2207. Revision 1.122 2002/12/15 22:50:00 florian
  2208. + some stuff for the new hidden parameter handling added
  2209. Revision 1.121 2002/12/15 21:34:15 peter
  2210. * give sign difference between ordinals a small penalty. This is
  2211. needed to get word->[longword|longint] working
  2212. Revision 1.120 2002/12/15 21:30:12 florian
  2213. * tcallnode.paraitem introduced, all references to defcoll removed
  2214. Revision 1.119 2002/12/15 20:59:58 peter
  2215. * fix crash with default parameters
  2216. Revision 1.118 2002/12/15 11:26:02 peter
  2217. * ignore vs_hidden parameters when choosing overloaded proc
  2218. Revision 1.117 2002/12/11 22:42:28 peter
  2219. * tcallnode.det_resulttype rewrite, merged code from nice_ncal and
  2220. the old code. The new code collects the information about possible
  2221. candidates only once resultting in much less calls to type compare
  2222. routines
  2223. Revision 1.116 2002/12/07 14:27:07 carl
  2224. * 3% memory optimization
  2225. * changed some types
  2226. + added type checking with different size for call node and for
  2227. parameters
  2228. Revision 1.115 2002/12/06 17:51:10 peter
  2229. * merged cdecl and array fixes
  2230. Revision 1.114 2002/12/06 16:56:58 peter
  2231. * only compile cs_fp_emulation support when cpufpuemu is defined
  2232. * define cpufpuemu for m68k only
  2233. Revision 1.113 2002/11/27 20:04:38 peter
  2234. * cdecl array of const fixes
  2235. Revision 1.112 2002/11/27 15:33:46 peter
  2236. * the never ending story of tp procvar hacks
  2237. Revision 1.111 2002/11/27 02:31:17 peter
  2238. * fixed inlinetree parsing in det_resulttype
  2239. Revision 1.110 2002/11/25 18:43:32 carl
  2240. - removed the invalid if <> checking (Delphi is strange on this)
  2241. + implemented abstract warning on instance creation of class with
  2242. abstract methods.
  2243. * some error message cleanups
  2244. Revision 1.109 2002/11/25 17:43:17 peter
  2245. * splitted defbase in defutil,symutil,defcmp
  2246. * merged isconvertable and is_equal into compare_defs(_ext)
  2247. * made operator search faster by walking the list only once
  2248. Revision 1.108 2002/11/18 17:31:54 peter
  2249. * pass proccalloption to ret_in_xxx and push_xxx functions
  2250. Revision 1.107 2002/11/15 01:58:50 peter
  2251. * merged changes from 1.0.7 up to 04-11
  2252. - -V option for generating bug report tracing
  2253. - more tracing for option parsing
  2254. - errors for cdecl and high()
  2255. - win32 import stabs
  2256. - win32 records<=8 are returned in eax:edx (turned off by default)
  2257. - heaptrc update
  2258. - more info for temp management in .s file with EXTDEBUG
  2259. Revision 1.106 2002/10/14 18:20:30 carl
  2260. * var parameter checking for classes and interfaces in Delphi mode
  2261. Revision 1.105 2002/10/06 21:02:17 peter
  2262. * fixed limit checking for qword
  2263. Revision 1.104 2002/10/05 15:15:45 peter
  2264. * Write unknwon compiler proc using Comment and only in Extdebug
  2265. Revision 1.103 2002/10/05 12:43:25 carl
  2266. * fixes for Delphi 6 compilation
  2267. (warning : Some features do not work under Delphi)
  2268. Revision 1.102 2002/10/05 00:48:57 peter
  2269. * support inherited; support for overload as it is handled by
  2270. delphi. This is only for delphi mode as it is working is
  2271. undocumented and hard to predict what is done
  2272. Revision 1.101 2002/09/16 14:11:12 peter
  2273. * add argument to equal_paras() to support default values or not
  2274. Revision 1.100 2002/09/15 17:49:59 peter
  2275. * don't have strict var parameter checking for procedures in the
  2276. system unit
  2277. Revision 1.99 2002/09/09 19:30:34 peter
  2278. * don't allow convertable parameters for var and out parameters in
  2279. delphi and tp mode
  2280. Revision 1.98 2002/09/07 15:25:02 peter
  2281. * old logs removed and tabs fixed
  2282. Revision 1.97 2002/09/07 12:16:05 carl
  2283. * second part bug report 1996 fix, testrange in cordconstnode
  2284. only called if option is set (also make parsing a tiny faster)
  2285. Revision 1.96 2002/09/05 14:53:41 peter
  2286. * fixed old callnode.det_resulttype code
  2287. * old ncal code is default again
  2288. Revision 1.95 2002/09/03 21:32:49 daniel
  2289. * Small bugfix for procdef selection
  2290. Revision 1.94 2002/09/03 19:27:22 daniel
  2291. * Activated new ncal code
  2292. Revision 1.93 2002/09/03 16:26:26 daniel
  2293. * Make Tprocdef.defs protected
  2294. Revision 1.92 2002/09/01 13:28:37 daniel
  2295. - write_access fields removed in favor of a flag
  2296. Revision 1.91 2002/09/01 12:14:15 peter
  2297. * remove debug line
  2298. * containself methods can be called directly
  2299. Revision 1.90 2002/09/01 08:01:16 daniel
  2300. * Removed sets from Tcallnode.det_resulttype
  2301. + Added read/write notifications of variables. These will be usefull
  2302. for providing information for several optimizations. For example
  2303. the value of the loop variable of a for loop does matter is the
  2304. variable is read after the for loop, but if it's no longer used
  2305. or written, it doesn't matter and this can be used to optimize
  2306. the loop code generation.
  2307. Revision 1.89 2002/08/23 16:13:16 peter
  2308. * also firstpass funcretrefnode if available. This was breaking the
  2309. asnode compilerproc code
  2310. Revision 1.88 2002/08/20 10:31:26 daniel
  2311. * Tcallnode.det_resulttype rewritten
  2312. Revision 1.87 2002/08/19 19:36:42 peter
  2313. * More fixes for cross unit inlining, all tnodes are now implemented
  2314. * Moved pocall_internconst to po_internconst because it is not a
  2315. calling type at all and it conflicted when inlining of these small
  2316. functions was requested
  2317. Revision 1.86 2002/08/17 22:09:44 florian
  2318. * result type handling in tcgcal.pass_2 overhauled
  2319. * better tnode.dowrite
  2320. * some ppc stuff fixed
  2321. Revision 1.85 2002/08/17 09:23:34 florian
  2322. * first part of procinfo rewrite
  2323. Revision 1.84 2002/08/16 14:24:57 carl
  2324. * issameref() to test if two references are the same (then emit no opcodes)
  2325. + ret_in_reg to replace ret_in_acc
  2326. (fix some register allocation bugs at the same time)
  2327. + save_std_register now has an extra parameter which is the
  2328. usedinproc registers
  2329. Revision 1.83 2002/07/20 11:57:53 florian
  2330. * types.pas renamed to defbase.pas because D6 contains a types
  2331. unit so this would conflicts if D6 programms are compiled
  2332. + Willamette/SSE2 instructions to assembler added
  2333. Revision 1.82 2002/07/19 11:41:35 daniel
  2334. * State tracker work
  2335. * The whilen and repeatn are now completely unified into whilerepeatn. This
  2336. allows the state tracker to change while nodes automatically into
  2337. repeat nodes.
  2338. * Resulttypepass improvements to the notn. 'not not a' is optimized away and
  2339. 'not(a>b)' is optimized into 'a<=b'.
  2340. * Resulttypepass improvements to the whilerepeatn. 'while not a' is optimized
  2341. by removing the notn and later switchting the true and falselabels. The
  2342. same is done with 'repeat until not a'.
  2343. Revision 1.81 2002/07/15 18:03:14 florian
  2344. * readded removed changes
  2345. Revision 1.79 2002/07/11 14:41:27 florian
  2346. * start of the new generic parameter handling
  2347. Revision 1.80 2002/07/14 18:00:43 daniel
  2348. + Added the beginning of a state tracker. This will track the values of
  2349. variables through procedures and optimize things away.
  2350. Revision 1.78 2002/07/04 20:43:00 florian
  2351. * first x86-64 patches
  2352. }