symdef.inc 127 KB

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