symsym.inc 64 KB

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