symdef.inc 74 KB

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