tccal.pas 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl
  4. Type checking and register allocation for call nodes
  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 tccal;
  19. interface
  20. uses
  21. symtable,tree;
  22. procedure firstcallparan(var p : ptree;defcoll : pdefcoll);
  23. procedure firstcalln(var p : ptree);
  24. procedure firstprocinline(var p : ptree);
  25. implementation
  26. uses
  27. cobjects,verbose,globals,systems,
  28. aasm,types,
  29. hcodegen,htypechk,pass_1
  30. {$ifdef i386}
  31. ,i386,tgeni386
  32. {$endif}
  33. {$ifdef m68k}
  34. ,m68k,tgeni386
  35. {$endif}
  36. ;
  37. {*****************************************************************************
  38. FirstCallParaN
  39. *****************************************************************************}
  40. procedure firstcallparan(var p : ptree;defcoll : pdefcoll);
  41. var
  42. old_array_constructor : boolean;
  43. store_valid : boolean;
  44. oldtype : pdef;
  45. convtyp : tconverttype;
  46. begin
  47. inc(parsing_para_level);
  48. if assigned(p^.right) then
  49. begin
  50. if defcoll=nil then
  51. firstcallparan(p^.right,nil)
  52. else
  53. firstcallparan(p^.right,defcoll^.next);
  54. p^.registers32:=p^.right^.registers32;
  55. p^.registersfpu:=p^.right^.registersfpu;
  56. {$ifdef SUPPORT_MMX}
  57. p^.registersmmx:=p^.right^.registersmmx;
  58. {$endif}
  59. end;
  60. if defcoll=nil then
  61. begin
  62. old_array_constructor:=allow_array_constructor;
  63. allow_array_constructor:=true;
  64. if not(assigned(p^.resulttype)) or
  65. (p^.left^.treetype=typeconvn) then
  66. firstpass(p^.left);
  67. allow_array_constructor:=old_array_constructor;
  68. if codegenerror then
  69. begin
  70. dec(parsing_para_level);
  71. exit;
  72. end;
  73. p^.resulttype:=p^.left^.resulttype;
  74. end
  75. { if we know the routine which is called, then the type }
  76. { conversions are inserted }
  77. else
  78. begin
  79. if count_ref then
  80. begin
  81. store_valid:=must_be_valid;
  82. if (defcoll^.paratyp=vs_var) then
  83. test_protected(p^.left);
  84. if (defcoll^.paratyp<>vs_var) then
  85. must_be_valid:=true
  86. else
  87. must_be_valid:=false;
  88. { here we must add something for the implicit type }
  89. { conversion from array of char to pchar }
  90. { if isconvertable(p^.left^.resulttype,defcoll^.data,convtyp,
  91. p^.left^.treetype,false) then
  92. if convtyp=tc_array_to_pointer then
  93. must_be_valid:=false; }
  94. { only process typeconvn, else it will break other trees }
  95. old_array_constructor:=allow_array_constructor;
  96. allow_array_constructor:=true;
  97. if (p^.left^.treetype=typeconvn) then
  98. firstpass(p^.left);
  99. allow_array_constructor:=old_array_constructor;
  100. must_be_valid:=store_valid;
  101. end;
  102. if not(is_shortstring(p^.left^.resulttype) and
  103. is_shortstring(defcoll^.data)) and
  104. (defcoll^.data^.deftype<>formaldef) then
  105. begin
  106. if (defcoll^.paratyp=vs_var) and
  107. { allows conversion from word to integer and
  108. byte to shortint }
  109. (not(
  110. (p^.left^.resulttype^.deftype=orddef) and
  111. (defcoll^.data^.deftype=orddef) and
  112. (p^.left^.resulttype^.size=defcoll^.data^.size)
  113. ) and
  114. { an implicit pointer conversion is allowed }
  115. not(
  116. (p^.left^.resulttype^.deftype=pointerdef) and
  117. (defcoll^.data^.deftype=pointerdef)
  118. ) and
  119. { child classes can be also passed }
  120. not(
  121. (p^.left^.resulttype^.deftype=objectdef) and
  122. (defcoll^.data^.deftype=objectdef) and
  123. pobjectdef(p^.left^.resulttype)^.isrelated(pobjectdef(defcoll^.data))
  124. ) and
  125. { passing a single element to a openarray of the same type }
  126. not(
  127. (is_open_array(defcoll^.data) and
  128. is_equal(parraydef(defcoll^.data)^.definition,p^.left^.resulttype))
  129. ) and
  130. { an implicit file conversion is also allowed }
  131. { from a typed file to an untyped one }
  132. not(
  133. (p^.left^.resulttype^.deftype=filedef) and
  134. (defcoll^.data^.deftype=filedef) and
  135. (pfiledef(defcoll^.data)^.filetype = ft_untyped) and
  136. (pfiledef(p^.left^.resulttype)^.filetype = ft_typed)
  137. ) and
  138. not(is_equal(p^.left^.resulttype,defcoll^.data))) then
  139. CGMessage(parser_e_call_by_ref_without_typeconv);
  140. { don't generate an type conversion for open arrays }
  141. { else we loss the ranges }
  142. if is_open_array(defcoll^.data) then
  143. begin
  144. oldtype:=p^.left^.resulttype;
  145. p^.left:=gentypeconvnode(p^.left,defcoll^.data);
  146. firstpass(p^.left);
  147. p^.left^.resulttype:=oldtype;
  148. end
  149. else
  150. begin
  151. p^.left:=gentypeconvnode(p^.left,defcoll^.data);
  152. firstpass(p^.left);
  153. end;
  154. if codegenerror then
  155. begin
  156. dec(parsing_para_level);
  157. exit;
  158. end;
  159. end;
  160. { check var strings }
  161. if (cs_strict_var_strings in aktlocalswitches) and
  162. is_shortstring(p^.left^.resulttype) and
  163. is_shortstring(defcoll^.data) and
  164. (defcoll^.paratyp=vs_var) and
  165. not(is_equal(p^.left^.resulttype,defcoll^.data)) then
  166. CGMessage(type_e_strict_var_string_violation);
  167. { Variablen, die call by reference �bergeben werden, }
  168. { k”nnen nicht in ein Register kopiert werden }
  169. { is this usefull here ? }
  170. { this was missing in formal parameter list }
  171. if defcoll^.paratyp=vs_var then
  172. begin
  173. set_unique(p^.left);
  174. make_not_regable(p^.left);
  175. end;
  176. p^.resulttype:=defcoll^.data;
  177. end;
  178. if p^.left^.registers32>p^.registers32 then
  179. p^.registers32:=p^.left^.registers32;
  180. if p^.left^.registersfpu>p^.registersfpu then
  181. p^.registersfpu:=p^.left^.registersfpu;
  182. {$ifdef SUPPORT_MMX}
  183. if p^.left^.registersmmx>p^.registersmmx then
  184. p^.registersmmx:=p^.left^.registersmmx;
  185. {$endif SUPPORT_MMX}
  186. dec(parsing_para_level);
  187. end;
  188. {*****************************************************************************
  189. FirstCallN
  190. *****************************************************************************}
  191. procedure firstcalln(var p : ptree);
  192. type
  193. pprocdefcoll = ^tprocdefcoll;
  194. tprocdefcoll = record
  195. data : pprocdef;
  196. nextpara : pdefcoll;
  197. firstpara : pdefcoll;
  198. next : pprocdefcoll;
  199. end;
  200. var
  201. hp,procs,hp2 : pprocdefcoll;
  202. pd : pprocdef;
  203. actprocsym : pprocsym;
  204. def_from,def_to,conv_to : pdef;
  205. pt,inlinecode : ptree;
  206. exactmatch,inlined : boolean;
  207. paralength,l : longint;
  208. pdc : pdefcoll;
  209. { only Dummy }
  210. hcvt : tconverttype;
  211. regi : tregister;
  212. store_valid, old_count_ref : boolean;
  213. { types.is_equal can't handle a formaldef ! }
  214. function is_equal(def1,def2 : pdef) : boolean;
  215. begin
  216. { safety check }
  217. if not (assigned(def1) or assigned(def2)) then
  218. begin
  219. is_equal:=false;
  220. exit;
  221. end;
  222. { all types can be passed to a formaldef }
  223. is_equal:=(def1^.deftype=formaldef) or
  224. (types.is_equal(def1,def2))
  225. { to support ansi/long/wide strings in a proper way }
  226. { string and string[10] are assumed as equal }
  227. { when searching the correct overloaded procedure }
  228. or
  229. (
  230. (def1^.deftype=stringdef) and (def2^.deftype=stringdef) and
  231. (pstringdef(def1)^.string_typ=pstringdef(def2)^.string_typ)
  232. )
  233. { set can also be a not yet converted array constructor }
  234. or
  235. (
  236. (def1^.deftype=setdef) and (def2^.deftype=arraydef) and
  237. (parraydef(def2)^.IsConstructor) and not(parraydef(def2)^.IsVariant)
  238. )
  239. ;
  240. end;
  241. function is_in_limit(def_from,def_to : pdef) : boolean;
  242. begin
  243. is_in_limit:=(def_from^.deftype = orddef) and
  244. (def_to^.deftype = orddef) and
  245. (porddef(def_from)^.low>porddef(def_to)^.low) and
  246. (porddef(def_from)^.high<porddef(def_to)^.high);
  247. end;
  248. var
  249. is_const : boolean;
  250. begin
  251. { release registers! }
  252. { if procdefinition<>nil then we called firstpass already }
  253. { it seems to be bad because of the registers }
  254. { at least we can avoid the overloaded search !! }
  255. procs:=nil;
  256. { made this global for disposing !! }
  257. store_valid:=must_be_valid;
  258. must_be_valid:=false;
  259. inlined:=false;
  260. if assigned(p^.procdefinition) and
  261. ((p^.procdefinition^.options and poinline)<>0) then
  262. begin
  263. inlinecode:=p^.right;
  264. if assigned(inlinecode) then
  265. begin
  266. inlined:=true;
  267. p^.procdefinition^.options:=p^.procdefinition^.options and (not poinline);
  268. end;
  269. p^.right:=nil;
  270. end;
  271. { procedure variable ? }
  272. if assigned(p^.right) then
  273. begin
  274. { procedure does a call }
  275. procinfo.flags:=procinfo.flags or pi_do_call;
  276. { calc the correture value for the register }
  277. {$ifdef i386}
  278. for regi:=R_EAX to R_EDI do
  279. inc(reg_pushes[regi],t_times*2);
  280. {$endif}
  281. {$ifdef m68k}
  282. for regi:=R_D0 to R_A6 do
  283. inc(reg_pushes[regi],t_times*2);
  284. {$endif}
  285. { calculate the type of the parameters }
  286. if assigned(p^.left) then
  287. begin
  288. old_count_ref:=count_ref;
  289. count_ref:=false;
  290. firstcallparan(p^.left,nil);
  291. count_ref:=old_count_ref;
  292. if codegenerror then
  293. exit;
  294. end;
  295. firstpass(p^.right);
  296. { check the parameters }
  297. pdc:=pprocvardef(p^.right^.resulttype)^.para1;
  298. pt:=p^.left;
  299. while assigned(pdc) and assigned(pt) do
  300. begin
  301. pt:=pt^.right;
  302. pdc:=pdc^.next;
  303. end;
  304. if assigned(pt) or assigned(pdc) then
  305. CGMessage(parser_e_illegal_parameter_list);
  306. { insert type conversions }
  307. if assigned(p^.left) then
  308. begin
  309. old_count_ref:=count_ref;
  310. count_ref:=true;
  311. firstcallparan(p^.left,pprocvardef(p^.right^.resulttype)^.para1);
  312. count_ref:=old_count_ref;
  313. if codegenerror then
  314. exit;
  315. end;
  316. p^.resulttype:=pprocvardef(p^.right^.resulttype)^.retdef;
  317. { this was missing, leads to a bug below if
  318. the procvar is a function }
  319. p^.procdefinition:=pprocdef(p^.right^.resulttype);
  320. end
  321. else
  322. { not a procedure variable }
  323. begin
  324. { determine the type of the parameters }
  325. if assigned(p^.left) then
  326. begin
  327. old_count_ref:=count_ref;
  328. count_ref:=false;
  329. store_valid:=must_be_valid;
  330. must_be_valid:=false;
  331. firstcallparan(p^.left,nil);
  332. count_ref:=old_count_ref;
  333. must_be_valid:=store_valid;
  334. if codegenerror then
  335. exit;
  336. end;
  337. { do we know the procedure to call ? }
  338. if not(assigned(p^.procdefinition)) then
  339. begin
  340. actprocsym:=pprocsym(p^.symtableprocentry);
  341. { determine length of parameter list }
  342. pt:=p^.left;
  343. paralength:=0;
  344. while assigned(pt) do
  345. begin
  346. inc(paralength);
  347. pt:=pt^.right;
  348. end;
  349. { link all procedures which have the same # of parameters }
  350. pd:=actprocsym^.definition;
  351. while assigned(pd) do
  352. begin
  353. { we should also check that the overloaded function
  354. has been declared in a unit that is in the uses !! }
  355. { pd^.owner should be in the symtablestack !! }
  356. { Laenge der deklarierten Parameterliste feststellen: }
  357. { not necessary why nextprocsym field }
  358. {st:=symtablestack;
  359. if (pd^.owner^.symtabletype<>objectsymtable) then
  360. while assigned(st) do
  361. begin
  362. if (st=pd^.owner) then break;
  363. st:=st^.next;
  364. end;
  365. if assigned(st) then }
  366. begin
  367. pdc:=pd^.para1;
  368. l:=0;
  369. while assigned(pdc) do
  370. begin
  371. inc(l);
  372. pdc:=pdc^.next;
  373. end;
  374. { only when the # of parameter are equal }
  375. if l=paralength then
  376. begin
  377. new(hp);
  378. hp^.data:=pd;
  379. hp^.next:=procs;
  380. hp^.nextpara:=pd^.para1;
  381. hp^.firstpara:=pd^.para1;
  382. procs:=hp;
  383. end;
  384. end;
  385. pd:=pd^.nextoverloaded;
  386. {$ifdef CHAINPROCSYMS}
  387. if (pd=nil) and not (p^.unit_specific) then
  388. begin
  389. actprocsym:=actprocsym^.nextprocsym;
  390. if assigned(actprocsym) then
  391. pd:=actprocsym^.definition;
  392. end;
  393. {$endif CHAINPROCSYMS}
  394. end;
  395. { no procedures found? then there is something wrong
  396. with the parameter size }
  397. if not assigned(procs) and
  398. ((parsing_para_level=0) or assigned(p^.left)) then
  399. begin
  400. CGMessage(parser_e_wrong_parameter_size);
  401. actprocsym^.write_parameter_lists;
  402. exit;
  403. end;
  404. { now we can compare parameter after parameter }
  405. pt:=p^.left;
  406. while assigned(pt) do
  407. begin
  408. { matches a parameter of one procedure exact ? }
  409. exactmatch:=false;
  410. hp:=procs;
  411. while assigned(hp) do
  412. begin
  413. if is_equal(hp^.nextpara^.data,pt^.resulttype) then
  414. begin
  415. if hp^.nextpara^.data=pt^.resulttype then
  416. begin
  417. pt^.exact_match_found:=true;
  418. hp^.nextpara^.argconvtyp:=act_exact;
  419. end
  420. else
  421. hp^.nextpara^.argconvtyp:=act_equal;
  422. exactmatch:=true;
  423. end
  424. else
  425. hp^.nextpara^.argconvtyp:=act_convertable;
  426. hp:=hp^.next;
  427. end;
  428. { .... if yes, del all the other procedures }
  429. if exactmatch then
  430. begin
  431. { the first .... }
  432. while (assigned(procs)) and not(is_equal(procs^.nextpara^.data,pt^.resulttype)) do
  433. begin
  434. hp:=procs^.next;
  435. dispose(procs);
  436. procs:=hp;
  437. end;
  438. { and the others }
  439. hp:=procs;
  440. while (assigned(hp)) and assigned(hp^.next) do
  441. begin
  442. if not(is_equal(hp^.next^.nextpara^.data,pt^.resulttype)) then
  443. begin
  444. hp2:=hp^.next^.next;
  445. dispose(hp^.next);
  446. hp^.next:=hp2;
  447. end
  448. else
  449. hp:=hp^.next;
  450. end;
  451. end
  452. { when a parameter matches exact, remove all procs
  453. which need typeconvs }
  454. else
  455. begin
  456. { the first... }
  457. while (assigned(procs)) and
  458. not(isconvertable(pt^.resulttype,procs^.nextpara^.data,
  459. hcvt,pt^.left^.treetype,false)) do
  460. begin
  461. hp:=procs^.next;
  462. dispose(procs);
  463. procs:=hp;
  464. end;
  465. { and the others }
  466. hp:=procs;
  467. while (assigned(hp)) and assigned(hp^.next) do
  468. begin
  469. if not(isconvertable(pt^.resulttype,hp^.next^.nextpara^.data,
  470. hcvt,pt^.left^.treetype,false)) then
  471. begin
  472. hp2:=hp^.next^.next;
  473. dispose(hp^.next);
  474. hp^.next:=hp2;
  475. end
  476. else
  477. hp:=hp^.next;
  478. end;
  479. end;
  480. { update nextpara for all procedures }
  481. hp:=procs;
  482. while assigned(hp) do
  483. begin
  484. hp^.nextpara:=hp^.nextpara^.next;
  485. hp:=hp^.next;
  486. end;
  487. { load next parameter }
  488. pt:=pt^.right;
  489. end;
  490. if not assigned(procs) then
  491. begin
  492. { there is an error, must be wrong type, because
  493. wrong size is already checked (PFV) }
  494. if (parsing_para_level=0) or (p^.left<>nil) then
  495. begin
  496. CGMessage(parser_e_wrong_parameter_type);
  497. actprocsym^.write_parameter_lists;
  498. exit;
  499. end
  500. else
  501. begin
  502. { try to convert to procvar }
  503. p^.treetype:=loadn;
  504. p^.resulttype:=pprocsym(p^.symtableprocentry)^.definition;
  505. p^.symtableentry:=p^.symtableprocentry;
  506. p^.is_first:=false;
  507. p^.disposetyp:=dt_nothing;
  508. firstpass(p);
  509. exit;
  510. end;
  511. end;
  512. { if there are several choices left then for orddef }
  513. { if a type is totally included in the other }
  514. { we don't fear an overflow , }
  515. { so we can do as if it is an exact match }
  516. { this will convert integer to longint }
  517. { rather than to words }
  518. { conversion of byte to integer or longint }
  519. {would still not be solved }
  520. if assigned(procs^.next) then
  521. begin
  522. hp:=procs;
  523. while assigned(hp) do
  524. begin
  525. hp^.nextpara:=hp^.firstpara;
  526. hp:=hp^.next;
  527. end;
  528. pt:=p^.left;
  529. while assigned(pt) do
  530. begin
  531. { matches a parameter of one procedure exact ? }
  532. exactmatch:=false;
  533. def_from:=pt^.resulttype;
  534. hp:=procs;
  535. while assigned(hp) do
  536. begin
  537. if not is_equal(hp^.nextpara^.data,pt^.resulttype) then
  538. begin
  539. def_to:=hp^.nextpara^.data;
  540. if ((def_from^.deftype=orddef) and (def_to^.deftype=orddef)) and
  541. (is_in_limit(def_from,def_to) or
  542. ((hp^.nextpara^.paratyp=vs_var) and
  543. (def_from^.size=def_to^.size))) then
  544. begin
  545. exactmatch:=true;
  546. conv_to:=def_to;
  547. end;
  548. end;
  549. hp:=hp^.next;
  550. end;
  551. { .... if yes, del all the other procedures }
  552. if exactmatch then
  553. begin
  554. { the first .... }
  555. while (assigned(procs)) and not(is_in_limit(def_from,procs^.nextpara^.data)) do
  556. begin
  557. hp:=procs^.next;
  558. dispose(procs);
  559. procs:=hp;
  560. end;
  561. { and the others }
  562. hp:=procs;
  563. while (assigned(hp)) and assigned(hp^.next) do
  564. begin
  565. if not(is_in_limit(def_from,hp^.next^.nextpara^.data)) then
  566. begin
  567. hp2:=hp^.next^.next;
  568. dispose(hp^.next);
  569. hp^.next:=hp2;
  570. end
  571. else
  572. begin
  573. def_to:=hp^.next^.nextpara^.data;
  574. if (conv_to^.size>def_to^.size) or
  575. ((porddef(conv_to)^.low<porddef(def_to)^.low) and
  576. (porddef(conv_to)^.high>porddef(def_to)^.high)) then
  577. begin
  578. hp2:=procs;
  579. procs:=hp;
  580. conv_to:=def_to;
  581. dispose(hp2);
  582. end
  583. else
  584. hp:=hp^.next;
  585. end;
  586. end;
  587. end;
  588. { update nextpara for all procedures }
  589. hp:=procs;
  590. while assigned(hp) do
  591. begin
  592. hp^.nextpara:=hp^.nextpara^.next;
  593. hp:=hp^.next;
  594. end;
  595. pt:=pt^.right;
  596. end;
  597. end;
  598. { let's try to eliminate equal is exact is there }
  599. {if assigned(procs^.next) then
  600. begin
  601. pt:=p^.left;
  602. while assigned(pt) do
  603. begin
  604. if pt^.exact_match_found then
  605. begin
  606. hp:=procs;
  607. while (assigned(procs)) and (procs^.nextpara^.data<>pt^.resulttype) do
  608. begin
  609. hp:=procs^.next;
  610. dispose(procs);
  611. procs:=hp;
  612. end;
  613. end;
  614. pt:=pt^.right;
  615. end;
  616. end; }
  617. {$ifndef CHAINPROCSYMS}
  618. if assigned(procs^.next) then
  619. begin
  620. CGMessage(cg_e_cant_choose_overload_function);
  621. actprocsym^.write_parameter_lists;
  622. end;
  623. {$else CHAINPROCSYMS}
  624. if assigned(procs^.next) then
  625. { if the last retained is the only one }
  626. { from a unit it is OK PM }
  627. { the last is the one coming from the first symtable }
  628. { as the diff defcoll are inserted in front }
  629. begin
  630. hp2:=procs;
  631. while assigned(hp2^.next) and assigned(hp2^.next^.next) do
  632. hp2:=hp2^.next;
  633. if (hp2^.data^.owner<>hp2^.next^.data^.owner) then
  634. begin
  635. hp:=procs^.next;
  636. {hp2 is the correct one }
  637. hp2:=hp2^.next;
  638. while hp<>hp2 do
  639. begin
  640. dispose(procs);
  641. procs:=hp;
  642. hp:=procs^.next;
  643. end;
  644. procs:=hp2;
  645. end
  646. else
  647. begin
  648. CGMessage(cg_e_cant_choose_overload_function);
  649. actprocsym^.write_parameter_lists;
  650. error(too_much_matches);
  651. end;
  652. end;
  653. {$endif CHAINPROCSYMS}
  654. {$ifdef UseBrowser}
  655. if make_ref then
  656. begin
  657. procs^.data^.lastref:=new(pref,init(procs^.data^.lastref,@p^.fileinfo));
  658. end;
  659. {$endif UseBrowser}
  660. p^.procdefinition:=procs^.data;
  661. p^.resulttype:=procs^.data^.retdef;
  662. { big error for with statements
  663. p^.symtableproc:=p^.procdefinition^.owner; }
  664. p^.location.loc:=LOC_MEM;
  665. {$ifdef CHAINPROCSYMS}
  666. { object with method read;
  667. call to read(x) will be a usual procedure call }
  668. if assigned(p^.methodpointer) and
  669. (p^.procdefinition^._class=nil) then
  670. begin
  671. { not ok for extended }
  672. case p^.methodpointer^.treetype of
  673. typen,hnewn : fatalerror(no_para_match);
  674. end;
  675. disposetree(p^.methodpointer);
  676. p^.methodpointer:=nil;
  677. end;
  678. {$endif CHAINPROCSYMS}
  679. end;{ end of procedure to call determination }
  680. is_const:=((p^.procdefinition^.options and pointernconst)<>0) and
  681. (p^.left^.left^.treetype in [realconstn,ordconstn]);
  682. { handle predefined procedures }
  683. if ((p^.procdefinition^.options and pointernproc)<>0) or is_const then
  684. begin
  685. { settextbuf needs two args }
  686. if assigned(p^.left^.right) then
  687. pt:=geninlinenode(pprocdef(p^.procdefinition)^.extnumber,is_const,p^.left)
  688. else
  689. begin
  690. pt:=geninlinenode(pprocdef(p^.procdefinition)^.extnumber,is_const,p^.left^.left);
  691. putnode(p^.left);
  692. end;
  693. putnode(p);
  694. firstpass(pt);
  695. p:=pt;
  696. must_be_valid:=store_valid;
  697. if codegenerror then
  698. exit;
  699. dispose(procs);
  700. exit;
  701. end
  702. else
  703. { no intern procedure => we do a call }
  704. { calc the correture value for the register }
  705. { handle predefined procedures }
  706. if (p^.procdefinition^.options and poinline)<>0 then
  707. begin
  708. if assigned(p^.methodpointer) then
  709. CGMessage(cg_e_unable_inline_object_methods);
  710. if assigned(p^.right) and (p^.right^.treetype<>procinlinen) then
  711. CGMessage(cg_e_unable_inline_procvar);
  712. { p^.treetype:=procinlinen; }
  713. if not assigned(p^.right) then
  714. begin
  715. if assigned(p^.procdefinition^.code) then
  716. inlinecode:=genprocinlinenode(p,ptree(p^.procdefinition^.code))
  717. else
  718. CGMessage(cg_e_no_code_for_inline_stored);
  719. if assigned(inlinecode) then
  720. begin
  721. { consider it has not inlined if called
  722. again inside the args }
  723. p^.procdefinition^.options:=p^.procdefinition^.options and (not poinline);
  724. firstpass(inlinecode);
  725. inlined:=true;
  726. end;
  727. end;
  728. end
  729. else
  730. procinfo.flags:=procinfo.flags or pi_do_call;
  731. { work trough all parameters to insert the type conversions }
  732. { !!! done now after internproc !! (PM) }
  733. if assigned(p^.left) then
  734. begin
  735. old_count_ref:=count_ref;
  736. count_ref:=true;
  737. firstcallparan(p^.left,p^.procdefinition^.para1);
  738. count_ref:=old_count_ref;
  739. end;
  740. {$ifdef i386}
  741. for regi:=R_EAX to R_EDI do
  742. begin
  743. if (p^.procdefinition^.usedregisters and ($80 shr word(regi)))<>0 then
  744. inc(reg_pushes[regi],t_times*2);
  745. end;
  746. {$endif}
  747. {$ifdef m68k}
  748. for regi:=R_D0 to R_A6 do
  749. begin
  750. if (p^.procdefinition^.usedregisters and ($800 shr word(regi)))<>0 then
  751. inc(reg_pushes[regi],t_times*2);
  752. end;
  753. {$endif}
  754. end;
  755. { ensure that the result type is set }
  756. p^.resulttype:=p^.procdefinition^.retdef;
  757. { get a register for the return value }
  758. if (p^.resulttype<>pdef(voiddef)) then
  759. begin
  760. if (p^.procdefinition^.options and poconstructor)<>0 then
  761. begin
  762. { extra handling of classes }
  763. { p^.methodpointer should be assigned! }
  764. if assigned(p^.methodpointer) and assigned(p^.methodpointer^.resulttype) and
  765. (p^.methodpointer^.resulttype^.deftype=classrefdef) then
  766. begin
  767. p^.location.loc:=LOC_REGISTER;
  768. p^.registers32:=1;
  769. { the result type depends on the classref }
  770. p^.resulttype:=pclassrefdef(p^.methodpointer^.resulttype)^.definition;
  771. end
  772. { a object constructor returns the result with the flags }
  773. else
  774. p^.location.loc:=LOC_FLAGS;
  775. end
  776. else
  777. begin
  778. {$ifdef SUPPORT_MMX}
  779. if (cs_mmx in aktlocalswitches) and
  780. is_mmx_able_array(p^.resulttype) then
  781. begin
  782. p^.location.loc:=LOC_MMXREGISTER;
  783. p^.registersmmx:=1;
  784. end
  785. else
  786. {$endif SUPPORT_MMX}
  787. if ret_in_acc(p^.resulttype) then
  788. begin
  789. p^.location.loc:=LOC_REGISTER;
  790. p^.registers32:=1;
  791. end
  792. else if (p^.resulttype^.deftype=floatdef) then
  793. begin
  794. p^.location.loc:=LOC_FPU;
  795. p^.registersfpu:=1;
  796. end
  797. end;
  798. end;
  799. { a fpu can be used in any procedure !! }
  800. p^.registersfpu:=p^.procdefinition^.fpu_used;
  801. { if this is a call to a method calc the registers }
  802. if (p^.methodpointer<>nil) then
  803. begin
  804. case p^.methodpointer^.treetype of
  805. { but only, if this is not a supporting node }
  806. typen,hnewn : ;
  807. else
  808. begin
  809. { R.Assign is not a constructor !!! }
  810. { but for R^.Assign, R must be valid !! }
  811. if ((p^.procdefinition^.options and poconstructor) <> 0) or
  812. ((p^.methodpointer^.treetype=loadn) and
  813. ((pobjectdef(p^.methodpointer^.resulttype)^.options and oo_hasvirtual) = 0)) then
  814. must_be_valid:=false
  815. else
  816. must_be_valid:=true;
  817. firstpass(p^.methodpointer);
  818. p^.registersfpu:=max(p^.methodpointer^.registersfpu,p^.registersfpu);
  819. p^.registers32:=max(p^.methodpointer^.registers32,p^.registers32);
  820. {$ifdef SUPPORT_MMX}
  821. p^.registersmmx:=max(p^.methodpointer^.registersmmx,p^.registersmmx);
  822. {$endif SUPPORT_MMX}
  823. end;
  824. end;
  825. end;
  826. if inlined then
  827. begin
  828. p^.right:=inlinecode;
  829. p^.procdefinition^.options:=p^.procdefinition^.options or poinline;
  830. end;
  831. { determine the registers of the procedure variable }
  832. { is this OK for inlined procs also ?? (PM) }
  833. if assigned(p^.right) then
  834. begin
  835. p^.registersfpu:=max(p^.right^.registersfpu,p^.registersfpu);
  836. p^.registers32:=max(p^.right^.registers32,p^.registers32);
  837. {$ifdef SUPPORT_MMX}
  838. p^.registersmmx:=max(p^.right^.registersmmx,p^.registersmmx);
  839. {$endif SUPPORT_MMX}
  840. end;
  841. { determine the registers of the procedure }
  842. if assigned(p^.left) then
  843. begin
  844. p^.registersfpu:=max(p^.left^.registersfpu,p^.registersfpu);
  845. p^.registers32:=max(p^.left^.registers32,p^.registers32);
  846. {$ifdef SUPPORT_MMX}
  847. p^.registersmmx:=max(p^.left^.registersmmx,p^.registersmmx);
  848. {$endif SUPPORT_MMX}
  849. end;
  850. if assigned(procs) then
  851. dispose(procs);
  852. must_be_valid:=store_valid;
  853. end;
  854. {*****************************************************************************
  855. FirstProcInlineN
  856. *****************************************************************************}
  857. procedure firstprocinline(var p : ptree);
  858. begin
  859. { left contains the code in tree form }
  860. { but it has already been firstpassed }
  861. { so firstpass(p^.left); does not seem required }
  862. { might be required later if we change the arg handling !! }
  863. end;
  864. end.
  865. {
  866. $Log$
  867. Revision 1.4 1998-09-27 10:16:24 florian
  868. * type casts pchar<->ansistring fixed
  869. * ansistring[..] calls does now an unique call
  870. Revision 1.3 1998/09/24 14:27:40 peter
  871. * some better support for openarray
  872. Revision 1.2 1998/09/24 09:02:16 peter
  873. * rewritten isconvertable to use case
  874. * array of .. and single variable are compatible
  875. Revision 1.1 1998/09/23 20:42:24 peter
  876. * splitted pass_1
  877. }