ncal.pas 111 KB

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