tccal.pas 40 KB

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