ncal.pas 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. This file implements the node for sub procedure calling
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit ncal;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. node,
  23. symbase,symsym,symdef,symtable;
  24. type
  25. tcallnode = class(tbinarynode)
  26. { the symbol containing the definition of the procedure }
  27. { to call }
  28. symtableprocentry : tprocsym;
  29. { the symtable containing symtableprocentry }
  30. symtableproc : tsymtable;
  31. { the definition of the procedure to call }
  32. procdefinition : tabstractprocdef;
  33. methodpointer : tnode;
  34. { only the processor specific nodes need to override this }
  35. { constructor }
  36. constructor create(l:tnode; v : tprocsym;st : tsymtable; mp : tnode);virtual;
  37. {$ifdef hascompilerproc}
  38. constructor createintern(const name: string; params: tnode);
  39. {$endif hascompilerproc}
  40. destructor destroy;override;
  41. function getcopy : tnode;override;
  42. procedure insertintolist(l : tnodelist);override;
  43. function pass_1 : tnode;override;
  44. function det_resulttype:tnode;override;
  45. function docompare(p: tnode): boolean; override;
  46. procedure set_procvar(procvar:tnode);
  47. end;
  48. tcallparaflags = (
  49. { flags used by tcallparanode }
  50. cpf_exact_match_found,
  51. cpf_convlevel1found,
  52. cpf_convlevel2found,
  53. cpf_is_colon_para
  54. );
  55. tcallparanode = class(tbinarynode)
  56. callparaflags : set of tcallparaflags;
  57. hightree : tnode;
  58. { only the processor specific nodes need to override this }
  59. { constructor }
  60. constructor create(expr,next : tnode);virtual;
  61. destructor destroy;override;
  62. function getcopy : tnode;override;
  63. procedure insertintolist(l : tnodelist);override;
  64. procedure gen_high_tree(openstring:boolean);
  65. procedure get_paratype;
  66. procedure insert_typeconv(defcoll : tparaitem;do_count : boolean);
  67. procedure det_registers;
  68. procedure firstcallparan(defcoll : tparaitem;do_count : boolean);
  69. procedure secondcallparan(defcoll : tparaitem;
  70. push_from_left_to_right,inlined,is_cdecl : boolean;
  71. para_alignment,para_offset : longint);virtual;abstract;
  72. function docompare(p: tnode): boolean; override;
  73. end;
  74. tprocinlinenode = class(tnode)
  75. inlinetree : tnode;
  76. inlineprocsym : tprocsym;
  77. retoffset,para_offset,para_size : longint;
  78. constructor create(callp,code : tnode);virtual;
  79. destructor destroy;override;
  80. function getcopy : tnode;override;
  81. procedure insertintolist(l : tnodelist);override;
  82. function pass_1 : tnode;override;
  83. function docompare(p: tnode): boolean; override;
  84. end;
  85. var
  86. ccallnode : class of tcallnode;
  87. ccallparanode : class of tcallparanode;
  88. cprocinlinenode : class of tprocinlinenode;
  89. implementation
  90. uses
  91. cutils,globtype,systems,
  92. verbose,globals,
  93. symconst,symtype,types,
  94. htypechk,pass_1,cpubase,
  95. ncnv,nld,ninl,nadd,ncon,hcodegen,
  96. tgcpu
  97. {$ifdef newcg}
  98. ,cgbase
  99. {$endif newcg}
  100. ;
  101. {****************************************************************************
  102. TCALLPARANODE
  103. ****************************************************************************}
  104. constructor tcallparanode.create(expr,next : tnode);
  105. begin
  106. inherited create(callparan,expr,next);
  107. hightree:=nil;
  108. if assigned(expr) then
  109. expr.set_file_line(self);
  110. callparaflags:=[];
  111. end;
  112. destructor tcallparanode.destroy;
  113. begin
  114. hightree.free;
  115. inherited destroy;
  116. end;
  117. function tcallparanode.getcopy : tnode;
  118. var
  119. n : tcallparanode;
  120. begin
  121. n:=tcallparanode(inherited getcopy);
  122. n.callparaflags:=callparaflags;
  123. if assigned(hightree) then
  124. n.hightree:=hightree.getcopy
  125. else
  126. n.hightree:=nil;
  127. result:=n;
  128. end;
  129. procedure tcallparanode.insertintolist(l : tnodelist);
  130. begin
  131. end;
  132. procedure tcallparanode.get_paratype;
  133. var
  134. old_get_para_resulttype : boolean;
  135. old_array_constructor : boolean;
  136. begin
  137. inc(parsing_para_level);
  138. if assigned(right) then
  139. tcallparanode(right).get_paratype;
  140. old_array_constructor:=allow_array_constructor;
  141. old_get_para_resulttype:=get_para_resulttype;
  142. get_para_resulttype:=true;
  143. allow_array_constructor:=true;
  144. resulttypepass(left);
  145. get_para_resulttype:=old_get_para_resulttype;
  146. allow_array_constructor:=old_array_constructor;
  147. if codegenerror then
  148. resulttype:=generrortype
  149. else
  150. resulttype:=left.resulttype;
  151. dec(parsing_para_level);
  152. end;
  153. procedure tcallparanode.insert_typeconv(defcoll : tparaitem;do_count : boolean);
  154. var
  155. oldtype : ttype;
  156. {$ifdef extdebug}
  157. store_count_ref : boolean;
  158. {$endif def extdebug}
  159. begin
  160. inc(parsing_para_level);
  161. if not assigned(defcoll) then
  162. internalerror(200104261);
  163. {$ifdef extdebug}
  164. if do_count then
  165. begin
  166. store_count_ref:=count_ref;
  167. count_ref:=true;
  168. end;
  169. {$endif def extdebug}
  170. if assigned(right) then
  171. begin
  172. { if we are a para that belongs to varargs then keep
  173. the current defcoll }
  174. if (nf_varargs_para in flags) then
  175. tcallparanode(right).insert_typeconv(defcoll,do_count)
  176. else
  177. tcallparanode(right).insert_typeconv(tparaitem(defcoll.next),do_count);
  178. end;
  179. { Be sure to have the resulttype }
  180. if not assigned(left.resulttype.def) then
  181. resulttypepass(left);
  182. { Handle varargs directly, no typeconvs or typechecking needed }
  183. if (nf_varargs_para in flags) then
  184. begin
  185. { convert pascal to C types }
  186. case left.resulttype.def.deftype of
  187. stringdef :
  188. inserttypeconv(left,charpointertype);
  189. floatdef :
  190. inserttypeconv(left,s64floattype);
  191. end;
  192. set_varstate(left,true);
  193. resulttype:=left.resulttype;
  194. dec(parsing_para_level);
  195. exit;
  196. end;
  197. { Do we need arrayconstructor -> set conversion, then insert
  198. it here before the arrayconstructor node breaks the tree
  199. with its conversions of enum->ord }
  200. if (left.nodetype=arrayconstructorn) and
  201. (defcoll.paratype.def.deftype=setdef) then
  202. inserttypeconv(left,defcoll.paratype);
  203. { set some settings needed for arrayconstructor }
  204. if is_array_constructor(left.resulttype.def) then
  205. begin
  206. if is_array_of_const(defcoll.paratype.def) then
  207. begin
  208. if assigned(aktcallprocsym) and
  209. (([pocall_cppdecl,pocall_cdecl]*aktcallprocsym.definition.proccalloptions)<>[]) and
  210. (po_external in aktcallprocsym.definition.procoptions) then
  211. include(left.flags,nf_cargs);
  212. { force variant array }
  213. include(left.flags,nf_forcevaria);
  214. end
  215. else
  216. begin
  217. include(left.flags,nf_novariaallowed);
  218. { now that the resultting type is know we can insert the required
  219. typeconvs for the array constructor }
  220. tarrayconstructornode(left).force_type(tarraydef(defcoll.paratype.def).elementtype);
  221. end;
  222. end;
  223. { check if local proc/func is assigned to procvar }
  224. if left.resulttype.def.deftype=procvardef then
  225. test_local_to_procvar(tprocvardef(left.resulttype.def),defcoll.paratype.def);
  226. { generate the high() value tree }
  227. if not(assigned(aktcallprocsym) and
  228. (([pocall_cppdecl,pocall_cdecl]*aktcallprocsym.definition.proccalloptions)<>[]) and
  229. (po_external in aktcallprocsym.definition.procoptions)) and
  230. push_high_param(defcoll.paratype.def) then
  231. gen_high_tree(is_open_string(defcoll.paratype.def));
  232. { test conversions }
  233. if not(is_shortstring(left.resulttype.def) and
  234. is_shortstring(defcoll.paratype.def)) and
  235. (defcoll.paratype.def.deftype<>formaldef) then
  236. begin
  237. if (defcoll.paratyp in [vs_var,vs_out]) and
  238. { allows conversion from word to integer and
  239. byte to shortint, but only for TP7 compatibility }
  240. (not(
  241. (m_tp7 in aktmodeswitches) and
  242. (left.resulttype.def.deftype=orddef) and
  243. (defcoll.paratype.def.deftype=orddef) and
  244. (left.resulttype.def.size=defcoll.paratype.def.size)
  245. ) and
  246. { an implicit pointer conversion is allowed }
  247. not(
  248. (left.resulttype.def.deftype=pointerdef) and
  249. (defcoll.paratype.def.deftype=pointerdef)
  250. ) and
  251. { child classes can be also passed }
  252. not(
  253. (left.resulttype.def.deftype=objectdef) and
  254. (defcoll.paratype.def.deftype=objectdef) and
  255. tobjectdef(left.resulttype.def).is_related(tobjectdef(defcoll.paratype.def))
  256. ) and
  257. { passing a single element to a openarray of the same type }
  258. not(
  259. (is_open_array(defcoll.paratype.def) and
  260. is_equal(tarraydef(defcoll.paratype.def).elementtype.def,left.resulttype.def))
  261. ) and
  262. { an implicit file conversion is also allowed }
  263. { from a typed file to an untyped one }
  264. not(
  265. (left.resulttype.def.deftype=filedef) and
  266. (defcoll.paratype.def.deftype=filedef) and
  267. (tfiledef(defcoll.paratype.def).filetyp = ft_untyped) and
  268. (tfiledef(left.resulttype.def).filetyp = ft_typed)
  269. ) and
  270. not(is_equal(left.resulttype.def,defcoll.paratype.def))) then
  271. begin
  272. CGMessagePos2(left.fileinfo,parser_e_call_by_ref_without_typeconv,
  273. left.resulttype.def.typename,defcoll.paratype.def.typename);
  274. end;
  275. { Process open parameters }
  276. if push_high_param(defcoll.paratype.def) then
  277. begin
  278. { insert type conv but hold the ranges of the array }
  279. oldtype:=left.resulttype;
  280. inserttypeconv(left,defcoll.paratype);
  281. left.resulttype:=oldtype;
  282. end
  283. else
  284. begin
  285. inserttypeconv(left,defcoll.paratype);
  286. end;
  287. if codegenerror then
  288. begin
  289. dec(parsing_para_level);
  290. exit;
  291. end;
  292. end;
  293. { check var strings }
  294. if (cs_strict_var_strings in aktlocalswitches) and
  295. is_shortstring(left.resulttype.def) and
  296. is_shortstring(defcoll.paratype.def) and
  297. (defcoll.paratyp in [vs_out,vs_var]) and
  298. not(is_open_string(defcoll.paratype.def)) and
  299. not(is_equal(left.resulttype.def,defcoll.paratype.def)) then
  300. begin
  301. aktfilepos:=left.fileinfo;
  302. CGMessage(type_e_strict_var_string_violation);
  303. end;
  304. { Handle formal parameters separate }
  305. if (defcoll.paratype.def.deftype=formaldef) then
  306. begin
  307. case defcoll.paratyp of
  308. vs_var,
  309. vs_out :
  310. begin
  311. if not valid_for_formal_var(left) then
  312. CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
  313. end;
  314. vs_const :
  315. begin
  316. if not valid_for_formal_const(left) then
  317. CGMessagePos(left.fileinfo,parser_e_illegal_parameter_list);
  318. end;
  319. end;
  320. end
  321. else
  322. begin
  323. { check if the argument is allowed }
  324. if (defcoll.paratyp in [vs_out,vs_var]) then
  325. valid_for_var(left);
  326. end;
  327. if defcoll.paratyp in [vs_var,vs_const] then
  328. begin
  329. { Causes problems with const ansistrings if also }
  330. { done for vs_const (JM) }
  331. if defcoll.paratyp = vs_var then
  332. set_unique(left);
  333. make_not_regable(left);
  334. end;
  335. { ansistrings out paramaters doesn't need to be }
  336. { unique, they are finalized }
  337. if defcoll.paratyp=vs_out then
  338. make_not_regable(left);
  339. if do_count then
  340. begin
  341. { not completly proper, but avoids some warnings }
  342. if (defcoll.paratyp in [vs_var,vs_out]) then
  343. set_funcret_is_valid(left);
  344. set_varstate(left,not(defcoll.paratyp in [vs_var,vs_out]));
  345. end;
  346. { must only be done after typeconv PM }
  347. resulttype:=defcoll.paratype;
  348. dec(parsing_para_level);
  349. {$ifdef extdebug}
  350. if do_count then
  351. count_ref:=store_count_ref;
  352. {$endif def extdebug}
  353. end;
  354. procedure tcallparanode.det_registers;
  355. var
  356. old_get_para_resulttype : boolean;
  357. old_array_constructor : boolean;
  358. begin
  359. if assigned(right) then
  360. begin
  361. tcallparanode(right).det_registers;
  362. registers32:=right.registers32;
  363. registersfpu:=right.registersfpu;
  364. {$ifdef SUPPORT_MMX}
  365. registersmmx:=right.registersmmx;
  366. {$endif}
  367. end;
  368. old_array_constructor:=allow_array_constructor;
  369. old_get_para_resulttype:=get_para_resulttype;
  370. get_para_resulttype:=true;
  371. allow_array_constructor:=true;
  372. firstpass(left);
  373. get_para_resulttype:=old_get_para_resulttype;
  374. allow_array_constructor:=old_array_constructor;
  375. if left.registers32>registers32 then
  376. registers32:=left.registers32;
  377. if left.registersfpu>registersfpu then
  378. registersfpu:=left.registersfpu;
  379. {$ifdef SUPPORT_MMX}
  380. if left.registersmmx>registersmmx then
  381. registersmmx:=left.registersmmx;
  382. {$endif SUPPORT_MMX}
  383. end;
  384. procedure tcallparanode.firstcallparan(defcoll : tparaitem;do_count : boolean);
  385. begin
  386. if not assigned(left.resulttype.def) then
  387. begin
  388. get_paratype;
  389. if assigned(defcoll) then
  390. insert_typeconv(defcoll,do_count);
  391. end;
  392. det_registers;
  393. end;
  394. procedure tcallparanode.gen_high_tree(openstring:boolean);
  395. var
  396. len : longint;
  397. st : tsymtable;
  398. loadconst : boolean;
  399. srsym : tsym;
  400. begin
  401. if assigned(hightree) then
  402. exit;
  403. len:=-1;
  404. loadconst:=true;
  405. case left.resulttype.def.deftype of
  406. arraydef :
  407. begin
  408. if is_open_array(left.resulttype.def) or
  409. is_array_of_const(left.resulttype.def) then
  410. begin
  411. st:=tloadnode(left).symtable;
  412. srsym:=searchsymonlyin(st,'high'+tvarsym(tloadnode(left).symtableentry).name);
  413. hightree:=cloadnode.create(tvarsym(srsym),st);
  414. loadconst:=false;
  415. end
  416. else
  417. begin
  418. { this is an empty constructor }
  419. len:=tarraydef(left.resulttype.def).highrange-
  420. tarraydef(left.resulttype.def).lowrange;
  421. end;
  422. end;
  423. stringdef :
  424. begin
  425. if openstring then
  426. begin
  427. if is_open_string(left.resulttype.def) then
  428. begin
  429. st:=tloadnode(left).symtable;
  430. srsym:=searchsymonlyin(st,'high'+tvarsym(tloadnode(left).symtableentry).name);
  431. hightree:=cloadnode.create(tvarsym(srsym),st);
  432. loadconst:=false;
  433. end
  434. else
  435. len:=tstringdef(left.resulttype.def).len;
  436. end
  437. else
  438. { passing a string to an array of char }
  439. begin
  440. if (left.nodetype=stringconstn) then
  441. begin
  442. len:=str_length(left);
  443. if len>0 then
  444. dec(len);
  445. end
  446. else
  447. begin
  448. hightree:=caddnode.create(subn,geninlinenode(in_length_x,false,left.getcopy),
  449. cordconstnode.create(1,s32bittype));
  450. firstpass(hightree);
  451. hightree:=ctypeconvnode.create(hightree,s32bittype);
  452. loadconst:=false;
  453. end;
  454. end;
  455. end;
  456. else
  457. len:=0;
  458. end;
  459. if loadconst then
  460. hightree:=cordconstnode.create(len,s32bittype);
  461. firstpass(hightree);
  462. end;
  463. function tcallparanode.docompare(p: tnode): boolean;
  464. begin
  465. docompare :=
  466. inherited docompare(p) and
  467. (callparaflags = tcallparanode(p).callparaflags) and
  468. hightree.isequal(tcallparanode(p).hightree);
  469. end;
  470. {****************************************************************************
  471. TCALLNODE
  472. ****************************************************************************}
  473. constructor tcallnode.create(l:tnode;v : tprocsym;st : tsymtable; mp : tnode);
  474. begin
  475. inherited create(calln,l,nil);
  476. symtableprocentry:=v;
  477. symtableproc:=st;
  478. include(flags,nf_return_value_used);
  479. methodpointer:=mp;
  480. procdefinition:=nil;
  481. end;
  482. {$ifdef hascompilerproc}
  483. constructor tcallnode.createintern(const name: string; params: tnode);
  484. var
  485. srsym: tsym;
  486. begin
  487. srsym := searchsymonlyin(systemunit,name);
  488. if not assigned(srsym) or
  489. (srsym.typ <> procsym) then
  490. internalerror(200107271);
  491. self.create(params,tprocsym(srsym),systemunit,nil);
  492. end;
  493. {$endif hascompilerproc}
  494. destructor tcallnode.destroy;
  495. begin
  496. methodpointer.free;
  497. inherited destroy;
  498. end;
  499. procedure tcallnode.set_procvar(procvar:tnode);
  500. begin
  501. right:=procvar;
  502. end;
  503. function tcallnode.getcopy : tnode;
  504. var
  505. n : tcallnode;
  506. begin
  507. n:=tcallnode(inherited getcopy);
  508. n.symtableprocentry:=symtableprocentry;
  509. n.symtableproc:=symtableproc;
  510. n.procdefinition:=procdefinition;
  511. if assigned(methodpointer) then
  512. n.methodpointer:=methodpointer.getcopy
  513. else
  514. n.methodpointer:=nil;
  515. result:=n;
  516. end;
  517. procedure tcallnode.insertintolist(l : tnodelist);
  518. begin
  519. end;
  520. function tcallnode.det_resulttype:tnode;
  521. type
  522. pprocdefcoll = ^tprocdefcoll;
  523. tprocdefcoll = record
  524. data : tprocdef;
  525. nextpara : tparaitem;
  526. firstpara : tparaitem;
  527. next : pprocdefcoll;
  528. end;
  529. var
  530. hp,procs,hp2 : pprocdefcoll;
  531. pd : tprocdef;
  532. oldcallprocsym : tprocsym;
  533. def_from,def_to,conv_to : tdef;
  534. hpt : tnode;
  535. pt : tcallparanode;
  536. exactmatch : boolean;
  537. paralength,lastpara : longint;
  538. lastparatype : tdef;
  539. pdc : tparaitem;
  540. {$ifdef TEST_PROCSYMS}
  541. nextprocsym : tprocsym;
  542. symt : tsymtable;
  543. {$endif TEST_PROCSYMS}
  544. { only Dummy }
  545. hcvt : tconverttype;
  546. label
  547. errorexit;
  548. { check if the resulttype.def from tree p is equal with def, needed
  549. for stringconstn and formaldef }
  550. function is_equal(p:tcallparanode;def:tdef) : boolean;
  551. begin
  552. { safety check }
  553. if not (assigned(def) or assigned(p.resulttype.def)) then
  554. begin
  555. is_equal:=false;
  556. exit;
  557. end;
  558. { all types can be passed to a formaldef }
  559. is_equal:=(def.deftype=formaldef) or
  560. (types.is_equal(p.resulttype.def,def))
  561. { integer constants are compatible with all integer parameters if
  562. the specified value matches the range }
  563. or
  564. (
  565. (tbinarynode(p).left.nodetype=ordconstn) and
  566. is_integer(p.resulttype.def) and
  567. is_integer(def) and
  568. (tordconstnode(p.left).value>=torddef(def).low) and
  569. (tordconstnode(p.left).value<=torddef(def).high)
  570. )
  571. { to support ansi/long/wide strings in a proper way }
  572. { string and string[10] are assumed as equal }
  573. { when searching the correct overloaded procedure }
  574. or
  575. (
  576. (def.deftype=stringdef) and (p.resulttype.def.deftype=stringdef) and
  577. (tstringdef(def).string_typ=tstringdef(p.resulttype.def).string_typ)
  578. )
  579. or
  580. (
  581. (p.left.nodetype=stringconstn) and
  582. (is_ansistring(p.resulttype.def) and is_pchar(def))
  583. )
  584. or
  585. (
  586. (p.left.nodetype=ordconstn) and
  587. (is_char(p.resulttype.def) and (is_shortstring(def) or is_ansistring(def)))
  588. )
  589. { set can also be a not yet converted array constructor }
  590. or
  591. (
  592. (def.deftype=setdef) and (p.resulttype.def.deftype=arraydef) and
  593. (tarraydef(p.resulttype.def).IsConstructor) and not(tarraydef(p.resulttype.def).IsVariant)
  594. )
  595. { in tp7 mode proc -> procvar is allowed }
  596. or
  597. (
  598. (m_tp_procvar in aktmodeswitches) and
  599. (def.deftype=procvardef) and (p.left.nodetype=calln) and
  600. (proc_to_procvar_equal(tprocdef(tcallnode(p.left).procdefinition),tprocvardef(def)))
  601. )
  602. ;
  603. end;
  604. function is_in_limit(def_from,def_to : tdef) : boolean;
  605. begin
  606. is_in_limit:=(def_from.deftype = orddef) and
  607. (def_to.deftype = orddef) and
  608. (torddef(def_from).low>torddef(def_to).low) and
  609. (torddef(def_from).high<torddef(def_to).high);
  610. end;
  611. var
  612. i : longint;
  613. is_const : boolean;
  614. bestord : torddef;
  615. begin
  616. result:=nil;
  617. procs:=nil;
  618. oldcallprocsym:=aktcallprocsym;
  619. aktcallprocsym:=nil;
  620. { determine length of parameter list }
  621. pt:=tcallparanode(left);
  622. paralength:=0;
  623. while assigned(pt) do
  624. begin
  625. inc(paralength);
  626. pt:=tcallparanode(pt.right);
  627. end;
  628. { determine the type of the parameters }
  629. if assigned(left) then
  630. begin
  631. tcallparanode(left).get_paratype;
  632. if codegenerror then
  633. goto errorexit;
  634. end;
  635. { procedure variable ? }
  636. if assigned(right) then
  637. begin
  638. set_varstate(right,true);
  639. resulttypepass(right);
  640. if codegenerror then
  641. exit;
  642. procdefinition:=tabstractprocdef(right.resulttype.def);
  643. { check the amount of parameters }
  644. pdc:=tparaitem(procdefinition.Para.first);
  645. pt:=tcallparanode(left);
  646. lastpara:=paralength;
  647. while assigned(pdc) and assigned(pt) do
  648. begin
  649. { only goto next para if we're out of the varargs }
  650. if not(po_varargs in procdefinition.procoptions) or
  651. (lastpara<=procdefinition.maxparacount) then
  652. pdc:=tparaitem(pdc.next);
  653. pt:=tcallparanode(pt.right);
  654. dec(lastpara);
  655. end;
  656. if assigned(pt) or assigned(pdc) then
  657. begin
  658. if assigned(pt) then
  659. aktfilepos:=pt.fileinfo;
  660. CGMessage(parser_e_wrong_parameter_size);
  661. end;
  662. end
  663. else
  664. { not a procedure variable }
  665. begin
  666. aktcallprocsym:=tprocsym(symtableprocentry);
  667. { do we know the procedure to call ? }
  668. if not(assigned(procdefinition)) then
  669. begin
  670. {$ifdef TEST_PROCSYMS}
  671. if (unit_specific) or
  672. assigned(methodpointer) then
  673. nextprocsym:=nil
  674. else while not assigned(procs) do
  675. begin
  676. symt:=symtableproc;
  677. srsym:=nil;
  678. while assigned(symt^.next) and not assigned(srsym) do
  679. begin
  680. symt:=symt^.next;
  681. srsym:=searchsymonlyin(symt,actprocsym.name);
  682. if assigned(srsym) then
  683. if srsym.typ<>procsym then
  684. begin
  685. { reject all that is not a procedure }
  686. srsym:=nil;
  687. { don't search elsewhere }
  688. while assigned(symt^.next) do
  689. symt:=symt^.next;
  690. end;
  691. end;
  692. nextprocsym:=srsym;
  693. end;
  694. {$endif TEST_PROCSYMS}
  695. { link all procedures which have the same # of parameters }
  696. pd:=aktcallprocsym.definition;
  697. while assigned(pd) do
  698. begin
  699. { only when the # of parameter are supported by the
  700. procedure }
  701. if (paralength>=pd.minparacount) and
  702. ((po_varargs in pd.procoptions) or { varargs }
  703. (paralength<=pd.maxparacount)) then
  704. begin
  705. new(hp);
  706. hp^.data:=pd;
  707. hp^.next:=procs;
  708. hp^.firstpara:=tparaitem(pd.Para.first);
  709. if not(po_varargs in pd.procoptions) then
  710. begin
  711. { if not all parameters are given, then skip the
  712. default parameters }
  713. for i:=1 to pd.maxparacount-paralength do
  714. hp^.firstpara:=tparaitem(hp^.firstPara.next);
  715. end;
  716. hp^.nextpara:=hp^.firstpara;
  717. procs:=hp;
  718. end;
  719. pd:=pd.nextoverloaded;
  720. end;
  721. { no procedures found? then there is something wrong
  722. with the parameter size }
  723. if not assigned(procs) then
  724. begin
  725. { in tp mode we can try to convert to procvar if
  726. there are no parameters specified }
  727. if not(assigned(left)) and
  728. (m_tp_procvar in aktmodeswitches) then
  729. begin
  730. hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc);
  731. if (symtableprocentry.owner.symtabletype=objectsymtable) and
  732. assigned(methodpointer) then
  733. tloadnode(hpt).set_mp(methodpointer.getcopy);
  734. resulttypepass(hpt);
  735. right:=hpt;
  736. end
  737. else
  738. begin
  739. if assigned(left) then
  740. aktfilepos:=left.fileinfo;
  741. CGMessage(parser_e_wrong_parameter_size);
  742. aktcallprocsym.write_parameter_lists(nil);
  743. end;
  744. goto errorexit;
  745. end;
  746. { now we can compare parameter after parameter }
  747. pt:=tcallparanode(left);
  748. { we start with the last parameter }
  749. lastpara:=paralength+1;
  750. lastparatype:=nil;
  751. while assigned(pt) do
  752. begin
  753. dec(lastpara);
  754. { walk all procedures and determine how this parameter matches and set:
  755. 1. pt.exact_match_found if one parameter has an exact match
  756. 2. exactmatch if an equal or exact match is found
  757. 3. Para.argconvtyp to exact,equal or convertable
  758. (when convertable then also convertlevel is set)
  759. 4. pt.convlevel1found if there is a convertlevel=1
  760. 5. pt.convlevel2found if there is a convertlevel=2
  761. }
  762. exactmatch:=false;
  763. hp:=procs;
  764. while assigned(hp) do
  765. begin
  766. { varargs are always equal, but not exact }
  767. if (po_varargs in hp^.data.procoptions) and
  768. (lastpara>hp^.data.minparacount) then
  769. begin
  770. hp^.nextPara.argconvtyp:=act_equal;
  771. exactmatch:=true;
  772. end
  773. else
  774. begin
  775. if is_equal(pt,hp^.nextPara.paratype.def) then
  776. begin
  777. if hp^.nextPara.paratype.def=pt.resulttype.def then
  778. begin
  779. include(pt.callparaflags,cpf_exact_match_found);
  780. hp^.nextPara.argconvtyp:=act_exact;
  781. end
  782. else
  783. hp^.nextPara.argconvtyp:=act_equal;
  784. exactmatch:=true;
  785. end
  786. else
  787. begin
  788. hp^.nextPara.argconvtyp:=act_convertable;
  789. hp^.nextPara.convertlevel:=isconvertable(pt.resulttype.def,hp^.nextPara.paratype.def,
  790. hcvt,pt.left.nodetype,false);
  791. case hp^.nextPara.convertlevel of
  792. 1 : include(pt.callparaflags,cpf_convlevel1found);
  793. 2 : include(pt.callparaflags,cpf_convlevel2found);
  794. end;
  795. end;
  796. end;
  797. hp:=hp^.next;
  798. end;
  799. { If there was an exactmatch then delete all convertables }
  800. if exactmatch then
  801. begin
  802. hp:=procs;
  803. procs:=nil;
  804. while assigned(hp) do
  805. begin
  806. hp2:=hp^.next;
  807. { keep if not convertable }
  808. if (hp^.nextPara.argconvtyp<>act_convertable) then
  809. begin
  810. hp^.next:=procs;
  811. procs:=hp;
  812. end
  813. else
  814. dispose(hp);
  815. hp:=hp2;
  816. end;
  817. end
  818. else
  819. { No exact match was found, remove all procedures that are
  820. not convertable (convertlevel=0) }
  821. begin
  822. hp:=procs;
  823. procs:=nil;
  824. while assigned(hp) do
  825. begin
  826. hp2:=hp^.next;
  827. { keep if not convertable }
  828. if (hp^.nextPara.convertlevel<>0) then
  829. begin
  830. hp^.next:=procs;
  831. procs:=hp;
  832. end
  833. else
  834. begin
  835. { save the type for nice error message }
  836. lastparatype:=hp^.nextPara.paratype.def;
  837. dispose(hp);
  838. end;
  839. hp:=hp2;
  840. end;
  841. end;
  842. { update nextpara for all procedures }
  843. hp:=procs;
  844. while assigned(hp) do
  845. begin
  846. { only goto next para if we're out of the varargs }
  847. if not(po_varargs in hp^.data.procoptions) or
  848. (lastpara<=hp^.data.maxparacount) then
  849. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  850. hp:=hp^.next;
  851. end;
  852. { load next parameter or quit loop if no procs left }
  853. if assigned(procs) then
  854. pt:=tcallparanode(pt.right)
  855. else
  856. break;
  857. end;
  858. { All parameters are checked, check if there are any
  859. procedures left }
  860. if not assigned(procs) then
  861. begin
  862. { there is an error, must be wrong type, because
  863. wrong size is already checked (PFV) }
  864. if (not assigned(lastparatype)) or
  865. (not assigned(pt)) or
  866. (not assigned(pt.resulttype.def)) then
  867. internalerror(39393)
  868. else
  869. begin
  870. aktfilepos:=pt.fileinfo;
  871. CGMessage3(type_e_wrong_parameter_type,tostr(lastpara),
  872. pt.resulttype.def.typename,lastparatype.typename);
  873. end;
  874. aktcallprocsym.write_parameter_lists(nil);
  875. goto errorexit;
  876. end;
  877. { if there are several choices left then for orddef }
  878. { if a type is totally included in the other }
  879. { we don't fear an overflow , }
  880. { so we can do as if it is an exact match }
  881. { this will convert integer to longint }
  882. { rather than to words }
  883. { conversion of byte to integer or longint }
  884. {would still not be solved }
  885. if assigned(procs) and assigned(procs^.next) then
  886. begin
  887. hp:=procs;
  888. while assigned(hp) do
  889. begin
  890. hp^.nextpara:=hp^.firstpara;
  891. hp:=hp^.next;
  892. end;
  893. pt:=tcallparanode(left);
  894. while assigned(pt) do
  895. begin
  896. { matches a parameter of one procedure exact ? }
  897. exactmatch:=false;
  898. def_from:=pt.resulttype.def;
  899. hp:=procs;
  900. while assigned(hp) do
  901. begin
  902. if not is_equal(pt,hp^.nextPara.paratype.def) then
  903. begin
  904. def_to:=hp^.nextPara.paratype.def;
  905. if ((def_from.deftype=orddef) and (def_to.deftype=orddef)) and
  906. (is_in_limit(def_from,def_to) or
  907. ((hp^.nextPara.paratyp in [vs_var,vs_out]) and
  908. (def_from.size=def_to.size))) then
  909. begin
  910. exactmatch:=true;
  911. conv_to:=def_to;
  912. end;
  913. end;
  914. hp:=hp^.next;
  915. end;
  916. { .... if yes, del all the other procedures }
  917. if exactmatch then
  918. begin
  919. { the first .... }
  920. while (assigned(procs)) and not(is_in_limit(def_from,procs^.nextPara.paratype.def)) do
  921. begin
  922. hp:=procs^.next;
  923. dispose(procs);
  924. procs:=hp;
  925. end;
  926. { and the others }
  927. hp:=procs;
  928. while (assigned(hp)) and assigned(hp^.next) do
  929. begin
  930. if not(is_in_limit(def_from,hp^.next^.nextPara.paratype.def)) then
  931. begin
  932. hp2:=hp^.next^.next;
  933. dispose(hp^.next);
  934. hp^.next:=hp2;
  935. end
  936. else
  937. begin
  938. def_to:=hp^.next^.nextPara.paratype.def;
  939. if (conv_to.size>def_to.size) or
  940. ((torddef(conv_to).low<torddef(def_to).low) and
  941. (torddef(conv_to).high>torddef(def_to).high)) then
  942. begin
  943. hp2:=procs;
  944. procs:=hp;
  945. conv_to:=def_to;
  946. dispose(hp2);
  947. end
  948. else
  949. hp:=hp^.next;
  950. end;
  951. end;
  952. end;
  953. { update nextpara for all procedures }
  954. hp:=procs;
  955. while assigned(hp) do
  956. begin
  957. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  958. hp:=hp^.next;
  959. end;
  960. pt:=tcallparanode(pt.right);
  961. end;
  962. end;
  963. { let's try to eliminate equal if there is an exact match
  964. is there }
  965. if assigned(procs) and assigned(procs^.next) then
  966. begin
  967. { reset nextpara for all procs left }
  968. hp:=procs;
  969. while assigned(hp) do
  970. begin
  971. hp^.nextpara:=hp^.firstpara;
  972. hp:=hp^.next;
  973. end;
  974. pt:=tcallparanode(left);
  975. while assigned(pt) do
  976. begin
  977. if cpf_exact_match_found in pt.callparaflags then
  978. begin
  979. hp:=procs;
  980. procs:=nil;
  981. while assigned(hp) do
  982. begin
  983. hp2:=hp^.next;
  984. { keep the exact matches, dispose the others }
  985. if (hp^.nextPara.argconvtyp=act_exact) then
  986. begin
  987. hp^.next:=procs;
  988. procs:=hp;
  989. end
  990. else
  991. dispose(hp);
  992. hp:=hp2;
  993. end;
  994. end;
  995. { update nextpara for all procedures }
  996. hp:=procs;
  997. while assigned(hp) do
  998. begin
  999. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1000. hp:=hp^.next;
  1001. end;
  1002. pt:=tcallparanode(pt.right);
  1003. end;
  1004. end;
  1005. { Check if there are integer constant to integer
  1006. parameters then choose the best matching integer
  1007. parameter and remove the others, this is Delphi
  1008. compatible. 1 = byte, 256 = word, etc. }
  1009. if assigned(procs) and assigned(procs^.next) then
  1010. begin
  1011. { reset nextpara for all procs left }
  1012. hp:=procs;
  1013. while assigned(hp) do
  1014. begin
  1015. hp^.nextpara:=hp^.firstpara;
  1016. hp:=hp^.next;
  1017. end;
  1018. pt:=tcallparanode(left);
  1019. while assigned(pt) do
  1020. begin
  1021. bestord:=nil;
  1022. if (pt.left.nodetype=ordconstn) and
  1023. is_integer(pt.resulttype.def) then
  1024. begin
  1025. hp:=procs;
  1026. while assigned(hp) do
  1027. begin
  1028. def_to:=hp^.nextPara.paratype.def;
  1029. { to be sure, it couldn't be something else,
  1030. also the defs here are all in the range
  1031. so now find the closest range }
  1032. if not is_integer(def_to) then
  1033. internalerror(43297815);
  1034. if (not assigned(bestord)) or
  1035. ((torddef(def_to).low>bestord.low) or
  1036. (torddef(def_to).high<bestord.high)) then
  1037. bestord:=torddef(def_to);
  1038. hp:=hp^.next;
  1039. end;
  1040. end;
  1041. { if a bestmatch is found then remove the other
  1042. procs which don't match the bestord }
  1043. if assigned(bestord) then
  1044. begin
  1045. hp:=procs;
  1046. procs:=nil;
  1047. while assigned(hp) do
  1048. begin
  1049. hp2:=hp^.next;
  1050. { keep matching bestord, dispose the others }
  1051. if (torddef(hp^.nextPara.paratype.def)=bestord) then
  1052. begin
  1053. hp^.next:=procs;
  1054. procs:=hp;
  1055. end
  1056. else
  1057. dispose(hp);
  1058. hp:=hp2;
  1059. end;
  1060. end;
  1061. { update nextpara for all procedures }
  1062. hp:=procs;
  1063. while assigned(hp) do
  1064. begin
  1065. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1066. hp:=hp^.next;
  1067. end;
  1068. pt:=tcallparanode(pt.right);
  1069. end;
  1070. end;
  1071. { Check if there are convertlevel 1 and 2 differences
  1072. left for the parameters, then discard all convertlevel
  1073. 2 procedures. The value of convlevelXfound can still
  1074. be used, because all convertables are still here or
  1075. not }
  1076. if assigned(procs) and assigned(procs^.next) then
  1077. begin
  1078. { reset nextpara for all procs left }
  1079. hp:=procs;
  1080. while assigned(hp) do
  1081. begin
  1082. hp^.nextpara:=hp^.firstpara;
  1083. hp:=hp^.next;
  1084. end;
  1085. pt:=tcallparanode(left);
  1086. while assigned(pt) do
  1087. begin
  1088. if (cpf_convlevel1found in pt.callparaflags) and
  1089. (cpf_convlevel2found in pt.callparaflags) then
  1090. begin
  1091. hp:=procs;
  1092. procs:=nil;
  1093. while assigned(hp) do
  1094. begin
  1095. hp2:=hp^.next;
  1096. { keep all not act_convertable and all convertlevels=1 }
  1097. if (hp^.nextPara.argconvtyp<>act_convertable) or
  1098. (hp^.nextPara.convertlevel=1) then
  1099. begin
  1100. hp^.next:=procs;
  1101. procs:=hp;
  1102. end
  1103. else
  1104. dispose(hp);
  1105. hp:=hp2;
  1106. end;
  1107. end;
  1108. { update nextpara for all procedures }
  1109. hp:=procs;
  1110. while assigned(hp) do
  1111. begin
  1112. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1113. hp:=hp^.next;
  1114. end;
  1115. pt:=tcallparanode(pt.right);
  1116. end;
  1117. end;
  1118. if not(assigned(procs)) or assigned(procs^.next) then
  1119. begin
  1120. CGMessage(cg_e_cant_choose_overload_function);
  1121. aktcallprocsym.write_parameter_lists(nil);
  1122. goto errorexit;
  1123. end;
  1124. {$ifdef TEST_PROCSYMS}
  1125. if (procs=nil) and assigned(nextprocsym) then
  1126. begin
  1127. symtableprocentry:=nextprocsym;
  1128. symtableproc:=symt;
  1129. end;
  1130. end ; { of while assigned(symtableprocentry) do }
  1131. {$endif TEST_PROCSYMS}
  1132. if make_ref then
  1133. begin
  1134. procs^.data.lastref:=tref.create(procs^.data.lastref,@fileinfo);
  1135. inc(procs^.data.refcount);
  1136. if procs^.data.defref=nil then
  1137. procs^.data.defref:=procs^.data.lastref;
  1138. end;
  1139. procdefinition:=procs^.data;
  1140. { big error for with statements
  1141. symtableproc:=procdefinition.owner;
  1142. but neede for overloaded operators !! }
  1143. if symtableproc=nil then
  1144. symtableproc:=procdefinition.owner;
  1145. {$ifdef CHAINPROCSYMS}
  1146. { object with method read;
  1147. call to read(x) will be a usual procedure call }
  1148. if assigned(methodpointer) and
  1149. (procdefinition._class=nil) then
  1150. begin
  1151. { not ok for extended }
  1152. case methodpointer^.nodetype of
  1153. typen,hnewn : fatalerror(no_para_match);
  1154. end;
  1155. methodpointer.free;
  1156. methodpointer:=nil;
  1157. end;
  1158. {$endif CHAINPROCSYMS}
  1159. end; { end of procedure to call determination }
  1160. { add needed default parameters }
  1161. if assigned(procs) and
  1162. (paralength<procdefinition.maxparacount) then
  1163. begin
  1164. { add default parameters, just read back the skipped
  1165. paras starting from firstPara.previous, when not available
  1166. (all parameters are default) then start with the last
  1167. parameter and read backward (PFV) }
  1168. if not assigned(procs^.firstpara) then
  1169. pdc:=tparaitem(procs^.data.Para.last)
  1170. else
  1171. pdc:=tparaitem(procs^.firstPara.previous);
  1172. while assigned(pdc) do
  1173. begin
  1174. if not assigned(pdc.defaultvalue) then
  1175. internalerror(751349858);
  1176. left:=ccallparanode.create(genconstsymtree(tconstsym(pdc.defaultvalue)),left);
  1177. pdc:=tparaitem(pdc.previous);
  1178. end;
  1179. end;
  1180. end;
  1181. { handle predefined procedures }
  1182. is_const:=(pocall_internconst in procdefinition.proccalloptions) and
  1183. ((block_type in [bt_const,bt_type]) or
  1184. (assigned(left) and (tcallparanode(left).left.nodetype in [realconstn,ordconstn])));
  1185. if (pocall_internproc in procdefinition.proccalloptions) or is_const then
  1186. begin
  1187. if assigned(left) then
  1188. begin
  1189. { ptr and settextbuf needs two args }
  1190. if assigned(tcallparanode(left).right) then
  1191. begin
  1192. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,left);
  1193. left:=nil;
  1194. end
  1195. else
  1196. begin
  1197. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,tcallparanode(left).left);
  1198. tcallparanode(left).left:=nil;
  1199. end;
  1200. end
  1201. else
  1202. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,nil);
  1203. resulttypepass(hpt);
  1204. result:=hpt;
  1205. goto errorexit;
  1206. end;
  1207. { Calling a message method directly ? }
  1208. if assigned(procdefinition) and
  1209. (po_containsself in procdefinition.procoptions) then
  1210. message(cg_e_cannot_call_message_direct);
  1211. { ensure that the result type is set }
  1212. resulttype:=procdefinition.rettype;
  1213. { get a register for the return value }
  1214. if (not is_void(resulttype.def)) then
  1215. begin
  1216. if ret_in_acc(resulttype.def) then
  1217. begin
  1218. { wide- and ansistrings are returned in EAX }
  1219. { but they are imm. moved to a memory location }
  1220. if is_widestring(resulttype.def) or
  1221. is_ansistring(resulttype.def) then
  1222. begin
  1223. { we use ansistrings so no fast exit here }
  1224. procinfo^.no_fast_exit:=true;
  1225. end;
  1226. end;
  1227. end;
  1228. { constructors return their current class type, not the type where the
  1229. constructor is declared, this can be different because of inheritance }
  1230. if (procdefinition.proctypeoption=potype_constructor) then
  1231. begin
  1232. if assigned(methodpointer) and
  1233. assigned(methodpointer.resulttype.def) and
  1234. (methodpointer.resulttype.def.deftype=classrefdef) then
  1235. resulttype:=tclassrefdef(methodpointer.resulttype.def).pointertype;
  1236. end;
  1237. { flag all callparanodes that belong to the varargs }
  1238. if (po_varargs in procdefinition.procoptions) then
  1239. begin
  1240. pt:=tcallparanode(left);
  1241. i:=paralength;
  1242. while (i>procdefinition.maxparacount) do
  1243. begin
  1244. include(tcallparanode(pt).flags,nf_varargs_para);
  1245. pt:=tcallparanode(pt.right);
  1246. dec(i);
  1247. end;
  1248. end;
  1249. { insert type conversions }
  1250. if assigned(left) then
  1251. tcallparanode(left).insert_typeconv(tparaitem(procdefinition.Para.first),true);
  1252. errorexit:
  1253. { Reset some settings back }
  1254. if assigned(procs) then
  1255. dispose(procs);
  1256. aktcallprocsym:=oldcallprocsym;
  1257. end;
  1258. function tcallnode.pass_1 : tnode;
  1259. var
  1260. inlinecode : tnode;
  1261. inlined : boolean;
  1262. {$ifdef m68k}
  1263. regi : tregister;
  1264. {$endif}
  1265. method_must_be_valid : boolean;
  1266. label
  1267. errorexit;
  1268. begin
  1269. result:=nil;
  1270. inlined:=false;
  1271. { work trough all parameters to get the register requirements }
  1272. if assigned(left) then
  1273. tcallparanode(left).det_registers;
  1274. if assigned(procdefinition) and
  1275. (pocall_inline in procdefinition.proccalloptions) then
  1276. begin
  1277. inlinecode:=right;
  1278. if assigned(inlinecode) then
  1279. begin
  1280. inlined:=true;
  1281. exclude(procdefinition.proccalloptions,pocall_inline);
  1282. end;
  1283. right:=nil;
  1284. end;
  1285. { procedure variable ? }
  1286. if assigned(right) then
  1287. begin
  1288. firstpass(right);
  1289. { procedure does a call }
  1290. if not (block_type in [bt_const,bt_type]) then
  1291. procinfo^.flags:=procinfo^.flags or pi_do_call;
  1292. {$ifndef newcg}
  1293. { calc the correct value for the register }
  1294. {$ifdef i386}
  1295. incrementregisterpushed($ff);
  1296. {$else}
  1297. incrementregisterpushed(ALL_REGISTERS);
  1298. {$endif}
  1299. {$endif newcg}
  1300. end
  1301. else
  1302. { not a procedure variable }
  1303. begin
  1304. location.loc:=LOC_MEM;
  1305. { calc the correture value for the register }
  1306. { handle predefined procedures }
  1307. if (pocall_inline in procdefinition.proccalloptions) then
  1308. begin
  1309. if assigned(methodpointer) then
  1310. CGMessage(cg_e_unable_inline_object_methods);
  1311. if assigned(right) and (right.nodetype<>procinlinen) then
  1312. CGMessage(cg_e_unable_inline_procvar);
  1313. { nodetype:=procinlinen; }
  1314. if not assigned(right) then
  1315. begin
  1316. if assigned(tprocdef(procdefinition).code) then
  1317. inlinecode:=cprocinlinenode.create(self,tnode(tprocdef(procdefinition).code))
  1318. else
  1319. CGMessage(cg_e_no_code_for_inline_stored);
  1320. if assigned(inlinecode) then
  1321. begin
  1322. { consider it has not inlined if called
  1323. again inside the args }
  1324. exclude(procdefinition.proccalloptions,pocall_inline);
  1325. firstpass(inlinecode);
  1326. inlined:=true;
  1327. end;
  1328. end;
  1329. end
  1330. else
  1331. begin
  1332. if not (block_type in [bt_const,bt_type]) then
  1333. procinfo^.flags:=procinfo^.flags or pi_do_call;
  1334. end;
  1335. {$ifndef newcg}
  1336. incrementregisterpushed(tprocdef(procdefinition).usedregisters);
  1337. {$endif newcg}
  1338. end;
  1339. { get a register for the return value }
  1340. if (not is_void(resulttype.def)) then
  1341. begin
  1342. if (procdefinition.proctypeoption=potype_constructor) then
  1343. begin
  1344. { extra handling of classes }
  1345. { methodpointer should be assigned! }
  1346. if assigned(methodpointer) and
  1347. assigned(methodpointer.resulttype.def) and
  1348. (methodpointer.resulttype.def.deftype=classrefdef) then
  1349. begin
  1350. location.loc:=LOC_REGISTER;
  1351. registers32:=1;
  1352. end
  1353. { a object constructor returns the result with the flags }
  1354. else
  1355. location.loc:=LOC_FLAGS;
  1356. end
  1357. else
  1358. begin
  1359. {$ifdef SUPPORT_MMX}
  1360. if (cs_mmx in aktlocalswitches) and
  1361. is_mmx_able_array(resulttype.def) then
  1362. begin
  1363. location.loc:=LOC_MMXREGISTER;
  1364. registersmmx:=1;
  1365. end
  1366. else
  1367. {$endif SUPPORT_MMX}
  1368. if ret_in_acc(resulttype.def) then
  1369. begin
  1370. location.loc:=LOC_REGISTER;
  1371. if is_64bitint(resulttype.def) then
  1372. registers32:=2
  1373. else
  1374. registers32:=1;
  1375. { wide- and ansistrings are returned in EAX }
  1376. { but they are imm. moved to a memory location }
  1377. if is_widestring(resulttype.def) or
  1378. is_ansistring(resulttype.def) then
  1379. begin
  1380. location.loc:=LOC_MEM;
  1381. registers32:=1;
  1382. end;
  1383. end
  1384. else if (resulttype.def.deftype=floatdef) then
  1385. begin
  1386. location.loc:=LOC_FPU;
  1387. {$ifdef m68k}
  1388. if (cs_fp_emulation in aktmoduleswitches) or
  1389. (tfloatdef(resulttype.def).typ=s32real) then
  1390. registers32:=1
  1391. else
  1392. registersfpu:=1;
  1393. {$else not m68k}
  1394. registersfpu:=1;
  1395. {$endif not m68k}
  1396. end
  1397. else
  1398. location.loc:=LOC_MEM;
  1399. end;
  1400. end;
  1401. { a fpu can be used in any procedure !! }
  1402. registersfpu:=procdefinition.fpu_used;
  1403. { if this is a call to a method calc the registers }
  1404. if (methodpointer<>nil) then
  1405. begin
  1406. case methodpointer.nodetype of
  1407. { but only, if this is not a supporting node }
  1408. typen: ;
  1409. { we need one register for new return value PM }
  1410. hnewn : if registers32=0 then
  1411. registers32:=1;
  1412. else
  1413. begin
  1414. if (procdefinition.proctypeoption in [potype_constructor,potype_destructor]) and
  1415. assigned(symtableproc) and (symtableproc.symtabletype=withsymtable) and
  1416. not twithsymtable(symtableproc).direct_with then
  1417. begin
  1418. CGmessage(cg_e_cannot_call_cons_dest_inside_with);
  1419. end; { Is accepted by Delphi !! }
  1420. { this is not a good reason to accept it in FPC if we produce
  1421. wrong code for it !!! (PM) }
  1422. { R.Assign is not a constructor !!! }
  1423. { but for R^.Assign, R must be valid !! }
  1424. if (procdefinition.proctypeoption=potype_constructor) or
  1425. ((methodpointer.nodetype=loadn) and
  1426. (not(oo_has_virtual in tobjectdef(methodpointer.resulttype.def).objectoptions))) then
  1427. method_must_be_valid:=false
  1428. else
  1429. method_must_be_valid:=true;
  1430. firstpass(methodpointer);
  1431. set_varstate(methodpointer,method_must_be_valid);
  1432. { The object is already used ven if it is called once }
  1433. if (methodpointer.nodetype=loadn) and
  1434. (tloadnode(methodpointer).symtableentry.typ=varsym) then
  1435. tvarsym(tloadnode(methodpointer).symtableentry).varstate:=vs_used;
  1436. registersfpu:=max(methodpointer.registersfpu,registersfpu);
  1437. registers32:=max(methodpointer.registers32,registers32);
  1438. {$ifdef SUPPORT_MMX}
  1439. registersmmx:=max(methodpointer.registersmmx,registersmmx);
  1440. {$endif SUPPORT_MMX}
  1441. end;
  1442. end;
  1443. end;
  1444. if inlined then
  1445. right:=inlinecode;
  1446. { determine the registers of the procedure variable }
  1447. { is this OK for inlined procs also ?? (PM) }
  1448. if assigned(right) then
  1449. begin
  1450. registersfpu:=max(right.registersfpu,registersfpu);
  1451. registers32:=max(right.registers32,registers32);
  1452. {$ifdef SUPPORT_MMX}
  1453. registersmmx:=max(right.registersmmx,registersmmx);
  1454. {$endif SUPPORT_MMX}
  1455. end;
  1456. { determine the registers of the procedure }
  1457. if assigned(left) then
  1458. begin
  1459. registersfpu:=max(left.registersfpu,registersfpu);
  1460. registers32:=max(left.registers32,registers32);
  1461. {$ifdef SUPPORT_MMX}
  1462. registersmmx:=max(left.registersmmx,registersmmx);
  1463. {$endif SUPPORT_MMX}
  1464. end;
  1465. errorexit:
  1466. if inlined then
  1467. include(procdefinition.proccalloptions,pocall_inline);
  1468. end;
  1469. function tcallnode.docompare(p: tnode): boolean;
  1470. begin
  1471. docompare :=
  1472. inherited docompare(p) and
  1473. (symtableprocentry = tcallnode(p).symtableprocentry) and
  1474. (symtableproc = tcallnode(p).symtableproc) and
  1475. (procdefinition = tcallnode(p).procdefinition) and
  1476. (methodpointer = tcallnode(p).methodpointer);
  1477. end;
  1478. {****************************************************************************
  1479. TPROCINLINENODE
  1480. ****************************************************************************}
  1481. constructor tprocinlinenode.create(callp,code : tnode);
  1482. begin
  1483. inherited create(procinlinen);
  1484. inlineprocsym:=tcallnode(callp).symtableprocentry;
  1485. retoffset:=-target_info.size_of_pointer; { less dangerous as zero (PM) }
  1486. para_offset:=0;
  1487. para_size:=inlineprocsym.definition.para_size(target_info.alignment.paraalign);
  1488. if ret_in_param(inlineprocsym.definition.rettype.def) then
  1489. inc(para_size,target_info.size_of_pointer);
  1490. { copy args }
  1491. if assigned(code) then
  1492. inlinetree:=code.getcopy
  1493. else inlinetree := nil;
  1494. registers32:=code.registers32;
  1495. registersfpu:=code.registersfpu;
  1496. {$ifdef SUPPORT_MMX}
  1497. registersmmx:=code.registersmmx;
  1498. {$endif SUPPORT_MMX}
  1499. resulttype:=inlineprocsym.definition.rettype;
  1500. end;
  1501. destructor tprocinlinenode.destroy;
  1502. begin
  1503. if assigned(inlinetree) then
  1504. inlinetree.free;
  1505. inherited destroy;
  1506. end;
  1507. function tprocinlinenode.getcopy : tnode;
  1508. var
  1509. n : tprocinlinenode;
  1510. begin
  1511. n:=tprocinlinenode(inherited getcopy);
  1512. if assigned(inlinetree) then
  1513. n.inlinetree:=inlinetree.getcopy
  1514. else
  1515. n.inlinetree:=nil;
  1516. n.inlineprocsym:=inlineprocsym;
  1517. n.retoffset:=retoffset;
  1518. n.para_offset:=para_offset;
  1519. n.para_size:=para_size;
  1520. getcopy:=n;
  1521. end;
  1522. procedure tprocinlinenode.insertintolist(l : tnodelist);
  1523. begin
  1524. end;
  1525. function tprocinlinenode.pass_1 : tnode;
  1526. begin
  1527. result:=nil;
  1528. { left contains the code in tree form }
  1529. { but it has already been firstpassed }
  1530. { so firstpass(left); does not seem required }
  1531. { might be required later if we change the arg handling !! }
  1532. end;
  1533. function tprocinlinenode.docompare(p: tnode): boolean;
  1534. begin
  1535. docompare :=
  1536. inherited docompare(p) and
  1537. inlinetree.isequal(tprocinlinenode(p).inlinetree) and
  1538. (inlineprocsym = tprocinlinenode(p).inlineprocsym);
  1539. end;
  1540. begin
  1541. ccallnode:=tcallnode;
  1542. ccallparanode:=tcallparanode;
  1543. cprocinlinenode:=tprocinlinenode;
  1544. end.
  1545. {
  1546. $Log$
  1547. Revision 1.40 2001-08-06 21:40:46 peter
  1548. * funcret moved from tprocinfo to tprocdef
  1549. Revision 1.39 2001/08/01 15:07:29 jonas
  1550. + "compilerproc" directive support, which turns both the public and mangled
  1551. name to lowercase(declaration_name). This prevents a normal user from
  1552. accessing the routine, but they can still be easily looked up within
  1553. the compiler. This is used for helper procedures and should facilitate
  1554. the writing of more processor independent code in the code generator
  1555. itself (mostly written by Peter)
  1556. + new "createintern" constructor for tcal nodes to create a call to
  1557. helper exported using the "compilerproc" directive
  1558. + support for high(dynamic_array) using the the above new things
  1559. + definition of 'HASCOMPILERPROC' symbol (to be able to check in the
  1560. compiler and rtl whether the "compilerproc" directive is supported)
  1561. Revision 1.38 2001/07/30 20:52:25 peter
  1562. * fixed array constructor passing with type conversions
  1563. Revision 1.37 2001/07/09 21:15:40 peter
  1564. * Length made internal
  1565. * Add array support for Length
  1566. Revision 1.36 2001/07/01 20:16:15 peter
  1567. * alignmentinfo record added
  1568. * -Oa argument supports more alignment settings that can be specified
  1569. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  1570. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  1571. required alignment and the maximum usefull alignment. The final
  1572. alignment will be choosen per variable size dependent on these
  1573. settings
  1574. Revision 1.35 2001/06/04 18:08:19 peter
  1575. * procvar support for varargs
  1576. Revision 1.34 2001/06/04 11:48:02 peter
  1577. * better const to var checking
  1578. Revision 1.33 2001/05/20 12:09:31 peter
  1579. * fixed exit with ansistring return from function call, no_fast_exit
  1580. should be set in det_resulttype instead of pass_1
  1581. Revision 1.32 2001/04/26 21:55:05 peter
  1582. * defcoll must be assigned in insert_typeconv
  1583. Revision 1.31 2001/04/21 12:03:11 peter
  1584. * m68k updates merged from fixes branch
  1585. Revision 1.30 2001/04/18 22:01:54 peter
  1586. * registration of targets and assemblers
  1587. Revision 1.29 2001/04/13 23:52:29 peter
  1588. * don't allow passing signed-unsigned ords to var parameter, this
  1589. forbids smallint-word, shortint-byte, longint-cardinal mixtures.
  1590. It's still allowed in tp7 -So mode.
  1591. Revision 1.28 2001/04/13 22:22:59 peter
  1592. * call set_varstate for procvar calls
  1593. Revision 1.27 2001/04/13 01:22:08 peter
  1594. * symtable change to classes
  1595. * range check generation and errors fixed, make cycle DEBUG=1 works
  1596. * memory leaks fixed
  1597. Revision 1.26 2001/04/04 22:42:39 peter
  1598. * move constant folding into det_resulttype
  1599. Revision 1.25 2001/04/02 21:20:30 peter
  1600. * resulttype rewrite
  1601. Revision 1.24 2001/03/12 12:47:46 michael
  1602. + Patches from peter
  1603. Revision 1.23 2001/02/26 19:44:52 peter
  1604. * merged generic m68k updates from fixes branch
  1605. Revision 1.22 2001/01/08 21:46:46 peter
  1606. * don't push high value for open array with cdecl;external;
  1607. Revision 1.21 2000/12/31 11:14:10 jonas
  1608. + implemented/fixed docompare() mathods for all nodes (not tested)
  1609. + nopt.pas, nadd.pas, i386/n386opt.pas: optimized nodes for adding strings
  1610. and constant strings/chars together
  1611. * n386add.pas: don't copy temp strings (of size 256) to another temp string
  1612. when adding
  1613. Revision 1.20 2000/12/25 00:07:26 peter
  1614. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  1615. tlinkedlist objects)
  1616. Revision 1.19 2000/12/17 14:35:12 peter
  1617. * fixed crash with procvar load in tp mode
  1618. Revision 1.18 2000/11/29 00:30:32 florian
  1619. * unused units removed from uses clause
  1620. * some changes for widestrings
  1621. Revision 1.17 2000/11/22 15:12:06 jonas
  1622. * fixed inline-related problems (partially "merges")
  1623. Revision 1.16 2000/11/11 16:14:52 peter
  1624. * fixed crash with settextbuf,ptr
  1625. Revision 1.15 2000/11/06 21:36:25 peter
  1626. * fixed var parameter varstate bug
  1627. Revision 1.14 2000/11/04 14:25:20 florian
  1628. + merged Attila's changes for interfaces, not tested yet
  1629. Revision 1.13 2000/10/31 22:02:47 peter
  1630. * symtable splitted, no real code changes
  1631. Revision 1.12 2000/10/21 18:16:11 florian
  1632. * a lot of changes:
  1633. - basic dyn. array support
  1634. - basic C++ support
  1635. - some work for interfaces done
  1636. ....
  1637. Revision 1.11 2000/10/21 14:35:27 peter
  1638. * readd to many remove p. for tcallnode.is_equal()
  1639. Revision 1.10 2000/10/14 21:52:55 peter
  1640. * fixed memory leaks
  1641. Revision 1.9 2000/10/14 10:14:50 peter
  1642. * moehrendorf oct 2000 rewrite
  1643. Revision 1.8 2000/10/01 19:48:24 peter
  1644. * lot of compile updates for cg11
  1645. Revision 1.7 2000/09/28 19:49:52 florian
  1646. *** empty log message ***
  1647. Revision 1.6 2000/09/27 18:14:31 florian
  1648. * fixed a lot of syntax errors in the n*.pas stuff
  1649. Revision 1.5 2000/09/24 21:15:34 florian
  1650. * some errors fix to get more stuff compilable
  1651. Revision 1.4 2000/09/24 20:17:44 florian
  1652. * more conversion work done
  1653. Revision 1.3 2000/09/24 15:06:19 peter
  1654. * use defines.inc
  1655. Revision 1.2 2000/09/20 21:52:38 florian
  1656. * removed a lot of errors
  1657. Revision 1.1 2000/09/20 20:52:16 florian
  1658. * initial revision
  1659. }