symsym.inc 63 KB

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