ncal.pas 76 KB

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