ncal.pas 111 KB

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