symsym.pas 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568
  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_really_const : boolean;
  214. constructor create(const n : string;p : tdef;really_const : boolean);
  215. constructor createtype(const n : string;const tt : ttype;really_const : 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;really_const : boolean);
  1497. begin
  1498. inherited create(n);
  1499. typ:=typedconstsym;
  1500. typedconsttype.setdef(p);
  1501. is_really_const:=really_const;
  1502. prefix:=stringdup(procprefix);
  1503. end;
  1504. constructor ttypedconstsym.createtype(const n : string;const tt : ttype;really_const : boolean);
  1505. begin
  1506. ttypedconstsym(self).create(n,nil,really_const);
  1507. typedconsttype:=tt;
  1508. end;
  1509. constructor ttypedconstsym.load(ppufile:tcompilerppufile);
  1510. begin
  1511. inherited loadsym(ppufile);
  1512. typ:=typedconstsym;
  1513. ppufile.gettype(typedconsttype);
  1514. prefix:=stringdup(ppufile.getstring);
  1515. is_really_const:=boolean(ppufile.getbyte);
  1516. end;
  1517. destructor ttypedconstsym.destroy;
  1518. begin
  1519. stringdispose(prefix);
  1520. inherited destroy;
  1521. end;
  1522. function ttypedconstsym.mangledname : string;
  1523. begin
  1524. mangledname:='TC_'+prefix^+'_'+name;
  1525. end;
  1526. function ttypedconstsym.getsize : longint;
  1527. begin
  1528. if assigned(typedconsttype.def) then
  1529. getsize:=typedconsttype.def.size
  1530. else
  1531. getsize:=0;
  1532. end;
  1533. procedure ttypedconstsym.deref;
  1534. begin
  1535. typedconsttype.resolve;
  1536. end;
  1537. procedure ttypedconstsym.write(ppufile:tcompilerppufile);
  1538. begin
  1539. inherited writesym(ppufile);
  1540. ppufile.puttype(typedconsttype);
  1541. ppufile.putstring(prefix^);
  1542. ppufile.putbyte(byte(is_really_const));
  1543. ppufile.writeentry(ibtypedconstsym);
  1544. end;
  1545. procedure ttypedconstsym.insert_in_data;
  1546. var
  1547. curconstsegment : taasmoutput;
  1548. address,l,varalign : longint;
  1549. storefilepos : tfileposinfo;
  1550. begin
  1551. storefilepos:=aktfilepos;
  1552. aktfilepos:=akttokenpos;
  1553. if is_really_const then
  1554. curconstsegment:=consts
  1555. else
  1556. curconstsegment:=datasegment;
  1557. l:=getsize;
  1558. varalign:=size_2_align(l);
  1559. varalign:=used_align(varalign,aktalignment.constalignmin,aktalignment.constalignmax);
  1560. address:=align(owner.datasize,varalign);
  1561. { insert cut for smartlinking or alignment }
  1562. if (cs_create_smart in aktmoduleswitches) then
  1563. curconstSegment.concat(Tai_cut.Create)
  1564. else if (address<>owner.datasize) then
  1565. curconstSegment.concat(Tai_align.create(varalign));
  1566. owner.datasize:=address+l;
  1567. {$ifdef GDB}
  1568. if cs_debuginfo in aktmoduleswitches then
  1569. concatstabto(curconstsegment);
  1570. {$endif GDB}
  1571. if (owner.symtabletype=globalsymtable) then
  1572. begin
  1573. if (owner.unitid=0) then
  1574. curconstSegment.concat(Tai_symbol.Createdataname_global(mangledname,getsize));
  1575. end
  1576. else
  1577. begin
  1578. if (cs_create_smart in aktmoduleswitches) or
  1579. DLLSource then
  1580. curconstSegment.concat(Tai_symbol.Createdataname_global(mangledname,getsize))
  1581. else
  1582. curconstSegment.concat(Tai_symbol.Createdataname(mangledname,getsize));
  1583. end;
  1584. aktfilepos:=storefilepos;
  1585. end;
  1586. {$ifdef GDB}
  1587. function ttypedconstsym.stabstring : pchar;
  1588. var
  1589. st : char;
  1590. begin
  1591. if (cs_gdb_gsym in aktglobalswitches) and (owner.symtabletype=globalsymtable) then
  1592. st := 'G'
  1593. else
  1594. st := 'S';
  1595. stabstring := strpnew('"'+name+':'+st+
  1596. tstoreddef(typedconsttype.def).numberstring+'",'+tostr(n_STSYM)+',0,'+
  1597. tostr(fileinfo.line)+','+mangledname);
  1598. end;
  1599. {$endif GDB}
  1600. {****************************************************************************
  1601. TCONSTSYM
  1602. ****************************************************************************}
  1603. constructor tconstsym.create_ord(const n : string;t : tconsttyp;v : TConstExprInt);
  1604. begin
  1605. inherited create(n);
  1606. typ:=constsym;
  1607. consttyp:=t;
  1608. valueord:=v;
  1609. valueordptr:=0;
  1610. valueptr:=nil;
  1611. ResStrIndex:=0;
  1612. consttype.reset;
  1613. len:=0;
  1614. end;
  1615. constructor tconstsym.create_ord_typed(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  1616. begin
  1617. inherited create(n);
  1618. typ:=constsym;
  1619. consttyp:=t;
  1620. valueord:=v;
  1621. valueordptr:=0;
  1622. valueptr:=nil;
  1623. ResStrIndex:=0;
  1624. consttype:=tt;
  1625. len:=0;
  1626. end;
  1627. constructor tconstsym.create_ordptr_typed(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  1628. begin
  1629. inherited create(n);
  1630. typ:=constsym;
  1631. consttyp:=t;
  1632. valueord:=0;
  1633. valueordptr:=v;
  1634. valueptr:=nil;
  1635. ResStrIndex:=0;
  1636. consttype:=tt;
  1637. len:=0;
  1638. end;
  1639. constructor tconstsym.create_ptr(const n : string;t : tconsttyp;v : pointer);
  1640. begin
  1641. inherited create(n);
  1642. typ:=constsym;
  1643. consttyp:=t;
  1644. valueord:=0;
  1645. valueordptr:=0;
  1646. valueptr:=v;
  1647. ResStrIndex:=0;
  1648. consttype.reset;
  1649. len:=0;
  1650. end;
  1651. constructor tconstsym.create_ptr_typed(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  1652. begin
  1653. inherited create(n);
  1654. typ:=constsym;
  1655. consttyp:=t;
  1656. valueord:=0;
  1657. valueordptr:=0;
  1658. valueptr:=v;
  1659. ResStrIndex:=0;
  1660. consttype:=tt;
  1661. len:=0;
  1662. end;
  1663. constructor tconstsym.create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  1664. begin
  1665. inherited create(n);
  1666. typ:=constsym;
  1667. consttyp:=t;
  1668. valueord:=0;
  1669. valueordptr:=0;
  1670. valueptr:=str;
  1671. consttype.reset;
  1672. len:=l;
  1673. if t=constresourcestring then
  1674. ResStrIndex:=ResourceStrings.Register(name,pchar(valueptr),len);
  1675. end;
  1676. constructor tconstsym.load(ppufile:tcompilerppufile);
  1677. var
  1678. pd : pbestreal;
  1679. ps : pnormalset;
  1680. pc : pchar;
  1681. l1,l2 : longint;
  1682. begin
  1683. inherited loadsym(ppufile);
  1684. typ:=constsym;
  1685. consttype.reset;
  1686. consttyp:=tconsttyp(ppufile.getbyte);
  1687. valueord:=0;
  1688. valueordptr:=0;
  1689. valueptr:=nil;
  1690. case consttyp of
  1691. constint:
  1692. if sizeof(tconstexprint)=8 then
  1693. begin
  1694. l1:=ppufile.getlongint;
  1695. l2:=ppufile.getlongint;
  1696. {$ifopt R+}
  1697. {$define Range_check_on}
  1698. {$endif opt R+}
  1699. {$R- needed here }
  1700. valueord:=qword(l1)+(int64(l2) shl 32);
  1701. {$ifdef Range_check_on}
  1702. {$R+}
  1703. {$undef Range_check_on}
  1704. {$endif Range_check_on}
  1705. end
  1706. else
  1707. valueord:=ppufile.getlongint;
  1708. constwchar,
  1709. constbool,
  1710. constchar :
  1711. valueord:=ppufile.getlongint;
  1712. constord :
  1713. begin
  1714. ppufile.gettype(consttype);
  1715. if sizeof(TConstExprInt)=8 then
  1716. begin
  1717. l1:=ppufile.getlongint;
  1718. l2:=ppufile.getlongint;
  1719. {$ifopt R+}
  1720. {$define Range_check_on}
  1721. {$endif opt R+}
  1722. {$R- needed here }
  1723. valueord:=qword(l1)+(int64(l2) shl 32);
  1724. {$ifdef Range_check_on}
  1725. {$R+}
  1726. {$undef Range_check_on}
  1727. {$endif Range_check_on}
  1728. end
  1729. else
  1730. valueord:=ppufile.getlongint;
  1731. end;
  1732. constpointer :
  1733. begin
  1734. ppufile.gettype(consttype);
  1735. if sizeof(TConstPtrUInt)=8 then
  1736. begin
  1737. l1:=ppufile.getlongint;
  1738. l2:=ppufile.getlongint;
  1739. {$ifopt R+}
  1740. {$define Range_check_on}
  1741. {$endif opt R+}
  1742. {$R- needed here }
  1743. valueordptr:=qword(l1)+(int64(l2) shl 32);
  1744. {$ifdef Range_check_on}
  1745. {$R+}
  1746. {$undef Range_check_on}
  1747. {$endif Range_check_on}
  1748. end
  1749. else
  1750. valueordptr:=ppufile.getlongint;
  1751. end;
  1752. conststring,
  1753. constresourcestring :
  1754. begin
  1755. len:=ppufile.getlongint;
  1756. getmem(pc,len+1);
  1757. ppufile.getdata(pc^,len);
  1758. if consttyp=constresourcestring then
  1759. ResStrIndex:=ppufile.getlongint;
  1760. valueptr:=pc;
  1761. end;
  1762. constreal :
  1763. begin
  1764. new(pd);
  1765. pd^:=ppufile.getreal;
  1766. valueptr:=pd;
  1767. end;
  1768. constset :
  1769. begin
  1770. ppufile.gettype(consttype);
  1771. new(ps);
  1772. ppufile.getnormalset(ps^);
  1773. valueptr:=ps;
  1774. end;
  1775. constnil : ;
  1776. else
  1777. Message1(unit_f_ppu_invalid_entry,tostr(ord(consttyp)));
  1778. end;
  1779. end;
  1780. destructor tconstsym.destroy;
  1781. begin
  1782. case consttyp of
  1783. conststring,
  1784. constresourcestring :
  1785. freemem(pchar(valueptr),len+1);
  1786. constreal :
  1787. dispose(pbestreal(valueptr));
  1788. constset :
  1789. dispose(pnormalset(valueptr));
  1790. end;
  1791. inherited destroy;
  1792. end;
  1793. function tconstsym.mangledname : string;
  1794. begin
  1795. mangledname:=name;
  1796. end;
  1797. procedure tconstsym.deref;
  1798. begin
  1799. if consttyp in [constord,constpointer,constset] then
  1800. consttype.resolve;
  1801. end;
  1802. procedure tconstsym.write(ppufile:tcompilerppufile);
  1803. begin
  1804. inherited writesym(ppufile);
  1805. ppufile.putbyte(byte(consttyp));
  1806. case consttyp of
  1807. constnil : ;
  1808. constint:
  1809. begin
  1810. if sizeof(TConstExprInt)=8 then
  1811. begin
  1812. ppufile.putlongint(longint(lo(valueord)));
  1813. ppufile.putlongint(longint(hi(valueord)));
  1814. end
  1815. else
  1816. ppufile.putlongint(valueord);
  1817. end;
  1818. constbool,
  1819. constchar :
  1820. ppufile.putlongint(valueord);
  1821. constord :
  1822. begin
  1823. ppufile.puttype(consttype);
  1824. if sizeof(TConstExprInt)=8 then
  1825. begin
  1826. ppufile.putlongint(longint(lo(valueord)));
  1827. ppufile.putlongint(longint(hi(valueord)));
  1828. end
  1829. else
  1830. ppufile.putlongint(valueord);
  1831. end;
  1832. constpointer :
  1833. begin
  1834. ppufile.puttype(consttype);
  1835. if sizeof(TConstPtrUInt)=8 then
  1836. begin
  1837. ppufile.putlongint(longint(lo(valueordptr)));
  1838. ppufile.putlongint(longint(hi(valueordptr)));
  1839. end
  1840. else
  1841. ppufile.putlongint(valueordptr);
  1842. end;
  1843. conststring,
  1844. constresourcestring :
  1845. begin
  1846. ppufile.putlongint(len);
  1847. ppufile.putdata(pchar(valueptr)^,len);
  1848. if consttyp=constresourcestring then
  1849. ppufile.putlongint(ResStrIndex);
  1850. end;
  1851. constreal :
  1852. ppufile.putreal(pbestreal(valueptr)^);
  1853. constset :
  1854. begin
  1855. ppufile.puttype(consttype);
  1856. ppufile.putnormalset(valueptr^);
  1857. end;
  1858. else
  1859. internalerror(13);
  1860. end;
  1861. ppufile.writeentry(ibconstsym);
  1862. end;
  1863. {$ifdef GDB}
  1864. function tconstsym.stabstring : pchar;
  1865. var st : string;
  1866. begin
  1867. {even GDB v4.16 only now 'i' 'r' and 'e' !!!}
  1868. case consttyp of
  1869. conststring : begin
  1870. st := 's'''+strpas(pchar(valueptr))+'''';
  1871. end;
  1872. constbool,
  1873. constint,
  1874. constord,
  1875. constchar : st := 'i'+int64tostr(valueord);
  1876. constpointer :
  1877. st := 'i'+int64tostr(valueordptr);
  1878. constreal : begin
  1879. system.str(pbestreal(valueptr)^,st);
  1880. st := 'r'+st;
  1881. end;
  1882. { if we don't know just put zero !! }
  1883. else st:='i0';
  1884. {***SETCONST}
  1885. {constset:;} {*** I don't know what to do with a set.}
  1886. { sets are not recognized by GDB}
  1887. {***}
  1888. end;
  1889. stabstring := strpnew('"'+name+':c='+st+'",'+tostr(N_function)+',0,'+
  1890. tostr(fileinfo.line)+',0');
  1891. end;
  1892. procedure tconstsym.concatstabto(asmlist : taasmoutput);
  1893. begin
  1894. if consttyp <> conststring then
  1895. inherited concatstabto(asmlist);
  1896. end;
  1897. {$endif GDB}
  1898. {****************************************************************************
  1899. TENUMSYM
  1900. ****************************************************************************}
  1901. constructor tenumsym.create(const n : string;def : tenumdef;v : longint);
  1902. begin
  1903. inherited create(n);
  1904. typ:=enumsym;
  1905. definition:=def;
  1906. value:=v;
  1907. if def.min>v then
  1908. def.setmin(v);
  1909. if def.max<v then
  1910. def.setmax(v);
  1911. order;
  1912. end;
  1913. constructor tenumsym.load(ppufile:tcompilerppufile);
  1914. begin
  1915. inherited loadsym(ppufile);
  1916. typ:=enumsym;
  1917. definition:=tenumdef(ppufile.getderef);
  1918. value:=ppufile.getlongint;
  1919. nextenum := Nil;
  1920. end;
  1921. procedure tenumsym.deref;
  1922. begin
  1923. resolvedef(tdef(definition));
  1924. order;
  1925. end;
  1926. procedure tenumsym.order;
  1927. var
  1928. sym : tenumsym;
  1929. begin
  1930. sym := tenumsym(definition.firstenum);
  1931. if sym = nil then
  1932. begin
  1933. definition.firstenum := self;
  1934. nextenum := nil;
  1935. exit;
  1936. end;
  1937. { reorder the symbols in increasing value }
  1938. if value < sym.value then
  1939. begin
  1940. nextenum := sym;
  1941. definition.firstenum := self;
  1942. end
  1943. else
  1944. begin
  1945. while (sym.value <= value) and assigned(sym.nextenum) do
  1946. sym := sym.nextenum;
  1947. nextenum := sym.nextenum;
  1948. sym.nextenum := self;
  1949. end;
  1950. end;
  1951. procedure tenumsym.write(ppufile:tcompilerppufile);
  1952. begin
  1953. inherited writesym(ppufile);
  1954. ppufile.putderef(definition);
  1955. ppufile.putlongint(value);
  1956. ppufile.writeentry(ibenumsym);
  1957. end;
  1958. {$ifdef GDB}
  1959. procedure tenumsym.concatstabto(asmlist : taasmoutput);
  1960. begin
  1961. {enum elements have no stab !}
  1962. end;
  1963. {$EndIf GDB}
  1964. {****************************************************************************
  1965. TTYPESYM
  1966. ****************************************************************************}
  1967. constructor ttypesym.create(const n : string;const tt : ttype);
  1968. begin
  1969. inherited create(n);
  1970. typ:=typesym;
  1971. restype:=tt;
  1972. {$ifdef GDB}
  1973. isusedinstab := false;
  1974. {$endif GDB}
  1975. { register the typesym for the definition }
  1976. if assigned(restype.def) and
  1977. (restype.def.deftype<>errordef) and
  1978. not(assigned(restype.def.typesym)) then
  1979. restype.def.typesym:=self;
  1980. end;
  1981. constructor ttypesym.load(ppufile:tcompilerppufile);
  1982. begin
  1983. inherited loadsym(ppufile);
  1984. typ:=typesym;
  1985. {$ifdef GDB}
  1986. isusedinstab := false;
  1987. {$endif GDB}
  1988. ppufile.gettype(restype);
  1989. end;
  1990. function ttypesym.gettypedef:tdef;
  1991. begin
  1992. gettypedef:=restype.def;
  1993. end;
  1994. procedure ttypesym.deref;
  1995. begin
  1996. restype.resolve;
  1997. end;
  1998. procedure ttypesym.write(ppufile:tcompilerppufile);
  1999. begin
  2000. inherited writesym(ppufile);
  2001. ppufile.puttype(restype);
  2002. ppufile.writeentry(ibtypesym);
  2003. end;
  2004. procedure ttypesym.load_references(ppufile:tcompilerppufile;locals:boolean);
  2005. begin
  2006. inherited load_references(ppufile,locals);
  2007. if (restype.def.deftype=recorddef) then
  2008. tstoredsymtable(trecorddef(restype.def).symtable).load_references(ppufile,locals);
  2009. if (restype.def.deftype=objectdef) then
  2010. tstoredsymtable(tobjectdef(restype.def).symtable).load_references(ppufile,locals);
  2011. end;
  2012. function ttypesym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  2013. begin
  2014. if not inherited write_references(ppufile,locals) then
  2015. begin
  2016. { write address of this symbol if record or object
  2017. even if no real refs are there
  2018. because we need it for the symtable }
  2019. if (restype.def.deftype in [recorddef,objectdef]) then
  2020. begin
  2021. ppufile.putderef(self);
  2022. ppufile.writeentry(ibsymref);
  2023. end;
  2024. end;
  2025. write_references:=true;
  2026. if (restype.def.deftype=recorddef) then
  2027. tstoredsymtable(trecorddef(restype.def).symtable).write_references(ppufile,locals);
  2028. if (restype.def.deftype=objectdef) then
  2029. tstoredsymtable(tobjectdef(restype.def).symtable).write_references(ppufile,locals);
  2030. end;
  2031. {$ifdef GDB}
  2032. function ttypesym.stabstring : pchar;
  2033. var
  2034. stabchar : string[2];
  2035. short : string;
  2036. begin
  2037. if restype.def.deftype in tagtypes then
  2038. stabchar := 'Tt'
  2039. else
  2040. stabchar := 't';
  2041. short := '"'+name+':'+stabchar+tstoreddef(restype.def).numberstring
  2042. +'",'+tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',0';
  2043. stabstring := strpnew(short);
  2044. end;
  2045. procedure ttypesym.concatstabto(asmlist : taasmoutput);
  2046. begin
  2047. {not stabs for forward defs }
  2048. if assigned(restype.def) then
  2049. if (restype.def.typesym = self) then
  2050. tstoreddef(restype.def).concatstabto(asmlist)
  2051. else
  2052. inherited concatstabto(asmlist);
  2053. end;
  2054. {$endif GDB}
  2055. {****************************************************************************
  2056. TSYSSYM
  2057. ****************************************************************************}
  2058. constructor tsyssym.create(const n : string;l : longint);
  2059. begin
  2060. inherited create(n);
  2061. typ:=syssym;
  2062. number:=l;
  2063. end;
  2064. constructor tsyssym.load(ppufile:tcompilerppufile);
  2065. begin
  2066. inherited loadsym(ppufile);
  2067. typ:=syssym;
  2068. number:=ppufile.getlongint;
  2069. end;
  2070. destructor tsyssym.destroy;
  2071. begin
  2072. inherited destroy;
  2073. end;
  2074. procedure tsyssym.write(ppufile:tcompilerppufile);
  2075. begin
  2076. inherited writesym(ppufile);
  2077. ppufile.putlongint(number);
  2078. ppufile.writeentry(ibsyssym);
  2079. end;
  2080. {$ifdef GDB}
  2081. procedure tsyssym.concatstabto(asmlist : taasmoutput);
  2082. begin
  2083. end;
  2084. {$endif GDB}
  2085. {****************************************************************************
  2086. TRTTISYM
  2087. ****************************************************************************}
  2088. constructor trttisym.create(const n:string;rt:trttitype);
  2089. const
  2090. prefix : array[trttitype] of string[5]=('$rtti','$init');
  2091. begin
  2092. inherited create(prefix[rt]+n);
  2093. typ:=rttisym;
  2094. lab:=nil;
  2095. rttityp:=rt;
  2096. end;
  2097. constructor trttisym.load(ppufile:tcompilerppufile);
  2098. begin
  2099. inherited loadsym(ppufile);
  2100. typ:=rttisym;
  2101. lab:=nil;
  2102. rttityp:=trttitype(ppufile.getbyte);
  2103. end;
  2104. procedure trttisym.write(ppufile:tcompilerppufile);
  2105. begin
  2106. inherited writesym(ppufile);
  2107. ppufile.putbyte(byte(rttityp));
  2108. ppufile.writeentry(ibrttisym);
  2109. end;
  2110. function trttisym.mangledname : string;
  2111. const
  2112. prefix : array[trttitype] of string[5]=('RTTI_','INIT_');
  2113. var
  2114. s : string;
  2115. p : tsymtable;
  2116. begin
  2117. s:='';
  2118. p:=owner;
  2119. while assigned(p) and (p.symtabletype=localsymtable) do
  2120. begin
  2121. s:=s+'_'+p.defowner.name;
  2122. p:=p.defowner.owner;
  2123. end;
  2124. if not(p.symtabletype in [globalsymtable,staticsymtable]) then
  2125. internalerror(200108265);
  2126. mangledname:=prefix[rttityp]+p.name^+s+'$_'+Copy(name,5,255);
  2127. end;
  2128. function trttisym.get_label:tasmsymbol;
  2129. begin
  2130. { the label is always a global label }
  2131. if not assigned(lab) then
  2132. lab:=newasmsymboltype(mangledname,AB_GLOBAL,AT_DATA);
  2133. get_label:=lab;
  2134. end;
  2135. { persistent rtti generation }
  2136. procedure generate_rtti(p:tsym);
  2137. var
  2138. rsym : trttisym;
  2139. def : tstoreddef;
  2140. begin
  2141. { rtti can only be generated for classes that are always typesyms }
  2142. if not(p.typ=typesym) then
  2143. internalerror(200108261);
  2144. def:=tstoreddef(ttypesym(p).restype.def);
  2145. { only create rtti once for each definition }
  2146. if not(df_has_rttitable in def.defoptions) then
  2147. begin
  2148. { definition should be in the same symtable as the symbol }
  2149. if p.owner<>def.owner then
  2150. internalerror(200108262);
  2151. { create rttisym }
  2152. rsym:=trttisym.create(p.name,fullrtti);
  2153. p.owner.insert(rsym);
  2154. { register rttisym in definition }
  2155. include(def.defoptions,df_has_rttitable);
  2156. def.rttitablesym:=rsym;
  2157. { write rtti data }
  2158. def.write_child_rtti_data(fullrtti);
  2159. if (cs_create_smart in aktmoduleswitches) then
  2160. rttiList.concat(Tai_cut.Create);
  2161. rttiList.concat(Tai_symbol.Create(rsym.get_label,0));
  2162. def.write_rtti_data(fullrtti);
  2163. rttiList.concat(Tai_symbol_end.Create(rsym.get_label));
  2164. end;
  2165. end;
  2166. { persistent init table generation }
  2167. procedure generate_inittable(p:tsym);
  2168. var
  2169. rsym : trttisym;
  2170. def : tstoreddef;
  2171. begin
  2172. { anonymous types are also allowed for records that can be varsym }
  2173. case p.typ of
  2174. typesym :
  2175. def:=tstoreddef(ttypesym(p).restype.def);
  2176. varsym :
  2177. def:=tstoreddef(tvarsym(p).vartype.def);
  2178. else
  2179. internalerror(200108263);
  2180. end;
  2181. { only create inittable once for each definition }
  2182. if not(df_has_inittable in def.defoptions) then
  2183. begin
  2184. { definition should be in the same symtable as the symbol }
  2185. if p.owner<>def.owner then
  2186. internalerror(200108264);
  2187. { create rttisym }
  2188. rsym:=trttisym.create(p.name,initrtti);
  2189. p.owner.insert(rsym);
  2190. { register rttisym in definition }
  2191. include(def.defoptions,df_has_inittable);
  2192. def.inittablesym:=rsym;
  2193. { write inittable data }
  2194. def.write_child_rtti_data(initrtti);
  2195. if (cs_create_smart in aktmoduleswitches) then
  2196. rttiList.concat(Tai_cut.Create);
  2197. rttiList.concat(Tai_symbol.Create(rsym.get_label,0));
  2198. def.write_rtti_data(initrtti);
  2199. rttiList.concat(Tai_symbol_end.Create(rsym.get_label));
  2200. end;
  2201. end;
  2202. end.
  2203. {
  2204. $Log$
  2205. Revision 1.22 2001-09-19 11:04:42 michael
  2206. * Smartlinking with interfaces fixed
  2207. * Better smartlinking for rtti and init tables
  2208. Revision 1.21 2001/09/02 21:18:29 peter
  2209. * split constsym.value in valueord,valueordptr,valueptr. The valueordptr
  2210. is used for holding target platform pointer values. As those can be
  2211. bigger than the source platform.
  2212. Revision 1.20 2001/08/30 20:13:54 peter
  2213. * rtti/init table updates
  2214. * rttisym for reusable global rtti/init info
  2215. * support published for interfaces
  2216. Revision 1.19 2001/08/26 13:36:50 florian
  2217. * some cg reorganisation
  2218. * some PPC updates
  2219. Revision 1.18 2001/08/19 09:39:28 peter
  2220. * local browser support fixed
  2221. Revision 1.16 2001/08/12 20:00:26 peter
  2222. * don't write fpuregable for varoptions
  2223. Revision 1.15 2001/08/06 21:40:48 peter
  2224. * funcret moved from tprocinfo to tprocdef
  2225. Revision 1.14 2001/07/01 20:16:17 peter
  2226. * alignmentinfo record added
  2227. * -Oa argument supports more alignment settings that can be specified
  2228. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  2229. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  2230. required alignment and the maximum usefull alignment. The final
  2231. alignment will be choosen per variable size dependent on these
  2232. settings
  2233. Revision 1.13 2001/05/08 21:06:32 florian
  2234. * some more support for widechars commited especially
  2235. regarding type casting and constants
  2236. Revision 1.12 2001/05/06 14:49:17 peter
  2237. * ppu object to class rewrite
  2238. * move ppu read and write stuff to fppu
  2239. Revision 1.11 2001/04/18 22:01:59 peter
  2240. * registration of targets and assemblers
  2241. Revision 1.10 2001/04/13 01:22:16 peter
  2242. * symtable change to classes
  2243. * range check generation and errors fixed, make cycle DEBUG=1 works
  2244. * memory leaks fixed
  2245. Revision 1.9 2001/04/02 21:20:35 peter
  2246. * resulttype rewrite
  2247. Revision 1.8 2001/03/11 22:58:51 peter
  2248. * getsym redesign, removed the globals srsym,srsymtable
  2249. Revision 1.7 2000/12/25 00:07:30 peter
  2250. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  2251. tlinkedlist objects)
  2252. Revision 1.6 2000/11/28 00:25:17 pierre
  2253. + use int64tostr function for integer consts
  2254. Revision 1.5 2000/11/13 14:44:35 jonas
  2255. * fixes so no more range errors with improved range checking code
  2256. Revision 1.4 2000/11/08 23:15:17 florian
  2257. * tprocdef.procsym must be set also when a tprocdef is loaded from a PPU
  2258. Revision 1.3 2000/11/06 23:13:53 peter
  2259. * uppercase manglednames
  2260. Revision 1.2 2000/11/01 23:04:38 peter
  2261. * tprocdef.fullprocname added for better casesensitve writing of
  2262. procedures
  2263. Revision 1.1 2000/10/31 22:02:52 peter
  2264. * symtable splitted, no real code changes
  2265. }