ncal.pas 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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 defines.inc}
  20. interface
  21. uses
  22. node,symtable;
  23. type
  24. tcallnode = class(tbinarynode)
  25. { the symbol containing the definition of the procedure }
  26. { to call }
  27. symtableprocentry : pprocsym;
  28. { the symtable containing symtableprocentry }
  29. symtableproc : psymtable;
  30. { the definition of the procedure to call }
  31. procdefinition : pabstractprocdef;
  32. methodpointer : tnode;
  33. { only the processor specific nodes need to override this }
  34. { constructor }
  35. constructor create(v : pprocsym;st : psymtable; mp : tnode);virtual;
  36. destructor destroy;override;
  37. function getcopy : tnode;override;
  38. procedure insertintolist(l : tnodelist);override;
  39. function pass_1 : tnode;override;
  40. end;
  41. tcallparaflags = (
  42. { flags used by tcallparanode }
  43. cpf_exact_match_found,
  44. cpf_convlevel1found,
  45. cpf_convlevel2found,
  46. cpf_is_colon_para
  47. );
  48. tcallparanode = class(tbinarynode)
  49. callparaflags : set of tcallparaflags;
  50. hightree : tnode;
  51. { only the processor specific nodes need to override this }
  52. { constructor }
  53. constructor create(expr,next : tnode);virtual;
  54. destructor destroy;override;
  55. function getcopy : tnode;override;
  56. procedure insertintolist(l : tnodelist);override;
  57. procedure gen_high_tree(openstring:boolean);
  58. { tcallparanode doesn't use pass_1 }
  59. { tcallnode takes care of this }
  60. procedure firstcallparan(defcoll : pparaitem;do_count : boolean);virtual;
  61. procedure secondcallparan(defcoll : pparaitem;
  62. push_from_left_to_right,inlined,is_cdecl : boolean;
  63. para_alignment,para_offset : longint);virtual;abstract;
  64. end;
  65. tprocinlinenode = class(tnode)
  66. inlinetree : tnode;
  67. inlineprocsym : pprocsym;
  68. retoffset,para_offset,para_size : longint;
  69. constructor create(callp,code : tnode);virtual;
  70. destructor destroy;override;
  71. function getcopy : tnode;override;
  72. procedure insertintolist(l : tnodelist);override;
  73. function pass_1 : tnode;override;
  74. end;
  75. function gencallparanode(expr,next : tnode) : tnode;
  76. function gencallnode(v : pprocsym;st : psymtable) : tnode;
  77. { uses the callnode to create the new procinline node }
  78. function genprocinlinenode(callp,code : tnode) : tnode;
  79. var
  80. ccallnode : class of tcallnode;
  81. ccallparanode : class of tcallparanode;
  82. cprocinlinenode : class of tprocinlinenode;
  83. implementation
  84. uses
  85. cutils,globtype,systems,
  86. cobjects,verbose,globals,
  87. symconst,aasm,types,
  88. htypechk,pass_1,cpubase,
  89. ncnv,nld,ninl,nadd,ncon
  90. {$ifdef newcg}
  91. ,cgbase
  92. ,tgobj
  93. {$else newcg}
  94. ,hcodegen
  95. {$ifdef i386}
  96. ,tgeni386
  97. {$endif}
  98. {$ifdef m68k}
  99. ,tgen68k
  100. {$endif m68k}
  101. {$endif newcg}
  102. ;
  103. function gencallnode(v : pprocsym;st : psymtable) : tnode;
  104. begin
  105. gencallnode:=ccallnode.create(v,st,nil);
  106. end;
  107. function gencallparanode(expr,next : tnode) : tnode;
  108. begin
  109. gencallparanode:=ccallparanode.create(expr,next);
  110. end;
  111. function genprocinlinenode(callp,code : tnode) : tnode;
  112. var
  113. p : tnode;
  114. begin
  115. p:=cprocinlinenode.create(callp,code);
  116. genprocinlinenode:=p;
  117. end;
  118. {****************************************************************************
  119. TCALLPARANODE
  120. ****************************************************************************}
  121. constructor tcallparanode.create(expr,next : tnode);
  122. begin
  123. inherited create(callparan,expr,next);
  124. hightree:=nil;
  125. if assigned(expr) then
  126. expr.set_file_line(self);
  127. callparaflags:=[];
  128. end;
  129. destructor tcallparanode.destroy;
  130. begin
  131. hightree.free;
  132. inherited destroy;
  133. end;
  134. function tcallparanode.getcopy : tnode;
  135. var
  136. n : tcallparanode;
  137. begin
  138. n:=tcallparanode(inherited getcopy);
  139. n.callparaflags:=callparaflags;
  140. if assigned(hightree) then
  141. n.hightree:=hightree.getcopy
  142. else
  143. n.hightree:=nil;
  144. result:=n;
  145. end;
  146. procedure tcallparanode.insertintolist(l : tnodelist);
  147. begin
  148. end;
  149. procedure tcallparanode.firstcallparan(defcoll : pparaitem;do_count : boolean);
  150. var
  151. old_get_para_resulttype : boolean;
  152. old_array_constructor : boolean;
  153. oldtype : pdef;
  154. {$ifdef extdebug}
  155. store_count_ref : boolean;
  156. {$endif def extdebug}
  157. {convtyp : tconverttype;}
  158. begin
  159. inc(parsing_para_level);
  160. {$ifdef extdebug}
  161. if do_count then
  162. begin
  163. store_count_ref:=count_ref;
  164. count_ref:=true;
  165. end;
  166. {$endif def extdebug}
  167. if assigned(right) then
  168. begin
  169. if defcoll=nil then
  170. tcallparanode(right).firstcallparan(nil,do_count)
  171. else
  172. tcallparanode(right).firstcallparan(pparaitem(defcoll^.next),do_count);
  173. registers32:=right.registers32;
  174. registersfpu:=right.registersfpu;
  175. {$ifdef SUPPORT_MMX}
  176. registersmmx:=right.registersmmx;
  177. {$endif}
  178. end;
  179. if defcoll=nil then
  180. begin
  181. old_array_constructor:=allow_array_constructor;
  182. old_get_para_resulttype:=get_para_resulttype;
  183. get_para_resulttype:=true;
  184. allow_array_constructor:=true;
  185. firstpass(left);
  186. get_para_resulttype:=old_get_para_resulttype;
  187. allow_array_constructor:=old_array_constructor;
  188. if codegenerror then
  189. begin
  190. dec(parsing_para_level);
  191. exit;
  192. end;
  193. resulttype:=left.resulttype;
  194. end
  195. { if we know the routine which is called, then the type }
  196. { conversions are inserted }
  197. else
  198. begin
  199. { Do we need arrayconstructor -> set conversion, then insert
  200. it here before the arrayconstructor node breaks the tree
  201. with its conversions of enum->ord }
  202. if (left.nodetype=arrayconstructorn) and
  203. (defcoll^.paratype.def^.deftype=setdef) then
  204. left:=gentypeconvnode(left,defcoll^.paratype.def);
  205. { set some settings needed for arrayconstructor }
  206. if is_array_constructor(left.resulttype) then
  207. begin
  208. if is_array_of_const(defcoll^.paratype.def) then
  209. begin
  210. if assigned(aktcallprocsym) and
  211. (([pocall_cppdecl,pocall_cdecl]*aktcallprocsym^.definition^.proccalloptions)<>[]) and
  212. (po_external in aktcallprocsym^.definition^.procoptions) then
  213. include(left.flags,nf_cargs);
  214. { force variant array }
  215. include(left.flags,nf_forcevaria);
  216. end
  217. else
  218. begin
  219. include(left.flags,nf_novariaallowed);
  220. tarrayconstructornode(left).constructordef:=parraydef(defcoll^.paratype.def)^.elementtype.def;
  221. end;
  222. end;
  223. if do_count then
  224. begin
  225. { not completly proper, but avoids some warnings }
  226. if (defcoll^.paratyp=vs_var) then
  227. set_funcret_is_valid(left);
  228. { protected has nothing to do with read/write
  229. if (defcoll^.paratyp=vs_var) then
  230. test_protected(left);
  231. }
  232. { set_varstate(left,defcoll^.paratyp<>vs_var);
  233. must only be done after typeconv PM }
  234. { only process typeconvn and arrayconstructn, else it will
  235. break other trees }
  236. { But this is need to get correct varstate !! PM }
  237. old_array_constructor:=allow_array_constructor;
  238. old_get_para_resulttype:=get_para_resulttype;
  239. allow_array_constructor:=true;
  240. get_para_resulttype:=false;
  241. if (left.nodetype in [arrayconstructorn,typeconvn]) then
  242. firstpass(left);
  243. if not assigned(resulttype) then
  244. resulttype:=left.resulttype;
  245. get_para_resulttype:=old_get_para_resulttype;
  246. allow_array_constructor:=old_array_constructor;
  247. end;
  248. { check if local proc/func is assigned to procvar }
  249. if left.resulttype^.deftype=procvardef then
  250. test_local_to_procvar(pprocvardef(left.resulttype),defcoll^.paratype.def);
  251. { property is not allowed as var parameter }
  252. if (defcoll^.paratyp in [vs_out,vs_var]) and
  253. (nf_isproperty in left.flags) then
  254. CGMessagePos(left.fileinfo,type_e_argument_cant_be_assigned);
  255. { generate the high() value tree }
  256. if push_high_param(defcoll^.paratype.def) then
  257. gen_high_tree(is_open_string(defcoll^.paratype.def));
  258. if not(is_shortstring(left.resulttype) and
  259. is_shortstring(defcoll^.paratype.def)) and
  260. (defcoll^.paratype.def^.deftype<>formaldef) then
  261. begin
  262. if (defcoll^.paratyp in [vs_var,vs_out]) and
  263. { allows conversion from word to integer and
  264. byte to shortint }
  265. (not(
  266. (left.resulttype^.deftype=orddef) and
  267. (defcoll^.paratype.def^.deftype=orddef) and
  268. (left.resulttype^.size=defcoll^.paratype.def^.size)
  269. ) and
  270. { an implicit pointer conversion is allowed }
  271. not(
  272. (left.resulttype^.deftype=pointerdef) and
  273. (defcoll^.paratype.def^.deftype=pointerdef)
  274. ) and
  275. { child classes can be also passed }
  276. not(
  277. (left.resulttype^.deftype=objectdef) and
  278. (defcoll^.paratype.def^.deftype=objectdef) and
  279. pobjectdef(left.resulttype)^.is_related(pobjectdef(defcoll^.paratype.def))
  280. ) and
  281. { passing a single element to a openarray of the same type }
  282. not(
  283. (is_open_array(defcoll^.paratype.def) and
  284. is_equal(parraydef(defcoll^.paratype.def)^.elementtype.def,left.resulttype))
  285. ) and
  286. { an implicit file conversion is also allowed }
  287. { from a typed file to an untyped one }
  288. not(
  289. (left.resulttype^.deftype=filedef) and
  290. (defcoll^.paratype.def^.deftype=filedef) and
  291. (pfiledef(defcoll^.paratype.def)^.filetyp = ft_untyped) and
  292. (pfiledef(left.resulttype)^.filetyp = ft_typed)
  293. ) and
  294. not(is_equal(left.resulttype,defcoll^.paratype.def))) then
  295. begin
  296. CGMessagePos2(left.fileinfo,parser_e_call_by_ref_without_typeconv,
  297. left.resulttype^.typename,defcoll^.paratype.def^.typename);
  298. end;
  299. { Process open parameters }
  300. if push_high_param(defcoll^.paratype.def) then
  301. begin
  302. { insert type conv but hold the ranges of the array }
  303. oldtype:=left.resulttype;
  304. left:=gentypeconvnode(left,defcoll^.paratype.def);
  305. firstpass(left);
  306. left.resulttype:=oldtype;
  307. end
  308. else
  309. begin
  310. left:=gentypeconvnode(left,defcoll^.paratype.def);
  311. firstpass(left);
  312. end;
  313. if codegenerror then
  314. begin
  315. dec(parsing_para_level);
  316. exit;
  317. end;
  318. end;
  319. { check var strings }
  320. if (cs_strict_var_strings in aktlocalswitches) and
  321. is_shortstring(left.resulttype) and
  322. is_shortstring(defcoll^.paratype.def) and
  323. (defcoll^.paratyp in [vs_out,vs_var]) and
  324. not(is_open_string(defcoll^.paratype.def)) and
  325. not(is_equal(left.resulttype,defcoll^.paratype.def)) then
  326. begin
  327. aktfilepos:=left.fileinfo;
  328. CGMessage(type_e_strict_var_string_violation);
  329. end;
  330. { Variablen for call by reference may not be copied }
  331. { into a register }
  332. { is this usefull here ? }
  333. { this was missing in formal parameter list }
  334. if (defcoll^.paratype.def=pdef(cformaldef)) then
  335. begin
  336. if defcoll^.paratyp=vs_var then
  337. begin
  338. if not valid_for_formal_var(left) then
  339. begin
  340. aktfilepos:=left.fileinfo;
  341. CGMessage(parser_e_illegal_parameter_list);
  342. end;
  343. end;
  344. if defcoll^.paratyp=vs_const then
  345. begin
  346. if not valid_for_formal_const(left) then
  347. begin
  348. aktfilepos:=left.fileinfo;
  349. CGMessage(parser_e_illegal_parameter_list);
  350. end;
  351. end;
  352. end;
  353. if defcoll^.paratyp in [vs_var,vs_const] then
  354. begin
  355. { Causes problems with const ansistrings if also }
  356. { done for vs_const (JM) }
  357. if defcoll^.paratyp = vs_var then
  358. set_unique(left);
  359. make_not_regable(left);
  360. end;
  361. { ansistrings out paramaters doesn't need to be }
  362. { unique, they are finalized }
  363. if defcoll^.paratyp=vs_out then
  364. make_not_regable(left);
  365. if do_count then
  366. set_varstate(left,defcoll^.paratyp <> vs_var);
  367. { must only be done after typeconv PM }
  368. resulttype:=defcoll^.paratype.def;
  369. end;
  370. if left.registers32>registers32 then
  371. registers32:=left.registers32;
  372. if left.registersfpu>registersfpu then
  373. registersfpu:=left.registersfpu;
  374. {$ifdef SUPPORT_MMX}
  375. if left.registersmmx>registersmmx then
  376. registersmmx:=left.registersmmx;
  377. {$endif SUPPORT_MMX}
  378. dec(parsing_para_level);
  379. {$ifdef extdebug}
  380. if do_count then
  381. count_ref:=store_count_ref;
  382. {$endif def extdebug}
  383. end;
  384. procedure tcallparanode.gen_high_tree(openstring:boolean);
  385. var
  386. len : longint;
  387. st : psymtable;
  388. loadconst : boolean;
  389. begin
  390. if assigned(hightree) then
  391. exit;
  392. len:=-1;
  393. loadconst:=true;
  394. case left.resulttype^.deftype of
  395. arraydef :
  396. begin
  397. if is_open_array(left.resulttype) or
  398. is_array_of_const(left.resulttype) then
  399. begin
  400. st:=tloadnode(left).symtable;
  401. getsymonlyin(st,'high'+pvarsym(tloadnode(left).symtableentry)^.name);
  402. hightree:=genloadnode(pvarsym(srsym),st);
  403. loadconst:=false;
  404. end
  405. else
  406. begin
  407. { this is an empty constructor }
  408. len:=parraydef(left.resulttype)^.highrange-
  409. parraydef(left.resulttype)^.lowrange;
  410. end;
  411. end;
  412. stringdef :
  413. begin
  414. if openstring then
  415. begin
  416. if is_open_string(left.resulttype) then
  417. begin
  418. st:=tloadnode(left).symtable;
  419. getsymonlyin(st,'high'+pvarsym(tloadnode(left).symtableentry)^.name);
  420. hightree:=genloadnode(pvarsym(srsym),st);
  421. loadconst:=false;
  422. end
  423. else
  424. len:=pstringdef(left.resulttype)^.len;
  425. end
  426. else
  427. { passing a string to an array of char }
  428. begin
  429. if (left.nodetype=stringconstn) then
  430. begin
  431. len:=str_length(left);
  432. if len>0 then
  433. dec(len);
  434. end
  435. else
  436. begin
  437. hightree:=caddnode.create(subn,geninlinenode(in_length_string,false,left.getcopy),
  438. genordinalconstnode(1,s32bitdef));
  439. firstpass(hightree);
  440. hightree:=gentypeconvnode(hightree,s32bitdef);
  441. loadconst:=false;
  442. end;
  443. end;
  444. end;
  445. else
  446. len:=0;
  447. end;
  448. if loadconst then
  449. hightree:=genordinalconstnode(len,s32bitdef);
  450. firstpass(hightree);
  451. end;
  452. {****************************************************************************
  453. TCALLNODE
  454. ****************************************************************************}
  455. constructor tcallnode.create(v : pprocsym;st : psymtable; mp : tnode);
  456. begin
  457. inherited create(calln,nil,nil);
  458. symtableprocentry:=v;
  459. symtableproc:=st;
  460. include(flags,nf_return_value_used);
  461. methodpointer:=mp;
  462. procdefinition:=nil;
  463. end;
  464. destructor tcallnode.destroy;
  465. begin
  466. methodpointer.free;
  467. inherited destroy;
  468. end;
  469. function tcallnode.getcopy : tnode;
  470. var
  471. n : tcallnode;
  472. begin
  473. n:=tcallnode(inherited getcopy);
  474. n.symtableprocentry:=symtableprocentry;
  475. n.symtableproc:=symtableproc;
  476. n.procdefinition:=procdefinition;
  477. if assigned(methodpointer) then
  478. n.methodpointer:=methodpointer.getcopy
  479. else
  480. n.methodpointer:=nil;
  481. result:=n;
  482. end;
  483. procedure tcallnode.insertintolist(l : tnodelist);
  484. begin
  485. end;
  486. function tcallnode.pass_1 : tnode;
  487. type
  488. pprocdefcoll = ^tprocdefcoll;
  489. tprocdefcoll = record
  490. data : pprocdef;
  491. nextpara : pparaitem;
  492. firstpara : pparaitem;
  493. next : pprocdefcoll;
  494. end;
  495. var
  496. hp,procs,hp2 : pprocdefcoll;
  497. pd : pprocdef;
  498. oldcallprocsym : pprocsym;
  499. def_from,def_to,conv_to : pdef;
  500. hpt,inlinecode : tnode;
  501. pt : tcallparanode;
  502. exactmatch,inlined : boolean;
  503. paralength,lastpara : longint;
  504. lastparatype : pdef;
  505. pdc : pparaitem;
  506. {$ifdef TEST_PROCSYMS}
  507. nextprocsym : pprocsym;
  508. symt : psymtable;
  509. {$endif TEST_PROCSYMS}
  510. { only Dummy }
  511. hcvt : tconverttype;
  512. {$ifdef m68k}
  513. regi : tregister;
  514. {$endif}
  515. method_must_be_valid : boolean;
  516. label
  517. errorexit;
  518. { check if the resulttype from tree p is equal with def, needed
  519. for stringconstn and formaldef }
  520. function is_equal(p:tcallparanode;def:pdef) : boolean;
  521. begin
  522. { safety check }
  523. if not (assigned(def) or assigned(p.resulttype)) then
  524. begin
  525. is_equal:=false;
  526. exit;
  527. end;
  528. { all types can be passed to a formaldef }
  529. is_equal:=(def^.deftype=formaldef) or
  530. (types.is_equal(p.resulttype,def))
  531. { integer constants are compatible with all integer parameters if
  532. the specified value matches the range }
  533. or
  534. (
  535. (tbinarynode(p).left.nodetype=ordconstn) and
  536. is_integer(p.resulttype) and
  537. is_integer(def) and
  538. (tordconstnode(p.left).value>=porddef(def)^.low) and
  539. (tordconstnode(p.left).value<=porddef(def)^.high)
  540. )
  541. { to support ansi/long/wide strings in a proper way }
  542. { string and string[10] are assumed as equal }
  543. { when searching the correct overloaded procedure }
  544. or
  545. (
  546. (def^.deftype=stringdef) and (p.resulttype^.deftype=stringdef) and
  547. (pstringdef(def)^.string_typ=pstringdef(p.resulttype)^.string_typ)
  548. )
  549. or
  550. (
  551. (p.left.nodetype=stringconstn) and
  552. (is_ansistring(p.resulttype) and is_pchar(def))
  553. )
  554. or
  555. (
  556. (p.left.nodetype=ordconstn) and
  557. (is_char(p.resulttype) and (is_shortstring(def) or is_ansistring(def)))
  558. )
  559. { set can also be a not yet converted array constructor }
  560. or
  561. (
  562. (def^.deftype=setdef) and (p.resulttype^.deftype=arraydef) and
  563. (parraydef(p.resulttype)^.IsConstructor) and not(parraydef(p.resulttype)^.IsVariant)
  564. )
  565. { in tp7 mode proc -> procvar is allowed }
  566. or
  567. (
  568. (m_tp_procvar in aktmodeswitches) and
  569. (def^.deftype=procvardef) and (p.left.nodetype=calln) and
  570. (proc_to_procvar_equal(pprocdef(tcallnode(p.left).procdefinition),pprocvardef(def)))
  571. )
  572. ;
  573. end;
  574. function is_in_limit(def_from,def_to : pdef) : boolean;
  575. begin
  576. is_in_limit:=(def_from^.deftype = orddef) and
  577. (def_to^.deftype = orddef) and
  578. (porddef(def_from)^.low>porddef(def_to)^.low) and
  579. (porddef(def_from)^.high<porddef(def_to)^.high);
  580. end;
  581. var
  582. is_const : boolean;
  583. i : longint;
  584. bestord : porddef;
  585. begin
  586. pass_1:=nil;
  587. { release registers! }
  588. { if procdefinition<>nil then we called firstpass already }
  589. { it seems to be bad because of the registers }
  590. { at least we can avoid the overloaded search !! }
  591. procs:=nil;
  592. { made this global for disposing !! }
  593. oldcallprocsym:=aktcallprocsym;
  594. aktcallprocsym:=nil;
  595. inlined:=false;
  596. if assigned(procdefinition) and
  597. (pocall_inline in procdefinition^.proccalloptions) then
  598. begin
  599. inlinecode:=right;
  600. if assigned(inlinecode) then
  601. begin
  602. inlined:=true;
  603. exclude(procdefinition^.proccalloptions,pocall_inline);
  604. end;
  605. right:=nil;
  606. end;
  607. if assigned(procdefinition) and
  608. (po_containsself in procdefinition^.procoptions) then
  609. message(cg_e_cannot_call_message_direct);
  610. { procedure variable ? }
  611. if assigned(right) then
  612. begin
  613. { procedure does a call }
  614. procinfo^.flags:=procinfo^.flags or pi_do_call;
  615. {$ifndef newcg}
  616. { calc the correture value for the register }
  617. {$ifdef i386}
  618. incrementregisterpushed($ff);
  619. {$endif}
  620. {$ifdef m68k}
  621. for regi:=R_D0 to R_A6 do
  622. inc(reg_pushes[regi],t_times*2);
  623. {$endif}
  624. {$endif newcg}
  625. { calculate the type of the parameters }
  626. if assigned(left) then
  627. begin
  628. tcallparanode(left).firstcallparan(nil,false);
  629. if codegenerror then
  630. goto errorexit;
  631. end;
  632. firstpass(right);
  633. set_varstate(right,true);
  634. { check the parameters }
  635. pdc:=pparaitem(pprocvardef(right.resulttype)^.para^.first);
  636. pt:=tcallparanode(left);
  637. while assigned(pdc) and assigned(pt) do
  638. begin
  639. pt:=tcallparanode(pt.right);
  640. pdc:=pparaitem(pdc^.next);
  641. end;
  642. if assigned(pt) or assigned(pdc) then
  643. begin
  644. if assigned(pt) then
  645. aktfilepos:=pt.fileinfo;
  646. CGMessage(parser_e_illegal_parameter_list);
  647. end;
  648. { insert type conversions }
  649. if assigned(left) then
  650. begin
  651. tcallparanode(left).firstcallparan(pparaitem(pprocvardef(right.resulttype)^.para^.first),true);
  652. if codegenerror then
  653. goto errorexit;
  654. end;
  655. resulttype:=pprocvardef(right.resulttype)^.rettype.def;
  656. { this was missing, leads to a bug below if
  657. the procvar is a function }
  658. procdefinition:=pabstractprocdef(right.resulttype);
  659. end
  660. else
  661. { not a procedure variable }
  662. begin
  663. { determine the type of the parameters }
  664. if assigned(left) then
  665. begin
  666. tcallparanode(left).firstcallparan(nil,false);
  667. if codegenerror then
  668. goto errorexit;
  669. end;
  670. aktcallprocsym:=pprocsym(symtableprocentry);
  671. { do we know the procedure to call ? }
  672. if not(assigned(procdefinition)) then
  673. begin
  674. {$ifdef TEST_PROCSYMS}
  675. if (unit_specific) or
  676. assigned(methodpointer) then
  677. nextprocsym:=nil
  678. else while not assigned(procs) do
  679. begin
  680. symt:=symtableproc;
  681. srsym:=nil;
  682. while assigned(symt^.next) and not assigned(srsym) do
  683. begin
  684. symt:=symt^.next;
  685. getsymonlyin(symt,actprocsym^.name);
  686. if assigned(srsym) then
  687. if srsym^.typ<>procsym then
  688. begin
  689. { reject all that is not a procedure }
  690. srsym:=nil;
  691. { don't search elsewhere }
  692. while assigned(symt^.next) do
  693. symt:=symt^.next;
  694. end;
  695. end;
  696. nextprocsym:=srsym;
  697. end;
  698. {$endif TEST_PROCSYMS}
  699. { determine length of parameter list }
  700. pt:=tcallparanode(left);
  701. paralength:=0;
  702. while assigned(pt) do
  703. begin
  704. inc(paralength);
  705. pt:=tcallparanode(pt.right);
  706. end;
  707. { link all procedures which have the same # of parameters }
  708. pd:=aktcallprocsym^.definition;
  709. while assigned(pd) do
  710. begin
  711. { only when the # of parameter are supported by the
  712. procedure }
  713. if (paralength>=pd^.minparacount) and (paralength<=pd^.maxparacount) then
  714. begin
  715. new(hp);
  716. hp^.data:=pd;
  717. hp^.next:=procs;
  718. hp^.firstpara:=pparaitem(pd^.para^.first);
  719. { if not all parameters are given, then skip the
  720. default parameters }
  721. for i:=1 to pd^.maxparacount-paralength do
  722. hp^.firstpara:=pparaitem(hp^.firstpara^.next);
  723. hp^.nextpara:=hp^.firstpara;
  724. procs:=hp;
  725. end;
  726. pd:=pd^.nextoverloaded;
  727. end;
  728. { no procedures found? then there is something wrong
  729. with the parameter size }
  730. if not assigned(procs) then
  731. begin
  732. { in tp mode we can try to convert to procvar if
  733. there are no parameters specified }
  734. if not(assigned(left)) and
  735. (m_tp_procvar in aktmodeswitches) then
  736. begin
  737. if (symtableprocentry^.owner^.symtabletype=objectsymtable) and
  738. (pobjectdef(symtableprocentry^.owner^.defowner)^.is_class) then
  739. hpt:=genloadmethodcallnode(pprocsym(symtableprocentry),symtableproc,
  740. methodpointer.getcopy)
  741. else
  742. hpt:=genloadcallnode(pprocsym(symtableprocentry),symtableproc);
  743. firstpass(hpt);
  744. pass_1:=hpt;
  745. end
  746. else
  747. begin
  748. if assigned(left) then
  749. aktfilepos:=left.fileinfo;
  750. CGMessage(parser_e_wrong_parameter_size);
  751. aktcallprocsym^.write_parameter_lists(nil);
  752. end;
  753. goto errorexit;
  754. end;
  755. { now we can compare parameter after parameter }
  756. pt:=tcallparanode(left);
  757. { we start with the last parameter }
  758. lastpara:=paralength+1;
  759. lastparatype:=nil;
  760. while assigned(pt) do
  761. begin
  762. dec(lastpara);
  763. { walk all procedures and determine how this parameter matches and set:
  764. 1. pt.exact_match_found if one parameter has an exact match
  765. 2. exactmatch if an equal or exact match is found
  766. 3. para^.argconvtyp to exact,equal or convertable
  767. (when convertable then also convertlevel is set)
  768. 4. pt.convlevel1found if there is a convertlevel=1
  769. 5. pt.convlevel2found if there is a convertlevel=2
  770. }
  771. exactmatch:=false;
  772. hp:=procs;
  773. while assigned(hp) do
  774. begin
  775. if is_equal(pt,hp^.nextpara^.paratype.def) then
  776. begin
  777. if hp^.nextpara^.paratype.def=pt.resulttype then
  778. begin
  779. include(pt.callparaflags,cpf_exact_match_found);
  780. hp^.nextpara^.argconvtyp:=act_exact;
  781. end
  782. else
  783. hp^.nextpara^.argconvtyp:=act_equal;
  784. exactmatch:=true;
  785. end
  786. else
  787. begin
  788. hp^.nextpara^.argconvtyp:=act_convertable;
  789. hp^.nextpara^.convertlevel:=isconvertable(pt.resulttype,hp^.nextpara^.paratype.def,
  790. hcvt,pt.left.nodetype,false);
  791. case hp^.nextpara^.convertlevel of
  792. 1 : include(pt.callparaflags,cpf_convlevel1found);
  793. 2 : include(pt.callparaflags,cpf_convlevel2found);
  794. end;
  795. end;
  796. hp:=hp^.next;
  797. end;
  798. { If there was an exactmatch then delete all convertables }
  799. if exactmatch then
  800. begin
  801. hp:=procs;
  802. procs:=nil;
  803. while assigned(hp) do
  804. begin
  805. hp2:=hp^.next;
  806. { keep if not convertable }
  807. if (hp^.nextpara^.argconvtyp<>act_convertable) then
  808. begin
  809. hp^.next:=procs;
  810. procs:=hp;
  811. end
  812. else
  813. dispose(hp);
  814. hp:=hp2;
  815. end;
  816. end
  817. else
  818. { No exact match was found, remove all procedures that are
  819. not convertable (convertlevel=0) }
  820. begin
  821. hp:=procs;
  822. procs:=nil;
  823. while assigned(hp) do
  824. begin
  825. hp2:=hp^.next;
  826. { keep if not convertable }
  827. if (hp^.nextpara^.convertlevel<>0) then
  828. begin
  829. hp^.next:=procs;
  830. procs:=hp;
  831. end
  832. else
  833. begin
  834. { save the type for nice error message }
  835. lastparatype:=hp^.nextpara^.paratype.def;
  836. dispose(hp);
  837. end;
  838. hp:=hp2;
  839. end;
  840. end;
  841. { update nextpara for all procedures }
  842. hp:=procs;
  843. while assigned(hp) do
  844. begin
  845. hp^.nextpara:=pparaitem(hp^.nextpara^.next);
  846. hp:=hp^.next;
  847. end;
  848. { load next parameter or quit loop if no procs left }
  849. if assigned(procs) then
  850. pt:=tcallparanode(pt.right)
  851. else
  852. break;
  853. end;
  854. { All parameters are checked, check if there are any
  855. procedures left }
  856. if not assigned(procs) then
  857. begin
  858. { there is an error, must be wrong type, because
  859. wrong size is already checked (PFV) }
  860. if (not assigned(lastparatype)) or
  861. (not assigned(pt)) or
  862. (not assigned(pt.resulttype)) then
  863. internalerror(39393)
  864. else
  865. begin
  866. aktfilepos:=pt.fileinfo;
  867. CGMessage3(type_e_wrong_parameter_type,tostr(lastpara),
  868. pt.resulttype^.typename,lastparatype^.typename);
  869. end;
  870. aktcallprocsym^.write_parameter_lists(nil);
  871. goto errorexit;
  872. end;
  873. { if there are several choices left then for orddef }
  874. { if a type is totally included in the other }
  875. { we don't fear an overflow , }
  876. { so we can do as if it is an exact match }
  877. { this will convert integer to longint }
  878. { rather than to words }
  879. { conversion of byte to integer or longint }
  880. {would still not be solved }
  881. if assigned(procs) and assigned(procs^.next) then
  882. begin
  883. hp:=procs;
  884. while assigned(hp) do
  885. begin
  886. hp^.nextpara:=hp^.firstpara;
  887. hp:=hp^.next;
  888. end;
  889. pt:=tcallparanode(left);
  890. while assigned(pt) do
  891. begin
  892. { matches a parameter of one procedure exact ? }
  893. exactmatch:=false;
  894. def_from:=pt.resulttype;
  895. hp:=procs;
  896. while assigned(hp) do
  897. begin
  898. if not is_equal(pt,hp^.nextpara^.paratype.def) then
  899. begin
  900. def_to:=hp^.nextpara^.paratype.def;
  901. if ((def_from^.deftype=orddef) and (def_to^.deftype=orddef)) and
  902. (is_in_limit(def_from,def_to) or
  903. ((hp^.nextpara^.paratyp in [vs_var,vs_out]) and
  904. (def_from^.size=def_to^.size))) then
  905. begin
  906. exactmatch:=true;
  907. conv_to:=def_to;
  908. end;
  909. end;
  910. hp:=hp^.next;
  911. end;
  912. { .... if yes, del all the other procedures }
  913. if exactmatch then
  914. begin
  915. { the first .... }
  916. while (assigned(procs)) and not(is_in_limit(def_from,procs^.nextpara^.paratype.def)) do
  917. begin
  918. hp:=procs^.next;
  919. dispose(procs);
  920. procs:=hp;
  921. end;
  922. { and the others }
  923. hp:=procs;
  924. while (assigned(hp)) and assigned(hp^.next) do
  925. begin
  926. if not(is_in_limit(def_from,hp^.next^.nextpara^.paratype.def)) then
  927. begin
  928. hp2:=hp^.next^.next;
  929. dispose(hp^.next);
  930. hp^.next:=hp2;
  931. end
  932. else
  933. begin
  934. def_to:=hp^.next^.nextpara^.paratype.def;
  935. if (conv_to^.size>def_to^.size) or
  936. ((porddef(conv_to)^.low<porddef(def_to)^.low) and
  937. (porddef(conv_to)^.high>porddef(def_to)^.high)) then
  938. begin
  939. hp2:=procs;
  940. procs:=hp;
  941. conv_to:=def_to;
  942. dispose(hp2);
  943. end
  944. else
  945. hp:=hp^.next;
  946. end;
  947. end;
  948. end;
  949. { update nextpara for all procedures }
  950. hp:=procs;
  951. while assigned(hp) do
  952. begin
  953. hp^.nextpara:=pparaitem(hp^.nextpara^.next);
  954. hp:=hp^.next;
  955. end;
  956. pt:=tcallparanode(pt.right);
  957. end;
  958. end;
  959. { let's try to eliminate equal if there is an exact match
  960. is there }
  961. if assigned(procs) and assigned(procs^.next) then
  962. begin
  963. { reset nextpara for all procs left }
  964. hp:=procs;
  965. while assigned(hp) do
  966. begin
  967. hp^.nextpara:=hp^.firstpara;
  968. hp:=hp^.next;
  969. end;
  970. pt:=tcallparanode(left);
  971. while assigned(pt) do
  972. begin
  973. if cpf_exact_match_found in pt.callparaflags then
  974. begin
  975. hp:=procs;
  976. procs:=nil;
  977. while assigned(hp) do
  978. begin
  979. hp2:=hp^.next;
  980. { keep the exact matches, dispose the others }
  981. if (hp^.nextpara^.argconvtyp=act_exact) then
  982. begin
  983. hp^.next:=procs;
  984. procs:=hp;
  985. end
  986. else
  987. dispose(hp);
  988. hp:=hp2;
  989. end;
  990. end;
  991. { update nextpara for all procedures }
  992. hp:=procs;
  993. while assigned(hp) do
  994. begin
  995. hp^.nextpara:=pparaitem(hp^.nextpara^.next);
  996. hp:=hp^.next;
  997. end;
  998. pt:=tcallparanode(pt.right);
  999. end;
  1000. end;
  1001. { Check if there are integer constant to integer
  1002. parameters then choose the best matching integer
  1003. parameter and remove the others, this is Delphi
  1004. compatible. 1 = byte, 256 = word, etc. }
  1005. if assigned(procs) and assigned(procs^.next) then
  1006. begin
  1007. { reset nextpara for all procs left }
  1008. hp:=procs;
  1009. while assigned(hp) do
  1010. begin
  1011. hp^.nextpara:=hp^.firstpara;
  1012. hp:=hp^.next;
  1013. end;
  1014. pt:=tcallparanode(left);
  1015. while assigned(pt) do
  1016. begin
  1017. bestord:=nil;
  1018. if (pt.left.nodetype=ordconstn) and
  1019. is_integer(pt.resulttype) then
  1020. begin
  1021. hp:=procs;
  1022. while assigned(hp) do
  1023. begin
  1024. def_to:=hp^.nextpara^.paratype.def;
  1025. { to be sure, it couldn't be something else,
  1026. also the defs here are all in the range
  1027. so now find the closest range }
  1028. if not is_integer(def_to) then
  1029. internalerror(43297815);
  1030. if (not assigned(bestord)) or
  1031. ((porddef(def_to)^.low>bestord^.low) or
  1032. (porddef(def_to)^.high<bestord^.high)) then
  1033. bestord:=porddef(def_to);
  1034. hp:=hp^.next;
  1035. end;
  1036. end;
  1037. { if a bestmatch is found then remove the other
  1038. procs which don't match the bestord }
  1039. if assigned(bestord) then
  1040. begin
  1041. hp:=procs;
  1042. procs:=nil;
  1043. while assigned(hp) do
  1044. begin
  1045. hp2:=hp^.next;
  1046. { keep matching bestord, dispose the others }
  1047. if (porddef(hp^.nextpara^.paratype.def)=bestord) then
  1048. begin
  1049. hp^.next:=procs;
  1050. procs:=hp;
  1051. end
  1052. else
  1053. dispose(hp);
  1054. hp:=hp2;
  1055. end;
  1056. end;
  1057. { update nextpara for all procedures }
  1058. hp:=procs;
  1059. while assigned(hp) do
  1060. begin
  1061. hp^.nextpara:=pparaitem(hp^.nextpara^.next);
  1062. hp:=hp^.next;
  1063. end;
  1064. pt:=tcallparanode(pt.right);
  1065. end;
  1066. end;
  1067. { Check if there are convertlevel 1 and 2 differences
  1068. left for the parameters, then discard all convertlevel
  1069. 2 procedures. The value of convlevelXfound can still
  1070. be used, because all convertables are still here or
  1071. not }
  1072. if assigned(procs) and assigned(procs^.next) then
  1073. begin
  1074. { reset nextpara for all procs left }
  1075. hp:=procs;
  1076. while assigned(hp) do
  1077. begin
  1078. hp^.nextpara:=hp^.firstpara;
  1079. hp:=hp^.next;
  1080. end;
  1081. pt:=tcallparanode(left);
  1082. while assigned(pt) do
  1083. begin
  1084. if (cpf_convlevel1found in pt.callparaflags) and
  1085. (cpf_convlevel2found in pt.callparaflags) then
  1086. begin
  1087. hp:=procs;
  1088. procs:=nil;
  1089. while assigned(hp) do
  1090. begin
  1091. hp2:=hp^.next;
  1092. { keep all not act_convertable and all convertlevels=1 }
  1093. if (hp^.nextpara^.argconvtyp<>act_convertable) or
  1094. (hp^.nextpara^.convertlevel=1) then
  1095. begin
  1096. hp^.next:=procs;
  1097. procs:=hp;
  1098. end
  1099. else
  1100. dispose(hp);
  1101. hp:=hp2;
  1102. end;
  1103. end;
  1104. { update nextpara for all procedures }
  1105. hp:=procs;
  1106. while assigned(hp) do
  1107. begin
  1108. hp^.nextpara:=pparaitem(hp^.nextpara^.next);
  1109. hp:=hp^.next;
  1110. end;
  1111. pt:=tcallparanode(pt.right);
  1112. end;
  1113. end;
  1114. if not(assigned(procs)) or assigned(procs^.next) then
  1115. begin
  1116. CGMessage(cg_e_cant_choose_overload_function);
  1117. aktcallprocsym^.write_parameter_lists(nil);
  1118. goto errorexit;
  1119. end;
  1120. {$ifdef TEST_PROCSYMS}
  1121. if (procs=nil) and assigned(nextprocsym) then
  1122. begin
  1123. symtableprocentry:=nextprocsym;
  1124. symtableproc:=symt;
  1125. end;
  1126. end ; { of while assigned(symtableprocentry) do }
  1127. {$endif TEST_PROCSYMS}
  1128. if make_ref then
  1129. begin
  1130. procs^.data^.lastref:=new(pref,init(procs^.data^.lastref,@fileinfo));
  1131. inc(procs^.data^.refcount);
  1132. if procs^.data^.defref=nil then
  1133. procs^.data^.defref:=procs^.data^.lastref;
  1134. end;
  1135. procdefinition:=procs^.data;
  1136. resulttype:=procs^.data^.rettype.def;
  1137. { big error for with statements
  1138. symtableproc:=procdefinition^.owner;
  1139. but neede for overloaded operators !! }
  1140. if symtableproc=nil then
  1141. symtableproc:=procdefinition^.owner;
  1142. location.loc:=LOC_MEM;
  1143. {$ifdef CHAINPROCSYMS}
  1144. { object with method read;
  1145. call to read(x) will be a usual procedure call }
  1146. if assigned(methodpointer) and
  1147. (procdefinition^._class=nil) then
  1148. begin
  1149. { not ok for extended }
  1150. case methodpointer^.nodetype of
  1151. typen,hnewn : fatalerror(no_para_match);
  1152. end;
  1153. methodpointer.free;
  1154. methodpointer:=nil;
  1155. end;
  1156. {$endif CHAINPROCSYMS}
  1157. end; { end of procedure to call determination }
  1158. is_const:=(pocall_internconst in procdefinition^.proccalloptions) and
  1159. ((block_type=bt_const) or
  1160. (assigned(left) and (tcallparanode(left).left.nodetype in [realconstn,ordconstn])));
  1161. { handle predefined procedures }
  1162. if (pocall_internproc in procdefinition^.proccalloptions) or is_const then
  1163. begin
  1164. if assigned(left) then
  1165. begin
  1166. { settextbuf needs two args }
  1167. if assigned(tcallparanode(left).right) then
  1168. hpt:=geninlinenode(pprocdef(procdefinition)^.extnumber,is_const,left)
  1169. else
  1170. begin
  1171. hpt:=geninlinenode(pprocdef(procdefinition)^.extnumber,is_const,
  1172. tcallparanode(left).left);
  1173. tcallparanode(left).left:=nil;
  1174. left.free;
  1175. left:=nil;
  1176. end;
  1177. end
  1178. else
  1179. begin
  1180. hpt:=geninlinenode(pprocdef(procdefinition)^.extnumber,is_const,nil);
  1181. end;
  1182. firstpass(hpt);
  1183. pass_1:=hpt;
  1184. goto errorexit;
  1185. end
  1186. else
  1187. { no intern procedure => we do a call }
  1188. { calc the correture value for the register }
  1189. { handle predefined procedures }
  1190. if (pocall_inline in procdefinition^.proccalloptions) then
  1191. begin
  1192. if assigned(methodpointer) then
  1193. CGMessage(cg_e_unable_inline_object_methods);
  1194. if assigned(right) and (right.nodetype<>procinlinen) then
  1195. CGMessage(cg_e_unable_inline_procvar);
  1196. { nodetype:=procinlinen; }
  1197. if not assigned(right) then
  1198. begin
  1199. if assigned(pprocdef(procdefinition)^.code) then
  1200. inlinecode:=genprocinlinenode(self,tnode(pprocdef(procdefinition)^.code))
  1201. else
  1202. CGMessage(cg_e_no_code_for_inline_stored);
  1203. if assigned(inlinecode) then
  1204. begin
  1205. { consider it has not inlined if called
  1206. again inside the args }
  1207. exclude(procdefinition^.proccalloptions,pocall_inline);
  1208. firstpass(inlinecode);
  1209. inlined:=true;
  1210. end;
  1211. end;
  1212. end
  1213. else
  1214. procinfo^.flags:=procinfo^.flags or pi_do_call;
  1215. { add needed default parameters }
  1216. if assigned(procs) and
  1217. (paralength<procdefinition^.maxparacount) then
  1218. begin
  1219. { add default parameters, just read back the skipped
  1220. paras starting from firstpara^.previous, when not available
  1221. (all parameters are default) then start with the last
  1222. parameter and read backward (PFV) }
  1223. if not assigned(procs^.firstpara) then
  1224. pdc:=pparaitem(procs^.data^.para^.last)
  1225. else
  1226. pdc:=pparaitem(procs^.firstpara^.previous);
  1227. while assigned(pdc) do
  1228. begin
  1229. if not assigned(pdc^.defaultvalue) then
  1230. internalerror(751349858);
  1231. left:=gencallparanode(genconstsymtree(pconstsym(pdc^.defaultvalue)),left);
  1232. pdc:=pparaitem(pdc^.previous);
  1233. end;
  1234. end;
  1235. { work trough all parameters to insert the type conversions }
  1236. if assigned(left) then
  1237. tcallparanode(left).firstcallparan(pparaitem(procdefinition^.para^.first),true);
  1238. {$ifndef newcg}
  1239. {$ifdef i386}
  1240. incrementregisterpushed(pprocdef(procdefinition)^.usedregisters);
  1241. {$endif}
  1242. {$ifdef m68k}
  1243. for regi:=R_D0 to R_A6 do
  1244. begin
  1245. if (pprocdef(procdefinition)^.usedregisters and ($800 shr word(regi)))<>0 then
  1246. inc(reg_pushes[regi],t_times*2);
  1247. end;
  1248. {$endif}
  1249. {$endif newcg}
  1250. end;
  1251. { ensure that the result type is set }
  1252. resulttype:=procdefinition^.rettype.def;
  1253. { get a register for the return value }
  1254. if (resulttype<>pdef(voiddef)) then
  1255. begin
  1256. if (procdefinition^.proctypeoption=potype_constructor) then
  1257. begin
  1258. { extra handling of classes }
  1259. { methodpointer should be assigned! }
  1260. if assigned(methodpointer) and assigned(methodpointer.resulttype) and
  1261. (methodpointer.resulttype^.deftype=classrefdef) then
  1262. begin
  1263. location.loc:=LOC_REGISTER;
  1264. registers32:=1;
  1265. { the result type depends on the classref }
  1266. resulttype:=pclassrefdef(methodpointer.resulttype)^.pointertype.def;
  1267. end
  1268. { a object constructor returns the result with the flags }
  1269. else
  1270. location.loc:=LOC_FLAGS;
  1271. end
  1272. else
  1273. begin
  1274. {$ifdef SUPPORT_MMX}
  1275. if (cs_mmx in aktlocalswitches) and
  1276. is_mmx_able_array(resulttype) then
  1277. begin
  1278. location.loc:=LOC_MMXREGISTER;
  1279. registersmmx:=1;
  1280. end
  1281. else
  1282. {$endif SUPPORT_MMX}
  1283. if ret_in_acc(resulttype) then
  1284. begin
  1285. location.loc:=LOC_REGISTER;
  1286. if is_64bitint(resulttype) then
  1287. registers32:=2
  1288. else
  1289. registers32:=1;
  1290. { wide- and ansistrings are returned in EAX }
  1291. { but they are imm. moved to a memory location }
  1292. if is_widestring(resulttype) or
  1293. is_ansistring(resulttype) then
  1294. begin
  1295. location.loc:=LOC_MEM;
  1296. { this is wrong we still need one register PM
  1297. registers32:=0; }
  1298. { we use ansistrings so no fast exit here }
  1299. procinfo^.no_fast_exit:=true;
  1300. registers32:=1;
  1301. end;
  1302. end
  1303. else if (resulttype^.deftype=floatdef) then
  1304. begin
  1305. location.loc:=LOC_FPU;
  1306. registersfpu:=1;
  1307. end
  1308. else
  1309. location.loc:=LOC_MEM;
  1310. end;
  1311. end;
  1312. { a fpu can be used in any procedure !! }
  1313. registersfpu:=procdefinition^.fpu_used;
  1314. { if this is a call to a method calc the registers }
  1315. if (methodpointer<>nil) then
  1316. begin
  1317. case methodpointer.nodetype of
  1318. { but only, if this is not a supporting node }
  1319. typen: ;
  1320. { we need one register for new return value PM }
  1321. hnewn : if registers32=0 then
  1322. registers32:=1;
  1323. else
  1324. begin
  1325. if (procdefinition^.proctypeoption in [potype_constructor,potype_destructor]) and
  1326. assigned(symtableproc) and (symtableproc^.symtabletype=withsymtable) and
  1327. not pwithsymtable(symtableproc)^.direct_with then
  1328. begin
  1329. CGmessage(cg_e_cannot_call_cons_dest_inside_with);
  1330. end; { Is accepted by Delphi !! }
  1331. { this is not a good reason to accept it in FPC if we produce
  1332. wrong code for it !!! (PM) }
  1333. { R.Assign is not a constructor !!! }
  1334. { but for R^.Assign, R must be valid !! }
  1335. if (procdefinition^.proctypeoption=potype_constructor) or
  1336. ((methodpointer.nodetype=loadn) and
  1337. (not(oo_has_virtual in pobjectdef(methodpointer.resulttype)^.objectoptions))) then
  1338. method_must_be_valid:=false
  1339. else
  1340. method_must_be_valid:=true;
  1341. firstpass(methodpointer);
  1342. set_varstate(methodpointer,method_must_be_valid);
  1343. { The object is already used ven if it is called once }
  1344. if (methodpointer.nodetype=loadn) and
  1345. (tloadnode(methodpointer).symtableentry^.typ=varsym) then
  1346. pvarsym(tloadnode(methodpointer).symtableentry)^.varstate:=vs_used;
  1347. registersfpu:=max(methodpointer.registersfpu,registersfpu);
  1348. registers32:=max(methodpointer.registers32,registers32);
  1349. {$ifdef SUPPORT_MMX}
  1350. registersmmx:=max(methodpointer.registersmmx,registersmmx);
  1351. {$endif SUPPORT_MMX}
  1352. end;
  1353. end;
  1354. end;
  1355. if inlined then
  1356. right:=inlinecode;
  1357. { determine the registers of the procedure variable }
  1358. { is this OK for inlined procs also ?? (PM) }
  1359. if assigned(right) then
  1360. begin
  1361. registersfpu:=max(right.registersfpu,registersfpu);
  1362. registers32:=max(right.registers32,registers32);
  1363. {$ifdef SUPPORT_MMX}
  1364. registersmmx:=max(right.registersmmx,registersmmx);
  1365. {$endif SUPPORT_MMX}
  1366. end;
  1367. { determine the registers of the procedure }
  1368. if assigned(left) then
  1369. begin
  1370. registersfpu:=max(left.registersfpu,registersfpu);
  1371. registers32:=max(left.registers32,registers32);
  1372. {$ifdef SUPPORT_MMX}
  1373. registersmmx:=max(left.registersmmx,registersmmx);
  1374. {$endif SUPPORT_MMX}
  1375. end;
  1376. errorexit:
  1377. { Reset some settings back }
  1378. if assigned(procs) then
  1379. dispose(procs);
  1380. if inlined then
  1381. include(procdefinition^.proccalloptions,pocall_inline);
  1382. aktcallprocsym:=oldcallprocsym;
  1383. end;
  1384. {****************************************************************************
  1385. TPROCINLINENODE
  1386. ****************************************************************************}
  1387. constructor tprocinlinenode.create(callp,code : tnode);
  1388. begin
  1389. inherited create(procinlinen);
  1390. inlineprocsym:=tcallnode(callp).symtableprocentry;
  1391. retoffset:=-4; { less dangerous as zero (PM) }
  1392. para_offset:=0;
  1393. {$IFDEF NEWST}
  1394. {Fixme!!}
  1395. internalerror($00022801);
  1396. {$ELSE}
  1397. para_size:=inlineprocsym^.definition^.para_size(target_os.stackalignment);
  1398. if ret_in_param(inlineprocsym^.definition^.rettype.def) then
  1399. para_size:=para_size+target_os.size_of_pointer;
  1400. {$ENDIF NEWST}
  1401. { copy args }
  1402. inlinetree:=code;
  1403. registers32:=code.registers32;
  1404. registersfpu:=code.registersfpu;
  1405. {$ifdef SUPPORT_MMX}
  1406. registersmmx:=code.registersmmx;
  1407. {$endif SUPPORT_MMX}
  1408. {$IFDEF NEWST}
  1409. {Fixme!!}
  1410. {$ELSE}
  1411. resulttype:=inlineprocsym^.definition^.rettype.def;
  1412. {$ENDIF NEWST}
  1413. end;
  1414. destructor tprocinlinenode.destroy;
  1415. begin
  1416. inlinetree.free;
  1417. inherited destroy;
  1418. end;
  1419. function tprocinlinenode.getcopy : tnode;
  1420. var
  1421. n : tprocinlinenode;
  1422. begin
  1423. n:=tprocinlinenode(inherited getcopy);
  1424. if assigned(inlinetree) then
  1425. n.inlinetree:=inlinetree.getcopy
  1426. else
  1427. n.inlinetree:=nil;
  1428. n.inlineprocsym:=inlineprocsym;
  1429. n.retoffset:=retoffset;
  1430. n.para_offset:=para_offset;
  1431. n.para_size:=para_size;
  1432. getcopy:=n;
  1433. end;
  1434. procedure tprocinlinenode.insertintolist(l : tnodelist);
  1435. begin
  1436. end;
  1437. function tprocinlinenode.pass_1 : tnode;
  1438. begin
  1439. pass_1:=nil;
  1440. { left contains the code in tree form }
  1441. { but it has already been firstpassed }
  1442. { so firstpass(left); does not seem required }
  1443. { might be required later if we change the arg handling !! }
  1444. end;
  1445. begin
  1446. ccallnode:=tcallnode;
  1447. ccallparanode:=tcallparanode;
  1448. cprocinlinenode:=tprocinlinenode;
  1449. end.
  1450. {
  1451. $Log$
  1452. Revision 1.12 2000-10-21 18:16:11 florian
  1453. * a lot of changes:
  1454. - basic dyn. array support
  1455. - basic C++ support
  1456. - some work for interfaces done
  1457. ....
  1458. Revision 1.11 2000/10/21 14:35:27 peter
  1459. * readd to many remove p. for tcallnode.is_equal()
  1460. Revision 1.10 2000/10/14 21:52:55 peter
  1461. * fixed memory leaks
  1462. Revision 1.9 2000/10/14 10:14:50 peter
  1463. * moehrendorf oct 2000 rewrite
  1464. Revision 1.8 2000/10/01 19:48:24 peter
  1465. * lot of compile updates for cg11
  1466. Revision 1.7 2000/09/28 19:49:52 florian
  1467. *** empty log message ***
  1468. Revision 1.6 2000/09/27 18:14:31 florian
  1469. * fixed a lot of syntax errors in the n*.pas stuff
  1470. Revision 1.5 2000/09/24 21:15:34 florian
  1471. * some errors fix to get more stuff compilable
  1472. Revision 1.4 2000/09/24 20:17:44 florian
  1473. * more conversion work done
  1474. Revision 1.3 2000/09/24 15:06:19 peter
  1475. * use defines.inc
  1476. Revision 1.2 2000/09/20 21:52:38 florian
  1477. * removed a lot of errors
  1478. Revision 1.1 2000/09/20 20:52:16 florian
  1479. * initial revision
  1480. }