symsym.pas 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
  4. Implementation for the symbols types of the symtable
  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. unit symsym;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,
  24. { target }
  25. cpuinfo,
  26. { symtable }
  27. symconst,symbase,symtype,symdef,
  28. { ppu }
  29. ppu,symppu,
  30. { aasm }
  31. aasm,cpubase
  32. ;
  33. type
  34. {************************************************
  35. TSym
  36. ************************************************}
  37. { this object is the base for all symbol objects }
  38. tstoredsym = class(tsym)
  39. {$ifdef GDB}
  40. isstabwritten : boolean;
  41. {$endif GDB}
  42. refs : longint;
  43. lastref,
  44. defref,
  45. lastwritten : tref;
  46. refcount : longint;
  47. constructor create(const n : string);
  48. constructor loadsym(ppufile:tcompilerppufile);
  49. destructor destroy;override;
  50. procedure write(ppufile:tcompilerppufile);virtual;abstract;
  51. procedure writesym(ppufile:tcompilerppufile);
  52. procedure deref;override;
  53. function mangledname : string;override;
  54. procedure insert_in_data;virtual;
  55. {$ifdef GDB}
  56. function stabstring : pchar;virtual;
  57. procedure concatstabto(asmlist : taasmoutput);virtual;
  58. {$endif GDB}
  59. procedure load_references(ppufile:tcompilerppufile;locals:boolean);virtual;
  60. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;virtual;
  61. end;
  62. tlabelsym = class(tstoredsym)
  63. lab : tasmlabel;
  64. used,
  65. defined : boolean;
  66. code : pointer; { should be ptree! }
  67. constructor create(const n : string; l : tasmlabel);
  68. destructor destroy;override;
  69. constructor load(ppufile:tcompilerppufile);
  70. function mangledname : string;override;
  71. procedure write(ppufile:tcompilerppufile);override;
  72. end;
  73. tunitsym = class(tstoredsym)
  74. unitsymtable : tsymtable;
  75. prevsym : tunitsym;
  76. constructor create(const n : string;ref : tsymtable);
  77. constructor load(ppufile:tcompilerppufile);
  78. destructor destroy;override;
  79. procedure write(ppufile:tcompilerppufile);override;
  80. procedure restoreunitsym;
  81. {$ifdef GDB}
  82. procedure concatstabto(asmlist : taasmoutput);override;
  83. {$endif GDB}
  84. end;
  85. terrorsym = class(tstoredsym)
  86. constructor create;
  87. end;
  88. tprocsym = class(tstoredsym)
  89. definition : tprocdef;
  90. {$ifdef CHAINPROCSYMS}
  91. nextprocsym : tprocsym;
  92. {$endif CHAINPROCSYMS}
  93. is_global : boolean;
  94. constructor create(const n : string);
  95. constructor load(ppufile:tcompilerppufile);
  96. destructor destroy;override;
  97. function mangledname : string;override;
  98. { writes all declarations except the specified one }
  99. procedure write_parameter_lists(skitdef:tprocdef);
  100. { tests, if all procedures definitions are defined and not }
  101. { only forward }
  102. procedure check_forward;
  103. procedure order_overloaded;
  104. procedure write(ppufile:tcompilerppufile);override;
  105. procedure deref;override;
  106. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  107. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  108. {$ifdef GDB}
  109. function stabstring : pchar;override;
  110. procedure concatstabto(asmlist : taasmoutput);override;
  111. {$endif GDB}
  112. end;
  113. ttypesym = class(tstoredsym)
  114. restype : ttype;
  115. {$ifdef GDB}
  116. isusedinstab : boolean;
  117. {$endif GDB}
  118. constructor create(const n : string;const tt : ttype);
  119. constructor load(ppufile:tcompilerppufile);
  120. procedure write(ppufile:tcompilerppufile);override;
  121. procedure deref;override;
  122. function gettypedef:tdef;override;
  123. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  124. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  125. {$ifdef GDB}
  126. function stabstring : pchar;override;
  127. procedure concatstabto(asmlist : taasmoutput);override;
  128. {$endif GDB}
  129. end;
  130. tvarsym = class(tstoredsym)
  131. address : longint;
  132. localvarsym : tvarsym;
  133. vartype : ttype;
  134. varoptions : tvaroptions;
  135. reg : tregister; { if reg<>R_NO, then the variable is an register variable }
  136. varspez : tvarspez; { sets the type of access }
  137. varstate : tvarstate;
  138. constructor create(const n : string;const tt : ttype);
  139. constructor create_dll(const n : string;const tt : ttype);
  140. constructor create_C(const n,mangled : string;const tt : ttype);
  141. constructor load(ppufile:tcompilerppufile);
  142. destructor destroy;override;
  143. procedure write(ppufile:tcompilerppufile);override;
  144. procedure deref;override;
  145. procedure setmangledname(const s : string);
  146. function mangledname : string;override;
  147. procedure insert_in_data;override;
  148. function getsize : longint;
  149. function getvaluesize : longint;
  150. function getpushsize : longint;
  151. {$ifdef GDB}
  152. function stabstring : pchar;override;
  153. procedure concatstabto(asmlist : taasmoutput);override;
  154. {$endif GDB}
  155. private
  156. _mangledname : pchar;
  157. end;
  158. tpropertysym = class(tstoredsym)
  159. propoptions : tpropertyoptions;
  160. propoverriden : tpropertysym;
  161. proptype,
  162. indextype : ttype;
  163. index,
  164. default : longint;
  165. readaccess,
  166. writeaccess,
  167. storedaccess : tsymlist;
  168. constructor create(const n : string);
  169. destructor destroy;override;
  170. constructor load(ppufile:tcompilerppufile);
  171. function getsize : longint;
  172. procedure write(ppufile:tcompilerppufile);override;
  173. function gettypedef:tdef;override;
  174. procedure deref;override;
  175. procedure dooverride(overriden:tpropertysym);
  176. {$ifdef GDB}
  177. function stabstring : pchar;override;
  178. procedure concatstabto(asmlist : taasmoutput);override;
  179. {$endif GDB}
  180. end;
  181. tfuncretsym = class(tstoredsym)
  182. returntype : ttype;
  183. address : longint;
  184. funcretstate : tvarstate;
  185. constructor create(const n : string;const tt : ttype);
  186. constructor load(ppufile:tcompilerppufile);
  187. destructor destroy;override;
  188. procedure write(ppufile:tcompilerppufile);override;
  189. procedure deref;override;
  190. procedure insert_in_data;override;
  191. {$ifdef GDB}
  192. procedure concatstabto(asmlist : taasmoutput);override;
  193. {$endif GDB}
  194. end;
  195. tabsolutesym = class(tvarsym)
  196. abstyp : absolutetyp;
  197. absseg : boolean;
  198. ref : tstoredsym;
  199. asmname : pstring;
  200. constructor create(const n : string;const tt : ttype);
  201. constructor load(ppufile:tcompilerppufile);
  202. procedure deref;override;
  203. function mangledname : string;override;
  204. procedure write(ppufile:tcompilerppufile);override;
  205. procedure insert_in_data;override;
  206. {$ifdef GDB}
  207. procedure concatstabto(asmlist : taasmoutput);override;
  208. {$endif GDB}
  209. end;
  210. ttypedconstsym = class(tstoredsym)
  211. prefix : pstring;
  212. typedconsttype : ttype;
  213. is_writable : boolean;
  214. constructor create(const n : string;p : tdef;writable : boolean);
  215. constructor createtype(const n : string;const tt : ttype;writable : boolean);
  216. constructor load(ppufile:tcompilerppufile);
  217. destructor destroy;override;
  218. function mangledname : string;override;
  219. procedure write(ppufile:tcompilerppufile);override;
  220. procedure deref;override;
  221. function getsize:longint;
  222. procedure insert_in_data;override;
  223. {$ifdef GDB}
  224. function stabstring : pchar;override;
  225. {$endif GDB}
  226. end;
  227. tconstsym = class(tstoredsym)
  228. consttype : ttype;
  229. consttyp : tconsttyp;
  230. resstrindex, { needed for resource strings }
  231. valueord : tconstexprint; { used for ordinal values }
  232. valueordptr : TConstPtrUInt; { used for pointer values }
  233. valueptr : pointer; { used for string, set, real values }
  234. len : longint; { len is needed for string length }
  235. constructor create_ord(const n : string;t : tconsttyp;v : tconstexprint);
  236. constructor create_ord_typed(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  237. constructor create_ordptr_typed(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  238. constructor create_ptr(const n : string;t : tconsttyp;v : pointer);
  239. constructor create_ptr_typed(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  240. constructor create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  241. constructor load(ppufile:tcompilerppufile);
  242. destructor destroy;override;
  243. function mangledname : string;override;
  244. procedure deref;override;
  245. procedure write(ppufile:tcompilerppufile);override;
  246. {$ifdef GDB}
  247. function stabstring : pchar;override;
  248. procedure concatstabto(asmlist : taasmoutput);override;
  249. {$endif GDB}
  250. end;
  251. tenumsym = class(tstoredsym)
  252. value : longint;
  253. definition : tenumdef;
  254. nextenum : tenumsym;
  255. constructor create(const n : string;def : tenumdef;v : longint);
  256. constructor load(ppufile:tcompilerppufile);
  257. procedure write(ppufile:tcompilerppufile);override;
  258. procedure deref;override;
  259. procedure order;
  260. {$ifdef GDB}
  261. procedure concatstabto(asmlist : taasmoutput);override;
  262. {$endif GDB}
  263. end;
  264. tsyssym = class(tstoredsym)
  265. number : longint;
  266. constructor create(const n : string;l : longint);
  267. constructor load(ppufile:tcompilerppufile);
  268. destructor destroy;override;
  269. procedure write(ppufile:tcompilerppufile);override;
  270. {$ifdef GDB}
  271. procedure concatstabto(asmlist : taasmoutput);override;
  272. {$endif GDB}
  273. end;
  274. { compiler generated symbol to point to rtti and init/finalize tables }
  275. trttisym = class(tstoredsym)
  276. lab : tasmsymbol;
  277. rttityp : trttitype;
  278. constructor create(const n:string;rt:trttitype);
  279. constructor load(ppufile:tcompilerppufile);
  280. procedure write(ppufile:tcompilerppufile);override;
  281. function mangledname:string;override;
  282. function get_label:tasmsymbol;
  283. end;
  284. { register variables }
  285. pregvarinfo = ^tregvarinfo;
  286. tregvarinfo = record
  287. regvars : array[1..maxvarregs] of tvarsym;
  288. regvars_para : array[1..maxvarregs] of boolean;
  289. regvars_refs : array[1..maxvarregs] of longint;
  290. fpuregvars : array[1..maxfpuvarregs] of tvarsym;
  291. fpuregvars_para : array[1..maxfpuvarregs] of boolean;
  292. fpuregvars_refs : array[1..maxfpuvarregs] of longint;
  293. end;
  294. var
  295. aktprocsym : tprocsym; { pointer to the symbol for the
  296. currently be parsed procedure }
  297. aktcallprocsym : tprocsym; { pointer to the symbol for the
  298. currently be called procedure,
  299. only set/unset in firstcall }
  300. aktvarsym : tvarsym; { pointer to the symbol for the
  301. currently read var, only used
  302. for variable directives }
  303. generrorsym : tsym;
  304. procprefix : string; { prefix generated for the current compiled proc }
  305. const
  306. current_object_option : tsymoptions = [sp_public];
  307. { rtti and init/final }
  308. procedure generate_rtti(p:tsym);
  309. procedure generate_inittable(p:tsym);
  310. implementation
  311. uses
  312. {$ifdef Delphi}
  313. sysutils,
  314. {$else Delphi}
  315. strings,
  316. {$endif Delphi}
  317. { global }
  318. globtype,globals,verbose,
  319. { target }
  320. systems,
  321. { symtable }
  322. symtable,types,
  323. {$ifdef GDB}
  324. gdb,
  325. {$endif GDB}
  326. { aasm }
  327. cpuasm,
  328. { module }
  329. fmodule,
  330. { codegen }
  331. cgbase,cresstr
  332. ;
  333. {****************************************************************************
  334. TSYM (base for all symtypes)
  335. ****************************************************************************}
  336. constructor tstoredsym.create(const n : string);
  337. begin
  338. inherited create(n);
  339. symoptions:=current_object_option;
  340. {$ifdef GDB}
  341. isstabwritten := false;
  342. {$endif GDB}
  343. fileinfo:=akttokenpos;
  344. defref:=nil;
  345. refs:=0;
  346. lastwritten:=nil;
  347. refcount:=0;
  348. if (cs_browser in aktmoduleswitches) and make_ref then
  349. begin
  350. defref:=tref.create(defref,@akttokenpos);
  351. inc(refcount);
  352. end;
  353. lastref:=defref;
  354. end;
  355. constructor tstoredsym.loadsym(ppufile:tcompilerppufile);
  356. var
  357. s : string;
  358. nr : word;
  359. begin
  360. nr:=ppufile.getword;
  361. s:=ppufile.getstring;
  362. inherited create(s);
  363. { force the correct indexnr. must be after create! }
  364. indexnr:=nr;
  365. ppufile.getsmallset(symoptions);
  366. ppufile.getposinfo(fileinfo);
  367. lastref:=nil;
  368. defref:=nil;
  369. refs:=0;
  370. lastwritten:=nil;
  371. refcount:=0;
  372. {$ifdef GDB}
  373. isstabwritten := false;
  374. {$endif GDB}
  375. end;
  376. procedure tstoredsym.deref;
  377. begin
  378. end;
  379. procedure tstoredsym.load_references(ppufile:tcompilerppufile;locals:boolean);
  380. var
  381. pos : tfileposinfo;
  382. move_last : boolean;
  383. begin
  384. move_last:=lastwritten=lastref;
  385. while (not ppufile.endofentry) do
  386. begin
  387. ppufile.getposinfo(pos);
  388. inc(refcount);
  389. lastref:=tref.create(lastref,@pos);
  390. lastref.is_written:=true;
  391. if refcount=1 then
  392. defref:=lastref;
  393. end;
  394. if move_last then
  395. lastwritten:=lastref;
  396. end;
  397. { big problem here :
  398. wrong refs were written because of
  399. interface parsing of other units PM
  400. moduleindex must be checked !! }
  401. function tstoredsym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  402. var
  403. ref : tref;
  404. symref_written,move_last : boolean;
  405. begin
  406. write_references:=false;
  407. if lastwritten=lastref then
  408. exit;
  409. { should we update lastref }
  410. move_last:=true;
  411. symref_written:=false;
  412. { write symbol refs }
  413. if assigned(lastwritten) then
  414. ref:=lastwritten
  415. else
  416. ref:=defref;
  417. while assigned(ref) do
  418. begin
  419. if ref.moduleindex=current_module.unit_index then
  420. begin
  421. { write address to this symbol }
  422. if not symref_written then
  423. begin
  424. ppufile.putderef(self);
  425. symref_written:=true;
  426. end;
  427. ppufile.putposinfo(ref.posinfo);
  428. ref.is_written:=true;
  429. if move_last then
  430. lastwritten:=ref;
  431. end
  432. else if not ref.is_written then
  433. move_last:=false
  434. else if move_last then
  435. lastwritten:=ref;
  436. ref:=ref.nextref;
  437. end;
  438. if symref_written then
  439. ppufile.writeentry(ibsymref);
  440. write_references:=symref_written;
  441. end;
  442. destructor tstoredsym.destroy;
  443. begin
  444. if assigned(defref) then
  445. begin
  446. defref.freechain;
  447. defref.free;
  448. end;
  449. inherited destroy;
  450. end;
  451. procedure tstoredsym.writesym(ppufile:tcompilerppufile);
  452. begin
  453. ppufile.putword(indexnr);
  454. ppufile.putstring(_realname^);
  455. ppufile.putsmallset(symoptions);
  456. ppufile.putposinfo(fileinfo);
  457. end;
  458. function tstoredsym.mangledname : string;
  459. begin
  460. mangledname:=name;
  461. end;
  462. { for most symbol types there is nothing to do at all }
  463. procedure tstoredsym.insert_in_data;
  464. begin
  465. end;
  466. {$ifdef GDB}
  467. function tstoredsym.stabstring : pchar;
  468. begin
  469. stabstring:=strpnew('"'+name+'",'+tostr(N_LSYM)+',0,'+
  470. tostr(fileinfo.line)+',0');
  471. end;
  472. procedure tstoredsym.concatstabto(asmlist : taasmoutput);
  473. var
  474. stab_str : pchar;
  475. begin
  476. if not isstabwritten then
  477. begin
  478. stab_str := stabstring;
  479. { count_dbx(stab_str); moved to GDB.PAS }
  480. asmList.concat(Tai_stabs.Create(stab_str));
  481. isstabwritten:=true;
  482. end;
  483. end;
  484. {$endif GDB}
  485. {****************************************************************************
  486. TLABELSYM
  487. ****************************************************************************}
  488. constructor tlabelsym.create(const n : string; l : tasmlabel);
  489. begin
  490. inherited create(n);
  491. typ:=labelsym;
  492. lab:=l;
  493. used:=false;
  494. defined:=false;
  495. code:=nil;
  496. end;
  497. constructor tlabelsym.load(ppufile:tcompilerppufile);
  498. begin
  499. inherited loadsym(ppufile);
  500. typ:=labelsym;
  501. { this is all dummy
  502. it is only used for local browsing }
  503. lab:=nil;
  504. code:=nil;
  505. used:=false;
  506. defined:=true;
  507. end;
  508. destructor tlabelsym.destroy;
  509. begin
  510. inherited destroy;
  511. end;
  512. function tlabelsym.mangledname : string;
  513. begin
  514. mangledname:=lab.name;
  515. end;
  516. procedure tlabelsym.write(ppufile:tcompilerppufile);
  517. begin
  518. if owner.symtabletype=globalsymtable then
  519. Message(sym_e_ill_label_decl)
  520. else
  521. begin
  522. inherited writesym(ppufile);
  523. ppufile.writeentry(iblabelsym);
  524. end;
  525. end;
  526. {****************************************************************************
  527. TUNITSYM
  528. ****************************************************************************}
  529. constructor tunitsym.create(const n : string;ref : tsymtable);
  530. var
  531. old_make_ref : boolean;
  532. begin
  533. old_make_ref:=make_ref;
  534. make_ref:=false;
  535. inherited create(n);
  536. make_ref:=old_make_ref;
  537. typ:=unitsym;
  538. unitsymtable:=ref;
  539. prevsym:=tglobalsymtable(ref).unitsym;
  540. tglobalsymtable(ref).unitsym:=self;
  541. refs:=0;
  542. end;
  543. constructor tunitsym.load(ppufile:tcompilerppufile);
  544. begin
  545. inherited loadsym(ppufile);
  546. typ:=unitsym;
  547. unitsymtable:=nil;
  548. prevsym:=nil;
  549. refs:=0;
  550. end;
  551. { we need to remove it from the prevsym chain ! }
  552. procedure tunitsym.restoreunitsym;
  553. var pus,ppus : tunitsym;
  554. begin
  555. if assigned(unitsymtable) then
  556. begin
  557. ppus:=nil;
  558. pus:=tglobalsymtable(unitsymtable).unitsym;
  559. if pus=self then
  560. tglobalsymtable(unitsymtable).unitsym:=prevsym
  561. else while assigned(pus) do
  562. begin
  563. if pus=self then
  564. begin
  565. ppus.prevsym:=prevsym;
  566. break;
  567. end
  568. else
  569. begin
  570. ppus:=pus;
  571. pus:=ppus.prevsym;
  572. end;
  573. end;
  574. end;
  575. unitsymtable:=nil;
  576. prevsym:=nil;
  577. end;
  578. destructor tunitsym.destroy;
  579. begin
  580. restoreunitsym;
  581. inherited destroy;
  582. end;
  583. procedure tunitsym.write(ppufile:tcompilerppufile);
  584. begin
  585. inherited writesym(ppufile);
  586. ppufile.writeentry(ibunitsym);
  587. end;
  588. {$ifdef GDB}
  589. procedure tunitsym.concatstabto(asmlist : taasmoutput);
  590. begin
  591. {Nothing to write to stabs !}
  592. end;
  593. {$endif GDB}
  594. {****************************************************************************
  595. TPROCSYM
  596. ****************************************************************************}
  597. constructor tprocsym.create(const n : string);
  598. begin
  599. inherited create(n);
  600. typ:=procsym;
  601. definition:=nil;
  602. owner:=nil;
  603. is_global := false;
  604. end;
  605. constructor tprocsym.load(ppufile:tcompilerppufile);
  606. begin
  607. inherited loadsym(ppufile);
  608. typ:=procsym;
  609. definition:=tprocdef(ppufile.getderef);
  610. is_global := false;
  611. end;
  612. destructor tprocsym.destroy;
  613. begin
  614. inherited destroy;
  615. end;
  616. function tprocsym.mangledname : string;
  617. begin
  618. mangledname:=definition.mangledname;
  619. end;
  620. procedure tprocsym.write_parameter_lists(skitdef:tprocdef);
  621. var
  622. p : tprocdef;
  623. begin
  624. p:=definition;
  625. while assigned(p) do
  626. begin
  627. if p<>skitdef then
  628. MessagePos1(p.fileinfo,sym_b_param_list,p.fullprocname);
  629. p:=p.nextoverloaded;
  630. end;
  631. end;
  632. procedure tprocsym.check_forward;
  633. var
  634. pd : tprocdef;
  635. begin
  636. pd:=definition;
  637. while assigned(pd) do
  638. begin
  639. if pd.forwarddef then
  640. begin
  641. MessagePos1(fileinfo,sym_e_forward_not_resolved,pd.fullprocname);
  642. { Turn futher error messages off }
  643. pd.forwarddef:=false;
  644. end;
  645. pd:=pd.nextoverloaded;
  646. { do not check defs of operators in other units }
  647. if assigned(pd) and (pd.procsym<>self) then
  648. pd:=nil;
  649. end;
  650. end;
  651. procedure tprocsym.deref;
  652. var
  653. pd : tprocdef;
  654. begin
  655. resolvedef(tdef(definition));
  656. pd:=definition;
  657. while assigned(pd) do
  658. begin
  659. pd.procsym:=self;
  660. pd:=pd.nextoverloaded;
  661. end;
  662. end;
  663. procedure tprocsym.order_overloaded;
  664. var firstdef,currdef,lastdef,nextotdef : tprocdef;
  665. begin
  666. if not assigned(definition) then
  667. exit;
  668. firstdef:=definition;
  669. currdef:=definition;
  670. while assigned(currdef) and (currdef.owner=firstdef.owner) do
  671. begin
  672. currdef.count:=false;
  673. currdef:=currdef.nextoverloaded;
  674. end;
  675. nextotdef:=currdef;
  676. definition:=definition.nextoverloaded;
  677. firstdef.nextoverloaded:=nil;
  678. while (definition<>nextotdef) do
  679. begin
  680. currdef:=firstdef;
  681. lastdef:=definition;
  682. definition:=definition.nextoverloaded;
  683. if lastdef.mangledname<firstdef.mangledname then
  684. begin
  685. lastdef.nextoverloaded:=firstdef;
  686. firstdef:=lastdef;
  687. end
  688. else
  689. begin
  690. while assigned(currdef.nextoverloaded) and
  691. (lastdef.mangledname>currdef.nextoverloaded.mangledname) do
  692. currdef:=currdef.nextoverloaded;
  693. lastdef.nextoverloaded:=currdef.nextoverloaded;
  694. currdef.nextoverloaded:=lastdef;
  695. end;
  696. end;
  697. definition:=firstdef;
  698. currdef:=definition;
  699. while assigned(currdef) do
  700. begin
  701. currdef.count:=true;
  702. lastdef:=currdef;
  703. currdef:=currdef.nextoverloaded;
  704. end;
  705. lastdef.nextoverloaded:=nextotdef;
  706. end;
  707. procedure tprocsym.write(ppufile:tcompilerppufile);
  708. begin
  709. inherited writesym(ppufile);
  710. ppufile.putderef(definition);
  711. ppufile.writeentry(ibprocsym);
  712. end;
  713. procedure tprocsym.load_references(ppufile:tcompilerppufile;locals:boolean);
  714. (*var
  715. prdef,prdef2 : tprocdef;
  716. b : byte; *)
  717. begin
  718. inherited load_references(ppufile,locals);
  719. (*prdef:=definition;
  720. done in tsymtable.load_browser (PM)
  721. { take care about operators !! }
  722. if (current_module^.flags and uf_has_browser) <>0 then
  723. while assigned(prdef) and (prdef.owner=definition.owner) do
  724. begin
  725. b:=ppufile.readentry;
  726. if b<>ibdefref then
  727. Message(unit_f_ppu_read_error);
  728. prdef2:=tprocdef(readdefref);
  729. resolvedef(prdef2);
  730. if prdef<>prdef2 then
  731. Message(unit_f_ppu_read_error);
  732. prdef.load_references(ppufile);
  733. prdef:=prdef.nextoverloaded;
  734. end; *)
  735. end;
  736. function tprocsym.write_references(ppufile:tcompilerppufile;locals:boolean) : boolean;
  737. var
  738. prdef : tprocdef;
  739. begin
  740. write_references:=false;
  741. if not inherited write_references(ppufile,locals) then
  742. exit;
  743. write_references:=true;
  744. prdef:=definition;
  745. while assigned(prdef) and (prdef.owner=definition.owner) do
  746. begin
  747. prdef.write_references(ppufile,locals);
  748. prdef:=prdef.nextoverloaded;
  749. end;
  750. end;
  751. {$ifdef GDB}
  752. function tprocsym.stabstring : pchar;
  753. Var RetType : Char;
  754. Obj,Info : String;
  755. stabsstr : string;
  756. p : pchar;
  757. begin
  758. obj := name;
  759. info := '';
  760. if is_global then
  761. RetType := 'F'
  762. else
  763. RetType := 'f';
  764. if assigned(owner) then
  765. begin
  766. if (owner.symtabletype = objectsymtable) then
  767. obj := upper(owner.name^)+'__'+name;
  768. { this code was correct only as long as the local symboltable
  769. of the parent had the same name as the function
  770. but this is no true anymore !! PM
  771. if (owner.symtabletype=localsymtable) and assigned(owner.name) then
  772. info := ','+name+','+owner.name^; }
  773. if (owner.symtabletype=localsymtable) and assigned(owner.defowner) and
  774. assigned(tprocdef(owner.defowner).procsym) then
  775. info := ','+name+','+tprocdef(owner.defowner).procsym.name;
  776. end;
  777. stabsstr:=definition.mangledname;
  778. getmem(p,length(stabsstr)+255);
  779. strpcopy(p,'"'+obj+':'+RetType
  780. +tstoreddef(definition.rettype.def).numberstring+info+'",'+tostr(n_function)
  781. +',0,'+
  782. tostr(aktfilepos.line)
  783. +',');
  784. strpcopy(strend(p),stabsstr);
  785. stabstring:=strnew(p);
  786. freemem(p,length(stabsstr)+255);
  787. end;
  788. procedure tprocsym.concatstabto(asmlist : taasmoutput);
  789. begin
  790. if (pocall_internproc in definition.proccalloptions) then exit;
  791. if not isstabwritten then
  792. asmList.concat(Tai_stabs.Create(stabstring));
  793. isstabwritten := true;
  794. if assigned(definition.parast) then
  795. tstoredsymtable(definition.parast).concatstabto(asmlist);
  796. { local type defs and vars should not be written
  797. inside the main proc stab }
  798. if assigned(definition.localst) and
  799. (lexlevel>main_program_level) then
  800. tstoredsymtable(definition.localst).concatstabto(asmlist);
  801. definition.is_def_stab_written := written;
  802. end;
  803. {$endif GDB}
  804. {****************************************************************************
  805. TERRORSYM
  806. ****************************************************************************}
  807. constructor terrorsym.create;
  808. begin
  809. inherited create('');
  810. typ:=errorsym;
  811. end;
  812. {****************************************************************************
  813. TPROPERTYSYM
  814. ****************************************************************************}
  815. constructor tpropertysym.create(const n : string);
  816. begin
  817. inherited create(n);
  818. typ:=propertysym;
  819. propoptions:=[];
  820. index:=0;
  821. default:=0;
  822. proptype.reset;
  823. indextype.reset;
  824. readaccess:=tsymlist.create;
  825. writeaccess:=tsymlist.create;
  826. storedaccess:=tsymlist.create;
  827. end;
  828. constructor tpropertysym.load(ppufile:tcompilerppufile);
  829. begin
  830. inherited loadsym(ppufile);
  831. typ:=propertysym;
  832. ppufile.getsmallset(propoptions);
  833. if (ppo_is_override in propoptions) then
  834. begin
  835. propoverriden:=tpropertysym(ppufile.getderef);
  836. { we need to have these objects initialized }
  837. readaccess:=tsymlist.create;
  838. writeaccess:=tsymlist.create;
  839. storedaccess:=tsymlist.create;
  840. end
  841. else
  842. begin
  843. ppufile.gettype(proptype);
  844. index:=ppufile.getlongint;
  845. default:=ppufile.getlongint;
  846. ppufile.gettype(indextype);
  847. readaccess:=ppufile.getsymlist;
  848. writeaccess:=ppufile.getsymlist;
  849. storedaccess:=ppufile.getsymlist;
  850. end;
  851. end;
  852. destructor tpropertysym.destroy;
  853. begin
  854. readaccess.free;
  855. writeaccess.free;
  856. storedaccess.free;
  857. inherited destroy;
  858. end;
  859. function tpropertysym.gettypedef:tdef;
  860. begin
  861. gettypedef:=proptype.def;
  862. end;
  863. procedure tpropertysym.deref;
  864. begin
  865. if (ppo_is_override in propoptions) then
  866. begin
  867. resolvesym(tsym(propoverriden));
  868. dooverride(propoverriden);
  869. end
  870. else
  871. begin
  872. proptype.resolve;
  873. indextype.resolve;
  874. readaccess.resolve;
  875. writeaccess.resolve;
  876. storedaccess.resolve;
  877. end;
  878. end;
  879. function tpropertysym.getsize : longint;
  880. begin
  881. getsize:=0;
  882. end;
  883. procedure tpropertysym.write(ppufile:tcompilerppufile);
  884. begin
  885. inherited writesym(ppufile);
  886. ppufile.putsmallset(propoptions);
  887. if (ppo_is_override in propoptions) then
  888. ppufile.putderef(propoverriden)
  889. else
  890. begin
  891. ppufile.puttype(proptype);
  892. ppufile.putlongint(index);
  893. ppufile.putlongint(default);
  894. ppufile.puttype(indextype);
  895. ppufile.putsymlist(readaccess);
  896. ppufile.putsymlist(writeaccess);
  897. ppufile.putsymlist(storedaccess);
  898. end;
  899. ppufile.writeentry(ibpropertysym);
  900. end;
  901. procedure tpropertysym.dooverride(overriden:tpropertysym);
  902. begin
  903. propoverriden:=overriden;
  904. proptype:=overriden.proptype;
  905. propoptions:=overriden.propoptions+[ppo_is_override];
  906. index:=overriden.index;
  907. default:=overriden.default;
  908. indextype:=overriden.indextype;
  909. readaccess.clear;
  910. readaccess:=overriden.readaccess.getcopy;
  911. writeaccess.clear;
  912. writeaccess:=overriden.writeaccess.getcopy;
  913. storedaccess.clear;
  914. storedaccess:=overriden.storedaccess.getcopy;
  915. end;
  916. {$ifdef GDB}
  917. function tpropertysym.stabstring : pchar;
  918. begin
  919. { !!!! don't know how to handle }
  920. stabstring:=strpnew('');
  921. end;
  922. procedure tpropertysym.concatstabto(asmlist : taasmoutput);
  923. begin
  924. { !!!! don't know how to handle }
  925. end;
  926. {$endif GDB}
  927. {****************************************************************************
  928. TFUNCRETSYM
  929. ****************************************************************************}
  930. constructor tfuncretsym.create(const n : string;const tt:ttype);
  931. begin
  932. inherited create(n);
  933. typ:=funcretsym;
  934. returntype:=tt;
  935. funcretstate:=vs_declared;
  936. { address valid for ret in param only }
  937. { otherwise set by insert }
  938. address:=pprocinfo(procinfo)^.return_offset;
  939. end;
  940. constructor tfuncretsym.load(ppufile:tcompilerppufile);
  941. begin
  942. inherited loadsym(ppufile);
  943. ppufile.gettype(returntype);
  944. address:=ppufile.getlongint;
  945. typ:=funcretsym;
  946. end;
  947. destructor tfuncretsym.destroy;
  948. begin
  949. inherited destroy;
  950. end;
  951. procedure tfuncretsym.write(ppufile:tcompilerppufile);
  952. begin
  953. inherited writesym(ppufile);
  954. ppufile.puttype(returntype);
  955. ppufile.putlongint(address);
  956. ppufile.writeentry(ibfuncretsym);
  957. funcretstate:=vs_used;
  958. end;
  959. procedure tfuncretsym.deref;
  960. begin
  961. returntype.resolve;
  962. end;
  963. {$ifdef GDB}
  964. procedure tfuncretsym.concatstabto(asmlist : taasmoutput);
  965. begin
  966. { Nothing to do here, it is done in genexitcode }
  967. end;
  968. {$endif GDB}
  969. procedure tfuncretsym.insert_in_data;
  970. var
  971. varalign,l : longint;
  972. begin
  973. { if retoffset is already set then reuse it, this is needed
  974. when inserting the result variable }
  975. if procinfo^.return_offset<>0 then
  976. address:=procinfo^.return_offset
  977. else
  978. begin
  979. { allocate space in local if ret in acc or in fpu }
  980. if ret_in_acc(returntype.def) or
  981. (returntype.def.deftype=floatdef) then
  982. begin
  983. l:=returntype.def.size;
  984. varalign:=size_2_align(l);
  985. varalign:=used_align(varalign,aktalignment.localalignmin,owner.dataalignment);
  986. address:=align(owner.datasize+l,varalign);
  987. owner.datasize:=address;
  988. procinfo^.return_offset:=-address;
  989. end;
  990. end;
  991. end;
  992. {****************************************************************************
  993. TABSOLUTESYM
  994. ****************************************************************************}
  995. constructor tabsolutesym.create(const n : string;const tt : ttype);
  996. begin
  997. inherited create(n,tt);
  998. typ:=absolutesym;
  999. end;
  1000. constructor tabsolutesym.load(ppufile:tcompilerppufile);
  1001. begin
  1002. { Note: This needs to load everything of tvarsym.write }
  1003. inherited load(ppufile);
  1004. { load absolute }
  1005. typ:=absolutesym;
  1006. ref:=nil;
  1007. address:=0;
  1008. asmname:=nil;
  1009. abstyp:=absolutetyp(ppufile.getbyte);
  1010. absseg:=false;
  1011. case abstyp of
  1012. tovar :
  1013. asmname:=stringdup(ppufile.getstring);
  1014. toasm :
  1015. asmname:=stringdup(ppufile.getstring);
  1016. toaddr :
  1017. begin
  1018. address:=ppufile.getlongint;
  1019. absseg:=boolean(ppufile.getbyte);
  1020. end;
  1021. end;
  1022. end;
  1023. procedure tabsolutesym.write(ppufile:tcompilerppufile);
  1024. var
  1025. hvo : tvaroptions;
  1026. begin
  1027. { Note: This needs to write everything of tvarsym.write }
  1028. inherited writesym(ppufile);
  1029. ppufile.putbyte(byte(varspez));
  1030. if read_member then
  1031. ppufile.putlongint(address);
  1032. { write only definition or definitionsym }
  1033. ppufile.puttype(vartype);
  1034. hvo:=varoptions-[vo_regable];
  1035. ppufile.putsmallset(hvo);
  1036. ppufile.putbyte(byte(abstyp));
  1037. case abstyp of
  1038. tovar :
  1039. ppufile.putstring(ref.name);
  1040. toasm :
  1041. ppufile.putstring(asmname^);
  1042. toaddr :
  1043. begin
  1044. ppufile.putlongint(address);
  1045. ppufile.putbyte(byte(absseg));
  1046. end;
  1047. end;
  1048. ppufile.writeentry(ibabsolutesym);
  1049. end;
  1050. procedure tabsolutesym.deref;
  1051. var
  1052. srsym : tsym;
  1053. srsymtable : tsymtable;
  1054. begin
  1055. { inheritance of varsym.deref ! }
  1056. vartype.resolve;
  1057. { own absolute deref }
  1058. if (abstyp=tovar) and (asmname<>nil) then
  1059. begin
  1060. { search previous loaded symtables }
  1061. searchsym(asmname^,srsym,srsymtable);
  1062. if not assigned(srsym) then
  1063. srsym:=searchsymonlyin(owner,asmname^);
  1064. if not assigned(srsym) then
  1065. srsym:=generrorsym;
  1066. ref:=tstoredsym(srsym);
  1067. stringdispose(asmname);
  1068. end;
  1069. end;
  1070. function tabsolutesym.mangledname : string;
  1071. begin
  1072. case abstyp of
  1073. tovar :
  1074. mangledname:=ref.mangledname;
  1075. toasm :
  1076. mangledname:=asmname^;
  1077. toaddr :
  1078. mangledname:='$'+tostr(address);
  1079. else
  1080. internalerror(10002);
  1081. end;
  1082. end;
  1083. procedure tabsolutesym.insert_in_data;
  1084. begin
  1085. end;
  1086. {$ifdef GDB}
  1087. procedure tabsolutesym.concatstabto(asmlist : taasmoutput);
  1088. begin
  1089. { I don't know how to handle this !! }
  1090. end;
  1091. {$endif GDB}
  1092. {****************************************************************************
  1093. TVARSYM
  1094. ****************************************************************************}
  1095. constructor tvarsym.create(const n : string;const tt : ttype);
  1096. begin
  1097. inherited create(n);
  1098. typ:=varsym;
  1099. vartype:=tt;
  1100. _mangledname:=nil;
  1101. varspez:=vs_value;
  1102. address:=0;
  1103. localvarsym:=nil;
  1104. refs:=0;
  1105. varstate:=vs_used;
  1106. varoptions:=[];
  1107. { can we load the value into a register ? }
  1108. if tstoreddef(tt.def).is_intregable then
  1109. include(varoptions,vo_regable)
  1110. else
  1111. exclude(varoptions,vo_regable);
  1112. if tstoreddef(tt.def).is_fpuregable then
  1113. include(varoptions,vo_fpuregable)
  1114. else
  1115. exclude(varoptions,vo_fpuregable);
  1116. reg:=R_NO;
  1117. end;
  1118. constructor tvarsym.create_dll(const n : string;const tt : ttype);
  1119. begin
  1120. tvarsym(self).create(n,tt);
  1121. include(varoptions,vo_is_dll_var);
  1122. end;
  1123. constructor tvarsym.create_C(const n,mangled : string;const tt : ttype);
  1124. begin
  1125. tvarsym(self).create(n,tt);
  1126. include(varoptions,vo_is_C_var);
  1127. setmangledname(mangled);
  1128. end;
  1129. constructor tvarsym.load(ppufile:tcompilerppufile);
  1130. begin
  1131. inherited loadsym(ppufile);
  1132. typ:=varsym;
  1133. _mangledname:=nil;
  1134. reg:=R_NO;
  1135. refs := 0;
  1136. varstate:=vs_used;
  1137. varspez:=tvarspez(ppufile.getbyte);
  1138. if read_member then
  1139. address:=ppufile.getlongint
  1140. else
  1141. address:=0;
  1142. localvarsym:=nil;
  1143. ppufile.gettype(vartype);
  1144. ppufile.getsmallset(varoptions);
  1145. if (vo_is_C_var in varoptions) then
  1146. setmangledname(ppufile.getstring);
  1147. end;
  1148. destructor tvarsym.destroy;
  1149. begin
  1150. strdispose(_mangledname);
  1151. inherited destroy;
  1152. end;
  1153. procedure tvarsym.deref;
  1154. begin
  1155. vartype.resolve;
  1156. end;
  1157. procedure tvarsym.write(ppufile:tcompilerppufile);
  1158. var
  1159. hvo : tvaroptions;
  1160. begin
  1161. inherited writesym(ppufile);
  1162. ppufile.putbyte(byte(varspez));
  1163. if read_member then
  1164. ppufile.putlongint(address);
  1165. ppufile.puttype(vartype);
  1166. { symbols which are load are never candidates for a register,
  1167. turn off the regable }
  1168. hvo:=varoptions-[vo_regable,vo_fpuregable];
  1169. ppufile.putsmallset(hvo);
  1170. if (vo_is_C_var in varoptions) then
  1171. ppufile.putstring(mangledname);
  1172. ppufile.writeentry(ibvarsym);
  1173. end;
  1174. procedure tvarsym.setmangledname(const s : string);
  1175. begin
  1176. _mangledname:=strpnew(s);
  1177. end;
  1178. function tvarsym.mangledname : string;
  1179. var
  1180. prefix : string;
  1181. begin
  1182. if assigned(_mangledname) then
  1183. begin
  1184. mangledname:=strpas(_mangledname);
  1185. exit;
  1186. end;
  1187. case owner.symtabletype of
  1188. staticsymtable :
  1189. if (cs_create_smart in aktmoduleswitches) then
  1190. prefix:='_'+upper(owner.name^)+'$$$_'
  1191. else
  1192. prefix:='_';
  1193. globalsymtable :
  1194. prefix:=
  1195. 'U_'+upper(owner.name^)+'_';
  1196. else
  1197. Message(sym_e_invalid_call_tvarsymmangledname);
  1198. end;
  1199. mangledname:=prefix+name;
  1200. end;
  1201. function tvarsym.getsize : longint;
  1202. begin
  1203. if assigned(vartype.def) then
  1204. getsize:=vartype.def.size
  1205. else
  1206. getsize:=0;
  1207. end;
  1208. function tvarsym.getvaluesize : longint;
  1209. begin
  1210. if assigned(vartype.def) and
  1211. (varspez=vs_value) and
  1212. ((vartype.def.deftype<>arraydef) or
  1213. (tarraydef(vartype.def).highrange>=tarraydef(vartype.def).lowrange)) then
  1214. getvaluesize:=vartype.def.size
  1215. else
  1216. getvaluesize:=0;
  1217. end;
  1218. function tvarsym.getpushsize : longint;
  1219. begin
  1220. if assigned(vartype.def) then
  1221. begin
  1222. case varspez of
  1223. vs_out,
  1224. vs_var :
  1225. getpushsize:=target_info.size_of_pointer;
  1226. vs_value,
  1227. vs_const :
  1228. begin
  1229. if push_addr_param(vartype.def) then
  1230. getpushsize:=target_info.size_of_pointer
  1231. else
  1232. getpushsize:=vartype.def.size;
  1233. end;
  1234. end;
  1235. end
  1236. else
  1237. getpushsize:=0;
  1238. end;
  1239. procedure tvarsym.insert_in_data;
  1240. var
  1241. varalign,
  1242. l,modulo : longint;
  1243. storefilepos : tfileposinfo;
  1244. begin
  1245. if (vo_is_external in varoptions) then
  1246. exit;
  1247. { handle static variables of objects especially }
  1248. if read_member and (owner.symtabletype=objectsymtable) and
  1249. (sp_static in symoptions) then
  1250. begin
  1251. { the data filed is generated in parser.pas
  1252. with a tobject_FIELDNAME variable }
  1253. { this symbol can't be loaded to a register }
  1254. exclude(varoptions,vo_regable);
  1255. exclude(varoptions,vo_fpuregable);
  1256. end
  1257. else
  1258. if not(read_member) then
  1259. begin
  1260. { made problems with parameters etc. ! (FK) }
  1261. { check for instance of an abstract object or class }
  1262. {
  1263. if (tvarsym(sym).definition.deftype=objectdef) and
  1264. ((tobjectdef(tvarsym(sym).definition).options and oo_is_abstract)<>0) then
  1265. Message(sym_e_no_instance_of_abstract_object);
  1266. }
  1267. storefilepos:=aktfilepos;
  1268. aktfilepos:=akttokenpos;
  1269. if (vo_is_thread_var in varoptions) then
  1270. l:=target_info.size_of_pointer
  1271. else
  1272. l:=getvaluesize;
  1273. case owner.symtabletype of
  1274. stt_exceptsymtable:
  1275. { can contain only one symbol, address calculated later }
  1276. ;
  1277. localsymtable :
  1278. begin
  1279. varstate:=vs_declared;
  1280. varalign:=size_2_align(l);
  1281. varalign:=used_align(varalign,aktalignment.localalignmin,aktalignment.localalignmax);
  1282. address:=align(owner.datasize+l,varalign);
  1283. owner.datasize:=address;
  1284. end;
  1285. staticsymtable :
  1286. begin
  1287. { enable unitialized warning for local symbols }
  1288. varstate:=vs_declared;
  1289. varalign:=size_2_align(l);
  1290. varalign:=used_align(varalign,aktalignment.varalignmin,aktalignment.varalignmax);
  1291. address:=align(owner.datasize,varalign);
  1292. { insert cut for smartlinking or alignment }
  1293. if (cs_create_smart in aktmoduleswitches) then
  1294. bssSegment.concat(Tai_cut.Create)
  1295. else if (address<>owner.datasize) then
  1296. bssSegment.concat(Tai_align.create(varalign));
  1297. owner.datasize:=address+l;
  1298. {$ifdef GDB}
  1299. if cs_debuginfo in aktmoduleswitches then
  1300. concatstabto(bsssegment);
  1301. {$endif GDB}
  1302. if (cs_create_smart in aktmoduleswitches) or
  1303. DLLSource or
  1304. (vo_is_exported in varoptions) or
  1305. (vo_is_C_var in varoptions) then
  1306. bssSegment.concat(Tai_datablock.Create_global(mangledname,l))
  1307. else
  1308. bssSegment.concat(Tai_datablock.Create(mangledname,l));
  1309. { this symbol can't be loaded to a register }
  1310. exclude(varoptions,vo_regable);
  1311. exclude(varoptions,vo_fpuregable);
  1312. end;
  1313. globalsymtable :
  1314. begin
  1315. varalign:=size_2_align(l);
  1316. varalign:=used_align(varalign,aktalignment.varalignmin,aktalignment.varalignmax);
  1317. address:=align(owner.datasize,varalign);
  1318. { insert cut for smartlinking or alignment }
  1319. if (cs_create_smart in aktmoduleswitches) then
  1320. bssSegment.concat(Tai_cut.Create)
  1321. else if (address<>owner.datasize) then
  1322. bssSegment.concat(Tai_align.create(varalign));
  1323. owner.datasize:=address+l;
  1324. {$ifdef GDB}
  1325. if cs_debuginfo in aktmoduleswitches then
  1326. concatstabto(bsssegment);
  1327. {$endif GDB}
  1328. bssSegment.concat(Tai_datablock.Create_global(mangledname,l));
  1329. { this symbol can't be loaded to a register }
  1330. exclude(varoptions,vo_regable);
  1331. exclude(varoptions,vo_fpuregable);
  1332. end;
  1333. recordsymtable,
  1334. objectsymtable :
  1335. begin
  1336. { this symbol can't be loaded to a register }
  1337. exclude(varoptions,vo_regable);
  1338. exclude(varoptions,vo_fpuregable);
  1339. { get the alignment size }
  1340. if (aktalignment.recordalignmax=-1) then
  1341. begin
  1342. varalign:=vartype.def.alignment;
  1343. if (varalign>4) and ((varalign mod 4)<>0) and
  1344. (vartype.def.deftype=arraydef) then
  1345. begin
  1346. Message1(sym_w_wrong_C_pack,vartype.def.typename);
  1347. end;
  1348. if varalign=0 then
  1349. varalign:=l;
  1350. if (owner.dataalignment<aktalignment.maxCrecordalign) then
  1351. begin
  1352. if (varalign>16) and (owner.dataalignment<32) then
  1353. owner.dataalignment:=32
  1354. else if (varalign>12) and (owner.dataalignment<16) then
  1355. owner.dataalignment:=16
  1356. { 12 is needed for long double }
  1357. else if (varalign>8) and (owner.dataalignment<12) then
  1358. owner.dataalignment:=12
  1359. else if (varalign>4) and (owner.dataalignment<8) then
  1360. owner.dataalignment:=8
  1361. else if (varalign>2) and (owner.dataalignment<4) then
  1362. owner.dataalignment:=4
  1363. else if (varalign>1) and (owner.dataalignment<2) then
  1364. owner.dataalignment:=2;
  1365. end;
  1366. owner.dataalignment:=max(owner.dataalignment,aktalignment.maxCrecordalign);
  1367. end
  1368. else
  1369. varalign:=vartype.def.alignment;
  1370. if varalign=0 then
  1371. varalign:=size_2_align(l);
  1372. varalign:=used_align(varalign,aktalignment.recordalignmin,owner.dataalignment);
  1373. address:=align(owner.datasize,varalign);
  1374. owner.datasize:=address+l;
  1375. end;
  1376. parasymtable :
  1377. begin
  1378. { here we need the size of a push instead of the
  1379. size of the data }
  1380. l:=getpushsize;
  1381. varalign:=size_2_align(l);
  1382. varstate:=vs_assigned;
  1383. { we need the new datasize already aligned so we can't
  1384. use the align_address here }
  1385. address:=owner.datasize;
  1386. varalign:=used_align(varalign,owner.dataalignment,owner.dataalignment);
  1387. owner.datasize:=align(address+l,varalign);
  1388. end
  1389. else
  1390. begin
  1391. modulo:=owner.datasize and 3;
  1392. if (l>=4) and (modulo<>0) then
  1393. inc(owner.datasize,4-modulo)
  1394. else
  1395. if (l>=2) and ((modulo and 1)<>0) then
  1396. inc(owner.datasize);
  1397. address:=owner.datasize;
  1398. inc(owner.datasize,l);
  1399. end;
  1400. end;
  1401. aktfilepos:=storefilepos;
  1402. end;
  1403. end;
  1404. {$ifdef GDB}
  1405. function tvarsym.stabstring : pchar;
  1406. var
  1407. st : string;
  1408. begin
  1409. st:=tstoreddef(vartype.def).numberstring;
  1410. if (owner.symtabletype = objectsymtable) and
  1411. (sp_static in symoptions) then
  1412. begin
  1413. if (cs_gdb_gsym in aktglobalswitches) then st := 'G'+st else st := 'S'+st;
  1414. stabstring := strpnew('"'+upper(owner.name^)+'__'+name+':'+st+
  1415. '",'+
  1416. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1417. end
  1418. else if (owner.symtabletype = globalsymtable) then
  1419. begin
  1420. { Here we used S instead of
  1421. because with G GDB doesn't look at the address field
  1422. but searches the same name or with a leading underscore
  1423. but these names don't exist in pascal !}
  1424. if (cs_gdb_gsym in aktglobalswitches) then st := 'G'+st else st := 'S'+st;
  1425. stabstring := strpnew('"'+name+':'+st+'",'+
  1426. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1427. end
  1428. else if owner.symtabletype = staticsymtable then
  1429. begin
  1430. stabstring := strpnew('"'+name+':S'+st+'",'+
  1431. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1432. end
  1433. else if (owner.symtabletype in [parasymtable,inlineparasymtable]) then
  1434. begin
  1435. case varspez of
  1436. vs_out,
  1437. vs_var : st := 'v'+st;
  1438. vs_value,
  1439. vs_const : if push_addr_param(vartype.def) then
  1440. st := 'v'+st { should be 'i' but 'i' doesn't work }
  1441. else
  1442. st := 'p'+st;
  1443. end;
  1444. stabstring := strpnew('"'+name+':'+st+'",'+
  1445. tostr(N_tsym)+',0,'+tostr(fileinfo.line)+','+
  1446. tostr(address+owner.address_fixup));
  1447. {offset to ebp => will not work if the framepointer is esp
  1448. so some optimizing will make things harder to debug }
  1449. end
  1450. else if (owner.symtabletype in [localsymtable,inlinelocalsymtable]) then
  1451. {$ifdef i386}
  1452. if reg<>R_NO then
  1453. begin
  1454. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1455. { this is the register order for GDB}
  1456. stabstring:=strpnew('"'+name+':r'+st+'",'+
  1457. tostr(N_RSYM)+',0,'+
  1458. tostr(fileinfo.line)+','+tostr(GDB_i386index[reg]));
  1459. end
  1460. else
  1461. {$endif i386}
  1462. { I don't know if this will work (PM) }
  1463. if (vo_is_C_var in varoptions) then
  1464. stabstring := strpnew('"'+name+':S'+st+'",'+
  1465. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname)
  1466. else
  1467. stabstring := strpnew('"'+name+':'+st+'",'+
  1468. tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',-'+tostr(address-owner.address_fixup))
  1469. else
  1470. stabstring := inherited stabstring;
  1471. end;
  1472. procedure tvarsym.concatstabto(asmlist : taasmoutput);
  1473. {$ifdef i386}
  1474. var stab_str : pchar;
  1475. {$endif i386}
  1476. begin
  1477. inherited concatstabto(asmlist);
  1478. {$ifdef i386}
  1479. if (owner.symtabletype=parasymtable) and
  1480. (reg<>R_NO) then
  1481. begin
  1482. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1483. { this is the register order for GDB}
  1484. stab_str:=strpnew('"'+name+':r'
  1485. +tstoreddef(vartype.def).numberstring+'",'+
  1486. tostr(N_RSYM)+',0,'+
  1487. tostr(fileinfo.line)+','+tostr(GDB_i386index[reg]));
  1488. asmList.concat(Tai_stabs.Create(stab_str));
  1489. end;
  1490. {$endif i386}
  1491. end;
  1492. {$endif GDB}
  1493. {****************************************************************************
  1494. TTYPEDCONSTSYM
  1495. *****************************************************************************}
  1496. constructor ttypedconstsym.create(const n : string;p : tdef;writable : boolean);
  1497. begin
  1498. inherited create(n);
  1499. typ:=typedconstsym;
  1500. typedconsttype.setdef(p);
  1501. is_writable:=writable;
  1502. prefix:=stringdup(procprefix);
  1503. end;
  1504. constructor ttypedconstsym.createtype(const n : string;const tt : ttype;writable : boolean);
  1505. begin
  1506. inherited create(n);
  1507. typ:=typedconstsym;
  1508. typedconsttype:=tt;
  1509. is_writable:=writable;
  1510. prefix:=stringdup(procprefix);
  1511. end;
  1512. constructor ttypedconstsym.load(ppufile:tcompilerppufile);
  1513. begin
  1514. inherited loadsym(ppufile);
  1515. typ:=typedconstsym;
  1516. ppufile.gettype(typedconsttype);
  1517. prefix:=stringdup(ppufile.getstring);
  1518. is_writable:=boolean(ppufile.getbyte);
  1519. end;
  1520. destructor ttypedconstsym.destroy;
  1521. begin
  1522. stringdispose(prefix);
  1523. inherited destroy;
  1524. end;
  1525. function ttypedconstsym.mangledname : string;
  1526. begin
  1527. mangledname:='TC_'+prefix^+'_'+name;
  1528. end;
  1529. function ttypedconstsym.getsize : longint;
  1530. begin
  1531. if assigned(typedconsttype.def) then
  1532. getsize:=typedconsttype.def.size
  1533. else
  1534. getsize:=0;
  1535. end;
  1536. procedure ttypedconstsym.deref;
  1537. begin
  1538. typedconsttype.resolve;
  1539. end;
  1540. procedure ttypedconstsym.write(ppufile:tcompilerppufile);
  1541. begin
  1542. inherited writesym(ppufile);
  1543. ppufile.puttype(typedconsttype);
  1544. ppufile.putstring(prefix^);
  1545. ppufile.putbyte(byte(is_writable));
  1546. ppufile.writeentry(ibtypedconstsym);
  1547. end;
  1548. procedure ttypedconstsym.insert_in_data;
  1549. var
  1550. curconstsegment : taasmoutput;
  1551. address,l,varalign : longint;
  1552. storefilepos : tfileposinfo;
  1553. begin
  1554. storefilepos:=aktfilepos;
  1555. aktfilepos:=akttokenpos;
  1556. if is_writable then
  1557. curconstsegment:=datasegment
  1558. else
  1559. curconstsegment:=consts;
  1560. l:=getsize;
  1561. varalign:=size_2_align(l);
  1562. varalign:=used_align(varalign,aktalignment.constalignmin,aktalignment.constalignmax);
  1563. address:=align(owner.datasize,varalign);
  1564. { insert cut for smartlinking or alignment }
  1565. if (cs_create_smart in aktmoduleswitches) then
  1566. curconstSegment.concat(Tai_cut.Create)
  1567. else if (address<>owner.datasize) then
  1568. curconstSegment.concat(Tai_align.create(varalign));
  1569. owner.datasize:=address+l;
  1570. {$ifdef GDB}
  1571. if cs_debuginfo in aktmoduleswitches then
  1572. concatstabto(curconstsegment);
  1573. {$endif GDB}
  1574. if (owner.symtabletype=globalsymtable) then
  1575. begin
  1576. if (owner.unitid=0) then
  1577. curconstSegment.concat(Tai_symbol.Createdataname_global(mangledname,getsize));
  1578. end
  1579. else
  1580. begin
  1581. if (cs_create_smart in aktmoduleswitches) or
  1582. DLLSource then
  1583. curconstSegment.concat(Tai_symbol.Createdataname_global(mangledname,getsize))
  1584. else
  1585. curconstSegment.concat(Tai_symbol.Createdataname(mangledname,getsize));
  1586. end;
  1587. aktfilepos:=storefilepos;
  1588. end;
  1589. {$ifdef GDB}
  1590. function ttypedconstsym.stabstring : pchar;
  1591. var
  1592. st : char;
  1593. begin
  1594. if (cs_gdb_gsym in aktglobalswitches) and (owner.symtabletype=globalsymtable) then
  1595. st := 'G'
  1596. else
  1597. st := 'S';
  1598. stabstring := strpnew('"'+name+':'+st+
  1599. tstoreddef(typedconsttype.def).numberstring+'",'+tostr(n_STSYM)+',0,'+
  1600. tostr(fileinfo.line)+','+mangledname);
  1601. end;
  1602. {$endif GDB}
  1603. {****************************************************************************
  1604. TCONSTSYM
  1605. ****************************************************************************}
  1606. constructor tconstsym.create_ord(const n : string;t : tconsttyp;v : TConstExprInt);
  1607. begin
  1608. inherited create(n);
  1609. typ:=constsym;
  1610. consttyp:=t;
  1611. valueord:=v;
  1612. valueordptr:=0;
  1613. valueptr:=nil;
  1614. ResStrIndex:=0;
  1615. consttype.reset;
  1616. len:=0;
  1617. end;
  1618. constructor tconstsym.create_ord_typed(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  1619. begin
  1620. inherited create(n);
  1621. typ:=constsym;
  1622. consttyp:=t;
  1623. valueord:=v;
  1624. valueordptr:=0;
  1625. valueptr:=nil;
  1626. ResStrIndex:=0;
  1627. consttype:=tt;
  1628. len:=0;
  1629. end;
  1630. constructor tconstsym.create_ordptr_typed(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  1631. begin
  1632. inherited create(n);
  1633. typ:=constsym;
  1634. consttyp:=t;
  1635. valueord:=0;
  1636. valueordptr:=v;
  1637. valueptr:=nil;
  1638. ResStrIndex:=0;
  1639. consttype:=tt;
  1640. len:=0;
  1641. end;
  1642. constructor tconstsym.create_ptr(const n : string;t : tconsttyp;v : pointer);
  1643. begin
  1644. inherited create(n);
  1645. typ:=constsym;
  1646. consttyp:=t;
  1647. valueord:=0;
  1648. valueordptr:=0;
  1649. valueptr:=v;
  1650. ResStrIndex:=0;
  1651. consttype.reset;
  1652. len:=0;
  1653. end;
  1654. constructor tconstsym.create_ptr_typed(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  1655. begin
  1656. inherited create(n);
  1657. typ:=constsym;
  1658. consttyp:=t;
  1659. valueord:=0;
  1660. valueordptr:=0;
  1661. valueptr:=v;
  1662. ResStrIndex:=0;
  1663. consttype:=tt;
  1664. len:=0;
  1665. end;
  1666. constructor tconstsym.create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  1667. begin
  1668. inherited create(n);
  1669. typ:=constsym;
  1670. consttyp:=t;
  1671. valueord:=0;
  1672. valueordptr:=0;
  1673. valueptr:=str;
  1674. consttype.reset;
  1675. len:=l;
  1676. if t=constresourcestring then
  1677. ResStrIndex:=ResourceStrings.Register(name,pchar(valueptr),len);
  1678. end;
  1679. constructor tconstsym.load(ppufile:tcompilerppufile);
  1680. var
  1681. pd : pbestreal;
  1682. ps : pnormalset;
  1683. pc : pchar;
  1684. l1,l2 : longint;
  1685. begin
  1686. inherited loadsym(ppufile);
  1687. typ:=constsym;
  1688. consttype.reset;
  1689. consttyp:=tconsttyp(ppufile.getbyte);
  1690. valueord:=0;
  1691. valueordptr:=0;
  1692. valueptr:=nil;
  1693. case consttyp of
  1694. constint:
  1695. if sizeof(tconstexprint)=8 then
  1696. begin
  1697. l1:=ppufile.getlongint;
  1698. l2:=ppufile.getlongint;
  1699. {$ifopt R+}
  1700. {$define Range_check_on}
  1701. {$endif opt R+}
  1702. {$R- needed here }
  1703. valueord:=qword(l1)+(int64(l2) shl 32);
  1704. {$ifdef Range_check_on}
  1705. {$R+}
  1706. {$undef Range_check_on}
  1707. {$endif Range_check_on}
  1708. end
  1709. else
  1710. valueord:=ppufile.getlongint;
  1711. constwchar,
  1712. constbool,
  1713. constchar :
  1714. valueord:=ppufile.getlongint;
  1715. constord :
  1716. begin
  1717. ppufile.gettype(consttype);
  1718. if sizeof(TConstExprInt)=8 then
  1719. begin
  1720. l1:=ppufile.getlongint;
  1721. l2:=ppufile.getlongint;
  1722. {$ifopt R+}
  1723. {$define Range_check_on}
  1724. {$endif opt R+}
  1725. {$R- needed here }
  1726. valueord:=qword(l1)+(int64(l2) shl 32);
  1727. {$ifdef Range_check_on}
  1728. {$R+}
  1729. {$undef Range_check_on}
  1730. {$endif Range_check_on}
  1731. end
  1732. else
  1733. valueord:=ppufile.getlongint;
  1734. end;
  1735. constpointer :
  1736. begin
  1737. ppufile.gettype(consttype);
  1738. if sizeof(TConstPtrUInt)=8 then
  1739. begin
  1740. l1:=ppufile.getlongint;
  1741. l2:=ppufile.getlongint;
  1742. {$ifopt R+}
  1743. {$define Range_check_on}
  1744. {$endif opt R+}
  1745. {$R- needed here }
  1746. valueordptr:=qword(l1)+(int64(l2) shl 32);
  1747. {$ifdef Range_check_on}
  1748. {$R+}
  1749. {$undef Range_check_on}
  1750. {$endif Range_check_on}
  1751. end
  1752. else
  1753. valueordptr:=ppufile.getlongint;
  1754. end;
  1755. conststring,
  1756. constresourcestring :
  1757. begin
  1758. len:=ppufile.getlongint;
  1759. getmem(pc,len+1);
  1760. ppufile.getdata(pc^,len);
  1761. if consttyp=constresourcestring then
  1762. ResStrIndex:=ppufile.getlongint;
  1763. valueptr:=pc;
  1764. end;
  1765. constreal :
  1766. begin
  1767. new(pd);
  1768. pd^:=ppufile.getreal;
  1769. valueptr:=pd;
  1770. end;
  1771. constset :
  1772. begin
  1773. ppufile.gettype(consttype);
  1774. new(ps);
  1775. ppufile.getnormalset(ps^);
  1776. valueptr:=ps;
  1777. end;
  1778. constnil : ;
  1779. else
  1780. Message1(unit_f_ppu_invalid_entry,tostr(ord(consttyp)));
  1781. end;
  1782. end;
  1783. destructor tconstsym.destroy;
  1784. begin
  1785. case consttyp of
  1786. conststring,
  1787. constresourcestring :
  1788. freemem(pchar(valueptr),len+1);
  1789. constreal :
  1790. dispose(pbestreal(valueptr));
  1791. constset :
  1792. dispose(pnormalset(valueptr));
  1793. end;
  1794. inherited destroy;
  1795. end;
  1796. function tconstsym.mangledname : string;
  1797. begin
  1798. mangledname:=name;
  1799. end;
  1800. procedure tconstsym.deref;
  1801. begin
  1802. if consttyp in [constord,constpointer,constset] then
  1803. consttype.resolve;
  1804. end;
  1805. procedure tconstsym.write(ppufile:tcompilerppufile);
  1806. begin
  1807. inherited writesym(ppufile);
  1808. ppufile.putbyte(byte(consttyp));
  1809. case consttyp of
  1810. constnil : ;
  1811. constint:
  1812. begin
  1813. if sizeof(TConstExprInt)=8 then
  1814. begin
  1815. ppufile.putlongint(longint(lo(valueord)));
  1816. ppufile.putlongint(longint(hi(valueord)));
  1817. end
  1818. else
  1819. ppufile.putlongint(valueord);
  1820. end;
  1821. constbool,
  1822. constchar :
  1823. ppufile.putlongint(valueord);
  1824. constord :
  1825. begin
  1826. ppufile.puttype(consttype);
  1827. if sizeof(TConstExprInt)=8 then
  1828. begin
  1829. ppufile.putlongint(longint(lo(valueord)));
  1830. ppufile.putlongint(longint(hi(valueord)));
  1831. end
  1832. else
  1833. ppufile.putlongint(valueord);
  1834. end;
  1835. constpointer :
  1836. begin
  1837. ppufile.puttype(consttype);
  1838. if sizeof(TConstPtrUInt)=8 then
  1839. begin
  1840. ppufile.putlongint(longint(lo(valueordptr)));
  1841. ppufile.putlongint(longint(hi(valueordptr)));
  1842. end
  1843. else
  1844. ppufile.putlongint(valueordptr);
  1845. end;
  1846. conststring,
  1847. constresourcestring :
  1848. begin
  1849. ppufile.putlongint(len);
  1850. ppufile.putdata(pchar(valueptr)^,len);
  1851. if consttyp=constresourcestring then
  1852. ppufile.putlongint(ResStrIndex);
  1853. end;
  1854. constreal :
  1855. ppufile.putreal(pbestreal(valueptr)^);
  1856. constset :
  1857. begin
  1858. ppufile.puttype(consttype);
  1859. ppufile.putnormalset(valueptr^);
  1860. end;
  1861. else
  1862. internalerror(13);
  1863. end;
  1864. ppufile.writeentry(ibconstsym);
  1865. end;
  1866. {$ifdef GDB}
  1867. function tconstsym.stabstring : pchar;
  1868. var st : string;
  1869. begin
  1870. {even GDB v4.16 only now 'i' 'r' and 'e' !!!}
  1871. case consttyp of
  1872. conststring : begin
  1873. st := 's'''+strpas(pchar(valueptr))+'''';
  1874. end;
  1875. constbool,
  1876. constint,
  1877. constord,
  1878. constchar : st := 'i'+int64tostr(valueord);
  1879. constpointer :
  1880. st := 'i'+int64tostr(valueordptr);
  1881. constreal : begin
  1882. system.str(pbestreal(valueptr)^,st);
  1883. st := 'r'+st;
  1884. end;
  1885. { if we don't know just put zero !! }
  1886. else st:='i0';
  1887. {***SETCONST}
  1888. {constset:;} {*** I don't know what to do with a set.}
  1889. { sets are not recognized by GDB}
  1890. {***}
  1891. end;
  1892. stabstring := strpnew('"'+name+':c='+st+'",'+tostr(N_function)+',0,'+
  1893. tostr(fileinfo.line)+',0');
  1894. end;
  1895. procedure tconstsym.concatstabto(asmlist : taasmoutput);
  1896. begin
  1897. if consttyp <> conststring then
  1898. inherited concatstabto(asmlist);
  1899. end;
  1900. {$endif GDB}
  1901. {****************************************************************************
  1902. TENUMSYM
  1903. ****************************************************************************}
  1904. constructor tenumsym.create(const n : string;def : tenumdef;v : longint);
  1905. begin
  1906. inherited create(n);
  1907. typ:=enumsym;
  1908. definition:=def;
  1909. value:=v;
  1910. if def.min>v then
  1911. def.setmin(v);
  1912. if def.max<v then
  1913. def.setmax(v);
  1914. order;
  1915. end;
  1916. constructor tenumsym.load(ppufile:tcompilerppufile);
  1917. begin
  1918. inherited loadsym(ppufile);
  1919. typ:=enumsym;
  1920. definition:=tenumdef(ppufile.getderef);
  1921. value:=ppufile.getlongint;
  1922. nextenum := Nil;
  1923. end;
  1924. procedure tenumsym.deref;
  1925. begin
  1926. resolvedef(tdef(definition));
  1927. order;
  1928. end;
  1929. procedure tenumsym.order;
  1930. var
  1931. sym : tenumsym;
  1932. begin
  1933. sym := tenumsym(definition.firstenum);
  1934. if sym = nil then
  1935. begin
  1936. definition.firstenum := self;
  1937. nextenum := nil;
  1938. exit;
  1939. end;
  1940. { reorder the symbols in increasing value }
  1941. if value < sym.value then
  1942. begin
  1943. nextenum := sym;
  1944. definition.firstenum := self;
  1945. end
  1946. else
  1947. begin
  1948. while (sym.value <= value) and assigned(sym.nextenum) do
  1949. sym := sym.nextenum;
  1950. nextenum := sym.nextenum;
  1951. sym.nextenum := self;
  1952. end;
  1953. end;
  1954. procedure tenumsym.write(ppufile:tcompilerppufile);
  1955. begin
  1956. inherited writesym(ppufile);
  1957. ppufile.putderef(definition);
  1958. ppufile.putlongint(value);
  1959. ppufile.writeentry(ibenumsym);
  1960. end;
  1961. {$ifdef GDB}
  1962. procedure tenumsym.concatstabto(asmlist : taasmoutput);
  1963. begin
  1964. {enum elements have no stab !}
  1965. end;
  1966. {$EndIf GDB}
  1967. {****************************************************************************
  1968. TTYPESYM
  1969. ****************************************************************************}
  1970. constructor ttypesym.create(const n : string;const tt : ttype);
  1971. begin
  1972. inherited create(n);
  1973. typ:=typesym;
  1974. restype:=tt;
  1975. {$ifdef GDB}
  1976. isusedinstab := false;
  1977. {$endif GDB}
  1978. { register the typesym for the definition }
  1979. if assigned(restype.def) and
  1980. (restype.def.deftype<>errordef) and
  1981. not(assigned(restype.def.typesym)) then
  1982. restype.def.typesym:=self;
  1983. end;
  1984. constructor ttypesym.load(ppufile:tcompilerppufile);
  1985. begin
  1986. inherited loadsym(ppufile);
  1987. typ:=typesym;
  1988. {$ifdef GDB}
  1989. isusedinstab := false;
  1990. {$endif GDB}
  1991. ppufile.gettype(restype);
  1992. end;
  1993. function ttypesym.gettypedef:tdef;
  1994. begin
  1995. gettypedef:=restype.def;
  1996. end;
  1997. procedure ttypesym.deref;
  1998. begin
  1999. restype.resolve;
  2000. end;
  2001. procedure ttypesym.write(ppufile:tcompilerppufile);
  2002. begin
  2003. inherited writesym(ppufile);
  2004. ppufile.puttype(restype);
  2005. ppufile.writeentry(ibtypesym);
  2006. end;
  2007. procedure ttypesym.load_references(ppufile:tcompilerppufile;locals:boolean);
  2008. begin
  2009. inherited load_references(ppufile,locals);
  2010. if (restype.def.deftype=recorddef) then
  2011. tstoredsymtable(trecorddef(restype.def).symtable).load_references(ppufile,locals);
  2012. if (restype.def.deftype=objectdef) then
  2013. tstoredsymtable(tobjectdef(restype.def).symtable).load_references(ppufile,locals);
  2014. end;
  2015. function ttypesym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  2016. begin
  2017. if not inherited write_references(ppufile,locals) then
  2018. begin
  2019. { write address of this symbol if record or object
  2020. even if no real refs are there
  2021. because we need it for the symtable }
  2022. if (restype.def.deftype in [recorddef,objectdef]) then
  2023. begin
  2024. ppufile.putderef(self);
  2025. ppufile.writeentry(ibsymref);
  2026. end;
  2027. end;
  2028. write_references:=true;
  2029. if (restype.def.deftype=recorddef) then
  2030. tstoredsymtable(trecorddef(restype.def).symtable).write_references(ppufile,locals);
  2031. if (restype.def.deftype=objectdef) then
  2032. tstoredsymtable(tobjectdef(restype.def).symtable).write_references(ppufile,locals);
  2033. end;
  2034. {$ifdef GDB}
  2035. function ttypesym.stabstring : pchar;
  2036. var
  2037. stabchar : string[2];
  2038. short : string;
  2039. begin
  2040. if restype.def.deftype in tagtypes then
  2041. stabchar := 'Tt'
  2042. else
  2043. stabchar := 't';
  2044. short := '"'+name+':'+stabchar+tstoreddef(restype.def).numberstring
  2045. +'",'+tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',0';
  2046. stabstring := strpnew(short);
  2047. end;
  2048. procedure ttypesym.concatstabto(asmlist : taasmoutput);
  2049. begin
  2050. {not stabs for forward defs }
  2051. if assigned(restype.def) then
  2052. if (restype.def.typesym = self) then
  2053. tstoreddef(restype.def).concatstabto(asmlist)
  2054. else
  2055. inherited concatstabto(asmlist);
  2056. end;
  2057. {$endif GDB}
  2058. {****************************************************************************
  2059. TSYSSYM
  2060. ****************************************************************************}
  2061. constructor tsyssym.create(const n : string;l : longint);
  2062. begin
  2063. inherited create(n);
  2064. typ:=syssym;
  2065. number:=l;
  2066. end;
  2067. constructor tsyssym.load(ppufile:tcompilerppufile);
  2068. begin
  2069. inherited loadsym(ppufile);
  2070. typ:=syssym;
  2071. number:=ppufile.getlongint;
  2072. end;
  2073. destructor tsyssym.destroy;
  2074. begin
  2075. inherited destroy;
  2076. end;
  2077. procedure tsyssym.write(ppufile:tcompilerppufile);
  2078. begin
  2079. inherited writesym(ppufile);
  2080. ppufile.putlongint(number);
  2081. ppufile.writeentry(ibsyssym);
  2082. end;
  2083. {$ifdef GDB}
  2084. procedure tsyssym.concatstabto(asmlist : taasmoutput);
  2085. begin
  2086. end;
  2087. {$endif GDB}
  2088. {****************************************************************************
  2089. TRTTISYM
  2090. ****************************************************************************}
  2091. constructor trttisym.create(const n:string;rt:trttitype);
  2092. const
  2093. prefix : array[trttitype] of string[5]=('$rtti','$init');
  2094. begin
  2095. inherited create(prefix[rt]+n);
  2096. typ:=rttisym;
  2097. lab:=nil;
  2098. rttityp:=rt;
  2099. end;
  2100. constructor trttisym.load(ppufile:tcompilerppufile);
  2101. begin
  2102. inherited loadsym(ppufile);
  2103. typ:=rttisym;
  2104. lab:=nil;
  2105. rttityp:=trttitype(ppufile.getbyte);
  2106. end;
  2107. procedure trttisym.write(ppufile:tcompilerppufile);
  2108. begin
  2109. inherited writesym(ppufile);
  2110. ppufile.putbyte(byte(rttityp));
  2111. ppufile.writeentry(ibrttisym);
  2112. end;
  2113. function trttisym.mangledname : string;
  2114. const
  2115. prefix : array[trttitype] of string[5]=('RTTI_','INIT_');
  2116. var
  2117. s : string;
  2118. p : tsymtable;
  2119. begin
  2120. s:='';
  2121. p:=owner;
  2122. while assigned(p) and (p.symtabletype=localsymtable) do
  2123. begin
  2124. s:=s+'_'+p.defowner.name;
  2125. p:=p.defowner.owner;
  2126. end;
  2127. if not(p.symtabletype in [globalsymtable,staticsymtable]) then
  2128. internalerror(200108265);
  2129. mangledname:=prefix[rttityp]+p.name^+s+'$_'+Copy(name,5,255);
  2130. end;
  2131. function trttisym.get_label:tasmsymbol;
  2132. begin
  2133. { the label is always a global label }
  2134. if not assigned(lab) then
  2135. lab:=newasmsymboltype(mangledname,AB_GLOBAL,AT_DATA);
  2136. get_label:=lab;
  2137. end;
  2138. { persistent rtti generation }
  2139. procedure generate_rtti(p:tsym);
  2140. var
  2141. rsym : trttisym;
  2142. def : tstoreddef;
  2143. begin
  2144. { rtti can only be generated for classes that are always typesyms }
  2145. if not(p.typ=typesym) then
  2146. internalerror(200108261);
  2147. def:=tstoreddef(ttypesym(p).restype.def);
  2148. { only create rtti once for each definition }
  2149. if not(df_has_rttitable in def.defoptions) then
  2150. begin
  2151. { definition should be in the same symtable as the symbol }
  2152. if p.owner<>def.owner then
  2153. internalerror(200108262);
  2154. { create rttisym }
  2155. rsym:=trttisym.create(p.name,fullrtti);
  2156. p.owner.insert(rsym);
  2157. { register rttisym in definition }
  2158. include(def.defoptions,df_has_rttitable);
  2159. def.rttitablesym:=rsym;
  2160. { write rtti data }
  2161. def.write_child_rtti_data(fullrtti);
  2162. if (cs_create_smart in aktmoduleswitches) then
  2163. rttiList.concat(Tai_cut.Create);
  2164. rttiList.concat(Tai_symbol.Create(rsym.get_label,0));
  2165. def.write_rtti_data(fullrtti);
  2166. rttiList.concat(Tai_symbol_end.Create(rsym.get_label));
  2167. end;
  2168. end;
  2169. { persistent init table generation }
  2170. procedure generate_inittable(p:tsym);
  2171. var
  2172. rsym : trttisym;
  2173. def : tstoreddef;
  2174. begin
  2175. { anonymous types are also allowed for records that can be varsym }
  2176. case p.typ of
  2177. typesym :
  2178. def:=tstoreddef(ttypesym(p).restype.def);
  2179. varsym :
  2180. def:=tstoreddef(tvarsym(p).vartype.def);
  2181. else
  2182. internalerror(200108263);
  2183. end;
  2184. { only create inittable once for each definition }
  2185. if not(df_has_inittable in def.defoptions) then
  2186. begin
  2187. { definition should be in the same symtable as the symbol }
  2188. if p.owner<>def.owner then
  2189. internalerror(200108264);
  2190. { create rttisym }
  2191. rsym:=trttisym.create(p.name,initrtti);
  2192. p.owner.insert(rsym);
  2193. { register rttisym in definition }
  2194. include(def.defoptions,df_has_inittable);
  2195. def.inittablesym:=rsym;
  2196. { write inittable data }
  2197. def.write_child_rtti_data(initrtti);
  2198. if (cs_create_smart in aktmoduleswitches) then
  2199. rttiList.concat(Tai_cut.Create);
  2200. rttiList.concat(Tai_symbol.Create(rsym.get_label,0));
  2201. def.write_rtti_data(initrtti);
  2202. rttiList.concat(Tai_symbol_end.Create(rsym.get_label));
  2203. end;
  2204. end;
  2205. end.
  2206. {
  2207. $Log$
  2208. Revision 1.23 2001-10-20 20:30:21 peter
  2209. * read only typed const support, switch $J-
  2210. Revision 1.22 2001/09/19 11:04:42 michael
  2211. * Smartlinking with interfaces fixed
  2212. * Better smartlinking for rtti and init tables
  2213. Revision 1.21 2001/09/02 21:18:29 peter
  2214. * split constsym.value in valueord,valueordptr,valueptr. The valueordptr
  2215. is used for holding target platform pointer values. As those can be
  2216. bigger than the source platform.
  2217. Revision 1.20 2001/08/30 20:13:54 peter
  2218. * rtti/init table updates
  2219. * rttisym for reusable global rtti/init info
  2220. * support published for interfaces
  2221. Revision 1.19 2001/08/26 13:36:50 florian
  2222. * some cg reorganisation
  2223. * some PPC updates
  2224. Revision 1.18 2001/08/19 09:39:28 peter
  2225. * local browser support fixed
  2226. Revision 1.16 2001/08/12 20:00:26 peter
  2227. * don't write fpuregable for varoptions
  2228. Revision 1.15 2001/08/06 21:40:48 peter
  2229. * funcret moved from tprocinfo to tprocdef
  2230. Revision 1.14 2001/07/01 20:16:17 peter
  2231. * alignmentinfo record added
  2232. * -Oa argument supports more alignment settings that can be specified
  2233. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  2234. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  2235. required alignment and the maximum usefull alignment. The final
  2236. alignment will be choosen per variable size dependent on these
  2237. settings
  2238. Revision 1.13 2001/05/08 21:06:32 florian
  2239. * some more support for widechars commited especially
  2240. regarding type casting and constants
  2241. Revision 1.12 2001/05/06 14:49:17 peter
  2242. * ppu object to class rewrite
  2243. * move ppu read and write stuff to fppu
  2244. Revision 1.11 2001/04/18 22:01:59 peter
  2245. * registration of targets and assemblers
  2246. Revision 1.10 2001/04/13 01:22:16 peter
  2247. * symtable change to classes
  2248. * range check generation and errors fixed, make cycle DEBUG=1 works
  2249. * memory leaks fixed
  2250. Revision 1.9 2001/04/02 21:20:35 peter
  2251. * resulttype rewrite
  2252. Revision 1.8 2001/03/11 22:58:51 peter
  2253. * getsym redesign, removed the globals srsym,srsymtable
  2254. Revision 1.7 2000/12/25 00:07:30 peter
  2255. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  2256. tlinkedlist objects)
  2257. Revision 1.6 2000/11/28 00:25:17 pierre
  2258. + use int64tostr function for integer consts
  2259. Revision 1.5 2000/11/13 14:44:35 jonas
  2260. * fixes so no more range errors with improved range checking code
  2261. Revision 1.4 2000/11/08 23:15:17 florian
  2262. * tprocdef.procsym must be set also when a tprocdef is loaded from a PPU
  2263. Revision 1.3 2000/11/06 23:13:53 peter
  2264. * uppercase manglednames
  2265. Revision 1.2 2000/11/01 23:04:38 peter
  2266. * tprocdef.fullprocname added for better casesensitve writing of
  2267. procedures
  2268. Revision 1.1 2000/10/31 22:02:52 peter
  2269. * symtable splitted, no real code changes
  2270. }