symdef.inc 96 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl, Pierre Muller
  4. Symbol table implementation for the definitions
  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 definitions)
  20. ****************************************************************************}
  21. const
  22. { if you change one of the following contants, }
  23. { you have also to change the typinfo unit }
  24. tkUnknown = 0;
  25. tkInteger = 1;
  26. tkChar = 2;
  27. tkEnumeration = 3;
  28. tkFloat = 4;
  29. tkSet = 6;
  30. tkMethod = 7;
  31. tkSString = 8;
  32. tkString = tkSString;
  33. tkLString = 9;
  34. tkAString = 10;
  35. tkWString = 11;
  36. tkVariant = 12;
  37. tkArray = 13;
  38. tkRecord = 14;
  39. tkInterface = 15;
  40. tkClass = 16;
  41. tkObject = 17;
  42. tkWChar = 18;
  43. tkBool = 19;
  44. otSByte = 0;
  45. otUByte = 1;
  46. otSWord = 2;
  47. otUWord = 3;
  48. otSLong = 4;
  49. otULong = 5;
  50. ftSingle = 0;
  51. ftDouble = 1;
  52. ftExtended = 2;
  53. ftComp = 3;
  54. ftCurr = 4;
  55. ftFixed16 = 5;
  56. ftFixed32 = 6;
  57. constructor tdef.init;
  58. begin
  59. deftype:=abstractdef;
  60. owner := nil;
  61. next := nil;
  62. sym := nil;
  63. indexnb := 0;
  64. if registerdef then
  65. symtablestack^.registerdef(@self);
  66. has_rtti:=false;
  67. has_inittable:=false;
  68. {$ifdef GDB}
  69. is_def_stab_written := false;
  70. globalnb := 0;
  71. {$endif GDB}
  72. if assigned(lastglobaldef) then
  73. begin
  74. lastglobaldef^.nextglobal := @self;
  75. previousglobal:=lastglobaldef;
  76. end
  77. else
  78. begin
  79. firstglobaldef := @self;
  80. previousglobal := nil;
  81. end;
  82. lastglobaldef := @self;
  83. nextglobal := nil;
  84. end;
  85. constructor tdef.load;
  86. begin
  87. deftype:=abstractdef;
  88. indexnb := 0;
  89. sym := nil;
  90. owner := nil;
  91. next := nil;
  92. has_rtti:=false;
  93. has_inittable:=false;
  94. {$ifdef GDB}
  95. is_def_stab_written := false;
  96. globalnb := 0;
  97. {$endif GDB}
  98. if assigned(lastglobaldef) then
  99. begin
  100. lastglobaldef^.nextglobal := @self;
  101. previousglobal:=lastglobaldef;
  102. end
  103. else
  104. begin
  105. firstglobaldef := @self;
  106. previousglobal:=nil;
  107. end;
  108. lastglobaldef := @self;
  109. nextglobal := nil;
  110. end;
  111. destructor tdef.done;
  112. begin
  113. { first element ? }
  114. if not(assigned(previousglobal)) then
  115. begin
  116. firstglobaldef := nextglobal;
  117. if assigned(firstglobaldef) then
  118. firstglobaldef^.previousglobal:=nil;
  119. end
  120. else
  121. begin
  122. { remove reference in the element before }
  123. previousglobal^.nextglobal:=nextglobal;
  124. end;
  125. { last element ? }
  126. if not(assigned(nextglobal)) then
  127. begin
  128. lastglobaldef := previousglobal;
  129. if assigned(lastglobaldef) then
  130. lastglobaldef^.nextglobal:=nil;
  131. end
  132. else
  133. nextglobal^.previousglobal:=previousglobal;
  134. previousglobal:=nil;
  135. nextglobal:=nil;
  136. end;
  137. procedure tdef.write;
  138. begin
  139. {$ifdef GDB}
  140. if globalnb = 0 then
  141. begin
  142. if assigned(owner) then
  143. globalnb := owner^.getnewtypecount
  144. else
  145. begin
  146. globalnb := PGlobalTypeCount^;
  147. Inc(PGlobalTypeCount^);
  148. end;
  149. end;
  150. {$endif GDB}
  151. end;
  152. function tdef.size : longint;
  153. begin
  154. size:=savesize;
  155. end;
  156. {$ifdef GDB}
  157. procedure tdef.set_globalnb;
  158. begin
  159. globalnb :=PGlobalTypeCount^;
  160. inc(PglobalTypeCount^);
  161. end;
  162. function tdef.stabstring : pchar;
  163. begin
  164. stabstring := strpnew('t'+numberstring+';');
  165. end;
  166. function tdef.numberstring : string;
  167. var table : psymtable;
  168. begin
  169. {formal def have no type !}
  170. if deftype = formaldef then
  171. begin
  172. numberstring := voiddef^.numberstring;
  173. exit;
  174. end;
  175. if (not assigned(sym)) or (not sym^.isusedinstab) then
  176. begin
  177. {set even if debuglist is not defined}
  178. if assigned(sym) then
  179. sym^.isusedinstab := true;
  180. if assigned(debuglist) and not is_def_stab_written then
  181. concatstabto(debuglist);
  182. end;
  183. if not use_dbx then
  184. begin
  185. if globalnb = 0 then
  186. set_globalnb;
  187. numberstring := tostr(globalnb);
  188. end
  189. else
  190. begin
  191. if globalnb = 0 then
  192. begin
  193. if assigned(owner) then
  194. globalnb := owner^.getnewtypecount
  195. else
  196. begin
  197. globalnb := PGlobalTypeCount^;
  198. Inc(PGlobalTypeCount^);
  199. end;
  200. end;
  201. if assigned(sym) then
  202. begin
  203. table := sym^.owner;
  204. if table^.unitid > 0 then
  205. numberstring := '('+tostr(table^.unitid)+','
  206. +tostr(sym^.definition^.globalnb)+')'
  207. else
  208. numberstring := tostr(globalnb);
  209. exit;
  210. end;
  211. numberstring := tostr(globalnb);
  212. end;
  213. end;
  214. function tdef.allstabstring : pchar;
  215. var stabchar : string[2];
  216. ss,st : pchar;
  217. name : string;
  218. sym_line_no : longint;
  219. begin
  220. ss := stabstring;
  221. getmem(st,strlen(ss)+512);
  222. stabchar := 't';
  223. if deftype in tagtypes then
  224. stabchar := 'Tt';
  225. if assigned(sym) then
  226. begin
  227. name := sym^.name;
  228. sym_line_no:=sym^.fileinfo.line;
  229. end
  230. else
  231. begin
  232. name := ' ';
  233. sym_line_no:=0;
  234. end;
  235. strpcopy(st,'"'+name+':'+stabchar+numberstring+'=');
  236. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  237. allstabstring := strnew(st);
  238. freemem(st,strlen(ss)+512);
  239. strdispose(ss);
  240. end;
  241. procedure tdef.concatstabto(asmlist : paasmoutput);
  242. var stab_str : pchar;
  243. begin
  244. if ((sym = nil) or sym^.isusedinstab or use_dbx)
  245. and not is_def_stab_written then
  246. begin
  247. If use_dbx then
  248. begin
  249. { otherwise you get two of each def }
  250. If assigned(sym) then
  251. begin
  252. if sym^.typ=typesym then
  253. sym^.isusedinstab:=true;
  254. if (sym^.owner = nil) or
  255. ((sym^.owner^.symtabletype = unitsymtable) and
  256. punitsymtable(sym^.owner)^.dbx_count_ok) then
  257. begin
  258. {with DBX we get the definition from the other objects }
  259. is_def_stab_written := true;
  260. exit;
  261. end;
  262. end;
  263. end;
  264. { to avoid infinite loops }
  265. is_def_stab_written := true;
  266. stab_str := allstabstring;
  267. if asmlist = debuglist then do_count_dbx := true;
  268. { count_dbx(stab_str); moved to GDB.PAS}
  269. asmlist^.concat(new(pai_stabs,init(stab_str)));
  270. end;
  271. end;
  272. {$endif GDB}
  273. procedure tdef.deref;
  274. begin
  275. end;
  276. { rtti generation }
  277. procedure tdef.generate_rtti;
  278. begin
  279. has_rtti:=true;
  280. getlabel(rtti_label);
  281. write_child_rtti_data;
  282. rttilist^.concat(new(pai_label,init(rtti_label)));
  283. write_rtti_data;
  284. end;
  285. function tdef.get_rtti_label : plabel;
  286. begin
  287. if not(has_rtti) then
  288. generate_rtti;
  289. get_rtti_label:=rtti_label;
  290. end;
  291. { init table handling }
  292. function tdef.needs_inittable : boolean;
  293. begin
  294. needs_inittable:=false;
  295. end;
  296. procedure tdef.generate_inittable;
  297. begin
  298. has_inittable:=true;
  299. getlabel(inittable_label);
  300. write_child_init_data;
  301. rttilist^.concat(new(pai_label,init(inittable_label)));
  302. write_init_data;
  303. end;
  304. procedure tdef.write_init_data;
  305. begin
  306. write_rtti_data;
  307. end;
  308. procedure tdef.write_child_init_data;
  309. begin
  310. write_child_rtti_data;
  311. end;
  312. function tdef.get_inittable_label : plabel;
  313. begin
  314. if not(has_inittable) then
  315. generate_inittable;
  316. get_inittable_label:=inittable_label;
  317. end;
  318. procedure tdef.writename;
  319. var
  320. str : string;
  321. begin
  322. { name }
  323. if assigned(sym) then
  324. begin
  325. str:=sym^.name;
  326. rttilist^.concat(new(pai_string,init(chr(length(str))+str)));
  327. end
  328. else
  329. rttilist^.concat(new(pai_string,init(#0)))
  330. end;
  331. { returns true, if the definition can be published }
  332. function tdef.is_publishable : boolean;
  333. begin
  334. is_publishable:=false;
  335. end;
  336. procedure tdef.write_rtti_data;
  337. begin
  338. end;
  339. procedure tdef.write_child_rtti_data;
  340. begin
  341. end;
  342. {****************************************************************************
  343. TSTRINGDEF
  344. ****************************************************************************}
  345. constructor tstringdef.init(l : byte);
  346. begin
  347. tdef.init;
  348. string_typ:=st_shortstring;
  349. deftype:=stringdef;
  350. len:=l;
  351. savesize:=len+1;
  352. end;
  353. constructor tstringdef.load;
  354. begin
  355. tdef.load;
  356. string_typ:=st_shortstring;
  357. deftype:=stringdef;
  358. len:=readbyte;
  359. savesize:=len+1;
  360. end;
  361. constructor tstringdef.longinit(l : longint);
  362. begin
  363. tdef.init;
  364. string_typ:=st_longstring;
  365. deftype:=stringdef;
  366. len:=l;
  367. savesize:=target_os.size_of_pointer;
  368. end;
  369. constructor tstringdef.longload;
  370. begin
  371. tdef.load;
  372. deftype:=stringdef;
  373. string_typ:=st_longstring;
  374. len:=readlong;
  375. savesize:=target_os.size_of_pointer;
  376. end;
  377. constructor tstringdef.ansiinit(l : longint);
  378. begin
  379. tdef.init;
  380. string_typ:=st_ansistring;
  381. deftype:=stringdef;
  382. len:=l;
  383. savesize:=target_os.size_of_pointer;
  384. end;
  385. constructor tstringdef.ansiload;
  386. begin
  387. tdef.load;
  388. deftype:=stringdef;
  389. string_typ:=st_ansistring;
  390. len:=readlong;
  391. savesize:=target_os.size_of_pointer;
  392. end;
  393. constructor tstringdef.wideinit(l : longint);
  394. begin
  395. tdef.init;
  396. string_typ:=st_widestring;
  397. deftype:=stringdef;
  398. len:=l;
  399. savesize:=target_os.size_of_pointer;
  400. end;
  401. constructor tstringdef.wideload;
  402. begin
  403. tdef.load;
  404. deftype:=stringdef;
  405. string_typ:=st_widestring;
  406. len:=readlong;
  407. savesize:=target_os.size_of_pointer;
  408. end;
  409. function tstringdef.size : longint;
  410. begin
  411. size:=savesize;
  412. end;
  413. procedure tstringdef.write;
  414. begin
  415. tdef.write;
  416. if string_typ=st_shortstring then
  417. writebyte(len)
  418. else
  419. writelong(len);
  420. case string_typ of
  421. st_shortstring : current_ppu^.writeentry(ibstringdef);
  422. st_longstring : current_ppu^.writeentry(iblongstringdef);
  423. st_ansistring : current_ppu^.writeentry(ibansistringdef);
  424. st_widestring : current_ppu^.writeentry(ibwidestringdef);
  425. end;
  426. end;
  427. {$ifdef GDB}
  428. function tstringdef.stabstring : pchar;
  429. var
  430. bytest,charst,longst : string;
  431. begin
  432. case string_typ of
  433. st_shortstring:
  434. begin
  435. charst := typeglobalnumber('char');
  436. { this is what I found in stabs.texinfo but
  437. gdb 4.12 for go32 doesn't understand that !! }
  438. {$IfDef GDBknowsstrings}
  439. stabstring := strpnew('n'+charst+';'+tostr(len));
  440. {$else}
  441. bytest := typeglobalnumber('byte');
  442. stabstring := strpnew('s'+tostr(len+1)+'length:'+bytest
  443. +',0,8;st:ar'+bytest
  444. +';1;'+tostr(len)+';'+charst+',8,'+tostr(len*8)+';;');
  445. {$EndIf}
  446. end;
  447. st_longstring:
  448. begin
  449. charst := typeglobalnumber('char');
  450. { this is what I found in stabs.texinfo but
  451. gdb 4.12 for go32 doesn't understand that !! }
  452. {$IfDef GDBknowsstrings}
  453. stabstring := strpnew('n'+charst+';'+tostr(len));
  454. {$else}
  455. bytest := typeglobalnumber('byte');
  456. longst := typeglobalnumber('longint');
  457. stabstring := strpnew('s'+tostr(len+5)+'length:'+longst
  458. +',0,32;dummy:'+bytest+',32,8;st:ar'+bytest
  459. +';1;'+tostr(len)+';'+charst+',40,'+tostr(len*8)+';;');
  460. {$EndIf}
  461. end;
  462. st_ansistring:
  463. begin
  464. { an ansi string looks like a pchar easy !! }
  465. stabstring:=strpnew('*'+typeglobalnumber('char'));
  466. end;
  467. st_widestring:
  468. begin
  469. { an ansi string looks like a pchar easy !! }
  470. stabstring:=strpnew('*'+typeglobalnumber('char'));
  471. end;
  472. end;
  473. end;
  474. procedure tstringdef.concatstabto(asmlist : paasmoutput);
  475. begin
  476. inherited concatstabto(asmlist);
  477. end;
  478. {$endif GDB}
  479. function tstringdef.needs_inittable : boolean;
  480. begin
  481. needs_inittable:=string_typ in [st_ansistring,st_widestring];
  482. end;
  483. procedure tstringdef.write_rtti_data;
  484. begin
  485. case string_typ of
  486. st_ansistring:
  487. begin
  488. rttilist^.concat(new(pai_const,init_8bit(tkAString)));
  489. end;
  490. st_widestring:
  491. begin
  492. rttilist^.concat(new(pai_const,init_8bit(tkWString)));
  493. end;
  494. st_longstring:
  495. begin
  496. rttilist^.concat(new(pai_const,init_8bit(tkLString)));
  497. end;
  498. st_shortstring:
  499. begin
  500. rttilist^.concat(new(pai_const,init_8bit(tkSString)));
  501. rttilist^.concat(new(pai_const,init_8bit(len)));
  502. end;
  503. end;
  504. end;
  505. function tstringdef.is_publishable : boolean;
  506. begin
  507. is_publishable:=true;
  508. end;
  509. {****************************************************************************
  510. TENUMDEF
  511. ****************************************************************************}
  512. constructor tenumdef.init;
  513. begin
  514. tdef.init;
  515. deftype:=enumdef;
  516. minval:=0;
  517. maxval:=0;
  518. calcsavesize;
  519. has_jumps:=false;
  520. basedef:=nil;
  521. rangenr:=0;
  522. first:=nil;
  523. end;
  524. constructor tenumdef.init_subrange(_basedef:penumdef;_min,_max:longint);
  525. begin
  526. tdef.init;
  527. deftype:=enumdef;
  528. minval:=_min;
  529. maxval:=_max;
  530. basedef:=_basedef;
  531. calcsavesize;
  532. has_jumps:=false;
  533. rangenr:=0;
  534. first:=nil;
  535. end;
  536. constructor tenumdef.load;
  537. begin
  538. tdef.load;
  539. deftype:=enumdef;
  540. basedef:=penumdef(readdefref);
  541. minval:=readlong;
  542. maxval:=readlong;
  543. savesize:=readlong;
  544. has_jumps:=false;
  545. first:=Nil;
  546. end;
  547. procedure tenumdef.calcsavesize;
  548. begin
  549. if (aktpackenum=4) or (min<0) or (max>65535) then
  550. savesize:=4
  551. else
  552. if (aktpackenum=2) or (min<0) or (max>255) then
  553. savesize:=2
  554. else
  555. savesize:=1;
  556. end;
  557. procedure tenumdef.setmax(_max:longint);
  558. begin
  559. maxval:=_max;
  560. calcsavesize;
  561. end;
  562. procedure tenumdef.setmin(_min:longint);
  563. begin
  564. minval:=_min;
  565. calcsavesize;
  566. end;
  567. function tenumdef.min:longint;
  568. begin
  569. min:=minval;
  570. end;
  571. function tenumdef.max:longint;
  572. begin
  573. max:=maxval;
  574. end;
  575. procedure tenumdef.deref;
  576. begin
  577. resolvedef(pdef(basedef));
  578. end;
  579. destructor tenumdef.done;
  580. begin
  581. inherited done;
  582. end;
  583. procedure tenumdef.write;
  584. begin
  585. tdef.write;
  586. writedefref(basedef);
  587. writelong(min);
  588. writelong(max);
  589. writelong(savesize);
  590. current_ppu^.writeentry(ibenumdef);
  591. end;
  592. function tenumdef.getrangecheckstring : string;
  593. begin
  594. if (cs_smartlink in aktmoduleswitches) then
  595. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  596. else
  597. getrangecheckstring:='R_'+tostr(rangenr);
  598. end;
  599. procedure tenumdef.genrangecheck;
  600. begin
  601. if rangenr=0 then
  602. begin
  603. { generate two constant for bounds }
  604. getlabelnr(rangenr);
  605. if (cs_smartlink in aktmoduleswitches) then
  606. datasegment^.concat(new(pai_symbol,init_global(getrangecheckstring)))
  607. else
  608. datasegment^.concat(new(pai_symbol,init(getrangecheckstring)));
  609. datasegment^.concat(new(pai_const,init_32bit(min)));
  610. datasegment^.concat(new(pai_const,init_32bit(max)));
  611. end;
  612. end;
  613. {$ifdef GDB}
  614. function tenumdef.stabstring : pchar;
  615. var st,st2 : pchar;
  616. p : penumsym;
  617. s : string;
  618. memsize : word;
  619. begin
  620. memsize := memsizeinc;
  621. getmem(st,memsize);
  622. strpcopy(st,'e');
  623. p := first;
  624. while assigned(p) do
  625. begin
  626. s :=p^.name+':'+tostr(p^.value)+',';
  627. { place for the ending ';' also }
  628. if (strlen(st)+length(s)+1<memsize) then
  629. strpcopy(strend(st),s)
  630. else
  631. begin
  632. getmem(st2,memsize+memsizeinc);
  633. strcopy(st2,st);
  634. freemem(st,memsize);
  635. st := st2;
  636. memsize := memsize+memsizeinc;
  637. strpcopy(strend(st),s);
  638. end;
  639. p := p^.next;
  640. end;
  641. strpcopy(strend(st),';');
  642. stabstring := strnew(st);
  643. freemem(st,memsize);
  644. end;
  645. {$endif GDB}
  646. procedure tenumdef.write_child_rtti_data;
  647. begin
  648. if assigned(basedef) then
  649. basedef^.get_rtti_label;
  650. end;
  651. procedure tenumdef.write_rtti_data;
  652. begin
  653. rttilist^.concat(new(pai_const,init_8bit(tkEnumeration)));
  654. case savesize of
  655. 1:
  656. rttilist^.concat(new(pai_const,init_8bit(otUByte)));
  657. 2:
  658. rttilist^.concat(new(pai_const,init_8bit(otUWord)));
  659. 4:
  660. rttilist^.concat(new(pai_const,init_8bit(otULong)));
  661. end;
  662. rttilist^.concat(new(pai_const,init_32bit(min)));
  663. rttilist^.concat(new(pai_const,init_32bit(max)));
  664. if assigned(basedef) then
  665. rttilist^.concat(new(pai_const,init_symbol(strpnew(lab2str(basedef^.get_rtti_label)))))
  666. else
  667. rttilist^.concat(new(pai_const,init_32bit(0)));
  668. {!!!!!!! Name list }
  669. end;
  670. function tenumdef.is_publishable : boolean;
  671. begin
  672. is_publishable:=true;
  673. end;
  674. {****************************************************************************
  675. TORDDEF
  676. ****************************************************************************}
  677. constructor torddef.init(t : tbasetype;v,b : longint);
  678. begin
  679. inherited init;
  680. deftype:=orddef;
  681. low:=v;
  682. high:=b;
  683. typ:=t;
  684. rangenr:=0;
  685. setsize;
  686. end;
  687. constructor torddef.load;
  688. begin
  689. inherited load;
  690. deftype:=orddef;
  691. typ:=tbasetype(readbyte);
  692. low:=readlong;
  693. high:=readlong;
  694. rangenr:=0;
  695. setsize;
  696. end;
  697. procedure torddef.setsize;
  698. begin
  699. if typ=uauto then
  700. begin
  701. { generate a unsigned range if high<0 and low>=0 }
  702. if (low>=0) and (high<0) then
  703. begin
  704. savesize:=4;
  705. typ:=u32bit;
  706. end
  707. else if (low>=0) and (high<=255) then
  708. begin
  709. savesize:=1;
  710. typ:=u8bit;
  711. end
  712. else if (low>=-128) and (high<=127) then
  713. begin
  714. savesize:=1;
  715. typ:=s8bit;
  716. end
  717. else if (low>=0) and (high<=65536) then
  718. begin
  719. savesize:=2;
  720. typ:=u16bit;
  721. end
  722. else if (low>=-32768) and (high<=32767) then
  723. begin
  724. savesize:=2;
  725. typ:=s16bit;
  726. end
  727. else
  728. begin
  729. savesize:=4;
  730. typ:=s32bit;
  731. end;
  732. end
  733. else
  734. begin
  735. case typ of
  736. u8bit,s8bit,
  737. uchar,bool8bit : savesize:=1;
  738. u16bit,s16bit,
  739. bool16bit : savesize:=2;
  740. s32bit,u32bit,
  741. bool32bit : savesize:=4;
  742. else
  743. savesize:=0;
  744. end;
  745. end;
  746. { there are no entrys for range checking }
  747. rangenr:=0;
  748. end;
  749. function torddef.getrangecheckstring : string;
  750. begin
  751. if (cs_smartlink in aktmoduleswitches) then
  752. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  753. else
  754. getrangecheckstring:='R_'+tostr(rangenr);
  755. end;
  756. procedure torddef.genrangecheck;
  757. begin
  758. if rangenr=0 then
  759. begin
  760. { generate two constant for bounds }
  761. getlabelnr(rangenr);
  762. if (cs_smartlink in aktmoduleswitches) then
  763. datasegment^.concat(new(pai_symbol,init_global(getrangecheckstring)))
  764. else
  765. datasegment^.concat(new(pai_symbol,init(getrangecheckstring)));
  766. if low<=high then
  767. begin
  768. datasegment^.concat(new(pai_const,init_32bit(low)));
  769. datasegment^.concat(new(pai_const,init_32bit(high)));
  770. end
  771. { for u32bit we need two bounds }
  772. else
  773. begin
  774. datasegment^.concat(new(pai_const,init_32bit(low)));
  775. datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
  776. inc(nextlabelnr);
  777. if (cs_smartlink in aktmoduleswitches) then
  778. datasegment^.concat(new(pai_symbol,init_global('R_'+current_module^.modulename^+tostr(rangenr+1))))
  779. else
  780. datasegment^.concat(new(pai_symbol,init('R_'+tostr(rangenr+1))));
  781. datasegment^.concat(new(pai_const,init_32bit($80000000)));
  782. datasegment^.concat(new(pai_const,init_32bit(high)));
  783. end;
  784. end;
  785. end;
  786. procedure torddef.write;
  787. begin
  788. tdef.write;
  789. writebyte(byte(typ));
  790. writelong(low);
  791. writelong(high);
  792. current_ppu^.writeentry(iborddef);
  793. end;
  794. {$ifdef GDB}
  795. function torddef.stabstring : pchar;
  796. begin
  797. case typ of
  798. uvoid : stabstring := strpnew(numberstring+';');
  799. {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
  800. bool8bit,
  801. bool16bit,
  802. bool32bit : stabstring := strpnew('r'+numberstring+';0;255;');
  803. { u32bit : stabstring := strpnew('r'+
  804. s32bitdef^.numberstring+';0;-1;'); }
  805. else
  806. stabstring := strpnew('r'+s32bitdef^.numberstring+';'+tostr(low)+';'+tostr(high)+';');
  807. end;
  808. end;
  809. {$endif GDB}
  810. procedure torddef.write_rtti_data;
  811. const
  812. trans : array[uchar..bool8bit] of byte =
  813. (otUByte,otUByte,otUWord,otULong,otSByte,otSWord,otSLong,otUByte);
  814. begin
  815. case typ of
  816. bool8bit:
  817. rttilist^.concat(new(pai_const,init_8bit(tkBool)));
  818. uchar:
  819. rttilist^.concat(new(pai_const,init_8bit(tkChar)));
  820. else
  821. rttilist^.concat(new(pai_const,init_8bit(tkInteger)));
  822. end;
  823. rttilist^.concat(new(pai_const,init_8bit(byte(trans[typ]))));
  824. rttilist^.concat(new(pai_const,init_32bit(low)));
  825. rttilist^.concat(new(pai_const,init_32bit(high)));
  826. end;
  827. function torddef.is_publishable : boolean;
  828. begin
  829. is_publishable:=typ in [uchar..bool8bit];
  830. end;
  831. {****************************************************************************
  832. TFLOATDEF
  833. ****************************************************************************}
  834. constructor tfloatdef.init(t : tfloattype);
  835. begin
  836. inherited init;
  837. deftype:=floatdef;
  838. typ:=t;
  839. setsize;
  840. end;
  841. constructor tfloatdef.load;
  842. begin
  843. inherited load;
  844. deftype:=floatdef;
  845. typ:=tfloattype(readbyte);
  846. setsize;
  847. end;
  848. procedure tfloatdef.setsize;
  849. begin
  850. case typ of
  851. f16bit : savesize:=2;
  852. f32bit,
  853. s32real : savesize:=4;
  854. s64real : savesize:=8;
  855. s64bit : savesize:=8;
  856. s80real : savesize:=extended_size;
  857. else
  858. savesize:=0;
  859. end;
  860. end;
  861. procedure tfloatdef.write;
  862. begin
  863. inherited write;
  864. writebyte(byte(typ));
  865. current_ppu^.writeentry(ibfloatdef);
  866. end;
  867. {$ifdef GDB}
  868. function tfloatdef.stabstring : pchar;
  869. begin
  870. case typ of
  871. s32real,
  872. s64real : stabstring := strpnew('r'+
  873. s32bitdef^.numberstring+';'+tostr(savesize)+';0;');
  874. { for fixed real use longint instead to be able to }
  875. { debug something at least }
  876. f32bit:
  877. stabstring := s32bitdef^.stabstring;
  878. f16bit:
  879. stabstring := strpnew('r'+s32bitdef^.numberstring+';0;'+
  880. tostr($ffff)+';');
  881. { found this solution in stabsread.c from GDB v4.16 }
  882. s64bit : stabstring := strpnew('r'+
  883. s32bitdef^.numberstring+';-'+tostr(savesize)+';0;');
  884. {$ifdef i386}
  885. { under dos at least you must give a size of twelve instead of 10 !! }
  886. { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
  887. s80real : stabstring := strpnew('r'+s32bitdef^.numberstring+';12;0;');
  888. {$endif i386}
  889. else
  890. internalerror(10005);
  891. end;
  892. end;
  893. {$endif GDB}
  894. procedure tfloatdef.write_rtti_data;
  895. const
  896. translate : array[tfloattype] of byte =
  897. (ftFixed32,ftSingle,ftDouble,ftExtended,ftComp,ftFixed16);
  898. begin
  899. rttilist^.concat(new(pai_const,init_8bit(tkFloat)));
  900. rttilist^.concat(new(pai_const,init_8bit(translate[typ])));
  901. end;
  902. function tfloatdef.is_publishable : boolean;
  903. begin
  904. is_publishable:=true;
  905. end;
  906. {****************************************************************************
  907. TFILEDEF
  908. ****************************************************************************}
  909. constructor tfiledef.init(ft : tfiletype;tas : pdef);
  910. begin
  911. inherited init;
  912. deftype:=filedef;
  913. filetype:=ft;
  914. typed_as:=tas;
  915. setsize;
  916. end;
  917. constructor tfiledef.load;
  918. begin
  919. inherited load;
  920. deftype:=filedef;
  921. filetype:=tfiletype(readbyte);
  922. if filetype=ft_typed then
  923. typed_as:=readdefref
  924. else
  925. typed_as:=nil;
  926. setsize;
  927. end;
  928. procedure tfiledef.deref;
  929. begin
  930. if filetype=ft_typed then
  931. resolvedef(typed_as);
  932. end;
  933. procedure tfiledef.setsize;
  934. begin
  935. case filetype of
  936. ft_text : savesize:=572;
  937. ft_typed,
  938. ft_untyped : savesize:=316;
  939. end;
  940. end;
  941. procedure tfiledef.write;
  942. begin
  943. inherited write;
  944. writebyte(byte(filetype));
  945. if filetype=ft_typed then
  946. writedefref(typed_as);
  947. current_ppu^.writeentry(ibfiledef);
  948. end;
  949. {$ifdef GDB}
  950. function tfiledef.stabstring : pchar;
  951. begin
  952. {$IfDef GDBknowsfiles}
  953. case filetyp of
  954. ft_typed : stabstring := strpnew('d'+typed_as^.numberstring{+';'});
  955. ft_untyped : stabstring := strpnew('d'+voiddef^.numberstring{+';'});
  956. ft_text : stabstring := strpnew('d'+cchardef^.numberstring{+';'});
  957. end;
  958. {$Else}
  959. {based on
  960. FileRec = Packed Record
  961. Handle,
  962. Mode,
  963. RecSize : longint;
  964. _private : array[1..32] of byte;
  965. UserData : array[1..16] of byte;
  966. name : array[0..255] of char;
  967. End; }
  968. { the buffer part is still missing !! (PM) }
  969. { but the string could become too long !! }
  970. stabstring := strpnew('s'+tostr(savesize)+
  971. 'HANDLE:'+typeglobalnumber('longint')+',0,32;'+
  972. 'MODE:'+typeglobalnumber('longint')+',32,32;'+
  973. 'RECSIZE:'+typeglobalnumber('longint')+',64,32;'+
  974. '_PRIVATE:ar'+typeglobalnumber('word')+';1;32;'+typeglobalnumber('byte')
  975. +',96,256;'+
  976. 'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')
  977. +',352,128;'+
  978. 'NAME:ar'+typeglobalnumber('word')+';0;255;'+typeglobalnumber('char')
  979. +',480,2048;;');
  980. {$EndIf}
  981. end;
  982. procedure tfiledef.concatstabto(asmlist : paasmoutput);
  983. begin
  984. { most file defs are unnamed !!! }
  985. if ((sym = nil) or sym^.isusedinstab or use_dbx) and not is_def_stab_written then
  986. begin
  987. if assigned(typed_as) then forcestabto(asmlist,typed_as);
  988. inherited concatstabto(asmlist);
  989. end;
  990. end;
  991. {$endif GDB}
  992. {****************************************************************************
  993. TPOINTERDEF
  994. ****************************************************************************}
  995. constructor tpointerdef.init(def : pdef);
  996. begin
  997. inherited init;
  998. deftype:=pointerdef;
  999. definition:=def;
  1000. savesize:=target_os.size_of_pointer;
  1001. end;
  1002. constructor tpointerdef.load;
  1003. begin
  1004. inherited load;
  1005. deftype:=pointerdef;
  1006. { the real address in memory is calculated later (deref) }
  1007. definition:=readdefref;
  1008. savesize:=target_os.size_of_pointer;
  1009. end;
  1010. procedure tpointerdef.deref;
  1011. begin
  1012. resolvedef(definition);
  1013. end;
  1014. procedure tpointerdef.write;
  1015. begin
  1016. inherited write;
  1017. writedefref(definition);
  1018. current_ppu^.writeentry(ibpointerdef);
  1019. end;
  1020. {$ifdef GDB}
  1021. function tpointerdef.stabstring : pchar;
  1022. begin
  1023. stabstring := strpnew('*'+definition^.numberstring);
  1024. end;
  1025. procedure tpointerdef.concatstabto(asmlist : paasmoutput);
  1026. var st,nb : string;
  1027. sym_line_no : longint;
  1028. begin
  1029. if ( (sym=nil) or sym^.isusedinstab or use_dbx) and not is_def_stab_written then
  1030. begin
  1031. if assigned(definition) then
  1032. if definition^.deftype in [recorddef,objectdef] then
  1033. begin
  1034. is_def_stab_written := true;
  1035. {to avoid infinite recursion in record with next-like fields }
  1036. nb := definition^.numberstring;
  1037. is_def_stab_written := false;
  1038. if not definition^.is_def_stab_written then
  1039. begin
  1040. if assigned(definition^.sym) then
  1041. begin
  1042. if assigned(sym) then
  1043. begin
  1044. st := sym^.name;
  1045. sym_line_no:=sym^.fileinfo.line;
  1046. end
  1047. else
  1048. begin
  1049. st := ' ';
  1050. sym_line_no:=0;
  1051. end;
  1052. st := '"'+st+':t'+numberstring+'=*'+definition^.numberstring
  1053. +'=xs'+definition^.sym^.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
  1054. if asmlist = debuglist then do_count_dbx := true;
  1055. asmlist^.concat(new(pai_stabs,init(strpnew(st))));
  1056. end;
  1057. end else inherited concatstabto(asmlist);
  1058. is_def_stab_written := true;
  1059. end else
  1060. begin
  1061. forcestabto(asmlist,definition);
  1062. inherited concatstabto(asmlist);
  1063. end;
  1064. end;
  1065. end;
  1066. {$endif GDB}
  1067. {****************************************************************************
  1068. TCLASSREFDEF
  1069. ****************************************************************************}
  1070. constructor tclassrefdef.init(def : pdef);
  1071. begin
  1072. inherited init(def);
  1073. deftype:=classrefdef;
  1074. definition:=def;
  1075. savesize:=target_os.size_of_pointer;
  1076. end;
  1077. constructor tclassrefdef.load;
  1078. begin
  1079. inherited load;
  1080. deftype:=classrefdef;
  1081. end;
  1082. procedure tclassrefdef.write;
  1083. begin
  1084. { be careful, tclassdefref inherits from tpointerdef }
  1085. tdef.write;
  1086. writedefref(definition);
  1087. current_ppu^.writeentry(ibclassrefdef);
  1088. end;
  1089. {$ifdef GDB}
  1090. function tclassrefdef.stabstring : pchar;
  1091. begin
  1092. stabstring:=strpnew('');
  1093. end;
  1094. procedure tclassrefdef.concatstabto(asmlist : paasmoutput);
  1095. begin
  1096. end;
  1097. {$endif GDB}
  1098. {***************************************************************************
  1099. TSETDEF
  1100. ***************************************************************************}
  1101. { For i386 smallsets work,
  1102. for m68k there are problems
  1103. can be test by compiling with -dusesmallset PM }
  1104. {$ifdef i386}
  1105. {$define usesmallset}
  1106. {$endif i386}
  1107. constructor tsetdef.init(s : pdef;high : longint);
  1108. begin
  1109. inherited init;
  1110. deftype:=setdef;
  1111. setof:=s;
  1112. {$ifdef usesmallset}
  1113. { small sets only working for i386 PM }
  1114. if high<32 then
  1115. begin
  1116. settype:=smallset;
  1117. savesize:=Sizeof(longint);
  1118. end
  1119. else
  1120. {$endif usesmallset}
  1121. if high<256 then
  1122. begin
  1123. settype:=normset;
  1124. savesize:=32;
  1125. end
  1126. else
  1127. {$ifdef testvarsets}
  1128. if high<$10000 then
  1129. begin
  1130. settype:=varset;
  1131. savesize:=4*((high+31) div 32);
  1132. end
  1133. else
  1134. {$endif testvarsets}
  1135. Message(sym_e_ill_type_decl_set);
  1136. end;
  1137. constructor tsetdef.load;
  1138. begin
  1139. inherited load;
  1140. deftype:=setdef;
  1141. setof:=readdefref;
  1142. settype:=tsettype(readbyte);
  1143. case settype of
  1144. normset : savesize:=32;
  1145. varset : savesize:=readlong;
  1146. smallset : savesize:=Sizeof(longint);
  1147. end;
  1148. end;
  1149. procedure tsetdef.write;
  1150. begin
  1151. inherited write;
  1152. writedefref(setof);
  1153. writebyte(byte(settype));
  1154. if settype=varset then
  1155. writelong(savesize);
  1156. current_ppu^.writeentry(ibsetdef);
  1157. end;
  1158. {$ifdef GDB}
  1159. function tsetdef.stabstring : pchar;
  1160. begin
  1161. stabstring := strpnew('S'+setof^.numberstring);
  1162. end;
  1163. procedure tsetdef.concatstabto(asmlist : paasmoutput);
  1164. begin
  1165. if ( not assigned(sym) or sym^.isusedinstab or use_dbx) and
  1166. not is_def_stab_written then
  1167. begin
  1168. if assigned(setof) then
  1169. forcestabto(asmlist,setof);
  1170. inherited concatstabto(asmlist);
  1171. end;
  1172. end;
  1173. {$endif GDB}
  1174. procedure tsetdef.deref;
  1175. begin
  1176. resolvedef(setof);
  1177. end;
  1178. procedure tsetdef.write_rtti_data;
  1179. begin
  1180. rttilist^.concat(new(pai_const,init_8bit(tkSet)));
  1181. rttilist^.concat(new(pai_const,init_8bit(otULong)));
  1182. rttilist^.concat(new(pai_const,init_symbol(strpnew(lab2str(setof^.get_rtti_label)))));
  1183. end;
  1184. procedure tsetdef.write_child_rtti_data;
  1185. begin
  1186. setof^.get_rtti_label;
  1187. end;
  1188. function tsetdef.is_publishable : boolean;
  1189. begin
  1190. is_publishable:=settype=smallset;
  1191. end;
  1192. {***************************************************************************
  1193. TFORMALDEF
  1194. ***************************************************************************}
  1195. constructor tformaldef.init;
  1196. begin
  1197. inherited init;
  1198. deftype:=formaldef;
  1199. savesize:=target_os.size_of_pointer;
  1200. end;
  1201. constructor tformaldef.load;
  1202. begin
  1203. inherited load;
  1204. deftype:=formaldef;
  1205. savesize:=target_os.size_of_pointer;
  1206. end;
  1207. procedure tformaldef.write;
  1208. begin
  1209. inherited write;
  1210. current_ppu^.writeentry(ibformaldef);
  1211. end;
  1212. {$ifdef GDB}
  1213. function tformaldef.stabstring : pchar;
  1214. begin
  1215. stabstring := strpnew('formal'+numberstring+';');
  1216. end;
  1217. procedure tformaldef.concatstabto(asmlist : paasmoutput);
  1218. begin
  1219. { formaldef can't be stab'ed !}
  1220. end;
  1221. {$endif GDB}
  1222. {***************************************************************************
  1223. TARRAYDEF
  1224. ***************************************************************************}
  1225. constructor tarraydef.init(l,h : longint;rd : pdef);
  1226. begin
  1227. inherited init;
  1228. deftype:=arraydef;
  1229. lowrange:=l;
  1230. highrange:=h;
  1231. rangedef:=rd;
  1232. definition:=nil;
  1233. IsVariant:=false;
  1234. IsConstructor:=false;
  1235. IsArrayOfConst:=false;
  1236. rangenr:=0;
  1237. end;
  1238. constructor tarraydef.load;
  1239. begin
  1240. inherited load;
  1241. deftype:=arraydef;
  1242. { the addresses are calculated later }
  1243. definition:=readdefref;
  1244. rangedef:=readdefref;
  1245. lowrange:=readlong;
  1246. highrange:=readlong;
  1247. IsArrayOfConst:=boolean(readbyte);
  1248. IsVariant:=false;
  1249. IsConstructor:=false;
  1250. rangenr:=0;
  1251. end;
  1252. function tarraydef.getrangecheckstring : string;
  1253. begin
  1254. if (cs_smartlink in aktmoduleswitches) then
  1255. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  1256. else
  1257. getrangecheckstring:='R_'+tostr(rangenr);
  1258. end;
  1259. procedure tarraydef.genrangecheck;
  1260. begin
  1261. if rangenr=0 then
  1262. begin
  1263. { generates the data for range checking }
  1264. getlabelnr(rangenr);
  1265. if (cs_smartlink in aktmoduleswitches) then
  1266. datasegment^.concat(new(pai_symbol,init_global(getrangecheckstring)))
  1267. else
  1268. datasegment^.concat(new(pai_symbol,init(getrangecheckstring)));
  1269. datasegment^.concat(new(pai_const,init_32bit(lowrange)));
  1270. datasegment^.concat(new(pai_const,init_32bit(highrange)));
  1271. end;
  1272. end;
  1273. procedure tarraydef.deref;
  1274. begin
  1275. resolvedef(definition);
  1276. resolvedef(rangedef);
  1277. end;
  1278. procedure tarraydef.write;
  1279. begin
  1280. inherited write;
  1281. writedefref(definition);
  1282. writedefref(rangedef);
  1283. writelong(lowrange);
  1284. writelong(highrange);
  1285. writebyte(byte(IsArrayOfConst));
  1286. current_ppu^.writeentry(ibarraydef);
  1287. end;
  1288. {$ifdef GDB}
  1289. function tarraydef.stabstring : pchar;
  1290. begin
  1291. stabstring := strpnew('ar'+rangedef^.numberstring+';'
  1292. +tostr(lowrange)+';'+tostr(highrange)+';'+definition^.numberstring);
  1293. end;
  1294. procedure tarraydef.concatstabto(asmlist : paasmoutput);
  1295. begin
  1296. if (not assigned(sym) or sym^.isusedinstab or use_dbx)
  1297. and not is_def_stab_written then
  1298. begin
  1299. {when array are inserted they have no definition yet !!}
  1300. if assigned(definition) then
  1301. inherited concatstabto(asmlist);
  1302. end;
  1303. end;
  1304. {$endif GDB}
  1305. function tarraydef.elesize : longint;
  1306. begin
  1307. elesize:=definition^.size;
  1308. end;
  1309. function tarraydef.size : longint;
  1310. begin
  1311. size:=(highrange-lowrange+1)*elesize;
  1312. end;
  1313. function tarraydef.needs_inittable : boolean;
  1314. begin
  1315. needs_inittable:=definition^.needs_inittable;
  1316. end;
  1317. procedure tarraydef.write_child_rtti_table;
  1318. begin
  1319. definition^.get_rtti_label;
  1320. end;
  1321. procedure tarraydef.write_rtti_data;
  1322. begin
  1323. rttilist^.concat(new(pai_const,init_8bit(13)));
  1324. writename;
  1325. { size of elements }
  1326. rttilist^.concat(new(pai_const,init_32bit(definition^.size)));
  1327. { count of elements }
  1328. rttilist^.concat(new(pai_const,init_32bit(highrange-lowrange+1)));
  1329. { element type }
  1330. rttilist^.concat(new(pai_const,init_symbol(strpnew(lab2str(definition^.get_rtti_label)))));
  1331. end;
  1332. {***************************************************************************
  1333. TRECDEF
  1334. ***************************************************************************}
  1335. constructor trecdef.init(p : psymtable);
  1336. begin
  1337. inherited init;
  1338. deftype:=recorddef;
  1339. symtable:=p;
  1340. savesize:=symtable^.datasize;
  1341. symtable^.defowner := @self;
  1342. end;
  1343. constructor trecdef.load;
  1344. var
  1345. oldread_member : boolean;
  1346. begin
  1347. inherited load;
  1348. deftype:=recorddef;
  1349. savesize:=readlong;
  1350. oldread_member:=read_member;
  1351. read_member:=true;
  1352. symtable:=new(psymtable,loadasstruct(recordsymtable));
  1353. read_member:=oldread_member;
  1354. symtable^.defowner := @self;
  1355. end;
  1356. destructor trecdef.done;
  1357. begin
  1358. if assigned(symtable) then dispose(symtable,done);
  1359. inherited done;
  1360. end;
  1361. var
  1362. binittable : boolean;
  1363. procedure check_rec_inittable(s : psym);
  1364. begin
  1365. if (s^.typ=varsym) and
  1366. ((pvarsym(s)^.definition^.deftype<>objectdef)
  1367. or not(pobjectdef(pvarsym(s)^.definition)^.isclass)) then
  1368. binittable:=pvarsym(s)^.definition^.needs_inittable;
  1369. end;
  1370. function trecdef.needs_inittable : boolean;
  1371. var
  1372. oldb : boolean;
  1373. begin
  1374. { there are recursive calls to needs_rtti possible, }
  1375. { so we have to change to old value how else should }
  1376. { we do that ? check_rec_rtti can't be a nested }
  1377. { procedure of needs_rtti ! }
  1378. oldb:=binittable;
  1379. binittable:=false;
  1380. symtable^.foreach(check_rec_inittable);
  1381. needs_inittable:=binittable;
  1382. binittable:=oldb;
  1383. end;
  1384. procedure trecdef.deref;
  1385. var
  1386. hp : pdef;
  1387. oldrecsyms : psymtable;
  1388. begin
  1389. oldrecsyms:=aktrecordsymtable;
  1390. aktrecordsymtable:=symtable;
  1391. { now dereference the definitions }
  1392. hp:=symtable^.rootdef;
  1393. while assigned(hp) do
  1394. begin
  1395. hp^.deref;
  1396. { set owner }
  1397. hp^.owner:=symtable;
  1398. hp:=hp^.next;
  1399. end;
  1400. {$ifdef tp}
  1401. symtable^.foreach(derefsym);
  1402. {$else}
  1403. symtable^.foreach(@derefsym);
  1404. {$endif}
  1405. aktrecordsymtable:=oldrecsyms;
  1406. end;
  1407. procedure trecdef.write;
  1408. var
  1409. oldread_member : boolean;
  1410. begin
  1411. oldread_member:=read_member;
  1412. read_member:=true;
  1413. inherited write;
  1414. writelong(savesize);
  1415. current_ppu^.writeentry(ibrecorddef);
  1416. self.symtable^.writeasstruct;
  1417. read_member:=oldread_member;
  1418. end;
  1419. {$ifdef GDB}
  1420. Const StabRecString : pchar = Nil;
  1421. StabRecSize : longint = 0;
  1422. RecOffset : Longint = 0;
  1423. procedure addname(p : psym);
  1424. var
  1425. news, newrec : pchar;
  1426. spec : string[2];
  1427. begin
  1428. { static variables from objects are like global objects }
  1429. if ((p^.properties and sp_static)<>0) then
  1430. exit;
  1431. if ((p^.properties and sp_protected)<>0) then
  1432. spec:='/1'
  1433. else if ((p^.properties and sp_private)<>0) then
  1434. spec:='/0'
  1435. else
  1436. spec:='';
  1437. If p^.typ = varsym then
  1438. begin
  1439. newrec := strpnew(p^.name+':'+spec+pvarsym(p)^.definition^.numberstring
  1440. +','+tostr(pvarsym(p)^.address*8)+','
  1441. +tostr(pvarsym(p)^.definition^.size*8)+';');
  1442. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  1443. begin
  1444. getmem(news,stabrecsize+memsizeinc);
  1445. strcopy(news,stabrecstring);
  1446. freemem(stabrecstring,stabrecsize);
  1447. stabrecsize:=stabrecsize+memsizeinc;
  1448. stabrecstring:=news;
  1449. end;
  1450. strcat(StabRecstring,newrec);
  1451. strdispose(newrec);
  1452. {This should be used for case !!}
  1453. RecOffset := RecOffset + pvarsym(p)^.definition^.size;
  1454. end;
  1455. end;
  1456. function trecdef.stabstring : pchar;
  1457. Var oldrec : pchar;
  1458. oldsize : longint;
  1459. cur : psym;
  1460. begin
  1461. oldrec := stabrecstring;
  1462. oldsize:=stabrecsize;
  1463. GetMem(stabrecstring,memsizeinc);
  1464. stabrecsize:=memsizeinc;
  1465. strpcopy(stabRecString,'s'+tostr(savesize));
  1466. RecOffset := 0;
  1467. {$ifdef nonextfield}
  1468. {$ifdef tp}
  1469. symtable^.foreach(addname);
  1470. {$else}
  1471. symtable^.foreach(@addname);
  1472. {$endif}
  1473. {$else nonextfield}
  1474. cur:=symtable^.root;
  1475. while assigned(cur) do
  1476. begin
  1477. addname(cur);
  1478. cur:=cur^.nextsym;
  1479. end;
  1480. {$endif nonextfield}
  1481. { FPC doesn't want to convert a char to a pchar}
  1482. { is this a bug ? }
  1483. strpcopy(strend(StabRecString),';');
  1484. stabstring := strnew(StabRecString);
  1485. Freemem(stabrecstring,stabrecsize);
  1486. stabrecstring := oldrec;
  1487. stabrecsize:=oldsize;
  1488. end;
  1489. procedure trecdef.concatstabto(asmlist : paasmoutput);
  1490. begin
  1491. if (not assigned(sym) or sym^.isusedinstab or use_dbx) and
  1492. (not is_def_stab_written) then
  1493. inherited concatstabto(asmlist);
  1494. end;
  1495. {$endif GDB}
  1496. var
  1497. count : longint;
  1498. procedure count_inittable_fields(sym : psym);{$ifndef fpc}far;{$endif}
  1499. begin
  1500. if pvarsym(sym)^.definition^.needs_inittable then
  1501. inc(count);
  1502. end;
  1503. procedure count_fields(sym : psym);{$ifndef fpc}far;{$endif}
  1504. begin
  1505. inc(count);
  1506. end;
  1507. procedure write_field_inittable(sym : psym);{$ifndef fpc}far;{$endif}
  1508. begin
  1509. if pvarsym(sym)^.definition^.needs_inittable then
  1510. begin
  1511. rttilist^.concat(new(pai_const,init_symbol(strpnew(lab2str(pvarsym(sym)^.definition^.get_inittable_label)))));
  1512. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  1513. end;
  1514. end;
  1515. procedure write_field_rtti(sym : psym);{$ifndef fpc}far;{$endif}
  1516. begin
  1517. rttilist^.concat(new(pai_const,init_symbol(strpnew(lab2str(pvarsym(sym)^.definition^.get_rtti_label)))));
  1518. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  1519. end;
  1520. procedure generate_child_inittable(sym : psym);{$ifndef fpc}far;{$endif}
  1521. begin
  1522. if (sym^.typ=varsym) and pvarsym(sym)^.definition^.needs_inittable then
  1523. { force inittable generation }
  1524. pvarsym(sym)^.definition^.get_inittable_label;
  1525. end;
  1526. procedure generate_child_rtti(sym : psym);{$ifndef fpc}far;{$endif}
  1527. begin
  1528. pvarsym(sym)^.definition^.get_rtti_label;
  1529. end;
  1530. procedure trecdef.write_child_rtti_data;
  1531. begin
  1532. symtable^.foreach(generate_child_rtti);
  1533. end;
  1534. procedure trecdef.write_child_init_data;
  1535. begin
  1536. symtable^.foreach(generate_child_inittable);
  1537. end;
  1538. procedure trecdef.write_rtti_data;
  1539. begin
  1540. rttilist^.concat(new(pai_const,init_8bit(14)));
  1541. writename;
  1542. rttilist^.concat(new(pai_const,init_32bit(size)));
  1543. count:=0;
  1544. symtable^.foreach(count_fields);
  1545. rttilist^.concat(new(pai_const,init_32bit(count)));
  1546. symtable^.foreach(write_field_rtti);
  1547. end;
  1548. procedure trecdef.write_init_data;
  1549. begin
  1550. rttilist^.concat(new(pai_const,init_8bit(14)));
  1551. writename;
  1552. rttilist^.concat(new(pai_const,init_32bit(size)));
  1553. count:=0;
  1554. symtable^.foreach(count_inittable_fields);
  1555. rttilist^.concat(new(pai_const,init_32bit(count)));
  1556. symtable^.foreach(write_field_inittable);
  1557. end;
  1558. {***************************************************************************
  1559. TABSTRACTPROCDEF
  1560. ***************************************************************************}
  1561. constructor tabstractprocdef.init;
  1562. begin
  1563. inherited init;
  1564. para1:=nil;
  1565. fpu_used:=0;
  1566. options:=0;
  1567. retdef:=voiddef;
  1568. savesize:=target_os.size_of_pointer;
  1569. end;
  1570. procedure disposepdefcoll(var para1 : pdefcoll);
  1571. var
  1572. hp : pdefcoll;
  1573. begin
  1574. hp:=para1;
  1575. while assigned(hp) do
  1576. begin
  1577. para1:=hp^.next;
  1578. dispose(hp);
  1579. hp:=para1;
  1580. end;
  1581. end;
  1582. destructor tabstractprocdef.done;
  1583. begin
  1584. disposepdefcoll(para1);
  1585. inherited done;
  1586. end;
  1587. procedure tabstractprocdef.concatdef(p : pdef;vsp : tvarspez);
  1588. var
  1589. hp : pdefcoll;
  1590. begin
  1591. new(hp);
  1592. hp^.paratyp:=vsp;
  1593. hp^.data:=p;
  1594. hp^.next:=para1;
  1595. para1:=hp;
  1596. end;
  1597. { all functions returning in FPU are
  1598. assume to use 2 FPU registers
  1599. until the function implementation
  1600. is processed PM }
  1601. procedure tabstractprocdef.test_if_fpu_result;
  1602. begin
  1603. if assigned(retdef) and is_fpu(retdef) then
  1604. fpu_used:=2;
  1605. end;
  1606. procedure tabstractprocdef.deref;
  1607. var
  1608. hp : pdefcoll;
  1609. begin
  1610. inherited deref;
  1611. resolvedef(retdef);
  1612. hp:=para1;
  1613. while assigned(hp) do
  1614. begin
  1615. resolvedef(hp^.data);
  1616. hp:=hp^.next;
  1617. end;
  1618. end;
  1619. constructor tabstractprocdef.load;
  1620. var
  1621. last,hp : pdefcoll;
  1622. count,i : word;
  1623. begin
  1624. inherited load;
  1625. retdef:=readdefref;
  1626. fpu_used:=readbyte;
  1627. options:=readlong;
  1628. count:=readword;
  1629. para1:=nil;
  1630. savesize:=target_os.size_of_pointer;
  1631. for i:=1 to count do
  1632. begin
  1633. new(hp);
  1634. hp^.paratyp:=tvarspez(readbyte);
  1635. hp^.data:=readdefref;
  1636. hp^.next:=nil;
  1637. if para1=nil then
  1638. para1:=hp
  1639. else
  1640. last^.next:=hp;
  1641. last:=hp;
  1642. end;
  1643. end;
  1644. function tabstractprocdef.para_size : longint;
  1645. var
  1646. pdc : pdefcoll;
  1647. l : longint;
  1648. begin
  1649. l:=0;
  1650. pdc:=para1;
  1651. while assigned(pdc) do
  1652. begin
  1653. case pdc^.paratyp of
  1654. vs_value : inc(l,align(pdc^.data^.size,target_os.stackalignment));
  1655. vs_var : inc(l,target_os.size_of_pointer);
  1656. vs_const : if dont_copy_const_param(pdc^.data) then
  1657. inc(l,target_os.size_of_pointer)
  1658. else
  1659. inc(l,align(pdc^.data^.size,target_os.stackalignment));
  1660. end;
  1661. pdc:=pdc^.next;
  1662. end;
  1663. para_size:=l;
  1664. end;
  1665. procedure tabstractprocdef.write;
  1666. var
  1667. count : word;
  1668. hp : pdefcoll;
  1669. begin
  1670. inherited write;
  1671. writedefref(retdef);
  1672. writebyte(fpu_used);
  1673. writelong(options);
  1674. hp:=para1;
  1675. count:=0;
  1676. while assigned(hp) do
  1677. begin
  1678. inc(count);
  1679. hp:=hp^.next;
  1680. end;
  1681. writeword(count);
  1682. hp:=para1;
  1683. while assigned(hp) do
  1684. begin
  1685. writebyte(byte(hp^.paratyp));
  1686. writedefref(hp^.data);
  1687. hp:=hp^.next;
  1688. end;
  1689. end;
  1690. function tabstractprocdef.demangled_paras : string;
  1691. var s : string;
  1692. p : pdefcoll;
  1693. begin
  1694. s:='';
  1695. p:=para1;
  1696. if assigned(p) then
  1697. begin
  1698. s:=s+'(';
  1699. while assigned(p) do
  1700. begin
  1701. if assigned(p^.data^.sym) then
  1702. s:=s+p^.data^.sym^.name
  1703. else if p^.paratyp=vs_var then
  1704. s:=s+'var'
  1705. else if p^.paratyp=vs_const then
  1706. s:=s+'const';
  1707. p:=p^.next;
  1708. if assigned(p) then
  1709. s:=s+','
  1710. else
  1711. s:=s+')';
  1712. end;
  1713. end;
  1714. demangled_paras:=s;
  1715. end;
  1716. {$ifdef GDB}
  1717. function tabstractprocdef.stabstring : pchar;
  1718. begin
  1719. stabstring := strpnew('abstractproc'+numberstring+';');
  1720. end;
  1721. procedure tabstractprocdef.concatstabto(asmlist : paasmoutput);
  1722. begin
  1723. if (not assigned(sym) or sym^.isusedinstab or use_dbx)
  1724. and not is_def_stab_written then
  1725. begin
  1726. if assigned(retdef) then forcestabto(asmlist,retdef);
  1727. inherited concatstabto(asmlist);
  1728. end;
  1729. end;
  1730. {$endif GDB}
  1731. {***************************************************************************
  1732. TPROCDEF
  1733. ***************************************************************************}
  1734. constructor tprocdef.init;
  1735. begin
  1736. inherited init;
  1737. deftype:=procdef;
  1738. _mangledname:=nil;
  1739. nextoverloaded:=nil;
  1740. extnumber:=-1;
  1741. localst:=new(psymtable,init(localsymtable));
  1742. parast:=new(psymtable,init(parasymtable));
  1743. { this is used by insert
  1744. to check same names in parast and localst }
  1745. localst^.next:=parast;
  1746. {$ifdef UseBrowser}
  1747. defref:=nil;
  1748. lastwritten:=nil;
  1749. refcount:=0;
  1750. if (cs_browser in aktmoduleswitches) and make_ref then
  1751. begin
  1752. defref:=new(pref,init(defref,@tokenpos));
  1753. inc(refcount);
  1754. end;
  1755. lastref:=defref;
  1756. {$endif UseBrowser}
  1757. { first, we assume, that all registers are used }
  1758. {$ifdef i386}
  1759. usedregisters:=$ff;
  1760. {$endif i386}
  1761. {$ifdef m68k}
  1762. usedregisters:=$FFFF;
  1763. {$endif}
  1764. {$ifdef alpha}
  1765. usedregisters_int:=$ffffffff;
  1766. usedregisters_fpu:=$ffffffff;
  1767. {$endif alpha}
  1768. forwarddef:=true;
  1769. _class := nil;
  1770. code:=nil;
  1771. end;
  1772. constructor tprocdef.load;
  1773. var
  1774. s : string;
  1775. begin
  1776. inherited load;
  1777. deftype:=procdef;
  1778. {$ifdef i386}
  1779. usedregisters:=readbyte;
  1780. {$endif i386}
  1781. {$ifdef m68k}
  1782. usedregisters:=readword;
  1783. {$endif}
  1784. {$ifdef alpha}
  1785. usedregisters_int:=readlong;
  1786. usedregisters_fpu:=readlong;
  1787. {$endif alpha}
  1788. s:=readstring;
  1789. setstring(_mangledname,s);
  1790. extnumber:=readlong;
  1791. nextoverloaded:=pprocdef(readdefref);
  1792. _class := pobjectdef(readdefref);
  1793. if (cs_link_deffile in aktglobalswitches) and ((options and poexports)<>0) then
  1794. deffile.AddExport(mangledname);
  1795. parast:=nil;
  1796. localst:=nil;
  1797. forwarddef:=false;
  1798. {$ifdef UseBrowser}
  1799. lastref:=nil;
  1800. lastwritten:=nil;
  1801. defref:=nil;
  1802. refcount:=0;
  1803. {$endif UseBrowser}
  1804. end;
  1805. {$ifdef UseBrowser}
  1806. procedure tprocdef.load_references;
  1807. var
  1808. pos : tfileposinfo;
  1809. move_last : boolean;
  1810. begin
  1811. move_last:=lastwritten=lastref;
  1812. while (not current_ppu^.endofentry) do
  1813. begin
  1814. readposinfo(pos);
  1815. inc(refcount);
  1816. lastref:=new(pref,init(lastref,@pos));
  1817. lastref^.is_written:=true;
  1818. if refcount=1 then
  1819. defref:=lastref;
  1820. end;
  1821. if move_last then
  1822. lastwritten:=lastref;
  1823. if (current_module^.flags and uf_local_browser)<>0 then
  1824. begin
  1825. new(parast,load);
  1826. parast^.load_browser;
  1827. new(localst,load);
  1828. localst^.load_browser;
  1829. end;
  1830. end;
  1831. function tprocdef.write_references : boolean;
  1832. var
  1833. ref : pref;
  1834. move_last : boolean;
  1835. begin
  1836. move_last:=lastwritten=lastref;
  1837. if move_last and ((current_module^.flags and uf_local_browser)=0) then
  1838. exit;
  1839. { write address of this symbol }
  1840. writedefref(@self);
  1841. { write refs }
  1842. if assigned(lastwritten) then
  1843. ref:=lastwritten
  1844. else
  1845. ref:=defref;
  1846. while assigned(ref) do
  1847. begin
  1848. if ref^.moduleindex=current_module^.unit_index then
  1849. begin
  1850. writeposinfo(ref^.posinfo);
  1851. ref^.is_written:=true;
  1852. if move_last then
  1853. lastwritten:=ref;
  1854. end
  1855. else if not ref^.is_written then
  1856. move_last:=false
  1857. else if move_last then
  1858. lastwritten:=ref;
  1859. ref:=ref^.nextref;
  1860. end;
  1861. current_ppu^.writeentry(ibdefref);
  1862. write_references:=true;
  1863. if (current_module^.flags and uf_local_browser)<>0 then
  1864. begin
  1865. { we need dummy para and local symtables
  1866. PPU files are then easier to read PM }
  1867. if not assigned(parast) then
  1868. parast:=new(psymtable,init(parasymtable));
  1869. parast^.write;
  1870. parast^.write_browser;
  1871. if not assigned(localst) then
  1872. localst:=new(psymtable,init(localsymtable));
  1873. localst^.write;
  1874. localst^.write_browser;
  1875. end;
  1876. end;
  1877. procedure tprocdef.add_to_browserlog;
  1878. begin
  1879. if assigned(defref) then
  1880. begin
  1881. Browse.AddLog('***'+mangledname);
  1882. Browse.AddLogRefs(defref);
  1883. if (current_module^.flags and uf_local_browser)<>0 then
  1884. begin
  1885. if assigned(parast) then
  1886. parast^.writebrowserlog;
  1887. if assigned(localst) then
  1888. localst^.writebrowserlog;
  1889. end;
  1890. end;
  1891. end;
  1892. {$endif UseBrowser}
  1893. destructor tprocdef.done;
  1894. begin
  1895. {$ifdef UseBrowser}
  1896. if assigned(defref) then
  1897. dispose(defref,done);
  1898. {$endif UseBrowser}
  1899. if assigned(parast) then
  1900. dispose(parast,done);
  1901. if assigned(localst) then
  1902. dispose(localst,done);
  1903. if assigned(code) and ((options and poinline) <> 0) then
  1904. disposetree(ptree(code));
  1905. if
  1906. {$ifdef tp}
  1907. not(use_big) and
  1908. {$endif}
  1909. assigned(_mangledname) then
  1910. strdispose(_mangledname);
  1911. inherited done;
  1912. end;
  1913. procedure tprocdef.write;
  1914. begin
  1915. inherited write;
  1916. {$ifdef i386}
  1917. writebyte(usedregisters);
  1918. {$endif i386}
  1919. {$ifdef m68k}
  1920. writeword(usedregisters);
  1921. {$endif}
  1922. {$ifdef alpha}
  1923. writelong(usedregisters_int);
  1924. writelong(usedregisters_fpu);
  1925. {$endif alpha}
  1926. writestring(mangledname);
  1927. writelong(extnumber);
  1928. if (options and pooperator) = 0 then
  1929. writedefref(nextoverloaded)
  1930. else
  1931. begin
  1932. { only write the overloads from the same unit }
  1933. if nextoverloaded^.owner=owner then
  1934. writedefref(nextoverloaded)
  1935. else
  1936. writedefref(nil);
  1937. end;
  1938. writedefref(_class);
  1939. if (options and poinline) <> 0 then
  1940. begin
  1941. { we need to save
  1942. - the para and the local symtable
  1943. - the code ptree !! PM
  1944. writesymtable(parast);
  1945. writesymtable(localst);
  1946. writeptree(ptree(code));
  1947. }
  1948. end;
  1949. current_ppu^.writeentry(ibprocdef);
  1950. end;
  1951. {$ifdef GDB}
  1952. procedure addparaname(p : psym);
  1953. var vs : char;
  1954. begin
  1955. if pvarsym(p)^.varspez = vs_value then vs := '1'
  1956. else vs := '0';
  1957. strpcopy(strend(StabRecString),p^.name+':'+pvarsym(p)^.definition^.numberstring+','+vs+';');
  1958. end;
  1959. function tprocdef.stabstring : pchar;
  1960. var param : pdefcoll;
  1961. i : word;
  1962. vartyp : char;
  1963. oldrec : pchar;
  1964. begin
  1965. oldrec := stabrecstring;
  1966. getmem(StabRecString,1024);
  1967. param := para1;
  1968. i := 0;
  1969. while assigned(param) do
  1970. begin
  1971. inc(i);
  1972. param := param^.next;
  1973. end;
  1974. strpcopy(StabRecString,'f'+retdef^.numberstring);
  1975. if i>0 then
  1976. begin
  1977. strpcopy(strend(StabRecString),','+tostr(i)+';');
  1978. (* confuse gdb !! PM
  1979. if assigned(parast) then
  1980. {$IfDef TP}
  1981. parast^.foreach(addparaname)
  1982. {$Else}
  1983. parast^.foreach(@addparaname)
  1984. {$EndIf}
  1985. else
  1986. begin
  1987. param := para1;
  1988. i := 0;
  1989. while assigned(param) do
  1990. begin
  1991. inc(i);
  1992. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  1993. {Here we have lost the parameter names !!}
  1994. {using lower case parameters }
  1995. strpcopy(strend(stabrecstring),'p'+tostr(i)
  1996. +':'+param^.data^.numberstring+','+vartyp+';');
  1997. param := param^.next;
  1998. end;
  1999. end; *)
  2000. {strpcopy(strend(StabRecString),';');}
  2001. end;
  2002. stabstring := strnew(stabrecstring);
  2003. freemem(stabrecstring,1024);
  2004. stabrecstring := oldrec;
  2005. end;
  2006. procedure tprocdef.concatstabto(asmlist : paasmoutput);
  2007. begin
  2008. end;
  2009. {$endif GDB}
  2010. procedure tprocdef.deref;
  2011. begin
  2012. inherited deref;
  2013. resolvedef(pdef(nextoverloaded));
  2014. resolvedef(pdef(_class));
  2015. end;
  2016. function tprocdef.mangledname : string;
  2017. {$ifdef tp}
  2018. var
  2019. oldpos : longint;
  2020. s : string;
  2021. b : byte;
  2022. {$endif tp}
  2023. begin
  2024. {$ifdef tp}
  2025. if use_big then
  2026. begin
  2027. symbolstream.seek(longint(_mangledname));
  2028. symbolstream.read(b,1);
  2029. symbolstream.read(s[1],b);
  2030. s[0]:=chr(b);
  2031. mangledname:=s;
  2032. end
  2033. else
  2034. {$endif}
  2035. mangledname:=strpas(_mangledname);
  2036. end;
  2037. {$IfDef GDB}
  2038. function tprocdef.cplusplusmangledname : string;
  2039. var
  2040. s,s2 : string;
  2041. param : pdefcoll;
  2042. begin
  2043. s := sym^.name;
  2044. if _class <> nil then
  2045. begin
  2046. s2 := _class^.name^;
  2047. s := s+'__'+tostr(length(s2))+s2;
  2048. end else s := s + '_';
  2049. param := para1;
  2050. while assigned(param) do
  2051. begin
  2052. s2 := param^.data^.sym^.name;
  2053. s := s+tostr(length(s2))+s2;
  2054. param := param^.next;
  2055. end;
  2056. cplusplusmangledname:=s;
  2057. end;
  2058. {$EndIf GDB}
  2059. procedure tprocdef.setmangledname(const s : string);
  2060. begin
  2061. if {$ifdef tp}not(use_big) and{$endif} (assigned(_mangledname)) then
  2062. strdispose(_mangledname);
  2063. setstring(_mangledname,s);
  2064. {$ifdef UseBrowser}
  2065. if assigned(parast) then
  2066. begin
  2067. stringdispose(parast^.name);
  2068. parast^.name:=stringdup('args of '+s);
  2069. end;
  2070. if assigned(localst) then
  2071. begin
  2072. stringdispose(localst^.name);
  2073. localst^.name:=stringdup('locals of '+s);
  2074. end;
  2075. {$endif UseBrowser}
  2076. end;
  2077. {***************************************************************************
  2078. TPROCVARDEF
  2079. ***************************************************************************}
  2080. constructor tprocvardef.init;
  2081. begin
  2082. inherited init;
  2083. deftype:=procvardef;
  2084. end;
  2085. constructor tprocvardef.load;
  2086. begin
  2087. inherited load;
  2088. deftype:=procvardef;
  2089. end;
  2090. procedure tprocvardef.write;
  2091. begin
  2092. { here we cannot get a real good value so just give something }
  2093. { plausible (PM) }
  2094. { a more secure way would be
  2095. to allways store in a temp }
  2096. if is_fpu(retdef) then
  2097. fpu_used:=2
  2098. else
  2099. fpu_used:=0;
  2100. inherited write;
  2101. current_ppu^.writeentry(ibprocvardef);
  2102. end;
  2103. function tprocvardef.size : longint;
  2104. begin
  2105. if (options and pomethodpointer)=0 then
  2106. size:=target_os.size_of_pointer
  2107. else
  2108. size:=2*target_os.size_of_pointer;
  2109. end;
  2110. {$ifdef GDB}
  2111. function tprocvardef.stabstring : pchar;
  2112. var
  2113. nss : pchar;
  2114. i : word;
  2115. param : pdefcoll;
  2116. begin
  2117. i := 0;
  2118. param := para1;
  2119. while assigned(param) do
  2120. begin
  2121. inc(i);
  2122. param := param^.next;
  2123. end;
  2124. getmem(nss,1024);
  2125. strpcopy(nss,'f'+retdef^.numberstring+','+tostr(i)+';');
  2126. param := para1;
  2127. i := 0;
  2128. { this confuses gdb !!
  2129. we should use 'F' instead of 'f' but
  2130. as we use c++ language mode
  2131. it does not like that either
  2132. Please do not remove this part
  2133. might be used once
  2134. gdb for pascal is ready PM }
  2135. (* while assigned(param) do
  2136. begin
  2137. inc(i);
  2138. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  2139. {Here we have lost the parameter names !!}
  2140. pst := strpnew('p'+tostr(i)+':'+param^.data^.numberstring+','+vartyp+';');
  2141. strcat(nss,pst);
  2142. strdispose(pst);
  2143. param := param^.next;
  2144. end; *)
  2145. {strpcopy(strend(nss),';');}
  2146. stabstring := strnew(nss);
  2147. freemem(nss,1024);
  2148. end;
  2149. procedure tprocvardef.concatstabto(asmlist : paasmoutput);
  2150. begin
  2151. if ( not assigned(sym) or sym^.isusedinstab or use_dbx)
  2152. and not is_def_stab_written then
  2153. inherited concatstabto(asmlist);
  2154. is_def_stab_written:=true;
  2155. end;
  2156. {$endif GDB}
  2157. procedure tprocvardef.write_rtti_data;
  2158. begin
  2159. {!!!!!!!}
  2160. end;
  2161. procedure tprocvardef.write_child_rtti_data;
  2162. begin
  2163. {!!!!!!!!}
  2164. end;
  2165. function tprocvardef.is_publishable : boolean;
  2166. begin
  2167. is_publishable:=(options and pomethodpointer)<>0;
  2168. end;
  2169. {***************************************************************************
  2170. TOBJECTDEF
  2171. ***************************************************************************}
  2172. {$ifdef GDB}
  2173. const
  2174. vtabletype : word = 0;
  2175. vtableassigned : boolean = false;
  2176. {$endif GDB}
  2177. constructor tobjectdef.init(const n : string;c : pobjectdef);
  2178. begin
  2179. tdef.init;
  2180. deftype:=objectdef;
  2181. options:=0;
  2182. publicsyms:=new(psymtable,init(objectsymtable));
  2183. publicsyms^.name := stringdup(n);
  2184. { create space for vmt !! }
  2185. {$ifdef OLDVMTSTYLE}
  2186. publicsyms^.datasize:=target_os.size_of_pointer;
  2187. options:=oo_hasvmt;
  2188. vmt_offset:=0;
  2189. {$else }
  2190. options:=0;
  2191. vmt_offset:=0;
  2192. publicsyms^.datasize:=0;
  2193. {$endif }
  2194. publicsyms^.defowner:=@self;
  2195. set_parent(c);
  2196. name:=stringdup(n);
  2197. end;
  2198. procedure tobjectdef.set_parent( c : pobjectdef);
  2199. begin
  2200. { nothing to do if the parent was not forward !}
  2201. if assigned(childof) then
  2202. exit;
  2203. childof:=c;
  2204. { some options are inherited !! }
  2205. if assigned(c) then
  2206. begin
  2207. options:= options or (c^.options and
  2208. (oo_hasvirtual or oo_hasprivate or
  2209. oo_hasprotected or
  2210. oo_hasconstructor or oo_hasdestructor
  2211. ));
  2212. { add the data of the anchestor class }
  2213. publicsyms^.datasize:=publicsyms^.datasize
  2214. +childof^.publicsyms^.datasize;
  2215. if ((options and oo_hasvmt)<>0) and
  2216. ((c^.options and oo_hasvmt)<>0) then
  2217. publicsyms^.datasize:=publicsyms^.datasize-target_os.size_of_pointer;
  2218. { if parent has a vmt field then
  2219. the offset is the same for the child PM }
  2220. if ((c^.options and oo_hasvmt)<>0) then
  2221. begin
  2222. vmt_offset:=c^.vmt_offset;
  2223. options:=options or oo_hasvmt;
  2224. end;
  2225. end;
  2226. savesize := publicsyms^.datasize;
  2227. end;
  2228. constructor tobjectdef.load;
  2229. var
  2230. oldread_member : boolean;
  2231. begin
  2232. tdef.load;
  2233. deftype:=objectdef;
  2234. savesize:=readlong;
  2235. vmt_offset:=readlong;
  2236. name:=stringdup(readstring);
  2237. childof:=pobjectdef(readdefref);
  2238. options:=readlong;
  2239. oldread_member:=read_member;
  2240. read_member:=true;
  2241. object_options:=true;
  2242. publicsyms:=new(psymtable,loadasstruct(objectsymtable));
  2243. object_options:=false;
  2244. read_member:=oldread_member;
  2245. publicsyms^.defowner:=@self;
  2246. { publicsyms^.datasize:=savesize; }
  2247. publicsyms^.name := stringdup(name^);
  2248. { handles the predefined class tobject }
  2249. { the last TOBJECT which is loaded gets }
  2250. { it ! }
  2251. if (name^='TOBJECT') and not(cs_compilesystem in aktmoduleswitches) and
  2252. isclass and (childof=pointer($ffffffff)) then
  2253. class_tobject:=@self;
  2254. end;
  2255. procedure tobjectdef.insertvmt;
  2256. begin
  2257. if (options and oo_hasvmt)<>0 then
  2258. internalerror(12345)
  2259. else
  2260. begin
  2261. { first round up to multiple of 4 }
  2262. if (aktpackrecords=2) then
  2263. begin
  2264. if (publicsyms^.datasize and 1)<>0 then
  2265. inc(publicsyms^.datasize);
  2266. end;
  2267. if (aktpackrecords>=4) then
  2268. begin
  2269. if (publicsyms^.datasize mod 4) <> 0 then
  2270. publicsyms^.datasize:=publicsyms^.datasize+4-(publicsyms^.datasize mod 4);
  2271. end;
  2272. vmt_offset:=publicsyms^.datasize;
  2273. publicsyms^.datasize:=publicsyms^.datasize+target_os.size_of_pointer;
  2274. options:=options or oo_hasvmt;
  2275. end;
  2276. end;
  2277. procedure tobjectdef.check_forwards;
  2278. begin
  2279. publicsyms^.check_forwards;
  2280. if (options and oo_isforward)<>0 then
  2281. begin
  2282. { ok, in future, the forward can be resolved }
  2283. Message1(sym_e_class_forward_not_resolved,name^);
  2284. options:=options and not(oo_isforward);
  2285. end;
  2286. end;
  2287. destructor tobjectdef.done;
  2288. begin
  2289. {!!!!
  2290. if assigned(privatesyms) then
  2291. dispose(privatesyms,done);
  2292. if assigned(protectedsyms) then
  2293. dispose(protectedsyms,done); }
  2294. if assigned(publicsyms) then
  2295. dispose(publicsyms,done);
  2296. if (options and oo_isforward)<>0 then
  2297. Message1(sym_e_class_forward_not_resolved,name^);
  2298. stringdispose(name);
  2299. tdef.done;
  2300. end;
  2301. { true, if self inherits from d (or if they are equal) }
  2302. function tobjectdef.isrelated(d : pobjectdef) : boolean;
  2303. var
  2304. hp : pobjectdef;
  2305. begin
  2306. hp:=@self;
  2307. while assigned(hp) do
  2308. begin
  2309. if hp=d then
  2310. begin
  2311. isrelated:=true;
  2312. exit;
  2313. end;
  2314. hp:=hp^.childof;
  2315. end;
  2316. isrelated:=false;
  2317. end;
  2318. function tobjectdef.size : longint;
  2319. begin
  2320. if (options and oo_is_class)<>0 then
  2321. size:=target_os.size_of_pointer
  2322. else
  2323. size:=publicsyms^.datasize;
  2324. end;
  2325. procedure tobjectdef.deref;
  2326. var
  2327. hp : pdef;
  2328. oldrecsyms : psymtable;
  2329. begin
  2330. resolvedef(pdef(childof));
  2331. oldrecsyms:=aktrecordsymtable;
  2332. aktrecordsymtable:=publicsyms;
  2333. { nun die Definitionen dereferenzieren }
  2334. hp:=publicsyms^.rootdef;
  2335. while assigned(hp) do
  2336. begin
  2337. hp^.deref;
  2338. { set owner }
  2339. hp^.owner:=publicsyms;
  2340. hp:=hp^.next;
  2341. end;
  2342. {$ifdef tp}
  2343. publicsyms^.foreach(derefsym);
  2344. {$else}
  2345. publicsyms^.foreach(@derefsym);
  2346. {$endif}
  2347. aktrecordsymtable:=oldrecsyms;
  2348. end;
  2349. function tobjectdef.vmt_mangledname : string;
  2350. {DM: I get a nil pointer on the owner name. I don't know if this
  2351. mayhappen, and I have therefore fixed the problem by doing nil pointer
  2352. checks.}
  2353. var
  2354. s1,s2:string;
  2355. begin
  2356. if (options and oo_hasvmt)=0 then
  2357. internalerror(12346);
  2358. if owner^.name=nil then
  2359. s1:=''
  2360. else
  2361. s1:=owner^.name^;
  2362. if name=nil then
  2363. s2:=''
  2364. else
  2365. s2:=name^;
  2366. vmt_mangledname:='VMT_'+s1+'$_'+s2;
  2367. end;
  2368. function tobjectdef.rtti_name : string;
  2369. var
  2370. s1,s2:string;
  2371. begin
  2372. if owner^.name=nil then
  2373. s1:=''
  2374. else
  2375. s1:=owner^.name^;
  2376. if name=nil then
  2377. s2:=''
  2378. else
  2379. s2:=name^;
  2380. rtti_name:='RTTI_'+s1+'$_'+s2;
  2381. end;
  2382. function tobjectdef.isclass : boolean;
  2383. begin
  2384. isclass:=(options and oo_is_class)<>0;
  2385. end;
  2386. procedure tobjectdef.write;
  2387. var
  2388. oldread_member : boolean;
  2389. begin
  2390. tdef.write;
  2391. writelong(size);
  2392. writelong(vmt_offset);
  2393. writestring(name^);
  2394. writedefref(childof);
  2395. writelong(options);
  2396. current_ppu^.writeentry(ibobjectdef);
  2397. oldread_member:=read_member;
  2398. read_member:=true;
  2399. object_options:=true;
  2400. publicsyms^.writeasstruct;
  2401. object_options:=false;
  2402. read_member:=oldread_member;
  2403. end;
  2404. {$ifdef GDB}
  2405. procedure addprocname(p :psym);
  2406. var virtualind,argnames : string;
  2407. news, newrec : pchar;
  2408. pd,ipd : pprocdef;
  2409. lindex : longint;
  2410. para : pdefcoll;
  2411. arglength : byte;
  2412. sp : char;
  2413. begin
  2414. If p^.typ = procsym then
  2415. begin
  2416. pd := pprocsym(p)^.definition;
  2417. { this will be used for full implementation of object stabs
  2418. not yet done }
  2419. ipd := pd;
  2420. while assigned(ipd^.nextoverloaded) do ipd := ipd^.nextoverloaded;
  2421. if (pd^.options and povirtualmethod) <> 0 then
  2422. begin
  2423. lindex := pd^.extnumber;
  2424. {doesnt seem to be necessary
  2425. lindex := lindex or $80000000;}
  2426. virtualind := '*'+tostr(lindex)+';'+ipd^._class^.numberstring+';'
  2427. end else virtualind := '.';
  2428. { arguments are not listed here }
  2429. {we don't need another definition}
  2430. para := pd^.para1;
  2431. argnames := '';
  2432. while assigned(para) do
  2433. begin
  2434. if para^.data^.deftype = formaldef then
  2435. begin
  2436. if para^.paratyp=vs_var then
  2437. argnames := argnames+'3var'
  2438. else if para^.paratyp=vs_const then
  2439. argnames:=argnames+'5const';
  2440. end
  2441. else
  2442. begin
  2443. { if the arg definition is like (v: ^byte;..
  2444. there is no sym attached to data !!! }
  2445. if assigned(para^.data^.sym) then
  2446. begin
  2447. arglength := length(para^.data^.sym^.name);
  2448. argnames := argnames + tostr(arglength)+para^.data^.sym^.name;
  2449. end
  2450. else
  2451. begin
  2452. argnames:=argnames+'11unnamedtype';
  2453. end;
  2454. end;
  2455. para := para^.next;
  2456. end;
  2457. ipd^.is_def_stab_written := true;
  2458. { here 2A must be changed for private and protected }
  2459. { 0 is private 1 protected and 2 public }
  2460. if (p^.properties and sp_private)<>0 then sp:='0'
  2461. else if (p^.properties and sp_protected)<>0 then sp:='1'
  2462. else sp:='2';
  2463. newrec := strpnew(p^.name+'::'+ipd^.numberstring
  2464. +'=##'+pd^.retdef^.numberstring+';:'+argnames+';'+sp+'A'
  2465. +virtualind+';');
  2466. { get spare place for a string at the end }
  2467. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  2468. begin
  2469. getmem(news,stabrecsize+memsizeinc);
  2470. strcopy(news,stabrecstring);
  2471. freemem(stabrecstring,stabrecsize);
  2472. stabrecsize:=stabrecsize+memsizeinc;
  2473. stabrecstring:=news;
  2474. end;
  2475. strcat(StabRecstring,newrec);
  2476. {freemem(newrec,memsizeinc); }
  2477. strdispose(newrec);
  2478. {This should be used for case !!}
  2479. RecOffset := RecOffset + pd^.size;
  2480. end;
  2481. end;
  2482. function tobjectdef.stabstring : pchar;
  2483. var anc : pobjectdef;
  2484. oldrec : pchar;
  2485. oldrecsize : longint;
  2486. str_end : string;
  2487. {$ifndef nonextfield}
  2488. cur : psym;
  2489. {$endif nonextfield}
  2490. begin
  2491. oldrec := stabrecstring;
  2492. oldrecsize:=stabrecsize;
  2493. stabrecsize:=memsizeinc;
  2494. GetMem(stabrecstring,stabrecsize);
  2495. strpcopy(stabRecString,'s'+tostr(size));
  2496. if assigned(childof) then
  2497. {only one ancestor not virtual, public, at base offset 0 }
  2498. { !1 , 0 2 0 , }
  2499. strpcopy(strend(stabrecstring),'!1,020,'+childof^.numberstring+';');
  2500. {virtual table to implement yet}
  2501. RecOffset := 0;
  2502. {$ifdef nonextfield}
  2503. {$ifdef tp}
  2504. publicsyms^.foreach(addname);
  2505. {$else}
  2506. publicsyms^.foreach(@addname);
  2507. {$endif}
  2508. {$else nonextfield}
  2509. cur:=publicsyms^.root;
  2510. while assigned(cur) do
  2511. begin
  2512. addname(cur);
  2513. cur:=cur^.nextsym;
  2514. end;
  2515. {$endif nonextfield}
  2516. if (options and oo_hasvmt) <> 0 then
  2517. if not assigned(childof) or ((childof^.options and oo_hasvmt) = 0) then
  2518. begin
  2519. strpcopy(strend(stabrecstring),'$vf'+numberstring+':'+typeglobalnumber('vtblarray')
  2520. +','+tostr(vmt_offset*8)+';');
  2521. end;
  2522. {$ifdef nonextfield}
  2523. {$ifdef tp}
  2524. publicsyms^.foreach(addprocname);
  2525. {$else}
  2526. publicsyms^.foreach(@addprocname);
  2527. {$endif tp }
  2528. {$else nonextfield}
  2529. cur:=publicsyms^.root;
  2530. while assigned(cur) do
  2531. begin
  2532. addprocname(cur);
  2533. cur:=cur^.nextsym;
  2534. end;
  2535. {$endif nonextfield}
  2536. if (options and oo_hasvmt) <> 0 then
  2537. begin
  2538. anc := @self;
  2539. while assigned(anc^.childof) and ((anc^.childof^.options and oo_hasvmt) <> 0) do
  2540. anc := anc^.childof;
  2541. str_end:=';~%'+anc^.numberstring+';';
  2542. end
  2543. else
  2544. str_end:=';';
  2545. strpcopy(strend(stabrecstring),str_end);
  2546. stabstring := strnew(StabRecString);
  2547. freemem(stabrecstring,stabrecsize);
  2548. stabrecstring := oldrec;
  2549. stabrecsize:=oldrecsize;
  2550. end;
  2551. {$endif GDB}
  2552. procedure tobjectdef.write_child_init_data;
  2553. begin
  2554. end;
  2555. procedure tobjectdef.write_init_data;
  2556. begin
  2557. if isclass then
  2558. rttilist^.concat(new(pai_const,init_8bit(tkclass)))
  2559. else
  2560. rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  2561. { generate the name }
  2562. rttilist^.concat(new(pai_const,init_8bit(length(name^))));
  2563. rttilist^.concat(new(pai_string,init(name^)));
  2564. rttilist^.concat(new(pai_const,init_32bit(size)));
  2565. count:=0;
  2566. publicsyms^.foreach(count_inittable_fields);
  2567. rttilist^.concat(new(pai_const,init_32bit(count)));
  2568. publicsyms^.foreach(write_field_inittable);
  2569. end;
  2570. function tobjectdef.needs_inittable : boolean;
  2571. var
  2572. oldb : boolean;
  2573. begin
  2574. { there are recursive calls to needs_inittable possible, }
  2575. { so we have to change to old value how else should }
  2576. { we do that ? check_rec_rtti can't be a nested }
  2577. { procedure of needs_rtti ! }
  2578. oldb:=binittable;
  2579. binittable:=false;
  2580. publicsyms^.foreach(check_rec_inittable);
  2581. needs_inittable:=binittable;
  2582. binittable:=oldb;
  2583. end;
  2584. procedure count_published_properties(sym : psym);{$ifndef fpc}far;{$endif}
  2585. begin
  2586. if (sym^.typ=propertysym) and ((sym^.properties and sp_published)<>0) then
  2587. inc(count);
  2588. end;
  2589. procedure write_property_info(sym : psym);{$ifndef fpc}far;{$endif}
  2590. var
  2591. proctypesinfo : byte;
  2592. procedure writeproc(sym : psym;def : pdef;shiftvalue : byte);
  2593. var
  2594. typvalue : byte;
  2595. begin
  2596. if not(assigned(sym)) then
  2597. begin
  2598. rttilist^.concat(new(pai_const,init_32bit(1)));
  2599. typvalue:=3;
  2600. end
  2601. else if sym^.typ=varsym then
  2602. begin
  2603. rttilist^.concat(new(pai_const,init_32bit(
  2604. pvarsym(sym)^.address)));
  2605. typvalue:=0;
  2606. end
  2607. else
  2608. begin
  2609. if (pprocdef(def)^.options and povirtualmethod)=0 then
  2610. begin
  2611. rttilist^.concat(new(pai_const,init_symbol(strpnew(pprocdef(def)^.mangledname))));
  2612. typvalue:=1;
  2613. end
  2614. else
  2615. begin
  2616. { virtual method, write vmt offset }
  2617. rttilist^.concat(new(pai_const,init_32bit(pprocdef(def)^.extnumber*4+12)));
  2618. typvalue:=2;
  2619. end;
  2620. end;
  2621. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  2622. end;
  2623. begin
  2624. if (ppropertysym(sym)^.options and ppo_indexed)<>0 then
  2625. proctypesinfo:=$40
  2626. else
  2627. proctypesinfo:=0;
  2628. if (sym^.typ=propertysym) and ((sym^.properties and sp_published)<>0) then
  2629. begin
  2630. rttilist^.concat(new(pai_const,init_symbol(strpnew(lab2str(ppropertysym(sym)^.proptype^.get_rtti_label)))));
  2631. writeproc(ppropertysym(sym)^.readaccesssym,ppropertysym(sym)^.readaccessdef,0);
  2632. writeproc(ppropertysym(sym)^.writeaccesssym,ppropertysym(sym)^.writeaccessdef,2);
  2633. { isn't it stored ? }
  2634. if (ppropertysym(sym)^.options and ppo_stored)=0 then
  2635. begin
  2636. rttilist^.concat(new(pai_const,init_32bit(1)));
  2637. proctypesinfo:=proctypesinfo or (3 shl 4);
  2638. end
  2639. else
  2640. writeproc(ppropertysym(sym)^.storedsym,ppropertysym(sym)^.storeddef,4);
  2641. rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.index)));
  2642. rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.default)));
  2643. rttilist^.concat(new(pai_const,init_16bit(count)));
  2644. inc(count);
  2645. rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
  2646. rttilist^.concat(new(pai_const,init_8bit(length(ppropertysym(sym)^.name))));
  2647. rttilist^.concat(new(pai_string,init(ppropertysym(sym)^.name)));
  2648. end;
  2649. end;
  2650. procedure generate_published_child_rtti(sym : psym);{$ifndef fpc}far;{$endif}
  2651. begin
  2652. if (sym^.typ=propertysym) and ((sym^.properties and sp_published)<>0) then
  2653. ppropertysym(sym)^.proptype^.get_rtti_label;
  2654. end;
  2655. procedure tobjectdef.write_child_rtti_data;
  2656. begin
  2657. publicsyms^.foreach(generate_published_child_rtti);
  2658. end;
  2659. procedure tobjectdef.generate_rtti;
  2660. begin
  2661. has_rtti:=true;
  2662. getlabel(rtti_label);
  2663. write_child_rtti_data;
  2664. rttilist^.concat(new(pai_symbol,init_global(rtti_name)));
  2665. rttilist^.concat(new(pai_label,init(rtti_label)));
  2666. write_rtti_data;
  2667. end;
  2668. function tobjectdef.next_free_name_index : longint;
  2669. var
  2670. i : longint;
  2671. begin
  2672. if assigned(childof) and ((childof^.options and oo_can_have_published)<>0) then
  2673. i:=childof^.next_free_name_index
  2674. else
  2675. i:=0;
  2676. count:=0;
  2677. publicsyms^.foreach(count_published_properties);
  2678. next_free_name_index:=i+count;
  2679. end;
  2680. procedure tobjectdef.write_rtti_data;
  2681. begin
  2682. if isclass then
  2683. rttilist^.concat(new(pai_const,init_8bit(tkclass)))
  2684. else
  2685. rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  2686. { generate the name }
  2687. rttilist^.concat(new(pai_const,init_8bit(length(name^))));
  2688. rttilist^.concat(new(pai_string,init(name^)));
  2689. { write class type }
  2690. rttilist^.concat(new(pai_const,init_symbol(strpnew(vmt_mangledname))));
  2691. { write owner typeinfo }
  2692. if assigned(childof) and ((childof^.options and oo_can_have_published)<>0) then
  2693. rttilist^.concat(new(pai_const,init_symbol(strpnew(lab2str(childof^.get_rtti_label)))))
  2694. else
  2695. rttilist^.concat(new(pai_const,init_32bit(0)));
  2696. { write published properties count }
  2697. count:=0;
  2698. publicsyms^.foreach(count_published_properties);
  2699. rttilist^.concat(new(pai_const,init_16bit(count)));
  2700. { write unit name }
  2701. if assigned(owner^.name) then
  2702. begin
  2703. rttilist^.concat(new(pai_const,init_8bit(length(owner^.name^))));
  2704. rttilist^.concat(new(pai_string,init(owner^.name^)));
  2705. end
  2706. else
  2707. rttilist^.concat(new(pai_const,init_8bit(0)));
  2708. { count is used to write nameindex }
  2709. { but we need an offset of the owner }
  2710. { to give each property an own slot }
  2711. if assigned(childof) and ((childof^.options and oo_can_have_published)<>0) then
  2712. count:=childof^.next_free_name_index
  2713. else
  2714. count:=0;
  2715. publicsyms^.foreach(write_property_info);
  2716. end;
  2717. function tobjectdef.is_publishable : boolean;
  2718. begin
  2719. is_publishable:=isclass;
  2720. end;
  2721. {****************************************************************************
  2722. TERRORDEF
  2723. ****************************************************************************}
  2724. constructor terrordef.init;
  2725. begin
  2726. inherited init;
  2727. deftype:=errordef;
  2728. end;
  2729. {$ifdef GDB}
  2730. function terrordef.stabstring : pchar;
  2731. begin
  2732. stabstring:=strpnew('error'+numberstring);
  2733. end;
  2734. {$endif GDB}
  2735. {
  2736. $Log$
  2737. Revision 1.63 1998-10-20 09:32:56 peter
  2738. * removed some unused vars
  2739. Revision 1.62 1998/10/20 08:06:58 pierre
  2740. * several memory corruptions due to double freemem solved
  2741. => never use p^.loc.location:=p^.left^.loc.location;
  2742. + finally I added now by default
  2743. that ra386dir translates global and unit symbols
  2744. + added a first field in tsymtable and
  2745. a nextsym field in tsym
  2746. (this allows to obtain ordered type info for
  2747. records and objects in gdb !)
  2748. Revision 1.61 1998/10/19 08:55:05 pierre
  2749. * wrong stabs info corrected once again !!
  2750. + variable vmt offset with vmt field only if required
  2751. implemented now !!!
  2752. Revision 1.60 1998/10/16 13:12:53 pierre
  2753. * added vmt_offsets in destructors code also !!!
  2754. * vmt_offset code for m68k
  2755. Revision 1.59 1998/10/16 08:51:51 peter
  2756. + target_os.stackalignment
  2757. + stack can be aligned at 2 or 4 byte boundaries
  2758. Revision 1.58 1998/10/15 15:13:30 pierre
  2759. + added oo_hasconstructor and oo_hasdestructor
  2760. for objects options
  2761. Revision 1.57 1998/10/14 15:54:20 pierre
  2762. * smallsets are not entirely implemented for
  2763. m68k added a ifdef usesmallset
  2764. that is allways defined for i386
  2765. (enables testing for m68k)
  2766. Revision 1.56 1998/10/09 11:47:56 pierre
  2767. * still more memory leaks fixes !!
  2768. Revision 1.55 1998/10/06 17:16:55 pierre
  2769. * some memory leaks fixed (thanks to Peter for heaptrc !)
  2770. Revision 1.54 1998/10/05 21:33:28 peter
  2771. * fixed 161,165,166,167,168
  2772. Revision 1.53 1998/10/05 12:48:39 pierre
  2773. * wrong handling of range check for arrays fixed
  2774. Revision 1.52 1998/10/02 07:20:38 florian
  2775. * range checking in units doesn't work if the units are smartlinked, fixed
  2776. Revision 1.51 1998/09/25 12:01:41 florian
  2777. * tobjectdef.publicsyms.datasize was set to savesize, this is wrong now
  2778. because the symtable size is read from the ppu file
  2779. Revision 1.50 1998/09/23 15:46:40 florian
  2780. * problem with with and classes fixed
  2781. Revision 1.49 1998/09/23 12:03:55 peter
  2782. * overloading fix for array of const
  2783. Revision 1.48 1998/09/22 15:37:23 peter
  2784. + array of const start
  2785. Revision 1.47 1998/09/21 15:46:01 michael
  2786. Applied florians fix for check_rec_inittable
  2787. Revision 1.46 1998/09/21 08:45:21 pierre
  2788. + added vmt_offset in tobjectdef.write for fututre use
  2789. (first steps to have objects without vmt if no virtual !!)
  2790. + added fpu_used field for tabstractprocdef :
  2791. sets this level to 2 if the functions return with value in FPU
  2792. (is then set to correct value at parsing of implementation)
  2793. THIS MIGHT refuse some code with FPU expression too complex
  2794. that were accepted before and even in some cases
  2795. that don't overflow in fact
  2796. ( like if f : float; is a forward that finally in implementation
  2797. only uses one fpu register !!)
  2798. Nevertheless I think that it will improve security on
  2799. FPU operations !!
  2800. * most other changes only for UseBrowser code
  2801. (added symtable references for record and objects)
  2802. local switch for refs to args and local of each function
  2803. (static symtable still missing)
  2804. UseBrowser still not stable and probably broken by
  2805. the definition hash array !!
  2806. Revision 1.45 1998/09/20 08:31:29 florian
  2807. + bit 6 of tpropinfo.propprocs is set, if the property contains a
  2808. constant index
  2809. Revision 1.44 1998/09/19 15:23:58 florian
  2810. * rtti for ordtypes corrected
  2811. Revision 1.43 1998/09/18 17:12:40 florian
  2812. * problem with writing of class references fixed
  2813. Revision 1.42 1998/09/17 13:41:20 pierre
  2814. sizeof(TPOINT) problem
  2815. Revision 1.40.2.2 1998/09/17 08:42:33 pierre
  2816. TPOINT sizeof fix
  2817. Revision 1.41 1998/09/15 17:39:30 jonas
  2818. + bugfix from bugfix branch
  2819. Revision 1.40.2.1 1998/09/15 17:35:32 jonas
  2820. * chenged string_typ in tstringdef.wideload from ansistring to widestring
  2821. Revision 1.40 1998/09/09 15:34:00 peter
  2822. * removed warnings
  2823. Revision 1.39 1998/09/08 10:23:44 pierre
  2824. * name field of filedef corrected
  2825. Revision 1.38 1998/09/07 23:10:23 florian
  2826. * a lot of stuff fixed regarding rtti and publishing of properties,
  2827. basics should now work
  2828. Revision 1.37 1998/09/07 19:33:24 florian
  2829. + some stuff for property rtti added:
  2830. - NameIndex of the TPropInfo record is now written correctly
  2831. - the DEFAULT/NODEFAULT keyword is supported now
  2832. - the default value and the storedsym/def are now written to
  2833. the PPU fiel
  2834. Revision 1.36 1998/09/07 17:37:01 florian
  2835. * first fixes for published properties
  2836. Revision 1.35 1998/09/06 22:42:02 florian
  2837. + rtti genreation for properties added
  2838. Revision 1.34 1998/09/04 18:15:02 peter
  2839. * filedef updated
  2840. Revision 1.33 1998/09/03 17:08:49 pierre
  2841. * better lines for stabs
  2842. (no scroll back to if before else part
  2843. no return to case line at jump outside case)
  2844. + source lines also if not in order
  2845. Revision 1.32 1998/09/03 16:03:20 florian
  2846. + rtti generation
  2847. * init table generation changed
  2848. Revision 1.31 1998/09/02 15:14:28 peter
  2849. * enum packing changed from len to max
  2850. Revision 1.30 1998/09/01 17:37:29 peter
  2851. * removed debug writeln :(
  2852. Revision 1.29 1998/09/01 12:53:25 peter
  2853. + aktpackenum
  2854. Revision 1.28 1998/09/01 07:54:22 pierre
  2855. * UseBrowser a little updated (might still be buggy !!)
  2856. * bug in psub.pas in function specifier removed
  2857. * stdcall allowed in interface and in implementation
  2858. (FPC will not yet complain if it is missing in either part
  2859. because stdcall is only a dummy !!)
  2860. Revision 1.27 1998/08/28 12:51:43 florian
  2861. + ansistring to pchar type cast fixed
  2862. Revision 1.26 1998/08/25 12:42:44 pierre
  2863. * CDECL changed to CVAR for variables
  2864. specifications are read in structures also
  2865. + started adding GPC compatibility mode ( option -Sp)
  2866. * names changed to lowercase
  2867. Revision 1.25 1998/08/23 21:04:38 florian
  2868. + rtti generation for classes added
  2869. + new/dispose do now also a call to INITIALIZE/FINALIZE, if necessaray
  2870. Revision 1.24 1998/08/20 12:53:26 peter
  2871. * object_options are always written for object syms
  2872. Revision 1.23 1998/08/19 00:42:42 peter
  2873. + subrange types for enums
  2874. + checking for bounds type with ranges
  2875. Revision 1.22 1998/08/17 10:10:10 peter
  2876. - removed OLDPPU
  2877. Revision 1.21 1998/08/10 14:50:28 peter
  2878. + localswitches, moduleswitches, globalswitches splitting
  2879. Revision 1.20 1998/07/18 22:54:30 florian
  2880. * some ansi/wide/longstring support fixed:
  2881. o parameter passing
  2882. o returning as result from functions
  2883. Revision 1.19 1998/07/14 14:47:05 peter
  2884. * released NEWINPUT
  2885. Revision 1.18 1998/07/10 10:51:04 peter
  2886. * m68k updates
  2887. Revision 1.16 1998/07/07 11:20:13 peter
  2888. + NEWINPUT for a better inputfile and scanner object
  2889. Revision 1.15 1998/06/24 14:48:37 peter
  2890. * ifdef newppu -> ifndef oldppu
  2891. Revision 1.14 1998/06/16 08:56:31 peter
  2892. + targetcpu
  2893. * cleaner pmodules for newppu
  2894. Revision 1.13 1998/06/15 15:38:09 pierre
  2895. * small bug in systems.pas corrected
  2896. + operators in different units better hanlded
  2897. Revision 1.12 1998/06/15 14:30:12 daniel
  2898. * Reverted my changes.
  2899. Revision 1.10 1998/06/13 00:10:16 peter
  2900. * working browser and newppu
  2901. * some small fixes against crashes which occured in bp7 (but not in
  2902. fpc?!)
  2903. Revision 1.9 1998/06/12 14:10:37 michael
  2904. * Fixed wrong code for ansistring
  2905. Revision 1.8 1998/06/11 10:11:58 peter
  2906. * -gb works again
  2907. Revision 1.7 1998/06/07 15:30:25 florian
  2908. + first working rtti
  2909. + data init/final. for local variables
  2910. Revision 1.6 1998/06/05 14:37:37 pierre
  2911. * fixes for inline for operators
  2912. * inline procedure more correctly restricted
  2913. Revision 1.5 1998/06/04 23:52:01 peter
  2914. * m68k compiles
  2915. + .def file creation moved to gendef.pas so it could also be used
  2916. for win32
  2917. Revision 1.4 1998/06/04 09:55:45 pierre
  2918. * demangled name of procsym reworked to become independant of the mangling
  2919. scheme
  2920. Revision 1.3 1998/06/03 22:49:03 peter
  2921. + wordbool,longbool
  2922. * rename bis,von -> high,low
  2923. * moved some systemunit loading/creating to psystem.pas
  2924. Revision 1.2 1998/05/31 14:13:37 peter
  2925. * fixed call bugs with assembler readers
  2926. + OPR_SYMBOL to hold a symbol in the asm parser
  2927. * fixed staticsymtable vars which were acessed through %ebp instead of
  2928. name
  2929. Revision 1.1 1998/05/27 19:45:09 peter
  2930. * symtable.pas splitted into includefiles
  2931. * symtable adapted for $ifndef OLDPPU
  2932. }