tccal.pas 39 KB

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