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