symdef.inc 121 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 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. { and the rtl/i386,template/rttip.inc files }
  25. tkUnknown = 0;
  26. tkInteger = 1;
  27. tkChar = 2;
  28. tkEnumeration = 3;
  29. tkFloat = 4;
  30. tkSet = 5;
  31. tkMethod = 6;
  32. tkSString = 7;
  33. tkString = tkSString;
  34. tkLString = 8;
  35. tkAString = 9;
  36. tkWString = 10;
  37. tkVariant = 11;
  38. tkArray = 12;
  39. tkRecord = 13;
  40. tkInterface = 14;
  41. tkClass = 15;
  42. tkObject = 16;
  43. tkWChar = 17;
  44. tkBool = 18;
  45. tkInt64 = 19;
  46. tkQWord = 20;
  47. otSByte = 0;
  48. otUByte = 1;
  49. otSWord = 2;
  50. otUWord = 3;
  51. otSLong = 4;
  52. otULong = 5;
  53. ftSingle = 0;
  54. ftDouble = 1;
  55. ftExtended = 2;
  56. ftComp = 3;
  57. ftCurr = 4;
  58. ftFixed16 = 5;
  59. ftFixed32 = 6;
  60. mkProcedure = 0;
  61. mkFunction = 1;
  62. mkConstructor = 2;
  63. mkDestructor = 3;
  64. mkClassProcedure= 4;
  65. mkClassFunction = 5;
  66. pfvar = 1;
  67. pfConst = 2;
  68. pfArray = 4;
  69. pfAddress = 8;
  70. pfReference = 16;
  71. pfOut = 32;
  72. constructor tdef.init;
  73. begin
  74. inherited init;
  75. deftype:=abstractdef;
  76. owner := nil;
  77. typesym := nil;
  78. savesize := 0;
  79. if registerdef then
  80. symtablestack^.registerdef(@self);
  81. has_rtti:=false;
  82. has_inittable:=false;
  83. {$ifdef GDB}
  84. is_def_stab_written := false;
  85. globalnb := 0;
  86. {$endif GDB}
  87. if assigned(lastglobaldef) then
  88. begin
  89. lastglobaldef^.nextglobal := @self;
  90. previousglobal:=lastglobaldef;
  91. end
  92. else
  93. begin
  94. firstglobaldef := @self;
  95. previousglobal := nil;
  96. end;
  97. lastglobaldef := @self;
  98. nextglobal := nil;
  99. end;
  100. constructor tdef.load;
  101. begin
  102. deftype:=abstractdef;
  103. next := nil;
  104. owner := nil;
  105. has_rtti:=false;
  106. has_inittable:=false;
  107. {$ifdef GDB}
  108. is_def_stab_written := false;
  109. globalnb := 0;
  110. {$endif GDB}
  111. if assigned(lastglobaldef) then
  112. begin
  113. lastglobaldef^.nextglobal := @self;
  114. previousglobal:=lastglobaldef;
  115. end
  116. else
  117. begin
  118. firstglobaldef := @self;
  119. previousglobal:=nil;
  120. end;
  121. lastglobaldef := @self;
  122. nextglobal := nil;
  123. { load }
  124. indexnr:=readword;
  125. typesym:=ptypesym(readsymref);
  126. end;
  127. destructor tdef.done;
  128. begin
  129. { first element ? }
  130. if not(assigned(previousglobal)) then
  131. begin
  132. firstglobaldef := nextglobal;
  133. if assigned(firstglobaldef) then
  134. firstglobaldef^.previousglobal:=nil;
  135. end
  136. else
  137. begin
  138. { remove reference in the element before }
  139. previousglobal^.nextglobal:=nextglobal;
  140. end;
  141. { last element ? }
  142. if not(assigned(nextglobal)) then
  143. begin
  144. lastglobaldef := previousglobal;
  145. if assigned(lastglobaldef) then
  146. lastglobaldef^.nextglobal:=nil;
  147. end
  148. else
  149. nextglobal^.previousglobal:=previousglobal;
  150. previousglobal:=nil;
  151. nextglobal:=nil;
  152. {$ifdef SYNONYM}
  153. while assigned(typesym) do
  154. begin
  155. typesym^.restype.setdef(nil);
  156. typesym:=typesym^.synonym;
  157. end;
  158. {$endif}
  159. end;
  160. { used for enumdef because the symbols are
  161. inserted in the owner symtable }
  162. procedure tdef.correct_owner_symtable;
  163. var
  164. st : psymtable;
  165. begin
  166. if assigned(owner) and
  167. (owner^.symtabletype in [recordsymtable,objectsymtable]) then
  168. begin
  169. owner^.defindex^.deleteindex(@self);
  170. st:=owner;
  171. while (st^.symtabletype in [recordsymtable,objectsymtable]) do
  172. st:=st^.next;
  173. st^.registerdef(@self);
  174. end;
  175. end;
  176. function tdef.typename:string;
  177. begin
  178. if assigned(typesym) then
  179. typename:=Upper(typesym^.name)
  180. else
  181. typename:=gettypename;
  182. end;
  183. function tdef.gettypename : string;
  184. begin
  185. gettypename:='<unknown type>'
  186. end;
  187. function tdef.is_in_current : boolean;
  188. var
  189. p : psymtable;
  190. begin
  191. p:=owner;
  192. is_in_current:=false;
  193. while assigned(p) do
  194. begin
  195. if (p=current_module^.globalsymtable) or (p=current_module^.localsymtable)
  196. or (p^.symtabletype in [globalsymtable,staticsymtable]) then
  197. begin
  198. is_in_current:=true;
  199. exit;
  200. end
  201. else if p^.symtabletype in [localsymtable,parasymtable,objectsymtable] then
  202. begin
  203. if assigned(p^.defowner) then
  204. p:=pobjectdef(p^.defowner)^.owner
  205. else
  206. exit;
  207. end
  208. else
  209. exit;
  210. end;
  211. end;
  212. procedure tdef.write;
  213. begin
  214. writeword(indexnr);
  215. writesymref(typesym);
  216. {$ifdef GDB}
  217. if globalnb = 0 then
  218. begin
  219. if assigned(owner) then
  220. globalnb := owner^.getnewtypecount
  221. else
  222. begin
  223. globalnb := PGlobalTypeCount^;
  224. Inc(PGlobalTypeCount^);
  225. end;
  226. end;
  227. {$endif GDB}
  228. end;
  229. function tdef.size : longint;
  230. begin
  231. size:=savesize;
  232. end;
  233. function tdef.alignment : longint;
  234. begin
  235. { normal alignment by default }
  236. alignment:=0;
  237. end;
  238. {$ifdef GDB}
  239. procedure tdef.set_globalnb;
  240. begin
  241. globalnb :=PGlobalTypeCount^;
  242. inc(PglobalTypeCount^);
  243. end;
  244. function tdef.stabstring : pchar;
  245. begin
  246. stabstring := strpnew('t'+numberstring+';');
  247. end;
  248. function tdef.numberstring : string;
  249. var table : psymtable;
  250. begin
  251. {formal def have no type !}
  252. if deftype = formaldef then
  253. begin
  254. numberstring := voiddef^.numberstring;
  255. exit;
  256. end;
  257. if (not assigned(typesym)) or (not typesym^.isusedinstab) then
  258. begin
  259. {set even if debuglist is not defined}
  260. if assigned(typesym) then
  261. typesym^.isusedinstab := true;
  262. if assigned(debuglist) and not is_def_stab_written then
  263. concatstabto(debuglist);
  264. end;
  265. if not (cs_gdb_dbx in aktglobalswitches) then
  266. begin
  267. if globalnb = 0 then
  268. set_globalnb;
  269. numberstring := tostr(globalnb);
  270. end
  271. else
  272. begin
  273. if globalnb = 0 then
  274. begin
  275. if assigned(owner) then
  276. globalnb := owner^.getnewtypecount
  277. else
  278. begin
  279. globalnb := PGlobalTypeCount^;
  280. Inc(PGlobalTypeCount^);
  281. end;
  282. end;
  283. if assigned(typesym) then
  284. begin
  285. table := typesym^.owner;
  286. if table^.unitid > 0 then
  287. numberstring := '('+tostr(table^.unitid)+','+tostr(typesym^.restype.def^.globalnb)+')'
  288. else
  289. numberstring := tostr(globalnb);
  290. exit;
  291. end;
  292. numberstring := tostr(globalnb);
  293. end;
  294. end;
  295. function tdef.allstabstring : pchar;
  296. var stabchar : string[2];
  297. ss,st : pchar;
  298. sname : string;
  299. sym_line_no : longint;
  300. begin
  301. ss := stabstring;
  302. getmem(st,strlen(ss)+512);
  303. stabchar := 't';
  304. if deftype in tagtypes then
  305. stabchar := 'Tt';
  306. if assigned(typesym) then
  307. begin
  308. sname := typesym^.name;
  309. sym_line_no:=typesym^.fileinfo.line;
  310. end
  311. else
  312. begin
  313. sname := ' ';
  314. sym_line_no:=0;
  315. end;
  316. strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
  317. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  318. allstabstring := strnew(st);
  319. freemem(st,strlen(ss)+512);
  320. strdispose(ss);
  321. end;
  322. procedure tdef.concatstabto(asmlist : paasmoutput);
  323. var stab_str : pchar;
  324. begin
  325. if ((typesym = nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  326. and not is_def_stab_written then
  327. begin
  328. If cs_gdb_dbx in aktglobalswitches then
  329. begin
  330. { otherwise you get two of each def }
  331. If assigned(typesym) then
  332. begin
  333. if typesym^.typ=symconst.typesym then
  334. typesym^.isusedinstab:=true;
  335. if (typesym^.owner = nil) or
  336. ((typesym^.owner^.symtabletype = unitsymtable) and
  337. punitsymtable(typesym^.owner)^.dbx_count_ok) then
  338. begin
  339. {with DBX we get the definition from the other objects }
  340. is_def_stab_written := true;
  341. exit;
  342. end;
  343. end;
  344. end;
  345. { to avoid infinite loops }
  346. is_def_stab_written := true;
  347. stab_str := allstabstring;
  348. asmlist^.concat(new(pai_stabs,init(stab_str)));
  349. end;
  350. end;
  351. {$endif GDB}
  352. procedure tdef.deref;
  353. begin
  354. resolvesym(psym(typesym));
  355. end;
  356. { rtti generation }
  357. procedure tdef.generate_rtti;
  358. begin
  359. if not has_rtti then
  360. begin
  361. has_rtti:=true;
  362. getdatalabel(rtti_label);
  363. write_child_rtti_data;
  364. rttilist^.concat(new(pai_symbol,init(rtti_label,0)));
  365. write_rtti_data;
  366. rttilist^.concat(new(pai_symbol_end,init(rtti_label)));
  367. end;
  368. end;
  369. function tdef.get_rtti_label : string;
  370. begin
  371. generate_rtti;
  372. get_rtti_label:=rtti_label^.name;
  373. end;
  374. { init table handling }
  375. function tdef.needs_inittable : boolean;
  376. begin
  377. needs_inittable:=false;
  378. end;
  379. procedure tdef.generate_inittable;
  380. begin
  381. has_inittable:=true;
  382. getdatalabel(inittable_label);
  383. write_child_init_data;
  384. rttilist^.concat(new(pai_label,init(inittable_label)));
  385. write_init_data;
  386. end;
  387. procedure tdef.write_init_data;
  388. begin
  389. write_rtti_data;
  390. end;
  391. procedure tdef.write_child_init_data;
  392. begin
  393. write_child_rtti_data;
  394. end;
  395. function tdef.get_inittable_label : pasmlabel;
  396. begin
  397. if not(has_inittable) then
  398. generate_inittable;
  399. get_inittable_label:=inittable_label;
  400. end;
  401. procedure tdef.write_rtti_name;
  402. var
  403. str : string;
  404. begin
  405. { name }
  406. if assigned(typesym) then
  407. begin
  408. str:=typesym^.name;
  409. rttilist^.concat(new(pai_string,init(chr(length(str))+str)));
  410. end
  411. else
  412. rttilist^.concat(new(pai_string,init(#0)))
  413. end;
  414. { returns true, if the definition can be published }
  415. function tdef.is_publishable : boolean;
  416. begin
  417. is_publishable:=false;
  418. end;
  419. procedure tdef.write_rtti_data;
  420. begin
  421. end;
  422. procedure tdef.write_child_rtti_data;
  423. begin
  424. end;
  425. function tdef.is_intregable : boolean;
  426. begin
  427. is_intregable:=false;
  428. case deftype of
  429. pointerdef,
  430. enumdef,
  431. procvardef :
  432. is_intregable:=true;
  433. orddef :
  434. case porddef(@self)^.typ of
  435. bool8bit,bool16bit,bool32bit,
  436. u8bit,u16bit,u32bit,
  437. s8bit,s16bit,s32bit:
  438. is_intregable:=true;
  439. end;
  440. setdef:
  441. is_intregable:=is_smallset(@self);
  442. end;
  443. end;
  444. function tdef.is_fpuregable : boolean;
  445. begin
  446. is_fpuregable:=(deftype=floatdef) and not(pfloatdef(@self)^.typ in [f32bit,f16bit]);
  447. end;
  448. {****************************************************************************
  449. TSTRINGDEF
  450. ****************************************************************************}
  451. constructor tstringdef.shortinit(l : byte);
  452. begin
  453. tdef.init;
  454. string_typ:=st_shortstring;
  455. deftype:=stringdef;
  456. len:=l;
  457. savesize:=len+1;
  458. end;
  459. constructor tstringdef.shortload;
  460. begin
  461. tdef.load;
  462. string_typ:=st_shortstring;
  463. deftype:=stringdef;
  464. len:=readbyte;
  465. savesize:=len+1;
  466. end;
  467. constructor tstringdef.longinit(l : longint);
  468. begin
  469. tdef.init;
  470. string_typ:=st_longstring;
  471. deftype:=stringdef;
  472. len:=l;
  473. savesize:=target_os.size_of_pointer;
  474. end;
  475. constructor tstringdef.longload;
  476. begin
  477. tdef.load;
  478. deftype:=stringdef;
  479. string_typ:=st_longstring;
  480. len:=readlong;
  481. savesize:=target_os.size_of_pointer;
  482. end;
  483. constructor tstringdef.ansiinit(l : longint);
  484. begin
  485. tdef.init;
  486. string_typ:=st_ansistring;
  487. deftype:=stringdef;
  488. len:=l;
  489. savesize:=target_os.size_of_pointer;
  490. end;
  491. constructor tstringdef.ansiload;
  492. begin
  493. tdef.load;
  494. deftype:=stringdef;
  495. string_typ:=st_ansistring;
  496. len:=readlong;
  497. savesize:=target_os.size_of_pointer;
  498. end;
  499. constructor tstringdef.wideinit(l : longint);
  500. begin
  501. tdef.init;
  502. string_typ:=st_widestring;
  503. deftype:=stringdef;
  504. len:=l;
  505. savesize:=target_os.size_of_pointer;
  506. end;
  507. constructor tstringdef.wideload;
  508. begin
  509. tdef.load;
  510. deftype:=stringdef;
  511. string_typ:=st_widestring;
  512. len:=readlong;
  513. savesize:=target_os.size_of_pointer;
  514. end;
  515. function tstringdef.stringtypname:string;
  516. const
  517. typname:array[tstringtype] of string[8]=('',
  518. 'SHORTSTR','LONGSTR','ANSISTR','WIDESTR'
  519. );
  520. begin
  521. stringtypname:=typname[string_typ];
  522. end;
  523. function tstringdef.size : longint;
  524. begin
  525. size:=savesize;
  526. end;
  527. procedure tstringdef.write;
  528. begin
  529. tdef.write;
  530. if string_typ=st_shortstring then
  531. writebyte(len)
  532. else
  533. writelong(len);
  534. case string_typ of
  535. st_shortstring : current_ppu^.writeentry(ibshortstringdef);
  536. st_longstring : current_ppu^.writeentry(iblongstringdef);
  537. st_ansistring : current_ppu^.writeentry(ibansistringdef);
  538. st_widestring : current_ppu^.writeentry(ibwidestringdef);
  539. end;
  540. end;
  541. {$ifdef GDB}
  542. function tstringdef.stabstring : pchar;
  543. var
  544. bytest,charst,longst : string;
  545. begin
  546. case string_typ of
  547. st_shortstring:
  548. begin
  549. charst := typeglobalnumber('char');
  550. { this is what I found in stabs.texinfo but
  551. gdb 4.12 for go32 doesn't understand that !! }
  552. {$IfDef GDBknowsstrings}
  553. stabstring := strpnew('n'+charst+';'+tostr(len));
  554. {$else}
  555. bytest := typeglobalnumber('byte');
  556. stabstring := strpnew('s'+tostr(len+1)+'length:'+bytest
  557. +',0,8;st:ar'+bytest
  558. +';1;'+tostr(len)+';'+charst+',8,'+tostr(len*8)+';;');
  559. {$EndIf}
  560. end;
  561. st_longstring:
  562. begin
  563. charst := typeglobalnumber('char');
  564. { this is what I found in stabs.texinfo but
  565. gdb 4.12 for go32 doesn't understand that !! }
  566. {$IfDef GDBknowsstrings}
  567. stabstring := strpnew('n'+charst+';'+tostr(len));
  568. {$else}
  569. bytest := typeglobalnumber('byte');
  570. longst := typeglobalnumber('longint');
  571. stabstring := strpnew('s'+tostr(len+5)+'length:'+longst
  572. +',0,32;dummy:'+bytest+',32,8;st:ar'+bytest
  573. +';1;'+tostr(len)+';'+charst+',40,'+tostr(len*8)+';;');
  574. {$EndIf}
  575. end;
  576. st_ansistring:
  577. begin
  578. { an ansi string looks like a pchar easy !! }
  579. stabstring:=strpnew('*'+typeglobalnumber('char'));
  580. end;
  581. st_widestring:
  582. begin
  583. { an ansi string looks like a pchar easy !! }
  584. stabstring:=strpnew('*'+typeglobalnumber('char'));
  585. end;
  586. end;
  587. end;
  588. procedure tstringdef.concatstabto(asmlist : paasmoutput);
  589. begin
  590. inherited concatstabto(asmlist);
  591. end;
  592. {$endif GDB}
  593. function tstringdef.needs_inittable : boolean;
  594. begin
  595. needs_inittable:=string_typ in [st_ansistring,st_widestring];
  596. end;
  597. function tstringdef.gettypename : string;
  598. const
  599. names : array[tstringtype] of string[20] = ('',
  600. 'ShortString','LongString','AnsiString','WideString');
  601. begin
  602. gettypename:=names[string_typ];
  603. end;
  604. procedure tstringdef.write_rtti_data;
  605. begin
  606. case string_typ of
  607. st_ansistring:
  608. begin
  609. rttilist^.concat(new(pai_const,init_8bit(tkAString)));
  610. write_rtti_name;
  611. end;
  612. st_widestring:
  613. begin
  614. rttilist^.concat(new(pai_const,init_8bit(tkWString)));
  615. write_rtti_name;
  616. end;
  617. st_longstring:
  618. begin
  619. rttilist^.concat(new(pai_const,init_8bit(tkLString)));
  620. write_rtti_name;
  621. end;
  622. st_shortstring:
  623. begin
  624. rttilist^.concat(new(pai_const,init_8bit(tkSString)));
  625. write_rtti_name;
  626. rttilist^.concat(new(pai_const,init_8bit(len)));
  627. end;
  628. end;
  629. end;
  630. function tstringdef.is_publishable : boolean;
  631. begin
  632. is_publishable:=true;
  633. end;
  634. {****************************************************************************
  635. TENUMDEF
  636. ****************************************************************************}
  637. constructor tenumdef.init;
  638. begin
  639. tdef.init;
  640. deftype:=enumdef;
  641. minval:=0;
  642. maxval:=0;
  643. calcsavesize;
  644. has_jumps:=false;
  645. basedef:=nil;
  646. rangenr:=0;
  647. firstenum:=nil;
  648. correct_owner_symtable;
  649. end;
  650. constructor tenumdef.init_subrange(_basedef:penumdef;_min,_max:longint);
  651. begin
  652. tdef.init;
  653. deftype:=enumdef;
  654. minval:=_min;
  655. maxval:=_max;
  656. basedef:=_basedef;
  657. calcsavesize;
  658. has_jumps:=false;
  659. rangenr:=0;
  660. firstenum:=basedef^.firstenum;
  661. while assigned(firstenum) and (penumsym(firstenum)^.value<>minval) do
  662. firstenum:=firstenum^.nextenum;
  663. correct_owner_symtable;
  664. end;
  665. constructor tenumdef.load;
  666. begin
  667. tdef.load;
  668. deftype:=enumdef;
  669. basedef:=penumdef(readdefref);
  670. minval:=readlong;
  671. maxval:=readlong;
  672. savesize:=readlong;
  673. has_jumps:=false;
  674. firstenum:=Nil;
  675. end;
  676. procedure tenumdef.calcsavesize;
  677. begin
  678. if (aktpackenum=4) or (min<0) or (max>65535) then
  679. savesize:=4
  680. else
  681. if (aktpackenum=2) or (min<0) or (max>255) then
  682. savesize:=2
  683. else
  684. savesize:=1;
  685. end;
  686. procedure tenumdef.setmax(_max:longint);
  687. begin
  688. maxval:=_max;
  689. calcsavesize;
  690. end;
  691. procedure tenumdef.setmin(_min:longint);
  692. begin
  693. minval:=_min;
  694. calcsavesize;
  695. end;
  696. function tenumdef.min:longint;
  697. begin
  698. min:=minval;
  699. end;
  700. function tenumdef.max:longint;
  701. begin
  702. max:=maxval;
  703. end;
  704. procedure tenumdef.deref;
  705. begin
  706. inherited deref;
  707. resolvedef(pdef(basedef));
  708. end;
  709. destructor tenumdef.done;
  710. begin
  711. inherited done;
  712. end;
  713. procedure tenumdef.write;
  714. begin
  715. tdef.write;
  716. writedefref(basedef);
  717. writelong(min);
  718. writelong(max);
  719. writelong(savesize);
  720. current_ppu^.writeentry(ibenumdef);
  721. end;
  722. function tenumdef.getrangecheckstring : string;
  723. begin
  724. if (cs_create_smart in aktmoduleswitches) then
  725. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  726. else
  727. getrangecheckstring:='R_'+tostr(rangenr);
  728. end;
  729. procedure tenumdef.genrangecheck;
  730. begin
  731. if rangenr=0 then
  732. begin
  733. { generate two constant for bounds }
  734. getlabelnr(rangenr);
  735. if (cs_create_smart in aktmoduleswitches) then
  736. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,8)))
  737. else
  738. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,8)));
  739. datasegment^.concat(new(pai_const,init_32bit(min)));
  740. datasegment^.concat(new(pai_const,init_32bit(max)));
  741. end;
  742. end;
  743. {$ifdef GDB}
  744. function tenumdef.stabstring : pchar;
  745. var st,st2 : pchar;
  746. p : penumsym;
  747. s : string;
  748. memsize : word;
  749. begin
  750. memsize := memsizeinc;
  751. getmem(st,memsize);
  752. strpcopy(st,'e');
  753. p := firstenum;
  754. while assigned(p) do
  755. begin
  756. s :=p^.name+':'+tostr(p^.value)+',';
  757. { place for the ending ';' also }
  758. if (strlen(st)+length(s)+1<memsize) then
  759. strpcopy(strend(st),s)
  760. else
  761. begin
  762. getmem(st2,memsize+memsizeinc);
  763. strcopy(st2,st);
  764. freemem(st,memsize);
  765. st := st2;
  766. memsize := memsize+memsizeinc;
  767. strpcopy(strend(st),s);
  768. end;
  769. p := p^.nextenum;
  770. end;
  771. strpcopy(strend(st),';');
  772. stabstring := strnew(st);
  773. freemem(st,memsize);
  774. end;
  775. {$endif GDB}
  776. procedure tenumdef.write_child_rtti_data;
  777. begin
  778. if assigned(basedef) then
  779. basedef^.get_rtti_label;
  780. end;
  781. procedure tenumdef.write_rtti_data;
  782. var
  783. hp : penumsym;
  784. begin
  785. rttilist^.concat(new(pai_const,init_8bit(tkEnumeration)));
  786. write_rtti_name;
  787. case savesize of
  788. 1:
  789. rttilist^.concat(new(pai_const,init_8bit(otUByte)));
  790. 2:
  791. rttilist^.concat(new(pai_const,init_8bit(otUWord)));
  792. 4:
  793. rttilist^.concat(new(pai_const,init_8bit(otULong)));
  794. end;
  795. rttilist^.concat(new(pai_const,init_32bit(min)));
  796. rttilist^.concat(new(pai_const,init_32bit(max)));
  797. if assigned(basedef) then
  798. rttilist^.concat(new(pai_const_symbol,initname(basedef^.get_rtti_label)))
  799. else
  800. rttilist^.concat(new(pai_const,init_32bit(0)));
  801. hp:=firstenum;
  802. while assigned(hp) do
  803. begin
  804. rttilist^.concat(new(pai_const,init_8bit(length(hp^.name))));
  805. rttilist^.concat(new(pai_string,init(globals.lower(hp^.name))));
  806. hp:=hp^.nextenum;
  807. end;
  808. rttilist^.concat(new(pai_const,init_8bit(0)));
  809. end;
  810. function tenumdef.is_publishable : boolean;
  811. begin
  812. is_publishable:=true;
  813. end;
  814. function tenumdef.gettypename : string;
  815. begin
  816. gettypename:='<enumeration type>';
  817. end;
  818. {****************************************************************************
  819. TORDDEF
  820. ****************************************************************************}
  821. constructor torddef.init(t : tbasetype;v,b : longint);
  822. begin
  823. inherited init;
  824. deftype:=orddef;
  825. low:=v;
  826. high:=b;
  827. typ:=t;
  828. rangenr:=0;
  829. setsize;
  830. end;
  831. constructor torddef.load;
  832. begin
  833. inherited load;
  834. deftype:=orddef;
  835. typ:=tbasetype(readbyte);
  836. low:=readlong;
  837. high:=readlong;
  838. rangenr:=0;
  839. setsize;
  840. end;
  841. procedure torddef.setsize;
  842. begin
  843. if typ=uauto then
  844. begin
  845. { generate a unsigned range if high<0 and low>=0 }
  846. if (low>=0) and (high<0) then
  847. begin
  848. savesize:=4;
  849. typ:=u32bit;
  850. end
  851. else if (low>=0) and (high<=255) then
  852. begin
  853. savesize:=1;
  854. typ:=u8bit;
  855. end
  856. else if (low>=-128) and (high<=127) then
  857. begin
  858. savesize:=1;
  859. typ:=s8bit;
  860. end
  861. else if (low>=0) and (high<=65536) then
  862. begin
  863. savesize:=2;
  864. typ:=u16bit;
  865. end
  866. else if (low>=-32768) and (high<=32767) then
  867. begin
  868. savesize:=2;
  869. typ:=s16bit;
  870. end
  871. else
  872. begin
  873. savesize:=4;
  874. typ:=s32bit;
  875. end;
  876. end
  877. else
  878. begin
  879. case typ of
  880. u8bit,s8bit,
  881. uchar,bool8bit:
  882. savesize:=1;
  883. u16bit,s16bit,
  884. bool16bit,uwidechar:
  885. savesize:=2;
  886. s32bit,u32bit,
  887. bool32bit:
  888. savesize:=4;
  889. u64bit,s64bit:
  890. savesize:=8;
  891. else
  892. savesize:=0;
  893. end;
  894. end;
  895. { there are no entrys for range checking }
  896. rangenr:=0;
  897. end;
  898. function torddef.getrangecheckstring : string;
  899. begin
  900. if (cs_create_smart in aktmoduleswitches) then
  901. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  902. else
  903. getrangecheckstring:='R_'+tostr(rangenr);
  904. end;
  905. procedure torddef.genrangecheck;
  906. var
  907. rangechecksize : longint;
  908. begin
  909. if rangenr=0 then
  910. begin
  911. if low<=high then
  912. rangechecksize:=8
  913. else
  914. rangechecksize:=16;
  915. { generate two constant for bounds }
  916. getlabelnr(rangenr);
  917. if (cs_create_smart in aktmoduleswitches) then
  918. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,rangechecksize)))
  919. else
  920. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,rangechecksize)));
  921. if low<=high then
  922. begin
  923. datasegment^.concat(new(pai_const,init_32bit(low)));
  924. datasegment^.concat(new(pai_const,init_32bit(high)));
  925. end
  926. { for u32bit we need two bounds }
  927. else
  928. begin
  929. datasegment^.concat(new(pai_const,init_32bit(low)));
  930. datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
  931. datasegment^.concat(new(pai_const,init_32bit($80000000)));
  932. datasegment^.concat(new(pai_const,init_32bit(high)));
  933. end;
  934. end;
  935. end;
  936. procedure torddef.write;
  937. begin
  938. tdef.write;
  939. writebyte(byte(typ));
  940. writelong(low);
  941. writelong(high);
  942. current_ppu^.writeentry(iborddef);
  943. end;
  944. {$ifdef GDB}
  945. function torddef.stabstring : pchar;
  946. begin
  947. case typ of
  948. uvoid : stabstring := strpnew(numberstring+';');
  949. {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
  950. {$ifdef Use_integer_types_for_boolean}
  951. bool8bit,
  952. bool16bit,
  953. bool32bit : stabstring := strpnew('r'+numberstring+';0;255;');
  954. {$else : not Use_integer_types_for_boolean}
  955. bool8bit : stabstring := strpnew('-21;');
  956. bool16bit : stabstring := strpnew('-22;');
  957. bool32bit : stabstring := strpnew('-23;');
  958. u64bit : stabstring := strpnew('-32;');
  959. s64bit : stabstring := strpnew('-31;');
  960. {$endif not Use_integer_types_for_boolean}
  961. { u32bit : stabstring := strpnew('r'+
  962. s32bitdef^.numberstring+';0;-1;'); }
  963. else
  964. stabstring := strpnew('r'+s32bitdef^.numberstring+';'+tostr(low)+';'+tostr(high)+';');
  965. end;
  966. end;
  967. {$endif GDB}
  968. procedure torddef.write_rtti_data;
  969. procedure dointeger;
  970. const
  971. trans : array[uchar..bool8bit] of byte =
  972. (otUByte,otUByte,otUWord,otULong,otSByte,otSWord,otSLong,otUByte);
  973. begin
  974. write_rtti_name;
  975. rttilist^.concat(new(pai_const,init_8bit(byte(trans[typ]))));
  976. rttilist^.concat(new(pai_const,init_32bit(low)));
  977. rttilist^.concat(new(pai_const,init_32bit(high)));
  978. end;
  979. begin
  980. case typ of
  981. s64bit :
  982. begin
  983. rttilist^.concat(new(pai_const,init_8bit(tkInt64)));
  984. write_rtti_name;
  985. { low }
  986. rttilist^.concat(new(pai_const,init_32bit($0)));
  987. rttilist^.concat(new(pai_const,init_32bit($8000)));
  988. { high }
  989. rttilist^.concat(new(pai_const,init_32bit($ffff)));
  990. rttilist^.concat(new(pai_const,init_32bit($7fff)));
  991. end;
  992. u64bit :
  993. begin
  994. rttilist^.concat(new(pai_const,init_8bit(tkQWord)));
  995. write_rtti_name;
  996. { low }
  997. rttilist^.concat(new(pai_const,init_32bit($0)));
  998. rttilist^.concat(new(pai_const,init_32bit($0)));
  999. { high }
  1000. rttilist^.concat(new(pai_const,init_32bit($0)));
  1001. rttilist^.concat(new(pai_const,init_32bit($8000)));
  1002. end;
  1003. bool8bit:
  1004. begin
  1005. rttilist^.concat(new(pai_const,init_8bit(tkBool)));
  1006. dointeger;
  1007. end;
  1008. uchar:
  1009. begin
  1010. rttilist^.concat(new(pai_const,init_8bit(tkWChar)));
  1011. dointeger;
  1012. end;
  1013. uwidechar:
  1014. begin
  1015. rttilist^.concat(new(pai_const,init_8bit(tkChar)));
  1016. dointeger;
  1017. end;
  1018. else
  1019. begin
  1020. rttilist^.concat(new(pai_const,init_8bit(tkInteger)));
  1021. dointeger;
  1022. end;
  1023. end;
  1024. end;
  1025. function torddef.is_publishable : boolean;
  1026. begin
  1027. is_publishable:=typ in [uchar..bool8bit];
  1028. end;
  1029. function torddef.gettypename : string;
  1030. const
  1031. names : array[tbasetype] of string[20] = ('<unknown type>',
  1032. 'untyped','Char','Byte','Word','DWord','ShortInt',
  1033. 'SmallInt','LongInt','Boolean','WordBool',
  1034. 'LongBool','QWord','Int64','WideChar');
  1035. begin
  1036. gettypename:=names[typ];
  1037. end;
  1038. {****************************************************************************
  1039. TFLOATDEF
  1040. ****************************************************************************}
  1041. constructor tfloatdef.init(t : tfloattype);
  1042. begin
  1043. inherited init;
  1044. deftype:=floatdef;
  1045. typ:=t;
  1046. setsize;
  1047. end;
  1048. constructor tfloatdef.load;
  1049. begin
  1050. inherited load;
  1051. deftype:=floatdef;
  1052. typ:=tfloattype(readbyte);
  1053. setsize;
  1054. end;
  1055. procedure tfloatdef.setsize;
  1056. begin
  1057. case typ of
  1058. f16bit : savesize:=2;
  1059. f32bit,
  1060. s32real : savesize:=4;
  1061. s64real : savesize:=8;
  1062. s80real : savesize:=extended_size;
  1063. s64comp : savesize:=8;
  1064. else
  1065. savesize:=0;
  1066. end;
  1067. end;
  1068. procedure tfloatdef.write;
  1069. begin
  1070. inherited write;
  1071. writebyte(byte(typ));
  1072. current_ppu^.writeentry(ibfloatdef);
  1073. end;
  1074. {$ifdef GDB}
  1075. function tfloatdef.stabstring : pchar;
  1076. begin
  1077. case typ of
  1078. s32real,
  1079. s64real : stabstring := strpnew('r'+
  1080. s32bitdef^.numberstring+';'+tostr(savesize)+';0;');
  1081. { for fixed real use longint instead to be able to }
  1082. { debug something at least }
  1083. f32bit:
  1084. stabstring := s32bitdef^.stabstring;
  1085. f16bit:
  1086. stabstring := strpnew('r'+s32bitdef^.numberstring+';0;'+
  1087. tostr($ffff)+';');
  1088. { found this solution in stabsread.c from GDB v4.16 }
  1089. s64comp : stabstring := strpnew('r'+
  1090. s32bitdef^.numberstring+';-'+tostr(savesize)+';0;');
  1091. {$ifdef i386}
  1092. { under dos at least you must give a size of twelve instead of 10 !! }
  1093. { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
  1094. s80real : stabstring := strpnew('r'+s32bitdef^.numberstring+';12;0;');
  1095. {$endif i386}
  1096. else
  1097. internalerror(10005);
  1098. end;
  1099. end;
  1100. {$endif GDB}
  1101. procedure tfloatdef.write_rtti_data;
  1102. const
  1103. {tfloattype = (s32real,s64real,s80real,s64bit,f16bit,f32bit);}
  1104. translate : array[tfloattype] of byte =
  1105. (ftSingle,ftDouble,ftExtended,ftComp,ftFixed16,ftFixed32);
  1106. begin
  1107. rttilist^.concat(new(pai_const,init_8bit(tkFloat)));
  1108. write_rtti_name;
  1109. rttilist^.concat(new(pai_const,init_8bit(translate[typ])));
  1110. end;
  1111. function tfloatdef.is_publishable : boolean;
  1112. begin
  1113. is_publishable:=true;
  1114. end;
  1115. function tfloatdef.gettypename : string;
  1116. const
  1117. names : array[tfloattype] of string[20] = (
  1118. 'Single','Double','Extended','Comp','Fixed','Fixed16');
  1119. begin
  1120. gettypename:=names[typ];
  1121. end;
  1122. {****************************************************************************
  1123. TFILEDEF
  1124. ****************************************************************************}
  1125. constructor tfiledef.inittext;
  1126. begin
  1127. inherited init;
  1128. deftype:=filedef;
  1129. filetyp:=ft_text;
  1130. typedfiletype.reset;
  1131. setsize;
  1132. end;
  1133. constructor tfiledef.inituntyped;
  1134. begin
  1135. inherited init;
  1136. deftype:=filedef;
  1137. filetyp:=ft_untyped;
  1138. typedfiletype.reset;
  1139. setsize;
  1140. end;
  1141. constructor tfiledef.inittyped(const tt : ttype);
  1142. begin
  1143. inherited init;
  1144. deftype:=filedef;
  1145. filetyp:=ft_typed;
  1146. typedfiletype:=tt;
  1147. setsize;
  1148. end;
  1149. constructor tfiledef.inittypeddef(p : pdef);
  1150. begin
  1151. inherited init;
  1152. deftype:=filedef;
  1153. filetyp:=ft_typed;
  1154. typedfiletype.setdef(p);
  1155. setsize;
  1156. end;
  1157. constructor tfiledef.load;
  1158. begin
  1159. inherited load;
  1160. deftype:=filedef;
  1161. filetyp:=tfiletyp(readbyte);
  1162. if filetyp=ft_typed then
  1163. typedfiletype.load
  1164. else
  1165. typedfiletype.reset;
  1166. setsize;
  1167. end;
  1168. procedure tfiledef.deref;
  1169. begin
  1170. inherited deref;
  1171. if filetyp=ft_typed then
  1172. typedfiletype.resolve;
  1173. end;
  1174. procedure tfiledef.setsize;
  1175. begin
  1176. case filetyp of
  1177. ft_text :
  1178. savesize:=572;
  1179. ft_typed,
  1180. ft_untyped :
  1181. savesize:=316;
  1182. end;
  1183. end;
  1184. procedure tfiledef.write;
  1185. begin
  1186. inherited write;
  1187. writebyte(byte(filetyp));
  1188. if filetyp=ft_typed then
  1189. typedfiletype.write;
  1190. current_ppu^.writeentry(ibfiledef);
  1191. end;
  1192. {$ifdef GDB}
  1193. function tfiledef.stabstring : pchar;
  1194. begin
  1195. {$IfDef GDBknowsfiles}
  1196. case filetyp of
  1197. ft_typed :
  1198. stabstring := strpnew('d'+typedfiletype.def^.numberstring{+';'});
  1199. ft_untyped :
  1200. stabstring := strpnew('d'+voiddef^.numberstring{+';'});
  1201. ft_text :
  1202. stabstring := strpnew('d'+cchardef^.numberstring{+';'});
  1203. end;
  1204. {$Else}
  1205. {based on
  1206. FileRec = Packed Record
  1207. Handle,
  1208. Mode,
  1209. RecSize : longint;
  1210. _private : array[1..32] of byte;
  1211. UserData : array[1..16] of byte;
  1212. name : array[0..255] of char;
  1213. End; }
  1214. { the buffer part is still missing !! (PM) }
  1215. { but the string could become too long !! }
  1216. stabstring := strpnew('s'+tostr(savesize)+
  1217. 'HANDLE:'+typeglobalnumber('longint')+',0,32;'+
  1218. 'MODE:'+typeglobalnumber('longint')+',32,32;'+
  1219. 'RECSIZE:'+typeglobalnumber('longint')+',64,32;'+
  1220. '_PRIVATE:ar'+typeglobalnumber('word')+';1;32;'+typeglobalnumber('byte')
  1221. +',96,256;'+
  1222. 'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')
  1223. +',352,128;'+
  1224. 'NAME:ar'+typeglobalnumber('word')+';0;255;'+typeglobalnumber('char')
  1225. +',480,2048;;');
  1226. {$EndIf}
  1227. end;
  1228. procedure tfiledef.concatstabto(asmlist : paasmoutput);
  1229. begin
  1230. { most file defs are unnamed !!! }
  1231. if ((typesym = nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1232. not is_def_stab_written then
  1233. begin
  1234. if assigned(typedfiletype.def) then forcestabto(asmlist,typedfiletype.def);
  1235. inherited concatstabto(asmlist);
  1236. end;
  1237. end;
  1238. {$endif GDB}
  1239. function tfiledef.gettypename : string;
  1240. begin
  1241. case filetyp of
  1242. ft_untyped:
  1243. gettypename:='File';
  1244. ft_typed:
  1245. gettypename:='File Of '+typedfiletype.def^.typename;
  1246. ft_text:
  1247. gettypename:='Text'
  1248. end;
  1249. end;
  1250. {****************************************************************************
  1251. TPOINTERDEF
  1252. ****************************************************************************}
  1253. constructor tpointerdef.init(const tt : ttype);
  1254. begin
  1255. tdef.init;
  1256. deftype:=pointerdef;
  1257. pointertype:=tt;
  1258. is_far:=false;
  1259. savesize:=target_os.size_of_pointer;
  1260. end;
  1261. constructor tpointerdef.initfar(const tt : ttype);
  1262. begin
  1263. tdef.init;
  1264. deftype:=pointerdef;
  1265. pointertype:=tt;
  1266. is_far:=true;
  1267. savesize:=target_os.size_of_pointer;
  1268. end;
  1269. constructor tpointerdef.initdef(p : pdef);
  1270. var
  1271. t : ttype;
  1272. begin
  1273. t.setdef(p);
  1274. tpointerdef.init(t);
  1275. end;
  1276. constructor tpointerdef.initfardef(p : pdef);
  1277. var
  1278. t : ttype;
  1279. begin
  1280. t.setdef(p);
  1281. tpointerdef.initfar(t);
  1282. end;
  1283. constructor tpointerdef.load;
  1284. begin
  1285. tdef.load;
  1286. deftype:=pointerdef;
  1287. pointertype.load;
  1288. is_far:=(readbyte<>0);
  1289. savesize:=target_os.size_of_pointer;
  1290. end;
  1291. destructor tpointerdef.done;
  1292. begin
  1293. if assigned(pointertype.def) and
  1294. (pointertype.def^.deftype=forwarddef) then
  1295. begin
  1296. dispose(pointertype.def,done);
  1297. pointertype.reset;
  1298. end;
  1299. inherited done;
  1300. end;
  1301. procedure tpointerdef.deref;
  1302. begin
  1303. inherited deref;
  1304. pointertype.resolve;
  1305. end;
  1306. procedure tpointerdef.write;
  1307. begin
  1308. inherited write;
  1309. pointertype.write;
  1310. writebyte(byte(is_far));
  1311. current_ppu^.writeentry(ibpointerdef);
  1312. end;
  1313. {$ifdef GDB}
  1314. function tpointerdef.stabstring : pchar;
  1315. begin
  1316. stabstring := strpnew('*'+pointertype.def^.numberstring);
  1317. end;
  1318. procedure tpointerdef.concatstabto(asmlist : paasmoutput);
  1319. var st,nb : string;
  1320. sym_line_no : longint;
  1321. begin
  1322. if assigned(pointertype.def) and
  1323. (pointertype.def^.deftype=forwarddef) then
  1324. exit;
  1325. if ( (typesym=nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1326. not is_def_stab_written then
  1327. begin
  1328. if assigned(pointertype.def) then
  1329. if pointertype.def^.deftype in [recorddef,objectdef] then
  1330. begin
  1331. is_def_stab_written := true;
  1332. nb:=pointertype.def^.numberstring;
  1333. {to avoid infinite recursion in record with next-like fields }
  1334. is_def_stab_written := false;
  1335. if not pointertype.def^.is_def_stab_written then
  1336. begin
  1337. if assigned(pointertype.def^.typesym) then
  1338. begin
  1339. if assigned(typesym) then
  1340. begin
  1341. st := typesym^.name;
  1342. sym_line_no:=typesym^.fileinfo.line;
  1343. end
  1344. else
  1345. begin
  1346. st := ' ';
  1347. sym_line_no:=0;
  1348. end;
  1349. st := '"'+st+':t'+numberstring+'=*'+nb
  1350. +'=xs'+pointertype.def^.typesym^.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
  1351. asmlist^.concat(new(pai_stabs,init(strpnew(st))));
  1352. end;
  1353. end else inherited concatstabto(asmlist);
  1354. is_def_stab_written := true;
  1355. end else
  1356. begin
  1357. { p =^p1; p1=^p problem }
  1358. is_def_stab_written := true;
  1359. forcestabto(asmlist,pointertype.def);
  1360. is_def_stab_written := false;
  1361. inherited concatstabto(asmlist);
  1362. end;
  1363. end;
  1364. end;
  1365. {$endif GDB}
  1366. function tpointerdef.gettypename : string;
  1367. begin
  1368. gettypename:='^'+pointertype.def^.typename;
  1369. end;
  1370. {****************************************************************************
  1371. TCLASSREFDEF
  1372. ****************************************************************************}
  1373. constructor tclassrefdef.init(def : pdef);
  1374. begin
  1375. inherited initdef(def);
  1376. deftype:=classrefdef;
  1377. end;
  1378. constructor tclassrefdef.load;
  1379. begin
  1380. { be careful, tclassdefref inherits from tpointerdef }
  1381. tdef.load;
  1382. deftype:=classrefdef;
  1383. pointertype.load;
  1384. is_far:=false;
  1385. savesize:=target_os.size_of_pointer;
  1386. end;
  1387. procedure tclassrefdef.write;
  1388. begin
  1389. { be careful, tclassdefref inherits from tpointerdef }
  1390. tdef.write;
  1391. pointertype.write;
  1392. current_ppu^.writeentry(ibclassrefdef);
  1393. end;
  1394. {$ifdef GDB}
  1395. function tclassrefdef.stabstring : pchar;
  1396. begin
  1397. stabstring:=strpnew(pvmtdef^.numberstring+';');
  1398. end;
  1399. procedure tclassrefdef.concatstabto(asmlist : paasmoutput);
  1400. begin
  1401. inherited concatstabto(asmlist);
  1402. end;
  1403. {$endif GDB}
  1404. function tclassrefdef.gettypename : string;
  1405. begin
  1406. gettypename:='Class Of '+pointertype.def^.typename;
  1407. end;
  1408. {***************************************************************************
  1409. TSETDEF
  1410. ***************************************************************************}
  1411. { For i386 smallsets work,
  1412. for m68k there are problems
  1413. can be test by compiling with -dusesmallset PM }
  1414. {$ifdef i386}
  1415. {$define usesmallset}
  1416. {$endif i386}
  1417. constructor tsetdef.init(s : pdef;high : longint);
  1418. begin
  1419. inherited init;
  1420. deftype:=setdef;
  1421. elementtype.setdef(s);
  1422. {$ifdef usesmallset}
  1423. { small sets only working for i386 PM }
  1424. if high<32 then
  1425. begin
  1426. settype:=smallset;
  1427. {$ifdef testvarsets}
  1428. if aktsetalloc=0 THEN { $PACKSET Fixed?}
  1429. {$endif}
  1430. savesize:=Sizeof(longint)
  1431. {$ifdef testvarsets}
  1432. else {No, use $PACKSET VALUE for rounding}
  1433. savesize:=aktsetalloc*((high+aktsetalloc*8-1) DIV (aktsetalloc*8))
  1434. {$endif}
  1435. ;
  1436. end
  1437. else
  1438. {$endif usesmallset}
  1439. if high<256 then
  1440. begin
  1441. settype:=normset;
  1442. savesize:=32;
  1443. end
  1444. else
  1445. {$ifdef testvarsets}
  1446. if high<$10000 then
  1447. begin
  1448. settype:=varset;
  1449. savesize:=4*((high+31) div 32);
  1450. end
  1451. else
  1452. {$endif testvarsets}
  1453. Message(sym_e_ill_type_decl_set);
  1454. end;
  1455. constructor tsetdef.load;
  1456. begin
  1457. inherited load;
  1458. deftype:=setdef;
  1459. elementtype.load;
  1460. settype:=tsettype(readbyte);
  1461. case settype of
  1462. normset : savesize:=32;
  1463. varset : savesize:=readlong;
  1464. smallset : savesize:=Sizeof(longint);
  1465. end;
  1466. end;
  1467. destructor tsetdef.done;
  1468. begin
  1469. inherited done;
  1470. end;
  1471. procedure tsetdef.write;
  1472. begin
  1473. inherited write;
  1474. elementtype.write;
  1475. writebyte(byte(settype));
  1476. if settype=varset then
  1477. writelong(savesize);
  1478. current_ppu^.writeentry(ibsetdef);
  1479. end;
  1480. {$ifdef GDB}
  1481. function tsetdef.stabstring : pchar;
  1482. begin
  1483. { For small sets write a longint, which can at least be seen
  1484. in the current GDB's (PFV)
  1485. this is obsolete with GDBPAS !!
  1486. and anyhow creates problems with version 4.18!! PM
  1487. if settype=smallset then
  1488. stabstring := strpnew('r'+s32bitdef^.numberstring+';0;0xffffffff;')
  1489. else }
  1490. stabstring := strpnew('S'+elementtype.def^.numberstring);
  1491. end;
  1492. procedure tsetdef.concatstabto(asmlist : paasmoutput);
  1493. begin
  1494. if ( not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1495. not is_def_stab_written then
  1496. begin
  1497. if assigned(elementtype.def) then
  1498. forcestabto(asmlist,elementtype.def);
  1499. inherited concatstabto(asmlist);
  1500. end;
  1501. end;
  1502. {$endif GDB}
  1503. procedure tsetdef.deref;
  1504. begin
  1505. inherited deref;
  1506. elementtype.resolve;
  1507. end;
  1508. procedure tsetdef.write_rtti_data;
  1509. begin
  1510. rttilist^.concat(new(pai_const,init_8bit(tkSet)));
  1511. write_rtti_name;
  1512. rttilist^.concat(new(pai_const,init_8bit(otULong)));
  1513. rttilist^.concat(new(pai_const_symbol,initname(elementtype.def^.get_rtti_label)));
  1514. end;
  1515. procedure tsetdef.write_child_rtti_data;
  1516. begin
  1517. elementtype.def^.get_rtti_label;
  1518. end;
  1519. function tsetdef.is_publishable : boolean;
  1520. begin
  1521. is_publishable:=settype=smallset;
  1522. end;
  1523. function tsetdef.gettypename : string;
  1524. begin
  1525. if assigned(elementtype.def) then
  1526. gettypename:='Set Of '+elementtype.def^.typename
  1527. else
  1528. gettypename:='Empty Set';
  1529. end;
  1530. {***************************************************************************
  1531. TFORMALDEF
  1532. ***************************************************************************}
  1533. constructor tformaldef.init;
  1534. var
  1535. stregdef : boolean;
  1536. begin
  1537. stregdef:=registerdef;
  1538. registerdef:=false;
  1539. inherited init;
  1540. deftype:=formaldef;
  1541. registerdef:=stregdef;
  1542. { formaldef must be registered at unit level !! }
  1543. if registerdef and assigned(current_module) then
  1544. if assigned(current_module^.localsymtable) then
  1545. psymtable(current_module^.localsymtable)^.registerdef(@self)
  1546. else if assigned(current_module^.globalsymtable) then
  1547. psymtable(current_module^.globalsymtable)^.registerdef(@self);
  1548. savesize:=target_os.size_of_pointer;
  1549. end;
  1550. constructor tformaldef.load;
  1551. begin
  1552. inherited load;
  1553. deftype:=formaldef;
  1554. savesize:=target_os.size_of_pointer;
  1555. end;
  1556. procedure tformaldef.write;
  1557. begin
  1558. inherited write;
  1559. current_ppu^.writeentry(ibformaldef);
  1560. end;
  1561. {$ifdef GDB}
  1562. function tformaldef.stabstring : pchar;
  1563. begin
  1564. stabstring := strpnew('formal'+numberstring+';');
  1565. end;
  1566. procedure tformaldef.concatstabto(asmlist : paasmoutput);
  1567. begin
  1568. { formaldef can't be stab'ed !}
  1569. end;
  1570. {$endif GDB}
  1571. function tformaldef.gettypename : string;
  1572. begin
  1573. gettypename:='Var';
  1574. end;
  1575. {***************************************************************************
  1576. TARRAYDEF
  1577. ***************************************************************************}
  1578. constructor tarraydef.init(l,h : longint;rd : pdef);
  1579. begin
  1580. inherited init;
  1581. deftype:=arraydef;
  1582. lowrange:=l;
  1583. highrange:=h;
  1584. rangetype.setdef(rd);
  1585. elementtype.reset;
  1586. IsVariant:=false;
  1587. IsConstructor:=false;
  1588. IsArrayOfConst:=false;
  1589. rangenr:=0;
  1590. end;
  1591. constructor tarraydef.load;
  1592. begin
  1593. inherited load;
  1594. deftype:=arraydef;
  1595. { the addresses are calculated later }
  1596. elementtype.load;
  1597. rangetype.load;
  1598. lowrange:=readlong;
  1599. highrange:=readlong;
  1600. IsArrayOfConst:=boolean(readbyte);
  1601. IsVariant:=false;
  1602. IsConstructor:=false;
  1603. rangenr:=0;
  1604. end;
  1605. function tarraydef.getrangecheckstring : string;
  1606. begin
  1607. if (cs_create_smart in aktmoduleswitches) then
  1608. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  1609. else
  1610. getrangecheckstring:='R_'+tostr(rangenr);
  1611. end;
  1612. procedure tarraydef.genrangecheck;
  1613. begin
  1614. if rangenr=0 then
  1615. begin
  1616. { generates the data for range checking }
  1617. getlabelnr(rangenr);
  1618. if (cs_create_smart in aktmoduleswitches) then
  1619. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,8)))
  1620. else
  1621. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,8)));
  1622. if lowrange<=highrange then
  1623. begin
  1624. datasegment^.concat(new(pai_const,init_32bit(lowrange)));
  1625. datasegment^.concat(new(pai_const,init_32bit(highrange)));
  1626. end
  1627. { for big arrays we need two bounds }
  1628. else
  1629. begin
  1630. datasegment^.concat(new(pai_const,init_32bit(lowrange)));
  1631. datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
  1632. datasegment^.concat(new(pai_const,init_32bit($80000000)));
  1633. datasegment^.concat(new(pai_const,init_32bit(highrange)));
  1634. end;
  1635. end;
  1636. end;
  1637. procedure tarraydef.deref;
  1638. begin
  1639. inherited deref;
  1640. elementtype.resolve;
  1641. rangetype.resolve;
  1642. end;
  1643. procedure tarraydef.write;
  1644. begin
  1645. inherited write;
  1646. elementtype.write;
  1647. rangetype.write;
  1648. writelong(lowrange);
  1649. writelong(highrange);
  1650. writebyte(byte(IsArrayOfConst));
  1651. current_ppu^.writeentry(ibarraydef);
  1652. end;
  1653. {$ifdef GDB}
  1654. function tarraydef.stabstring : pchar;
  1655. begin
  1656. stabstring := strpnew('ar'+rangetype.def^.numberstring+';'
  1657. +tostr(lowrange)+';'+tostr(highrange)+';'+elementtype.def^.numberstring);
  1658. end;
  1659. procedure tarraydef.concatstabto(asmlist : paasmoutput);
  1660. begin
  1661. if (not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  1662. and not is_def_stab_written then
  1663. begin
  1664. {when array are inserted they have no definition yet !!}
  1665. if assigned(elementtype.def) then
  1666. inherited concatstabto(asmlist);
  1667. end;
  1668. end;
  1669. {$endif GDB}
  1670. function tarraydef.elesize : longint;
  1671. begin
  1672. if isconstructor or is_open_array(@self) then
  1673. begin
  1674. { strings are stored by address only }
  1675. case elementtype.def^.deftype of
  1676. stringdef :
  1677. elesize:=4;
  1678. else
  1679. elesize:=elementtype.def^.size;
  1680. end;
  1681. end
  1682. else
  1683. elesize:=elementtype.def^.size;
  1684. end;
  1685. function tarraydef.size : longint;
  1686. begin
  1687. {Tarraydef.size may never be called for an open array!}
  1688. if highrange<lowrange then
  1689. internalerror(99080501);
  1690. If (elesize>0) and
  1691. (
  1692. (highrange-lowrange = $7fffffff) or
  1693. { () are needed around elesize-1 to avoid a possible
  1694. integer overflow for elesize=1 !! PM }
  1695. (($7fffffff div elesize + (elesize -1)) < (highrange - lowrange))
  1696. ) Then
  1697. Begin
  1698. Message(sym_e_segment_too_large);
  1699. size := 4
  1700. End
  1701. Else size:=(highrange-lowrange+1)*elesize;
  1702. end;
  1703. function tarraydef.alignment : longint;
  1704. begin
  1705. { alignment is the size of the elements }
  1706. alignment:=elesize;
  1707. end;
  1708. function tarraydef.needs_inittable : boolean;
  1709. begin
  1710. needs_inittable:=elementtype.def^.needs_inittable;
  1711. end;
  1712. procedure tarraydef.write_child_rtti_data;
  1713. begin
  1714. elementtype.def^.get_rtti_label;
  1715. end;
  1716. procedure tarraydef.write_rtti_data;
  1717. begin
  1718. rttilist^.concat(new(pai_const,init_8bit(tkarray)));
  1719. write_rtti_name;
  1720. { size of elements }
  1721. rttilist^.concat(new(pai_const,init_32bit(elesize)));
  1722. { count of elements }
  1723. rttilist^.concat(new(pai_const,init_32bit(highrange-lowrange+1)));
  1724. { element type }
  1725. rttilist^.concat(new(pai_const_symbol,initname(elementtype.def^.get_rtti_label)));
  1726. end;
  1727. function tarraydef.gettypename : string;
  1728. begin
  1729. if isarrayofconst or isConstructor then
  1730. begin
  1731. if isvariant then
  1732. gettypename:='Array Of Const'
  1733. else
  1734. gettypename:='Array Of '+elementtype.def^.typename;
  1735. end
  1736. else if is_open_array(@self) then
  1737. gettypename:='Array Of '+elementtype.def^.typename
  1738. else
  1739. begin
  1740. if rangetype.def^.deftype=enumdef then
  1741. gettypename:='Array['+rangetype.def^.typename+'] Of '+elementtype.def^.typename
  1742. else
  1743. gettypename:='Array['+tostr(lowrange)+'..'+
  1744. tostr(highrange)+'] Of '+elementtype.def^.typename
  1745. end;
  1746. end;
  1747. {***************************************************************************
  1748. trecorddef
  1749. ***************************************************************************}
  1750. constructor trecorddef.init(p : psymtable);
  1751. begin
  1752. inherited init;
  1753. deftype:=recorddef;
  1754. symtable:=p;
  1755. symtable^.defowner := @self;
  1756. symtable^.dataalignment:=packrecordalignment[aktpackrecords];
  1757. end;
  1758. constructor trecorddef.load;
  1759. var
  1760. oldread_member : boolean;
  1761. begin
  1762. inherited load;
  1763. deftype:=recorddef;
  1764. savesize:=readlong;
  1765. oldread_member:=read_member;
  1766. read_member:=true;
  1767. symtable:=new(psymtable,loadas(recordsymtable));
  1768. read_member:=oldread_member;
  1769. symtable^.defowner := @self;
  1770. end;
  1771. destructor trecorddef.done;
  1772. begin
  1773. if assigned(symtable) then
  1774. dispose(symtable,done);
  1775. inherited done;
  1776. end;
  1777. var
  1778. binittable : boolean;
  1779. procedure check_rec_inittable(s : pnamedindexobject);
  1780. begin
  1781. if (not binittable) and
  1782. (psym(s)^.typ=varsym) and
  1783. assigned(pvarsym(s)^.vartype.def) then
  1784. begin
  1785. if ((pvarsym(s)^.vartype.def^.deftype<>objectdef) or
  1786. not(pobjectdef(pvarsym(s)^.vartype.def)^.is_class)) then
  1787. binittable:=pvarsym(s)^.vartype.def^.needs_inittable;
  1788. end;
  1789. end;
  1790. function trecorddef.needs_inittable : boolean;
  1791. var
  1792. oldb : boolean;
  1793. begin
  1794. { there are recursive calls to needs_rtti possible, }
  1795. { so we have to change to old value how else should }
  1796. { we do that ? check_rec_rtti can't be a nested }
  1797. { procedure of needs_rtti ! }
  1798. oldb:=binittable;
  1799. binittable:=false;
  1800. symtable^.foreach({$ifndef TP}@{$endif}check_rec_inittable);
  1801. needs_inittable:=binittable;
  1802. binittable:=oldb;
  1803. end;
  1804. procedure trecorddef.deref;
  1805. var
  1806. oldrecsyms : psymtable;
  1807. begin
  1808. inherited deref;
  1809. oldrecsyms:=aktrecordsymtable;
  1810. aktrecordsymtable:=symtable;
  1811. { now dereference the definitions }
  1812. symtable^.deref;
  1813. aktrecordsymtable:=oldrecsyms;
  1814. end;
  1815. procedure trecorddef.write;
  1816. var
  1817. oldread_member : boolean;
  1818. begin
  1819. oldread_member:=read_member;
  1820. read_member:=true;
  1821. inherited write;
  1822. writelong(savesize);
  1823. current_ppu^.writeentry(ibrecorddef);
  1824. self.symtable^.writeas;
  1825. read_member:=oldread_member;
  1826. end;
  1827. function trecorddef.size:longint;
  1828. begin
  1829. size:=symtable^.datasize;
  1830. end;
  1831. function trecorddef.alignment:longint;
  1832. var
  1833. l : longint;
  1834. hp : pvarsym;
  1835. begin
  1836. { also check the first symbol for it's size, because a
  1837. packed record has dataalignment of 1, but the first
  1838. sym could be a longint which should be aligned on 4 bytes,
  1839. this is compatible with C record packing (PFV) }
  1840. hp:=pvarsym(symtable^.symindex^.first);
  1841. if assigned(hp) then
  1842. begin
  1843. l:=hp^.vartype.def^.size;
  1844. if l>symtable^.dataalignment then
  1845. begin
  1846. if l>=4 then
  1847. alignment:=4
  1848. else
  1849. if l>=2 then
  1850. alignment:=2
  1851. else
  1852. alignment:=1;
  1853. end
  1854. else
  1855. alignment:=symtable^.dataalignment;
  1856. end
  1857. else
  1858. alignment:=symtable^.dataalignment;
  1859. end;
  1860. {$ifdef GDB}
  1861. Const StabRecString : pchar = Nil;
  1862. StabRecSize : longint = 0;
  1863. RecOffset : Longint = 0;
  1864. procedure addname(p : pnamedindexobject);
  1865. var
  1866. news, newrec : pchar;
  1867. spec : string[3];
  1868. size : longint;
  1869. begin
  1870. { static variables from objects are like global objects }
  1871. if (sp_static in psym(p)^.symoptions) then
  1872. exit;
  1873. If psym(p)^.typ = varsym then
  1874. begin
  1875. if (sp_protected in psym(p)^.symoptions) then
  1876. spec:='/1'
  1877. else if (sp_private in psym(p)^.symoptions) then
  1878. spec:='/0'
  1879. else
  1880. spec:='';
  1881. { class fields are pointers PM }
  1882. if not assigned(pvarsym(p)^.vartype.def) then
  1883. writeln(pvarsym(p)^.name);
  1884. if (pvarsym(p)^.vartype.def^.deftype=objectdef) and
  1885. pobjectdef(pvarsym(p)^.vartype.def)^.is_class then
  1886. spec:=spec+'*';
  1887. size:=pvarsym(p)^.vartype.def^.size;
  1888. { open arrays made overflows !! }
  1889. if size>$fffffff then
  1890. size:=$fffffff;
  1891. newrec := strpnew(p^.name+':'+spec+pvarsym(p)^.vartype.def^.numberstring
  1892. +','+tostr(pvarsym(p)^.address*8)+','
  1893. +tostr(size*8)+';');
  1894. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  1895. begin
  1896. getmem(news,stabrecsize+memsizeinc);
  1897. strcopy(news,stabrecstring);
  1898. freemem(stabrecstring,stabrecsize);
  1899. stabrecsize:=stabrecsize+memsizeinc;
  1900. stabrecstring:=news;
  1901. end;
  1902. strcat(StabRecstring,newrec);
  1903. strdispose(newrec);
  1904. {This should be used for case !!}
  1905. RecOffset := RecOffset + pvarsym(p)^.vartype.def^.size;
  1906. end;
  1907. end;
  1908. function trecorddef.stabstring : pchar;
  1909. Var oldrec : pchar;
  1910. oldsize : longint;
  1911. begin
  1912. oldrec := stabrecstring;
  1913. oldsize:=stabrecsize;
  1914. GetMem(stabrecstring,memsizeinc);
  1915. stabrecsize:=memsizeinc;
  1916. strpcopy(stabRecString,'s'+tostr(size));
  1917. RecOffset := 0;
  1918. symtable^.foreach({$ifndef TP}@{$endif}addname);
  1919. { FPC doesn't want to convert a char to a pchar}
  1920. { is this a bug ? }
  1921. strpcopy(strend(StabRecString),';');
  1922. stabstring := strnew(StabRecString);
  1923. Freemem(stabrecstring,stabrecsize);
  1924. stabrecstring := oldrec;
  1925. stabrecsize:=oldsize;
  1926. end;
  1927. procedure trecorddef.concatstabto(asmlist : paasmoutput);
  1928. begin
  1929. if (not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1930. (not is_def_stab_written) then
  1931. inherited concatstabto(asmlist);
  1932. end;
  1933. {$endif GDB}
  1934. var
  1935. count : longint;
  1936. procedure count_inittable_fields(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1937. begin
  1938. if ((psym(sym)^.typ=varsym) and
  1939. pvarsym(sym)^.vartype.def^.needs_inittable)
  1940. and ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
  1941. (not pobjectdef(pvarsym(sym)^.vartype.def)^.is_class)) then
  1942. inc(count);
  1943. end;
  1944. procedure count_fields(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1945. begin
  1946. inc(count);
  1947. end;
  1948. procedure write_field_inittable(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1949. begin
  1950. if ((psym(sym)^.typ=varsym) and
  1951. pvarsym(sym)^.vartype.def^.needs_inittable) and
  1952. ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
  1953. (not pobjectdef(pvarsym(sym)^.vartype.def)^.is_class)) then
  1954. begin
  1955. rttilist^.concat(new(pai_const_symbol,init(pvarsym(sym)^.vartype.def^.get_inittable_label)));
  1956. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  1957. end;
  1958. end;
  1959. procedure write_field_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1960. begin
  1961. rttilist^.concat(new(pai_const_symbol,initname(pvarsym(sym)^.vartype.def^.get_rtti_label)));
  1962. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  1963. end;
  1964. procedure generate_child_inittable(sym:pnamedindexobject);{$ifndef fpc}far;{$endif}
  1965. begin
  1966. if (psym(sym)^.typ=varsym) and
  1967. pvarsym(sym)^.vartype.def^.needs_inittable then
  1968. { force inittable generation }
  1969. pvarsym(sym)^.vartype.def^.get_inittable_label;
  1970. end;
  1971. procedure generate_child_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1972. begin
  1973. pvarsym(sym)^.vartype.def^.get_rtti_label;
  1974. end;
  1975. procedure trecorddef.write_child_rtti_data;
  1976. begin
  1977. symtable^.foreach({$ifndef TP}@{$endif}generate_child_rtti);
  1978. end;
  1979. procedure trecorddef.write_child_init_data;
  1980. begin
  1981. symtable^.foreach({$ifndef TP}@{$endif}generate_child_inittable);
  1982. end;
  1983. procedure trecorddef.write_rtti_data;
  1984. begin
  1985. rttilist^.concat(new(pai_const,init_8bit(tkrecord)));
  1986. write_rtti_name;
  1987. rttilist^.concat(new(pai_const,init_32bit(size)));
  1988. count:=0;
  1989. symtable^.foreach({$ifndef TP}@{$endif}count_fields);
  1990. rttilist^.concat(new(pai_const,init_32bit(count)));
  1991. symtable^.foreach({$ifndef TP}@{$endif}write_field_rtti);
  1992. end;
  1993. procedure trecorddef.write_init_data;
  1994. begin
  1995. rttilist^.concat(new(pai_const,init_8bit(tkrecord)));
  1996. write_rtti_name;
  1997. rttilist^.concat(new(pai_const,init_32bit(size)));
  1998. count:=0;
  1999. symtable^.foreach({$ifndef TP}@{$endif}count_inittable_fields);
  2000. rttilist^.concat(new(pai_const,init_32bit(count)));
  2001. symtable^.foreach({$ifndef TP}@{$endif}write_field_inittable);
  2002. end;
  2003. function trecorddef.gettypename : string;
  2004. begin
  2005. gettypename:='<record type>'
  2006. end;
  2007. {***************************************************************************
  2008. TABSTRACTPROCDEF
  2009. ***************************************************************************}
  2010. constructor tabstractprocdef.init;
  2011. begin
  2012. inherited init;
  2013. new(para,init);
  2014. fpu_used:=0;
  2015. proctypeoption:=potype_none;
  2016. proccalloptions:=[];
  2017. procoptions:=[];
  2018. rettype.setdef(voiddef);
  2019. symtablelevel:=0;
  2020. savesize:=target_os.size_of_pointer;
  2021. end;
  2022. destructor tabstractprocdef.done;
  2023. begin
  2024. dispose(para,done);
  2025. inherited done;
  2026. end;
  2027. procedure tabstractprocdef.concatpara(tt:ttype;vsp : tvarspez);
  2028. var
  2029. hp : pparaitem;
  2030. begin
  2031. new(hp,init);
  2032. hp^.paratyp:=vsp;
  2033. hp^.paratype:=tt;
  2034. hp^.register:=R_NO;
  2035. para^.insert(hp);
  2036. end;
  2037. { all functions returning in FPU are
  2038. assume to use 2 FPU registers
  2039. until the function implementation
  2040. is processed PM }
  2041. procedure tabstractprocdef.test_if_fpu_result;
  2042. begin
  2043. if assigned(rettype.def) and is_fpu(rettype.def) then
  2044. fpu_used:=2;
  2045. end;
  2046. procedure tabstractprocdef.deref;
  2047. var
  2048. hp : pparaitem;
  2049. begin
  2050. inherited deref;
  2051. rettype.resolve;
  2052. hp:=pparaitem(para^.first);
  2053. while assigned(hp) do
  2054. begin
  2055. hp^.paratype.resolve;
  2056. hp:=pparaitem(hp^.next);
  2057. end;
  2058. end;
  2059. constructor tabstractprocdef.load;
  2060. var
  2061. hp : pparaitem;
  2062. count,i : word;
  2063. begin
  2064. inherited load;
  2065. new(para,init);
  2066. rettype.load;
  2067. fpu_used:=readbyte;
  2068. proctypeoption:=tproctypeoption(readlong);
  2069. readsmallset(proccalloptions);
  2070. readsmallset(procoptions);
  2071. count:=readword;
  2072. savesize:=target_os.size_of_pointer;
  2073. for i:=1 to count do
  2074. begin
  2075. new(hp,init);
  2076. hp^.paratyp:=tvarspez(readbyte);
  2077. { hp^.register:=tregister(readbyte); }
  2078. hp^.register:=R_NO;
  2079. hp^.paratype.load;
  2080. para^.concat(hp);
  2081. end;
  2082. end;
  2083. procedure tabstractprocdef.write;
  2084. var
  2085. hp : pparaitem;
  2086. begin
  2087. inherited write;
  2088. rettype.write;
  2089. current_ppu^.do_interface_crc:=false;
  2090. writebyte(fpu_used);
  2091. writelong(ord(proctypeoption));
  2092. writesmallset(proccalloptions);
  2093. writesmallset(procoptions);
  2094. writeword(para^.count);
  2095. hp:=pparaitem(para^.first);
  2096. while assigned(hp) do
  2097. begin
  2098. writebyte(byte(hp^.paratyp));
  2099. { writebyte(byte(hp^.register)); }
  2100. hp^.paratype.write;
  2101. hp:=pparaitem(hp^.next);
  2102. end;
  2103. end;
  2104. function tabstractprocdef.para_size(alignsize:longint) : longint;
  2105. var
  2106. pdc : pparaitem;
  2107. l : longint;
  2108. begin
  2109. l:=0;
  2110. pdc:=pparaitem(para^.first);
  2111. while assigned(pdc) do
  2112. begin
  2113. case pdc^.paratyp of
  2114. vs_var : inc(l,target_os.size_of_pointer);
  2115. vs_value,
  2116. vs_const : if push_addr_param(pdc^.paratype.def) then
  2117. inc(l,target_os.size_of_pointer)
  2118. else
  2119. inc(l,pdc^.paratype.def^.size);
  2120. end;
  2121. l:=align(l,alignsize);
  2122. pdc:=pparaitem(pdc^.next);
  2123. end;
  2124. para_size:=l;
  2125. end;
  2126. function tabstractprocdef.demangled_paras : string;
  2127. var
  2128. s : string;
  2129. hp : pparaitem;
  2130. begin
  2131. s:='(';
  2132. hp:=pparaitem(para^.last);
  2133. while assigned(hp) do
  2134. begin
  2135. if assigned(hp^.paratype.def^.typesym) then
  2136. s:=s+hp^.paratype.def^.typesym^.name
  2137. else if hp^.paratyp=vs_var then
  2138. s:=s+'var'
  2139. else if hp^.paratyp=vs_const then
  2140. s:=s+'const';
  2141. hp:=pparaitem(hp^.previous);
  2142. if assigned(hp) then
  2143. s:=s+',';
  2144. end;
  2145. s:=s+')';
  2146. demangled_paras:=s;
  2147. end;
  2148. function tabstractprocdef.proccalloption2str : string;
  2149. type
  2150. tproccallopt=record
  2151. mask : tproccalloption;
  2152. str : string[30];
  2153. end;
  2154. const
  2155. proccallopts=12;
  2156. proccallopt : array[1..proccallopts] of tproccallopt=(
  2157. (mask:pocall_none; str:''),
  2158. (mask:pocall_clearstack; str:'ClearStack'),
  2159. (mask:pocall_leftright; str:'LeftRight'),
  2160. (mask:pocall_cdecl; str:'Cdecl'),
  2161. (mask:pocall_register; str:'Register'),
  2162. (mask:pocall_stdcall; str:'StdCall'),
  2163. (mask:pocall_safecall; str:'SafeCall'),
  2164. (mask:pocall_palmossyscall;str:'PalmOSSysCall'),
  2165. (mask:pocall_system; str:'System'),
  2166. (mask:pocall_inline; str:'Inline'),
  2167. (mask:pocall_internproc; str:'InternProc'),
  2168. (mask:pocall_internconst; str:'InternConst')
  2169. );
  2170. var
  2171. s : string;
  2172. i : longint;
  2173. first : boolean;
  2174. begin
  2175. s:='';
  2176. first:=true;
  2177. for i:=1to proccallopts do
  2178. if (proccallopt[i].mask in proccalloptions) then
  2179. begin
  2180. if first then
  2181. first:=false
  2182. else
  2183. s:=s+';';
  2184. s:=s+proccallopt[i].str;
  2185. end;
  2186. proccalloption2str:=s;
  2187. end;
  2188. {$ifdef GDB}
  2189. function tabstractprocdef.stabstring : pchar;
  2190. begin
  2191. stabstring := strpnew('abstractproc'+numberstring+';');
  2192. end;
  2193. procedure tabstractprocdef.concatstabto(asmlist : paasmoutput);
  2194. begin
  2195. if (not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2196. and not is_def_stab_written then
  2197. begin
  2198. if assigned(rettype.def) then forcestabto(asmlist,rettype.def);
  2199. inherited concatstabto(asmlist);
  2200. end;
  2201. end;
  2202. {$endif GDB}
  2203. {***************************************************************************
  2204. TPROCDEF
  2205. ***************************************************************************}
  2206. constructor tprocdef.init;
  2207. begin
  2208. inherited init;
  2209. deftype:=procdef;
  2210. _mangledname:=nil;
  2211. nextoverloaded:=nil;
  2212. fileinfo:=aktfilepos;
  2213. extnumber:=-1;
  2214. localst:=new(psymtable,init(localsymtable));
  2215. parast:=new(psymtable,init(parasymtable));
  2216. localst^.defowner:=@self;
  2217. parast^.defowner:=@self;
  2218. { this is used by insert
  2219. to check same names in parast and localst }
  2220. localst^.next:=parast;
  2221. defref:=nil;
  2222. crossref:=nil;
  2223. lastwritten:=nil;
  2224. refcount:=0;
  2225. if (cs_browser in aktmoduleswitches) and make_ref then
  2226. begin
  2227. defref:=new(pref,init(defref,@tokenpos));
  2228. inc(refcount);
  2229. end;
  2230. lastref:=defref;
  2231. { first, we assume that all registers are used }
  2232. {$ifdef newcg}
  2233. usedregisters:=[firstreg..lastreg];
  2234. {$else newcg}
  2235. {$ifdef i386}
  2236. usedregisters:=$ff;
  2237. {$endif i386}
  2238. {$ifdef m68k}
  2239. usedregisters:=$FFFF;
  2240. {$endif}
  2241. {$endif newcg}
  2242. forwarddef:=true;
  2243. interfacedef:=false;
  2244. _class := nil;
  2245. code:=nil;
  2246. count:=false;
  2247. is_used:=false;
  2248. end;
  2249. constructor tprocdef.load;
  2250. var
  2251. s : string;
  2252. begin
  2253. inherited load;
  2254. deftype:=procdef;
  2255. {$ifdef newcg}
  2256. readnormalset(usedregisters);
  2257. {$else newcg}
  2258. {$ifdef i386}
  2259. usedregisters:=readbyte;
  2260. {$endif i386}
  2261. {$ifdef m68k}
  2262. usedregisters:=readword;
  2263. {$endif}
  2264. {$endif newcg}
  2265. s:=readstring;
  2266. setstring(_mangledname,s);
  2267. extnumber:=readlong;
  2268. nextoverloaded:=pprocdef(readdefref);
  2269. _class := pobjectdef(readdefref);
  2270. readposinfo(fileinfo);
  2271. if (cs_link_deffile in aktglobalswitches) and
  2272. (tf_need_export in target_info.flags) and
  2273. (po_exports in procoptions) then
  2274. deffile.AddExport(mangledname);
  2275. parast:=nil;
  2276. localst:=nil;
  2277. forwarddef:=false;
  2278. interfacedef:=false;
  2279. lastref:=nil;
  2280. lastwritten:=nil;
  2281. defref:=nil;
  2282. refcount:=0;
  2283. count:=true;
  2284. is_used:=false;
  2285. end;
  2286. Const local_symtable_index : longint = $8001;
  2287. procedure tprocdef.load_references;
  2288. var
  2289. pos : tfileposinfo;
  2290. {$ifndef NOLOCALBROWSER}
  2291. oldsymtablestack,
  2292. st : psymtable;
  2293. {$endif ndef NOLOCALBROWSER}
  2294. move_last : boolean;
  2295. begin
  2296. move_last:=lastwritten=lastref;
  2297. while (not current_ppu^.endofentry) do
  2298. begin
  2299. readposinfo(pos);
  2300. inc(refcount);
  2301. lastref:=new(pref,init(lastref,@pos));
  2302. lastref^.is_written:=true;
  2303. if refcount=1 then
  2304. defref:=lastref;
  2305. end;
  2306. if move_last then
  2307. lastwritten:=lastref;
  2308. if ((current_module^.flags and uf_local_browser)<>0)
  2309. and is_in_current then
  2310. begin
  2311. {$ifndef NOLOCALBROWSER}
  2312. oldsymtablestack:=symtablestack;
  2313. st:=aktlocalsymtable;
  2314. new(parast,loadas(parasymtable));
  2315. parast^.defowner:=@self;
  2316. aktlocalsymtable:=parast;
  2317. parast^.deref;
  2318. parast^.next:=owner;
  2319. parast^.load_browser;
  2320. aktlocalsymtable:=st;
  2321. new(localst,loadas(localsymtable));
  2322. localst^.defowner:=@self;
  2323. aktlocalsymtable:=localst;
  2324. symtablestack:=parast;
  2325. localst^.deref;
  2326. localst^.next:=parast;
  2327. localst^.load_browser;
  2328. aktlocalsymtable:=st;
  2329. symtablestack:=oldsymtablestack;
  2330. {$endif ndef NOLOCALBROWSER}
  2331. end;
  2332. end;
  2333. function tprocdef.write_references : boolean;
  2334. var
  2335. ref : pref;
  2336. {$ifndef NOLOCALBROWSER}
  2337. st : psymtable;
  2338. pdo : pobjectdef;
  2339. {$endif ndef NOLOCALBROWSER}
  2340. move_last : boolean;
  2341. begin
  2342. move_last:=lastwritten=lastref;
  2343. if move_last and (((current_module^.flags and uf_local_browser)=0)
  2344. or not is_in_current) then
  2345. exit;
  2346. { write address of this symbol }
  2347. writedefref(@self);
  2348. { write refs }
  2349. if assigned(lastwritten) then
  2350. ref:=lastwritten
  2351. else
  2352. ref:=defref;
  2353. while assigned(ref) do
  2354. begin
  2355. if ref^.moduleindex=current_module^.unit_index then
  2356. begin
  2357. writeposinfo(ref^.posinfo);
  2358. ref^.is_written:=true;
  2359. if move_last then
  2360. lastwritten:=ref;
  2361. end
  2362. else if not ref^.is_written then
  2363. move_last:=false
  2364. else if move_last then
  2365. lastwritten:=ref;
  2366. ref:=ref^.nextref;
  2367. end;
  2368. current_ppu^.writeentry(ibdefref);
  2369. write_references:=true;
  2370. if ((current_module^.flags and uf_local_browser)<>0)
  2371. and is_in_current then
  2372. begin
  2373. {$ifndef NOLOCALBROWSER}
  2374. pdo:=_class;
  2375. if (owner^.symtabletype<>localsymtable) then
  2376. while assigned(pdo) do
  2377. begin
  2378. if pdo^.symtable<>aktrecordsymtable then
  2379. begin
  2380. pdo^.symtable^.unitid:=local_symtable_index;
  2381. inc(local_symtable_index);
  2382. end;
  2383. pdo:=pdo^.childof;
  2384. end;
  2385. { we need TESTLOCALBROWSER para and local symtables
  2386. PPU files are then easier to read PM }
  2387. if not assigned(parast) then
  2388. parast:=new(psymtable,init(parasymtable));
  2389. parast^.defowner:=@self;
  2390. st:=aktlocalsymtable;
  2391. aktlocalsymtable:=parast;
  2392. parast^.writeas;
  2393. parast^.unitid:=local_symtable_index;
  2394. inc(local_symtable_index);
  2395. parast^.write_browser;
  2396. if not assigned(localst) then
  2397. localst:=new(psymtable,init(localsymtable));
  2398. localst^.defowner:=@self;
  2399. aktlocalsymtable:=localst;
  2400. localst^.writeas;
  2401. localst^.unitid:=local_symtable_index;
  2402. inc(local_symtable_index);
  2403. localst^.write_browser;
  2404. aktlocalsymtable:=st;
  2405. { decrement for }
  2406. local_symtable_index:=local_symtable_index-2;
  2407. pdo:=_class;
  2408. if (owner^.symtabletype<>localsymtable) then
  2409. while assigned(pdo) do
  2410. begin
  2411. if pdo^.symtable<>aktrecordsymtable then
  2412. dec(local_symtable_index);
  2413. pdo:=pdo^.childof;
  2414. end;
  2415. {$endif ndef NOLOCALBROWSER}
  2416. end;
  2417. end;
  2418. {$ifdef BrowserLog}
  2419. procedure tprocdef.add_to_browserlog;
  2420. begin
  2421. if assigned(defref) then
  2422. begin
  2423. browserlog.AddLog('***'+mangledname);
  2424. browserlog.AddLogRefs(defref);
  2425. if (current_module^.flags and uf_local_browser)<>0 then
  2426. begin
  2427. if assigned(parast) then
  2428. parast^.writebrowserlog;
  2429. if assigned(localst) then
  2430. localst^.writebrowserlog;
  2431. end;
  2432. end;
  2433. end;
  2434. {$endif BrowserLog}
  2435. destructor tprocdef.done;
  2436. begin
  2437. if assigned(defref) then
  2438. begin
  2439. defref^.freechain;
  2440. dispose(defref,done);
  2441. end;
  2442. if assigned(parast) then
  2443. dispose(parast,done);
  2444. if assigned(localst) and (localst^.symtabletype<>staticsymtable) then
  2445. dispose(localst,done);
  2446. if (pocall_inline in proccalloptions) and assigned(code) then
  2447. disposetree(ptree(code));
  2448. if (po_msgstr in procoptions) then
  2449. strdispose(messageinf.str);
  2450. if
  2451. {$ifdef tp}
  2452. not(use_big) and
  2453. {$endif}
  2454. assigned(_mangledname) then
  2455. strdispose(_mangledname);
  2456. inherited done;
  2457. end;
  2458. procedure tprocdef.write;
  2459. begin
  2460. inherited write;
  2461. current_ppu^.do_interface_crc:=false;
  2462. { set all registers to used for simplified compilation PM }
  2463. if simplify_ppu then
  2464. begin
  2465. {$ifdef newcg}
  2466. usedregisters:=[firstreg..lastreg];
  2467. {$else newcg}
  2468. {$ifdef i386}
  2469. usedregisters:=$ff;
  2470. {$endif i386}
  2471. {$ifdef m68k}
  2472. usedregisters:=$ffff;
  2473. {$endif}
  2474. {$endif newcg}
  2475. end;
  2476. {$ifdef newcg}
  2477. writenormalset(usedregisters);
  2478. {$else newcg}
  2479. {$ifdef i386}
  2480. writebyte(usedregisters);
  2481. {$endif i386}
  2482. {$ifdef m68k}
  2483. writeword(usedregisters);
  2484. {$endif}
  2485. {$endif newcg}
  2486. current_ppu^.do_interface_crc:=true;
  2487. writestring(mangledname);
  2488. writelong(extnumber);
  2489. if (proctypeoption<>potype_operator) then
  2490. writedefref(nextoverloaded)
  2491. else
  2492. begin
  2493. { only write the overloads from the same unit }
  2494. if assigned(nextoverloaded) and
  2495. (nextoverloaded^.owner=owner) then
  2496. writedefref(nextoverloaded)
  2497. else
  2498. writedefref(nil);
  2499. end;
  2500. writedefref(_class);
  2501. writeposinfo(fileinfo);
  2502. if (pocall_inline in proccalloptions) then
  2503. begin
  2504. { we need to save
  2505. - the para and the local symtable
  2506. - the code ptree !! PM
  2507. writesymtable(parast);
  2508. writesymtable(localst);
  2509. writeptree(ptree(code));
  2510. }
  2511. end;
  2512. current_ppu^.writeentry(ibprocdef);
  2513. end;
  2514. function tprocdef.haspara:boolean;
  2515. begin
  2516. haspara:=assigned(aktprocsym^.definition^.parast^.symindex^.first);
  2517. end;
  2518. {$ifdef GDB}
  2519. procedure addparaname(p : psym);
  2520. var vs : char;
  2521. begin
  2522. if pvarsym(p)^.varspez = vs_value then vs := '1'
  2523. else vs := '0';
  2524. strpcopy(strend(StabRecString),p^.name+':'+pvarsym(p)^.vartype.def^.numberstring+','+vs+';');
  2525. end;
  2526. function tprocdef.stabstring : pchar;
  2527. var
  2528. i : longint;
  2529. oldrec : pchar;
  2530. begin
  2531. oldrec := stabrecstring;
  2532. getmem(StabRecString,1024);
  2533. strpcopy(StabRecString,'f'+rettype.def^.numberstring);
  2534. i:=para^.count;
  2535. if i>0 then
  2536. begin
  2537. strpcopy(strend(StabRecString),','+tostr(i)+';');
  2538. (* confuse gdb !! PM
  2539. if assigned(parast) then
  2540. parast^.foreach({$ifndef TP}@{$endif}addparaname)
  2541. else
  2542. begin
  2543. param := para1;
  2544. i := 0;
  2545. while assigned(param) do
  2546. begin
  2547. inc(i);
  2548. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  2549. {Here we have lost the parameter names !!}
  2550. {using lower case parameters }
  2551. strpcopy(strend(stabrecstring),'p'+tostr(i)
  2552. +':'+param^.paratype.def^.numberstring+','+vartyp+';');
  2553. param := param^.next;
  2554. end;
  2555. end; *)
  2556. {strpcopy(strend(StabRecString),';');}
  2557. end;
  2558. stabstring := strnew(stabrecstring);
  2559. freemem(stabrecstring,1024);
  2560. stabrecstring := oldrec;
  2561. end;
  2562. procedure tprocdef.concatstabto(asmlist : paasmoutput);
  2563. begin
  2564. end;
  2565. {$endif GDB}
  2566. procedure tprocdef.deref;
  2567. begin
  2568. inherited deref;
  2569. resolvedef(pdef(nextoverloaded));
  2570. resolvedef(pdef(_class));
  2571. end;
  2572. function tprocdef.mangledname : string;
  2573. {$ifdef tp}
  2574. var
  2575. oldpos : longint;
  2576. s : string;
  2577. b : byte;
  2578. {$endif tp}
  2579. begin
  2580. {$ifndef Delphi}
  2581. {$ifdef tp}
  2582. if use_big then
  2583. begin
  2584. symbolstream.seek(longint(_mangledname));
  2585. symbolstream.read(b,1);
  2586. symbolstream.read(s[1],b);
  2587. s[0]:=chr(b);
  2588. mangledname:=s;
  2589. end
  2590. else
  2591. {$endif}
  2592. {$endif Delphi}
  2593. mangledname:=strpas(_mangledname);
  2594. if count then
  2595. is_used:=true;
  2596. end;
  2597. function tprocdef.procname: string;
  2598. var
  2599. s : string;
  2600. l : longint;
  2601. begin
  2602. s:=mangledname;
  2603. { delete leading $$'s }
  2604. l:=pos('$$',s);
  2605. while l<>0 do
  2606. begin
  2607. delete(s,1,l+1);
  2608. l:=pos('$$',s);
  2609. end;
  2610. { delete leading _$'s }
  2611. l:=pos('_$',s);
  2612. while l<>0 do
  2613. begin
  2614. delete(s,1,l+1);
  2615. l:=pos('_$',s);
  2616. end;
  2617. l:=pos('$',s);
  2618. if l=0 then
  2619. procname:=s
  2620. else
  2621. procname:=Copy(s,1,l-1);
  2622. end;
  2623. {$IfDef GDB}
  2624. function tprocdef.cplusplusmangledname : string;
  2625. var
  2626. s,s2 : string;
  2627. param : pparaitem;
  2628. begin
  2629. s := typesym^.name;
  2630. if _class <> nil then
  2631. begin
  2632. s2 := _class^.objname^;
  2633. s := s+'__'+tostr(length(s2))+s2;
  2634. end else s := s + '_';
  2635. param := pparaitem(para^.first);
  2636. while assigned(param) do
  2637. begin
  2638. s2 := param^.paratype.def^.typesym^.name;
  2639. s := s+tostr(length(s2))+s2;
  2640. param := pparaitem(param^.next);
  2641. end;
  2642. cplusplusmangledname:=s;
  2643. end;
  2644. {$EndIf GDB}
  2645. procedure tprocdef.setmangledname(const s : string);
  2646. begin
  2647. if {$ifdef tp}not(use_big) and{$endif} (assigned(_mangledname)) then
  2648. strdispose(_mangledname);
  2649. setstring(_mangledname,s);
  2650. if assigned(parast) then
  2651. begin
  2652. stringdispose(parast^.name);
  2653. parast^.name:=stringdup('args of '+s);
  2654. end;
  2655. if assigned(localst) then
  2656. begin
  2657. stringdispose(localst^.name);
  2658. localst^.name:=stringdup('locals of '+s);
  2659. end;
  2660. end;
  2661. {***************************************************************************
  2662. TPROCVARDEF
  2663. ***************************************************************************}
  2664. constructor tprocvardef.init;
  2665. begin
  2666. inherited init;
  2667. deftype:=procvardef;
  2668. end;
  2669. constructor tprocvardef.load;
  2670. begin
  2671. inherited load;
  2672. deftype:=procvardef;
  2673. end;
  2674. procedure tprocvardef.write;
  2675. begin
  2676. { here we cannot get a real good value so just give something }
  2677. { plausible (PM) }
  2678. { a more secure way would be
  2679. to allways store in a temp }
  2680. if is_fpu(rettype.def) then
  2681. fpu_used:=2
  2682. else
  2683. fpu_used:=0;
  2684. inherited write;
  2685. current_ppu^.writeentry(ibprocvardef);
  2686. end;
  2687. function tprocvardef.size : longint;
  2688. begin
  2689. if (po_methodpointer in procoptions) then
  2690. size:=2*target_os.size_of_pointer
  2691. else
  2692. size:=target_os.size_of_pointer;
  2693. end;
  2694. {$ifdef GDB}
  2695. function tprocvardef.stabstring : pchar;
  2696. var
  2697. nss : pchar;
  2698. { i : longint; }
  2699. begin
  2700. { i := para^.count; }
  2701. getmem(nss,1024);
  2702. { it is not a function but a function pointer !! (PM) }
  2703. strpcopy(nss,'*f'+rettype.def^.numberstring{+','+tostr(i)}+';');
  2704. { this confuses gdb !!
  2705. we should use 'F' instead of 'f' but
  2706. as we use c++ language mode
  2707. it does not like that either
  2708. Please do not remove this part
  2709. might be used once
  2710. gdb for pascal is ready PM }
  2711. (*
  2712. param := para1;
  2713. i := 0;
  2714. while assigned(param) do
  2715. begin
  2716. inc(i);
  2717. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  2718. {Here we have lost the parameter names !!}
  2719. pst := strpnew('p'+tostr(i)+':'+param^.paratype.def^.numberstring+','+vartyp+';');
  2720. strcat(nss,pst);
  2721. strdispose(pst);
  2722. param := param^.next;
  2723. end; *)
  2724. {strpcopy(strend(nss),';');}
  2725. stabstring := strnew(nss);
  2726. freemem(nss,1024);
  2727. end;
  2728. procedure tprocvardef.concatstabto(asmlist : paasmoutput);
  2729. begin
  2730. if ( not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2731. and not is_def_stab_written then
  2732. inherited concatstabto(asmlist);
  2733. is_def_stab_written:=true;
  2734. end;
  2735. {$endif GDB}
  2736. procedure tprocvardef.write_rtti_data;
  2737. var
  2738. pdc : pparaitem;
  2739. methodkind, paraspec : byte;
  2740. begin
  2741. if po_methodpointer in procoptions then
  2742. begin
  2743. { write method id and name }
  2744. rttilist^.concat(new(pai_const,init_8bit(tkmethod)));
  2745. write_rtti_name;
  2746. { write kind of method (can only be function or procedure)}
  2747. if rettype.def = pdef(voiddef) then { ### typecast shoudln't be necessary! (sg) }
  2748. methodkind := mkProcedure
  2749. else
  2750. methodkind := mkFunction;
  2751. rttilist^.concat(new(pai_const,init_8bit(methodkind)));
  2752. { get # of parameters }
  2753. rttilist^.concat(new(pai_const,init_8bit(para^.count)));
  2754. { write parameter info. The parameters must be written in reverse order
  2755. if this method uses right to left parameter pushing! }
  2756. if (pocall_leftright in proccalloptions) then
  2757. pdc:=pparaitem(para^.last)
  2758. else
  2759. pdc:=pparaitem(para^.first);
  2760. while assigned(pdc) do
  2761. begin
  2762. case pdc^.paratyp of
  2763. vs_value: paraspec := 0;
  2764. vs_const: paraspec := pfConst;
  2765. vs_var : paraspec := pfVar;
  2766. end;
  2767. { write flags for current parameter }
  2768. rttilist^.concat(new(pai_const,init_8bit(paraspec)));
  2769. { write name of current parameter ### how can I get this??? (sg)}
  2770. rttilist^.concat(new(pai_const,init_8bit(0)));
  2771. { write name of type of current parameter }
  2772. pdc^.paratype.def^.write_rtti_name;
  2773. if (pocall_leftright in proccalloptions) then
  2774. pdc:=pparaitem(pdc^.previous)
  2775. else
  2776. pdc:=pparaitem(pdc^.next);
  2777. end;
  2778. { write name of result type }
  2779. rettype.def^.write_rtti_name;
  2780. end;
  2781. end;
  2782. procedure tprocvardef.write_child_rtti_data;
  2783. begin
  2784. {!!!!!!!!}
  2785. end;
  2786. function tprocvardef.is_publishable : boolean;
  2787. begin
  2788. is_publishable:=(po_methodpointer in procoptions);
  2789. end;
  2790. function tprocvardef.gettypename : string;
  2791. begin
  2792. if assigned(rettype.def) and
  2793. (rettype.def<>pdef(voiddef)) then
  2794. gettypename:='<procedure variable type of function'+demangled_paras+
  2795. ':'+rettype.def^.gettypename+';'+proccalloption2str+'>'
  2796. else
  2797. gettypename:='<procedure variable type of procedure'+demangled_paras+
  2798. ';'+proccalloption2str+'>';
  2799. end;
  2800. {***************************************************************************
  2801. TOBJECTDEF
  2802. ***************************************************************************}
  2803. {$ifdef GDB}
  2804. const
  2805. vtabletype : word = 0;
  2806. vtableassigned : boolean = false;
  2807. {$endif GDB}
  2808. constructor tobjectdef.init(const n : string;c : pobjectdef);
  2809. begin
  2810. tdef.init;
  2811. deftype:=objectdef;
  2812. objectoptions:=[];
  2813. childof:=nil;
  2814. symtable:=new(psymtable,init(objectsymtable));
  2815. symtable^.name := stringdup(n);
  2816. { create space for vmt !! }
  2817. vmt_offset:=0;
  2818. symtable^.datasize:=0;
  2819. symtable^.defowner:=@self;
  2820. symtable^.dataalignment:=packrecordalignment[aktpackrecords];
  2821. set_parent(c);
  2822. objname:=stringdup(n);
  2823. end;
  2824. constructor tobjectdef.load;
  2825. var
  2826. oldread_member : boolean;
  2827. begin
  2828. tdef.load;
  2829. deftype:=objectdef;
  2830. savesize:=readlong;
  2831. vmt_offset:=readlong;
  2832. objname:=stringdup(readstring);
  2833. childof:=pobjectdef(readdefref);
  2834. readsmallset(objectoptions);
  2835. has_rtti:=boolean(readbyte);
  2836. oldread_member:=read_member;
  2837. read_member:=true;
  2838. symtable:=new(psymtable,loadas(objectsymtable));
  2839. read_member:=oldread_member;
  2840. symtable^.defowner:=@self;
  2841. symtable^.name := stringdup(objname^);
  2842. { handles the predefined class tobject }
  2843. { the last TOBJECT which is loaded gets }
  2844. { it ! }
  2845. if (childof=nil) and
  2846. is_class and
  2847. (objname^='TOBJECT') then
  2848. class_tobject:=@self;
  2849. end;
  2850. destructor tobjectdef.done;
  2851. begin
  2852. if assigned(symtable) then
  2853. dispose(symtable,done);
  2854. if (oo_is_forward in objectoptions) then
  2855. Message1(sym_e_class_forward_not_resolved,objname^);
  2856. stringdispose(objname);
  2857. tdef.done;
  2858. end;
  2859. procedure tobjectdef.write;
  2860. var
  2861. oldread_member : boolean;
  2862. begin
  2863. tdef.write;
  2864. writelong(size);
  2865. writelong(vmt_offset);
  2866. writestring(objname^);
  2867. writedefref(childof);
  2868. writesmallset(objectoptions);
  2869. writebyte(byte(has_rtti));
  2870. current_ppu^.writeentry(ibobjectdef);
  2871. oldread_member:=read_member;
  2872. read_member:=true;
  2873. symtable^.writeas;
  2874. read_member:=oldread_member;
  2875. end;
  2876. procedure tobjectdef.deref;
  2877. var
  2878. oldrecsyms : psymtable;
  2879. begin
  2880. inherited deref;
  2881. resolvedef(pdef(childof));
  2882. oldrecsyms:=aktrecordsymtable;
  2883. aktrecordsymtable:=symtable;
  2884. symtable^.deref;
  2885. aktrecordsymtable:=oldrecsyms;
  2886. end;
  2887. procedure tobjectdef.set_parent( c : pobjectdef);
  2888. begin
  2889. { nothing to do if the parent was not forward !}
  2890. if assigned(childof) then
  2891. exit;
  2892. childof:=c;
  2893. { some options are inherited !! }
  2894. if assigned(c) then
  2895. begin
  2896. objectoptions:=objectoptions+(c^.objectoptions*
  2897. [oo_has_virtual,oo_has_private,oo_has_protected,oo_has_constructor,oo_has_destructor]);
  2898. { add the data of the anchestor class }
  2899. inc(symtable^.datasize,c^.symtable^.datasize);
  2900. if (oo_has_vmt in objectoptions) and
  2901. (oo_has_vmt in c^.objectoptions) then
  2902. dec(symtable^.datasize,target_os.size_of_pointer);
  2903. { if parent has a vmt field then
  2904. the offset is the same for the child PM }
  2905. if (oo_has_vmt in c^.objectoptions) or is_class then
  2906. begin
  2907. vmt_offset:=c^.vmt_offset;
  2908. {$ifdef INCLUDEOK}
  2909. include(objectoptions,oo_has_vmt);
  2910. {$else}
  2911. objectoptions:=objectoptions+[oo_has_vmt];
  2912. {$endif}
  2913. end;
  2914. end;
  2915. savesize := symtable^.datasize;
  2916. end;
  2917. procedure tobjectdef.insertvmt;
  2918. begin
  2919. if (oo_has_vmt in objectoptions) then
  2920. internalerror(12345)
  2921. else
  2922. begin
  2923. { first round up to multiple of 4 }
  2924. if (symtable^.dataalignment=2) then
  2925. begin
  2926. if (symtable^.datasize and 1)<>0 then
  2927. inc(symtable^.datasize);
  2928. end
  2929. else
  2930. if (symtable^.dataalignment>=4) then
  2931. begin
  2932. if (symtable^.datasize mod 4) <> 0 then
  2933. inc(symtable^.datasize,4-(symtable^.datasize mod 4));
  2934. end;
  2935. vmt_offset:=symtable^.datasize;
  2936. inc(symtable^.datasize,target_os.size_of_pointer);
  2937. include(objectoptions,oo_has_vmt);
  2938. end;
  2939. end;
  2940. procedure tobjectdef.check_forwards;
  2941. begin
  2942. symtable^.check_forwards;
  2943. if (oo_is_forward in objectoptions) then
  2944. begin
  2945. { ok, in future, the forward can be resolved }
  2946. Message1(sym_e_class_forward_not_resolved,objname^);
  2947. {$ifdef INCLUDEOK}
  2948. exclude(objectoptions,oo_is_forward);
  2949. {$else}
  2950. objectoptions:=objectoptions-[oo_is_forward];
  2951. {$endif}
  2952. end;
  2953. end;
  2954. { true, if self inherits from d (or if they are equal) }
  2955. function tobjectdef.is_related(d : pobjectdef) : boolean;
  2956. var
  2957. hp : pobjectdef;
  2958. begin
  2959. hp:=@self;
  2960. while assigned(hp) do
  2961. begin
  2962. if hp=d then
  2963. begin
  2964. is_related:=true;
  2965. exit;
  2966. end;
  2967. hp:=hp^.childof;
  2968. end;
  2969. is_related:=false;
  2970. end;
  2971. var
  2972. sd : pprocdef;
  2973. procedure _searchdestructor(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  2974. var
  2975. p : pprocdef;
  2976. begin
  2977. { if we found already a destructor, then we exit }
  2978. if assigned(sd) then
  2979. exit;
  2980. if psym(sym)^.typ=procsym then
  2981. begin
  2982. p:=pprocsym(sym)^.definition;
  2983. while assigned(p) do
  2984. begin
  2985. if p^.proctypeoption=potype_destructor then
  2986. begin
  2987. sd:=p;
  2988. exit;
  2989. end;
  2990. p:=p^.nextoverloaded;
  2991. end;
  2992. end;
  2993. end;
  2994. function tobjectdef.searchdestructor : pprocdef;
  2995. var
  2996. o : pobjectdef;
  2997. begin
  2998. searchdestructor:=nil;
  2999. o:=@self;
  3000. sd:=nil;
  3001. while assigned(o) do
  3002. begin
  3003. symtable^.foreach({$ifndef TP}@{$endif}_searchdestructor);
  3004. if assigned(sd) then
  3005. begin
  3006. searchdestructor:=sd;
  3007. exit;
  3008. end;
  3009. o:=o^.childof;
  3010. end;
  3011. end;
  3012. function tobjectdef.size : longint;
  3013. begin
  3014. if (oo_is_class in objectoptions) then
  3015. size:=target_os.size_of_pointer
  3016. else
  3017. size:=symtable^.datasize;
  3018. end;
  3019. function tobjectdef.alignment:longint;
  3020. begin
  3021. alignment:=symtable^.dataalignment;
  3022. end;
  3023. function tobjectdef.vmtmethodoffset(index:longint):longint;
  3024. begin
  3025. { for offset of methods for classes, see rtl/inc/objpash.inc }
  3026. if is_class then
  3027. vmtmethodoffset:=(index+12)*target_os.size_of_pointer
  3028. else
  3029. {$ifdef WITHDMT}
  3030. vmtmethodoffset:=(index+4)*target_os.size_of_pointer;
  3031. {$else WITHDMT}
  3032. vmtmethodoffset:=(index+3)*target_os.size_of_pointer;
  3033. {$endif WITHDMT}
  3034. end;
  3035. function tobjectdef.vmt_mangledname : string;
  3036. {DM: I get a nil pointer on the owner name. I don't know if this
  3037. mayhappen, and I have therefore fixed the problem by doing nil pointer
  3038. checks.}
  3039. var
  3040. s1,s2:string;
  3041. begin
  3042. if not(oo_has_vmt in objectoptions) then
  3043. Message1(parser_object_has_no_vmt,objname^);
  3044. if owner^.name=nil then
  3045. s1:=''
  3046. else
  3047. s1:=owner^.name^;
  3048. if objname=nil then
  3049. s2:=''
  3050. else
  3051. s2:=objname^;
  3052. vmt_mangledname:='VMT_'+s1+'$_'+s2;
  3053. end;
  3054. function tobjectdef.rtti_name : string;
  3055. var
  3056. s1,s2:string;
  3057. begin
  3058. if owner^.name=nil then
  3059. s1:=''
  3060. else
  3061. s1:=owner^.name^;
  3062. if objname=nil then
  3063. s2:=''
  3064. else
  3065. s2:=objname^;
  3066. rtti_name:='RTTI_'+s1+'$_'+s2;
  3067. end;
  3068. function tobjectdef.is_class : boolean;
  3069. begin
  3070. is_class:=(oo_is_class in objectoptions);
  3071. end;
  3072. {$ifdef GDB}
  3073. procedure addprocname(p :pnamedindexobject);
  3074. var virtualind,argnames : string;
  3075. news, newrec : pchar;
  3076. pd,ipd : pprocdef;
  3077. lindex : longint;
  3078. para : pparaitem;
  3079. arglength : byte;
  3080. sp : char;
  3081. begin
  3082. If psym(p)^.typ = procsym then
  3083. begin
  3084. pd := pprocsym(p)^.definition;
  3085. { this will be used for full implementation of object stabs
  3086. not yet done }
  3087. ipd := pd;
  3088. while assigned(ipd^.nextoverloaded) do ipd := ipd^.nextoverloaded;
  3089. if (po_virtualmethod in pd^.procoptions) then
  3090. begin
  3091. lindex := pd^.extnumber;
  3092. {doesnt seem to be necessary
  3093. lindex := lindex or $80000000;}
  3094. virtualind := '*'+tostr(lindex)+';'+ipd^._class^.numberstring+';'
  3095. end else virtualind := '.';
  3096. { used by gdbpas to recognize constructor and destructors }
  3097. if (pd^.proctypeoption=potype_constructor) then
  3098. argnames:='__ct__'
  3099. else if (pd^.proctypeoption=potype_destructor) then
  3100. argnames:='__dt__'
  3101. else
  3102. argnames := '';
  3103. { arguments are not listed here }
  3104. {we don't need another definition}
  3105. para := pparaitem(pd^.para^.first);
  3106. while assigned(para) do
  3107. begin
  3108. if para^.paratype.def^.deftype = formaldef then
  3109. begin
  3110. if para^.paratyp=vs_var then
  3111. argnames := argnames+'3var'
  3112. else if para^.paratyp=vs_const then
  3113. argnames:=argnames+'5const';
  3114. end
  3115. else
  3116. begin
  3117. { if the arg definition is like (v: ^byte;..
  3118. there is no sym attached to data !!! }
  3119. if assigned(para^.paratype.def^.typesym) then
  3120. begin
  3121. arglength := length(para^.paratype.def^.typesym^.name);
  3122. argnames := argnames + tostr(arglength)+para^.paratype.def^.typesym^.name;
  3123. end
  3124. else
  3125. begin
  3126. argnames:=argnames+'11unnamedtype';
  3127. end;
  3128. end;
  3129. para := pparaitem(para^.next);
  3130. end;
  3131. ipd^.is_def_stab_written := true;
  3132. { here 2A must be changed for private and protected }
  3133. { 0 is private 1 protected and 2 public }
  3134. if (sp_private in psym(p)^.symoptions) then sp:='0'
  3135. else if (sp_protected in psym(p)^.symoptions) then sp:='1'
  3136. else sp:='2';
  3137. newrec := strpnew(p^.name+'::'+ipd^.numberstring
  3138. +'=##'+pd^.rettype.def^.numberstring+';:'+argnames+';'+sp+'A'
  3139. +virtualind+';');
  3140. { get spare place for a string at the end }
  3141. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  3142. begin
  3143. getmem(news,stabrecsize+memsizeinc);
  3144. strcopy(news,stabrecstring);
  3145. freemem(stabrecstring,stabrecsize);
  3146. stabrecsize:=stabrecsize+memsizeinc;
  3147. stabrecstring:=news;
  3148. end;
  3149. strcat(StabRecstring,newrec);
  3150. {freemem(newrec,memsizeinc); }
  3151. strdispose(newrec);
  3152. {This should be used for case !!}
  3153. RecOffset := RecOffset + pd^.size;
  3154. end;
  3155. end;
  3156. function tobjectdef.stabstring : pchar;
  3157. var anc : pobjectdef;
  3158. oldrec : pchar;
  3159. oldrecsize : longint;
  3160. str_end : string;
  3161. begin
  3162. oldrec := stabrecstring;
  3163. oldrecsize:=stabrecsize;
  3164. stabrecsize:=memsizeinc;
  3165. GetMem(stabrecstring,stabrecsize);
  3166. strpcopy(stabRecString,'s'+tostr(symtable^.datasize));
  3167. if assigned(childof) then
  3168. {only one ancestor not virtual, public, at base offset 0 }
  3169. { !1 , 0 2 0 , }
  3170. strpcopy(strend(stabrecstring),'!1,020,'+childof^.numberstring+';');
  3171. {virtual table to implement yet}
  3172. RecOffset := 0;
  3173. symtable^.foreach({$ifndef TP}@{$endif}addname);
  3174. if (oo_has_vmt in objectoptions) then
  3175. if not assigned(childof) or not(oo_has_vmt in childof^.objectoptions) then
  3176. begin
  3177. strpcopy(strend(stabrecstring),'$vf'+numberstring+':'+typeglobalnumber('vtblarray')
  3178. +','+tostr(vmt_offset*8)+';');
  3179. end;
  3180. symtable^.foreach({$ifndef TP}@{$endif}addprocname);
  3181. if (oo_has_vmt in objectoptions) then
  3182. begin
  3183. anc := @self;
  3184. while assigned(anc^.childof) and (oo_has_vmt in anc^.childof^.objectoptions) do
  3185. anc := anc^.childof;
  3186. str_end:=';~%'+anc^.numberstring+';';
  3187. end
  3188. else
  3189. str_end:=';';
  3190. strpcopy(strend(stabrecstring),str_end);
  3191. stabstring := strnew(StabRecString);
  3192. freemem(stabrecstring,stabrecsize);
  3193. stabrecstring := oldrec;
  3194. stabrecsize:=oldrecsize;
  3195. end;
  3196. {$endif GDB}
  3197. procedure tobjectdef.write_child_init_data;
  3198. begin
  3199. symtable^.foreach({$ifndef TP}@{$endif}generate_child_inittable);
  3200. end;
  3201. procedure tobjectdef.write_init_data;
  3202. begin
  3203. if is_class then
  3204. rttilist^.concat(new(pai_const,init_8bit(tkclass)))
  3205. else
  3206. rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  3207. { generate the name }
  3208. rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
  3209. rttilist^.concat(new(pai_string,init(objname^)));
  3210. rttilist^.concat(new(pai_const,init_32bit(size)));
  3211. count:=0;
  3212. symtable^.foreach({$ifndef TP}@{$endif}count_inittable_fields);
  3213. rttilist^.concat(new(pai_const,init_32bit(count)));
  3214. symtable^.foreach({$ifndef TP}@{$endif}write_field_inittable);
  3215. end;
  3216. function tobjectdef.needs_inittable : boolean;
  3217. var
  3218. oldb : boolean;
  3219. begin
  3220. if is_class then
  3221. needs_inittable:=false
  3222. else
  3223. begin
  3224. { there are recursive calls to needs_inittable possible, }
  3225. { so we have to change to old value how else should }
  3226. { we do that ? check_rec_rtti can't be a nested }
  3227. { procedure of needs_rtti ! }
  3228. oldb:=binittable;
  3229. binittable:=false;
  3230. symtable^.foreach({$ifndef TP}@{$endif}check_rec_inittable);
  3231. needs_inittable:=binittable;
  3232. binittable:=oldb;
  3233. end;
  3234. end;
  3235. procedure count_published_properties(sym:pnamedindexobject);
  3236. {$ifndef fpc}far;{$endif}
  3237. begin
  3238. if needs_prop_entry(psym(sym)) and
  3239. (psym(sym)^.typ<>varsym) then
  3240. inc(count);
  3241. end;
  3242. procedure write_property_info(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  3243. var
  3244. proctypesinfo : byte;
  3245. procedure writeproc(proc : psymlist; shiftvalue : byte);
  3246. var
  3247. typvalue : byte;
  3248. hp : psymlistitem;
  3249. address : longint;
  3250. begin
  3251. if not(assigned(proc) and assigned(proc^.firstsym)) then
  3252. begin
  3253. rttilist^.concat(new(pai_const,init_32bit(1)));
  3254. typvalue:=3;
  3255. end
  3256. else if proc^.firstsym^.sym^.typ=varsym then
  3257. begin
  3258. address:=0;
  3259. hp:=proc^.firstsym;
  3260. while assigned(hp) do
  3261. begin
  3262. inc(address,pvarsym(hp^.sym)^.address);
  3263. hp:=hp^.next;
  3264. end;
  3265. rttilist^.concat(new(pai_const,init_32bit(address)));
  3266. typvalue:=0;
  3267. end
  3268. else
  3269. begin
  3270. if not(po_virtualmethod in pprocdef(proc^.def)^.procoptions) then
  3271. begin
  3272. rttilist^.concat(new(pai_const_symbol,initname(pprocdef(proc^.def)^.mangledname)));
  3273. typvalue:=1;
  3274. end
  3275. else
  3276. begin
  3277. { virtual method, write vmt offset }
  3278. rttilist^.concat(new(pai_const,init_32bit(
  3279. pprocdef(proc^.def)^._class^.vmtmethodoffset(pprocdef(proc^.def)^.extnumber))));
  3280. typvalue:=2;
  3281. end;
  3282. end;
  3283. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  3284. end;
  3285. begin
  3286. if needs_prop_entry(psym(sym)) then
  3287. case psym(sym)^.typ of
  3288. varsym:
  3289. begin
  3290. {$ifdef dummy}
  3291. if not(pvarsym(sym)^.vartype.def^.deftype=objectdef) or
  3292. not(pobjectdef(pvarsym(sym)^.vartype.def)^.is_class) then
  3293. internalerror(1509992);
  3294. { access to implicit class property as field }
  3295. proctypesinfo:=(0 shl 0) or (0 shl 2) or (0 shl 4);
  3296. rttilist^.concat(new(pai_const_symbol,initname(pvarsym(sym)^.vartype.def^.get_rtti_label)));
  3297. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  3298. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  3299. { per default stored }
  3300. rttilist^.concat(new(pai_const,init_32bit(1)));
  3301. { index as well as ... }
  3302. rttilist^.concat(new(pai_const,init_32bit(0)));
  3303. { default value are zero }
  3304. rttilist^.concat(new(pai_const,init_32bit(0)));
  3305. rttilist^.concat(new(pai_const,init_16bit(count)));
  3306. inc(count);
  3307. rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
  3308. rttilist^.concat(new(pai_const,init_8bit(length(pvarsym(sym)^.name))));
  3309. rttilist^.concat(new(pai_string,init(pvarsym(sym)^.name)));
  3310. {$endif dummy}
  3311. end;
  3312. propertysym:
  3313. begin
  3314. if ppo_indexed in ppropertysym(sym)^.propoptions then
  3315. proctypesinfo:=$40
  3316. else
  3317. proctypesinfo:=0;
  3318. rttilist^.concat(new(pai_const_symbol,initname(ppropertysym(sym)^.proptype.def^.get_rtti_label)));
  3319. writeproc(ppropertysym(sym)^.readaccess,0);
  3320. writeproc(ppropertysym(sym)^.writeaccess,2);
  3321. { isn't it stored ? }
  3322. if not(ppo_stored in ppropertysym(sym)^.propoptions) then
  3323. begin
  3324. rttilist^.concat(new(pai_const,init_32bit(0)));
  3325. proctypesinfo:=proctypesinfo or (3 shl 4);
  3326. end
  3327. else
  3328. writeproc(ppropertysym(sym)^.storedaccess,4);
  3329. rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.index)));
  3330. rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.default)));
  3331. rttilist^.concat(new(pai_const,init_16bit(count)));
  3332. inc(count);
  3333. rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
  3334. rttilist^.concat(new(pai_const,init_8bit(length(ppropertysym(sym)^.name))));
  3335. rttilist^.concat(new(pai_string,init(ppropertysym(sym)^.name)));
  3336. end;
  3337. else internalerror(1509992);
  3338. end;
  3339. end;
  3340. procedure generate_published_child_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  3341. begin
  3342. if needs_prop_entry(psym(sym)) then
  3343. case psym(sym)^.typ of
  3344. varsym:
  3345. ;
  3346. { now ignored:
  3347. pvarsym(sym)^.vartype.def^.get_rtti_label;
  3348. }
  3349. propertysym:
  3350. ppropertysym(sym)^.proptype.def^.get_rtti_label;
  3351. else
  3352. internalerror(1509991);
  3353. end;
  3354. end;
  3355. procedure tobjectdef.write_child_rtti_data;
  3356. begin
  3357. symtable^.foreach({$ifndef TP}@{$endif}generate_published_child_rtti);
  3358. end;
  3359. procedure tobjectdef.generate_rtti;
  3360. begin
  3361. if not has_rtti then
  3362. begin
  3363. has_rtti:=true;
  3364. getdatalabel(rtti_label);
  3365. write_child_rtti_data;
  3366. rttilist^.concat(new(pai_symbol,initname_global(rtti_name,0)));
  3367. rttilist^.concat(new(pai_label,init(rtti_label)));
  3368. write_rtti_data;
  3369. rttilist^.concat(new(pai_symbol_end,initname(rtti_name)));
  3370. end;
  3371. end;
  3372. type
  3373. tclasslistitem = object(tlinkedlist_item)
  3374. index : longint;
  3375. p : pobjectdef;
  3376. end;
  3377. pclasslistitem = ^tclasslistitem;
  3378. var
  3379. classtablelist : tlinkedlist;
  3380. tablecount : longint;
  3381. function searchclasstablelist(p : pobjectdef) : pclasslistitem;
  3382. var
  3383. hp : pclasslistitem;
  3384. begin
  3385. hp:=pclasslistitem(classtablelist.first);
  3386. while assigned(hp) do
  3387. if hp^.p=p then
  3388. begin
  3389. searchclasstablelist:=hp;
  3390. exit;
  3391. end
  3392. else
  3393. hp:=pclasslistitem(hp^.next);
  3394. searchclasstablelist:=nil;
  3395. end;
  3396. procedure count_published_fields(sym:pnamedindexobject);
  3397. {$ifndef fpc}far;{$endif}
  3398. var
  3399. hp : pclasslistitem;
  3400. begin
  3401. if needs_prop_entry(psym(sym)) and
  3402. (psym(sym)^.typ=varsym) then
  3403. begin
  3404. if pvarsym(sym)^.vartype.def^.deftype<>objectdef then
  3405. internalerror(0206001);
  3406. hp:=searchclasstablelist(pobjectdef(pvarsym(sym)^.vartype.def));
  3407. if not(assigned(hp)) then
  3408. begin
  3409. hp:=new(pclasslistitem,init);
  3410. hp^.p:=pobjectdef(pvarsym(sym)^.vartype.def);
  3411. hp^.index:=tablecount;
  3412. classtablelist.concat(hp);
  3413. inc(tablecount);
  3414. end;
  3415. inc(count);
  3416. end;
  3417. end;
  3418. procedure writefields(sym:pnamedindexobject);
  3419. {$ifndef fpc}far;{$endif}
  3420. var
  3421. hp : pclasslistitem;
  3422. begin
  3423. if needs_prop_entry(psym(sym)) and
  3424. (psym(sym)^.typ=varsym) then
  3425. begin
  3426. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  3427. hp:=searchclasstablelist(pobjectdef(pvarsym(sym)^.vartype.def));
  3428. if not(assigned(hp)) then
  3429. internalerror(0206002);
  3430. rttilist^.concat(new(pai_const,init_16bit(hp^.index)));
  3431. rttilist^.concat(new(pai_const,init_8bit(length(pvarsym(sym)^.name))));
  3432. rttilist^.concat(new(pai_string,init(pvarsym(sym)^.name)));
  3433. end;
  3434. end;
  3435. function tobjectdef.generate_field_table : pasmlabel;
  3436. var
  3437. fieldtable,
  3438. classtable : pasmlabel;
  3439. hp : pclasslistitem;
  3440. begin
  3441. classtablelist.init;
  3442. getdatalabel(fieldtable);
  3443. getdatalabel(classtable);
  3444. count:=0;
  3445. tablecount:=0;
  3446. symtable^.foreach({$ifdef FPC}@{$endif}count_published_fields);
  3447. rttilist^.concat(new(pai_label,init(fieldtable)));
  3448. rttilist^.concat(new(pai_const,init_16bit(count)));
  3449. rttilist^.concat(new(pai_const_symbol,init(classtable)));
  3450. symtable^.foreach({$ifdef FPC}@{$endif}writefields);
  3451. { generate the class table }
  3452. rttilist^.concat(new(pai_label,init(classtable)));
  3453. rttilist^.concat(new(pai_const,init_16bit(tablecount)));
  3454. hp:=pclasslistitem(classtablelist.first);
  3455. while assigned(hp) do
  3456. begin
  3457. rttilist^.concat(new(pai_const_symbol,initname(pobjectdef(hp^.p)^.vmt_mangledname)));
  3458. hp:=pclasslistitem(hp^.next);
  3459. end;
  3460. generate_field_table:=fieldtable;
  3461. classtablelist.done;
  3462. end;
  3463. function tobjectdef.next_free_name_index : longint;
  3464. var
  3465. i : longint;
  3466. begin
  3467. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  3468. i:=childof^.next_free_name_index
  3469. else
  3470. i:=0;
  3471. count:=0;
  3472. symtable^.foreach({$ifndef TP}@{$endif}count_published_properties);
  3473. next_free_name_index:=i+count;
  3474. end;
  3475. procedure tobjectdef.write_rtti_data;
  3476. begin
  3477. if is_class then
  3478. rttilist^.concat(new(pai_const,init_8bit(tkclass)))
  3479. else
  3480. rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  3481. { generate the name }
  3482. rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
  3483. rttilist^.concat(new(pai_string,init(objname^)));
  3484. { write class type }
  3485. rttilist^.concat(new(pai_const_symbol,initname(vmt_mangledname)));
  3486. { write owner typeinfo }
  3487. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  3488. rttilist^.concat(new(pai_const_symbol,initname(childof^.get_rtti_label)))
  3489. else
  3490. rttilist^.concat(new(pai_const,init_32bit(0)));
  3491. { count total number of properties }
  3492. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  3493. count:=childof^.next_free_name_index
  3494. else
  3495. count:=0;
  3496. { write it }
  3497. symtable^.foreach({$ifndef TP}@{$endif}count_published_properties);
  3498. rttilist^.concat(new(pai_const,init_16bit(count)));
  3499. { write unit name }
  3500. if assigned(owner^.name) then
  3501. begin
  3502. rttilist^.concat(new(pai_const,init_8bit(length(owner^.name^))));
  3503. rttilist^.concat(new(pai_string,init(owner^.name^)));
  3504. end
  3505. else
  3506. rttilist^.concat(new(pai_const,init_8bit(0)));
  3507. { write published properties count }
  3508. count:=0;
  3509. symtable^.foreach({$ifndef TP}@{$endif}count_published_properties);
  3510. rttilist^.concat(new(pai_const,init_16bit(count)));
  3511. { count is used to write nameindex }
  3512. { but we need an offset of the owner }
  3513. { to give each property an own slot }
  3514. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  3515. count:=childof^.next_free_name_index
  3516. else
  3517. count:=0;
  3518. symtable^.foreach({$ifndef TP}@{$endif}write_property_info);
  3519. end;
  3520. function tobjectdef.is_publishable : boolean;
  3521. begin
  3522. is_publishable:=is_class;
  3523. end;
  3524. function tobjectdef.get_rtti_label : string;
  3525. begin
  3526. generate_rtti;
  3527. get_rtti_label:=rtti_name;
  3528. end;
  3529. {****************************************************************************
  3530. TFORWARDDEF
  3531. ****************************************************************************}
  3532. constructor tforwarddef.init(const s:string;const pos : tfileposinfo);
  3533. var
  3534. oldregisterdef : boolean;
  3535. begin
  3536. { never register the forwarddefs, they are disposed at the
  3537. end of the type declaration block }
  3538. oldregisterdef:=registerdef;
  3539. registerdef:=false;
  3540. inherited init;
  3541. registerdef:=oldregisterdef;
  3542. deftype:=forwarddef;
  3543. tosymname:=s;
  3544. forwardpos:=pos;
  3545. end;
  3546. function tforwarddef.gettypename:string;
  3547. begin
  3548. gettypename:='unresolved forward to '+tosymname;
  3549. end;
  3550. {****************************************************************************
  3551. TERRORDEF
  3552. ****************************************************************************}
  3553. constructor terrordef.init;
  3554. begin
  3555. inherited init;
  3556. deftype:=errordef;
  3557. end;
  3558. {$ifdef GDB}
  3559. function terrordef.stabstring : pchar;
  3560. begin
  3561. stabstring:=strpnew('error'+numberstring);
  3562. end;
  3563. {$endif GDB}
  3564. function terrordef.gettypename:string;
  3565. begin
  3566. gettypename:='<erroneous type>';
  3567. end;
  3568. {
  3569. $Log$
  3570. Revision 1.205 2000-06-30 22:11:29 peter
  3571. * fixed some getlabel to getdatalabel
  3572. Revision 1.204 2000/06/29 08:42:47 sg
  3573. * Fix for class field table writing
  3574. Revision 1.203 2000/06/25 09:25:29 peter
  3575. * setdef.typename, show Empty Set if elementtype is not set
  3576. Revision 1.202 2000/06/22 20:01:57 peter
  3577. * int64,qword rtti support
  3578. Revision 1.201 2000/06/18 18:11:32 peter
  3579. * C record packing fixed to also check first entry of the record
  3580. if bigger than the recordalignment itself
  3581. * variant record alignment uses alignment per variant and saves the
  3582. highest alignment value
  3583. Revision 1.200 2000/06/02 18:48:47 florian
  3584. + fieldtable support for classes
  3585. Revision 1.199 2000/04/01 14:17:08 peter
  3586. * arraydef.elesize returns 4 when strings are found in an openarray,
  3587. arrayconstructor. Since only the pointers to the strings are stored
  3588. Revision 1.198 2000/04/01 11:44:56 peter
  3589. * fixed rtti info for record
  3590. Revision 1.197 2000/03/01 12:35:45 pierre
  3591. * fix for bug 855
  3592. Revision 1.196 2000/02/14 20:58:43 marco
  3593. * Basic structures for new sethandling implemented.
  3594. Revision 1.195 2000/02/11 13:53:49 pierre
  3595. * avoid stack overflow in tref.done (bug 846)
  3596. Revision 1.194 2000/02/09 13:23:04 peter
  3597. * log truncated
  3598. Revision 1.193 2000/02/05 14:33:32 florian
  3599. * fixed init table generation for classes and arrays
  3600. Revision 1.192 2000/02/04 20:00:22 florian
  3601. * an exception in a construcor calls now the destructor (this applies only
  3602. to classes)
  3603. Revision 1.191 2000/01/30 23:29:06 peter
  3604. * fixed dup rtti writing for classes
  3605. Revision 1.190 2000/01/28 23:17:53 florian
  3606. * virtual XXXX; support for objects, only if -dWITHDMT is defined
  3607. Revision 1.189 2000/01/26 12:02:29 peter
  3608. * abstractprocdef.para_size needs alignment parameter
  3609. * secondcallparan gets para_alignment size instead of dword_align
  3610. Revision 1.188 2000/01/23 16:35:31 peter
  3611. * localbrowser loading of absolute fixed. It needed a symtablestack
  3612. which was not setup correctly
  3613. Revision 1.187 2000/01/09 23:16:06 peter
  3614. * added st_default stringtype
  3615. * genstringconstnode extended with stringtype parameter using st_default
  3616. will do the old behaviour
  3617. Revision 1.186 2000/01/07 01:14:39 peter
  3618. * updated copyright to 2000
  3619. Revision 1.185 2000/01/03 19:26:03 peter
  3620. * fixed resolving of ttypesym which are reference from object/record
  3621. fields.
  3622. Revision 1.184 1999/12/31 14:24:34 peter
  3623. * fixed rtti generation for classes with no published section
  3624. Revision 1.183 1999/12/23 12:19:42 peter
  3625. * check_rec_inittable fix from sg
  3626. Revision 1.182 1999/12/19 17:00:27 peter
  3627. * has_rtti should be saved in the ppu for objects
  3628. Revision 1.181 1999/12/18 14:55:21 florian
  3629. * very basic widestring support
  3630. Revision 1.180 1999/12/06 18:21:03 peter
  3631. * support !ENVVAR for long commandlines
  3632. * win32/go32v2 write short pathnames to link.res so c:\Program Files\ is
  3633. finally supported as installdir.
  3634. Revision 1.179 1999/12/01 12:42:33 peter
  3635. * fixed bug 698
  3636. * removed some notes about unused vars
  3637. Revision 1.178 1999/12/01 10:26:38 pierre
  3638. * restore the correct way for stabs of forward defs
  3639. Revision 1.177 1999/11/30 10:40:54 peter
  3640. + ttype, tsymlist
  3641. Revision 1.176 1999/11/09 23:35:49 pierre
  3642. + better reference pos for forward defs
  3643. Revision 1.175 1999/11/07 23:57:36 pierre
  3644. + higher level browser
  3645. Revision 1.174 1999/11/06 14:34:26 peter
  3646. * truncated log to 20 revs
  3647. }