ncal.pas 75 KB

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