symdef.inc 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl, Pierre Muller
  4. Symbol table implementation for the defenitions
  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. TDEF (base class for defenitions)
  20. ****************************************************************************}
  21. constructor tdef.init;
  22. begin
  23. deftype:=abstractdef;
  24. owner := nil;
  25. next := nil;
  26. sym := nil;
  27. indexnb := 0;
  28. if registerdef then
  29. symtablestack^.registerdef(@self);
  30. has_rtti:=false;
  31. {$ifdef GDB}
  32. is_def_stab_written := false;
  33. globalnb := 0;
  34. if assigned(lastglobaldef) then
  35. begin
  36. lastglobaldef^.nextglobal := @self;
  37. previousglobal:=lastglobaldef;
  38. end
  39. else
  40. begin
  41. firstglobaldef := @self;
  42. previousglobal := nil;
  43. end;
  44. lastglobaldef := @self;
  45. nextglobal := nil;
  46. {$endif GDB}
  47. end;
  48. constructor tdef.load;
  49. begin
  50. deftype:=abstractdef;
  51. indexnb := 0;
  52. sym := nil;
  53. owner := nil;
  54. next := nil;
  55. has_rtti:=false;
  56. {$ifdef GDB}
  57. is_def_stab_written := false;
  58. globalnb := 0;
  59. if assigned(lastglobaldef) then
  60. begin
  61. lastglobaldef^.nextglobal := @self;
  62. previousglobal:=lastglobaldef;
  63. end
  64. else
  65. begin
  66. firstglobaldef := @self;
  67. previousglobal:=nil;
  68. end;
  69. lastglobaldef := @self;
  70. nextglobal := nil;
  71. {$endif GDB}
  72. end;
  73. destructor tdef.done;
  74. begin
  75. {$ifdef GDB}
  76. { first element ? }
  77. if not(assigned(previousglobal)) then
  78. begin
  79. firstglobaldef := nextglobal;
  80. if assigned(firstglobaldef) then
  81. firstglobaldef^.previousglobal:=nil;
  82. end
  83. else
  84. begin
  85. { remove reference in the element before }
  86. previousglobal^.nextglobal:=nextglobal;
  87. end;
  88. { last element ? }
  89. if not(assigned(nextglobal)) then
  90. begin
  91. lastglobaldef := previousglobal;
  92. if assigned(lastglobaldef) then
  93. lastglobaldef^.nextglobal:=nil;
  94. end
  95. else
  96. nextglobal^.previousglobal:=previousglobal;
  97. previousglobal:=nil;
  98. nextglobal:=nil;
  99. {$endif GDB}
  100. end;
  101. procedure tdef.write;
  102. begin
  103. {$ifdef GDB}
  104. if globalnb = 0 then
  105. begin
  106. if assigned(owner) then
  107. globalnb := owner^.getnewtypecount
  108. else
  109. begin
  110. globalnb := PGlobalTypeCount^;
  111. Inc(PGlobalTypeCount^);
  112. end;
  113. end;
  114. {$endif GDB}
  115. end;
  116. function tdef.size : longint;
  117. begin
  118. size:=savesize;
  119. end;
  120. {$ifdef GDB}
  121. procedure tdef.set_globalnb;
  122. begin
  123. globalnb :=PGlobalTypeCount^;
  124. inc(PglobalTypeCount^);
  125. end;
  126. function tdef.stabstring : pchar;
  127. begin
  128. stabstring := strpnew('t'+numberstring+';');
  129. end;
  130. function tdef.numberstring : string;
  131. var table : psymtable;
  132. begin
  133. {formal def have no type !}
  134. if deftype = formaldef then
  135. begin
  136. numberstring := voiddef^.numberstring;
  137. exit;
  138. end;
  139. if (not assigned(sym)) or (not sym^.isusedinstab) then
  140. begin
  141. {set even if debuglist is not defined}
  142. if assigned(sym) then
  143. sym^.isusedinstab := true;
  144. if assigned(debuglist) and not is_def_stab_written then
  145. concatstabto(debuglist);
  146. end;
  147. if not use_dbx then
  148. begin
  149. if globalnb = 0 then
  150. set_globalnb;
  151. numberstring := tostr(globalnb);
  152. end
  153. else
  154. begin
  155. if globalnb = 0 then
  156. begin
  157. if assigned(owner) then
  158. globalnb := owner^.getnewtypecount
  159. else
  160. begin
  161. globalnb := PGlobalTypeCount^;
  162. Inc(PGlobalTypeCount^);
  163. end;
  164. end;
  165. if assigned(sym) then
  166. begin
  167. table := sym^.owner;
  168. if table^.unitid > 0 then
  169. numberstring := '('+tostr(table^.unitid)+','
  170. +tostr(sym^.definition^.globalnb)+')'
  171. else
  172. numberstring := tostr(globalnb);
  173. exit;
  174. end;
  175. numberstring := tostr(globalnb);
  176. end;
  177. end;
  178. function tdef.allstabstring : pchar;
  179. var stabchar : string[2];
  180. ss,st : pchar;
  181. name : string;
  182. sym_line_no : longint;
  183. begin
  184. ss := stabstring;
  185. getmem(st,strlen(ss)+512);
  186. stabchar := 't';
  187. if deftype in tagtypes then
  188. stabchar := 'Tt';
  189. if assigned(sym) then
  190. begin
  191. name := sym^.name;
  192. sym_line_no:=sym^.fileinfo.line;
  193. end
  194. else
  195. begin
  196. name := ' ';
  197. sym_line_no:=0;
  198. end;
  199. strpcopy(st,'"'+name+':'+stabchar+numberstring+'=');
  200. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  201. allstabstring := strnew(st);
  202. freemem(st,strlen(ss)+512);
  203. strdispose(ss);
  204. end;
  205. procedure tdef.concatstabto(asmlist : paasmoutput);
  206. var stab_str : pchar;
  207. begin
  208. if ((sym = nil) or sym^.isusedinstab or use_dbx)
  209. and not is_def_stab_written then
  210. begin
  211. If use_dbx then
  212. begin
  213. { otherwise you get two of each def }
  214. If assigned(sym) then
  215. begin
  216. if sym^.typ=typesym then
  217. sym^.isusedinstab:=true;
  218. if (sym^.owner = nil) or
  219. ((sym^.owner^.symtabletype = unitsymtable) and
  220. punitsymtable(sym^.owner)^.dbx_count_ok) then
  221. begin
  222. {with DBX we get the definition from the other objects }
  223. is_def_stab_written := true;
  224. exit;
  225. end;
  226. end;
  227. end;
  228. { to avoid infinite loops }
  229. is_def_stab_written := true;
  230. stab_str := allstabstring;
  231. if asmlist = debuglist then do_count_dbx := true;
  232. { count_dbx(stab_str); moved to GDB.PAS}
  233. asmlist^.concat(new(pai_stabs,init(stab_str)));
  234. end;
  235. end;
  236. {$endif GDB}
  237. procedure tdef.deref;
  238. begin
  239. end;
  240. function tdef.needs_rtti : boolean;
  241. begin
  242. needs_rtti:=false;
  243. end;
  244. procedure tdef.generate_rtti;
  245. begin
  246. has_rtti:=true;
  247. getlabel(rtti_label);
  248. rttilist^.concat(new(pai_label,init(rtti_label)));
  249. end;
  250. function tdef.get_rtti_label : plabel;
  251. begin
  252. if not(has_rtti) then
  253. generate_rtti;
  254. { I don't know what's the use of rtti_label
  255. but this was missing (PM) }
  256. get_rtti_label:=rtti_label;
  257. end;
  258. procedure tdef.writename;
  259. var
  260. str : string;
  261. begin
  262. { name }
  263. if assigned(sym) then
  264. begin
  265. str:=sym^.name;
  266. rttilist^.concat(new(pai_string,init(chr(length(str))+str)));
  267. end
  268. else
  269. rttilist^.concat(new(pai_string,init(#0)))
  270. end;
  271. {*************************************************************************************************************************
  272. TSTRINGDEF
  273. ****************************************************************************}
  274. constructor tstringdef.init(l : byte);
  275. begin
  276. tdef.init;
  277. string_typ:=st_shortstring;
  278. deftype:=stringdef;
  279. len:=l;
  280. savesize:=len+1;
  281. end;
  282. constructor tstringdef.load;
  283. begin
  284. tdef.load;
  285. string_typ:=st_shortstring;
  286. deftype:=stringdef;
  287. len:=readbyte;
  288. savesize:=len+1;
  289. end;
  290. constructor tstringdef.longinit(l : longint);
  291. begin
  292. tdef.init;
  293. string_typ:=st_longstring;
  294. deftype:=stringdef;
  295. len:=l;
  296. savesize:=Sizeof(pointer);
  297. end;
  298. constructor tstringdef.longload;
  299. begin
  300. tdef.load;
  301. deftype:=stringdef;
  302. string_typ:=st_longstring;
  303. len:=readlong;
  304. savesize:=Sizeof(pointer);
  305. end;
  306. constructor tstringdef.ansiinit(l : longint);
  307. begin
  308. tdef.init;
  309. string_typ:=st_ansistring;
  310. deftype:=stringdef;
  311. len:=l;
  312. savesize:=sizeof(pointer);
  313. end;
  314. constructor tstringdef.ansiload;
  315. begin
  316. tdef.load;
  317. deftype:=stringdef;
  318. string_typ:=st_ansistring;
  319. len:=readlong;
  320. savesize:=sizeof(pointer);
  321. end;
  322. constructor tstringdef.wideinit(l : longint);
  323. begin
  324. tdef.init;
  325. string_typ:=st_widestring;
  326. deftype:=stringdef;
  327. len:=l;
  328. savesize:=sizeof(pointer);
  329. end;
  330. constructor tstringdef.wideload;
  331. begin
  332. tdef.load;
  333. deftype:=stringdef;
  334. string_typ:=st_ansistring;
  335. len:=readlong;
  336. savesize:=sizeof(pointer);
  337. end;
  338. function tstringdef.size : longint;
  339. begin
  340. size:=savesize;
  341. end;
  342. procedure tstringdef.write;
  343. begin
  344. tdef.write;
  345. if string_typ=st_shortstring then
  346. writebyte(len)
  347. else
  348. writelong(len);
  349. case string_typ of
  350. st_shortstring : current_ppu^.writeentry(ibstringdef);
  351. st_longstring : current_ppu^.writeentry(iblongstringdef);
  352. st_ansistring : current_ppu^.writeentry(ibansistringdef);
  353. st_widestring : current_ppu^.writeentry(ibwidestringdef);
  354. end;
  355. end;
  356. {$ifdef GDB}
  357. function tstringdef.stabstring : pchar;
  358. var
  359. bytest,charst,longst : string;
  360. begin
  361. case string_typ of
  362. st_shortstring:
  363. begin
  364. charst := typeglobalnumber('char');
  365. { this is what I found in stabs.texinfo but
  366. gdb 4.12 for go32 doesn't understand that !! }
  367. {$IfDef GDBknowsstrings}
  368. stabstring := strpnew('n'+charst+';'+tostr(len));
  369. {$else}
  370. bytest := typeglobalnumber('byte');
  371. stabstring := strpnew('s'+tostr(len+1)+'length:'+bytest
  372. +',0,8;st:ar'+bytest
  373. +';1;'+tostr(len)+';'+charst+',8,'+tostr(len*8)+';;');
  374. {$EndIf}
  375. end;
  376. st_longstring:
  377. begin
  378. charst := typeglobalnumber('char');
  379. { this is what I found in stabs.texinfo but
  380. gdb 4.12 for go32 doesn't understand that !! }
  381. {$IfDef GDBknowsstrings}
  382. stabstring := strpnew('n'+charst+';'+tostr(len));
  383. {$else}
  384. bytest := typeglobalnumber('byte');
  385. longst := typeglobalnumber('longint');
  386. stabstring := strpnew('s'+tostr(len+5)+'length:'+longst
  387. +',0,32;dummy:'+bytest+',32,8;st:ar'+bytest
  388. +';1;'+tostr(len)+';'+charst+',40,'+tostr(len*8)+';;');
  389. {$EndIf}
  390. end;
  391. st_ansistring:
  392. begin
  393. { an ansi string looks like a pchar easy !! }
  394. stabstring:=strpnew('*'+typeglobalnumber('char'));
  395. end;
  396. st_widestring:
  397. begin
  398. { an ansi string looks like a pchar easy !! }
  399. stabstring:=strpnew('*'+typeglobalnumber('char'));
  400. end;
  401. end;
  402. end;
  403. procedure tstringdef.concatstabto(asmlist : paasmoutput);
  404. begin
  405. inherited concatstabto(asmlist);
  406. end;
  407. {$endif GDB}
  408. function tstringdef.needs_rtti : boolean;
  409. begin
  410. needs_rtti:=string_typ in [st_ansistring,st_widestring];
  411. end;
  412. procedure tstringdef.generate_rtti;
  413. begin
  414. inherited generate_rtti;
  415. case string_typ of
  416. st_ansistring:
  417. begin
  418. rttilist^.concat(new(pai_const,init_8bit(10)));
  419. end;
  420. st_widestring:
  421. begin
  422. rttilist^.concat(new(pai_const,init_8bit(11)));
  423. end;
  424. st_longstring:
  425. begin
  426. rttilist^.concat(new(pai_const,init_8bit(9)));
  427. rttilist^.concat(new(pai_const,init_32bit(len)));
  428. end;
  429. st_shortstring:
  430. begin
  431. rttilist^.concat(new(pai_const,init_8bit(8)));
  432. rttilist^.concat(new(pai_const,init_32bit(len)));
  433. end;
  434. end;
  435. end;
  436. {*************************************************************************************************************************
  437. TENUMDEF
  438. ****************************************************************************}
  439. constructor tenumdef.init;
  440. begin
  441. tdef.init;
  442. deftype:=enumdef;
  443. min:=0;
  444. max:=0;
  445. savesize:=Sizeof(longint);
  446. has_jumps:=false;
  447. basedef:=nil;
  448. first:=nil;
  449. end;
  450. constructor tenumdef.init_subrange(_basedef:penumdef;_min,_max:longint);
  451. begin
  452. tdef.init;
  453. deftype:=enumdef;
  454. min:=_min;
  455. max:=_max;
  456. basedef:=_basedef;
  457. savesize:=Sizeof(longint);
  458. has_jumps:=false;
  459. first:=nil;
  460. end;
  461. constructor tenumdef.load;
  462. begin
  463. tdef.load;
  464. deftype:=enumdef;
  465. basedef:=penumdef(readdefref);
  466. min:=readlong;
  467. max:=readlong;
  468. savesize:=Sizeof(longint);
  469. has_jumps:=false;
  470. first:=Nil;
  471. end;
  472. procedure tenumdef.deref;
  473. begin
  474. resolvedef(pdef(basedef));
  475. end;
  476. destructor tenumdef.done;
  477. begin
  478. inherited done;
  479. end;
  480. procedure tenumdef.write;
  481. begin
  482. tdef.write;
  483. writedefref(basedef);
  484. writelong(min);
  485. writelong(max);
  486. current_ppu^.writeentry(ibenumdef);
  487. end;
  488. {$ifdef GDB}
  489. function tenumdef.stabstring : pchar;
  490. var st,st2 : pchar;
  491. p : penumsym;
  492. s : string;
  493. memsize : word;
  494. begin
  495. memsize := memsizeinc;
  496. getmem(st,memsize);
  497. strpcopy(st,'e');
  498. p := first;
  499. while assigned(p) do
  500. begin
  501. s :=p^.name+':'+tostr(p^.value)+',';
  502. { place for the ending ';' also }
  503. if (strlen(st)+length(s)+1<memsize) then
  504. strpcopy(strend(st),s)
  505. else
  506. begin
  507. getmem(st2,memsize+memsizeinc);
  508. strcopy(st2,st);
  509. freemem(st,memsize);
  510. st := st2;
  511. memsize := memsize+memsizeinc;
  512. strpcopy(strend(st),s);
  513. end;
  514. p := p^.next;
  515. end;
  516. strpcopy(strend(st),';');
  517. stabstring := strnew(st);
  518. freemem(st,memsize);
  519. end;
  520. {$endif GDB}
  521. procedure tenumdef.generate_rtti;
  522. begin
  523. inherited generate_rtti;
  524. rttilist^.concat(new(pai_const,init_8bit(255)));
  525. end;
  526. {*************************************************************************************************************************
  527. TORDDEF
  528. ****************************************************************************}
  529. constructor torddef.init(t : tbasetype;v,b : longint);
  530. begin
  531. inherited init;
  532. deftype:=orddef;
  533. low:=v;
  534. high:=b;
  535. typ:=t;
  536. setsize;
  537. end;
  538. constructor torddef.load;
  539. begin
  540. inherited load;
  541. deftype:=orddef;
  542. typ:=tbasetype(readbyte);
  543. low:=readlong;
  544. high:=readlong;
  545. rangenr:=0;
  546. setsize;
  547. end;
  548. procedure torddef.setsize;
  549. begin
  550. if typ=uauto then
  551. begin
  552. { generate a unsigned range if high<0 and low>=0 }
  553. if (low>=0) and (high<0) then
  554. begin
  555. savesize:=4;
  556. typ:=u32bit;
  557. end
  558. else if (low>=0) and (high<=255) then
  559. begin
  560. savesize:=1;
  561. typ:=u8bit;
  562. end
  563. else if (low>=-128) and (high<=127) then
  564. begin
  565. savesize:=1;
  566. typ:=s8bit;
  567. end
  568. else if (low>=0) and (high<=65536) then
  569. begin
  570. savesize:=2;
  571. typ:=u16bit;
  572. end
  573. else if (low>=-32768) and (high<=32767) then
  574. begin
  575. savesize:=2;
  576. typ:=s16bit;
  577. end
  578. else
  579. begin
  580. savesize:=4;
  581. typ:=s32bit;
  582. end;
  583. end
  584. else
  585. begin
  586. case typ of
  587. u8bit,s8bit,
  588. uchar,bool8bit : savesize:=1;
  589. u16bit,s16bit,
  590. bool16bit : savesize:=2;
  591. s32bit,u32bit,
  592. bool32bit : savesize:=4;
  593. else
  594. savesize:=0;
  595. end;
  596. end;
  597. { there are no entrys for range checking }
  598. rangenr:=0;
  599. end;
  600. procedure torddef.genrangecheck;
  601. begin
  602. if rangenr=0 then
  603. begin
  604. { generate two constant for bounds }
  605. getlabelnr(rangenr);
  606. if (cs_smartlink in aktmoduleswitches) then
  607. datasegment^.concat(new(pai_symbol,init_global('R_'+current_module^.modulename^+tostr(rangenr))))
  608. else
  609. datasegment^.concat(new(pai_symbol,init('R_'+tostr(rangenr))));
  610. if low<=high then
  611. begin
  612. datasegment^.concat(new(pai_const,init_32bit(low)));
  613. datasegment^.concat(new(pai_const,init_32bit(high)));
  614. end
  615. { for u32bit we need two bounds }
  616. else
  617. begin
  618. datasegment^.concat(new(pai_const,init_32bit(low)));
  619. datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
  620. inc(nextlabelnr);
  621. if (cs_smartlink in aktmoduleswitches) then
  622. datasegment^.concat(new(pai_symbol,init_global('R_'+current_module^.modulename^+tostr(rangenr+1))))
  623. else
  624. datasegment^.concat(new(pai_symbol,init('R_'+tostr(rangenr+1))));
  625. datasegment^.concat(new(pai_const,init_32bit($80000000)));
  626. datasegment^.concat(new(pai_const,init_32bit(high)));
  627. end;
  628. end;
  629. end;
  630. procedure torddef.write;
  631. begin
  632. tdef.write;
  633. writebyte(byte(typ));
  634. writelong(low);
  635. writelong(high);
  636. current_ppu^.writeentry(iborddef);
  637. end;
  638. {$ifdef GDB}
  639. function torddef.stabstring : pchar;
  640. begin
  641. case typ of
  642. uvoid : stabstring := strpnew(numberstring+';');
  643. {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
  644. bool8bit,
  645. bool16bit,
  646. bool32bit : stabstring := strpnew('r'+numberstring+';0;255;');
  647. { u32bit : stabstring := strpnew('r'+
  648. s32bitdef^.numberstring+';0;-1;'); }
  649. else
  650. stabstring := strpnew('r'+s32bitdef^.numberstring+';'+tostr(low)+';'+tostr(high)+';');
  651. end;
  652. end;
  653. {$endif GDB}
  654. procedure torddef.generate_rtti;
  655. begin
  656. inherited generate_rtti;
  657. rttilist^.concat(new(pai_const,init_8bit(255)));
  658. end;
  659. {*************************************************************************************************************************
  660. TFLOATDEF
  661. ****************************************************************************}
  662. constructor tfloatdef.init(t : tfloattype);
  663. begin
  664. tdef.init;
  665. deftype:=floatdef;
  666. typ:=t;
  667. setsize;
  668. end;
  669. constructor tfloatdef.load;
  670. begin
  671. tdef.load;
  672. deftype:=floatdef;
  673. typ:=tfloattype(readbyte);
  674. setsize;
  675. end;
  676. procedure tfloatdef.setsize;
  677. begin
  678. case typ of
  679. f16bit:
  680. savesize:=2;
  681. f32bit,s32real:
  682. savesize:=4;
  683. s64real:
  684. savesize:=8;
  685. s64bit:
  686. savesize:=8;
  687. s80real:
  688. savesize:=extended_size;
  689. else savesize:=0;
  690. end;
  691. end;
  692. procedure tfloatdef.write;
  693. begin
  694. tdef.write;
  695. writebyte(byte(typ));
  696. current_ppu^.writeentry(ibfloatdef);
  697. end;
  698. {$ifdef GDB}
  699. function tfloatdef.stabstring : pchar;
  700. begin
  701. case typ of
  702. s32real,
  703. s64real : stabstring := strpnew('r'+
  704. s32bitdef^.numberstring+';'+tostr(savesize)+';0;');
  705. { for fixed real use longint instead to be able to }
  706. { debug something at least }
  707. f32bit:
  708. stabstring := s32bitdef^.stabstring;
  709. f16bit:
  710. stabstring := strpnew('r'+s32bitdef^.numberstring+';0;'+
  711. tostr($ffff)+';');
  712. { found this solution in stabsread.c from GDB v4.16 }
  713. s64bit : stabstring := strpnew('r'+
  714. s32bitdef^.numberstring+';-'+tostr(savesize)+';0;');
  715. {$ifdef i386}
  716. { under dos at least you must give a size of twelve instead of 10 !! }
  717. { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
  718. s80real : stabstring := strpnew('r'+s32bitdef^.numberstring+';12;0;');
  719. {$endif i386}
  720. else
  721. internalerror(10005);
  722. end;
  723. end;
  724. {$endif GDB}
  725. procedure tfloatdef.generate_rtti;
  726. begin
  727. inherited generate_rtti;
  728. rttilist^.concat(new(pai_const,init_8bit(255)));
  729. end;
  730. {*************************************************************************************************************************
  731. TFILEDEF
  732. ****************************************************************************}
  733. constructor tfiledef.init(ft : tfiletype;tas : pdef);
  734. begin
  735. inherited init;
  736. deftype:=filedef;
  737. filetype:=ft;
  738. typed_as:=tas;
  739. setsize;
  740. end;
  741. constructor tfiledef.load;
  742. begin
  743. tdef.load;
  744. deftype:=filedef;
  745. filetype:=tfiletype(readbyte);
  746. if filetype=ft_typed then
  747. typed_as:=readdefref
  748. else
  749. typed_as:=nil;
  750. setsize;
  751. end;
  752. procedure tfiledef.deref;
  753. begin
  754. if filetype=ft_typed then
  755. resolvedef(typed_as);
  756. end;
  757. procedure tfiledef.setsize;
  758. begin
  759. {$ifdef i386}
  760. case target_info.target of
  761. target_LINUX : begin
  762. case filetype of
  763. ft_text : savesize:=432;
  764. ft_typed,
  765. ft_untyped : savesize:=304;
  766. end;
  767. end;
  768. target_Win32 : begin
  769. case filetype of
  770. ft_text : savesize:=434;
  771. ft_typed,
  772. ft_untyped : savesize:=306;
  773. end;
  774. end;
  775. else
  776. begin
  777. case filetype of
  778. ft_text : savesize:=256;
  779. ft_typed,ft_untyped : savesize:=128;
  780. end;
  781. end;
  782. end;
  783. {$endif}
  784. {$ifdef m68k}
  785. case target_info.target of
  786. target_Amiga,
  787. target_Mac68k : begin
  788. case filetype of
  789. ft_text : savesize:=434;
  790. ft_typed,
  791. ft_untyped : savesize:=306;
  792. end;
  793. end;
  794. else
  795. begin
  796. case filetype of
  797. ft_text : savesize:=256;
  798. ft_typed,ft_untyped : savesize:=128;
  799. end;
  800. end;
  801. end;
  802. {$endif}
  803. end;
  804. procedure tfiledef.write;
  805. begin
  806. tdef.write;
  807. writebyte(byte(filetype));
  808. if filetype=ft_typed then
  809. writedefref(typed_as);
  810. current_ppu^.writeentry(ibfiledef);
  811. end;
  812. {$ifdef GDB}
  813. function tfiledef.stabstring : pchar;
  814. var Handlebitsize,namesize : longint;
  815. Handledef :string;
  816. begin
  817. {$IfDef GDBknowsfiles}
  818. case filetyp of
  819. ft_typed : stabstring := strpnew('d'+typed_as^.numberstring{+';'});
  820. ft_untyped : stabstring := strpnew('d'+voiddef^.numberstring{+';'});
  821. ft_text : stabstring := strpnew('d'+cchardef^.numberstring{+';'});
  822. end;
  823. {$Else }
  824. {based on
  825. filerec = record
  826. handle : word;
  827. mode : word;
  828. recsize : word;
  829. _private : array[1..26] of byte;
  830. userdata : array[1..16] of byte;
  831. name : string[79 or 255 for linux]; }
  832. {$ifdef i386}
  833. if (target_info.target=target_GO32V1) or
  834. (target_info.target=target_GO32V2) then
  835. namesize:=79
  836. else
  837. namesize:=255;
  838. if (target_info.target=target_Win32) then
  839. begin
  840. Handledef:='longint';
  841. Handlebitsize:=32;
  842. end
  843. else
  844. begin
  845. Handledef:='word';
  846. HandleBitSize:=16;
  847. end;
  848. {$endif}
  849. {$ifdef m68k}
  850. namesize:=79;
  851. Handledef:='word';
  852. HandleBitSize:=16;
  853. {$endif}
  854. { the buffer part is still missing !! (PM) }
  855. { but the string could become too long !! }
  856. stabstring := strpnew('s'+tostr(savesize)+
  857. 'HANDLE:'+typeglobalnumber(Handledef)+',0,'+tostr(HandleBitSize)+';'+
  858. 'MODE:'+typeglobalnumber('word')+','+tostr(HandleBitSize)+',16;'+
  859. 'RECSIZE:'+typeglobalnumber('word')+','+tostr(HandleBitSize+16)+',16;'+
  860. '_PRIVATE:ar'+typeglobalnumber('word')+';1;26;'+typeglobalnumber('byte')
  861. +','+tostr(HandleBitSize+32)+',208;'+
  862. 'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')
  863. +','+tostr(HandleBitSize+240)+',128;'+
  864. { 'NAME:s'+tostr(namesize+1)+
  865. 'length:'+typeglobalnumber('byte')+',0,8;'+
  866. 'st:ar'+typeglobalnumber('word')+';1;'
  867. +tostr(namesize)+';'+typeglobalnumber('char')+',8,'+tostr(8*namesize)+';;'+}
  868. 'NAME:ar'+typeglobalnumber('word')+';0;'
  869. +tostr(namesize)+';'+typeglobalnumber('char')+
  870. ','+tostr(HandleBitSize+368)+','+tostr(8*(namesize+1))+';;');
  871. {$EndIf}
  872. end;
  873. procedure tfiledef.concatstabto(asmlist : paasmoutput);
  874. begin
  875. { most file defs are unnamed !!! }
  876. if ((sym = nil) or sym^.isusedinstab or use_dbx) and not is_def_stab_written then
  877. begin
  878. if assigned(typed_as) then forcestabto(asmlist,typed_as);
  879. inherited concatstabto(asmlist);
  880. end;
  881. end;
  882. {$endif GDB}
  883. procedure tfiledef.generate_rtti;
  884. begin
  885. inherited generate_rtti;
  886. rttilist^.concat(new(pai_const,init_8bit(255)));
  887. end;
  888. {*************************************************************************************************************************
  889. TPOINTERDEF
  890. ****************************************************************************}
  891. constructor tpointerdef.init(def : pdef);
  892. begin
  893. inherited init;
  894. deftype:=pointerdef;
  895. definition:=def;
  896. savesize:=Sizeof(pointer);
  897. end;
  898. constructor tpointerdef.load;
  899. begin
  900. tdef.load;
  901. deftype:=pointerdef;
  902. { the real address in memory is calculated later (deref) }
  903. definition:=readdefref;
  904. savesize:=Sizeof(pointer);
  905. end;
  906. procedure tpointerdef.deref;
  907. begin
  908. resolvedef(definition);
  909. end;
  910. procedure tpointerdef.write;
  911. begin
  912. tdef.write;
  913. writedefref(definition);
  914. current_ppu^.writeentry(ibpointerdef);
  915. end;
  916. {$ifdef GDB}
  917. function tpointerdef.stabstring : pchar;
  918. begin
  919. stabstring := strpnew('*'+definition^.numberstring);
  920. end;
  921. procedure tpointerdef.concatstabto(asmlist : paasmoutput);
  922. var st,nb : string;
  923. sym_line_no : longint;
  924. begin
  925. if ( (sym=nil) or sym^.isusedinstab or use_dbx) and not is_def_stab_written then
  926. begin
  927. if assigned(definition) then
  928. if definition^.deftype in [recorddef,objectdef] then
  929. begin
  930. is_def_stab_written := true;
  931. {to avoid infinite recursion in record with next-like fields }
  932. nb := definition^.numberstring;
  933. is_def_stab_written := false;
  934. if not definition^.is_def_stab_written then
  935. begin
  936. if assigned(definition^.sym) then
  937. begin
  938. if assigned(sym) then
  939. begin
  940. st := sym^.name;
  941. sym_line_no:=sym^.fileinfo.line;
  942. end
  943. else
  944. begin
  945. st := ' ';
  946. sym_line_no:=0;
  947. end;
  948. st := '"'+st+':t'+numberstring+'=*'+definition^.numberstring
  949. +'=xs'+definition^.sym^.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
  950. if asmlist = debuglist then do_count_dbx := true;
  951. asmlist^.concat(new(pai_stabs,init(strpnew(st))));
  952. end;
  953. end else inherited concatstabto(asmlist);
  954. is_def_stab_written := true;
  955. end else
  956. begin
  957. forcestabto(asmlist,definition);
  958. inherited concatstabto(asmlist);
  959. end;
  960. end;
  961. end;
  962. {$endif GDB}
  963. procedure tpointerdef.generate_rtti;
  964. begin
  965. inherited generate_rtti;
  966. rttilist^.concat(new(pai_const,init_8bit(255)));
  967. end;
  968. {*************************************************************************************************************************
  969. TCLASSREFDEF
  970. ****************************************************************************}
  971. constructor tclassrefdef.init(def : pdef);
  972. begin
  973. inherited init(def);
  974. deftype:=classrefdef;
  975. definition:=def;
  976. savesize:=Sizeof(pointer);
  977. end;
  978. constructor tclassrefdef.load;
  979. begin
  980. inherited load;
  981. deftype:=classrefdef;
  982. end;
  983. procedure tclassrefdef.write;
  984. begin
  985. tdef.write;
  986. writedefref(definition);
  987. current_ppu^.writeentry(ibclassrefdef);
  988. end;
  989. {$ifdef GDB}
  990. function tclassrefdef.stabstring : pchar;
  991. begin
  992. stabstring:=strpnew('');
  993. end;
  994. procedure tclassrefdef.concatstabto(asmlist : paasmoutput);
  995. begin
  996. end;
  997. {$endif GDB}
  998. procedure tclassrefdef.generate_rtti;
  999. begin
  1000. inherited generate_rtti;
  1001. rttilist^.concat(new(pai_const,init_8bit(255)));
  1002. end;
  1003. {***********************************************************************************
  1004. TSETDEF
  1005. ***************************************************************************}
  1006. constructor tsetdef.init(s : pdef;high : longint);
  1007. begin
  1008. inherited init;
  1009. deftype:=setdef;
  1010. setof:=s;
  1011. if high<32 then
  1012. begin
  1013. settype:=smallset;
  1014. savesize:=Sizeof(longint);
  1015. end
  1016. else
  1017. if high<256 then
  1018. begin
  1019. settype:=normset;
  1020. savesize:=32;
  1021. end
  1022. else
  1023. {$ifdef testvarsets}
  1024. if high<$10000 then
  1025. begin
  1026. settype:=varset;
  1027. savesize:=4*((high+31) div 32);
  1028. end
  1029. else
  1030. {$endif testvarsets}
  1031. Message(sym_e_ill_type_decl_set);
  1032. end;
  1033. constructor tsetdef.load;
  1034. begin
  1035. tdef.load;
  1036. deftype:=setdef;
  1037. setof:=readdefref;
  1038. settype:=tsettype(readbyte);
  1039. case settype of
  1040. normset : savesize:=32;
  1041. varset : savesize:=readlong;
  1042. smallset : savesize:=Sizeof(longint);
  1043. end;
  1044. end;
  1045. procedure tsetdef.write;
  1046. begin
  1047. tdef.write;
  1048. writedefref(setof);
  1049. writebyte(byte(settype));
  1050. if settype=varset then
  1051. writelong(savesize);
  1052. current_ppu^.writeentry(ibsetdef);
  1053. end;
  1054. {$ifdef GDB}
  1055. function tsetdef.stabstring : pchar;
  1056. begin
  1057. stabstring := strpnew('S'+setof^.numberstring);
  1058. end;
  1059. procedure tsetdef.concatstabto(asmlist : paasmoutput);
  1060. begin
  1061. if ( not assigned(sym) or sym^.isusedinstab or use_dbx) and
  1062. not is_def_stab_written then
  1063. begin
  1064. if assigned(setof) then
  1065. forcestabto(asmlist,setof);
  1066. inherited concatstabto(asmlist);
  1067. end;
  1068. end;
  1069. {$endif GDB}
  1070. procedure tsetdef.deref;
  1071. begin
  1072. resolvedef(setof);
  1073. end;
  1074. procedure tsetdef.generate_rtti;
  1075. begin
  1076. inherited generate_rtti;
  1077. rttilist^.concat(new(pai_const,init_8bit(255)));
  1078. end;
  1079. {***********************************************************************************
  1080. TFORMALDEF
  1081. ***************************************************************************}
  1082. constructor tformaldef.init;
  1083. begin
  1084. inherited init;
  1085. deftype:=formaldef;
  1086. savesize:=Sizeof(pointer);
  1087. end;
  1088. constructor tformaldef.load;
  1089. begin
  1090. tdef.load;
  1091. deftype:=formaldef;
  1092. savesize:=Sizeof(pointer);
  1093. end;
  1094. procedure tformaldef.write;
  1095. begin
  1096. tdef.write;
  1097. current_ppu^.writeentry(ibformaldef);
  1098. end;
  1099. {$ifdef GDB}
  1100. function tformaldef.stabstring : pchar;
  1101. begin
  1102. stabstring := strpnew('formal'+numberstring+';');
  1103. end;
  1104. procedure tformaldef.concatstabto(asmlist : paasmoutput);
  1105. begin
  1106. { formaldef can't be stab'ed !}
  1107. end;
  1108. {$endif GDB}
  1109. procedure tformaldef.generate_rtti;
  1110. begin
  1111. inherited generate_rtti;
  1112. rttilist^.concat(new(pai_const,init_8bit(255)));
  1113. end;
  1114. {***********************************************************************************
  1115. TARRAYDEF
  1116. ***************************************************************************}
  1117. constructor tarraydef.init(l,h : longint;rd : pdef);
  1118. begin
  1119. tdef.init;
  1120. deftype:=arraydef;
  1121. lowrange:=l;
  1122. highrange:=h;
  1123. rangedef:=rd;
  1124. rangenr:=0;
  1125. definition:=nil;
  1126. end;
  1127. constructor tarraydef.load;
  1128. begin
  1129. tdef.load;
  1130. deftype:=arraydef;
  1131. { the addresses are calculated later }
  1132. definition:=readdefref;
  1133. rangedef:=readdefref;
  1134. lowrange:=readlong;
  1135. highrange:=readlong;
  1136. rangenr:=0;
  1137. end;
  1138. procedure tarraydef.genrangecheck;
  1139. begin
  1140. if rangenr=0 then
  1141. begin
  1142. { generates the data for range checking }
  1143. getlabelnr(rangenr);
  1144. datasegment^.concat(new(pai_symbol,init('R_'+tostr(rangenr))));
  1145. datasegment^.concat(new(pai_const,init_32bit(lowrange)));
  1146. datasegment^.concat(new(pai_const,init_32bit(highrange)));
  1147. end;
  1148. end;
  1149. procedure tarraydef.deref;
  1150. begin
  1151. resolvedef(definition);
  1152. resolvedef(rangedef);
  1153. end;
  1154. procedure tarraydef.write;
  1155. begin
  1156. tdef.write;
  1157. writedefref(definition);
  1158. writedefref(rangedef);
  1159. writelong(lowrange);
  1160. writelong(highrange);
  1161. current_ppu^.writeentry(ibarraydef);
  1162. end;
  1163. {$ifdef GDB}
  1164. function tarraydef.stabstring : pchar;
  1165. begin
  1166. stabstring := strpnew('ar'+rangedef^.numberstring+';'
  1167. +tostr(lowrange)+';'+tostr(highrange)+';'+definition^.numberstring);
  1168. end;
  1169. procedure tarraydef.concatstabto(asmlist : paasmoutput);
  1170. begin
  1171. if (not assigned(sym) or sym^.isusedinstab or use_dbx)
  1172. and not is_def_stab_written then
  1173. begin
  1174. {when array are inserted they have no definition yet !!}
  1175. if assigned(definition) then
  1176. inherited concatstabto(asmlist);
  1177. end;
  1178. end;
  1179. {$endif GDB}
  1180. function tarraydef.elesize : longint;
  1181. begin
  1182. elesize:=definition^.size;
  1183. end;
  1184. function tarraydef.size : longint;
  1185. begin
  1186. size:=(highrange-lowrange+1)*elesize;
  1187. end;
  1188. function tarraydef.needs_rtti : boolean;
  1189. begin
  1190. needs_rtti:=definition^.needs_rtti;
  1191. end;
  1192. procedure tarraydef.generate_rtti;
  1193. begin
  1194. { first, generate the rtti of the element type, else we get mixed }
  1195. { up because the rtti would be mixed }
  1196. if not(definition^.has_rtti) then
  1197. definition^.generate_rtti;
  1198. inherited generate_rtti;
  1199. rttilist^.concat(new(pai_const,init_8bit(13)));
  1200. writename;
  1201. { size of elements }
  1202. rttilist^.concat(new(pai_const,init_32bit(definition^.size)));
  1203. { count of elements }
  1204. rttilist^.concat(new(pai_const,init_32bit(highrange-lowrange+1)));
  1205. { element type }
  1206. rttilist^.concat(new(pai_const,init_symbol(strpnew(lab2str(definition^.get_rtti_label)))));
  1207. end;
  1208. {***********************************************************************************
  1209. TRECDEF
  1210. ***************************************************************************}
  1211. constructor trecdef.init(p : psymtable);
  1212. begin
  1213. tdef.init;
  1214. deftype:=recorddef;
  1215. symtable:=p;
  1216. savesize:=symtable^.datasize;
  1217. symtable^.defowner := @self;
  1218. end;
  1219. constructor trecdef.load;
  1220. var
  1221. oldread_member : boolean;
  1222. begin
  1223. tdef.load;
  1224. deftype:=recorddef;
  1225. savesize:=readlong;
  1226. oldread_member:=read_member;
  1227. read_member:=true;
  1228. symtable:=new(psymtable,loadasstruct(recordsymtable));
  1229. read_member:=oldread_member;
  1230. symtable^.defowner := @self;
  1231. end;
  1232. destructor trecdef.done;
  1233. begin
  1234. if assigned(symtable) then dispose(symtable,done);
  1235. inherited done;
  1236. end;
  1237. var
  1238. brtti : boolean;
  1239. procedure check_rec_rtti(s : psym);
  1240. begin
  1241. if (s^.typ=varsym) and (pvarsym(s)^.definition^.needs_rtti) then
  1242. brtti:=true;
  1243. end;
  1244. function trecdef.needs_rtti : boolean;
  1245. var
  1246. oldb : boolean;
  1247. begin
  1248. { there are recursive calls to needs_rtti possible, }
  1249. { so we have to change to old value how else should }
  1250. { we do that ? check_rec_rtti can't be a nested }
  1251. { procedure of needs_rtti ! }
  1252. oldb:=brtti;
  1253. brtti:=false;
  1254. symtable^.foreach(check_rec_rtti);
  1255. needs_rtti:=brtti;
  1256. brtti:=oldb;
  1257. end;
  1258. procedure trecdef.deref;
  1259. var
  1260. hp : pdef;
  1261. oldrecsyms : psymtable;
  1262. begin
  1263. oldrecsyms:=aktrecordsymtable;
  1264. aktrecordsymtable:=symtable;
  1265. { now dereference the definitions }
  1266. hp:=symtable^.rootdef;
  1267. while assigned(hp) do
  1268. begin
  1269. hp^.deref;
  1270. { set owner }
  1271. hp^.owner:=symtable;
  1272. hp:=hp^.next;
  1273. end;
  1274. {$ifdef tp}
  1275. symtable^.foreach(derefsym);
  1276. {$else}
  1277. symtable^.foreach(@derefsym);
  1278. {$endif}
  1279. aktrecordsymtable:=oldrecsyms;
  1280. end;
  1281. procedure trecdef.write;
  1282. var
  1283. oldread_member : boolean;
  1284. begin
  1285. oldread_member:=read_member;
  1286. read_member:=true;
  1287. tdef.write;
  1288. writelong(savesize);
  1289. current_ppu^.writeentry(ibrecorddef);
  1290. self.symtable^.writeasstruct;
  1291. read_member:=oldread_member;
  1292. end;
  1293. {$ifdef GDB}
  1294. Const StabRecString : pchar = Nil;
  1295. StabRecSize : longint = 0;
  1296. RecOffset : Longint = 0;
  1297. procedure addname(p : psym);
  1298. var
  1299. news, newrec : pchar;
  1300. begin
  1301. { static variables from objects are like global objects }
  1302. if ((p^.properties and sp_static)<>0) then
  1303. exit;
  1304. If p^.typ = varsym then
  1305. begin
  1306. newrec := strpnew(p^.name+':'+pvarsym(p)^.definition^.numberstring
  1307. +','+tostr(pvarsym(p)^.address*8)+','
  1308. +tostr(pvarsym(p)^.definition^.size*8)+';');
  1309. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  1310. begin
  1311. getmem(news,stabrecsize+memsizeinc);
  1312. strcopy(news,stabrecstring);
  1313. freemem(stabrecstring,stabrecsize);
  1314. stabrecsize:=stabrecsize+memsizeinc;
  1315. stabrecstring:=news;
  1316. end;
  1317. strcat(StabRecstring,newrec);
  1318. strdispose(newrec);
  1319. {This should be used for case !!}
  1320. RecOffset := RecOffset + pvarsym(p)^.definition^.size;
  1321. end;
  1322. end;
  1323. function trecdef.stabstring : pchar;
  1324. Var oldrec : pchar;
  1325. oldsize : longint;
  1326. begin
  1327. oldrec := stabrecstring;
  1328. oldsize:=stabrecsize;
  1329. GetMem(stabrecstring,memsizeinc);
  1330. stabrecsize:=memsizeinc;
  1331. strpcopy(stabRecString,'s'+tostr(savesize));
  1332. RecOffset := 0;
  1333. {$ifdef tp}
  1334. symtable^.foreach(addname);
  1335. {$else}
  1336. symtable^.foreach(@addname);
  1337. {$endif}
  1338. { FPC doesn't want to convert a char to a pchar}
  1339. { is this a bug ? }
  1340. strpcopy(strend(StabRecString),';');
  1341. stabstring := strnew(StabRecString);
  1342. Freemem(stabrecstring,stabrecsize);
  1343. stabrecstring := oldrec;
  1344. stabrecsize:=oldsize;
  1345. end;
  1346. procedure trecdef.concatstabto(asmlist : paasmoutput);
  1347. begin
  1348. if (not assigned(sym) or sym^.isusedinstab or use_dbx) and
  1349. (not is_def_stab_written) then
  1350. inherited concatstabto(asmlist);
  1351. end;
  1352. {$endif GDB}
  1353. var
  1354. count : longint;
  1355. procedure count_field(sym : psym);{$ifndef fpc}far;{$endif}
  1356. begin
  1357. inc(count);
  1358. end;
  1359. procedure write_field_info(sym : psym);{$ifndef fpc}far;{$endif}
  1360. begin
  1361. if (sym^.typ=varsym) and (pvarsym(sym)^.definition^.needs_rtti) then
  1362. begin
  1363. rttilist^.concat(new(pai_const,init_symbol(strpnew(lab2str(pvarsym(sym)^.definition^.get_rtti_label)))));
  1364. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  1365. end;
  1366. end;
  1367. procedure generate_child_rtti(sym : psym);{$ifndef fpc}far;{$endif}
  1368. begin
  1369. if (sym^.typ=varsym) and not(pvarsym(sym)^.definition^.has_rtti) then
  1370. pvarsym(sym)^.definition^.generate_rtti;
  1371. end;
  1372. procedure trecdef.generate_rtti;
  1373. begin
  1374. symtable^.foreach(generate_child_rtti);
  1375. inherited generate_rtti;
  1376. rttilist^.concat(new(pai_const,init_8bit(14)));
  1377. writename;
  1378. rttilist^.concat(new(pai_const,init_32bit(size)));
  1379. count:=0;
  1380. symtable^.foreach(count_field);
  1381. rttilist^.concat(new(pai_const,init_32bit(count)));
  1382. symtable^.foreach(write_field_info);
  1383. end;
  1384. {***********************************************************************************
  1385. TABSTRACTPROCDEF
  1386. ***************************************************************************}
  1387. constructor tabstractprocdef.init;
  1388. begin
  1389. inherited init;
  1390. para1:=nil;
  1391. {$ifdef StoreFPULevel}
  1392. fpu_used:=255;
  1393. {$endif StoreFPULevel}
  1394. options:=0;
  1395. retdef:=voiddef;
  1396. savesize:=Sizeof(pointer);
  1397. end;
  1398. destructor tabstractprocdef.done;
  1399. var
  1400. hp : pdefcoll;
  1401. begin
  1402. hp:=para1;
  1403. while assigned(hp) do
  1404. begin
  1405. para1:=hp^.next;
  1406. dispose(hp);
  1407. hp:=para1;
  1408. end;
  1409. inherited done;
  1410. end;
  1411. procedure tabstractprocdef.concatdef(p : pdef;vsp : tvarspez);
  1412. var
  1413. hp : pdefcoll;
  1414. begin
  1415. new(hp);
  1416. hp^.paratyp:=vsp;
  1417. hp^.data:=p;
  1418. hp^.next:=para1;
  1419. para1:=hp;
  1420. end;
  1421. procedure tabstractprocdef.deref;
  1422. var
  1423. hp : pdefcoll;
  1424. begin
  1425. inherited deref;
  1426. resolvedef(retdef);
  1427. hp:=para1;
  1428. while assigned(hp) do
  1429. begin
  1430. resolvedef(hp^.data);
  1431. hp:=hp^.next;
  1432. end;
  1433. end;
  1434. constructor tabstractprocdef.load;
  1435. var
  1436. last,hp : pdefcoll;
  1437. count,i : word;
  1438. begin
  1439. tdef.load;
  1440. retdef:=readdefref;
  1441. {$ifdef StoreFPULevel}
  1442. fpu_used:=readbyte;
  1443. {$endif StoreFPULevel}
  1444. options:=readlong;
  1445. count:=readword;
  1446. para1:=nil;
  1447. savesize:=Sizeof(pointer);
  1448. for i:=1 to count do
  1449. begin
  1450. new(hp);
  1451. hp^.paratyp:=tvarspez(readbyte);
  1452. hp^.data:=readdefref;
  1453. hp^.next:=nil;
  1454. if para1=nil then
  1455. para1:=hp
  1456. else
  1457. last^.next:=hp;
  1458. last:=hp;
  1459. end;
  1460. end;
  1461. function tabstractprocdef.para_size : longint;
  1462. var
  1463. pdc : pdefcoll;
  1464. l : longint;
  1465. begin
  1466. l:=0;
  1467. pdc:=para1;
  1468. while assigned(pdc) do
  1469. begin
  1470. case pdc^.paratyp of
  1471. vs_value :
  1472. l:=l+pdc^.data^.size+(pdc^.data^.size mod 2);
  1473. vs_var :
  1474. l:=l+sizeof(pointer);
  1475. vs_const :
  1476. if dont_copy_const_param(pdc^.data) then
  1477. l:=l+sizeof(pointer)
  1478. else
  1479. l:=l+pdc^.data^.size+(pdc^.data^.size mod 2);
  1480. end;
  1481. pdc:=pdc^.next;
  1482. end;
  1483. para_size:=l;
  1484. end;
  1485. procedure tabstractprocdef.write;
  1486. var
  1487. count : word;
  1488. hp : pdefcoll;
  1489. begin
  1490. tdef.write;
  1491. writedefref(retdef);
  1492. {$ifdef StoreFPULevel}
  1493. writebyte(fpu_used);
  1494. {$endif StoreFPULevel}
  1495. writelong(options);
  1496. hp:=para1;
  1497. count:=0;
  1498. while assigned(hp) do
  1499. begin
  1500. inc(count);
  1501. hp:=hp^.next;
  1502. end;
  1503. writeword(count);
  1504. hp:=para1;
  1505. while assigned(hp) do
  1506. begin
  1507. writebyte(byte(hp^.paratyp));
  1508. writedefref(hp^.data);
  1509. hp:=hp^.next;
  1510. end;
  1511. end;
  1512. function tabstractprocdef.demangled_paras : string;
  1513. var s : string;
  1514. p : pdefcoll;
  1515. begin
  1516. s:='';
  1517. p:=para1;
  1518. if assigned(p) then
  1519. begin
  1520. s:=s+'(';
  1521. while assigned(p) do
  1522. begin
  1523. if assigned(p^.data^.sym) then
  1524. s:=s+p^.data^.sym^.name
  1525. else if p^.paratyp=vs_var then
  1526. s:=s+'var'
  1527. else if p^.paratyp=vs_const then
  1528. s:=s+'const';
  1529. p:=p^.next;
  1530. if assigned(p) then
  1531. s:=s+','
  1532. else
  1533. s:=s+')';
  1534. end;
  1535. end;
  1536. demangled_paras:=s;
  1537. end;
  1538. {$ifdef GDB}
  1539. function tabstractprocdef.stabstring : pchar;
  1540. begin
  1541. stabstring := strpnew('abstractproc'+numberstring+';');
  1542. end;
  1543. procedure tabstractprocdef.concatstabto(asmlist : paasmoutput);
  1544. begin
  1545. if (not assigned(sym) or sym^.isusedinstab or use_dbx)
  1546. and not is_def_stab_written then
  1547. begin
  1548. if assigned(retdef) then forcestabto(asmlist,retdef);
  1549. inherited concatstabto(asmlist);
  1550. end;
  1551. end;
  1552. {$endif GDB}
  1553. {***********************************************************************************
  1554. TPROCDEF
  1555. ***************************************************************************}
  1556. constructor tprocdef.init;
  1557. begin
  1558. inherited init;
  1559. deftype:=procdef;
  1560. _mangledname:=nil;
  1561. nextoverloaded:=nil;
  1562. extnumber:=-1;
  1563. localst:=new(psymtable,init(localsymtable));
  1564. parast:=new(psymtable,init(parasymtable));
  1565. { this is used by insert
  1566. to check same names in parast and localst }
  1567. localst^.next:=parast;
  1568. {$ifdef UseBrowser}
  1569. defref:=nil;
  1570. lastwritten:=nil;
  1571. refcount:=0;
  1572. if (cs_browser in aktmoduleswitches) and make_ref then
  1573. begin
  1574. defref:=new(pref,init(defref,@tokenpos));
  1575. inc(refcount);
  1576. end;
  1577. lastref:=defref;
  1578. {$endif UseBrowser}
  1579. { first, we assume, that all registers are used }
  1580. {$ifdef i386}
  1581. usedregisters:=$ff;
  1582. {$endif i386}
  1583. {$ifdef m68k}
  1584. usedregisters:=$FFFF;
  1585. {$endif}
  1586. {$ifdef alpha}
  1587. usedregisters_int:=$ffffffff;
  1588. usedregisters_fpu:=$ffffffff;
  1589. {$endif alpha}
  1590. forwarddef:=true;
  1591. _class := nil;
  1592. code:=nil;
  1593. end;
  1594. constructor tprocdef.load;
  1595. var
  1596. s : string;
  1597. begin
  1598. { deftype:=procdef; this is at the wrong place !! }
  1599. inherited load;
  1600. deftype:=procdef;
  1601. {$ifdef i386}
  1602. usedregisters:=readbyte;
  1603. {$endif i386}
  1604. {$ifdef m68k}
  1605. usedregisters:=readword;
  1606. {$endif}
  1607. {$ifdef alpha}
  1608. usedregisters_int:=readlong;
  1609. usedregisters_fpu:=readlong;
  1610. {$endif alpha}
  1611. s:=readstring;
  1612. setstring(_mangledname,s);
  1613. extnumber:=readlong;
  1614. nextoverloaded:=pprocdef(readdefref);
  1615. _class := pobjectdef(readdefref);
  1616. if (cs_link_deffile in aktglobalswitches) and ((options and poexports)<>0) then
  1617. deffile.AddExport(mangledname);
  1618. parast:=nil;
  1619. localst:=nil;
  1620. forwarddef:=false;
  1621. {$ifdef UseBrowser}
  1622. lastref:=nil;
  1623. lastwritten:=nil;
  1624. defref:=nil;
  1625. refcount:=0;
  1626. {$endif UseBrowser}
  1627. end;
  1628. {$ifdef UseBrowser}
  1629. procedure tprocdef.load_references;
  1630. var
  1631. pos : tfileposinfo;
  1632. begin
  1633. while (not current_ppu^.endofentry) do
  1634. begin
  1635. readposinfo(pos);
  1636. inc(refcount);
  1637. lastref:=new(pref,init(lastref,@pos));
  1638. if refcount=1 then
  1639. defref:=lastref;
  1640. end;
  1641. end;
  1642. procedure tprocdef.write_references;
  1643. var
  1644. ref : pref;
  1645. begin
  1646. if lastwritten=lastref then
  1647. exit;
  1648. { write address of this symbol }
  1649. writedefref(@self);
  1650. { write refs }
  1651. if assigned(lastwritten) then
  1652. ref:=lastwritten
  1653. else
  1654. ref:=defref;
  1655. while assigned(ref) do
  1656. begin
  1657. writeposinfo(ref^.posinfo);
  1658. ref:=ref^.nextref;
  1659. end;
  1660. current_ppu^.writeentry(ibdefref);
  1661. lastwritten:=lastref;
  1662. end;
  1663. procedure tprocdef.add_to_browserlog;
  1664. begin
  1665. if assigned(defref) then
  1666. begin
  1667. Browse.AddLog('***'+mangledname);
  1668. Browse.AddLogRefs(defref);
  1669. end;
  1670. end;
  1671. {$endif UseBrowser}
  1672. destructor tprocdef.done;
  1673. begin
  1674. {$ifdef UseBrowser}
  1675. if assigned(defref) then
  1676. dispose(defref,done);
  1677. {$endif UseBrowser}
  1678. if assigned(parast) then
  1679. dispose(parast,done);
  1680. if assigned(localst) then
  1681. dispose(localst,done);
  1682. if
  1683. {$ifdef tp}
  1684. not(use_big) and
  1685. {$endif}
  1686. assigned(_mangledname) then
  1687. strdispose(_mangledname);
  1688. inherited done;
  1689. end;
  1690. procedure tprocdef.write;
  1691. begin
  1692. inherited write;
  1693. {$ifdef i386}
  1694. writebyte(usedregisters);
  1695. {$endif i386}
  1696. {$ifdef m68k}
  1697. writeword(usedregisters);
  1698. {$endif}
  1699. {$ifdef alpha}
  1700. writelong(usedregisters_int);
  1701. writelong(usedregisters_fpu);
  1702. {$endif alpha}
  1703. writestring(mangledname);
  1704. writelong(extnumber);
  1705. if (options and pooperator) = 0 then
  1706. writedefref(nextoverloaded)
  1707. else
  1708. begin
  1709. { only write the overloads from the same unit }
  1710. if nextoverloaded^.owner=owner then
  1711. writedefref(nextoverloaded)
  1712. else
  1713. writedefref(nil);
  1714. end;
  1715. writedefref(_class);
  1716. if (options and poinline) <> 0 then
  1717. begin
  1718. { we need to save
  1719. - the para and the local symtable
  1720. - the code ptree !! PM
  1721. writesymtable(parast);
  1722. writesymtable(localst);
  1723. writeptree(ptree(code));
  1724. }
  1725. end;
  1726. current_ppu^.writeentry(ibprocdef);
  1727. end;
  1728. {$ifdef GDB}
  1729. procedure addparaname(p : psym);
  1730. var vs : char;
  1731. begin
  1732. if pvarsym(p)^.varspez = vs_value then vs := '1'
  1733. else vs := '0';
  1734. strpcopy(strend(StabRecString),p^.name+':'+pvarsym(p)^.definition^.numberstring+','+vs+';');
  1735. end;
  1736. function tprocdef.stabstring : pchar;
  1737. var param : pdefcoll;
  1738. i : word;
  1739. vartyp : char;
  1740. oldrec : pchar;
  1741. begin
  1742. oldrec := stabrecstring;
  1743. getmem(StabRecString,1024);
  1744. param := para1;
  1745. i := 0;
  1746. while assigned(param) do
  1747. begin
  1748. inc(i);
  1749. param := param^.next;
  1750. end;
  1751. strpcopy(StabRecString,'f'+retdef^.numberstring);
  1752. if i>0 then
  1753. begin
  1754. strpcopy(strend(StabRecString),','+tostr(i)+';');
  1755. if assigned(parast) then
  1756. {$IfDef TP}
  1757. parast^.foreach(addparaname)
  1758. {$Else}
  1759. parast^.foreach(@addparaname)
  1760. {$EndIf}
  1761. else
  1762. begin
  1763. param := para1;
  1764. i := 0;
  1765. while assigned(param) do
  1766. begin
  1767. inc(i);
  1768. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  1769. {Here we have lost the parameter names !!}
  1770. {using lower case parameters }
  1771. strpcopy(strend(stabrecstring),'p'+tostr(i)
  1772. +':'+param^.data^.numberstring+','+vartyp+';');
  1773. param := param^.next;
  1774. end;
  1775. end;
  1776. {strpcopy(strend(StabRecString),';');}
  1777. end;
  1778. stabstring := strnew(stabrecstring);
  1779. freemem(stabrecstring,1024);
  1780. stabrecstring := oldrec;
  1781. end;
  1782. procedure tprocdef.concatstabto(asmlist : paasmoutput);
  1783. begin
  1784. end;
  1785. {$endif GDB}
  1786. procedure tprocdef.deref;
  1787. begin
  1788. inherited deref;
  1789. resolvedef(pdef(nextoverloaded));
  1790. resolvedef(pdef(_class));
  1791. end;
  1792. function tprocdef.mangledname : string;
  1793. {$ifdef tp}
  1794. var
  1795. oldpos : longint;
  1796. s : string;
  1797. b : byte;
  1798. {$endif tp}
  1799. begin
  1800. {$ifdef tp}
  1801. if use_big then
  1802. begin
  1803. symbolstream.seek(longint(_mangledname));
  1804. symbolstream.read(b,1);
  1805. symbolstream.read(s[1],b);
  1806. s[0]:=chr(b);
  1807. mangledname:=s;
  1808. end
  1809. else
  1810. {$endif}
  1811. mangledname:=strpas(_mangledname);
  1812. end;
  1813. {$IfDef GDB}
  1814. function tprocdef.cplusplusmangledname : string;
  1815. var
  1816. s,s2 : string;
  1817. param : pdefcoll;
  1818. begin
  1819. s := sym^.name;
  1820. if _class <> nil then
  1821. begin
  1822. s2 := _class^.name^;
  1823. s := s+'__'+tostr(length(s2))+s2;
  1824. end else s := s + '_';
  1825. param := para1;
  1826. while assigned(param) do
  1827. begin
  1828. s2 := param^.data^.sym^.name;
  1829. s := s+tostr(length(s2))+s2;
  1830. param := param^.next;
  1831. end;
  1832. cplusplusmangledname:=s;
  1833. end;
  1834. {$EndIf GDB}
  1835. procedure tprocdef.setmangledname(const s : string);
  1836. begin
  1837. if {$ifdef tp}not(use_big) and{$endif} (assigned(_mangledname)) then
  1838. strdispose(_mangledname);
  1839. setstring(_mangledname,s);
  1840. {$ifdef UseBrowser}
  1841. if assigned(parast) then
  1842. begin
  1843. stringdispose(parast^.name);
  1844. parast^.name:=stringdup('args of '+s);
  1845. end;
  1846. if assigned(localst) then
  1847. begin
  1848. stringdispose(localst^.name);
  1849. localst^.name:=stringdup('locals of '+s);
  1850. end;
  1851. {$endif UseBrowser}
  1852. end;
  1853. {***********************************************************************************
  1854. TPROCVARDEF
  1855. ***************************************************************************}
  1856. constructor tprocvardef.init;
  1857. begin
  1858. inherited init;
  1859. deftype:=procvardef;
  1860. end;
  1861. constructor tprocvardef.load;
  1862. begin
  1863. inherited load;
  1864. deftype:=procvardef;
  1865. end;
  1866. procedure tprocvardef.write;
  1867. begin
  1868. { here we cannot get a real good value so just give something }
  1869. { plausible (PM) }
  1870. {$ifdef StoreFPULevel}
  1871. if is_fpu(retdef) then
  1872. fpu_used:=2
  1873. else
  1874. fpu_used:=0;
  1875. {$endif StoreFPULevel}
  1876. inherited write;
  1877. current_ppu^.writeentry(ibprocvardef);
  1878. end;
  1879. function tprocvardef.size : longint;
  1880. begin
  1881. if (options and pomethodpointer)=0 then
  1882. size:=sizeof(pointer)
  1883. else
  1884. size:=2*sizeof(pointer);
  1885. end;
  1886. {$ifdef GDB}
  1887. function tprocvardef.stabstring : pchar;
  1888. var
  1889. nss : pchar;
  1890. i : word;
  1891. vartyp : char;
  1892. pst : pchar;
  1893. param : pdefcoll;
  1894. begin
  1895. i := 0;
  1896. param := para1;
  1897. while assigned(param) do
  1898. begin
  1899. inc(i);
  1900. param := param^.next;
  1901. end;
  1902. getmem(nss,1024);
  1903. strpcopy(nss,'f'+retdef^.numberstring+','+tostr(i)+';');
  1904. param := para1;
  1905. i := 0;
  1906. while assigned(param) do
  1907. begin
  1908. inc(i);
  1909. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  1910. {Here we have lost the parameter names !!}
  1911. pst := strpnew('p'+tostr(i)+':'+param^.data^.numberstring+','+vartyp+';');
  1912. strcat(nss,pst);
  1913. strdispose(pst);
  1914. param := param^.next;
  1915. end;
  1916. {strpcopy(strend(nss),';');}
  1917. stabstring := strnew(nss);
  1918. freemem(nss,1024);
  1919. end;
  1920. procedure tprocvardef.concatstabto(asmlist : paasmoutput);
  1921. begin
  1922. if ( not assigned(sym) or sym^.isusedinstab or use_dbx)
  1923. and not is_def_stab_written then
  1924. inherited concatstabto(asmlist);
  1925. is_def_stab_written:=true;
  1926. end;
  1927. {$endif GDB}
  1928. procedure tprocvardef.generate_rtti;
  1929. begin
  1930. inherited generate_rtti;
  1931. rttilist^.concat(new(pai_const,init_8bit(255)));
  1932. end;
  1933. {***************************************************************************
  1934. TOBJECTDEF
  1935. ***************************************************************************}
  1936. {$ifdef GDB}
  1937. const
  1938. vtabletype : word = 0;
  1939. vtableassigned : boolean = false;
  1940. {$endif GDB}
  1941. constructor tobjectdef.init(const n : string;c : pobjectdef);
  1942. begin
  1943. tdef.init;
  1944. deftype:=objectdef;
  1945. childof:=c;
  1946. options:=0;
  1947. { privatesyms:=new(psymtable,init(objectsymtable));
  1948. protectedsyms:=new(psymtable,init(objectsymtable)); }
  1949. publicsyms:=new(psymtable,init(objectsymtable));
  1950. publicsyms^.name := stringdup(n);
  1951. { add the data of the anchestor class }
  1952. if assigned(childof) then
  1953. begin
  1954. publicsyms^.datasize:=
  1955. publicsyms^.datasize-4+childof^.publicsyms^.datasize;
  1956. end;
  1957. name:=stringdup(n);
  1958. savesize := publicsyms^.datasize;
  1959. publicsyms^.defowner:=@self;
  1960. end;
  1961. constructor tobjectdef.load;
  1962. var
  1963. oldread_member : boolean;
  1964. begin
  1965. tdef.load;
  1966. deftype:=objectdef;
  1967. savesize:=readlong;
  1968. name:=stringdup(readstring);
  1969. childof:=pobjectdef(readdefref);
  1970. options:=readlong;
  1971. oldread_member:=read_member;
  1972. read_member:=true;
  1973. object_options:=true;
  1974. publicsyms:=new(psymtable,loadasstruct(objectsymtable));
  1975. object_options:=false;
  1976. read_member:=oldread_member;
  1977. publicsyms^.defowner:=@self;
  1978. publicsyms^.datasize:=savesize;
  1979. publicsyms^.name := stringdup(name^);
  1980. { handles the predefined class tobject }
  1981. { the last TOBJECT which is loaded gets }
  1982. { it ! }
  1983. if (name^='TOBJECT') and not(cs_compilesystem in aktmoduleswitches) and
  1984. isclass and (childof=pointer($ffffffff)) then
  1985. class_tobject:=@self;
  1986. end;
  1987. procedure tobjectdef.check_forwards;
  1988. begin
  1989. publicsyms^.check_forwards;
  1990. if (options and oo_isforward)<>0 then
  1991. begin
  1992. { ok, in future, the forward can be resolved }
  1993. Message1(sym_e_class_forward_not_resolved,name^);
  1994. options:=options and not(oo_isforward);
  1995. end;
  1996. end;
  1997. destructor tobjectdef.done;
  1998. begin
  1999. {!!!!
  2000. if assigned(privatesyms) then
  2001. dispose(privatesyms,done);
  2002. if assigned(protectedsyms) then
  2003. dispose(protectedsyms,done); }
  2004. if assigned(publicsyms) then
  2005. dispose(publicsyms,done);
  2006. if (options and oo_isforward)<>0 then
  2007. Message1(sym_e_class_forward_not_resolved,name^);
  2008. stringdispose(name);
  2009. tdef.done;
  2010. end;
  2011. { true, if self inherits from d (or if they are equal) }
  2012. function tobjectdef.isrelated(d : pobjectdef) : boolean;
  2013. var
  2014. hp : pobjectdef;
  2015. begin
  2016. hp:=@self;
  2017. while assigned(hp) do
  2018. begin
  2019. if hp=d then
  2020. begin
  2021. isrelated:=true;
  2022. exit;
  2023. end;
  2024. hp:=hp^.childof;
  2025. end;
  2026. isrelated:=false;
  2027. end;
  2028. function tobjectdef.size : longint;
  2029. begin
  2030. if (options and oois_class)<>0 then
  2031. size:=sizeof(pointer)
  2032. else
  2033. size:=publicsyms^.datasize;
  2034. end;
  2035. procedure tobjectdef.deref;
  2036. var
  2037. hp : pdef;
  2038. oldrecsyms : psymtable;
  2039. begin
  2040. resolvedef(pdef(childof));
  2041. oldrecsyms:=aktrecordsymtable;
  2042. aktrecordsymtable:=publicsyms;
  2043. { nun die Definitionen dereferenzieren }
  2044. hp:=publicsyms^.rootdef;
  2045. while assigned(hp) do
  2046. begin
  2047. hp^.deref;
  2048. { set owner }
  2049. hp^.owner:=publicsyms;
  2050. hp:=hp^.next;
  2051. end;
  2052. {$ifdef tp}
  2053. publicsyms^.foreach(derefsym);
  2054. {$else}
  2055. publicsyms^.foreach(@derefsym);
  2056. {$endif}
  2057. aktrecordsymtable:=oldrecsyms;
  2058. end;
  2059. function tobjectdef.vmt_mangledname : string;
  2060. {DM: I get a nil pointer on the owner name. I don't know if this
  2061. mayhappen, and I have therefore fixed the problem by doing nil pointer
  2062. checks.}
  2063. var s1,s2:string;
  2064. begin
  2065. if owner^.name=nil then
  2066. s1:=''
  2067. else
  2068. s1:=owner^.name^;
  2069. if name=nil then
  2070. s2:=''
  2071. else
  2072. s2:=name^;
  2073. vmt_mangledname:='VMT_'+s1+'$_'+s2;
  2074. end;
  2075. function tobjectdef.isclass : boolean;
  2076. begin
  2077. isclass:=(options and oois_class)<>0;
  2078. end;
  2079. procedure tobjectdef.write;
  2080. var
  2081. oldread_member : boolean;
  2082. begin
  2083. tdef.write;
  2084. writelong(size);
  2085. writestring(name^);
  2086. writedefref(childof);
  2087. writelong(options);
  2088. current_ppu^.writeentry(ibobjectdef);
  2089. oldread_member:=read_member;
  2090. read_member:=true;
  2091. object_options:=true;
  2092. publicsyms^.writeasstruct;
  2093. object_options:=false;
  2094. read_member:=oldread_member;
  2095. end;
  2096. {$ifdef GDB}
  2097. procedure addprocname(p :psym);
  2098. var virtualind,argnames : string;
  2099. news, newrec : pchar;
  2100. pd,ipd : pprocdef;
  2101. lindex : longint;
  2102. para : pdefcoll;
  2103. arglength : byte;
  2104. sp : char;
  2105. begin
  2106. If p^.typ = procsym then
  2107. begin
  2108. pd := pprocsym(p)^.definition;
  2109. { this will be used for full implementation of object stabs
  2110. not yet done }
  2111. ipd := pd;
  2112. while assigned(ipd^.nextoverloaded) do ipd := ipd^.nextoverloaded;
  2113. if (pd^.options and povirtualmethod) <> 0 then
  2114. begin
  2115. lindex := pd^.extnumber;
  2116. {doesnt seem to be necessary
  2117. lindex := lindex or $80000000;}
  2118. virtualind := '*'+tostr(lindex)+';'+ipd^._class^.numberstring+';'
  2119. end else virtualind := '.';
  2120. { arguments are not listed here }
  2121. {we don't need another definition}
  2122. para := pd^.para1;
  2123. argnames := '';
  2124. while assigned(para) do
  2125. begin
  2126. if para^.data^.deftype = formaldef then
  2127. begin
  2128. if para^.paratyp=vs_var then
  2129. argnames := argnames+'3var'
  2130. else if para^.paratyp=vs_const then
  2131. argnames:=argnames+'5const';
  2132. end
  2133. else
  2134. begin
  2135. { if the arg definition is like (v: ^byte;..
  2136. there is no sym attached to data !!! }
  2137. if assigned(para^.data^.sym) then
  2138. begin
  2139. arglength := length(para^.data^.sym^.name);
  2140. argnames := argnames + tostr(arglength)+para^.data^.sym^.name;
  2141. end
  2142. else
  2143. begin
  2144. argnames:=argnames+'11unnamedtype';
  2145. end;
  2146. end;
  2147. para := para^.next;
  2148. end;
  2149. ipd^.is_def_stab_written := true;
  2150. { here 2A must be changed for private and protected }
  2151. { 0 is private 1 protected and 2 public }
  2152. if (p^.properties and sp_private)<>0 then sp:='0'
  2153. else if (p^.properties and sp_protected)<>0 then sp:='1'
  2154. else sp:='2';
  2155. newrec := strpnew(p^.name+'::'+ipd^.numberstring
  2156. +'=##'+pd^.retdef^.numberstring+';:'+argnames+';'+sp+'A'
  2157. +virtualind+';');
  2158. { get spare place for a string at the end }
  2159. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  2160. begin
  2161. getmem(news,stabrecsize+memsizeinc);
  2162. strcopy(news,stabrecstring);
  2163. freemem(stabrecstring,stabrecsize);
  2164. stabrecsize:=stabrecsize+memsizeinc;
  2165. stabrecstring:=news;
  2166. end;
  2167. strcat(StabRecstring,newrec);
  2168. {freemem(newrec,memsizeinc); }
  2169. strdispose(newrec);
  2170. {This should be used for case !!}
  2171. RecOffset := RecOffset + pd^.size;
  2172. end;
  2173. end;
  2174. function tobjectdef.stabstring : pchar;
  2175. var anc : pobjectdef;
  2176. oldrec : pchar;
  2177. oldrecsize : longint;
  2178. str_end : string;
  2179. begin
  2180. oldrec := stabrecstring;
  2181. oldrecsize:=stabrecsize;
  2182. stabrecsize:=memsizeinc;
  2183. GetMem(stabrecstring,stabrecsize);
  2184. strpcopy(stabRecString,'s'+tostr(size));
  2185. if assigned(childof) then
  2186. {only one ancestor not virtual, public, at base offset 0 }
  2187. { !1 , 0 2 0 , }
  2188. strpcopy(strend(stabrecstring),'!1,020,'+childof^.numberstring+';');
  2189. {virtual table to implement yet}
  2190. RecOffset := 0;
  2191. {$ifdef tp}
  2192. publicsyms^.foreach(addname);
  2193. {$else}
  2194. publicsyms^.foreach(@addname);
  2195. {$endif tp}
  2196. if (options and oo_hasvirtual) <> 0 then
  2197. if not assigned(childof) or ((childof^.options and oo_hasvirtual) = 0) then
  2198. begin
  2199. str_end:='$vf'+numberstring+':'+typeglobalnumber('vtblarray')+',0;';
  2200. strpcopy(strend(stabrecstring),'$vf'+numberstring+':'+typeglobalnumber('vtblarray')+',0;');
  2201. end;
  2202. {$ifdef tp}
  2203. publicsyms^.foreach(addprocname);
  2204. {$else}
  2205. publicsyms^.foreach(@addprocname);
  2206. {$endif tp }
  2207. if (options and oo_hasvirtual) <> 0 then
  2208. begin
  2209. anc := @self;
  2210. while assigned(anc^.childof) and ((anc^.childof^.options and oo_hasvirtual) <> 0) do
  2211. anc := anc^.childof;
  2212. str_end:=';~%'+anc^.numberstring+';';
  2213. end
  2214. else
  2215. str_end:=';';
  2216. strpcopy(strend(stabrecstring),str_end);
  2217. stabstring := strnew(StabRecString);
  2218. freemem(stabrecstring,stabrecsize);
  2219. stabrecstring := oldrec;
  2220. stabrecsize:=oldrecsize;
  2221. end;
  2222. {$endif GDB}
  2223. procedure tobjectdef.generate_rtti;
  2224. begin
  2225. publicsyms^.foreach(generate_child_rtti);
  2226. inherited generate_rtti;
  2227. if isclass then
  2228. rttilist^.concat(new(pai_const,init_8bit(17)))
  2229. else
  2230. rttilist^.concat(new(pai_const,init_8bit(16)));
  2231. { generate the name }
  2232. rttilist^.concat(new(pai_const,init_8bit(length(name^))));
  2233. rttilist^.concat(new(pai_string,init(name^)));
  2234. rttilist^.concat(new(pai_const,init_32bit(size)));
  2235. count:=0;
  2236. publicsyms^.foreach(count_field);
  2237. rttilist^.concat(new(pai_const,init_32bit(count)));
  2238. publicsyms^.foreach(write_field_info);
  2239. end;
  2240. {****************************************************************************
  2241. TERRORDEF
  2242. ****************************************************************************}
  2243. constructor terrordef.init;
  2244. begin
  2245. tdef.init;
  2246. deftype:=errordef;
  2247. end;
  2248. {$ifdef GDB}
  2249. function terrordef.stabstring : pchar;
  2250. begin
  2251. stabstring:=strpnew('error'+numberstring);
  2252. end;
  2253. {$endif GDB}
  2254. {
  2255. $Log$
  2256. Revision 1.26 1998-08-25 12:42:44 pierre
  2257. * CDECL changed to CVAR for variables
  2258. specifications are read in structures also
  2259. + started adding GPC compatibility mode ( option -Sp)
  2260. * names changed to lowercase
  2261. Revision 1.25 1998/08/23 21:04:38 florian
  2262. + rtti generation for classes added
  2263. + new/dispose do now also a call to INITIALIZE/FINALIZE, if necessaray
  2264. Revision 1.24 1998/08/20 12:53:26 peter
  2265. * object_options are always written for object syms
  2266. Revision 1.23 1998/08/19 00:42:42 peter
  2267. + subrange types for enums
  2268. + checking for bounds type with ranges
  2269. Revision 1.22 1998/08/17 10:10:10 peter
  2270. - removed OLDPPU
  2271. Revision 1.21 1998/08/10 14:50:28 peter
  2272. + localswitches, moduleswitches, globalswitches splitting
  2273. Revision 1.20 1998/07/18 22:54:30 florian
  2274. * some ansi/wide/longstring support fixed:
  2275. o parameter passing
  2276. o returning as result from functions
  2277. Revision 1.19 1998/07/14 14:47:05 peter
  2278. * released NEWINPUT
  2279. Revision 1.18 1998/07/10 10:51:04 peter
  2280. * m68k updates
  2281. Revision 1.16 1998/07/07 11:20:13 peter
  2282. + NEWINPUT for a better inputfile and scanner object
  2283. Revision 1.15 1998/06/24 14:48:37 peter
  2284. * ifdef newppu -> ifndef oldppu
  2285. Revision 1.14 1998/06/16 08:56:31 peter
  2286. + targetcpu
  2287. * cleaner pmodules for newppu
  2288. Revision 1.13 1998/06/15 15:38:09 pierre
  2289. * small bug in systems.pas corrected
  2290. + operators in different units better hanlded
  2291. Revision 1.12 1998/06/15 14:30:12 daniel
  2292. * Reverted my changes.
  2293. Revision 1.10 1998/06/13 00:10:16 peter
  2294. * working browser and newppu
  2295. * some small fixes against crashes which occured in bp7 (but not in
  2296. fpc?!)
  2297. Revision 1.9 1998/06/12 14:10:37 michael
  2298. * Fixed wrong code for ansistring
  2299. Revision 1.8 1998/06/11 10:11:58 peter
  2300. * -gb works again
  2301. Revision 1.7 1998/06/07 15:30:25 florian
  2302. + first working rtti
  2303. + data init/final. for local variables
  2304. Revision 1.6 1998/06/05 14:37:37 pierre
  2305. * fixes for inline for operators
  2306. * inline procedure more correctly restricted
  2307. Revision 1.5 1998/06/04 23:52:01 peter
  2308. * m68k compiles
  2309. + .def file creation moved to gendef.pas so it could also be used
  2310. for win32
  2311. Revision 1.4 1998/06/04 09:55:45 pierre
  2312. * demangled name of procsym reworked to become independant of the mangling
  2313. scheme
  2314. Revision 1.3 1998/06/03 22:49:03 peter
  2315. + wordbool,longbool
  2316. * rename bis,von -> high,low
  2317. * moved some systemunit loading/creating to psystem.pas
  2318. Revision 1.2 1998/05/31 14:13:37 peter
  2319. * fixed call bugs with assembler readers
  2320. + OPR_SYMBOL to hold a symbol in the asm parser
  2321. * fixed staticsymtable vars which were acessed through %ebp instead of
  2322. name
  2323. Revision 1.1 1998/05/27 19:45:09 peter
  2324. * symtable.pas splitted into includefiles
  2325. * symtable adapted for $ifndef OLDPPU
  2326. }