2
0

ncal.pas 74 KB

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