ncal.pas 76 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968
  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. inlineprocsym : tprocsym;
  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(aktcallprocsym) and
  233. (aktcallprocsym.definition.proccalloption in [pocall_cppdecl,pocall_cdecl]) and
  234. (po_external in aktcallprocsym.definition.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(aktcallprocsym) and
  252. (aktcallprocsym.definition.proccalloption in [pocall_cppdecl,pocall_cdecl]) and
  253. (po_external in aktcallprocsym.definition.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.definition.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 : tprocdef;
  581. oldcallprocsym : tprocsym;
  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)))
  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. oldcallprocsym:=aktcallprocsym;
  668. aktcallprocsym:=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. aktcallprocsym:=tprocsym(symtableprocentry);
  716. { do we know the procedure to call ? }
  717. if not(assigned(procdefinition)) then
  718. begin
  719. {$ifdef TEST_PROCSYMS}
  720. if (unit_specific) or
  721. assigned(methodpointer) then
  722. nextprocsym:=nil
  723. else while not assigned(procs) do
  724. begin
  725. symt:=symtableproc;
  726. srsym:=nil;
  727. while assigned(symt^.next) and not assigned(srsym) do
  728. begin
  729. symt:=symt^.next;
  730. srsym:=searchsymonlyin(symt,actprocsym.name);
  731. if assigned(srsym) then
  732. if srsym.typ<>procsym then
  733. begin
  734. { reject all that is not a procedure }
  735. srsym:=nil;
  736. { don't search elsewhere }
  737. while assigned(symt^.next) do
  738. symt:=symt^.next;
  739. end;
  740. end;
  741. nextprocsym:=srsym;
  742. end;
  743. {$endif TEST_PROCSYMS}
  744. { link all procedures which have the same # of parameters }
  745. pd:=aktcallprocsym.definition;
  746. while assigned(pd) do
  747. begin
  748. { only when the # of parameter are supported by the
  749. procedure }
  750. if (paralength>=pd.minparacount) and
  751. ((po_varargs in pd.procoptions) or { varargs }
  752. (paralength<=pd.maxparacount)) then
  753. begin
  754. new(hp);
  755. hp^.data:=pd;
  756. hp^.next:=procs;
  757. hp^.firstpara:=tparaitem(pd.Para.first);
  758. if not(po_varargs in pd.procoptions) then
  759. begin
  760. { if not all parameters are given, then skip the
  761. default parameters }
  762. for i:=1 to pd.maxparacount-paralength do
  763. hp^.firstpara:=tparaitem(hp^.firstPara.next);
  764. end;
  765. hp^.nextpara:=hp^.firstpara;
  766. procs:=hp;
  767. end;
  768. pd:=pd.nextoverloaded;
  769. end;
  770. { no procedures found? then there is something wrong
  771. with the parameter size }
  772. if not assigned(procs) then
  773. begin
  774. { in tp mode we can try to convert to procvar if
  775. there are no parameters specified }
  776. if not(assigned(left)) and
  777. (m_tp_procvar in aktmodeswitches) then
  778. begin
  779. hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc);
  780. if (symtableprocentry.owner.symtabletype=objectsymtable) and
  781. assigned(methodpointer) then
  782. tloadnode(hpt).set_mp(methodpointer.getcopy);
  783. resulttypepass(hpt);
  784. result:=hpt;
  785. end
  786. else
  787. begin
  788. if assigned(left) then
  789. aktfilepos:=left.fileinfo;
  790. CGMessage(parser_e_wrong_parameter_size);
  791. aktcallprocsym.write_parameter_lists(nil);
  792. end;
  793. goto errorexit;
  794. end;
  795. { now we can compare parameter after parameter }
  796. pt:=tcallparanode(left);
  797. { we start with the last parameter }
  798. lastpara:=paralength+1;
  799. lastparatype:=nil;
  800. while assigned(pt) do
  801. begin
  802. dec(lastpara);
  803. { walk all procedures and determine how this parameter matches and set:
  804. 1. pt.exact_match_found if one parameter has an exact match
  805. 2. exactmatch if an equal or exact match is found
  806. 3. Para.argconvtyp to exact,equal or convertable
  807. (when convertable then also convertlevel is set)
  808. 4. pt.convlevel1found if there is a convertlevel=1
  809. 5. pt.convlevel2found if there is a convertlevel=2
  810. }
  811. exactmatch:=false;
  812. hp:=procs;
  813. while assigned(hp) do
  814. begin
  815. { varargs are always equal, but not exact }
  816. if (po_varargs in hp^.data.procoptions) and
  817. (lastpara>hp^.data.minparacount) then
  818. begin
  819. hp^.nextPara.argconvtyp:=act_equal;
  820. exactmatch:=true;
  821. end
  822. else
  823. begin
  824. if is_equal(pt,hp^.nextPara.paratype.def) then
  825. begin
  826. if hp^.nextPara.paratype.def=pt.resulttype.def then
  827. begin
  828. include(pt.callparaflags,cpf_exact_match_found);
  829. hp^.nextPara.argconvtyp:=act_exact;
  830. end
  831. else
  832. hp^.nextPara.argconvtyp:=act_equal;
  833. exactmatch:=true;
  834. end
  835. else
  836. begin
  837. hp^.nextPara.argconvtyp:=act_convertable;
  838. hp^.nextPara.convertlevel:=isconvertable(pt.resulttype.def,hp^.nextPara.paratype.def,
  839. hcvt,pt.left.nodetype,false);
  840. case hp^.nextPara.convertlevel of
  841. 1 : include(pt.callparaflags,cpf_convlevel1found);
  842. 2 : include(pt.callparaflags,cpf_convlevel2found);
  843. end;
  844. end;
  845. end;
  846. hp:=hp^.next;
  847. end;
  848. { If there was an exactmatch then delete all convertables }
  849. if exactmatch then
  850. begin
  851. hp:=procs;
  852. procs:=nil;
  853. while assigned(hp) do
  854. begin
  855. hp2:=hp^.next;
  856. { keep if not convertable }
  857. if (hp^.nextPara.argconvtyp<>act_convertable) then
  858. begin
  859. hp^.next:=procs;
  860. procs:=hp;
  861. end
  862. else
  863. dispose(hp);
  864. hp:=hp2;
  865. end;
  866. end
  867. else
  868. { No exact match was found, remove all procedures that are
  869. not convertable (convertlevel=0) }
  870. begin
  871. hp:=procs;
  872. procs:=nil;
  873. while assigned(hp) do
  874. begin
  875. hp2:=hp^.next;
  876. { keep if not convertable }
  877. if (hp^.nextPara.convertlevel<>0) then
  878. begin
  879. hp^.next:=procs;
  880. procs:=hp;
  881. end
  882. else
  883. begin
  884. { save the type for nice error message }
  885. lastparatype:=hp^.nextPara.paratype.def;
  886. dispose(hp);
  887. end;
  888. hp:=hp2;
  889. end;
  890. end;
  891. { update nextpara for all procedures }
  892. hp:=procs;
  893. while assigned(hp) do
  894. begin
  895. { only goto next para if we're out of the varargs }
  896. if not(po_varargs in hp^.data.procoptions) or
  897. (lastpara<=hp^.data.maxparacount) then
  898. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  899. hp:=hp^.next;
  900. end;
  901. { load next parameter or quit loop if no procs left }
  902. if assigned(procs) then
  903. pt:=tcallparanode(pt.right)
  904. else
  905. break;
  906. end;
  907. { All parameters are checked, check if there are any
  908. procedures left }
  909. if not assigned(procs) then
  910. begin
  911. { there is an error, must be wrong type, because
  912. wrong size is already checked (PFV) }
  913. if (not assigned(lastparatype)) or
  914. (not assigned(pt)) or
  915. (not assigned(pt.resulttype.def)) then
  916. internalerror(39393)
  917. else
  918. begin
  919. aktfilepos:=pt.fileinfo;
  920. CGMessage3(type_e_wrong_parameter_type,tostr(lastpara),
  921. pt.resulttype.def.typename,lastparatype.typename);
  922. end;
  923. aktcallprocsym.write_parameter_lists(nil);
  924. goto errorexit;
  925. end;
  926. { if there are several choices left then for orddef }
  927. { if a type is totally included in the other }
  928. { we don't fear an overflow , }
  929. { so we can do as if it is an exact match }
  930. { this will convert integer to longint }
  931. { rather than to words }
  932. { conversion of byte to integer or longint }
  933. { would still not be solved }
  934. if assigned(procs) and assigned(procs^.next) then
  935. begin
  936. hp:=procs;
  937. while assigned(hp) do
  938. begin
  939. hp^.nextpara:=hp^.firstpara;
  940. hp:=hp^.next;
  941. end;
  942. pt:=tcallparanode(left);
  943. while assigned(pt) do
  944. begin
  945. { matches a parameter of one procedure exact ? }
  946. exactmatch:=false;
  947. def_from:=pt.resulttype.def;
  948. hp:=procs;
  949. while assigned(hp) do
  950. begin
  951. if not is_equal(pt,hp^.nextPara.paratype.def) then
  952. begin
  953. def_to:=hp^.nextPara.paratype.def;
  954. if ((def_from.deftype=orddef) and (def_to.deftype=orddef)) and
  955. (is_in_limit(def_from,def_to) or
  956. ((hp^.nextPara.paratyp in [vs_var,vs_out]) and
  957. (def_from.size=def_to.size))) then
  958. begin
  959. exactmatch:=true;
  960. conv_to:=def_to;
  961. end;
  962. end;
  963. hp:=hp^.next;
  964. end;
  965. { .... if yes, del all the other procedures }
  966. if exactmatch then
  967. begin
  968. { the first .... }
  969. while (assigned(procs)) and not(is_in_limit(def_from,procs^.nextPara.paratype.def)) do
  970. begin
  971. hp:=procs^.next;
  972. dispose(procs);
  973. procs:=hp;
  974. end;
  975. { and the others }
  976. hp:=procs;
  977. while (assigned(hp)) and assigned(hp^.next) do
  978. begin
  979. if not(is_in_limit(def_from,hp^.next^.nextPara.paratype.def)) then
  980. begin
  981. hp2:=hp^.next^.next;
  982. dispose(hp^.next);
  983. hp^.next:=hp2;
  984. end
  985. else
  986. begin
  987. def_to:=hp^.next^.nextPara.paratype.def;
  988. if (conv_to.size>def_to.size) or
  989. ((torddef(conv_to).low<torddef(def_to).low) and
  990. (torddef(conv_to).high>torddef(def_to).high)) then
  991. begin
  992. hp2:=procs;
  993. procs:=hp;
  994. conv_to:=def_to;
  995. dispose(hp2);
  996. end
  997. else
  998. hp:=hp^.next;
  999. end;
  1000. end;
  1001. end;
  1002. { update nextpara for all procedures }
  1003. hp:=procs;
  1004. while assigned(hp) do
  1005. begin
  1006. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1007. hp:=hp^.next;
  1008. end;
  1009. pt:=tcallparanode(pt.right);
  1010. end;
  1011. end;
  1012. { let's try to eliminate equal if there is an exact match
  1013. is there }
  1014. if assigned(procs) and assigned(procs^.next) then
  1015. begin
  1016. { reset nextpara for all procs left }
  1017. hp:=procs;
  1018. while assigned(hp) do
  1019. begin
  1020. hp^.nextpara:=hp^.firstpara;
  1021. hp:=hp^.next;
  1022. end;
  1023. pt:=tcallparanode(left);
  1024. while assigned(pt) do
  1025. begin
  1026. if cpf_exact_match_found in pt.callparaflags then
  1027. begin
  1028. hp:=procs;
  1029. procs:=nil;
  1030. while assigned(hp) do
  1031. begin
  1032. hp2:=hp^.next;
  1033. { keep the exact matches, dispose the others }
  1034. if (hp^.nextPara.argconvtyp=act_exact) then
  1035. begin
  1036. hp^.next:=procs;
  1037. procs:=hp;
  1038. end
  1039. else
  1040. dispose(hp);
  1041. hp:=hp2;
  1042. end;
  1043. end;
  1044. { update nextpara for all procedures }
  1045. hp:=procs;
  1046. while assigned(hp) do
  1047. begin
  1048. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1049. hp:=hp^.next;
  1050. end;
  1051. pt:=tcallparanode(pt.right);
  1052. end;
  1053. end;
  1054. { Check if there are integer constant to integer
  1055. parameters then choose the best matching integer
  1056. parameter and remove the others, this is Delphi
  1057. compatible. 1 = byte, 256 = word, etc. }
  1058. if assigned(procs) and assigned(procs^.next) then
  1059. begin
  1060. { reset nextpara for all procs left }
  1061. hp:=procs;
  1062. while assigned(hp) do
  1063. begin
  1064. hp^.nextpara:=hp^.firstpara;
  1065. hp:=hp^.next;
  1066. end;
  1067. pt:=tcallparanode(left);
  1068. while assigned(pt) do
  1069. begin
  1070. bestord:=nil;
  1071. if (pt.left.nodetype=ordconstn) and
  1072. is_integer(pt.resulttype.def) then
  1073. begin
  1074. hp:=procs;
  1075. while assigned(hp) do
  1076. begin
  1077. def_to:=hp^.nextPara.paratype.def;
  1078. { to be sure, it couldn't be something else,
  1079. also the defs here are all in the range
  1080. so now find the closest range }
  1081. if not is_integer(def_to) then
  1082. internalerror(43297815);
  1083. if (not assigned(bestord)) or
  1084. ((torddef(def_to).low>bestord.low) or
  1085. (torddef(def_to).high<bestord.high)) then
  1086. bestord:=torddef(def_to);
  1087. hp:=hp^.next;
  1088. end;
  1089. end;
  1090. { if a bestmatch is found then remove the other
  1091. procs which don't match the bestord }
  1092. if assigned(bestord) then
  1093. begin
  1094. hp:=procs;
  1095. procs:=nil;
  1096. while assigned(hp) do
  1097. begin
  1098. hp2:=hp^.next;
  1099. { keep matching bestord, dispose the others }
  1100. if (torddef(hp^.nextPara.paratype.def)=bestord) then
  1101. begin
  1102. hp^.next:=procs;
  1103. procs:=hp;
  1104. end
  1105. else
  1106. dispose(hp);
  1107. hp:=hp2;
  1108. end;
  1109. end;
  1110. { update nextpara for all procedures }
  1111. hp:=procs;
  1112. while assigned(hp) do
  1113. begin
  1114. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1115. hp:=hp^.next;
  1116. end;
  1117. pt:=tcallparanode(pt.right);
  1118. end;
  1119. end;
  1120. { Check if there are convertlevel 1 and 2 differences
  1121. left for the parameters, then discard all convertlevel
  1122. 2 procedures. The value of convlevelXfound can still
  1123. be used, because all convertables are still here or
  1124. not }
  1125. if assigned(procs) and assigned(procs^.next) then
  1126. begin
  1127. { reset nextpara for all procs left }
  1128. hp:=procs;
  1129. while assigned(hp) do
  1130. begin
  1131. hp^.nextpara:=hp^.firstpara;
  1132. hp:=hp^.next;
  1133. end;
  1134. pt:=tcallparanode(left);
  1135. while assigned(pt) do
  1136. begin
  1137. if (cpf_convlevel1found in pt.callparaflags) and
  1138. (cpf_convlevel2found in pt.callparaflags) then
  1139. begin
  1140. hp:=procs;
  1141. procs:=nil;
  1142. while assigned(hp) do
  1143. begin
  1144. hp2:=hp^.next;
  1145. { keep all not act_convertable and all convertlevels=1 }
  1146. if (hp^.nextPara.argconvtyp<>act_convertable) or
  1147. (hp^.nextPara.convertlevel=1) then
  1148. begin
  1149. hp^.next:=procs;
  1150. procs:=hp;
  1151. end
  1152. else
  1153. dispose(hp);
  1154. hp:=hp2;
  1155. end;
  1156. end;
  1157. { update nextpara for all procedures }
  1158. hp:=procs;
  1159. while assigned(hp) do
  1160. begin
  1161. hp^.nextpara:=tparaitem(hp^.nextPara.next);
  1162. hp:=hp^.next;
  1163. end;
  1164. pt:=tcallparanode(pt.right);
  1165. end;
  1166. end;
  1167. if not(assigned(procs)) or assigned(procs^.next) then
  1168. begin
  1169. CGMessage(cg_e_cant_choose_overload_function);
  1170. aktcallprocsym.write_parameter_lists(nil);
  1171. goto errorexit;
  1172. end;
  1173. {$ifdef TEST_PROCSYMS}
  1174. if (procs=nil) and assigned(nextprocsym) then
  1175. begin
  1176. symtableprocentry:=nextprocsym;
  1177. symtableproc:=symt;
  1178. end;
  1179. end ; { of while assigned(symtableprocentry) do }
  1180. {$endif TEST_PROCSYMS}
  1181. if make_ref then
  1182. begin
  1183. procs^.data.lastref:=tref.create(procs^.data.lastref,@fileinfo);
  1184. inc(procs^.data.refcount);
  1185. if procs^.data.defref=nil then
  1186. procs^.data.defref:=procs^.data.lastref;
  1187. end;
  1188. procdefinition:=procs^.data;
  1189. { big error for with statements
  1190. symtableproc:=procdefinition.owner;
  1191. but neede for overloaded operators !! }
  1192. if symtableproc=nil then
  1193. symtableproc:=procdefinition.owner;
  1194. {$ifdef CHAINPROCSYMS}
  1195. { object with method read;
  1196. call to read(x) will be a usual procedure call }
  1197. if assigned(methodpointer) and
  1198. (procdefinition._class=nil) then
  1199. begin
  1200. { not ok for extended }
  1201. case methodpointer^.nodetype of
  1202. typen,hnewn : fatalerror(no_para_match);
  1203. end;
  1204. methodpointer.free;
  1205. methodpointer:=nil;
  1206. end;
  1207. {$endif CHAINPROCSYMS}
  1208. end; { end of procedure to call determination }
  1209. { add needed default parameters }
  1210. if assigned(procs) and
  1211. (paralength<procdefinition.maxparacount) then
  1212. begin
  1213. { add default parameters, just read back the skipped
  1214. paras starting from firstPara.previous, when not available
  1215. (all parameters are default) then start with the last
  1216. parameter and read backward (PFV) }
  1217. if not assigned(procs^.firstpara) then
  1218. pdc:=tparaitem(procs^.data.Para.last)
  1219. else
  1220. pdc:=tparaitem(procs^.firstPara.previous);
  1221. while assigned(pdc) do
  1222. begin
  1223. if not assigned(pdc.defaultvalue) then
  1224. internalerror(751349858);
  1225. left:=ccallparanode.create(genconstsymtree(tconstsym(pdc.defaultvalue)),left);
  1226. pdc:=tparaitem(pdc.previous);
  1227. end;
  1228. end;
  1229. end;
  1230. { handle predefined procedures }
  1231. is_const:=(procdefinition.proccalloption=pocall_internconst) and
  1232. ((block_type in [bt_const,bt_type]) or
  1233. (assigned(left) and (tcallparanode(left).left.nodetype in [realconstn,ordconstn])));
  1234. if (procdefinition.proccalloption=pocall_internproc) or is_const then
  1235. begin
  1236. if assigned(left) then
  1237. begin
  1238. { ptr and settextbuf needs two args }
  1239. if assigned(tcallparanode(left).right) then
  1240. begin
  1241. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,left);
  1242. left:=nil;
  1243. end
  1244. else
  1245. begin
  1246. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,tcallparanode(left).left);
  1247. tcallparanode(left).left:=nil;
  1248. end;
  1249. end
  1250. else
  1251. hpt:=geninlinenode(tprocdef(procdefinition).extnumber,is_const,nil);
  1252. result:=hpt;
  1253. goto errorexit;
  1254. end;
  1255. { Calling a message method directly ? }
  1256. if assigned(procdefinition) and
  1257. (po_containsself in procdefinition.procoptions) then
  1258. message(cg_e_cannot_call_message_direct);
  1259. { ensure that the result type is set }
  1260. if not restypeset then
  1261. resulttype:=procdefinition.rettype
  1262. else
  1263. resulttype:=restype;
  1264. { get a register for the return value }
  1265. if (not is_void(resulttype.def)) then
  1266. begin
  1267. if ret_in_acc(resulttype.def) then
  1268. begin
  1269. { wide- and ansistrings are returned in EAX }
  1270. { but they are imm. moved to a memory location }
  1271. if is_widestring(resulttype.def) or
  1272. is_ansistring(resulttype.def) then
  1273. begin
  1274. { we use ansistrings so no fast exit here }
  1275. procinfo^.no_fast_exit:=true;
  1276. end;
  1277. end;
  1278. end;
  1279. { constructors return their current class type, not the type where the
  1280. constructor is declared, this can be different because of inheritance }
  1281. if (procdefinition.proctypeoption=potype_constructor) then
  1282. begin
  1283. if assigned(methodpointer) and
  1284. assigned(methodpointer.resulttype.def) and
  1285. (methodpointer.resulttype.def.deftype=classrefdef) then
  1286. resulttype:=tclassrefdef(methodpointer.resulttype.def).pointertype;
  1287. end;
  1288. { flag all callparanodes that belong to the varargs }
  1289. if (po_varargs in procdefinition.procoptions) then
  1290. begin
  1291. pt:=tcallparanode(left);
  1292. i:=paralength;
  1293. while (i>procdefinition.maxparacount) do
  1294. begin
  1295. include(tcallparanode(pt).flags,nf_varargs_para);
  1296. pt:=tcallparanode(pt.right);
  1297. dec(i);
  1298. end;
  1299. end;
  1300. { insert type conversions }
  1301. if assigned(left) then
  1302. tcallparanode(left).insert_typeconv(tparaitem(procdefinition.Para.first),true);
  1303. errorexit:
  1304. { Reset some settings back }
  1305. if assigned(procs) then
  1306. dispose(procs);
  1307. aktcallprocsym:=oldcallprocsym;
  1308. end;
  1309. function tcallnode.pass_1 : tnode;
  1310. var
  1311. inlinecode : tnode;
  1312. inlined : boolean;
  1313. {$ifdef m68k}
  1314. regi : tregister;
  1315. {$endif}
  1316. method_must_be_valid : boolean;
  1317. label
  1318. errorexit;
  1319. begin
  1320. result:=nil;
  1321. inlined:=false;
  1322. { work trough all parameters to get the register requirements }
  1323. if assigned(left) then
  1324. tcallparanode(left).det_registers;
  1325. if assigned(procdefinition) and
  1326. (procdefinition.proccalloption=pocall_inline) then
  1327. begin
  1328. inlinecode:=right;
  1329. if assigned(inlinecode) then
  1330. inlined:=true;
  1331. right:=nil;
  1332. end;
  1333. { procedure variable ? }
  1334. if assigned(right) then
  1335. begin
  1336. firstpass(right);
  1337. { procedure does a call }
  1338. if not (block_type in [bt_const,bt_type]) then
  1339. procinfo^.flags:=procinfo^.flags or pi_do_call;
  1340. {$ifndef newcg}
  1341. { calc the correct value for the register }
  1342. {$ifdef i386}
  1343. incrementregisterpushed($ff);
  1344. {$else}
  1345. incrementregisterpushed(ALL_REGISTERS);
  1346. {$endif}
  1347. {$endif newcg}
  1348. end
  1349. else
  1350. { not a procedure variable }
  1351. begin
  1352. location.loc:=LOC_MEM;
  1353. { calc the correture value for the register }
  1354. { handle predefined procedures }
  1355. if (procdefinition.proccalloption=pocall_inline) then
  1356. begin
  1357. if assigned(methodpointer) then
  1358. CGMessage(cg_e_unable_inline_object_methods);
  1359. if assigned(right) and (right.nodetype<>procinlinen) then
  1360. CGMessage(cg_e_unable_inline_procvar);
  1361. { nodetype:=procinlinen; }
  1362. if not assigned(right) then
  1363. begin
  1364. if assigned(tprocdef(procdefinition).code) then
  1365. inlinecode:=cprocinlinenode.create(self,tnode(tprocdef(procdefinition).code))
  1366. else
  1367. CGMessage(cg_e_no_code_for_inline_stored);
  1368. if assigned(inlinecode) then
  1369. begin
  1370. { consider it has not inlined if called
  1371. again inside the args }
  1372. procdefinition.proccalloption:=pocall_fpccall;
  1373. firstpass(inlinecode);
  1374. inlined:=true;
  1375. end;
  1376. end;
  1377. end
  1378. else
  1379. begin
  1380. if not (block_type in [bt_const,bt_type]) then
  1381. procinfo^.flags:=procinfo^.flags or pi_do_call;
  1382. end;
  1383. {$ifndef newcg}
  1384. {$ifndef POWERPC}
  1385. { for the PowerPC standard calling conventions this information isn't necassary (FK) }
  1386. incrementregisterpushed(tprocdef(procdefinition).usedregisters);
  1387. {$endif POWERPC}
  1388. {$endif newcg}
  1389. end;
  1390. { get a register for the return value }
  1391. if (not is_void(resulttype.def)) then
  1392. begin
  1393. if (procdefinition.proctypeoption=potype_constructor) then
  1394. begin
  1395. { extra handling of classes }
  1396. { methodpointer should be assigned! }
  1397. if assigned(methodpointer) and
  1398. assigned(methodpointer.resulttype.def) and
  1399. (methodpointer.resulttype.def.deftype=classrefdef) then
  1400. begin
  1401. location.loc:=LOC_REGISTER;
  1402. registers32:=1;
  1403. end
  1404. { a object constructor returns the result with the flags }
  1405. else
  1406. location.loc:=LOC_FLAGS;
  1407. end
  1408. else
  1409. begin
  1410. {$ifdef SUPPORT_MMX}
  1411. if (cs_mmx in aktlocalswitches) and
  1412. is_mmx_able_array(resulttype.def) then
  1413. begin
  1414. location.loc:=LOC_MMXREGISTER;
  1415. registersmmx:=1;
  1416. end
  1417. else
  1418. {$endif SUPPORT_MMX}
  1419. if ret_in_acc(resulttype.def) then
  1420. begin
  1421. location.loc:=LOC_REGISTER;
  1422. if is_64bitint(resulttype.def) then
  1423. registers32:=2
  1424. else
  1425. registers32:=1;
  1426. { wide- and ansistrings are returned in EAX }
  1427. { but they are imm. moved to a memory location }
  1428. if is_widestring(resulttype.def) or
  1429. is_ansistring(resulttype.def) then
  1430. begin
  1431. location.loc:=LOC_MEM;
  1432. registers32:=1;
  1433. end;
  1434. end
  1435. else if (resulttype.def.deftype=floatdef) then
  1436. begin
  1437. location.loc:=LOC_FPU;
  1438. {$ifdef m68k}
  1439. if (cs_fp_emulation in aktmoduleswitches) or
  1440. (tfloatdef(resulttype.def).typ=s32real) then
  1441. registers32:=1
  1442. else
  1443. registersfpu:=1;
  1444. {$else not m68k}
  1445. registersfpu:=1;
  1446. {$endif not m68k}
  1447. end
  1448. else
  1449. location.loc:=LOC_MEM;
  1450. end;
  1451. end;
  1452. { a fpu can be used in any procedure !! }
  1453. registersfpu:=procdefinition.fpu_used;
  1454. { if this is a call to a method calc the registers }
  1455. if (methodpointer<>nil) then
  1456. begin
  1457. case methodpointer.nodetype of
  1458. { but only, if this is not a supporting node }
  1459. typen: ;
  1460. { we need one register for new return value PM }
  1461. hnewn : if registers32=0 then
  1462. registers32:=1;
  1463. else
  1464. begin
  1465. if (procdefinition.proctypeoption in [potype_constructor,potype_destructor]) and
  1466. assigned(symtableproc) and (symtableproc.symtabletype=withsymtable) and
  1467. not twithsymtable(symtableproc).direct_with then
  1468. begin
  1469. CGmessage(cg_e_cannot_call_cons_dest_inside_with);
  1470. end; { Is accepted by Delphi !! }
  1471. { this is not a good reason to accept it in FPC if we produce
  1472. wrong code for it !!! (PM) }
  1473. { R.Assign is not a constructor !!! }
  1474. { but for R^.Assign, R must be valid !! }
  1475. if (procdefinition.proctypeoption=potype_constructor) or
  1476. ((methodpointer.nodetype=loadn) and
  1477. (not(oo_has_virtual in tobjectdef(methodpointer.resulttype.def).objectoptions))) then
  1478. method_must_be_valid:=false
  1479. else
  1480. method_must_be_valid:=true;
  1481. firstpass(methodpointer);
  1482. set_varstate(methodpointer,method_must_be_valid);
  1483. { The object is already used ven if it is called once }
  1484. if (methodpointer.nodetype=loadn) and
  1485. (tloadnode(methodpointer).symtableentry.typ=varsym) then
  1486. tvarsym(tloadnode(methodpointer).symtableentry).varstate:=vs_used;
  1487. registersfpu:=max(methodpointer.registersfpu,registersfpu);
  1488. registers32:=max(methodpointer.registers32,registers32);
  1489. {$ifdef SUPPORT_MMX}
  1490. registersmmx:=max(methodpointer.registersmmx,registersmmx);
  1491. {$endif SUPPORT_MMX}
  1492. end;
  1493. end;
  1494. end;
  1495. if inlined then
  1496. right:=inlinecode;
  1497. { determine the registers of the procedure variable }
  1498. { is this OK for inlined procs also ?? (PM) }
  1499. if assigned(right) then
  1500. begin
  1501. registersfpu:=max(right.registersfpu,registersfpu);
  1502. registers32:=max(right.registers32,registers32);
  1503. {$ifdef SUPPORT_MMX}
  1504. registersmmx:=max(right.registersmmx,registersmmx);
  1505. {$endif SUPPORT_MMX}
  1506. end;
  1507. { determine the registers of the procedure }
  1508. if assigned(left) then
  1509. begin
  1510. registersfpu:=max(left.registersfpu,registersfpu);
  1511. registers32:=max(left.registers32,registers32);
  1512. {$ifdef SUPPORT_MMX}
  1513. registersmmx:=max(left.registersmmx,registersmmx);
  1514. {$endif SUPPORT_MMX}
  1515. end;
  1516. errorexit:
  1517. if inlined then
  1518. procdefinition.proccalloption:=pocall_inline;
  1519. end;
  1520. function tcallnode.docompare(p: tnode): boolean;
  1521. begin
  1522. docompare :=
  1523. inherited docompare(p) and
  1524. (symtableprocentry = tcallnode(p).symtableprocentry) and
  1525. (symtableproc = tcallnode(p).symtableproc) and
  1526. (procdefinition = tcallnode(p).procdefinition) and
  1527. (methodpointer.isequal(tcallnode(p).methodpointer)) and
  1528. ((restypeset and tcallnode(p).restypeset and
  1529. (is_equal(restype.def,tcallnode(p).restype.def))) or
  1530. (not restypeset and not tcallnode(p).restypeset));
  1531. end;
  1532. {****************************************************************************
  1533. TPROCINLINENODE
  1534. ****************************************************************************}
  1535. constructor tprocinlinenode.create(callp,code : tnode);
  1536. begin
  1537. inherited create(procinlinen);
  1538. inlineprocsym:=tcallnode(callp).symtableprocentry;
  1539. retoffset:=-target_info.size_of_pointer; { less dangerous as zero (PM) }
  1540. para_offset:=0;
  1541. para_size:=inlineprocsym.definition.para_size(target_info.alignment.paraalign);
  1542. if ret_in_param(inlineprocsym.definition.rettype.def) then
  1543. inc(para_size,target_info.size_of_pointer);
  1544. { copy args }
  1545. if assigned(code) then
  1546. inlinetree:=code.getcopy
  1547. else inlinetree := nil;
  1548. registers32:=code.registers32;
  1549. registersfpu:=code.registersfpu;
  1550. {$ifdef SUPPORT_MMX}
  1551. registersmmx:=code.registersmmx;
  1552. {$endif SUPPORT_MMX}
  1553. resulttype:=inlineprocsym.definition.rettype;
  1554. end;
  1555. destructor tprocinlinenode.destroy;
  1556. begin
  1557. if assigned(inlinetree) then
  1558. inlinetree.free;
  1559. inherited destroy;
  1560. end;
  1561. function tprocinlinenode.getcopy : tnode;
  1562. var
  1563. n : tprocinlinenode;
  1564. begin
  1565. n:=tprocinlinenode(inherited getcopy);
  1566. if assigned(inlinetree) then
  1567. n.inlinetree:=inlinetree.getcopy
  1568. else
  1569. n.inlinetree:=nil;
  1570. n.inlineprocsym:=inlineprocsym;
  1571. n.retoffset:=retoffset;
  1572. n.para_offset:=para_offset;
  1573. n.para_size:=para_size;
  1574. getcopy:=n;
  1575. end;
  1576. procedure tprocinlinenode.insertintolist(l : tnodelist);
  1577. begin
  1578. end;
  1579. function tprocinlinenode.pass_1 : tnode;
  1580. begin
  1581. result:=nil;
  1582. { left contains the code in tree form }
  1583. { but it has already been firstpassed }
  1584. { so firstpass(left); does not seem required }
  1585. { might be required later if we change the arg handling !! }
  1586. end;
  1587. function tprocinlinenode.docompare(p: tnode): boolean;
  1588. begin
  1589. docompare :=
  1590. inherited docompare(p) and
  1591. inlinetree.isequal(tprocinlinenode(p).inlinetree) and
  1592. (inlineprocsym = tprocinlinenode(p).inlineprocsym);
  1593. end;
  1594. begin
  1595. ccallnode:=tcallnode;
  1596. ccallparanode:=tcallparanode;
  1597. cprocinlinenode:=tprocinlinenode;
  1598. end.
  1599. {
  1600. $Log$
  1601. Revision 1.52 2001-10-25 21:22:33 peter
  1602. * calling convention rewrite
  1603. Revision 1.51 2001/10/13 09:01:14 jonas
  1604. * fixed bug with using procedures as procvar parameters in TP/Delphi mode
  1605. Revision 1.50 2001/10/12 16:04:32 peter
  1606. * nested inline fix (merged)
  1607. Revision 1.49 2001/09/02 21:12:06 peter
  1608. * move class of definitions into type section for delphi
  1609. Revision 1.48 2001/08/30 15:39:59 jonas
  1610. * fixed docompare for the fields I added to tcallnode in my previous
  1611. commit
  1612. * removed nested comment warning
  1613. Revision 1.47 2001/08/29 12:18:07 jonas
  1614. + new createinternres() constructor for tcallnode to support setting a
  1615. custom resulttype
  1616. * compilerproc typeconversions now set the resulttype from the type
  1617. conversion for the generated call node, because the resulttype of
  1618. of the compilerproc helper isn't always exact (e.g. the ones that
  1619. return shortstrings, actually return a shortstring[x], where x is
  1620. specified by the typeconversion node)
  1621. * ti386callnode.pass_2 now always uses resulttype instead of
  1622. procsym.definition.rettype (so the custom resulttype, if any, is
  1623. always used). Note that this "rettype" stuff is only for use with
  1624. compilerprocs.
  1625. Revision 1.46 2001/08/28 13:24:46 jonas
  1626. + compilerproc implementation of most string-related type conversions
  1627. - removed all code from the compiler which has been replaced by
  1628. compilerproc implementations (using (ifdef hascompilerproc) is not
  1629. necessary in the compiler)
  1630. Revision 1.45 2001/08/26 13:36:39 florian
  1631. * some cg reorganisation
  1632. * some PPC updates
  1633. Revision 1.44 2001/08/24 13:47:27 jonas
  1634. * moved "reverseparameters" from ninl.pas to ncal.pas
  1635. + support for non-persistent temps in ttempcreatenode.create, for use
  1636. with typeconversion nodes
  1637. Revision 1.43 2001/08/23 14:28:35 jonas
  1638. + tempcreate/ref/delete nodes (allows the use of temps in the
  1639. resulttype and first pass)
  1640. * made handling of read(ln)/write(ln) processor independent
  1641. * moved processor independent handling for str and reset/rewrite-typed
  1642. from firstpass to resulttype pass
  1643. * changed names of helpers in text.inc to be generic for use as
  1644. compilerprocs + added "iocheck" directive for most of them
  1645. * reading of ordinals is done by procedures instead of functions
  1646. because otherwise FPC_IOCHECK overwrote the result before it could
  1647. be stored elsewhere (range checking still works)
  1648. * compilerprocs can now be used in the system unit before they are
  1649. implemented
  1650. * added note to errore.msg that booleans can't be read using read/readln
  1651. Revision 1.42 2001/08/19 21:11:20 florian
  1652. * some bugs fix:
  1653. - overload; with external procedures fixed
  1654. - better selection of routine to do an overloaded
  1655. type case
  1656. - ... some more
  1657. Revision 1.41 2001/08/13 12:41:56 jonas
  1658. * made code for str(x,y) completely processor independent
  1659. Revision 1.40 2001/08/06 21:40:46 peter
  1660. * funcret moved from tprocinfo to tprocdef
  1661. Revision 1.39 2001/08/01 15:07:29 jonas
  1662. + "compilerproc" directive support, which turns both the public and mangled
  1663. name to lowercase(declaration_name). This prevents a normal user from
  1664. accessing the routine, but they can still be easily looked up within
  1665. the compiler. This is used for helper procedures and should facilitate
  1666. the writing of more processor independent code in the code generator
  1667. itself (mostly written by Peter)
  1668. + new "createintern" constructor for tcal nodes to create a call to
  1669. helper exported using the "compilerproc" directive
  1670. + support for high(dynamic_array) using the the above new things
  1671. + definition of 'HASCOMPILERPROC' symbol (to be able to check in the
  1672. compiler and rtl whether the "compilerproc" directive is supported)
  1673. Revision 1.38 2001/07/30 20:52:25 peter
  1674. * fixed array constructor passing with type conversions
  1675. Revision 1.37 2001/07/09 21:15:40 peter
  1676. * Length made internal
  1677. * Add array support for Length
  1678. Revision 1.36 2001/07/01 20:16:15 peter
  1679. * alignmentinfo record added
  1680. * -Oa argument supports more alignment settings that can be specified
  1681. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  1682. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  1683. required alignment and the maximum usefull alignment. The final
  1684. alignment will be choosen per variable size dependent on these
  1685. settings
  1686. Revision 1.35 2001/06/04 18:08:19 peter
  1687. * procvar support for varargs
  1688. Revision 1.34 2001/06/04 11:48:02 peter
  1689. * better const to var checking
  1690. Revision 1.33 2001/05/20 12:09:31 peter
  1691. * fixed exit with ansistring return from function call, no_fast_exit
  1692. should be set in det_resulttype instead of pass_1
  1693. Revision 1.32 2001/04/26 21:55:05 peter
  1694. * defcoll must be assigned in insert_typeconv
  1695. Revision 1.31 2001/04/21 12:03:11 peter
  1696. * m68k updates merged from fixes branch
  1697. Revision 1.30 2001/04/18 22:01:54 peter
  1698. * registration of targets and assemblers
  1699. Revision 1.29 2001/04/13 23:52:29 peter
  1700. * don't allow passing signed-unsigned ords to var parameter, this
  1701. forbids smallint-word, shortint-byte, longint-cardinal mixtures.
  1702. It's still allowed in tp7 -So mode.
  1703. Revision 1.28 2001/04/13 22:22:59 peter
  1704. * call set_varstate for procvar calls
  1705. Revision 1.27 2001/04/13 01:22:08 peter
  1706. * symtable change to classes
  1707. * range check generation and errors fixed, make cycle DEBUG=1 works
  1708. * memory leaks fixed
  1709. Revision 1.26 2001/04/04 22:42:39 peter
  1710. * move constant folding into det_resulttype
  1711. Revision 1.25 2001/04/02 21:20:30 peter
  1712. * resulttype rewrite
  1713. Revision 1.24 2001/03/12 12:47:46 michael
  1714. + Patches from peter
  1715. Revision 1.23 2001/02/26 19:44:52 peter
  1716. * merged generic m68k updates from fixes branch
  1717. Revision 1.22 2001/01/08 21:46:46 peter
  1718. * don't push high value for open array with cdecl;external;
  1719. Revision 1.21 2000/12/31 11:14:10 jonas
  1720. + implemented/fixed docompare() mathods for all nodes (not tested)
  1721. + nopt.pas, nadd.pas, i386/n386opt.pas: optimized nodes for adding strings
  1722. and constant strings/chars together
  1723. * n386add.pas: don't copy temp strings (of size 256) to another temp string
  1724. when adding
  1725. Revision 1.20 2000/12/25 00:07:26 peter
  1726. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  1727. tlinkedlist objects)
  1728. Revision 1.19 2000/12/17 14:35:12 peter
  1729. * fixed crash with procvar load in tp mode
  1730. Revision 1.18 2000/11/29 00:30:32 florian
  1731. * unused units removed from uses clause
  1732. * some changes for widestrings
  1733. Revision 1.17 2000/11/22 15:12:06 jonas
  1734. * fixed inline-related problems (partially "merges")
  1735. Revision 1.16 2000/11/11 16:14:52 peter
  1736. * fixed crash with settextbuf,ptr
  1737. Revision 1.15 2000/11/06 21:36:25 peter
  1738. * fixed var parameter varstate bug
  1739. Revision 1.14 2000/11/04 14:25:20 florian
  1740. + merged Attila's changes for interfaces, not tested yet
  1741. Revision 1.13 2000/10/31 22:02:47 peter
  1742. * symtable splitted, no real code changes
  1743. Revision 1.12 2000/10/21 18:16:11 florian
  1744. * a lot of changes:
  1745. - basic dyn. array support
  1746. - basic C++ support
  1747. - some work for interfaces done
  1748. ....
  1749. Revision 1.11 2000/10/21 14:35:27 peter
  1750. * readd to many remove p. for tcallnode.is_equal()
  1751. Revision 1.10 2000/10/14 21:52:55 peter
  1752. * fixed memory leaks
  1753. Revision 1.9 2000/10/14 10:14:50 peter
  1754. * moehrendorf oct 2000 rewrite
  1755. Revision 1.8 2000/10/01 19:48:24 peter
  1756. * lot of compile updates for cg11
  1757. Revision 1.7 2000/09/28 19:49:52 florian
  1758. *** empty log message ***
  1759. Revision 1.6 2000/09/27 18:14:31 florian
  1760. * fixed a lot of syntax errors in the n*.pas stuff
  1761. Revision 1.5 2000/09/24 21:15:34 florian
  1762. * some errors fix to get more stuff compilable
  1763. Revision 1.4 2000/09/24 20:17:44 florian
  1764. * more conversion work done
  1765. Revision 1.3 2000/09/24 15:06:19 peter
  1766. * use defines.inc
  1767. Revision 1.2 2000/09/20 21:52:38 florian
  1768. * removed a lot of errors
  1769. Revision 1.1 2000/09/20 20:52:16 florian
  1770. * initial revision
  1771. }