ncal.pas 75 KB

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