symdef.inc 115 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032
  1. {
  2. $Id$
  3. Copyright (c) 1993-98 by Florian Klaempfl, Pierre Muller
  4. Symbol table implementation for the definitions
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. {****************************************************************************
  19. TDEF (base class for definitions)
  20. ****************************************************************************}
  21. const
  22. { if you change one of the following contants, }
  23. { you have also to change the typinfo unit }
  24. { and the rtl/[i386,template/rttip.inc files }
  25. tkUnknown = 0;
  26. tkInteger = 1;
  27. tkChar = 2;
  28. tkEnumeration = 3;
  29. tkFloat = 4;
  30. tkSet = 5;
  31. tkMethod = 6;
  32. tkSString = 7;
  33. tkString = tkSString;
  34. tkLString = 8;
  35. tkAString = 9;
  36. tkWString = 10;
  37. tkVariant = 11;
  38. tkArray = 12;
  39. tkRecord = 13;
  40. tkInterface = 14;
  41. tkClass = 15;
  42. tkObject = 16;
  43. tkWChar = 17;
  44. tkBool = 18;
  45. otSByte = 0;
  46. otUByte = 1;
  47. otSWord = 2;
  48. otUWord = 3;
  49. otSLong = 4;
  50. otULong = 5;
  51. ftSingle = 0;
  52. ftDouble = 1;
  53. ftExtended = 2;
  54. ftComp = 3;
  55. ftCurr = 4;
  56. ftFixed16 = 5;
  57. ftFixed32 = 6;
  58. constructor tdef.init;
  59. begin
  60. inherited init;
  61. deftype:=abstractdef;
  62. owner := nil;
  63. sym := nil;
  64. savesize := 0;
  65. if registerdef then
  66. symtablestack^.registerdef(@self);
  67. has_rtti:=false;
  68. has_inittable:=false;
  69. {$ifdef GDB}
  70. is_def_stab_written := false;
  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. end;
  86. constructor tdef.load;
  87. begin
  88. deftype:=abstractdef;
  89. next := nil;
  90. owner := nil;
  91. has_rtti:=false;
  92. has_inittable:=false;
  93. {$ifdef GDB}
  94. is_def_stab_written := false;
  95. globalnb := 0;
  96. {$endif GDB}
  97. if assigned(lastglobaldef) then
  98. begin
  99. lastglobaldef^.nextglobal := @self;
  100. previousglobal:=lastglobaldef;
  101. end
  102. else
  103. begin
  104. firstglobaldef := @self;
  105. previousglobal:=nil;
  106. end;
  107. lastglobaldef := @self;
  108. nextglobal := nil;
  109. { load }
  110. indexnr:=readword;
  111. sym:=ptypesym(readsymref);
  112. end;
  113. destructor tdef.done;
  114. begin
  115. { first element ? }
  116. if not(assigned(previousglobal)) then
  117. begin
  118. firstglobaldef := nextglobal;
  119. if assigned(firstglobaldef) then
  120. firstglobaldef^.previousglobal:=nil;
  121. end
  122. else
  123. begin
  124. { remove reference in the element before }
  125. previousglobal^.nextglobal:=nextglobal;
  126. end;
  127. { last element ? }
  128. if not(assigned(nextglobal)) then
  129. begin
  130. lastglobaldef := previousglobal;
  131. if assigned(lastglobaldef) then
  132. lastglobaldef^.nextglobal:=nil;
  133. end
  134. else
  135. nextglobal^.previousglobal:=previousglobal;
  136. previousglobal:=nil;
  137. nextglobal:=nil;
  138. while assigned(sym) do
  139. begin
  140. sym^.definition:=nil;
  141. sym:=sym^.synonym;
  142. end;
  143. end;
  144. { used for enumdef because the symbols are
  145. inserted in the owner symtable }
  146. procedure tdef.correct_owner_symtable;
  147. var
  148. st : psymtable;
  149. begin
  150. if assigned(owner) and
  151. (owner^.symtabletype in [recordsymtable,objectsymtable]) then
  152. begin
  153. owner^.defindex^.deleteindex(@self);
  154. st:=owner;
  155. while (st^.symtabletype in [recordsymtable,objectsymtable]) do
  156. st:=st^.next;
  157. st^.registerdef(@self);
  158. end;
  159. end;
  160. function tdef.typename:string;
  161. begin
  162. if assigned(sym) then
  163. typename:=Upper(sym^.name)
  164. else
  165. typename:=gettypename;
  166. end;
  167. function tdef.gettypename : string;
  168. begin
  169. gettypename:='<unknown type>'
  170. end;
  171. function tdef.is_in_current : boolean;
  172. var
  173. p : psymtable;
  174. begin
  175. p:=owner;
  176. is_in_current:=false;
  177. while assigned(p) do
  178. begin
  179. if (p=current_module^.globalsymtable) or (p=current_module^.localsymtable)
  180. or (p^.symtabletype in [globalsymtable,staticsymtable]) then
  181. begin
  182. is_in_current:=true;
  183. exit;
  184. end
  185. else if p^.symtabletype=objectsymtable then
  186. begin
  187. if assigned(p^.defowner) then
  188. p:=pobjectdef(p^.defowner)^.owner
  189. else
  190. exit;
  191. end
  192. else
  193. exit;
  194. end;
  195. end;
  196. procedure tdef.write;
  197. begin
  198. writeword(indexnr);
  199. writesymref(sym);
  200. {$ifdef GDB}
  201. if globalnb = 0 then
  202. begin
  203. if assigned(owner) then
  204. globalnb := owner^.getnewtypecount
  205. else
  206. begin
  207. globalnb := PGlobalTypeCount^;
  208. Inc(PGlobalTypeCount^);
  209. end;
  210. end;
  211. {$endif GDB}
  212. end;
  213. function tdef.size : longint;
  214. begin
  215. size:=savesize;
  216. end;
  217. function tdef.alignment : longint;
  218. begin
  219. { normal alignment by default }
  220. alignment:=0;
  221. end;
  222. {$ifdef GDB}
  223. procedure tdef.set_globalnb;
  224. begin
  225. globalnb :=PGlobalTypeCount^;
  226. inc(PglobalTypeCount^);
  227. end;
  228. function tdef.stabstring : pchar;
  229. begin
  230. stabstring := strpnew('t'+numberstring+';');
  231. end;
  232. function tdef.numberstring : string;
  233. var table : psymtable;
  234. begin
  235. {formal def have no type !}
  236. if deftype = formaldef then
  237. begin
  238. numberstring := voiddef^.numberstring;
  239. exit;
  240. end;
  241. if (not assigned(sym)) or (not sym^.isusedinstab) then
  242. begin
  243. {set even if debuglist is not defined}
  244. if assigned(sym) then
  245. sym^.isusedinstab := true;
  246. if assigned(debuglist) and not is_def_stab_written then
  247. concatstabto(debuglist);
  248. end;
  249. if not (cs_gdb_dbx in aktglobalswitches) then
  250. begin
  251. if globalnb = 0 then
  252. set_globalnb;
  253. numberstring := tostr(globalnb);
  254. end
  255. else
  256. begin
  257. if globalnb = 0 then
  258. begin
  259. if assigned(owner) then
  260. globalnb := owner^.getnewtypecount
  261. else
  262. begin
  263. globalnb := PGlobalTypeCount^;
  264. Inc(PGlobalTypeCount^);
  265. end;
  266. end;
  267. if assigned(sym) then
  268. begin
  269. table := sym^.owner;
  270. if table^.unitid > 0 then
  271. numberstring := '('+tostr(table^.unitid)+','
  272. +tostr(sym^.definition^.globalnb)+')'
  273. else
  274. numberstring := tostr(globalnb);
  275. exit;
  276. end;
  277. numberstring := tostr(globalnb);
  278. end;
  279. end;
  280. function tdef.allstabstring : pchar;
  281. var stabchar : string[2];
  282. ss,st : pchar;
  283. sname : string;
  284. sym_line_no : longint;
  285. begin
  286. ss := stabstring;
  287. getmem(st,strlen(ss)+512);
  288. stabchar := 't';
  289. if deftype in tagtypes then
  290. stabchar := 'Tt';
  291. if assigned(sym) then
  292. begin
  293. sname := sym^.name;
  294. sym_line_no:=sym^.fileinfo.line;
  295. end
  296. else
  297. begin
  298. sname := ' ';
  299. sym_line_no:=0;
  300. end;
  301. strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
  302. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  303. allstabstring := strnew(st);
  304. freemem(st,strlen(ss)+512);
  305. strdispose(ss);
  306. end;
  307. procedure tdef.concatstabto(asmlist : paasmoutput);
  308. var stab_str : pchar;
  309. begin
  310. if ((sym = nil) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  311. and not is_def_stab_written then
  312. begin
  313. If cs_gdb_dbx in aktglobalswitches then
  314. begin
  315. { otherwise you get two of each def }
  316. If assigned(sym) then
  317. begin
  318. if sym^.typ=typesym then
  319. sym^.isusedinstab:=true;
  320. if (sym^.owner = nil) or
  321. ((sym^.owner^.symtabletype = unitsymtable) and
  322. punitsymtable(sym^.owner)^.dbx_count_ok) then
  323. begin
  324. {with DBX we get the definition from the other objects }
  325. is_def_stab_written := true;
  326. exit;
  327. end;
  328. end;
  329. end;
  330. { to avoid infinite loops }
  331. is_def_stab_written := true;
  332. stab_str := allstabstring;
  333. if asmlist = debuglist then do_count_dbx := true;
  334. { count_dbx(stab_str); moved to GDB.PAS}
  335. asmlist^.concat(new(pai_stabs,init(stab_str)));
  336. end;
  337. end;
  338. {$endif GDB}
  339. procedure tdef.deref;
  340. begin
  341. end;
  342. procedure tdef.symderef;
  343. begin
  344. resolvesym(psym(sym));
  345. end;
  346. { rtti generation }
  347. procedure tdef.generate_rtti;
  348. begin
  349. has_rtti:=true;
  350. getdatalabel(rtti_label);
  351. write_child_rtti_data;
  352. rttilist^.concat(new(pai_symbol,init(rtti_label)));
  353. write_rtti_data;
  354. end;
  355. function tdef.get_rtti_label : string;
  356. begin
  357. if not(has_rtti) then
  358. generate_rtti;
  359. get_rtti_label:=rtti_label^.name;
  360. end;
  361. { init table handling }
  362. function tdef.needs_inittable : boolean;
  363. begin
  364. needs_inittable:=false;
  365. end;
  366. procedure tdef.generate_inittable;
  367. begin
  368. has_inittable:=true;
  369. getdatalabel(inittable_label);
  370. write_child_init_data;
  371. rttilist^.concat(new(pai_label,init(inittable_label)));
  372. write_init_data;
  373. end;
  374. procedure tdef.write_init_data;
  375. begin
  376. write_rtti_data;
  377. end;
  378. procedure tdef.write_child_init_data;
  379. begin
  380. write_child_rtti_data;
  381. end;
  382. function tdef.get_inittable_label : pasmlabel;
  383. begin
  384. if not(has_inittable) then
  385. generate_inittable;
  386. get_inittable_label:=inittable_label;
  387. end;
  388. procedure tdef.write_rtti_name;
  389. var
  390. str : string;
  391. begin
  392. { name }
  393. if assigned(sym) then
  394. begin
  395. str:=sym^.name;
  396. rttilist^.concat(new(pai_string,init(chr(length(str))+str)));
  397. end
  398. else
  399. rttilist^.concat(new(pai_string,init(#0)))
  400. end;
  401. { returns true, if the definition can be published }
  402. function tdef.is_publishable : boolean;
  403. begin
  404. is_publishable:=false;
  405. end;
  406. procedure tdef.write_rtti_data;
  407. begin
  408. end;
  409. procedure tdef.write_child_rtti_data;
  410. begin
  411. end;
  412. {****************************************************************************
  413. TSTRINGDEF
  414. ****************************************************************************}
  415. constructor tstringdef.shortinit(l : byte);
  416. begin
  417. tdef.init;
  418. string_typ:=st_shortstring;
  419. deftype:=stringdef;
  420. len:=l;
  421. savesize:=len+1;
  422. end;
  423. constructor tstringdef.shortload;
  424. begin
  425. tdef.load;
  426. string_typ:=st_shortstring;
  427. deftype:=stringdef;
  428. len:=readbyte;
  429. savesize:=len+1;
  430. end;
  431. constructor tstringdef.longinit(l : longint);
  432. begin
  433. tdef.init;
  434. string_typ:=st_longstring;
  435. deftype:=stringdef;
  436. len:=l;
  437. savesize:=target_os.size_of_pointer;
  438. end;
  439. constructor tstringdef.longload;
  440. begin
  441. tdef.load;
  442. deftype:=stringdef;
  443. string_typ:=st_longstring;
  444. len:=readlong;
  445. savesize:=target_os.size_of_pointer;
  446. end;
  447. constructor tstringdef.ansiinit(l : longint);
  448. begin
  449. tdef.init;
  450. string_typ:=st_ansistring;
  451. deftype:=stringdef;
  452. len:=l;
  453. savesize:=target_os.size_of_pointer;
  454. end;
  455. constructor tstringdef.ansiload;
  456. begin
  457. tdef.load;
  458. deftype:=stringdef;
  459. string_typ:=st_ansistring;
  460. len:=readlong;
  461. savesize:=target_os.size_of_pointer;
  462. end;
  463. constructor tstringdef.wideinit(l : longint);
  464. begin
  465. tdef.init;
  466. string_typ:=st_widestring;
  467. deftype:=stringdef;
  468. len:=l;
  469. savesize:=target_os.size_of_pointer;
  470. end;
  471. constructor tstringdef.wideload;
  472. begin
  473. tdef.load;
  474. deftype:=stringdef;
  475. string_typ:=st_widestring;
  476. len:=readlong;
  477. savesize:=target_os.size_of_pointer;
  478. end;
  479. function tstringdef.stringtypname:string;
  480. const
  481. typname:array[tstringtype] of string[8]=(
  482. 'SHORTSTR','LONGSTR','ANSISTR','WIDESTR'
  483. );
  484. begin
  485. stringtypname:=typname[string_typ];
  486. end;
  487. function tstringdef.size : longint;
  488. begin
  489. size:=savesize;
  490. end;
  491. procedure tstringdef.write;
  492. begin
  493. tdef.write;
  494. if string_typ=st_shortstring then
  495. writebyte(len)
  496. else
  497. writelong(len);
  498. case string_typ of
  499. st_shortstring : current_ppu^.writeentry(ibshortstringdef);
  500. st_longstring : current_ppu^.writeentry(iblongstringdef);
  501. st_ansistring : current_ppu^.writeentry(ibansistringdef);
  502. st_widestring : current_ppu^.writeentry(ibwidestringdef);
  503. end;
  504. end;
  505. {$ifdef GDB}
  506. function tstringdef.stabstring : pchar;
  507. var
  508. bytest,charst,longst : string;
  509. begin
  510. case string_typ of
  511. st_shortstring:
  512. begin
  513. charst := typeglobalnumber('char');
  514. { this is what I found in stabs.texinfo but
  515. gdb 4.12 for go32 doesn't understand that !! }
  516. {$IfDef GDBknowsstrings}
  517. stabstring := strpnew('n'+charst+';'+tostr(len));
  518. {$else}
  519. bytest := typeglobalnumber('byte');
  520. stabstring := strpnew('s'+tostr(len+1)+'length:'+bytest
  521. +',0,8;st:ar'+bytest
  522. +';1;'+tostr(len)+';'+charst+',8,'+tostr(len*8)+';;');
  523. {$EndIf}
  524. end;
  525. st_longstring:
  526. begin
  527. charst := typeglobalnumber('char');
  528. { this is what I found in stabs.texinfo but
  529. gdb 4.12 for go32 doesn't understand that !! }
  530. {$IfDef GDBknowsstrings}
  531. stabstring := strpnew('n'+charst+';'+tostr(len));
  532. {$else}
  533. bytest := typeglobalnumber('byte');
  534. longst := typeglobalnumber('longint');
  535. stabstring := strpnew('s'+tostr(len+5)+'length:'+longst
  536. +',0,32;dummy:'+bytest+',32,8;st:ar'+bytest
  537. +';1;'+tostr(len)+';'+charst+',40,'+tostr(len*8)+';;');
  538. {$EndIf}
  539. end;
  540. st_ansistring:
  541. begin
  542. { an ansi string looks like a pchar easy !! }
  543. stabstring:=strpnew('*'+typeglobalnumber('char'));
  544. end;
  545. st_widestring:
  546. begin
  547. { an ansi string looks like a pchar easy !! }
  548. stabstring:=strpnew('*'+typeglobalnumber('char'));
  549. end;
  550. end;
  551. end;
  552. procedure tstringdef.concatstabto(asmlist : paasmoutput);
  553. begin
  554. inherited concatstabto(asmlist);
  555. end;
  556. {$endif GDB}
  557. function tstringdef.needs_inittable : boolean;
  558. begin
  559. needs_inittable:=string_typ in [st_ansistring,st_widestring];
  560. end;
  561. function tstringdef.gettypename : string;
  562. const
  563. names : array[tstringtype] of string[20] =
  564. ('ShortString','LongString','AnsiString','WideString');
  565. begin
  566. gettypename:=names[string_typ];
  567. end;
  568. procedure tstringdef.write_rtti_data;
  569. begin
  570. case string_typ of
  571. st_ansistring:
  572. begin
  573. rttilist^.concat(new(pai_const,init_8bit(tkAString)));
  574. write_rtti_name;
  575. end;
  576. st_widestring:
  577. begin
  578. rttilist^.concat(new(pai_const,init_8bit(tkWString)));
  579. write_rtti_name;
  580. end;
  581. st_longstring:
  582. begin
  583. rttilist^.concat(new(pai_const,init_8bit(tkLString)));
  584. write_rtti_name;
  585. end;
  586. st_shortstring:
  587. begin
  588. rttilist^.concat(new(pai_const,init_8bit(tkSString)));
  589. write_rtti_name;
  590. rttilist^.concat(new(pai_const,init_8bit(len)));
  591. end;
  592. end;
  593. end;
  594. function tstringdef.is_publishable : boolean;
  595. begin
  596. is_publishable:=true;
  597. end;
  598. {****************************************************************************
  599. TENUMDEF
  600. ****************************************************************************}
  601. constructor tenumdef.init;
  602. begin
  603. tdef.init;
  604. deftype:=enumdef;
  605. minval:=0;
  606. maxval:=0;
  607. calcsavesize;
  608. has_jumps:=false;
  609. basedef:=nil;
  610. rangenr:=0;
  611. firstenum:=nil;
  612. correct_owner_symtable;
  613. end;
  614. constructor tenumdef.init_subrange(_basedef:penumdef;_min,_max:longint);
  615. begin
  616. tdef.init;
  617. deftype:=enumdef;
  618. minval:=_min;
  619. maxval:=_max;
  620. basedef:=_basedef;
  621. calcsavesize;
  622. has_jumps:=false;
  623. rangenr:=0;
  624. firstenum:=basedef^.firstenum;
  625. while assigned(firstenum) and (penumsym(firstenum)^.value<>minval) do
  626. firstenum:=firstenum^.nextenum;
  627. correct_owner_symtable;
  628. end;
  629. constructor tenumdef.load;
  630. begin
  631. tdef.load;
  632. deftype:=enumdef;
  633. basedef:=penumdef(readdefref);
  634. minval:=readlong;
  635. maxval:=readlong;
  636. savesize:=readlong;
  637. has_jumps:=false;
  638. firstenum:=Nil;
  639. end;
  640. procedure tenumdef.calcsavesize;
  641. begin
  642. if (aktpackenum=4) or (min<0) or (max>65535) then
  643. savesize:=4
  644. else
  645. if (aktpackenum=2) or (min<0) or (max>255) then
  646. savesize:=2
  647. else
  648. savesize:=1;
  649. end;
  650. procedure tenumdef.setmax(_max:longint);
  651. begin
  652. maxval:=_max;
  653. calcsavesize;
  654. end;
  655. procedure tenumdef.setmin(_min:longint);
  656. begin
  657. minval:=_min;
  658. calcsavesize;
  659. end;
  660. function tenumdef.min:longint;
  661. begin
  662. min:=minval;
  663. end;
  664. function tenumdef.max:longint;
  665. begin
  666. max:=maxval;
  667. end;
  668. procedure tenumdef.deref;
  669. begin
  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_smartlink 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_smartlink in aktmoduleswitches) then
  699. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring)))
  700. else
  701. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring)));
  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(globals.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:
  848. savesize:=2;
  849. s32bit,u32bit,
  850. bool32bit:
  851. savesize:=4;
  852. u64bit,s64bitint:
  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_smartlink 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. begin
  870. if rangenr=0 then
  871. begin
  872. { generate two constant for bounds }
  873. getlabelnr(rangenr);
  874. if (cs_smartlink in aktmoduleswitches) then
  875. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring)))
  876. else
  877. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring)));
  878. if low<=high then
  879. begin
  880. datasegment^.concat(new(pai_const,init_32bit(low)));
  881. datasegment^.concat(new(pai_const,init_32bit(high)));
  882. end
  883. { for u32bit we need two bounds }
  884. else
  885. begin
  886. datasegment^.concat(new(pai_const,init_32bit(low)));
  887. datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
  888. datasegment^.concat(new(pai_const,init_32bit($80000000)));
  889. datasegment^.concat(new(pai_const,init_32bit(high)));
  890. end;
  891. end;
  892. end;
  893. procedure torddef.write;
  894. begin
  895. tdef.write;
  896. writebyte(byte(typ));
  897. writelong(low);
  898. writelong(high);
  899. current_ppu^.writeentry(iborddef);
  900. end;
  901. {$ifdef GDB}
  902. function torddef.stabstring : pchar;
  903. begin
  904. case typ of
  905. uvoid : stabstring := strpnew(numberstring+';');
  906. {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
  907. {$ifdef Use_integer_types_for_boolean}
  908. bool8bit,
  909. bool16bit,
  910. bool32bit : stabstring := strpnew('r'+numberstring+';0;255;');
  911. {$else : not Use_integer_types_for_boolean}
  912. bool8bit : stabstring := strpnew('-21;');
  913. bool16bit : stabstring := strpnew('-22;');
  914. bool32bit : stabstring := strpnew('-23;');
  915. u64bit : stabstring := strpnew('-32;');
  916. s64bitint : stabstring := strpnew('-31;');
  917. {$endif not Use_integer_types_for_boolean}
  918. { u32bit : stabstring := strpnew('r'+
  919. s32bitdef^.numberstring+';0;-1;'); }
  920. else
  921. stabstring := strpnew('r'+s32bitdef^.numberstring+';'+tostr(low)+';'+tostr(high)+';');
  922. end;
  923. end;
  924. {$endif GDB}
  925. procedure torddef.write_rtti_data;
  926. const
  927. trans : array[uchar..bool8bit] of byte =
  928. (otUByte,otUByte,otUWord,otULong,otSByte,otSWord,otSLong,otUByte);
  929. begin
  930. case typ of
  931. bool8bit:
  932. rttilist^.concat(new(pai_const,init_8bit(tkBool)));
  933. uchar:
  934. rttilist^.concat(new(pai_const,init_8bit(tkChar)));
  935. else
  936. rttilist^.concat(new(pai_const,init_8bit(tkInteger)));
  937. end;
  938. write_rtti_name;
  939. rttilist^.concat(new(pai_const,init_8bit(byte(trans[typ]))));
  940. rttilist^.concat(new(pai_const,init_32bit(low)));
  941. rttilist^.concat(new(pai_const,init_32bit(high)));
  942. end;
  943. function torddef.is_publishable : boolean;
  944. begin
  945. is_publishable:=typ in [uchar..bool8bit];
  946. end;
  947. function torddef.gettypename : string;
  948. const
  949. names : array[tbasetype] of string[20] = ('<unknown type>',
  950. 'untyped','Char','Byte','Word','DWord','ShortInt',
  951. 'SmallInt','LongInt','Boolean','WordBool',
  952. 'LongBool','QWord','Int64');
  953. begin
  954. gettypename:=names[typ];
  955. end;
  956. {****************************************************************************
  957. TFLOATDEF
  958. ****************************************************************************}
  959. constructor tfloatdef.init(t : tfloattype);
  960. begin
  961. inherited init;
  962. deftype:=floatdef;
  963. typ:=t;
  964. setsize;
  965. end;
  966. constructor tfloatdef.load;
  967. begin
  968. inherited load;
  969. deftype:=floatdef;
  970. typ:=tfloattype(readbyte);
  971. setsize;
  972. end;
  973. procedure tfloatdef.setsize;
  974. begin
  975. case typ of
  976. f16bit : savesize:=2;
  977. f32bit,
  978. s32real : savesize:=4;
  979. s64real : savesize:=8;
  980. s80real : savesize:=extended_size;
  981. s64comp : savesize:=8;
  982. else
  983. savesize:=0;
  984. end;
  985. end;
  986. procedure tfloatdef.write;
  987. begin
  988. inherited write;
  989. writebyte(byte(typ));
  990. current_ppu^.writeentry(ibfloatdef);
  991. end;
  992. {$ifdef GDB}
  993. function tfloatdef.stabstring : pchar;
  994. begin
  995. case typ of
  996. s32real,
  997. s64real : stabstring := strpnew('r'+
  998. s32bitdef^.numberstring+';'+tostr(savesize)+';0;');
  999. { for fixed real use longint instead to be able to }
  1000. { debug something at least }
  1001. f32bit:
  1002. stabstring := s32bitdef^.stabstring;
  1003. f16bit:
  1004. stabstring := strpnew('r'+s32bitdef^.numberstring+';0;'+
  1005. tostr($ffff)+';');
  1006. { found this solution in stabsread.c from GDB v4.16 }
  1007. s64comp : stabstring := strpnew('r'+
  1008. s32bitdef^.numberstring+';-'+tostr(savesize)+';0;');
  1009. {$ifdef i386}
  1010. { under dos at least you must give a size of twelve instead of 10 !! }
  1011. { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
  1012. s80real : stabstring := strpnew('r'+s32bitdef^.numberstring+';12;0;');
  1013. {$endif i386}
  1014. else
  1015. internalerror(10005);
  1016. end;
  1017. end;
  1018. {$endif GDB}
  1019. procedure tfloatdef.write_rtti_data;
  1020. const
  1021. {tfloattype = (s32real,s64real,s80real,s64bit,f16bit,f32bit);}
  1022. translate : array[tfloattype] of byte =
  1023. (ftSingle,ftDouble,ftExtended,ftComp,ftFixed16,ftFixed32);
  1024. begin
  1025. rttilist^.concat(new(pai_const,init_8bit(tkFloat)));
  1026. write_rtti_name;
  1027. rttilist^.concat(new(pai_const,init_8bit(translate[typ])));
  1028. end;
  1029. function tfloatdef.is_publishable : boolean;
  1030. begin
  1031. is_publishable:=true;
  1032. end;
  1033. function tfloatdef.gettypename : string;
  1034. const
  1035. names : array[tfloattype] of string[20] = (
  1036. 'Single','Double','Extended','Comp','Fixed','Fixed16');
  1037. begin
  1038. gettypename:=names[typ];
  1039. end;
  1040. {****************************************************************************
  1041. TFILEDEF
  1042. ****************************************************************************}
  1043. constructor tfiledef.init(ft : tfiletype;tas : pdef);
  1044. begin
  1045. inherited init;
  1046. deftype:=filedef;
  1047. filetype:=ft;
  1048. typed_as:=tas;
  1049. setsize;
  1050. end;
  1051. constructor tfiledef.load;
  1052. begin
  1053. inherited load;
  1054. deftype:=filedef;
  1055. filetype:=tfiletype(readbyte);
  1056. if filetype=ft_typed then
  1057. typed_as:=readdefref
  1058. else
  1059. typed_as:=nil;
  1060. setsize;
  1061. end;
  1062. procedure tfiledef.deref;
  1063. begin
  1064. if filetype=ft_typed then
  1065. resolvedef(typed_as);
  1066. end;
  1067. procedure tfiledef.setsize;
  1068. begin
  1069. case filetype of
  1070. ft_text : savesize:=572;
  1071. ft_typed,
  1072. ft_untyped : savesize:=316;
  1073. end;
  1074. end;
  1075. procedure tfiledef.write;
  1076. begin
  1077. inherited write;
  1078. writebyte(byte(filetype));
  1079. if filetype=ft_typed then
  1080. writedefref(typed_as);
  1081. current_ppu^.writeentry(ibfiledef);
  1082. end;
  1083. {$ifdef GDB}
  1084. function tfiledef.stabstring : pchar;
  1085. begin
  1086. {$IfDef GDBknowsfiles}
  1087. case filetyp of
  1088. ft_typed : stabstring := strpnew('d'+typed_as^.numberstring{+';'});
  1089. ft_untyped : stabstring := strpnew('d'+voiddef^.numberstring{+';'});
  1090. ft_text : stabstring := strpnew('d'+cchardef^.numberstring{+';'});
  1091. end;
  1092. {$Else}
  1093. {based on
  1094. FileRec = Packed Record
  1095. Handle,
  1096. Mode,
  1097. RecSize : longint;
  1098. _private : array[1..32] of byte;
  1099. UserData : array[1..16] of byte;
  1100. name : array[0..255] of char;
  1101. End; }
  1102. { the buffer part is still missing !! (PM) }
  1103. { but the string could become too long !! }
  1104. stabstring := strpnew('s'+tostr(savesize)+
  1105. 'HANDLE:'+typeglobalnumber('longint')+',0,32;'+
  1106. 'MODE:'+typeglobalnumber('longint')+',32,32;'+
  1107. 'RECSIZE:'+typeglobalnumber('longint')+',64,32;'+
  1108. '_PRIVATE:ar'+typeglobalnumber('word')+';1;32;'+typeglobalnumber('byte')
  1109. +',96,256;'+
  1110. 'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')
  1111. +',352,128;'+
  1112. 'NAME:ar'+typeglobalnumber('word')+';0;255;'+typeglobalnumber('char')
  1113. +',480,2048;;');
  1114. {$EndIf}
  1115. end;
  1116. procedure tfiledef.concatstabto(asmlist : paasmoutput);
  1117. begin
  1118. { most file defs are unnamed !!! }
  1119. if ((sym = nil) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1120. not is_def_stab_written then
  1121. begin
  1122. if assigned(typed_as) then forcestabto(asmlist,typed_as);
  1123. inherited concatstabto(asmlist);
  1124. end;
  1125. end;
  1126. {$endif GDB}
  1127. function tfiledef.gettypename : string;
  1128. begin
  1129. case filetype of
  1130. ft_untyped:
  1131. gettypename:='File';
  1132. ft_typed:
  1133. gettypename:='File Of '+typed_as^.typename;
  1134. ft_text:
  1135. gettypename:='Text'
  1136. end;
  1137. end;
  1138. {****************************************************************************
  1139. TPOINTERDEF
  1140. ****************************************************************************}
  1141. constructor tpointerdef.init(def : pdef);
  1142. begin
  1143. inherited init;
  1144. deftype:=pointerdef;
  1145. definition:=def;
  1146. is_far:=false;
  1147. savesize:=target_os.size_of_pointer;
  1148. end;
  1149. constructor tpointerdef.initfar(def : pdef);
  1150. begin
  1151. inherited init;
  1152. deftype:=pointerdef;
  1153. definition:=def;
  1154. is_far:=true;
  1155. savesize:=target_os.size_of_pointer;
  1156. end;
  1157. constructor tpointerdef.load;
  1158. begin
  1159. inherited load;
  1160. deftype:=pointerdef;
  1161. { the real address in memory is calculated later (deref) }
  1162. definition:=readdefref;
  1163. is_far:=(readbyte<>0);
  1164. savesize:=target_os.size_of_pointer;
  1165. end;
  1166. procedure tpointerdef.deref;
  1167. begin
  1168. resolvedef(definition);
  1169. end;
  1170. procedure tpointerdef.write;
  1171. begin
  1172. inherited write;
  1173. writedefref(definition);
  1174. writebyte(byte(is_far));
  1175. current_ppu^.writeentry(ibpointerdef);
  1176. end;
  1177. {$ifdef GDB}
  1178. function tpointerdef.stabstring : pchar;
  1179. begin
  1180. stabstring := strpnew('*'+definition^.numberstring);
  1181. end;
  1182. procedure tpointerdef.concatstabto(asmlist : paasmoutput);
  1183. var st,nb : string;
  1184. sym_line_no : longint;
  1185. begin
  1186. if ( (sym=nil) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1187. not is_def_stab_written then
  1188. begin
  1189. if assigned(definition) then
  1190. if definition^.deftype in [recorddef,objectdef] then
  1191. begin
  1192. is_def_stab_written := true;
  1193. {to avoid infinite recursion in record with next-like fields }
  1194. nb := definition^.numberstring;
  1195. is_def_stab_written := false;
  1196. if not definition^.is_def_stab_written then
  1197. begin
  1198. if assigned(definition^.sym) then
  1199. begin
  1200. if assigned(sym) then
  1201. begin
  1202. st := sym^.name;
  1203. sym_line_no:=sym^.fileinfo.line;
  1204. end
  1205. else
  1206. begin
  1207. st := ' ';
  1208. sym_line_no:=0;
  1209. end;
  1210. st := '"'+st+':t'+numberstring+'=*'+definition^.numberstring
  1211. +'=xs'+definition^.sym^.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
  1212. if asmlist = debuglist then do_count_dbx := true;
  1213. asmlist^.concat(new(pai_stabs,init(strpnew(st))));
  1214. end;
  1215. end else inherited concatstabto(asmlist);
  1216. is_def_stab_written := true;
  1217. end else
  1218. begin
  1219. { p =^p1; p1=^p problem }
  1220. is_def_stab_written := true;
  1221. forcestabto(asmlist,definition);
  1222. is_def_stab_written := false;
  1223. inherited concatstabto(asmlist);
  1224. end;
  1225. end;
  1226. end;
  1227. {$endif GDB}
  1228. function tpointerdef.gettypename : string;
  1229. begin
  1230. gettypename:='^'+definition^.typename;
  1231. end;
  1232. {****************************************************************************
  1233. TCLASSREFDEF
  1234. ****************************************************************************}
  1235. constructor tclassrefdef.init(def : pdef);
  1236. begin
  1237. inherited init(def);
  1238. deftype:=classrefdef;
  1239. definition:=def;
  1240. savesize:=target_os.size_of_pointer;
  1241. end;
  1242. constructor tclassrefdef.load;
  1243. begin
  1244. { be careful, tclassdefref inherits from tpointerdef }
  1245. tdef.load;
  1246. deftype:=classrefdef;
  1247. definition:=readdefref;
  1248. is_far:=false;
  1249. savesize:=target_os.size_of_pointer;
  1250. end;
  1251. procedure tclassrefdef.write;
  1252. begin
  1253. { be careful, tclassdefref inherits from tpointerdef }
  1254. tdef.write;
  1255. writedefref(definition);
  1256. current_ppu^.writeentry(ibclassrefdef);
  1257. end;
  1258. {$ifdef GDB}
  1259. function tclassrefdef.stabstring : pchar;
  1260. begin
  1261. stabstring:=strpnew('');
  1262. end;
  1263. procedure tclassrefdef.concatstabto(asmlist : paasmoutput);
  1264. begin
  1265. end;
  1266. {$endif GDB}
  1267. function tclassrefdef.gettypename : string;
  1268. begin
  1269. gettypename:='Class Of '+definition^.typename;
  1270. end;
  1271. {***************************************************************************
  1272. TSETDEF
  1273. ***************************************************************************}
  1274. { For i386 smallsets work,
  1275. for m68k there are problems
  1276. can be test by compiling with -dusesmallset PM }
  1277. {$ifdef i386}
  1278. {$define usesmallset}
  1279. {$endif i386}
  1280. constructor tsetdef.init(s : pdef;high : longint);
  1281. begin
  1282. inherited init;
  1283. deftype:=setdef;
  1284. setof:=s;
  1285. {$ifdef usesmallset}
  1286. { small sets only working for i386 PM }
  1287. if high<32 then
  1288. begin
  1289. settype:=smallset;
  1290. savesize:=Sizeof(longint);
  1291. end
  1292. else
  1293. {$endif usesmallset}
  1294. if high<256 then
  1295. begin
  1296. settype:=normset;
  1297. savesize:=32;
  1298. end
  1299. else
  1300. {$ifdef testvarsets}
  1301. if high<$10000 then
  1302. begin
  1303. settype:=varset;
  1304. savesize:=4*((high+31) div 32);
  1305. end
  1306. else
  1307. {$endif testvarsets}
  1308. Message(sym_e_ill_type_decl_set);
  1309. end;
  1310. constructor tsetdef.load;
  1311. begin
  1312. inherited load;
  1313. deftype:=setdef;
  1314. setof:=readdefref;
  1315. settype:=tsettype(readbyte);
  1316. case settype of
  1317. normset : savesize:=32;
  1318. varset : savesize:=readlong;
  1319. smallset : savesize:=Sizeof(longint);
  1320. end;
  1321. end;
  1322. procedure tsetdef.write;
  1323. begin
  1324. inherited write;
  1325. writedefref(setof);
  1326. writebyte(byte(settype));
  1327. if settype=varset then
  1328. writelong(savesize);
  1329. current_ppu^.writeentry(ibsetdef);
  1330. end;
  1331. {$ifdef GDB}
  1332. function tsetdef.stabstring : pchar;
  1333. begin
  1334. stabstring := strpnew('S'+setof^.numberstring);
  1335. end;
  1336. procedure tsetdef.concatstabto(asmlist : paasmoutput);
  1337. begin
  1338. if ( not assigned(sym) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1339. not is_def_stab_written then
  1340. begin
  1341. if assigned(setof) then
  1342. forcestabto(asmlist,setof);
  1343. inherited concatstabto(asmlist);
  1344. end;
  1345. end;
  1346. {$endif GDB}
  1347. procedure tsetdef.deref;
  1348. begin
  1349. resolvedef(setof);
  1350. end;
  1351. procedure tsetdef.write_rtti_data;
  1352. begin
  1353. rttilist^.concat(new(pai_const,init_8bit(tkSet)));
  1354. write_rtti_name;
  1355. rttilist^.concat(new(pai_const,init_8bit(otULong)));
  1356. rttilist^.concat(new(pai_const_symbol,initname(setof^.get_rtti_label)));
  1357. end;
  1358. procedure tsetdef.write_child_rtti_data;
  1359. begin
  1360. setof^.get_rtti_label;
  1361. end;
  1362. function tsetdef.is_publishable : boolean;
  1363. begin
  1364. is_publishable:=settype=smallset;
  1365. end;
  1366. function tsetdef.gettypename : string;
  1367. begin
  1368. gettypename:='Set Of '+setof^.typename;
  1369. end;
  1370. {***************************************************************************
  1371. TFORMALDEF
  1372. ***************************************************************************}
  1373. constructor tformaldef.init;
  1374. var
  1375. stregdef : boolean;
  1376. begin
  1377. stregdef:=registerdef;
  1378. registerdef:=false;
  1379. inherited init;
  1380. deftype:=formaldef;
  1381. registerdef:=stregdef;
  1382. { formaldef must be registered at unit level !! }
  1383. if registerdef and assigned(current_module) then
  1384. if assigned(current_module^.localsymtable) then
  1385. psymtable(current_module^.localsymtable)^.registerdef(@self)
  1386. else if assigned(current_module^.globalsymtable) then
  1387. psymtable(current_module^.globalsymtable)^.registerdef(@self);
  1388. savesize:=target_os.size_of_pointer;
  1389. end;
  1390. constructor tformaldef.load;
  1391. begin
  1392. inherited load;
  1393. deftype:=formaldef;
  1394. savesize:=target_os.size_of_pointer;
  1395. end;
  1396. procedure tformaldef.write;
  1397. begin
  1398. inherited write;
  1399. current_ppu^.writeentry(ibformaldef);
  1400. end;
  1401. {$ifdef GDB}
  1402. function tformaldef.stabstring : pchar;
  1403. begin
  1404. stabstring := strpnew('formal'+numberstring+';');
  1405. end;
  1406. procedure tformaldef.concatstabto(asmlist : paasmoutput);
  1407. begin
  1408. { formaldef can't be stab'ed !}
  1409. end;
  1410. {$endif GDB}
  1411. function tformaldef.gettypename : string;
  1412. begin
  1413. gettypename:='Var';
  1414. end;
  1415. {***************************************************************************
  1416. TARRAYDEF
  1417. ***************************************************************************}
  1418. constructor tarraydef.init(l,h : longint;rd : pdef);
  1419. begin
  1420. inherited init;
  1421. deftype:=arraydef;
  1422. lowrange:=l;
  1423. highrange:=h;
  1424. rangedef:=rd;
  1425. definition:=nil;
  1426. IsVariant:=false;
  1427. IsConstructor:=false;
  1428. IsArrayOfConst:=false;
  1429. rangenr:=0;
  1430. end;
  1431. constructor tarraydef.load;
  1432. begin
  1433. inherited load;
  1434. deftype:=arraydef;
  1435. { the addresses are calculated later }
  1436. definition:=readdefref;
  1437. rangedef:=readdefref;
  1438. lowrange:=readlong;
  1439. highrange:=readlong;
  1440. IsArrayOfConst:=boolean(readbyte);
  1441. IsVariant:=false;
  1442. IsConstructor:=false;
  1443. rangenr:=0;
  1444. end;
  1445. function tarraydef.getrangecheckstring : string;
  1446. begin
  1447. if (cs_smartlink in aktmoduleswitches) then
  1448. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  1449. else
  1450. getrangecheckstring:='R_'+tostr(rangenr);
  1451. end;
  1452. procedure tarraydef.genrangecheck;
  1453. begin
  1454. if rangenr=0 then
  1455. begin
  1456. { generates the data for range checking }
  1457. getlabelnr(rangenr);
  1458. if (cs_smartlink in aktmoduleswitches) then
  1459. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring)))
  1460. else
  1461. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring)));
  1462. datasegment^.concat(new(pai_const,init_32bit(lowrange)));
  1463. datasegment^.concat(new(pai_const,init_32bit(highrange)));
  1464. end;
  1465. end;
  1466. procedure tarraydef.deref;
  1467. begin
  1468. resolvedef(definition);
  1469. resolvedef(rangedef);
  1470. end;
  1471. procedure tarraydef.write;
  1472. begin
  1473. inherited write;
  1474. writedefref(definition);
  1475. writedefref(rangedef);
  1476. writelong(lowrange);
  1477. writelong(highrange);
  1478. writebyte(byte(IsArrayOfConst));
  1479. current_ppu^.writeentry(ibarraydef);
  1480. end;
  1481. {$ifdef GDB}
  1482. function tarraydef.stabstring : pchar;
  1483. begin
  1484. stabstring := strpnew('ar'+rangedef^.numberstring+';'
  1485. +tostr(lowrange)+';'+tostr(highrange)+';'+definition^.numberstring);
  1486. end;
  1487. procedure tarraydef.concatstabto(asmlist : paasmoutput);
  1488. begin
  1489. if (not assigned(sym) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  1490. and not is_def_stab_written then
  1491. begin
  1492. {when array are inserted they have no definition yet !!}
  1493. if assigned(definition) then
  1494. inherited concatstabto(asmlist);
  1495. end;
  1496. end;
  1497. {$endif GDB}
  1498. function tarraydef.elesize : longint;
  1499. begin
  1500. elesize:=definition^.size;
  1501. end;
  1502. function tarraydef.size : longint;
  1503. begin
  1504. { dirty hack to overcome an overflow (PFV) }
  1505. if highrange=$7fffffff then
  1506. size:=$7fffffff
  1507. else
  1508. size:=(highrange-lowrange+1)*elesize;
  1509. end;
  1510. function tarraydef.alignment : longint;
  1511. begin
  1512. { alignment is the size of the elements }
  1513. alignment:=definition^.size;
  1514. end;
  1515. function tarraydef.needs_inittable : boolean;
  1516. begin
  1517. needs_inittable:=definition^.needs_inittable;
  1518. end;
  1519. procedure tarraydef.write_child_rtti_data;
  1520. begin
  1521. definition^.get_rtti_label;
  1522. end;
  1523. procedure tarraydef.write_rtti_data;
  1524. begin
  1525. rttilist^.concat(new(pai_const,init_8bit(13)));
  1526. write_rtti_name;
  1527. { size of elements }
  1528. rttilist^.concat(new(pai_const,init_32bit(definition^.size)));
  1529. { count of elements }
  1530. rttilist^.concat(new(pai_const,init_32bit(highrange-lowrange+1)));
  1531. { element type }
  1532. rttilist^.concat(new(pai_const_symbol,initname(definition^.get_rtti_label)));
  1533. end;
  1534. function tarraydef.gettypename : string;
  1535. begin
  1536. if isarrayofconst or isConstructor then
  1537. gettypename:='Array Of Const'
  1538. else if is_open_array(@self) then
  1539. gettypename:='Array Of '+definition^.typename
  1540. else
  1541. begin
  1542. if rangedef^.deftype=enumdef then
  1543. gettypename:='Array['+rangedef^.typename+'] Of '+definition^.typename
  1544. else
  1545. gettypename:='Array['+tostr(lowrange)+'..'+
  1546. tostr(highrange)+'] Of '+definition^.typename
  1547. end;
  1548. end;
  1549. {***************************************************************************
  1550. TRECDEF
  1551. ***************************************************************************}
  1552. constructor trecdef.init(p : psymtable);
  1553. begin
  1554. inherited init;
  1555. deftype:=recorddef;
  1556. symtable:=p;
  1557. savesize:=symtable^.datasize;
  1558. symtable^.defowner := @self;
  1559. symtable^.dataalignment:=packrecordalignment[aktpackrecords];
  1560. end;
  1561. constructor trecdef.load;
  1562. var
  1563. oldread_member : boolean;
  1564. begin
  1565. inherited load;
  1566. deftype:=recorddef;
  1567. savesize:=readlong;
  1568. oldread_member:=read_member;
  1569. read_member:=true;
  1570. symtable:=new(psymtable,loadas(recordsymtable));
  1571. read_member:=oldread_member;
  1572. symtable^.defowner := @self;
  1573. end;
  1574. destructor trecdef.done;
  1575. begin
  1576. if assigned(symtable) then
  1577. dispose(symtable,done);
  1578. inherited done;
  1579. end;
  1580. var
  1581. binittable : boolean;
  1582. procedure check_rec_inittable(s : pnamedindexobject);
  1583. begin
  1584. if (psym(s)^.typ=varsym) and
  1585. ((pvarsym(s)^.definition^.deftype<>objectdef) or
  1586. not(pobjectdef(pvarsym(s)^.definition)^.isclass)) then
  1587. binittable:=pvarsym(s)^.definition^.needs_inittable;
  1588. end;
  1589. function trecdef.needs_inittable : boolean;
  1590. var
  1591. oldb : boolean;
  1592. begin
  1593. { there are recursive calls to needs_rtti possible, }
  1594. { so we have to change to old value how else should }
  1595. { we do that ? check_rec_rtti can't be a nested }
  1596. { procedure of needs_rtti ! }
  1597. oldb:=binittable;
  1598. binittable:=false;
  1599. symtable^.foreach({$ifndef TP}@{$endif}check_rec_inittable);
  1600. needs_inittable:=binittable;
  1601. binittable:=oldb;
  1602. end;
  1603. procedure trecdef.deref;
  1604. var
  1605. oldrecsyms : psymtable;
  1606. begin
  1607. oldrecsyms:=aktrecordsymtable;
  1608. aktrecordsymtable:=symtable;
  1609. { now dereference the definitions }
  1610. symtable^.deref;
  1611. aktrecordsymtable:=oldrecsyms;
  1612. end;
  1613. procedure trecdef.write;
  1614. var
  1615. oldread_member : boolean;
  1616. begin
  1617. oldread_member:=read_member;
  1618. read_member:=true;
  1619. inherited write;
  1620. writelong(savesize);
  1621. current_ppu^.writeentry(ibrecorddef);
  1622. self.symtable^.writeas;
  1623. read_member:=oldread_member;
  1624. end;
  1625. function trecdef.size:longint;
  1626. begin
  1627. size:=symtable^.datasize;
  1628. end;
  1629. function trecdef.alignment:longint;
  1630. begin
  1631. alignment:=symtable^.dataalignment;
  1632. end;
  1633. {$ifdef GDB}
  1634. Const StabRecString : pchar = Nil;
  1635. StabRecSize : longint = 0;
  1636. RecOffset : Longint = 0;
  1637. procedure addname(p : pnamedindexobject);
  1638. var
  1639. news, newrec : pchar;
  1640. spec : string[2];
  1641. size : longint;
  1642. begin
  1643. { static variables from objects are like global objects }
  1644. if ((psym(p)^.properties and sp_static)<>0) then
  1645. exit;
  1646. if ((psym(p)^.properties and sp_protected)<>0) then
  1647. spec:='/1'
  1648. else if ((psym(p)^.properties and sp_private)<>0) then
  1649. spec:='/0'
  1650. else
  1651. spec:='';
  1652. If psym(p)^.typ = varsym then
  1653. begin
  1654. size:=pvarsym(p)^.definition^.size;
  1655. { open arrays made overflows !! }
  1656. if size>$fffffff then
  1657. size:=$fffffff;
  1658. newrec := strpnew(p^.name+':'+spec+pvarsym(p)^.definition^.numberstring
  1659. +','+tostr(pvarsym(p)^.address*8)+','
  1660. +tostr(size*8)+';');
  1661. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  1662. begin
  1663. getmem(news,stabrecsize+memsizeinc);
  1664. strcopy(news,stabrecstring);
  1665. freemem(stabrecstring,stabrecsize);
  1666. stabrecsize:=stabrecsize+memsizeinc;
  1667. stabrecstring:=news;
  1668. end;
  1669. strcat(StabRecstring,newrec);
  1670. strdispose(newrec);
  1671. {This should be used for case !!}
  1672. RecOffset := RecOffset + pvarsym(p)^.definition^.size;
  1673. end;
  1674. end;
  1675. function trecdef.stabstring : pchar;
  1676. Var oldrec : pchar;
  1677. oldsize : longint;
  1678. begin
  1679. oldrec := stabrecstring;
  1680. oldsize:=stabrecsize;
  1681. GetMem(stabrecstring,memsizeinc);
  1682. stabrecsize:=memsizeinc;
  1683. strpcopy(stabRecString,'s'+tostr(savesize));
  1684. RecOffset := 0;
  1685. symtable^.foreach({$ifndef TP}@{$endif}addname);
  1686. { FPC doesn't want to convert a char to a pchar}
  1687. { is this a bug ? }
  1688. strpcopy(strend(StabRecString),';');
  1689. stabstring := strnew(StabRecString);
  1690. Freemem(stabrecstring,stabrecsize);
  1691. stabrecstring := oldrec;
  1692. stabrecsize:=oldsize;
  1693. end;
  1694. procedure trecdef.concatstabto(asmlist : paasmoutput);
  1695. begin
  1696. if (not assigned(sym) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1697. (not is_def_stab_written) then
  1698. inherited concatstabto(asmlist);
  1699. end;
  1700. {$endif GDB}
  1701. var
  1702. count : longint;
  1703. procedure count_inittable_fields(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1704. begin
  1705. if (psym(sym)^.typ=varsym) and
  1706. (pvarsym(sym)^.definition^.needs_inittable) then
  1707. inc(count);
  1708. end;
  1709. procedure count_fields(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1710. begin
  1711. inc(count);
  1712. end;
  1713. procedure write_field_inittable(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1714. begin
  1715. if (psym(sym)^.typ=varsym) and
  1716. pvarsym(sym)^.definition^.needs_inittable then
  1717. begin
  1718. rttilist^.concat(new(pai_const_symbol,init(pvarsym(sym)^.definition^.get_inittable_label)));
  1719. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  1720. end;
  1721. end;
  1722. procedure write_field_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1723. begin
  1724. rttilist^.concat(new(pai_const_symbol,initname(pvarsym(sym)^.definition^.get_rtti_label)));
  1725. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  1726. end;
  1727. procedure generate_child_inittable(sym:pnamedindexobject);{$ifndef fpc}far;{$endif}
  1728. begin
  1729. if (psym(sym)^.typ=varsym) and
  1730. pvarsym(sym)^.definition^.needs_inittable then
  1731. { force inittable generation }
  1732. pvarsym(sym)^.definition^.get_inittable_label;
  1733. end;
  1734. procedure generate_child_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1735. begin
  1736. pvarsym(sym)^.definition^.get_rtti_label;
  1737. end;
  1738. procedure trecdef.write_child_rtti_data;
  1739. begin
  1740. symtable^.foreach({$ifndef TP}@{$endif}generate_child_rtti);
  1741. end;
  1742. procedure trecdef.write_child_init_data;
  1743. begin
  1744. symtable^.foreach({$ifndef TP}@{$endif}generate_child_inittable);
  1745. end;
  1746. procedure trecdef.write_rtti_data;
  1747. begin
  1748. rttilist^.concat(new(pai_const,init_8bit(tkrecord)));
  1749. write_rtti_name;
  1750. rttilist^.concat(new(pai_const,init_32bit(size)));
  1751. count:=0;
  1752. symtable^.foreach({$ifndef TP}@{$endif}count_fields);
  1753. rttilist^.concat(new(pai_const,init_32bit(count)));
  1754. symtable^.foreach({$ifndef TP}@{$endif}write_field_rtti);
  1755. end;
  1756. procedure trecdef.write_init_data;
  1757. begin
  1758. rttilist^.concat(new(pai_const,init_8bit(14)));
  1759. write_rtti_name;
  1760. rttilist^.concat(new(pai_const,init_32bit(size)));
  1761. count:=0;
  1762. symtable^.foreach({$ifndef TP}@{$endif}count_inittable_fields);
  1763. rttilist^.concat(new(pai_const,init_32bit(count)));
  1764. symtable^.foreach({$ifndef TP}@{$endif}write_field_inittable);
  1765. end;
  1766. function trecdef.gettypename : string;
  1767. begin
  1768. gettypename:='<record type>'
  1769. end;
  1770. {***************************************************************************
  1771. TABSTRACTPROCDEF
  1772. ***************************************************************************}
  1773. constructor tabstractprocdef.init;
  1774. begin
  1775. inherited init;
  1776. para1:=nil;
  1777. fpu_used:=0;
  1778. options:=0;
  1779. retdef:=voiddef;
  1780. savesize:=target_os.size_of_pointer;
  1781. end;
  1782. procedure disposepdefcoll(var para1 : pdefcoll);
  1783. var
  1784. hp : pdefcoll;
  1785. begin
  1786. hp:=para1;
  1787. while assigned(hp) do
  1788. begin
  1789. para1:=hp^.next;
  1790. dispose(hp);
  1791. hp:=para1;
  1792. end;
  1793. end;
  1794. destructor tabstractprocdef.done;
  1795. begin
  1796. disposepdefcoll(para1);
  1797. inherited done;
  1798. end;
  1799. procedure tabstractprocdef.concatdef(p : pdef;vsp : tvarspez);
  1800. var
  1801. hp : pdefcoll;
  1802. begin
  1803. new(hp);
  1804. hp^.paratyp:=vsp;
  1805. hp^.data:=p;
  1806. hp^.next:=para1;
  1807. hp^.register:=R_NO;
  1808. para1:=hp;
  1809. end;
  1810. { all functions returning in FPU are
  1811. assume to use 2 FPU registers
  1812. until the function implementation
  1813. is processed PM }
  1814. procedure tabstractprocdef.test_if_fpu_result;
  1815. begin
  1816. if assigned(retdef) and is_fpu(retdef) then
  1817. fpu_used:=2;
  1818. end;
  1819. procedure tabstractprocdef.deref;
  1820. var
  1821. hp : pdefcoll;
  1822. begin
  1823. inherited deref;
  1824. resolvedef(retdef);
  1825. hp:=para1;
  1826. while assigned(hp) do
  1827. begin
  1828. resolvedef(hp^.data);
  1829. hp:=hp^.next;
  1830. end;
  1831. end;
  1832. constructor tabstractprocdef.load;
  1833. var
  1834. last,hp : pdefcoll;
  1835. count,i : word;
  1836. begin
  1837. inherited load;
  1838. retdef:=readdefref;
  1839. fpu_used:=readbyte;
  1840. options:=readlong;
  1841. count:=readword;
  1842. para1:=nil;
  1843. savesize:=target_os.size_of_pointer;
  1844. for i:=1 to count do
  1845. begin
  1846. new(hp);
  1847. hp^.paratyp:=tvarspez(readbyte);
  1848. { hp^.register:=tregister(readbyte); }
  1849. hp^.register:=R_NO;
  1850. hp^.data:=readdefref;
  1851. hp^.next:=nil;
  1852. if para1=nil then
  1853. para1:=hp
  1854. else
  1855. last^.next:=hp;
  1856. last:=hp;
  1857. end;
  1858. end;
  1859. function tabstractprocdef.para_size : longint;
  1860. var
  1861. pdc : pdefcoll;
  1862. l : longint;
  1863. begin
  1864. l:=0;
  1865. pdc:=para1;
  1866. while assigned(pdc) do
  1867. begin
  1868. case pdc^.paratyp of
  1869. vs_var : inc(l,target_os.size_of_pointer);
  1870. vs_value,
  1871. vs_const : if push_addr_param(pdc^.data) then
  1872. inc(l,target_os.size_of_pointer)
  1873. else
  1874. inc(l,align(pdc^.data^.size,target_os.stackalignment));
  1875. end;
  1876. pdc:=pdc^.next;
  1877. end;
  1878. para_size:=l;
  1879. end;
  1880. procedure tabstractprocdef.write;
  1881. var
  1882. count : word;
  1883. hp : pdefcoll;
  1884. begin
  1885. inherited write;
  1886. writedefref(retdef);
  1887. current_ppu^.do_interface_crc:=false;
  1888. writebyte(fpu_used);
  1889. writelong(options);
  1890. hp:=para1;
  1891. count:=0;
  1892. while assigned(hp) do
  1893. begin
  1894. inc(count);
  1895. hp:=hp^.next;
  1896. end;
  1897. writeword(count);
  1898. hp:=para1;
  1899. while assigned(hp) do
  1900. begin
  1901. writebyte(byte(hp^.paratyp));
  1902. { writebyte(byte(hp^.register)); }
  1903. writedefref(hp^.data);
  1904. hp:=hp^.next;
  1905. end;
  1906. end;
  1907. function tabstractprocdef.demangled_paras : string;
  1908. var s : string;
  1909. procedure doconcat(p : pdefcoll);
  1910. begin
  1911. if assigned(p^.next) then
  1912. doconcat(p^.next)
  1913. else
  1914. s:='(';
  1915. if assigned(p^.data^.sym) then
  1916. s:=s+p^.data^.sym^.name
  1917. else if p^.paratyp=vs_var then
  1918. s:=s+'var'
  1919. else if p^.paratyp=vs_const then
  1920. s:=s+'const';
  1921. if p<>para1 then
  1922. s:=s+','
  1923. else
  1924. s:=s+')';
  1925. end;
  1926. begin
  1927. s:='';
  1928. { a recursive solution is the easiest way to inverse the parameter }
  1929. { collection }
  1930. if assigned(para1) then
  1931. doconcat(para1);
  1932. demangled_paras:=s;
  1933. end;
  1934. {$ifdef GDB}
  1935. function tabstractprocdef.stabstring : pchar;
  1936. begin
  1937. stabstring := strpnew('abstractproc'+numberstring+';');
  1938. end;
  1939. procedure tabstractprocdef.concatstabto(asmlist : paasmoutput);
  1940. begin
  1941. if (not assigned(sym) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  1942. and not is_def_stab_written then
  1943. begin
  1944. if assigned(retdef) then forcestabto(asmlist,retdef);
  1945. inherited concatstabto(asmlist);
  1946. end;
  1947. end;
  1948. {$endif GDB}
  1949. {***************************************************************************
  1950. TPROCDEF
  1951. ***************************************************************************}
  1952. constructor tprocdef.init;
  1953. begin
  1954. inherited init;
  1955. deftype:=procdef;
  1956. _mangledname:=nil;
  1957. nextoverloaded:=nil;
  1958. fileinfo:=aktfilepos;
  1959. extnumber:=-1;
  1960. localst:=new(psymtable,init(localsymtable));
  1961. parast:=new(psymtable,init(parasymtable));
  1962. localst^.defowner:=@self;
  1963. parast^.defowner:=@self;
  1964. { this is used by insert
  1965. to check same names in parast and localst }
  1966. localst^.next:=parast;
  1967. defref:=nil;
  1968. crossref:=nil;
  1969. lastwritten:=nil;
  1970. refcount:=0;
  1971. if (cs_browser in aktmoduleswitches) and make_ref then
  1972. begin
  1973. defref:=new(pref,init(defref,@tokenpos));
  1974. inc(refcount);
  1975. end;
  1976. lastref:=defref;
  1977. { first, we assume that all registers are used }
  1978. {$ifdef i386}
  1979. usedregisters:=$ff;
  1980. {$endif i386}
  1981. {$ifdef m68k}
  1982. usedregisters:=$FFFF;
  1983. {$endif}
  1984. {$ifdef alpha}
  1985. usedregisters_int:=$ffffffff;
  1986. usedregisters_fpu:=$ffffffff;
  1987. {$endif alpha}
  1988. forwarddef:=true;
  1989. interfacedef:=false;
  1990. _class := nil;
  1991. code:=nil;
  1992. count:=false;
  1993. is_used:=false;
  1994. end;
  1995. constructor tprocdef.load;
  1996. var
  1997. s : string;
  1998. begin
  1999. inherited load;
  2000. deftype:=procdef;
  2001. {$ifdef i386}
  2002. usedregisters:=readbyte;
  2003. {$endif i386}
  2004. {$ifdef m68k}
  2005. usedregisters:=readword;
  2006. {$endif}
  2007. {$ifdef alpha}
  2008. usedregisters_int:=readlong;
  2009. usedregisters_fpu:=readlong;
  2010. {$endif alpha}
  2011. s:=readstring;
  2012. setstring(_mangledname,s);
  2013. extnumber:=readlong;
  2014. nextoverloaded:=pprocdef(readdefref);
  2015. _class := pobjectdef(readdefref);
  2016. readposinfo(fileinfo);
  2017. if (cs_link_deffile in aktglobalswitches) and ((options and poexports)<>0) then
  2018. deffile.AddExport(mangledname);
  2019. parast:=nil;
  2020. localst:=nil;
  2021. forwarddef:=false;
  2022. interfacedef:=false;
  2023. lastref:=nil;
  2024. lastwritten:=nil;
  2025. defref:=nil;
  2026. refcount:=0;
  2027. count:=true;
  2028. is_used:=false;
  2029. end;
  2030. Const local_symtable_index : longint = $8001;
  2031. procedure tprocdef.load_references;
  2032. var
  2033. pos : tfileposinfo;
  2034. {$ifndef NOLOCALBROWSER}
  2035. pdo : pobjectdef;
  2036. {$endif ndef NOLOCALBROWSER}
  2037. move_last : boolean;
  2038. begin
  2039. move_last:=lastwritten=lastref;
  2040. while (not current_ppu^.endofentry) do
  2041. begin
  2042. readposinfo(pos);
  2043. inc(refcount);
  2044. lastref:=new(pref,init(lastref,@pos));
  2045. lastref^.is_written:=true;
  2046. if refcount=1 then
  2047. defref:=lastref;
  2048. end;
  2049. if move_last then
  2050. lastwritten:=lastref;
  2051. if ((current_module^.flags and uf_local_browser)<>0)
  2052. and is_in_current then
  2053. begin
  2054. {$ifndef NOLOCALBROWSER}
  2055. pdo:=_class;
  2056. new(parast,loadas(parasymtable));
  2057. parast^.next:=owner;
  2058. parast^.load_browser;
  2059. new(localst,loadas(localsymtable));
  2060. localst^.next:=parast;
  2061. localst^.load_browser;
  2062. {$endif ndef NOLOCALBROWSER}
  2063. end;
  2064. end;
  2065. function tprocdef.write_references : boolean;
  2066. var
  2067. ref : pref;
  2068. {$ifndef NOLOCALBROWSER}
  2069. pdo : pobjectdef;
  2070. {$endif ndef NOLOCALBROWSER}
  2071. move_last : boolean;
  2072. begin
  2073. move_last:=lastwritten=lastref;
  2074. if move_last and (((current_module^.flags and uf_local_browser)=0)
  2075. or not is_in_current) then
  2076. exit;
  2077. { write address of this symbol }
  2078. writedefref(@self);
  2079. { write refs }
  2080. if assigned(lastwritten) then
  2081. ref:=lastwritten
  2082. else
  2083. ref:=defref;
  2084. while assigned(ref) do
  2085. begin
  2086. if ref^.moduleindex=current_module^.unit_index then
  2087. begin
  2088. writeposinfo(ref^.posinfo);
  2089. ref^.is_written:=true;
  2090. if move_last then
  2091. lastwritten:=ref;
  2092. end
  2093. else if not ref^.is_written then
  2094. move_last:=false
  2095. else if move_last then
  2096. lastwritten:=ref;
  2097. ref:=ref^.nextref;
  2098. end;
  2099. current_ppu^.writeentry(ibdefref);
  2100. write_references:=true;
  2101. if ((current_module^.flags and uf_local_browser)<>0)
  2102. and is_in_current then
  2103. begin
  2104. {$ifndef NOLOCALBROWSER}
  2105. pdo:=_class;
  2106. if (owner^.symtabletype<>localsymtable) then
  2107. while assigned(pdo) do
  2108. begin
  2109. if pdo^.publicsyms<>aktrecordsymtable then
  2110. begin
  2111. pdo^.publicsyms^.unitid:=local_symtable_index;
  2112. inc(local_symtable_index);
  2113. end;
  2114. pdo:=pdo^.childof;
  2115. end;
  2116. { we need TESTLOCALBROWSER para and local symtables
  2117. PPU files are then easier to read PM }
  2118. if not assigned(parast) then
  2119. parast:=new(psymtable,init(parasymtable));
  2120. parast^.writeas;
  2121. parast^.unitid:=local_symtable_index;
  2122. inc(local_symtable_index);
  2123. parast^.write_browser;
  2124. if not assigned(localst) then
  2125. localst:=new(psymtable,init(localsymtable));
  2126. localst^.writeas;
  2127. localst^.unitid:=local_symtable_index;
  2128. inc(local_symtable_index);
  2129. localst^.write_browser;
  2130. { decrement for }
  2131. local_symtable_index:=local_symtable_index-2;
  2132. pdo:=_class;
  2133. if (owner^.symtabletype<>localsymtable) then
  2134. while assigned(pdo) do
  2135. begin
  2136. if pdo^.publicsyms<>aktrecordsymtable then
  2137. dec(local_symtable_index);
  2138. pdo:=pdo^.childof;
  2139. end;
  2140. {$endif ndef NOLOCALBROWSER}
  2141. end;
  2142. end;
  2143. {$ifdef BrowserLog}
  2144. procedure tprocdef.add_to_browserlog;
  2145. begin
  2146. if assigned(defref) then
  2147. begin
  2148. browserlog.AddLog('***'+mangledname);
  2149. browserlog.AddLogRefs(defref);
  2150. if (current_module^.flags and uf_local_browser)<>0 then
  2151. begin
  2152. if assigned(parast) then
  2153. parast^.writebrowserlog;
  2154. if assigned(localst) then
  2155. localst^.writebrowserlog;
  2156. end;
  2157. end;
  2158. end;
  2159. {$endif BrowserLog}
  2160. destructor tprocdef.done;
  2161. begin
  2162. if assigned(defref) then
  2163. dispose(defref,done);
  2164. if assigned(parast) then
  2165. dispose(parast,done);
  2166. if assigned(localst) and (localst^.symtabletype<>staticsymtable) then
  2167. dispose(localst,done);
  2168. if ((options and poinline) <> 0) and assigned(code) then
  2169. disposetree(ptree(code));
  2170. if (options and pomsgstr)<>0 then
  2171. strdispose(messageinf.str);
  2172. if
  2173. {$ifdef tp}
  2174. not(use_big) and
  2175. {$endif}
  2176. assigned(_mangledname) then
  2177. globals.strdispose(_mangledname);
  2178. inherited done;
  2179. end;
  2180. procedure tprocdef.write;
  2181. begin
  2182. inherited write;
  2183. current_ppu^.do_interface_crc:=false;
  2184. {$ifdef i386}
  2185. writebyte(usedregisters);
  2186. {$endif i386}
  2187. {$ifdef m68k}
  2188. writeword(usedregisters);
  2189. {$endif}
  2190. {$ifdef alpha}
  2191. writelong(usedregisters_int);
  2192. writelong(usedregisters_fpu);
  2193. {$endif alpha}
  2194. writestring(mangledname);
  2195. current_ppu^.do_interface_crc:=true;
  2196. writelong(extnumber);
  2197. if (options and pooperator) = 0 then
  2198. writedefref(nextoverloaded)
  2199. else
  2200. begin
  2201. { only write the overloads from the same unit }
  2202. if assigned(nextoverloaded) and
  2203. (nextoverloaded^.owner=owner) then
  2204. writedefref(nextoverloaded)
  2205. else
  2206. writedefref(nil);
  2207. end;
  2208. writedefref(_class);
  2209. writeposinfo(fileinfo);
  2210. if (options and poinline) <> 0 then
  2211. begin
  2212. { we need to save
  2213. - the para and the local symtable
  2214. - the code ptree !! PM
  2215. writesymtable(parast);
  2216. writesymtable(localst);
  2217. writeptree(ptree(code));
  2218. }
  2219. end;
  2220. current_ppu^.writeentry(ibprocdef);
  2221. end;
  2222. function tprocdef.haspara:boolean;
  2223. begin
  2224. haspara:=assigned(aktprocsym^.definition^.parast^.symindex^.first);
  2225. end;
  2226. {$ifdef GDB}
  2227. procedure addparaname(p : psym);
  2228. var vs : char;
  2229. begin
  2230. if pvarsym(p)^.varspez = vs_value then vs := '1'
  2231. else vs := '0';
  2232. strpcopy(strend(StabRecString),p^.name+':'+pvarsym(p)^.definition^.numberstring+','+vs+';');
  2233. end;
  2234. function tprocdef.stabstring : pchar;
  2235. var param : pdefcoll;
  2236. i : word;
  2237. oldrec : pchar;
  2238. begin
  2239. oldrec := stabrecstring;
  2240. getmem(StabRecString,1024);
  2241. param := para1;
  2242. i := 0;
  2243. while assigned(param) do
  2244. begin
  2245. inc(i);
  2246. param := param^.next;
  2247. end;
  2248. strpcopy(StabRecString,'f'+retdef^.numberstring);
  2249. if i>0 then
  2250. begin
  2251. strpcopy(strend(StabRecString),','+tostr(i)+';');
  2252. (* confuse gdb !! PM
  2253. if assigned(parast) then
  2254. parast^.foreach({$ifndef TP}@{$endif}addparaname)
  2255. else
  2256. begin
  2257. param := para1;
  2258. i := 0;
  2259. while assigned(param) do
  2260. begin
  2261. inc(i);
  2262. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  2263. {Here we have lost the parameter names !!}
  2264. {using lower case parameters }
  2265. strpcopy(strend(stabrecstring),'p'+tostr(i)
  2266. +':'+param^.data^.numberstring+','+vartyp+';');
  2267. param := param^.next;
  2268. end;
  2269. end; *)
  2270. {strpcopy(strend(StabRecString),';');}
  2271. end;
  2272. stabstring := strnew(stabrecstring);
  2273. freemem(stabrecstring,1024);
  2274. stabrecstring := oldrec;
  2275. end;
  2276. procedure tprocdef.concatstabto(asmlist : paasmoutput);
  2277. begin
  2278. end;
  2279. {$endif GDB}
  2280. procedure tprocdef.deref;
  2281. begin
  2282. inherited deref;
  2283. resolvedef(pdef(nextoverloaded));
  2284. resolvedef(pdef(_class));
  2285. end;
  2286. function tprocdef.mangledname : string;
  2287. {$ifdef tp}
  2288. var
  2289. oldpos : longint;
  2290. s : string;
  2291. b : byte;
  2292. {$endif tp}
  2293. begin
  2294. {$ifndef Delphi}
  2295. {$ifdef tp}
  2296. if use_big then
  2297. begin
  2298. symbolstream.seek(longint(_mangledname));
  2299. symbolstream.read(b,1);
  2300. symbolstream.read(s[1],b);
  2301. s[0]:=chr(b);
  2302. mangledname:=s;
  2303. end
  2304. else
  2305. {$endif}
  2306. {$endif Delphi}
  2307. mangledname:=strpas(_mangledname);
  2308. if count then
  2309. is_used:=true;
  2310. end;
  2311. {$IfDef GDB}
  2312. function tprocdef.cplusplusmangledname : string;
  2313. var
  2314. s,s2 : string;
  2315. param : pdefcoll;
  2316. begin
  2317. s := sym^.name;
  2318. if _class <> nil then
  2319. begin
  2320. s2 := _class^.objname^;
  2321. s := s+'__'+tostr(length(s2))+s2;
  2322. end else s := s + '_';
  2323. param := para1;
  2324. while assigned(param) do
  2325. begin
  2326. s2 := param^.data^.sym^.name;
  2327. s := s+tostr(length(s2))+s2;
  2328. param := param^.next;
  2329. end;
  2330. cplusplusmangledname:=s;
  2331. end;
  2332. {$EndIf GDB}
  2333. procedure tprocdef.setmangledname(const s : string);
  2334. begin
  2335. if {$ifdef tp}not(use_big) and{$endif} (assigned(_mangledname)) then
  2336. strdispose(_mangledname);
  2337. setstring(_mangledname,s);
  2338. if assigned(parast) then
  2339. begin
  2340. stringdispose(parast^.name);
  2341. parast^.name:=stringdup('args of '+s);
  2342. end;
  2343. if assigned(localst) then
  2344. begin
  2345. stringdispose(localst^.name);
  2346. localst^.name:=stringdup('locals of '+s);
  2347. end;
  2348. end;
  2349. {***************************************************************************
  2350. TPROCVARDEF
  2351. ***************************************************************************}
  2352. constructor tprocvardef.init;
  2353. begin
  2354. inherited init;
  2355. deftype:=procvardef;
  2356. end;
  2357. constructor tprocvardef.load;
  2358. begin
  2359. inherited load;
  2360. deftype:=procvardef;
  2361. end;
  2362. procedure tprocvardef.write;
  2363. begin
  2364. { here we cannot get a real good value so just give something }
  2365. { plausible (PM) }
  2366. { a more secure way would be
  2367. to allways store in a temp }
  2368. if is_fpu(retdef) then
  2369. fpu_used:=2
  2370. else
  2371. fpu_used:=0;
  2372. inherited write;
  2373. current_ppu^.writeentry(ibprocvardef);
  2374. end;
  2375. function tprocvardef.size : longint;
  2376. begin
  2377. if (options and pomethodpointer)=0 then
  2378. size:=target_os.size_of_pointer
  2379. else
  2380. size:=2*target_os.size_of_pointer;
  2381. end;
  2382. {$ifdef GDB}
  2383. function tprocvardef.stabstring : pchar;
  2384. var
  2385. nss : pchar;
  2386. i : word;
  2387. param : pdefcoll;
  2388. begin
  2389. i := 0;
  2390. param := para1;
  2391. while assigned(param) do
  2392. begin
  2393. inc(i);
  2394. param := param^.next;
  2395. end;
  2396. getmem(nss,1024);
  2397. { it is not a function but a function pointer !! (PM) }
  2398. strpcopy(nss,'*f'+retdef^.numberstring{+','+tostr(i)}+';');
  2399. param := para1;
  2400. i := 0;
  2401. { this confuses gdb !!
  2402. we should use 'F' instead of 'f' but
  2403. as we use c++ language mode
  2404. it does not like that either
  2405. Please do not remove this part
  2406. might be used once
  2407. gdb for pascal is ready PM }
  2408. (* while assigned(param) do
  2409. begin
  2410. inc(i);
  2411. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  2412. {Here we have lost the parameter names !!}
  2413. pst := strpnew('p'+tostr(i)+':'+param^.data^.numberstring+','+vartyp+';');
  2414. strcat(nss,pst);
  2415. strdispose(pst);
  2416. param := param^.next;
  2417. end; *)
  2418. {strpcopy(strend(nss),';');}
  2419. stabstring := strnew(nss);
  2420. freemem(nss,1024);
  2421. end;
  2422. procedure tprocvardef.concatstabto(asmlist : paasmoutput);
  2423. begin
  2424. if ( not assigned(sym) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2425. and not is_def_stab_written then
  2426. inherited concatstabto(asmlist);
  2427. is_def_stab_written:=true;
  2428. end;
  2429. {$endif GDB}
  2430. procedure tprocvardef.write_rtti_data;
  2431. begin
  2432. {!!!!!!!}
  2433. end;
  2434. procedure tprocvardef.write_child_rtti_data;
  2435. begin
  2436. {!!!!!!!!}
  2437. end;
  2438. function tprocvardef.is_publishable : boolean;
  2439. begin
  2440. is_publishable:=(options and pomethodpointer)<>0;
  2441. end;
  2442. function tprocvardef.gettypename : string;
  2443. begin
  2444. if assigned(retdef) then
  2445. gettypename:='<procedure variable type of function'+demangled_paras+':'+retdef^.gettypename+'>'
  2446. else
  2447. gettypename:='<procedure variable type of procedure'+demangled_paras+'>';
  2448. end;
  2449. {***************************************************************************
  2450. TOBJECTDEF
  2451. ***************************************************************************}
  2452. {$ifdef GDB}
  2453. const
  2454. vtabletype : word = 0;
  2455. vtableassigned : boolean = false;
  2456. {$endif GDB}
  2457. constructor tobjectdef.init(const n : string;c : pobjectdef);
  2458. begin
  2459. tdef.init;
  2460. deftype:=objectdef;
  2461. options:=0;
  2462. childof:=nil;
  2463. publicsyms:=new(psymtable,init(objectsymtable));
  2464. publicsyms^.name := stringdup(n);
  2465. { create space for vmt !! }
  2466. options:=0;
  2467. vmt_offset:=0;
  2468. publicsyms^.datasize:=0;
  2469. publicsyms^.defowner:=@self;
  2470. publicsyms^.dataalignment:=packrecordalignment[aktpackrecords];
  2471. set_parent(c);
  2472. objname:=stringdup(n);
  2473. end;
  2474. procedure tobjectdef.set_parent( c : pobjectdef);
  2475. begin
  2476. { nothing to do if the parent was not forward !}
  2477. if assigned(childof) then
  2478. exit;
  2479. childof:=c;
  2480. { some options are inherited !! }
  2481. if assigned(c) then
  2482. begin
  2483. options:= options or (c^.options and
  2484. (oo_hasvirtual or oo_hasprivate or
  2485. oo_hasprotected or
  2486. oo_hasconstructor or oo_hasdestructor
  2487. ));
  2488. { add the data of the anchestor class }
  2489. publicsyms^.datasize:=publicsyms^.datasize
  2490. +childof^.publicsyms^.datasize;
  2491. if ((options and oo_hasvmt)<>0) and
  2492. ((c^.options and oo_hasvmt)<>0) then
  2493. publicsyms^.datasize:=publicsyms^.datasize-target_os.size_of_pointer;
  2494. { if parent has a vmt field then
  2495. the offset is the same for the child PM }
  2496. if ((c^.options and oo_hasvmt)<>0) or isclass then
  2497. begin
  2498. vmt_offset:=c^.vmt_offset;
  2499. options:=options or oo_hasvmt;
  2500. end;
  2501. end;
  2502. savesize := publicsyms^.datasize;
  2503. end;
  2504. constructor tobjectdef.load;
  2505. var
  2506. oldread_member : boolean;
  2507. begin
  2508. tdef.load;
  2509. deftype:=objectdef;
  2510. savesize:=readlong;
  2511. vmt_offset:=readlong;
  2512. objname:=stringdup(readstring);
  2513. childof:=pobjectdef(readdefref);
  2514. options:=readlong;
  2515. oldread_member:=read_member;
  2516. read_member:=true;
  2517. publicsyms:=new(psymtable,loadas(objectsymtable));
  2518. read_member:=oldread_member;
  2519. publicsyms^.defowner:=@self;
  2520. { publicsyms^.datasize:=savesize; }
  2521. publicsyms^.name := stringdup(objname^);
  2522. { handles the predefined class tobject }
  2523. { the last TOBJECT which is loaded gets }
  2524. { it ! }
  2525. if (objname^='TOBJECT') and
  2526. isclass and (childof=nil) then
  2527. class_tobject:=@self;
  2528. has_rtti:=true;
  2529. end;
  2530. procedure tobjectdef.insertvmt;
  2531. begin
  2532. if (options and oo_hasvmt)<>0 then
  2533. internalerror(12345)
  2534. else
  2535. begin
  2536. { first round up to multiple of 4 }
  2537. if (publicsyms^.dataalignment=2) then
  2538. begin
  2539. if (publicsyms^.datasize and 1)<>0 then
  2540. inc(publicsyms^.datasize);
  2541. end
  2542. else
  2543. if (publicsyms^.dataalignment>=4) then
  2544. begin
  2545. if (publicsyms^.datasize mod 4) <> 0 then
  2546. publicsyms^.datasize:=publicsyms^.datasize+4-(publicsyms^.datasize mod 4);
  2547. end;
  2548. vmt_offset:=publicsyms^.datasize;
  2549. publicsyms^.datasize:=publicsyms^.datasize+target_os.size_of_pointer;
  2550. options:=options or oo_hasvmt;
  2551. end;
  2552. end;
  2553. procedure tobjectdef.check_forwards;
  2554. begin
  2555. publicsyms^.check_forwards;
  2556. if (options and oo_isforward)<>0 then
  2557. begin
  2558. { ok, in future, the forward can be resolved }
  2559. Message1(sym_e_class_forward_not_resolved,objname^);
  2560. options:=options and not(oo_isforward);
  2561. end;
  2562. end;
  2563. destructor tobjectdef.done;
  2564. begin
  2565. if assigned(publicsyms) then
  2566. dispose(publicsyms,done);
  2567. if (options and oo_isforward)<>0 then
  2568. Message1(sym_e_class_forward_not_resolved,objname^);
  2569. stringdispose(objname);
  2570. tdef.done;
  2571. end;
  2572. { true, if self inherits from d (or if they are equal) }
  2573. function tobjectdef.isrelated(d : pobjectdef) : boolean;
  2574. var
  2575. hp : pobjectdef;
  2576. begin
  2577. hp:=@self;
  2578. while assigned(hp) do
  2579. begin
  2580. if hp=d then
  2581. begin
  2582. isrelated:=true;
  2583. exit;
  2584. end;
  2585. hp:=hp^.childof;
  2586. end;
  2587. isrelated:=false;
  2588. end;
  2589. function tobjectdef.size : longint;
  2590. begin
  2591. if (options and oo_is_class)<>0 then
  2592. size:=target_os.size_of_pointer
  2593. else
  2594. size:=publicsyms^.datasize;
  2595. end;
  2596. function tobjectdef.alignment:longint;
  2597. begin
  2598. alignment:=publicsyms^.dataalignment;
  2599. end;
  2600. procedure tobjectdef.deref;
  2601. var
  2602. oldrecsyms : psymtable;
  2603. begin
  2604. resolvedef(pdef(childof));
  2605. oldrecsyms:=aktrecordsymtable;
  2606. aktrecordsymtable:=publicsyms;
  2607. publicsyms^.deref;
  2608. aktrecordsymtable:=oldrecsyms;
  2609. end;
  2610. function tobjectdef.vmt_mangledname : string;
  2611. {DM: I get a nil pointer on the owner name. I don't know if this
  2612. mayhappen, and I have therefore fixed the problem by doing nil pointer
  2613. checks.}
  2614. var
  2615. s1,s2:string;
  2616. begin
  2617. if (options and oo_hasvmt)=0 then
  2618. {internalerror(12346);}
  2619. Message1(parser_object_has_no_vmt,objname^);
  2620. if owner^.name=nil then
  2621. s1:=''
  2622. else
  2623. s1:=owner^.name^;
  2624. if objname=nil then
  2625. s2:=''
  2626. else
  2627. s2:=objname^;
  2628. vmt_mangledname:='VMT_'+s1+'$_'+s2;
  2629. end;
  2630. function tobjectdef.rtti_name : string;
  2631. var
  2632. s1,s2:string;
  2633. begin
  2634. if owner^.name=nil then
  2635. s1:=''
  2636. else
  2637. s1:=owner^.name^;
  2638. if objname=nil then
  2639. s2:=''
  2640. else
  2641. s2:=objname^;
  2642. rtti_name:='RTTI_'+s1+'$_'+s2;
  2643. end;
  2644. function tobjectdef.isclass : boolean;
  2645. begin
  2646. isclass:=(options and oo_is_class)<>0;
  2647. end;
  2648. procedure tobjectdef.write;
  2649. var
  2650. oldread_member : boolean;
  2651. begin
  2652. tdef.write;
  2653. writelong(size);
  2654. writelong(vmt_offset);
  2655. writestring(objname^);
  2656. writedefref(childof);
  2657. writelong(options);
  2658. current_ppu^.writeentry(ibobjectdef);
  2659. oldread_member:=read_member;
  2660. read_member:=true;
  2661. publicsyms^.writeas;
  2662. read_member:=oldread_member;
  2663. end;
  2664. {$ifdef GDB}
  2665. procedure addprocname(p :pnamedindexobject);
  2666. var virtualind,argnames : string;
  2667. news, newrec : pchar;
  2668. pd,ipd : pprocdef;
  2669. lindex : longint;
  2670. para : pdefcoll;
  2671. arglength : byte;
  2672. sp : char;
  2673. begin
  2674. If psym(p)^.typ = procsym then
  2675. begin
  2676. pd := pprocsym(p)^.definition;
  2677. { this will be used for full implementation of object stabs
  2678. not yet done }
  2679. ipd := pd;
  2680. while assigned(ipd^.nextoverloaded) do ipd := ipd^.nextoverloaded;
  2681. if (pd^.options and povirtualmethod) <> 0 then
  2682. begin
  2683. lindex := pd^.extnumber;
  2684. {doesnt seem to be necessary
  2685. lindex := lindex or $80000000;}
  2686. virtualind := '*'+tostr(lindex)+';'+ipd^._class^.numberstring+';'
  2687. end else virtualind := '.';
  2688. { arguments are not listed here }
  2689. {we don't need another definition}
  2690. para := pd^.para1;
  2691. { used by gdbpas to recognize constructor and destructors }
  2692. if (pd^.options and poconstructor) <> 0 then
  2693. argnames:='__ct__'
  2694. else if (pd^.options and podestructor) <> 0 then
  2695. argnames:='__dt__'
  2696. else
  2697. argnames := '';
  2698. while assigned(para) do
  2699. begin
  2700. if para^.data^.deftype = formaldef then
  2701. begin
  2702. if para^.paratyp=vs_var then
  2703. argnames := argnames+'3var'
  2704. else if para^.paratyp=vs_const then
  2705. argnames:=argnames+'5const';
  2706. end
  2707. else
  2708. begin
  2709. { if the arg definition is like (v: ^byte;..
  2710. there is no sym attached to data !!! }
  2711. if assigned(para^.data^.sym) then
  2712. begin
  2713. arglength := length(para^.data^.sym^.name);
  2714. argnames := argnames + tostr(arglength)+para^.data^.sym^.name;
  2715. end
  2716. else
  2717. begin
  2718. argnames:=argnames+'11unnamedtype';
  2719. end;
  2720. end;
  2721. para := para^.next;
  2722. end;
  2723. ipd^.is_def_stab_written := true;
  2724. { here 2A must be changed for private and protected }
  2725. { 0 is private 1 protected and 2 public }
  2726. if (psym(p)^.properties and sp_private)<>0 then sp:='0'
  2727. else if (psym(p)^.properties and sp_protected)<>0 then sp:='1'
  2728. else sp:='2';
  2729. newrec := strpnew(p^.name+'::'+ipd^.numberstring
  2730. +'=##'+pd^.retdef^.numberstring+';:'+argnames+';'+sp+'A'
  2731. +virtualind+';');
  2732. { get spare place for a string at the end }
  2733. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  2734. begin
  2735. getmem(news,stabrecsize+memsizeinc);
  2736. strcopy(news,stabrecstring);
  2737. freemem(stabrecstring,stabrecsize);
  2738. stabrecsize:=stabrecsize+memsizeinc;
  2739. stabrecstring:=news;
  2740. end;
  2741. strcat(StabRecstring,newrec);
  2742. {freemem(newrec,memsizeinc); }
  2743. strdispose(newrec);
  2744. {This should be used for case !!}
  2745. RecOffset := RecOffset + pd^.size;
  2746. end;
  2747. end;
  2748. function tobjectdef.stabstring : pchar;
  2749. var anc : pobjectdef;
  2750. oldrec : pchar;
  2751. oldrecsize : longint;
  2752. str_end : string;
  2753. begin
  2754. oldrec := stabrecstring;
  2755. oldrecsize:=stabrecsize;
  2756. stabrecsize:=memsizeinc;
  2757. GetMem(stabrecstring,stabrecsize);
  2758. strpcopy(stabRecString,'s'+tostr(size));
  2759. if assigned(childof) then
  2760. {only one ancestor not virtual, public, at base offset 0 }
  2761. { !1 , 0 2 0 , }
  2762. strpcopy(strend(stabrecstring),'!1,020,'+childof^.numberstring+';');
  2763. {virtual table to implement yet}
  2764. RecOffset := 0;
  2765. publicsyms^.foreach({$ifndef TP}@{$endif}addname);
  2766. if (options and oo_hasvmt) <> 0 then
  2767. if not assigned(childof) or ((childof^.options and oo_hasvmt) = 0) then
  2768. begin
  2769. strpcopy(strend(stabrecstring),'$vf'+numberstring+':'+typeglobalnumber('vtblarray')
  2770. +','+tostr(vmt_offset*8)+';');
  2771. end;
  2772. publicsyms^.foreach({$ifndef TP}@{$endif}addprocname);
  2773. if (options and oo_hasvmt) <> 0 then
  2774. begin
  2775. anc := @self;
  2776. while assigned(anc^.childof) and ((anc^.childof^.options and oo_hasvmt) <> 0) do
  2777. anc := anc^.childof;
  2778. str_end:=';~%'+anc^.numberstring+';';
  2779. end
  2780. else
  2781. str_end:=';';
  2782. strpcopy(strend(stabrecstring),str_end);
  2783. stabstring := strnew(StabRecString);
  2784. freemem(stabrecstring,stabrecsize);
  2785. stabrecstring := oldrec;
  2786. stabrecsize:=oldrecsize;
  2787. end;
  2788. {$endif GDB}
  2789. procedure tobjectdef.write_child_init_data;
  2790. begin
  2791. end;
  2792. procedure tobjectdef.write_init_data;
  2793. begin
  2794. if isclass then
  2795. rttilist^.concat(new(pai_const,init_8bit(tkclass)))
  2796. else
  2797. rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  2798. { generate the name }
  2799. rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
  2800. rttilist^.concat(new(pai_string,init(objname^)));
  2801. rttilist^.concat(new(pai_const,init_32bit(size)));
  2802. count:=0;
  2803. publicsyms^.foreach({$ifndef TP}@{$endif}count_inittable_fields);
  2804. rttilist^.concat(new(pai_const,init_32bit(count)));
  2805. publicsyms^.foreach({$ifndef TP}@{$endif}write_field_inittable);
  2806. end;
  2807. function tobjectdef.needs_inittable : boolean;
  2808. var
  2809. oldb : boolean;
  2810. begin
  2811. { there are recursive calls to needs_inittable possible, }
  2812. { so we have to change to old value how else should }
  2813. { we do that ? check_rec_rtti can't be a nested }
  2814. { procedure of needs_rtti ! }
  2815. oldb:=binittable;
  2816. binittable:=false;
  2817. publicsyms^.foreach({$ifndef TP}@{$endif}check_rec_inittable);
  2818. needs_inittable:=binittable;
  2819. binittable:=oldb;
  2820. end;
  2821. procedure count_published_properties(sym:pnamedindexobject);
  2822. {$ifndef fpc}far;{$endif}
  2823. begin
  2824. if (psym(sym)^.typ=propertysym) and ((psym(sym)^.properties and sp_published)<>0) then
  2825. inc(count);
  2826. end;
  2827. procedure write_property_info(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  2828. var
  2829. proctypesinfo : byte;
  2830. procedure writeproc(sym : psym;def : pdef;shiftvalue : byte);
  2831. var
  2832. typvalue : byte;
  2833. begin
  2834. if not(assigned(sym)) then
  2835. begin
  2836. rttilist^.concat(new(pai_const,init_32bit(1)));
  2837. typvalue:=3;
  2838. end
  2839. else if sym^.typ=varsym then
  2840. begin
  2841. rttilist^.concat(new(pai_const,init_32bit(
  2842. pvarsym(sym)^.address)));
  2843. typvalue:=0;
  2844. end
  2845. else
  2846. begin
  2847. if (pprocdef(def)^.options and povirtualmethod)=0 then
  2848. begin
  2849. rttilist^.concat(new(pai_const_symbol,initname(pprocdef(def)^.mangledname)));
  2850. typvalue:=1;
  2851. end
  2852. else
  2853. begin
  2854. { virtual method, write vmt offset }
  2855. rttilist^.concat(new(pai_const,init_32bit(pprocdef(def)^.extnumber*4+12)));
  2856. typvalue:=2;
  2857. end;
  2858. end;
  2859. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  2860. end;
  2861. begin
  2862. if (psym(sym)^.typ=propertysym) and
  2863. ((ppropertysym(sym)^.options and ppo_indexed)<>0) then
  2864. proctypesinfo:=$40
  2865. else
  2866. proctypesinfo:=0;
  2867. if (psym(sym)^.typ=propertysym) and
  2868. ((psym(sym)^.properties and sp_published)<>0) then
  2869. begin
  2870. rttilist^.concat(new(pai_const_symbol,initname(ppropertysym(sym)^.proptype^.get_rtti_label)));
  2871. writeproc(ppropertysym(sym)^.readaccesssym,ppropertysym(sym)^.readaccessdef,0);
  2872. writeproc(ppropertysym(sym)^.writeaccesssym,ppropertysym(sym)^.writeaccessdef,2);
  2873. { isn't it stored ? }
  2874. if (ppropertysym(sym)^.options and ppo_stored)=0 then
  2875. begin
  2876. rttilist^.concat(new(pai_const,init_32bit(1)));
  2877. proctypesinfo:=proctypesinfo or (3 shl 4);
  2878. end
  2879. else
  2880. writeproc(ppropertysym(sym)^.storedsym,ppropertysym(sym)^.storeddef,4);
  2881. rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.index)));
  2882. rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.default)));
  2883. rttilist^.concat(new(pai_const,init_16bit(count)));
  2884. inc(count);
  2885. rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
  2886. rttilist^.concat(new(pai_const,init_8bit(length(ppropertysym(sym)^.name))));
  2887. rttilist^.concat(new(pai_string,init(ppropertysym(sym)^.name)));
  2888. end;
  2889. end;
  2890. procedure generate_published_child_rtti(sym : pnamedindexobject);
  2891. {$ifndef fpc}far;{$endif}
  2892. begin
  2893. if (psym(sym)^.typ=propertysym) and
  2894. ((psym(sym)^.properties and sp_published)<>0) then
  2895. ppropertysym(sym)^.proptype^.get_rtti_label;
  2896. end;
  2897. procedure tobjectdef.write_child_rtti_data;
  2898. begin
  2899. publicsyms^.foreach({$ifndef TP}@{$endif}generate_published_child_rtti);
  2900. end;
  2901. procedure tobjectdef.generate_rtti;
  2902. begin
  2903. has_rtti:=true;
  2904. getdatalabel(rtti_label);
  2905. write_child_rtti_data;
  2906. rttilist^.concat(new(pai_symbol,initname_global(rtti_name)));
  2907. rttilist^.concat(new(pai_label,init(rtti_label)));
  2908. write_rtti_data;
  2909. end;
  2910. function tobjectdef.next_free_name_index : longint;
  2911. var
  2912. i : longint;
  2913. begin
  2914. if assigned(childof) and ((childof^.options and oo_can_have_published)<>0) then
  2915. i:=childof^.next_free_name_index
  2916. else
  2917. i:=0;
  2918. count:=0;
  2919. publicsyms^.foreach({$ifndef TP}@{$endif}count_published_properties);
  2920. next_free_name_index:=i+count;
  2921. end;
  2922. procedure tobjectdef.write_rtti_data;
  2923. begin
  2924. if isclass then
  2925. rttilist^.concat(new(pai_const,init_8bit(tkclass)))
  2926. else
  2927. rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  2928. { generate the name }
  2929. rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
  2930. rttilist^.concat(new(pai_string,init(objname^)));
  2931. { write class type }
  2932. rttilist^.concat(new(pai_const_symbol,initname(vmt_mangledname)));
  2933. { write owner typeinfo }
  2934. if assigned(childof) and ((childof^.options and oo_can_have_published)<>0) then
  2935. rttilist^.concat(new(pai_const_symbol,initname(childof^.get_rtti_label)))
  2936. else
  2937. rttilist^.concat(new(pai_const,init_32bit(0)));
  2938. { count total number of properties }
  2939. if assigned(childof) and ((childof^.options and oo_can_have_published)<>0) then
  2940. count:=childof^.next_free_name_index
  2941. else
  2942. count:=0;
  2943. { write it }
  2944. publicsyms^.foreach({$ifndef TP}@{$endif}count_published_properties);
  2945. rttilist^.concat(new(pai_const,init_16bit(count)));
  2946. { write unit name }
  2947. if assigned(owner^.name) then
  2948. begin
  2949. rttilist^.concat(new(pai_const,init_8bit(length(owner^.name^))));
  2950. rttilist^.concat(new(pai_string,init(owner^.name^)));
  2951. end
  2952. else
  2953. rttilist^.concat(new(pai_const,init_8bit(0)));
  2954. { write published properties count }
  2955. count:=0;
  2956. publicsyms^.foreach({$ifndef TP}@{$endif}count_published_properties);
  2957. rttilist^.concat(new(pai_const,init_16bit(count)));
  2958. { count is used to write nameindex }
  2959. { but we need an offset of the owner }
  2960. { to give each property an own slot }
  2961. if assigned(childof) and ((childof^.options and oo_can_have_published)<>0) then
  2962. count:=childof^.next_free_name_index
  2963. else
  2964. count:=0;
  2965. publicsyms^.foreach({$ifndef TP}@{$endif}write_property_info);
  2966. end;
  2967. function tobjectdef.is_publishable : boolean;
  2968. begin
  2969. is_publishable:=isclass;
  2970. end;
  2971. function tobjectdef.get_rtti_label : string;
  2972. begin
  2973. get_rtti_label:=rtti_name;
  2974. end;
  2975. {****************************************************************************
  2976. TERRORDEF
  2977. ****************************************************************************}
  2978. constructor terrordef.init;
  2979. begin
  2980. inherited init;
  2981. deftype:=errordef;
  2982. end;
  2983. {$ifdef GDB}
  2984. function terrordef.stabstring : pchar;
  2985. begin
  2986. stabstring:=strpnew('error'+numberstring);
  2987. end;
  2988. {$endif GDB}
  2989. function terrordef.gettypename:string;
  2990. begin
  2991. gettypename:='<erroneous type>';
  2992. end;
  2993. {
  2994. $Log$
  2995. Revision 1.133 1999-07-23 16:05:28 peter
  2996. * alignment is now saved in the symtable
  2997. * C alignment added for records
  2998. * PPU version increased to solve .12 <-> .13 probs
  2999. Revision 1.132 1999/07/18 14:47:32 florian
  3000. * bug 487 fixed, (inc(<property>) isn't allowed)
  3001. * more fixes to compile with Delphi
  3002. Revision 1.131 1999/07/06 21:48:27 florian
  3003. * a lot bug fixes:
  3004. - po_external isn't any longer necessary for procedure compatibility
  3005. - m_tp_procvar is in -Sd now available
  3006. - error messages of procedure variables improved
  3007. - return values with init./finalization fixed
  3008. - data types with init./finalization aren't any longer allowed in variant
  3009. record
  3010. Revision 1.130 1999/06/22 16:24:44 pierre
  3011. * local browser stuff corrected
  3012. Revision 1.129 1999/06/02 22:44:21 pierre
  3013. * previous wrong log corrected
  3014. Revision 1.128 1999/06/02 22:25:52 pierre
  3015. * changed $ifdef FPC @ into $ifndef TP
  3016. Revision 1.127 1999/06/02 10:26:50 florian
  3017. * corrected order of parameter type for -vb
  3018. Revision 1.126 1999/06/02 10:11:50 florian
  3019. * make cycle fixed i.e. compilation with 0.99.10
  3020. * some fixes for qword
  3021. * start of register calling conventions
  3022. Revision 1.125 1999/06/01 14:45:56 peter
  3023. * @procvar is now always needed for FPC
  3024. Revision 1.124 1999/05/31 16:42:33 peter
  3025. * interfacedef flag for procdef if it's defined in the interface, to
  3026. make a difference with 'forward;' directive forwarddef. Fixes 253
  3027. Revision 1.123 1999/05/27 19:45:02 peter
  3028. * removed oldasm
  3029. * plabel -> pasmlabel
  3030. * -a switches to source writing automaticly
  3031. * assembler readers OOPed
  3032. * asmsymbol automaticly external
  3033. * jumptables and other label fixes for asm readers
  3034. Revision 1.122 1999/05/23 18:42:14 florian
  3035. * better error recovering in typed constants
  3036. * some problems with arrays of const fixed, some problems
  3037. due my previous
  3038. - the location type of array constructor is now LOC_MEM
  3039. - the pushing of high fixed
  3040. - parameter copying fixed
  3041. - zero temp. allocation removed
  3042. * small problem in the assembler writers fixed:
  3043. ref to nil wasn't written correctly
  3044. Revision 1.121 1999/05/21 13:55:19 peter
  3045. * NEWLAB for label as symbol
  3046. Revision 1.120 1999/05/20 22:22:43 pierre
  3047. + added synonym filed for ttypesym
  3048. allows a clean disposal of tdefs and related ttypesyms
  3049. Revision 1.119 1999/05/19 16:48:26 florian
  3050. * tdef.typename: returns a now a proper type name for the most types
  3051. Revision 1.118 1999/05/19 12:08:11 florian
  3052. * tobject wasn't set as default anchestor, was a problem with the new ppu
  3053. handling
  3054. Revision 1.117 1999/05/17 21:57:15 florian
  3055. * new temporary ansistring handling
  3056. Revision 1.116 1999/05/16 02:26:51 peter
  3057. * fixed loading of classrefdef
  3058. Revision 1.115 1999/05/14 17:52:26 peter
  3059. * new deref code
  3060. Revision 1.114 1999/05/13 21:59:41 peter
  3061. * removed oldppu code
  3062. * warning if objpas is loaded from uses
  3063. * first things for new deref writing
  3064. Revision 1.113 1999/05/12 00:19:58 peter
  3065. * removed R_DEFAULT_SEG
  3066. * uniform float names
  3067. Revision 1.112 1999/05/08 19:52:35 peter
  3068. + MessagePos() which is enhanced Message() function but also gets the
  3069. position info
  3070. * Removed comp warnings
  3071. Revision 1.111 1999/05/07 11:06:37 florian
  3072. * enumeration type names are now written in lowercase (rtti)
  3073. Revision 1.110 1999/05/06 09:05:28 peter
  3074. * generic write_float and str_float
  3075. * fixed constant float conversions
  3076. Revision 1.109 1999/05/05 10:05:56 florian
  3077. * a delphi compiled compiler recompiles ppc
  3078. Revision 1.108 1999/04/28 22:30:52 pierre
  3079. * delete -> deleteindex in tdef.correct_owner_symtable
  3080. Revision 1.107 1999/04/28 06:02:11 florian
  3081. * changes of Bruessel:
  3082. + message handler can now take an explicit self
  3083. * typinfo fixed: sometimes the type names weren't written
  3084. * the type checking for pointer comparisations and subtraction
  3085. and are now more strict (was also buggy)
  3086. * small bug fix to link.pas to support compiling on another
  3087. drive
  3088. * probable bug in popt386 fixed: call/jmp => push/jmp
  3089. transformation didn't count correctly the jmp references
  3090. + threadvar support
  3091. * warning if ln/sqrt gets an invalid constant argument
  3092. Revision 1.106 1999/04/26 18:30:01 peter
  3093. * farpointerdef moved into pointerdef.is_far
  3094. Revision 1.105 1999/04/26 13:31:47 peter
  3095. * release storenumber,double_checksum
  3096. Revision 1.104 1999/04/21 09:43:50 peter
  3097. * storenumber works
  3098. * fixed some typos in double_checksum
  3099. + incompatible types type1 and type2 message (with storenumber)
  3100. Revision 1.103 1999/04/19 09:28:20 peter
  3101. * fixed crash when writing overload operator to ppu
  3102. Revision 1.102 1999/04/17 22:01:28 pierre
  3103. * typo error fix in STORENUMBER code
  3104. Revision 1.101 1999/04/14 09:14:58 peter
  3105. * first things to store the symbol/def number in the ppu
  3106. Revision 1.100 1999/04/08 15:57:51 peter
  3107. + subrange checking for readln()
  3108. Revision 1.99 1999/04/07 15:39:32 pierre
  3109. + double_checksum code added
  3110. Revision 1.98 1999/03/06 17:24:16 peter
  3111. * reset savesize in tdef.init
  3112. Revision 1.97 1999/03/01 13:45:04 pierre
  3113. + added staticppusymtable symtable type for local browsing
  3114. Revision 1.96 1999/02/25 21:02:52 peter
  3115. * ag386bin updates
  3116. + coff writer
  3117. Revision 1.95 1999/02/23 18:29:23 pierre
  3118. * win32 compilation error fix
  3119. + some work for local browser (not cl=omplete yet)
  3120. Revision 1.94 1999/02/22 20:13:38 florian
  3121. + first implementation of message keyword
  3122. Revision 1.93 1999/02/22 13:07:07 pierre
  3123. + -b and -bl options work !
  3124. + cs_local_browser ($L+) is disabled if cs_browser ($Y+)
  3125. is not enabled when quitting global section
  3126. * local vars and procedures are not yet stored into PPU
  3127. Revision 1.92 1999/02/17 10:14:20 peter
  3128. * set the first enumsym also for subrange types
  3129. Revision 1.91 1999/02/08 09:51:21 pierre
  3130. * gdb info for local functions was wrong
  3131. Revision 1.90 1999/01/26 09:57:29 pierre
  3132. * open arrays stabs changed
  3133. Revision 1.89 1999/01/22 17:29:30 pierre
  3134. * overflow in addname for open arrays removed
  3135. Revision 1.88 1999/01/20 14:18:39 pierre
  3136. * bugs related to mangledname solved
  3137. - linux external without name
  3138. -external procs already used
  3139. (added count and is_used boolean fiels in tprocvar)
  3140. Revision 1.87 1999/01/19 10:56:05 pierre
  3141. typeof(object) without vmt generates an error instead of an internalerror
  3142. Revision 1.86 1999/01/12 14:25:32 peter
  3143. + BrowserLog for browser.log generation
  3144. + BrowserCol for browser info in TCollections
  3145. * released all other UseBrowser
  3146. Revision 1.85 1998/12/30 22:15:52 peter
  3147. + farpointer type
  3148. * absolutesym now also stores if its far
  3149. Revision 1.84 1998/12/30 13:41:12 peter
  3150. * released valuepara
  3151. Revision 1.83 1998/12/21 14:03:08 pierre
  3152. * procvar stabs correction
  3153. Revision 1.82 1998/12/19 00:23:52 florian
  3154. * ansistring memory leaks fixed
  3155. Revision 1.81 1998/12/11 08:57:22 pierre
  3156. * internal gdb types for booleans and 64bit integers
  3157. Revision 1.80 1998/12/10 09:47:26 florian
  3158. + basic operations with int64/qord (compiler with -dint64)
  3159. + rtti of enumerations extended: names are now written
  3160. Revision 1.79 1998/12/08 10:18:12 peter
  3161. + -gh for heaptrc unit
  3162. Revision 1.78 1998/12/08 09:06:30 pierre
  3163. + constructor destructor info for gdbpas
  3164. Revision 1.77 1998/12/01 23:37:39 pierre
  3165. * function type problem for gdb fix
  3166. Revision 1.76 1998/11/29 21:45:48 florian
  3167. * problem with arrays with init tables fixed
  3168. Revision 1.75 1998/11/29 12:45:59 peter
  3169. * hack for arraydef.size overflow
  3170. Revision 1.74 1998/11/27 14:50:47 peter
  3171. + open strings, $P switch support
  3172. Revision 1.73 1998/11/26 14:47:00 michael
  3173. + Fixed RTTI constants
  3174. Revision 1.72 1998/11/25 14:35:28 florian
  3175. * writting of rtti for properties fixed
  3176. Revision 1.71 1998/11/20 15:35:59 florian
  3177. * problems with rtti fixed, hope it works
  3178. Revision 1.70 1998/11/18 15:44:16 peter
  3179. * VALUEPARA for tp7 compatible value parameters
  3180. Revision 1.69 1998/11/10 17:54:56 peter
  3181. * removed warning
  3182. Revision 1.68 1998/11/05 23:34:36 peter
  3183. * don't dispose staticsymtable (caused crash under tp7 after a fatal
  3184. error)
  3185. Revision 1.67 1998/11/05 12:02:56 peter
  3186. * released useansistring
  3187. * removed -Sv, its now available in fpc modes
  3188. Revision 1.66 1998/10/26 22:58:22 florian
  3189. * new introduded problem with classes fix, the parent class wasn't set
  3190. correct, if the class was defined forward before
  3191. Revision 1.65 1998/10/26 14:19:28 pierre
  3192. + added options -lS and -lT for source and target os output
  3193. (to have a easier way to test OS_SOURCE abd OS_TARGET in makefiles)
  3194. * several problems with rtti data
  3195. (type of sym was not checked)
  3196. assumed to be varsym when they could be procsym or property syms !!
  3197. Revision 1.64 1998/10/22 17:11:21 pierre
  3198. + terminated the include exclude implementation for i386
  3199. * enums inside records fixed
  3200. Revision 1.63 1998/10/20 09:32:56 peter
  3201. * removed some unused vars
  3202. Revision 1.62 1998/10/20 08:06:58 pierre
  3203. * several memory corruptions due to double freemem solved
  3204. => never use p^.loc.location:=p^.left^.loc.location;
  3205. + finally I added now by default
  3206. that ra386dir translates global and unit symbols
  3207. + added a first field in tsymtable and
  3208. a nextsym field in tsym
  3209. (this allows to obtain ordered type info for
  3210. records and objects in gdb !)
  3211. Revision 1.61 1998/10/19 08:55:05 pierre
  3212. * wrong stabs info corrected once again !!
  3213. + variable vmt offset with vmt field only if required
  3214. implemented now !!!
  3215. Revision 1.60 1998/10/16 13:12:53 pierre
  3216. * added vmt_offsets in destructors code also !!!
  3217. * vmt_offset code for m68k
  3218. Revision 1.59 1998/10/16 08:51:51 peter
  3219. + target_os.stackalignment
  3220. + stack can be aligned at 2 or 4 byte boundaries
  3221. Revision 1.58 1998/10/15 15:13:30 pierre
  3222. + added oo_hasconstructor and oo_hasdestructor
  3223. for objects options
  3224. Revision 1.57 1998/10/14 15:54:20 pierre
  3225. * smallsets are not entirely implemented for
  3226. m68k added a ifdef usesmallset
  3227. that is allways defined for i386
  3228. (enables testing for m68k)
  3229. Revision 1.56 1998/10/09 11:47:56 pierre
  3230. * still more memory leaks fixes !!
  3231. Revision 1.55 1998/10/06 17:16:55 pierre
  3232. * some memory leaks fixed (thanks to Peter for heaptrc !)
  3233. Revision 1.54 1998/10/05 21:33:28 peter
  3234. * fixed 161,165,166,167,168
  3235. Revision 1.53 1998/10/05 12:48:39 pierre
  3236. * wrong handling of range check for arrays fixed
  3237. Revision 1.52 1998/10/02 07:20:38 florian
  3238. * range checking in units doesn't work if the units are smartlinked, fixed
  3239. Revision 1.51 1998/09/25 12:01:41 florian
  3240. * tobjectdef.publicsyms.datasize was set to savesize, this is wrong now
  3241. because the symtable size is read from the ppu file
  3242. Revision 1.50 1998/09/23 15:46:40 florian
  3243. * problem with with and classes fixed
  3244. Revision 1.49 1998/09/23 12:03:55 peter
  3245. * overloading fix for array of const
  3246. Revision 1.48 1998/09/22 15:37:23 peter
  3247. + array of const start
  3248. Revision 1.47 1998/09/21 15:46:01 michael
  3249. Applied florians fix for check_rec_inittable
  3250. Revision 1.46 1998/09/21 08:45:21 pierre
  3251. + added vmt_offset in tobjectdef.write for fututre use
  3252. (first steps to have objects without vmt if no virtual !!)
  3253. + added fpu_used field for tabstractprocdef :
  3254. sets this level to 2 if the functions return with value in FPU
  3255. (is then set to correct value at parsing of implementation)
  3256. THIS MIGHT refuse some code with FPU expression too complex
  3257. that were accepted before and even in some cases
  3258. that don't overflow in fact
  3259. ( like if f : float; is a forward that finally in implementation
  3260. only uses one fpu register !!)
  3261. Nevertheless I think that it will improve security on
  3262. FPU operations !!
  3263. * most other changes only for UseBrowser code
  3264. (added symtable references for record and objects)
  3265. local switch for refs to args and local of each function
  3266. (static symtable still missing)
  3267. UseBrowser still not stable and probably broken by
  3268. the definition hash array !!
  3269. Revision 1.45 1998/09/20 08:31:29 florian
  3270. + bit 6 of tpropinfo.propprocs is set, if the property contains a
  3271. constant index
  3272. Revision 1.44 1998/09/19 15:23:58 florian
  3273. * rtti for ordtypes corrected
  3274. Revision 1.43 1998/09/18 17:12:40 florian
  3275. * problem with writing of class references fixed
  3276. Revision 1.42 1998/09/17 13:41:20 pierre
  3277. sizeof(TPOINT) problem
  3278. Revision 1.40.2.2 1998/09/17 08:42:33 pierre
  3279. TPOINT sizeof fix
  3280. Revision 1.41 1998/09/15 17:39:30 jonas
  3281. + bugfix from bugfix branch
  3282. Revision 1.40.2.1 1998/09/15 17:35:32 jonas
  3283. * chenged string_typ in tstringdef.wideload from ansistring to widestring
  3284. Revision 1.40 1998/09/09 15:34:00 peter
  3285. * removed warnings
  3286. Revision 1.39 1998/09/08 10:23:44 pierre
  3287. * name field of filedef corrected
  3288. Revision 1.38 1998/09/07 23:10:23 florian
  3289. * a lot of stuff fixed regarding rtti and publishing of properties,
  3290. basics should now work
  3291. Revision 1.37 1998/09/07 19:33:24 florian
  3292. + some stuff for property rtti added:
  3293. - NameIndex of the TPropInfo record is now written correctly
  3294. - the DEFAULT/NODEFAULT keyword is supported now
  3295. - the default value and the storedsym/def are now written to
  3296. the PPU fiel
  3297. Revision 1.36 1998/09/07 17:37:01 florian
  3298. * first fixes for published properties
  3299. Revision 1.35 1998/09/06 22:42:02 florian
  3300. + rtti genreation for properties added
  3301. Revision 1.34 1998/09/04 18:15:02 peter
  3302. * filedef updated
  3303. Revision 1.33 1998/09/03 17:08:49 pierre
  3304. * better lines for stabs
  3305. (no scroll back to if before else part
  3306. no return to case line at jump outside case)
  3307. + source lines also if not in order
  3308. Revision 1.32 1998/09/03 16:03:20 florian
  3309. + rtti generation
  3310. * init table generation changed
  3311. Revision 1.31 1998/09/02 15:14:28 peter
  3312. * enum packing changed from len to max
  3313. Revision 1.30 1998/09/01 17:37:29 peter
  3314. * removed debug writeln :(
  3315. Revision 1.29 1998/09/01 12:53:25 peter
  3316. + aktpackenum
  3317. Revision 1.28 1998/09/01 07:54:22 pierre
  3318. * UseBrowser a little updated (might still be buggy !!)
  3319. * bug in psub.pas in function specifier removed
  3320. * stdcall allowed in interface and in implementation
  3321. (FPC will not yet complain if it is missing in either part
  3322. because stdcall is only a dummy !!)
  3323. Revision 1.27 1998/08/28 12:51:43 florian
  3324. + ansistring to pchar type cast fixed
  3325. Revision 1.26 1998/08/25 12:42:44 pierre
  3326. * CDECL changed to CVAR for variables
  3327. specifications are read in structures also
  3328. + started adding GPC compatibility mode ( option -Sp)
  3329. * names changed to lowercase
  3330. Revision 1.25 1998/08/23 21:04:38 florian
  3331. + rtti generation for classes added
  3332. + new/dispose do now also a call to INITIALIZE/FINALIZE, if necessaray
  3333. Revision 1.24 1998/08/20 12:53:26 peter
  3334. * object_options are always written for object syms
  3335. Revision 1.23 1998/08/19 00:42:42 peter
  3336. + subrange types for enums
  3337. + checking for bounds type with ranges
  3338. Revision 1.22 1998/08/17 10:10:10 peter
  3339. - removed OLDPPU
  3340. Revision 1.21 1998/08/10 14:50:28 peter
  3341. + localswitches, moduleswitches, globalswitches splitting
  3342. Revision 1.20 1998/07/18 22:54:30 florian
  3343. * some ansi/wide/longstring support fixed:
  3344. o parameter passing
  3345. o returning as result from functions
  3346. Revision 1.19 1998/07/14 14:47:05 peter
  3347. * released NEWINPUT
  3348. Revision 1.18 1998/07/10 10:51:04 peter
  3349. * m68k updates
  3350. Revision 1.16 1998/07/07 11:20:13 peter
  3351. + NEWINPUT for a better inputfile and scanner object
  3352. Revision 1.15 1998/06/24 14:48:37 peter
  3353. * ifdef newppu -> ifndef oldppu
  3354. Revision 1.14 1998/06/16 08:56:31 peter
  3355. + targetcpu
  3356. * cleaner pmodules for newppu
  3357. Revision 1.13 1998/06/15 15:38:09 pierre
  3358. * small bug in systems.pas corrected
  3359. + operators in different units better hanlded
  3360. Revision 1.12 1998/06/15 14:30:12 daniel
  3361. * Reverted my changes.
  3362. Revision 1.10 1998/06/13 00:10:16 peter
  3363. * working browser and newppu
  3364. * some small fixes against crashes which occured in bp7 (but not in
  3365. fpc?!)
  3366. Revision 1.9 1998/06/12 14:10:37 michael
  3367. * Fixed wrong code for ansistring
  3368. Revision 1.8 1998/06/11 10:11:58 peter
  3369. * -gb works again
  3370. Revision 1.7 1998/06/07 15:30:25 florian
  3371. + first working rtti
  3372. + data init/final. for local variables
  3373. Revision 1.6 1998/06/05 14:37:37 pierre
  3374. * fixes for inline for operators
  3375. * inline procedure more correctly restricted
  3376. Revision 1.5 1998/06/04 23:52:01 peter
  3377. * m68k compiles
  3378. + .def file creation moved to gendef.pas so it could also be used
  3379. for win32
  3380. Revision 1.4 1998/06/04 09:55:45 pierre
  3381. * demangled name of procsym reworked to become independant of the mangling
  3382. scheme
  3383. Revision 1.3 1998/06/03 22:49:03 peter
  3384. + wordbool,longbool
  3385. * rename bis,von -> high,low
  3386. * moved some systemunit loading/creating to psystem.pas
  3387. Revision 1.2 1998/05/31 14:13:37 peter
  3388. * fixed call bugs with assembler readers
  3389. + OPR_SYMBOL to hold a symbol in the asm parser
  3390. * fixed staticsymtable vars which were acessed through %ebp instead of
  3391. name
  3392. Revision 1.1 1998/05/27 19:45:09 peter
  3393. * symtable.pas splitted into includefiles
  3394. * symtable adapted for $ifndef OLDPPU
  3395. }