ncal.pas 78 KB

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