symsym.inc 64 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
  4. Implementation for the symbols types of the symtable
  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. {****************************************************************************
  19. TSYM (base for all symtypes)
  20. ****************************************************************************}
  21. constructor tsym.init(const n : string);
  22. begin
  23. inherited initname(n);
  24. typ:=abstractsym;
  25. symoptions:=current_object_option;
  26. {$ifdef GDB}
  27. isstabwritten := false;
  28. {$endif GDB}
  29. fileinfo:=tokenpos;
  30. defref:=nil;
  31. refs:=0;
  32. lastwritten:=nil;
  33. refcount:=0;
  34. if (cs_browser in aktmoduleswitches) and make_ref then
  35. begin
  36. defref:=new(pref,init(defref,@tokenpos));
  37. inc(refcount);
  38. end;
  39. lastref:=defref;
  40. end;
  41. constructor tsym.load;
  42. begin
  43. inherited init;
  44. indexnr:=readword;
  45. setname(readstring);
  46. typ:=abstractsym;
  47. readsmallset(symoptions);
  48. readposinfo(fileinfo);
  49. lastref:=nil;
  50. defref:=nil;
  51. refs:=0;
  52. lastwritten:=nil;
  53. refcount:=0;
  54. {$ifdef GDB}
  55. isstabwritten := false;
  56. {$endif GDB}
  57. end;
  58. procedure tsym.load_references;
  59. var
  60. pos : tfileposinfo;
  61. move_last : boolean;
  62. begin
  63. move_last:=lastwritten=lastref;
  64. while (not current_ppu^.endofentry) do
  65. begin
  66. readposinfo(pos);
  67. inc(refcount);
  68. lastref:=new(pref,init(lastref,@pos));
  69. lastref^.is_written:=true;
  70. if refcount=1 then
  71. defref:=lastref;
  72. end;
  73. if move_last then
  74. lastwritten:=lastref;
  75. end;
  76. { big problem here :
  77. wrong refs were written because of
  78. interface parsing of other units PM
  79. moduleindex must be checked !! }
  80. function tsym.write_references : boolean;
  81. var
  82. ref : pref;
  83. symref_written,move_last : boolean;
  84. begin
  85. write_references:=false;
  86. if lastwritten=lastref then
  87. exit;
  88. { should we update lastref }
  89. move_last:=true;
  90. symref_written:=false;
  91. { write symbol refs }
  92. if assigned(lastwritten) then
  93. ref:=lastwritten
  94. else
  95. ref:=defref;
  96. while assigned(ref) do
  97. begin
  98. if ref^.moduleindex=current_module^.unit_index then
  99. begin
  100. { write address to this symbol }
  101. if not symref_written then
  102. begin
  103. writesymref(@self);
  104. symref_written:=true;
  105. end;
  106. writeposinfo(ref^.posinfo);
  107. ref^.is_written:=true;
  108. if move_last then
  109. lastwritten:=ref;
  110. end
  111. else if not ref^.is_written then
  112. move_last:=false
  113. else if move_last then
  114. lastwritten:=ref;
  115. ref:=ref^.nextref;
  116. end;
  117. if symref_written then
  118. current_ppu^.writeentry(ibsymref);
  119. write_references:=symref_written;
  120. end;
  121. {$ifdef BrowserLog}
  122. procedure tsym.add_to_browserlog;
  123. begin
  124. if assigned(defref) then
  125. begin
  126. browserlog.AddLog('***'+name+'***');
  127. browserlog.AddLogRefs(defref);
  128. end;
  129. end;
  130. {$endif BrowserLog}
  131. destructor tsym.done;
  132. begin
  133. if assigned(defref) then
  134. begin
  135. defref^.freechain;
  136. dispose(defref,done);
  137. end;
  138. inherited done;
  139. end;
  140. procedure tsym.write;
  141. begin
  142. writeword(indexnr);
  143. writestring(name);
  144. writesmallset(symoptions);
  145. writeposinfo(fileinfo);
  146. end;
  147. procedure tsym.prederef;
  148. begin
  149. end;
  150. procedure tsym.deref;
  151. begin
  152. end;
  153. function tsym.mangledname : string;
  154. begin
  155. mangledname:=name;
  156. end;
  157. { for most symbol types there is nothing to do at all }
  158. procedure tsym.insert_in_data;
  159. begin
  160. end;
  161. {$ifdef GDB}
  162. function tsym.stabstring : pchar;
  163. begin
  164. stabstring:=strpnew('"'+name+'",'+tostr(N_LSYM)+',0,'+
  165. tostr(fileinfo.line)+',0');
  166. end;
  167. procedure tsym.concatstabto(asmlist : paasmoutput);
  168. var stab_str : pchar;
  169. begin
  170. if not isstabwritten then
  171. begin
  172. stab_str := stabstring;
  173. { count_dbx(stab_str); moved to GDB.PAS }
  174. asmlist^.concat(new(pai_stabs,init(stab_str)));
  175. isstabwritten:=true;
  176. end;
  177. end;
  178. {$endif GDB}
  179. {****************************************************************************
  180. TLABELSYM
  181. ****************************************************************************}
  182. constructor tlabelsym.init(const n : string; l : pasmlabel);
  183. begin
  184. inherited init(n);
  185. typ:=labelsym;
  186. lab:=l;
  187. used:=false;
  188. defined:=false;
  189. code:=nil;
  190. end;
  191. constructor tlabelsym.load;
  192. begin
  193. tsym.load;
  194. typ:=labelsym;
  195. { this is all dummy
  196. it is only used for local browsing }
  197. lab:=nil;
  198. code:=nil;
  199. used:=false;
  200. defined:=true;
  201. end;
  202. destructor tlabelsym.done;
  203. begin
  204. inherited done;
  205. end;
  206. function tlabelsym.mangledname : string;
  207. begin
  208. mangledname:=lab^.name;
  209. end;
  210. procedure tlabelsym.write;
  211. begin
  212. if owner^.symtabletype in [unitsymtable,globalsymtable] then
  213. Message(sym_e_ill_label_decl)
  214. else
  215. begin
  216. tsym.write;
  217. current_ppu^.writeentry(iblabelsym);
  218. end;
  219. end;
  220. {****************************************************************************
  221. TUNITSYM
  222. ****************************************************************************}
  223. constructor tunitsym.init(const n : string;ref : punitsymtable);
  224. var
  225. old_make_ref : boolean;
  226. begin
  227. old_make_ref:=make_ref;
  228. make_ref:=false;
  229. inherited init(n);
  230. make_ref:=old_make_ref;
  231. typ:=unitsym;
  232. unitsymtable:=ref;
  233. prevsym:=ref^.unitsym;
  234. ref^.unitsym:=@self;
  235. refs:=0;
  236. end;
  237. constructor tunitsym.load;
  238. begin
  239. tsym.load;
  240. typ:=unitsym;
  241. unitsymtable:=punitsymtable(current_module^.globalsymtable);
  242. prevsym:=nil;
  243. end;
  244. { we need to remove it from the prevsym chain ! }
  245. destructor tunitsym.done;
  246. var pus,ppus : punitsym;
  247. begin
  248. if assigned(unitsymtable) then
  249. begin
  250. ppus:=nil;
  251. pus:=unitsymtable^.unitsym;
  252. if pus=@self then
  253. unitsymtable^.unitsym:=prevsym
  254. else while assigned(pus) do
  255. begin
  256. if pus=@self then
  257. begin
  258. ppus^.prevsym:=prevsym;
  259. break;
  260. end
  261. else
  262. begin
  263. ppus:=pus;
  264. pus:=ppus^.prevsym;
  265. end;
  266. end;
  267. end;
  268. prevsym:=nil;
  269. unitsymtable:=nil;
  270. inherited done;
  271. end;
  272. procedure tunitsym.write;
  273. begin
  274. tsym.write;
  275. current_ppu^.writeentry(ibunitsym);
  276. end;
  277. {$ifdef GDB}
  278. procedure tunitsym.concatstabto(asmlist : paasmoutput);
  279. begin
  280. {Nothing to write to stabs !}
  281. end;
  282. {$endif GDB}
  283. {****************************************************************************
  284. TPROCSYM
  285. ****************************************************************************}
  286. constructor tprocsym.init(const n : string);
  287. begin
  288. tsym.init(n);
  289. typ:=procsym;
  290. definition:=nil;
  291. owner:=nil;
  292. is_global := false;
  293. end;
  294. constructor tprocsym.load;
  295. begin
  296. tsym.load;
  297. typ:=procsym;
  298. definition:=pprocdef(readdefref);
  299. is_global := false;
  300. end;
  301. destructor tprocsym.done;
  302. begin
  303. { don't check if errors !! }
  304. if Errorcount=0 then
  305. check_forward;
  306. tsym.done;
  307. end;
  308. function tprocsym.mangledname : string;
  309. begin
  310. mangledname:=definition^.mangledname;
  311. end;
  312. function tprocsym.demangledname:string;
  313. begin
  314. demangledname:=name+definition^.demangled_paras;
  315. end;
  316. procedure tprocsym.write_parameter_lists;
  317. var
  318. p : pprocdef;
  319. begin
  320. p:=definition;
  321. while assigned(p) do
  322. begin
  323. { force the error to be printed }
  324. Verbose.Message1(sym_b_param_list,name+p^.demangled_paras);
  325. p:=p^.nextoverloaded;
  326. end;
  327. end;
  328. procedure tprocsym.check_forward;
  329. var
  330. pd : pprocdef;
  331. begin
  332. pd:=definition;
  333. while assigned(pd) do
  334. begin
  335. if pd^.forwarddef then
  336. begin
  337. if assigned(pd^._class) then
  338. MessagePos1(fileinfo,sym_e_forward_not_resolved,pd^._class^.objname^+'.'+demangledname)
  339. else
  340. MessagePos1(fileinfo,sym_e_forward_not_resolved,demangledname);
  341. { Turn futher error messages off }
  342. pd^.forwarddef:=false;
  343. end;
  344. pd:=pd^.nextoverloaded;
  345. end;
  346. end;
  347. procedure tprocsym.deref;
  348. var
  349. t : ttoken;
  350. last,pd : pprocdef;
  351. begin
  352. resolvedef(pdef(definition));
  353. if (definition^.proctypeoption=potype_operator) then
  354. begin
  355. last:=definition;
  356. while assigned(last^.nextoverloaded) do
  357. last:=last^.nextoverloaded;
  358. for t:=first_overloaded to last_overloaded do
  359. if (name=overloaded_names[t]) then
  360. begin
  361. if assigned(overloaded_operators[t]) then
  362. begin
  363. pd:=overloaded_operators[t]^.definition;
  364. { test if not already in list, bug report by KC Wong PM }
  365. while assigned(pd) do
  366. if pd=last then
  367. break
  368. else
  369. pd:=pd^.nextoverloaded;
  370. if pd=last then
  371. break;
  372. last^.nextoverloaded:=overloaded_operators[t]^.definition;
  373. end;
  374. overloaded_operators[t]:=@self;
  375. break;
  376. end;
  377. end;
  378. end;
  379. procedure tprocsym.order_overloaded;
  380. var firstdef,currdef,lastdef : pprocdef;
  381. begin
  382. firstdef:=definition;
  383. currdef:=definition;
  384. while assigned(currdef) do
  385. begin
  386. currdef^.count:=false;
  387. currdef:=currdef^.nextoverloaded;
  388. end;
  389. definition:=definition^.nextoverloaded;
  390. firstdef^.nextoverloaded:=nil;
  391. while assigned(definition) do
  392. begin
  393. currdef:=firstdef;
  394. lastdef:=definition;
  395. definition:=definition^.nextoverloaded;
  396. if lastdef^.mangledname<firstdef^.mangledname then
  397. begin
  398. lastdef^.nextoverloaded:=firstdef;
  399. firstdef:=lastdef;
  400. end
  401. else
  402. begin
  403. while assigned(currdef^.nextoverloaded) and
  404. (lastdef^.mangledname>currdef^.nextoverloaded^.mangledname) do
  405. currdef:=currdef^.nextoverloaded;
  406. lastdef^.nextoverloaded:=currdef^.nextoverloaded;
  407. currdef^.nextoverloaded:=lastdef;
  408. end;
  409. end;
  410. definition:=firstdef;
  411. currdef:=definition;
  412. while assigned(currdef) do
  413. begin
  414. currdef^.count:=true;
  415. currdef:=currdef^.nextoverloaded;
  416. end;
  417. end;
  418. procedure tprocsym.write;
  419. begin
  420. tsym.write;
  421. writedefref(pdef(definition));
  422. current_ppu^.writeentry(ibprocsym);
  423. end;
  424. procedure tprocsym.load_references;
  425. (*var
  426. prdef,prdef2 : pprocdef;
  427. b : byte; *)
  428. begin
  429. inherited load_references;
  430. (*prdef:=definition;
  431. done in tsymtable.load_browser (PM)
  432. { take care about operators !! }
  433. if (current_module^.flags and uf_has_browser) <>0 then
  434. while assigned(prdef) and (prdef^.owner=definition^.owner) do
  435. begin
  436. b:=current_ppu^.readentry;
  437. if b<>ibdefref then
  438. Message(unit_f_ppu_read_error);
  439. prdef2:=pprocdef(readdefref);
  440. resolvedef(prdef2);
  441. if prdef<>prdef2 then
  442. Message(unit_f_ppu_read_error);
  443. prdef^.load_references;
  444. prdef:=prdef^.nextoverloaded;
  445. end; *)
  446. end;
  447. function tprocsym.write_references : boolean;
  448. var
  449. prdef : pprocdef;
  450. begin
  451. write_references:=false;
  452. if not inherited write_references then
  453. exit;
  454. write_references:=true;
  455. prdef:=definition;
  456. while assigned(prdef) and (prdef^.owner=definition^.owner) do
  457. begin
  458. prdef^.write_references;
  459. prdef:=prdef^.nextoverloaded;
  460. end;
  461. end;
  462. {$ifdef BrowserLog}
  463. procedure tprocsym.add_to_browserlog;
  464. var
  465. prdef : pprocdef;
  466. begin
  467. inherited add_to_browserlog;
  468. prdef:=definition;
  469. while assigned(prdef) do
  470. begin
  471. pprocdef(prdef)^.add_to_browserlog;
  472. prdef:=pprocdef(prdef)^.nextoverloaded;
  473. end;
  474. end;
  475. {$endif BrowserLog}
  476. {$ifdef GDB}
  477. function tprocsym.stabstring : pchar;
  478. Var RetType : Char;
  479. Obj,Info : String;
  480. stabsstr : string;
  481. p : pchar;
  482. begin
  483. obj := name;
  484. info := '';
  485. if is_global then
  486. RetType := 'F'
  487. else
  488. RetType := 'f';
  489. if assigned(owner) then
  490. begin
  491. if (owner^.symtabletype = objectsymtable) then
  492. obj := owner^.name^+'__'+name;
  493. { this code was correct only as long as the local symboltable
  494. of the parent had the same name as the function
  495. but this is no true anymore !! PM
  496. if (owner^.symtabletype=localsymtable) and assigned(owner^.name) then
  497. info := ','+name+','+owner^.name^; }
  498. if (owner^.symtabletype=localsymtable) and assigned(owner^.defowner) and
  499. assigned(pprocdef(owner^.defowner)^.procsym) then
  500. info := ','+name+','+pprocdef(owner^.defowner)^.procsym^.name;
  501. end;
  502. stabsstr:=definition^.mangledname;
  503. getmem(p,length(stabsstr)+255);
  504. strpcopy(p,'"'+obj+':'+RetType
  505. +definition^.rettype.def^.numberstring+info+'",'+tostr(n_function)
  506. +',0,'+
  507. tostr(aktfilepos.line)
  508. +',');
  509. strpcopy(strend(p),stabsstr);
  510. stabstring:=strnew(p);
  511. freemem(p,length(stabsstr)+255);
  512. end;
  513. procedure tprocsym.concatstabto(asmlist : paasmoutput);
  514. begin
  515. if (pocall_internproc in definition^.proccalloptions) then exit;
  516. if not isstabwritten then
  517. asmlist^.concat(new(pai_stabs,init(stabstring)));
  518. isstabwritten := true;
  519. if assigned(definition^.parast) then
  520. definition^.parast^.concatstabto(asmlist);
  521. if assigned(definition^.localst) then
  522. definition^.localst^.concatstabto(asmlist);
  523. definition^.is_def_stab_written := true;
  524. end;
  525. {$endif GDB}
  526. {****************************************************************************
  527. TPROGRAMSYM
  528. ****************************************************************************}
  529. constructor tprogramsym.init(const n : string);
  530. begin
  531. inherited init(n);
  532. typ:=programsym;
  533. end;
  534. {****************************************************************************
  535. TERRORSYM
  536. ****************************************************************************}
  537. constructor terrorsym.init;
  538. begin
  539. inherited init('');
  540. typ:=errorsym;
  541. end;
  542. {****************************************************************************
  543. TPROPERTYSYM
  544. ****************************************************************************}
  545. constructor tpropertysym.init(const n : string);
  546. begin
  547. inherited init(n);
  548. typ:=propertysym;
  549. propoptions:=[];
  550. index:=0;
  551. default:=0;
  552. proptype.reset;
  553. indextype.reset;
  554. new(readaccess,init);
  555. new(writeaccess,init);
  556. new(storedaccess,init);
  557. end;
  558. constructor tpropertysym.load;
  559. begin
  560. inherited load;
  561. typ:=propertysym;
  562. readsmallset(propoptions);
  563. if (ppo_is_override in propoptions) then
  564. begin
  565. propoverriden:=ppropertysym(readsymref);
  566. { we need to have these objects initialized }
  567. new(readaccess,init);
  568. new(writeaccess,init);
  569. new(storedaccess,init);
  570. end
  571. else
  572. begin
  573. proptype.load;
  574. index:=readlong;
  575. default:=readlong;
  576. indextype.load;
  577. new(readaccess,load);
  578. new(writeaccess,load);
  579. new(storedaccess,load);
  580. end;
  581. end;
  582. destructor tpropertysym.done;
  583. begin
  584. dispose(readaccess,done);
  585. dispose(writeaccess,done);
  586. dispose(storedaccess,done);
  587. inherited done;
  588. end;
  589. procedure tpropertysym.deref;
  590. begin
  591. if (ppo_is_override in propoptions) then
  592. begin
  593. resolvesym(psym(propoverriden));
  594. dooverride(propoverriden);
  595. end
  596. else
  597. begin
  598. proptype.resolve;
  599. indextype.resolve;
  600. readaccess^.resolve;
  601. writeaccess^.resolve;
  602. storedaccess^.resolve;
  603. end;
  604. end;
  605. function tpropertysym.getsize : longint;
  606. begin
  607. getsize:=0;
  608. end;
  609. procedure tpropertysym.write;
  610. begin
  611. tsym.write;
  612. writesmallset(propoptions);
  613. if (ppo_is_override in propoptions) then
  614. writesymref(propoverriden)
  615. else
  616. begin
  617. proptype.write;
  618. writelong(index);
  619. writelong(default);
  620. indextype.write;
  621. readaccess^.write;
  622. writeaccess^.write;
  623. storedaccess^.write;
  624. end;
  625. current_ppu^.writeentry(ibpropertysym);
  626. end;
  627. procedure tpropertysym.dooverride(overriden:ppropertysym);
  628. begin
  629. propoverriden:=overriden;
  630. proptype:=overriden^.proptype;
  631. propoptions:=overriden^.propoptions+[ppo_is_override];
  632. index:=overriden^.index;
  633. default:=overriden^.default;
  634. indextype:=overriden^.indextype;
  635. readaccess^.clear;
  636. readaccess:=overriden^.readaccess^.getcopy;
  637. writeaccess^.clear;
  638. writeaccess:=overriden^.writeaccess^.getcopy;
  639. storedaccess^.clear;
  640. storedaccess:=overriden^.storedaccess^.getcopy;
  641. end;
  642. {$ifdef GDB}
  643. function tpropertysym.stabstring : pchar;
  644. begin
  645. { !!!! don't know how to handle }
  646. stabstring:=strpnew('');
  647. end;
  648. procedure tpropertysym.concatstabto(asmlist : paasmoutput);
  649. begin
  650. { !!!! don't know how to handle }
  651. end;
  652. {$endif GDB}
  653. {****************************************************************************
  654. TFUNCRETSYM
  655. ****************************************************************************}
  656. constructor tfuncretsym.init(const n : string;approcinfo : pointer{pprocinfo});
  657. begin
  658. tsym.init(n);
  659. typ:=funcretsym;
  660. funcretprocinfo:=approcinfo;
  661. rettype:=pprocinfo(approcinfo)^.returntype;
  662. { address valid for ret in param only }
  663. { otherwise set by insert }
  664. address:=pprocinfo(approcinfo)^.return_offset;
  665. end;
  666. constructor tfuncretsym.load;
  667. begin
  668. tsym.load;
  669. rettype.load;
  670. address:=readlong;
  671. funcretprocinfo:=nil;
  672. typ:=funcretsym;
  673. end;
  674. destructor tfuncretsym.done;
  675. begin
  676. inherited done;
  677. end;
  678. procedure tfuncretsym.write;
  679. begin
  680. tsym.write;
  681. rettype.write;
  682. writelong(address);
  683. current_ppu^.writeentry(ibfuncretsym);
  684. end;
  685. procedure tfuncretsym.deref;
  686. begin
  687. rettype.resolve;
  688. end;
  689. {$ifdef GDB}
  690. procedure tfuncretsym.concatstabto(asmlist : paasmoutput);
  691. begin
  692. { Nothing to do here, it is done in genexitcode }
  693. end;
  694. {$endif GDB}
  695. procedure tfuncretsym.insert_in_data;
  696. var
  697. l : longint;
  698. begin
  699. { if retoffset is already set then reuse it, this is needed
  700. when inserting the result variable }
  701. if procinfo^.return_offset<>0 then
  702. address:=procinfo^.return_offset
  703. else
  704. begin
  705. { allocate space in local if ret in acc or in fpu }
  706. if ret_in_acc(procinfo^.returntype.def) or (procinfo^.returntype.def^.deftype=floatdef) then
  707. begin
  708. l:=rettype.def^.size;
  709. inc(owner^.datasize,l);
  710. {$ifdef m68k}
  711. { word alignment required for motorola }
  712. if (l=1) then
  713. inc(owner^.datasize,1)
  714. else
  715. {$endif}
  716. if (l>=4) and ((owner^.datasize and 3)<>0) then
  717. inc(owner^.datasize,4-(owner^.datasize and 3))
  718. else if (l>=2) and ((owner^.datasize and 1)<>0) then
  719. inc(owner^.datasize,2-(owner^.datasize and 1));
  720. address:=owner^.datasize;
  721. procinfo^.return_offset:=-owner^.datasize;
  722. end;
  723. end;
  724. end;
  725. {****************************************************************************
  726. TABSOLUTESYM
  727. ****************************************************************************}
  728. constructor tabsolutesym.init(const n : string;const tt : ttype);
  729. begin
  730. inherited init(n,tt);
  731. typ:=absolutesym;
  732. end;
  733. constructor tabsolutesym.initdef(const n : string;p : pdef);
  734. var
  735. t : ttype;
  736. begin
  737. t.setdef(p);
  738. tabsolutesym.init(n,t);
  739. end;
  740. constructor tabsolutesym.load;
  741. begin
  742. tvarsym.load;
  743. typ:=absolutesym;
  744. ref:=nil;
  745. address:=0;
  746. asmname:=nil;
  747. abstyp:=absolutetyp(readbyte);
  748. absseg:=false;
  749. case abstyp of
  750. tovar :
  751. begin
  752. asmname:=stringdup(readstring);
  753. ref:=srsym;
  754. end;
  755. toasm :
  756. asmname:=stringdup(readstring);
  757. toaddr :
  758. begin
  759. address:=readlong;
  760. absseg:=boolean(readbyte);
  761. end;
  762. end;
  763. end;
  764. procedure tabsolutesym.write;
  765. var
  766. hvo : tvaroptions;
  767. begin
  768. { Note: This needs to write everything of tvarsym.write }
  769. tsym.write;
  770. writebyte(byte(varspez));
  771. if read_member then
  772. writelong(address);
  773. { write only definition or definitionsym }
  774. vartype.write;
  775. hvo:=varoptions-[vo_regable];
  776. writesmallset(hvo);
  777. writebyte(byte(abstyp));
  778. case abstyp of
  779. tovar :
  780. writestring(ref^.name);
  781. toasm :
  782. writestring(asmname^);
  783. toaddr :
  784. begin
  785. writelong(address);
  786. writebyte(byte(absseg));
  787. end;
  788. end;
  789. current_ppu^.writeentry(ibabsolutesym);
  790. end;
  791. procedure tabsolutesym.deref;
  792. begin
  793. tvarsym.deref;
  794. if (abstyp=tovar) and (asmname<>nil) then
  795. begin
  796. { search previous loaded symtables }
  797. getsym(asmname^,false);
  798. if not(assigned(srsym)) then
  799. getsymonlyin(owner,asmname^);
  800. if not(assigned(srsym)) then
  801. srsym:=generrorsym;
  802. ref:=srsym;
  803. stringdispose(asmname);
  804. end;
  805. end;
  806. function tabsolutesym.mangledname : string;
  807. begin
  808. case abstyp of
  809. tovar :
  810. mangledname:=ref^.mangledname;
  811. toasm :
  812. mangledname:=asmname^;
  813. toaddr :
  814. mangledname:='$'+tostr(address);
  815. else
  816. internalerror(10002);
  817. end;
  818. end;
  819. procedure tabsolutesym.insert_in_data;
  820. begin
  821. end;
  822. {$ifdef GDB}
  823. procedure tabsolutesym.concatstabto(asmlist : paasmoutput);
  824. begin
  825. { I don't know how to handle this !! }
  826. end;
  827. {$endif GDB}
  828. {****************************************************************************
  829. TVARSYM
  830. ****************************************************************************}
  831. constructor tvarsym.init(const n : string;const tt : ttype);
  832. begin
  833. tsym.init(n);
  834. typ:=varsym;
  835. vartype:=tt;
  836. _mangledname:=nil;
  837. varspez:=vs_value;
  838. address:=0;
  839. localvarsym:=nil;
  840. refs:=0;
  841. varstate:=vs_used;
  842. varoptions:=[];
  843. { can we load the value into a register ? }
  844. if tt.def^.is_intregable then
  845. include(varoptions,vo_regable)
  846. else
  847. exclude(varoptions,vo_regable);
  848. if tt.def^.is_fpuregable then
  849. include(varoptions,vo_fpuregable)
  850. else
  851. exclude(varoptions,vo_fpuregable);
  852. reg:=R_NO;
  853. end;
  854. constructor tvarsym.init_dll(const n : string;const tt : ttype);
  855. begin
  856. tvarsym.init(n,tt);
  857. {$ifdef INCLUDEOK}
  858. include(varoptions,vo_is_dll_var);
  859. {$else}
  860. varoptions:=varoptions+[vo_is_dll_var];
  861. {$endif}
  862. end;
  863. constructor tvarsym.init_C(const n,mangled : string;const tt : ttype);
  864. begin
  865. tvarsym.init(n,tt);
  866. {$ifdef INCLUDEOK}
  867. include(varoptions,vo_is_C_var);
  868. {$else}
  869. varoptions:=varoptions+[vo_is_C_var];
  870. {$endif}
  871. setmangledname(mangled);
  872. end;
  873. constructor tvarsym.initdef(const n : string;p : pdef);
  874. var
  875. t : ttype;
  876. begin
  877. t.setdef(p);
  878. tvarsym.init(n,t);
  879. end;
  880. constructor tvarsym.load;
  881. begin
  882. tsym.load;
  883. typ:=varsym;
  884. _mangledname:=nil;
  885. reg:=R_NO;
  886. refs := 0;
  887. varstate:=vs_used;
  888. varspez:=tvarspez(readbyte);
  889. if read_member then
  890. address:=readlong
  891. else
  892. address:=0;
  893. localvarsym:=nil;
  894. vartype.load;
  895. readsmallset(varoptions);
  896. if (vo_is_C_var in varoptions) then
  897. setmangledname(readstring);
  898. end;
  899. destructor tvarsym.done;
  900. begin
  901. strdispose(_mangledname);
  902. inherited done;
  903. end;
  904. procedure tvarsym.deref;
  905. begin
  906. vartype.resolve;
  907. end;
  908. procedure tvarsym.write;
  909. var
  910. hvo : tvaroptions;
  911. begin
  912. tsym.write;
  913. writebyte(byte(varspez));
  914. if read_member then
  915. writelong(address);
  916. vartype.write;
  917. { symbols which are load are never candidates for a register,
  918. turn off the regable }
  919. hvo:=varoptions-[vo_regable];
  920. writesmallset(hvo);
  921. if (vo_is_C_var in varoptions) then
  922. writestring(mangledname);
  923. current_ppu^.writeentry(ibvarsym);
  924. end;
  925. procedure tvarsym.setmangledname(const s : string);
  926. begin
  927. _mangledname:=strpnew(s);
  928. end;
  929. function tvarsym.mangledname : string;
  930. var
  931. prefix : string;
  932. begin
  933. if assigned(_mangledname) then
  934. begin
  935. mangledname:=strpas(_mangledname);
  936. exit;
  937. end;
  938. case owner^.symtabletype of
  939. staticsymtable :
  940. if (cs_create_smart in aktmoduleswitches) then
  941. prefix:='_'+owner^.name^+'$$$_'
  942. else
  943. prefix:='_';
  944. unitsymtable,
  945. globalsymtable :
  946. prefix:=
  947. 'U_'+owner^.name^+'_';
  948. else
  949. Message(sym_e_invalid_call_tvarsymmangledname);
  950. end;
  951. mangledname:=prefix+name;
  952. end;
  953. function tvarsym.getsize : longint;
  954. begin
  955. if assigned(vartype.def) and
  956. (varspez=vs_value) and
  957. ((vartype.def^.deftype<>arraydef) or
  958. (Parraydef(vartype.def)^.highrange>=Parraydef(vartype.def)^.lowrange)) then
  959. getsize:=vartype.def^.size
  960. else
  961. getsize:=0;
  962. end;
  963. function tvarsym.getpushsize : longint;
  964. begin
  965. if assigned(vartype.def) then
  966. begin
  967. case varspez of
  968. vs_var :
  969. getpushsize:=target_os.size_of_pointer;
  970. vs_value,
  971. vs_const :
  972. begin
  973. if push_addr_param(vartype.def) then
  974. getpushsize:=target_os.size_of_pointer
  975. else
  976. getpushsize:=vartype.def^.size;
  977. end;
  978. end;
  979. end
  980. else
  981. getpushsize:=0;
  982. end;
  983. function data_align(length : longint) : longint;
  984. begin
  985. (* this is useless under go32v2 at least
  986. because the section are only align to dword
  987. if length>8 then
  988. data_align:=16
  989. else if length>4 then
  990. data_align:=8
  991. else *)
  992. if length>2 then
  993. data_align:=4
  994. else
  995. if length>1 then
  996. data_align:=2
  997. else
  998. data_align:=1;
  999. end;
  1000. procedure tvarsym.insert_in_data;
  1001. var
  1002. varalign,
  1003. l,ali,modulo : longint;
  1004. storefilepos : tfileposinfo;
  1005. begin
  1006. if (vo_is_external in varoptions) then
  1007. exit;
  1008. { handle static variables of objects especially }
  1009. if read_member and (owner^.symtabletype=objectsymtable) and
  1010. (sp_static in symoptions) then
  1011. begin
  1012. { the data filed is generated in parser.pas
  1013. with a tobject_FIELDNAME variable }
  1014. { this symbol can't be loaded to a register }
  1015. {$ifdef INCLUDEOK}
  1016. exclude(varoptions,vo_regable);
  1017. exclude(varoptions,vo_fpuregable);
  1018. {$else}
  1019. varoptions:=varoptions-[vo_regable,vo_fpuregable];
  1020. {$endif}
  1021. end
  1022. else
  1023. if not(read_member) then
  1024. begin
  1025. { made problems with parameters etc. ! (FK) }
  1026. { check for instance of an abstract object or class }
  1027. {
  1028. if (pvarsym(sym)^.definition^.deftype=objectdef) and
  1029. ((pobjectdef(pvarsym(sym)^.definition)^.options and oo_is_abstract)<>0) then
  1030. Message(sym_e_no_instance_of_abstract_object);
  1031. }
  1032. storefilepos:=aktfilepos;
  1033. aktfilepos:=tokenpos;
  1034. if (vo_is_thread_var in varoptions) then
  1035. l:=4
  1036. else
  1037. l:=getsize;
  1038. case owner^.symtabletype of
  1039. stt_exceptsymtable:
  1040. { can contain only one symbol, address calculated later }
  1041. ;
  1042. localsymtable :
  1043. begin
  1044. varstate:=vs_declared;
  1045. modulo:=owner^.datasize and 3;
  1046. {$ifdef m68k}
  1047. { word alignment required for motorola }
  1048. if (l=1) then
  1049. l:=2
  1050. else
  1051. {$endif}
  1052. {
  1053. if (cs_optimize in aktglobalswitches) and
  1054. (aktoptprocessor in [classp5,classp6]) and
  1055. (l>=8) and ((owner^.datasize and 7)<>0) then
  1056. inc(owner^.datasize,8-(owner^.datasize and 7))
  1057. else
  1058. }
  1059. begin
  1060. if (l>=4) and (modulo<>0) then
  1061. inc(l,4-modulo)
  1062. else
  1063. if (l>=2) and ((modulo and 1)<>0) then
  1064. inc(l,2-(modulo and 1));
  1065. end;
  1066. inc(owner^.datasize,l);
  1067. address:=owner^.datasize;
  1068. end;
  1069. staticsymtable :
  1070. begin
  1071. { enable unitialized warning for local symbols }
  1072. varstate:=vs_declared;
  1073. if (cs_create_smart in aktmoduleswitches) then
  1074. bsssegment^.concat(new(pai_cut,init));
  1075. ali:=data_align(l);
  1076. if ali>1 then
  1077. begin
  1078. modulo:=owner^.datasize mod ali;
  1079. if modulo>0 then
  1080. inc(owner^.datasize,ali-modulo);
  1081. end;
  1082. {$ifdef GDB}
  1083. if cs_debuginfo in aktmoduleswitches then
  1084. concatstabto(bsssegment);
  1085. {$endif GDB}
  1086. if (cs_create_smart in aktmoduleswitches) or
  1087. DLLSource or
  1088. (vo_is_C_var in varoptions) then
  1089. bsssegment^.concat(new(pai_datablock,init_global(mangledname,l)))
  1090. else
  1091. bsssegment^.concat(new(pai_datablock,init(mangledname,l)));
  1092. { increase datasize }
  1093. inc(owner^.datasize,l);
  1094. { this symbol can't be loaded to a register }
  1095. {$ifdef INCLUDEOK}
  1096. exclude(varoptions,vo_regable);
  1097. exclude(varoptions,vo_fpuregable);
  1098. {$else}
  1099. varoptions:=varoptions-[vo_regable,vo_fpuregable];
  1100. {$endif}
  1101. end;
  1102. globalsymtable :
  1103. begin
  1104. if (cs_create_smart in aktmoduleswitches) then
  1105. bsssegment^.concat(new(pai_cut,init));
  1106. ali:=data_align(l);
  1107. if ali>1 then
  1108. begin
  1109. modulo:=owner^.datasize mod ali;
  1110. if modulo>0 then
  1111. inc(owner^.datasize,ali-modulo);
  1112. end;
  1113. {$ifdef GDB}
  1114. if cs_debuginfo in aktmoduleswitches then
  1115. concatstabto(bsssegment);
  1116. {$endif GDB}
  1117. bsssegment^.concat(new(pai_datablock,init_global(mangledname,l)));
  1118. inc(owner^.datasize,l);
  1119. { this symbol can't be loaded to a register }
  1120. {$ifdef INCLUDEOK}
  1121. exclude(varoptions,vo_regable);
  1122. exclude(varoptions,vo_fpuregable);
  1123. {$else}
  1124. varoptions:=varoptions-[vo_regable,vo_fpuregable];
  1125. {$endif}
  1126. end;
  1127. recordsymtable,
  1128. objectsymtable :
  1129. begin
  1130. { this symbol can't be loaded to a register }
  1131. {$ifdef INCLUDEOK}
  1132. exclude(varoptions,vo_regable);
  1133. exclude(varoptions,vo_fpuregable);
  1134. {$else}
  1135. varoptions:=varoptions-[vo_regable,vo_fpuregable];
  1136. {$endif}
  1137. { get the alignment size }
  1138. if (aktpackrecords=packrecord_C) then
  1139. begin
  1140. varalign:=vartype.def^.alignment;
  1141. if varalign=0 then
  1142. begin
  1143. if (owner^.dataalignment<4) then
  1144. begin
  1145. if (l>=4) then
  1146. owner^.dataalignment:=4
  1147. else
  1148. if (owner^.dataalignment<2) and (l>=2) then
  1149. owner^.dataalignment:=2;
  1150. end;
  1151. end;
  1152. end
  1153. else
  1154. varalign:=0;
  1155. { align record and object fields }
  1156. if (l=1) or (varalign=1) or (owner^.dataalignment=1) then
  1157. begin
  1158. address:=owner^.datasize;
  1159. inc(owner^.datasize,l)
  1160. end
  1161. else
  1162. if (l=2) or (varalign=2) or (owner^.dataalignment=2) then
  1163. begin
  1164. owner^.datasize:=(owner^.datasize+1) and (not 1);
  1165. address:=owner^.datasize;
  1166. inc(owner^.datasize,l)
  1167. end
  1168. else
  1169. if (l<=4) or (varalign=4) or (owner^.dataalignment=4) then
  1170. begin
  1171. owner^.datasize:=(owner^.datasize+3) and (not 3);
  1172. address:=owner^.datasize;
  1173. inc(owner^.datasize,l);
  1174. end
  1175. else
  1176. if (l<=8) or (owner^.dataalignment=8) then
  1177. begin
  1178. owner^.datasize:=(owner^.datasize+7) and (not 7);
  1179. address:=owner^.datasize;
  1180. inc(owner^.datasize,l);
  1181. end
  1182. else
  1183. if (l<=16) or (owner^.dataalignment=16) then
  1184. begin
  1185. owner^.datasize:=(owner^.datasize+15) and (not 15);
  1186. address:=owner^.datasize;
  1187. inc(owner^.datasize,l);
  1188. end
  1189. else
  1190. if (l<=32) or (owner^.dataalignment=32) then
  1191. begin
  1192. owner^.datasize:=(owner^.datasize+31) and (not 31);
  1193. address:=owner^.datasize;
  1194. inc(owner^.datasize,l);
  1195. end;
  1196. end;
  1197. parasymtable :
  1198. begin
  1199. { here we need the size of a push instead of the
  1200. size of the data }
  1201. l:=getpushsize;
  1202. varstate:=vs_assigned;
  1203. address:=owner^.datasize;
  1204. owner^.datasize:=align(owner^.datasize+l,target_os.stackalignment);
  1205. end
  1206. else
  1207. begin
  1208. modulo:=owner^.datasize and 3;
  1209. if (l>=4) and (modulo<>0) then
  1210. inc(owner^.datasize,4-modulo)
  1211. else
  1212. if (l>=2) and ((modulo and 1)<>0) then
  1213. inc(owner^.datasize);
  1214. address:=owner^.datasize;
  1215. inc(owner^.datasize,l);
  1216. end;
  1217. end;
  1218. aktfilepos:=storefilepos;
  1219. end;
  1220. end;
  1221. {$ifdef GDB}
  1222. function tvarsym.stabstring : pchar;
  1223. var
  1224. st : string[2];
  1225. begin
  1226. if (vartype.def^.deftype=objectdef) and
  1227. pobjectdef(vartype.def)^.is_class then
  1228. st:='*'
  1229. else
  1230. st:='';
  1231. if (owner^.symtabletype = objectsymtable) and
  1232. (sp_static in symoptions) then
  1233. begin
  1234. if (cs_gdb_gsym in aktglobalswitches) then st := 'G'+st else st := 'S'+st;
  1235. {$ifndef Delphi}
  1236. stabstring := strpnew('"'+owner^.name^+'__'+name+':'+st+
  1237. +vartype.def^.numberstring+'",'+
  1238. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1239. {$endif}
  1240. end
  1241. else if (owner^.symtabletype = globalsymtable) or
  1242. (owner^.symtabletype = unitsymtable) then
  1243. begin
  1244. { Here we used S instead of
  1245. because with G GDB doesn't look at the address field
  1246. but searches the same name or with a leading underscore
  1247. but these names don't exist in pascal !}
  1248. if (cs_gdb_gsym in aktglobalswitches) then st := 'G'+st else st := 'S'+st;
  1249. stabstring := strpnew('"'+name+':'+st
  1250. +vartype.def^.numberstring+'",'+
  1251. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1252. end
  1253. else if owner^.symtabletype = staticsymtable then
  1254. begin
  1255. stabstring := strpnew('"'+name+':S'+st
  1256. +vartype.def^.numberstring+'",'+
  1257. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1258. end
  1259. else if (owner^.symtabletype in [parasymtable,inlineparasymtable]) then
  1260. begin
  1261. case varspez of
  1262. vs_var : st := 'v'+st;
  1263. vs_value,
  1264. vs_const : if push_addr_param(vartype.def) then
  1265. st := 'v'+st { should be 'i' but 'i' doesn't work }
  1266. else
  1267. st := 'p'+st;
  1268. end;
  1269. stabstring := strpnew('"'+name+':'+st
  1270. +vartype.def^.numberstring+'",'+
  1271. tostr(N_PSYM)+',0,'+tostr(fileinfo.line)+','+
  1272. tostr(address+owner^.address_fixup));
  1273. {offset to ebp => will not work if the framepointer is esp
  1274. so some optimizing will make things harder to debug }
  1275. end
  1276. else if (owner^.symtabletype in [localsymtable,inlinelocalsymtable]) then
  1277. {$ifdef i386}
  1278. if reg<>R_NO then
  1279. begin
  1280. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1281. { this is the register order for GDB}
  1282. stabstring:=strpnew('"'+name+':r'+st
  1283. +vartype.def^.numberstring+'",'+
  1284. tostr(N_RSYM)+',0,'+
  1285. tostr(fileinfo.line)+','+tostr(GDB_i386index[reg]));
  1286. end
  1287. else
  1288. {$endif i386}
  1289. { I don't know if this will work (PM) }
  1290. if (vo_is_C_var in varoptions) then
  1291. stabstring := strpnew('"'+name+':S'+st
  1292. +vartype.def^.numberstring+'",'+
  1293. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname)
  1294. else
  1295. stabstring := strpnew('"'+name+':'+st
  1296. +vartype.def^.numberstring+'",'+
  1297. tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',-'+tostr(address-owner^.address_fixup))
  1298. else
  1299. stabstring := inherited stabstring;
  1300. end;
  1301. procedure tvarsym.concatstabto(asmlist : paasmoutput);
  1302. {$ifdef i386}
  1303. var stab_str : pchar;
  1304. {$endif i386}
  1305. begin
  1306. inherited concatstabto(asmlist);
  1307. {$ifdef i386}
  1308. if (owner^.symtabletype=parasymtable) and
  1309. (reg<>R_NO) then
  1310. begin
  1311. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1312. { this is the register order for GDB}
  1313. stab_str:=strpnew('"'+name+':r'
  1314. +vartype.def^.numberstring+'",'+
  1315. tostr(N_RSYM)+',0,'+
  1316. tostr(fileinfo.line)+','+tostr(GDB_i386index[reg]));
  1317. asmlist^.concat(new(pai_stabs,init(stab_str)));
  1318. end;
  1319. {$endif i386}
  1320. end;
  1321. {$endif GDB}
  1322. {****************************************************************************
  1323. TTYPEDCONSTSYM
  1324. *****************************************************************************}
  1325. constructor ttypedconstsym.init(const n : string;p : pdef;really_const : boolean);
  1326. begin
  1327. tsym.init(n);
  1328. typ:=typedconstsym;
  1329. typedconsttype.setdef(p);
  1330. is_really_const:=really_const;
  1331. prefix:=stringdup(procprefix);
  1332. end;
  1333. constructor ttypedconstsym.inittype(const n : string;const tt : ttype;really_const : boolean);
  1334. begin
  1335. ttypedconstsym.init(n,nil,really_const);
  1336. typedconsttype:=tt;
  1337. end;
  1338. constructor ttypedconstsym.load;
  1339. begin
  1340. tsym.load;
  1341. typ:=typedconstsym;
  1342. typedconsttype.load;
  1343. prefix:=stringdup(readstring);
  1344. is_really_const:=boolean(readbyte);
  1345. end;
  1346. destructor ttypedconstsym.done;
  1347. begin
  1348. stringdispose(prefix);
  1349. tsym.done;
  1350. end;
  1351. function ttypedconstsym.mangledname : string;
  1352. begin
  1353. mangledname:='TC_'+prefix^+'_'+name;
  1354. end;
  1355. function ttypedconstsym.getsize : longint;
  1356. begin
  1357. if assigned(typedconsttype.def) then
  1358. getsize:=typedconsttype.def^.size
  1359. else
  1360. getsize:=0;
  1361. end;
  1362. procedure ttypedconstsym.deref;
  1363. begin
  1364. typedconsttype.resolve;
  1365. end;
  1366. procedure ttypedconstsym.write;
  1367. begin
  1368. tsym.write;
  1369. typedconsttype.write;
  1370. writestring(prefix^);
  1371. writebyte(byte(is_really_const));
  1372. current_ppu^.writeentry(ibtypedconstsym);
  1373. end;
  1374. procedure ttypedconstsym.insert_in_data;
  1375. var
  1376. curconstsegment : paasmoutput;
  1377. l,ali,modulo : longint;
  1378. storefilepos : tfileposinfo;
  1379. begin
  1380. storefilepos:=aktfilepos;
  1381. aktfilepos:=tokenpos;
  1382. if is_really_const then
  1383. curconstsegment:=consts
  1384. else
  1385. curconstsegment:=datasegment;
  1386. if (cs_create_smart in aktmoduleswitches) then
  1387. curconstsegment^.concat(new(pai_cut,init));
  1388. l:=getsize;
  1389. ali:=data_align(l);
  1390. if ali>1 then
  1391. begin
  1392. curconstsegment^.concat(new(pai_align,init(ali)));
  1393. modulo:=owner^.datasize mod ali;
  1394. if modulo>0 then
  1395. inc(owner^.datasize,ali-modulo);
  1396. end;
  1397. { Why was there no owner size update here ??? }
  1398. inc(owner^.datasize,l);
  1399. {$ifdef GDB}
  1400. if cs_debuginfo in aktmoduleswitches then
  1401. concatstabto(curconstsegment);
  1402. {$endif GDB}
  1403. if owner^.symtabletype=globalsymtable then
  1404. begin
  1405. curconstsegment^.concat(new(pai_symbol,initname_global(mangledname,getsize)));
  1406. end
  1407. else
  1408. if owner^.symtabletype<>unitsymtable then
  1409. begin
  1410. if (cs_create_smart in aktmoduleswitches) or
  1411. DLLSource then
  1412. curconstsegment^.concat(new(pai_symbol,initname_global(mangledname,getsize)))
  1413. else
  1414. curconstsegment^.concat(new(pai_symbol,initname(mangledname,getsize)));
  1415. end;
  1416. aktfilepos:=storefilepos;
  1417. end;
  1418. {$ifdef GDB}
  1419. function ttypedconstsym.stabstring : pchar;
  1420. var
  1421. st : char;
  1422. begin
  1423. if (cs_gdb_gsym in aktglobalswitches) and (owner^.symtabletype in [unitsymtable,globalsymtable]) then
  1424. st := 'G'
  1425. else
  1426. st := 'S';
  1427. stabstring := strpnew('"'+name+':'+st+
  1428. typedconsttype.def^.numberstring+'",'+tostr(n_STSYM)+',0,'+
  1429. tostr(fileinfo.line)+','+mangledname);
  1430. end;
  1431. {$endif GDB}
  1432. {****************************************************************************
  1433. TCONSTSYM
  1434. ****************************************************************************}
  1435. constructor tconstsym.init(const n : string;t : tconsttyp;v : longint);
  1436. begin
  1437. inherited init(n);
  1438. typ:=constsym;
  1439. consttyp:=t;
  1440. value:=v;
  1441. ResStrIndex:=0;
  1442. consttype.reset;
  1443. len:=0;
  1444. end;
  1445. constructor tconstsym.init_def(const n : string;t : tconsttyp;v : longint;def : pdef);
  1446. begin
  1447. inherited init(n);
  1448. typ:=constsym;
  1449. consttyp:=t;
  1450. value:=v;
  1451. consttype.setdef(def);
  1452. len:=0;
  1453. end;
  1454. constructor tconstsym.init_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  1455. begin
  1456. inherited init(n);
  1457. typ:=constsym;
  1458. consttyp:=t;
  1459. value:=longint(str);
  1460. consttype.reset;
  1461. len:=l;
  1462. if t=constresourcestring then
  1463. ResStrIndex:=registerresourcestring(name,pchar(value),len);
  1464. end;
  1465. constructor tconstsym.load;
  1466. var
  1467. pd : pbestreal;
  1468. ps : pnormalset;
  1469. begin
  1470. tsym.load;
  1471. typ:=constsym;
  1472. consttype.reset;
  1473. consttyp:=tconsttyp(readbyte);
  1474. case consttyp of
  1475. constint,
  1476. constbool,
  1477. constchar :
  1478. value:=readlong;
  1479. constpointer,
  1480. constord :
  1481. begin
  1482. consttype.load;
  1483. value:=readlong;
  1484. end;
  1485. conststring,constresourcestring :
  1486. begin
  1487. len:=readlong;
  1488. getmem(pchar(value),len+1);
  1489. current_ppu^.getdata(pchar(value)^,len);
  1490. if consttyp=constresourcestring then
  1491. ResStrIndex:=readlong;
  1492. end;
  1493. constreal :
  1494. begin
  1495. new(pd);
  1496. pd^:=readreal;
  1497. value:=longint(pd);
  1498. end;
  1499. constset :
  1500. begin
  1501. consttype.load;
  1502. new(ps);
  1503. readnormalset(ps^);
  1504. value:=longint(ps);
  1505. end;
  1506. constnil : ;
  1507. else
  1508. Message1(unit_f_ppu_invalid_entry,tostr(ord(consttyp)));
  1509. end;
  1510. end;
  1511. destructor tconstsym.done;
  1512. begin
  1513. case consttyp of
  1514. conststring :
  1515. freemem(pchar(value),len+1);
  1516. constreal :
  1517. dispose(pbestreal(value));
  1518. constset :
  1519. dispose(pnormalset(value));
  1520. end;
  1521. inherited done;
  1522. end;
  1523. function tconstsym.mangledname : string;
  1524. begin
  1525. mangledname:=name;
  1526. end;
  1527. procedure tconstsym.deref;
  1528. begin
  1529. if consttyp in [constord,constpointer,constset] then
  1530. consttype.resolve;
  1531. end;
  1532. procedure tconstsym.write;
  1533. begin
  1534. tsym.write;
  1535. writebyte(byte(consttyp));
  1536. case consttyp of
  1537. constnil : ;
  1538. constint,
  1539. constbool,
  1540. constchar :
  1541. writelong(value);
  1542. constpointer,
  1543. constord :
  1544. begin
  1545. consttype.write;
  1546. writelong(value);
  1547. end;
  1548. conststring,constresourcestring :
  1549. begin
  1550. writelong(len);
  1551. current_ppu^.putdata(pchar(value)^,len);
  1552. if consttyp=constresourcestring then
  1553. writelong(ResStrIndex);
  1554. end;
  1555. constreal :
  1556. writereal(pbestreal(value)^);
  1557. constset :
  1558. begin
  1559. consttype.write;
  1560. writenormalset(pointer(value)^);
  1561. end;
  1562. else
  1563. internalerror(13);
  1564. end;
  1565. current_ppu^.writeentry(ibconstsym);
  1566. end;
  1567. {$ifdef GDB}
  1568. function tconstsym.stabstring : pchar;
  1569. var st : string;
  1570. begin
  1571. {even GDB v4.16 only now 'i' 'r' and 'e' !!!}
  1572. case consttyp of
  1573. conststring : begin
  1574. { I had to remove ibm2ascii !! }
  1575. st := pstring(value)^;
  1576. {st := ibm2ascii(pstring(value)^);}
  1577. st := 's'''+st+'''';
  1578. end;
  1579. constbool,
  1580. constint,
  1581. constpointer,
  1582. constord,
  1583. constchar : st := 'i'+tostr(value);
  1584. constreal : begin
  1585. system.str(pbestreal(value)^,st);
  1586. st := 'r'+st;
  1587. end;
  1588. { if we don't know just put zero !! }
  1589. else st:='i0';
  1590. {***SETCONST}
  1591. {constset:;} {*** I don't know what to do with a set.}
  1592. { sets are not recognized by GDB}
  1593. {***}
  1594. end;
  1595. stabstring := strpnew('"'+name+':c='+st+'",'+tostr(N_function)+',0,'+
  1596. tostr(fileinfo.line)+',0');
  1597. end;
  1598. procedure tconstsym.concatstabto(asmlist : paasmoutput);
  1599. begin
  1600. if consttyp <> conststring then
  1601. inherited concatstabto(asmlist);
  1602. end;
  1603. {$endif GDB}
  1604. {****************************************************************************
  1605. TENUMSYM
  1606. ****************************************************************************}
  1607. constructor tenumsym.init(const n : string;def : penumdef;v : longint);
  1608. begin
  1609. tsym.init(n);
  1610. typ:=enumsym;
  1611. definition:=def;
  1612. value:=v;
  1613. if def^.min>v then
  1614. def^.setmin(v);
  1615. if def^.max<v then
  1616. def^.setmax(v);
  1617. order;
  1618. end;
  1619. constructor tenumsym.load;
  1620. begin
  1621. tsym.load;
  1622. typ:=enumsym;
  1623. definition:=penumdef(readdefref);
  1624. value:=readlong;
  1625. nextenum := Nil;
  1626. end;
  1627. procedure tenumsym.deref;
  1628. begin
  1629. resolvedef(pdef(definition));
  1630. order;
  1631. end;
  1632. procedure tenumsym.order;
  1633. var
  1634. sym : penumsym;
  1635. begin
  1636. sym := definition^.firstenum;
  1637. if sym = nil then
  1638. begin
  1639. definition^.firstenum := @self;
  1640. nextenum := nil;
  1641. exit;
  1642. end;
  1643. { reorder the symbols in increasing value }
  1644. if value < sym^.value then
  1645. begin
  1646. nextenum := sym;
  1647. definition^.firstenum := @self;
  1648. end
  1649. else
  1650. begin
  1651. while (sym^.value <= value) and assigned(sym^.nextenum) do
  1652. sym := sym^.nextenum;
  1653. nextenum := sym^.nextenum;
  1654. sym^.nextenum := @self;
  1655. end;
  1656. end;
  1657. procedure tenumsym.write;
  1658. begin
  1659. tsym.write;
  1660. writedefref(definition);
  1661. writelong(value);
  1662. current_ppu^.writeentry(ibenumsym);
  1663. end;
  1664. {$ifdef GDB}
  1665. procedure tenumsym.concatstabto(asmlist : paasmoutput);
  1666. begin
  1667. {enum elements have no stab !}
  1668. end;
  1669. {$EndIf GDB}
  1670. {****************************************************************************
  1671. TTYPESYM
  1672. ****************************************************************************}
  1673. constructor ttypesym.init(const n : string;const tt : ttype);
  1674. begin
  1675. tsym.init(n);
  1676. typ:=typesym;
  1677. restype:=tt;
  1678. {$ifdef GDB}
  1679. isusedinstab := false;
  1680. {$endif GDB}
  1681. {$ifdef SYNONYM}
  1682. if assigned(restype.def) then
  1683. begin
  1684. if not(assigned(restype.def^.typesym)) then
  1685. begin
  1686. restype.def^.typesym:=@self;
  1687. synonym:=nil;
  1688. {$ifdef INCLUDEOK}
  1689. include(symoptions,sp_primary_typesym);
  1690. {$else}
  1691. symoptions:=symoptions+[sp_primary_typesym];
  1692. {$endif}
  1693. end
  1694. else
  1695. begin
  1696. synonym:=restype.def^.typesym^.synonym;
  1697. restype.def^.typesym^.synonym:=@self;
  1698. end;
  1699. end;
  1700. {$else}
  1701. { register the typesym for the definition }
  1702. if assigned(restype.def) and
  1703. not(assigned(restype.def^.typesym)) then
  1704. restype.def^.typesym:=@self;
  1705. {$endif}
  1706. end;
  1707. constructor ttypesym.initdef(const n : string;d : pdef);
  1708. var
  1709. t : ttype;
  1710. begin
  1711. t.setdef(d);
  1712. ttypesym.init(n,t);
  1713. end;
  1714. constructor ttypesym.load;
  1715. begin
  1716. tsym.load;
  1717. typ:=typesym;
  1718. {$ifdef SYNONYM}
  1719. synonym:=nil;
  1720. {$endif}
  1721. {$ifdef GDB}
  1722. isusedinstab := false;
  1723. {$endif GDB}
  1724. restype.load;
  1725. end;
  1726. {$ifdef SYNONYM}
  1727. destructor ttypesym.done;
  1728. var
  1729. prevsym : ptypesym;
  1730. begin
  1731. if assigned(restype.def) then
  1732. begin
  1733. prevsym:=restype.def^.typesym;
  1734. if prevsym=@self then
  1735. restype.def^.typesym:=synonym;
  1736. while assigned(prevsym) do
  1737. begin
  1738. if (prevsym^.synonym=@self) then
  1739. begin
  1740. prevsym^.synonym:=synonym;
  1741. break;
  1742. end;
  1743. prevsym:=prevsym^.synonym;
  1744. end;
  1745. end;
  1746. synonym:=nil;
  1747. inherited done;
  1748. end;
  1749. {$endif}
  1750. procedure ttypesym.prederef;
  1751. begin
  1752. restype.resolve;
  1753. {$ifdef SYNONYM}
  1754. if assigned(restype.def) then
  1755. begin
  1756. if (sp_primary_typesym in symoptions) then
  1757. begin
  1758. if restype.def^.typesym<>@self then
  1759. synonym:=restype.def^.typesym;
  1760. restype.def^.typesym:=@self;
  1761. end
  1762. else
  1763. begin
  1764. if assigned(restype.def^.typesym) then
  1765. begin
  1766. synonym:=restype.def^.typesym^.synonym;
  1767. if restype.def^.typesym<>@self then
  1768. restype.def^.typesym^.synonym:=@self;
  1769. end
  1770. else
  1771. restype.def^.typesym:=@self;
  1772. end;
  1773. if (restype.def^.deftype=recorddef) and assigned(precorddef(restype.def)^.symtable) and
  1774. (restype.def^.typesym=@self) then
  1775. precorddef(restype.def)^.symtable^.name:=stringdup('record '+name);
  1776. end;
  1777. {$endif}
  1778. end;
  1779. procedure ttypesym.write;
  1780. begin
  1781. tsym.write;
  1782. restype.write;
  1783. current_ppu^.writeentry(ibtypesym);
  1784. end;
  1785. procedure ttypesym.load_references;
  1786. begin
  1787. inherited load_references;
  1788. if (restype.def^.deftype=recorddef) then
  1789. precorddef(restype.def)^.symtable^.load_browser;
  1790. if (restype.def^.deftype=objectdef) then
  1791. pobjectdef(restype.def)^.symtable^.load_browser;
  1792. end;
  1793. function ttypesym.write_references : boolean;
  1794. begin
  1795. if not inherited write_references then
  1796. { write address of this symbol if record or object
  1797. even if no real refs are there
  1798. because we need it for the symtable }
  1799. if (restype.def^.deftype=recorddef) or
  1800. (restype.def^.deftype=objectdef) then
  1801. begin
  1802. writesymref(@self);
  1803. current_ppu^.writeentry(ibsymref);
  1804. end;
  1805. write_references:=true;
  1806. if (restype.def^.deftype=recorddef) then
  1807. precorddef(restype.def)^.symtable^.write_browser;
  1808. if (restype.def^.deftype=objectdef) then
  1809. pobjectdef(restype.def)^.symtable^.write_browser;
  1810. end;
  1811. {$ifdef BrowserLog}
  1812. procedure ttypesym.add_to_browserlog;
  1813. begin
  1814. inherited add_to_browserlog;
  1815. if (restype.def^.deftype=recorddef) then
  1816. precorddef(restype.def)^.symtable^.writebrowserlog;
  1817. if (restype.def^.deftype=objectdef) then
  1818. pobjectdef(restype.def)^.symtable^.writebrowserlog;
  1819. end;
  1820. {$endif BrowserLog}
  1821. {$ifdef GDB}
  1822. function ttypesym.stabstring : pchar;
  1823. var
  1824. stabchar : string[2];
  1825. short : string;
  1826. begin
  1827. if restype.def^.deftype in tagtypes then
  1828. stabchar := 'Tt'
  1829. else
  1830. stabchar := 't';
  1831. short := '"'+name+':'+stabchar+restype.def^.numberstring
  1832. +'",'+tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',0';
  1833. stabstring := strpnew(short);
  1834. end;
  1835. procedure ttypesym.concatstabto(asmlist : paasmoutput);
  1836. begin
  1837. {not stabs for forward defs }
  1838. if assigned(restype.def) then
  1839. if (restype.def^.typesym = @self) then
  1840. restype.def^.concatstabto(asmlist)
  1841. else
  1842. inherited concatstabto(asmlist);
  1843. end;
  1844. {$endif GDB}
  1845. {****************************************************************************
  1846. TSYSSYM
  1847. ****************************************************************************}
  1848. constructor tsyssym.init(const n : string;l : longint);
  1849. begin
  1850. inherited init(n);
  1851. typ:=syssym;
  1852. number:=l;
  1853. end;
  1854. constructor tsyssym.load;
  1855. begin
  1856. tsym.load;
  1857. typ:=syssym;
  1858. number:=readlong;
  1859. end;
  1860. destructor tsyssym.done;
  1861. begin
  1862. inherited done;
  1863. end;
  1864. procedure tsyssym.write;
  1865. begin
  1866. tsym.write;
  1867. writelong(number);
  1868. current_ppu^.writeentry(ibsyssym);
  1869. end;
  1870. {$ifdef GDB}
  1871. procedure tsyssym.concatstabto(asmlist : paasmoutput);
  1872. begin
  1873. end;
  1874. {$endif GDB}
  1875. {****************************************************************************
  1876. TMACROSYM
  1877. ****************************************************************************}
  1878. constructor tmacrosym.init(const n : string);
  1879. begin
  1880. inherited init(n);
  1881. typ:=macrosym;
  1882. defined:=true;
  1883. defined_at_startup:=false;
  1884. is_used:=false;
  1885. buftext:=nil;
  1886. buflen:=0;
  1887. end;
  1888. destructor tmacrosym.done;
  1889. begin
  1890. if assigned(buftext) then
  1891. freemem(buftext,buflen);
  1892. inherited done;
  1893. end;
  1894. {
  1895. $Log$
  1896. Revision 1.141 2000-04-03 14:50:05 pierre
  1897. * avoid cyclic overloaded list for operators
  1898. Revision 1.140 2000/03/01 00:03:10 pierre
  1899. * fixes for locals in inlined procedures
  1900. fix for bug797
  1901. + stabs generation for inlined paras and locals
  1902. Revision 1.139 2000/02/11 13:53:49 pierre
  1903. * avoid stack overflow in tref.done (bug 846)
  1904. Revision 1.138 2000/02/09 13:23:05 peter
  1905. * log truncated
  1906. Revision 1.137 2000/02/04 08:47:10 florian
  1907. * better register variable allocation in -Or mode
  1908. Revision 1.136 2000/01/07 01:14:40 peter
  1909. * updated copyright to 2000
  1910. Revision 1.135 2000/01/03 19:26:04 peter
  1911. * fixed resolving of ttypesym which are reference from object/record
  1912. fields.
  1913. Revision 1.134 1999/12/20 21:42:37 pierre
  1914. + dllversion global variable
  1915. * FPC_USE_CPREFIX code removed, not necessary anymore
  1916. as we use .edata direct writing by default now.
  1917. Revision 1.133 1999/12/14 09:58:42 florian
  1918. + compiler checks now if a goto leaves an exception block
  1919. Revision 1.132 1999/12/01 12:42:33 peter
  1920. * fixed bug 698
  1921. * removed some notes about unused vars
  1922. Revision 1.131 1999/11/30 10:40:55 peter
  1923. + ttype, tsymlist
  1924. Revision 1.130 1999/11/26 00:19:12 peter
  1925. * property overriding dereference fix, but it need a bigger redesign
  1926. which i'll do tomorrow. This quick hack is for the lazarus ppl so
  1927. they can hack on mwcustomedit.
  1928. Revision 1.129 1999/11/21 01:42:37 pierre
  1929. * Nextoverloading ordering fix
  1930. Revision 1.128 1999/11/20 01:22:20 pierre
  1931. + cond FPC_USE_CPREFIX (needs also some RTL changes)
  1932. this allows to use unit global vars as DLL exports
  1933. (the underline prefix seems needed by dlltool)
  1934. Revision 1.127 1999/11/17 17:05:04 pierre
  1935. * Notes/hints changes
  1936. Revision 1.126 1999/11/15 22:00:48 peter
  1937. * labels used but not defined give error instead of warning, the warning
  1938. is now only with declared but not defined and not used.
  1939. Revision 1.125 1999/11/08 14:02:17 florian
  1940. * problem with "index X"-properties solved
  1941. * typed constants of class references are now allowed
  1942. Revision 1.124 1999/11/06 14:34:27 peter
  1943. * truncated log to 20 revs
  1944. Revision 1.123 1999/11/05 17:18:03 pierre
  1945. * local browsing works at first level
  1946. ie for function defined in interface or implementation
  1947. not yet for functions inside other functions
  1948. Revision 1.122 1999/10/21 16:41:41 florian
  1949. * problems with readln fixed: esi wasn't restored correctly when
  1950. reading ordinal fields of objects futher the register allocation
  1951. didn't take care of the extra register when reading ordinal values
  1952. * enumerations can now be used in constant indexes of properties
  1953. Revision 1.121 1999/10/01 08:02:48 peter
  1954. * forward type declaration rewritten
  1955. Revision 1.120 1999/09/27 23:44:58 peter
  1956. * procinfo is now a pointer
  1957. * support for result setting in sub procedure
  1958. Revision 1.119 1999/09/26 21:30:22 peter
  1959. + constant pointer support which can happend with typecasting like
  1960. const p=pointer(1)
  1961. * better procvar parsing in typed consts
  1962. Revision 1.118 1999/09/20 16:39:03 peter
  1963. * cs_create_smart instead of cs_smartlink
  1964. * -CX is create smartlink
  1965. * -CD is create dynamic, but does nothing atm.
  1966. }