ncal.pas 71 KB

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