ncal.pas 78 KB

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