symsym.pas 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 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 fpcdefs.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,
  24. { target }
  25. globtype,globals,
  26. { symtable }
  27. symconst,symbase,symtype,symdef,defcmp,
  28. { ppu }
  29. ppu,
  30. cclasses,symnot,
  31. { aasm }
  32. aasmbase,aasmtai,
  33. cpuinfo,cpubase,cgbase,cgutils,parabase
  34. ;
  35. type
  36. { this class is the base for all symbol objects }
  37. tstoredsym = class(tsym)
  38. public
  39. constructor create(const n : string);
  40. constructor ppuload(ppufile:tcompilerppufile);
  41. destructor destroy;override;
  42. procedure ppuwrite(ppufile:tcompilerppufile);virtual;
  43. {$ifdef GDB}
  44. function get_var_value(const s:string):string;
  45. function stabstr_evaluate(const s:string;vars:array of string):Pchar;
  46. procedure concatstabto(asmlist : taasmoutput);
  47. {$endif GDB}
  48. function mangledname : string; virtual;
  49. end;
  50. tlabelsym = class(tstoredsym)
  51. lab : tasmlabel;
  52. used,
  53. defined : boolean;
  54. code : pointer; { should be tnode }
  55. constructor create(const n : string; l : tasmlabel);
  56. constructor ppuload(ppufile:tcompilerppufile);
  57. function mangledname:string;override;
  58. procedure ppuwrite(ppufile:tcompilerppufile);override;
  59. {$ifdef GDB}
  60. function stabstring : pchar;override;
  61. {$endif GDB}
  62. end;
  63. tunitsym = class(Tstoredsym)
  64. unitsymtable : tsymtable;
  65. constructor create(const n : string;ref : tsymtable);
  66. constructor ppuload(ppufile:tcompilerppufile);
  67. destructor destroy;override;
  68. procedure ppuwrite(ppufile:tcompilerppufile);override;
  69. end;
  70. terrorsym = class(Tsym)
  71. constructor create;
  72. end;
  73. Tprocdefcallback = procedure(p:Tprocdef;arg:pointer);
  74. tprocsym = class(tstoredsym)
  75. protected
  76. pdlistfirst,
  77. pdlistlast : pprocdeflist; { linked list of overloaded procdefs }
  78. function getprocdef(nr:cardinal):Tprocdef;
  79. public
  80. procdef_count : byte;
  81. {$ifdef GDB}
  82. is_global : boolean;
  83. {$endif GDB}
  84. overloadchecked : boolean;
  85. property procdef[nr:cardinal]:Tprocdef read getprocdef;
  86. constructor create(const n : string);
  87. constructor ppuload(ppufile:tcompilerppufile);
  88. destructor destroy;override;
  89. { writes all declarations except the specified one }
  90. procedure write_parameter_lists(skipdef:tprocdef);
  91. { tests, if all procedures definitions are defined and not }
  92. { only forward }
  93. procedure check_forward;
  94. procedure unchain_overload;
  95. procedure ppuwrite(ppufile:tcompilerppufile);override;
  96. procedure buildderef;override;
  97. procedure deref;override;
  98. procedure addprocdef(p:tprocdef);
  99. procedure addprocdef_deref(const d:tderef);
  100. procedure add_para_match_to(Aprocsym:Tprocsym;cpoptions:tcompare_paras_options);
  101. procedure concat_procdefs_to(s:Tprocsym);
  102. procedure foreach_procdef_static(proc2call:Tprocdefcallback;arg:pointer);
  103. function first_procdef:Tprocdef;
  104. function last_procdef:Tprocdef;
  105. function search_procdef_nopara_boolret:Tprocdef;
  106. function search_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  107. function search_procdef_bypara(para:tlist;retdef:tdef;cpoptions:tcompare_paras_options):Tprocdef;
  108. function search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  109. function search_procdef_assignment_operator(fromdef,todef:tdef):Tprocdef;
  110. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  111. function is_visible_for_object(currobjdef:tdef):boolean;override;
  112. {$ifdef GDB}
  113. function stabstring : pchar;override;
  114. {$endif GDB}
  115. end;
  116. ttypesym = class(Tstoredsym)
  117. restype : ttype;
  118. constructor create(const n : string;const tt : ttype);
  119. constructor ppuload(ppufile:tcompilerppufile);
  120. procedure ppuwrite(ppufile:tcompilerppufile);override;
  121. procedure buildderef;override;
  122. procedure deref;override;
  123. function gettypedef:tdef;override;
  124. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  125. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  126. {$ifdef GDB}
  127. function stabstring : pchar;override;
  128. {$endif GDB}
  129. end;
  130. tabstractvarsym = class(tstoredsym)
  131. varoptions : tvaroptions;
  132. varspez : tvarspez; { sets the type of access }
  133. varregable : tvarregable;
  134. varstate : tvarstate;
  135. notifications : Tlinkedlist;
  136. constructor create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
  137. constructor ppuload(ppufile:tcompilerppufile);
  138. destructor destroy;override;
  139. procedure ppuwrite(ppufile:tcompilerppufile);override;
  140. procedure buildderef;override;
  141. procedure deref;override;
  142. function getsize : longint;
  143. function is_regvar:boolean;
  144. procedure trigger_notifications(what:Tnotification_flag);
  145. function register_notification(flags:Tnotification_flags;
  146. callback:Tnotification_callback):cardinal;
  147. procedure unregister_notification(id:cardinal);
  148. private
  149. procedure setvartype(const newtype: ttype);
  150. _vartype : ttype;
  151. public
  152. property vartype: ttype read _vartype write setvartype;
  153. end;
  154. tfieldvarsym = class(tabstractvarsym)
  155. fieldoffset : aint; { offset in record/object }
  156. constructor create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
  157. constructor ppuload(ppufile:tcompilerppufile);
  158. procedure ppuwrite(ppufile:tcompilerppufile);override;
  159. {$ifdef GDB}
  160. function stabstring : pchar;override;
  161. {$endif GDB}
  162. end;
  163. tabstractnormalvarsym = class(tabstractvarsym)
  164. defaultconstsym : tsym;
  165. defaultconstsymderef : tderef;
  166. localloc : TLocation; { register/reference for local var }
  167. constructor create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
  168. constructor ppuload(ppufile:tcompilerppufile);
  169. procedure ppuwrite(ppufile:tcompilerppufile);override;
  170. procedure buildderef;override;
  171. procedure deref;override;
  172. end;
  173. tlocalvarsym = class(tabstractnormalvarsym)
  174. constructor create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
  175. constructor ppuload(ppufile:tcompilerppufile);
  176. procedure ppuwrite(ppufile:tcompilerppufile);override;
  177. {$ifdef GDB}
  178. function stabstring : pchar;override;
  179. {$endif GDB}
  180. end;
  181. tparavarsym = class(tabstractnormalvarsym)
  182. paraloc : array[tcallercallee] of TCGPara;
  183. paranr : word; { position of this parameter }
  184. {$ifdef EXTDEBUG}
  185. eqval : tequaltype;
  186. {$endif EXTDEBUG}
  187. constructor create(const n : string;nr:word;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
  188. constructor ppuload(ppufile:tcompilerppufile);
  189. destructor destroy;override;
  190. procedure ppuwrite(ppufile:tcompilerppufile);override;
  191. {$ifdef GDB}
  192. function stabstring : pchar;override;
  193. {$endif GDB}
  194. end;
  195. tglobalvarsym = class(tabstractnormalvarsym)
  196. private
  197. _mangledname : pstring;
  198. public
  199. constructor create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
  200. constructor create_dll(const n : string;vsp:tvarspez;const tt : ttype);
  201. constructor create_C(const n,mangled : string;vsp:tvarspez;const tt : ttype);
  202. constructor ppuload(ppufile:tcompilerppufile);
  203. destructor destroy;override;
  204. procedure ppuwrite(ppufile:tcompilerppufile);override;
  205. function mangledname:string;override;
  206. procedure set_mangledname(const s:string);
  207. {$ifdef GDB}
  208. function stabstring : pchar;override;
  209. {$endif GDB}
  210. end;
  211. tabsolutevarsym = class(tabstractvarsym)
  212. public
  213. abstyp : absolutetyp;
  214. {$ifdef i386}
  215. absseg : boolean;
  216. {$endif i386}
  217. asmname : pstring;
  218. addroffset : aint;
  219. ref : tsymlist;
  220. constructor create(const n : string;const tt : ttype);
  221. constructor create_ref(const n : string;const tt : ttype;_ref:tsymlist);
  222. destructor destroy;override;
  223. constructor ppuload(ppufile:tcompilerppufile);
  224. procedure buildderef;override;
  225. procedure deref;override;
  226. function mangledname : string;override;
  227. procedure ppuwrite(ppufile:tcompilerppufile);override;
  228. {$ifdef gdb}
  229. function stabstring:Pchar;override;
  230. {$endif gdb}
  231. end;
  232. tpropertysym = class(Tstoredsym)
  233. propoptions : tpropertyoptions;
  234. propoverriden : tpropertysym;
  235. propoverridenderef : tderef;
  236. proptype,
  237. indextype : ttype;
  238. index,
  239. default : longint;
  240. readaccess,
  241. writeaccess,
  242. storedaccess : tsymlist;
  243. constructor create(const n : string);
  244. destructor destroy;override;
  245. constructor ppuload(ppufile:tcompilerppufile);
  246. function getsize : longint;
  247. procedure ppuwrite(ppufile:tcompilerppufile);override;
  248. function gettypedef:tdef;override;
  249. procedure buildderef;override;
  250. procedure deref;override;
  251. procedure dooverride(overriden:tpropertysym);
  252. end;
  253. ttypedconstsym = class(tstoredsym)
  254. private
  255. _mangledname : pstring;
  256. public
  257. typedconsttype : ttype;
  258. is_writable : boolean;
  259. constructor create(const n : string;p : tdef;writable : boolean);
  260. constructor createtype(const n : string;const tt : ttype;writable : boolean);
  261. constructor ppuload(ppufile:tcompilerppufile);
  262. destructor destroy;override;
  263. function mangledname : string;override;
  264. procedure ppuwrite(ppufile:tcompilerppufile);override;
  265. procedure buildderef;override;
  266. procedure deref;override;
  267. function getsize:longint;
  268. {$ifdef GDB}
  269. function stabstring : pchar;override;
  270. {$endif GDB}
  271. end;
  272. tconstvalue = record
  273. case integer of
  274. 0: (valueord : tconstexprint);
  275. 1: (valueordptr : tconstptruint);
  276. 2: (valueptr : pointer; len : longint);
  277. end;
  278. tconstsym = class(tstoredsym)
  279. consttype : ttype;
  280. consttyp : tconsttyp;
  281. value : tconstvalue;
  282. resstrindex : longint; { needed for resource strings }
  283. constructor create_ord(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  284. constructor create_ordptr(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  285. constructor create_ptr(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  286. constructor create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  287. constructor ppuload(ppufile:tcompilerppufile);
  288. destructor destroy;override;
  289. procedure buildderef;override;
  290. procedure deref;override;
  291. procedure ppuwrite(ppufile:tcompilerppufile);override;
  292. {$ifdef GDB}
  293. function stabstring : pchar;override;
  294. {$endif GDB}
  295. end;
  296. tenumsym = class(Tstoredsym)
  297. value : longint;
  298. definition : tenumdef;
  299. definitionderef : tderef;
  300. nextenum : tenumsym;
  301. constructor create(const n : string;def : tenumdef;v : longint);
  302. constructor ppuload(ppufile:tcompilerppufile);
  303. procedure ppuwrite(ppufile:tcompilerppufile);override;
  304. procedure buildderef;override;
  305. procedure deref;override;
  306. procedure order;
  307. end;
  308. tsyssym = class(Tstoredsym)
  309. number : longint;
  310. constructor create(const n : string;l : longint);
  311. constructor ppuload(ppufile:tcompilerppufile);
  312. destructor destroy;override;
  313. procedure ppuwrite(ppufile:tcompilerppufile);override;
  314. end;
  315. { compiler generated symbol to point to rtti and init/finalize tables }
  316. trttisym = class(tstoredsym)
  317. private
  318. _mangledname : pstring;
  319. public
  320. lab : tasmsymbol;
  321. rttityp : trttitype;
  322. constructor create(const n:string;rt:trttitype);
  323. constructor ppuload(ppufile:tcompilerppufile);
  324. destructor destroy;override;
  325. procedure ppuwrite(ppufile:tcompilerppufile);override;
  326. function mangledname:string;override;
  327. function get_label:tasmsymbol;
  328. end;
  329. var
  330. generrorsym : tsym;
  331. implementation
  332. uses
  333. { global }
  334. verbose,
  335. { target }
  336. systems,
  337. { symtable }
  338. defutil,symtable,
  339. { tree }
  340. node,
  341. { aasm }
  342. {$ifdef gdb}
  343. gdb,
  344. {$endif gdb}
  345. { codegen }
  346. paramgr,cresstr,
  347. procinfo
  348. ;
  349. {****************************************************************************
  350. Helpers
  351. ****************************************************************************}
  352. {****************************************************************************
  353. TSYM (base for all symtypes)
  354. ****************************************************************************}
  355. constructor tstoredsym.create(const n : string);
  356. begin
  357. inherited create(n);
  358. end;
  359. constructor tstoredsym.ppuload(ppufile:tcompilerppufile);
  360. var
  361. nr : word;
  362. s : string;
  363. begin
  364. nr:=ppufile.getword;
  365. s:=ppufile.getstring;
  366. if s[1]='$' then
  367. inherited createname(copy(s,2,255))
  368. else
  369. inherited createname(upper(s));
  370. _realname:=stringdup(s);
  371. typ:=abstractsym;
  372. { force the correct indexnr. must be after create! }
  373. indexnr:=nr;
  374. ppufile.getposinfo(fileinfo);
  375. ppufile.getsmallset(symoptions);
  376. lastref:=nil;
  377. defref:=nil;
  378. refs:=0;
  379. lastwritten:=nil;
  380. refcount:=0;
  381. {$ifdef GDB}
  382. isstabwritten := false;
  383. {$endif GDB}
  384. end;
  385. procedure tstoredsym.ppuwrite(ppufile:tcompilerppufile);
  386. begin
  387. ppufile.putword(indexnr);
  388. ppufile.putstring(_realname^);
  389. ppufile.putposinfo(fileinfo);
  390. ppufile.putsmallset(symoptions);
  391. end;
  392. destructor tstoredsym.destroy;
  393. begin
  394. if assigned(defref) then
  395. begin
  396. {$ifdef MEMDEBUG}
  397. membrowser.start;
  398. {$endif MEMDEBUG}
  399. defref.freechain;
  400. defref.free;
  401. {$ifdef MEMDEBUG}
  402. membrowser.stop;
  403. {$endif MEMDEBUG}
  404. end;
  405. inherited destroy;
  406. end;
  407. {$ifdef GDB}
  408. function Tstoredsym.get_var_value(const s:string):string;
  409. begin
  410. if s='mangledname' then
  411. get_var_value:=mangledname
  412. else
  413. get_var_value:=inherited get_var_value(s);
  414. end;
  415. function Tstoredsym.stabstr_evaluate(const s:string;vars:array of string):Pchar;
  416. begin
  417. stabstr_evaluate:=string_evaluate(s,@get_var_value,vars);
  418. end;
  419. procedure tstoredsym.concatstabto(asmlist : taasmoutput);
  420. var
  421. stabstr : Pchar;
  422. begin
  423. stabstr:=stabstring;
  424. if stabstr<>nil then
  425. asmlist.concat(Tai_stabs.create(stabstr));
  426. end;
  427. {$endif GDB}
  428. function tstoredsym.mangledname : string;
  429. begin
  430. internalerror(200204171);
  431. end;
  432. {****************************************************************************
  433. TLABELSYM
  434. ****************************************************************************}
  435. constructor tlabelsym.create(const n : string; l : tasmlabel);
  436. begin
  437. inherited create(n);
  438. typ:=labelsym;
  439. lab:=l;
  440. used:=false;
  441. defined:=false;
  442. code:=nil;
  443. end;
  444. constructor tlabelsym.ppuload(ppufile:tcompilerppufile);
  445. begin
  446. inherited ppuload(ppufile);
  447. typ:=labelsym;
  448. { this is all dummy
  449. it is only used for local browsing }
  450. lab:=nil;
  451. code:=nil;
  452. used:=false;
  453. defined:=true;
  454. end;
  455. function tlabelsym.mangledname:string;
  456. begin
  457. result:=lab.name;
  458. end;
  459. procedure tlabelsym.ppuwrite(ppufile:tcompilerppufile);
  460. begin
  461. if owner.symtabletype=globalsymtable then
  462. Message(sym_e_ill_label_decl)
  463. else
  464. begin
  465. inherited ppuwrite(ppufile);
  466. ppufile.writeentry(iblabelsym);
  467. end;
  468. end;
  469. {$ifdef GDB}
  470. function Tlabelsym.stabstring : pchar;
  471. begin
  472. stabstring:=stabstr_evaluate('"${name}",${N_LSYM},0,${line},0',[]);
  473. end;
  474. {$endif GDB}
  475. {****************************************************************************
  476. TUNITSYM
  477. ****************************************************************************}
  478. constructor tunitsym.create(const n : string;ref : tsymtable);
  479. var
  480. old_make_ref : boolean;
  481. begin
  482. old_make_ref:=make_ref;
  483. make_ref:=false;
  484. inherited create(n);
  485. make_ref:=old_make_ref;
  486. typ:=unitsym;
  487. unitsymtable:=ref;
  488. end;
  489. constructor tunitsym.ppuload(ppufile:tcompilerppufile);
  490. begin
  491. inherited ppuload(ppufile);
  492. typ:=unitsym;
  493. unitsymtable:=nil;
  494. end;
  495. destructor tunitsym.destroy;
  496. begin
  497. inherited destroy;
  498. end;
  499. procedure tunitsym.ppuwrite(ppufile:tcompilerppufile);
  500. begin
  501. inherited ppuwrite(ppufile);
  502. ppufile.writeentry(ibunitsym);
  503. end;
  504. {****************************************************************************
  505. TPROCSYM
  506. ****************************************************************************}
  507. constructor tprocsym.create(const n : string);
  508. begin
  509. inherited create(n);
  510. typ:=procsym;
  511. pdlistfirst:=nil;
  512. pdlistlast:=nil;
  513. owner:=nil;
  514. {$ifdef GDB}
  515. is_global:=false;
  516. {$endif GDB}
  517. { the tprocdef have their own symoptions, make the procsym
  518. always visible }
  519. symoptions:=[sp_public];
  520. overloadchecked:=false;
  521. procdef_count:=0;
  522. end;
  523. constructor tprocsym.ppuload(ppufile:tcompilerppufile);
  524. var
  525. pdderef : tderef;
  526. i,n : longint;
  527. begin
  528. inherited ppuload(ppufile);
  529. typ:=procsym;
  530. pdlistfirst:=nil;
  531. pdlistlast:=nil;
  532. procdef_count:=0;
  533. n:=ppufile.getword;
  534. for i:=1to n do
  535. begin
  536. ppufile.getderef(pdderef);
  537. addprocdef_deref(pdderef);
  538. end;
  539. {$ifdef GDB}
  540. is_global:=false;
  541. {$endif GDB}
  542. overloadchecked:=false;
  543. end;
  544. destructor tprocsym.destroy;
  545. var
  546. hp,p : pprocdeflist;
  547. begin
  548. p:=pdlistfirst;
  549. while assigned(p) do
  550. begin
  551. hp:=p^.next;
  552. dispose(p);
  553. p:=hp;
  554. end;
  555. inherited destroy;
  556. end;
  557. procedure tprocsym.ppuwrite(ppufile:tcompilerppufile);
  558. var
  559. p : pprocdeflist;
  560. n : word;
  561. begin
  562. inherited ppuwrite(ppufile);
  563. { count procdefs }
  564. n:=0;
  565. p:=pdlistfirst;
  566. while assigned(p) do
  567. begin
  568. { only write the proc definitions that belong
  569. to this procsym and are in the global symtable }
  570. if p^.own and
  571. (p^.def.owner.symtabletype in [globalsymtable,objectsymtable]) then
  572. inc(n);
  573. p:=p^.next;
  574. end;
  575. ppufile.putword(n);
  576. { write procdefs }
  577. p:=pdlistfirst;
  578. while assigned(p) do
  579. begin
  580. { only write the proc definitions that belong
  581. to this procsym and are in the global symtable }
  582. if p^.own and
  583. (p^.def.owner.symtabletype in [globalsymtable,objectsymtable]) then
  584. ppufile.putderef(p^.defderef);
  585. p:=p^.next;
  586. end;
  587. ppufile.writeentry(ibprocsym);
  588. end;
  589. procedure tprocsym.write_parameter_lists(skipdef:tprocdef);
  590. var
  591. p : pprocdeflist;
  592. begin
  593. p:=pdlistfirst;
  594. while assigned(p) do
  595. begin
  596. if p^.def<>skipdef then
  597. MessagePos1(p^.def.fileinfo,sym_h_param_list,p^.def.fullprocname(false));
  598. p:=p^.next;
  599. end;
  600. end;
  601. {Makes implicit externals (procedures declared in the interface
  602. section which do not have a counterpart in the implementation)
  603. to be an imported procedure. For mode macpas.}
  604. procedure import_implict_external(pd:tabstractprocdef);
  605. begin
  606. tprocdef(pd).forwarddef:=false;
  607. tprocdef(pd).setmangledname(target_info.CPrefix+tprocdef(pd).procsym.realname);
  608. end;
  609. procedure tprocsym.check_forward;
  610. var
  611. p : pprocdeflist;
  612. begin
  613. p:=pdlistfirst;
  614. while assigned(p) do
  615. begin
  616. if p^.own and (p^.def.forwarddef) then
  617. begin
  618. if (m_mac in aktmodeswitches) and (p^.def.interfacedef) then
  619. import_implict_external(p^.def)
  620. else
  621. begin
  622. MessagePos1(p^.def.fileinfo,sym_e_forward_not_resolved,p^.def.fullprocname(false));
  623. { Turn further error messages off }
  624. p^.def.forwarddef:=false;
  625. end
  626. end;
  627. p:=p^.next;
  628. end;
  629. end;
  630. procedure tprocsym.buildderef;
  631. var
  632. p : pprocdeflist;
  633. begin
  634. p:=pdlistfirst;
  635. while assigned(p) do
  636. begin
  637. if p^.own then
  638. p^.defderef.build(p^.def);
  639. p:=p^.next;
  640. end;
  641. end;
  642. procedure tprocsym.deref;
  643. var
  644. p : pprocdeflist;
  645. begin
  646. { We have removed the overloaded entries, because they
  647. are not valid anymore and we can't deref them because
  648. the unit were they come from is not necessary in
  649. our uses clause (PFV) }
  650. unchain_overload;
  651. { Deref our own procdefs }
  652. p:=pdlistfirst;
  653. while assigned(p) do
  654. begin
  655. if not p^.own then
  656. internalerror(200310291);
  657. p^.def:=tprocdef(p^.defderef.resolve);
  658. p:=p^.next;
  659. end;
  660. end;
  661. procedure tprocsym.addprocdef(p:tprocdef);
  662. var
  663. pd : pprocdeflist;
  664. begin
  665. new(pd);
  666. pd^.def:=p;
  667. pd^.defderef.reset;
  668. pd^.next:=nil;
  669. pd^.own:=(pd^.def.procsym=self);
  670. { Add at end of list to keep always
  671. a correct order, also after loading from ppu }
  672. if assigned(pdlistlast) then
  673. begin
  674. pdlistlast^.next:=pd;
  675. pdlistlast:=pd;
  676. end
  677. else
  678. begin
  679. pdlistfirst:=pd;
  680. pdlistlast:=pd;
  681. end;
  682. inc(procdef_count);
  683. end;
  684. procedure tprocsym.addprocdef_deref(const d:tderef);
  685. var
  686. pd : pprocdeflist;
  687. begin
  688. new(pd);
  689. pd^.def:=nil;
  690. pd^.defderef:=d;
  691. pd^.next:=nil;
  692. pd^.own:=true;
  693. { Add at end of list to keep always
  694. a correct order, also after loading from ppu }
  695. if assigned(pdlistlast) then
  696. begin
  697. pdlistlast^.next:=pd;
  698. pdlistlast:=pd;
  699. end
  700. else
  701. begin
  702. pdlistfirst:=pd;
  703. pdlistlast:=pd;
  704. end;
  705. inc(procdef_count);
  706. end;
  707. function Tprocsym.getprocdef(nr:cardinal):Tprocdef;
  708. var
  709. i : cardinal;
  710. pd : pprocdeflist;
  711. begin
  712. pd:=pdlistfirst;
  713. for i:=2 to nr do
  714. begin
  715. if not assigned(pd) then
  716. internalerror(200209051);
  717. pd:=pd^.next;
  718. end;
  719. getprocdef:=pd^.def;
  720. end;
  721. procedure Tprocsym.add_para_match_to(Aprocsym:Tprocsym;cpoptions:tcompare_paras_options);
  722. var
  723. pd:pprocdeflist;
  724. begin
  725. pd:=pdlistfirst;
  726. while assigned(pd) do
  727. begin
  728. if Aprocsym.search_procdef_bypara(pd^.def.paras,nil,cpoptions)=nil then
  729. Aprocsym.addprocdef(pd^.def);
  730. pd:=pd^.next;
  731. end;
  732. end;
  733. procedure Tprocsym.concat_procdefs_to(s:Tprocsym);
  734. var
  735. pd : pprocdeflist;
  736. begin
  737. pd:=pdlistfirst;
  738. while assigned(pd) do
  739. begin
  740. s.addprocdef(pd^.def);
  741. pd:=pd^.next;
  742. end;
  743. end;
  744. function Tprocsym.first_procdef:Tprocdef;
  745. begin
  746. if assigned(pdlistfirst) then
  747. first_procdef:=pdlistfirst^.def
  748. else
  749. first_procdef:=nil;
  750. end;
  751. function Tprocsym.last_procdef:Tprocdef;
  752. begin
  753. if assigned(pdlistlast) then
  754. last_procdef:=pdlistlast^.def
  755. else
  756. last_procdef:=nil;
  757. end;
  758. procedure Tprocsym.foreach_procdef_static(proc2call:Tprocdefcallback;arg:pointer);
  759. var
  760. p : pprocdeflist;
  761. begin
  762. p:=pdlistfirst;
  763. while assigned(p) do
  764. begin
  765. proc2call(p^.def,arg);
  766. p:=p^.next;
  767. end;
  768. end;
  769. function Tprocsym.search_procdef_nopara_boolret:Tprocdef;
  770. var
  771. p : pprocdeflist;
  772. begin
  773. search_procdef_nopara_boolret:=nil;
  774. p:=pdlistfirst;
  775. while p<>nil do
  776. begin
  777. if (p^.def.maxparacount=0) and
  778. is_boolean(p^.def.rettype.def) then
  779. begin
  780. search_procdef_nopara_boolret:=p^.def;
  781. break;
  782. end;
  783. p:=p^.next;
  784. end;
  785. end;
  786. function Tprocsym.search_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  787. var
  788. p : pprocdeflist;
  789. begin
  790. search_procdef_bytype:=nil;
  791. p:=pdlistfirst;
  792. while p<>nil do
  793. begin
  794. if p^.def.proctypeoption=pt then
  795. begin
  796. search_procdef_bytype:=p^.def;
  797. break;
  798. end;
  799. p:=p^.next;
  800. end;
  801. end;
  802. function Tprocsym.search_procdef_bypara(para:tlist;retdef:tdef;
  803. cpoptions:tcompare_paras_options):Tprocdef;
  804. var
  805. pd : pprocdeflist;
  806. eq : tequaltype;
  807. begin
  808. search_procdef_bypara:=nil;
  809. pd:=pdlistfirst;
  810. while assigned(pd) do
  811. begin
  812. if assigned(retdef) then
  813. eq:=compare_defs(retdef,pd^.def.rettype.def,nothingn)
  814. else
  815. eq:=te_equal;
  816. if (eq>=te_equal) or
  817. ((cpo_allowconvert in cpoptions) and (eq>te_incompatible)) then
  818. begin
  819. eq:=compare_paras(para,pd^.def.paras,cp_value_equal_const,cpoptions);
  820. if (eq>=te_equal) or
  821. ((cpo_allowconvert in cpoptions) and (eq>te_incompatible)) then
  822. begin
  823. search_procdef_bypara:=pd^.def;
  824. break;
  825. end;
  826. end;
  827. pd:=pd^.next;
  828. end;
  829. end;
  830. function Tprocsym.search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  831. var
  832. pd : pprocdeflist;
  833. eq,besteq : tequaltype;
  834. bestpd : tprocdef;
  835. begin
  836. { This function will return the pprocdef of pprocsym that
  837. is the best match for procvardef. When there are multiple
  838. matches it returns nil.}
  839. search_procdef_byprocvardef:=nil;
  840. bestpd:=nil;
  841. besteq:=te_incompatible;
  842. pd:=pdlistfirst;
  843. while assigned(pd) do
  844. begin
  845. eq:=proc_to_procvar_equal(pd^.def,d,false);
  846. if eq>=te_equal then
  847. begin
  848. { multiple procvars with the same equal level }
  849. if assigned(bestpd) and
  850. (besteq=eq) then
  851. exit;
  852. if eq>besteq then
  853. begin
  854. besteq:=eq;
  855. bestpd:=pd^.def;
  856. end;
  857. end;
  858. pd:=pd^.next;
  859. end;
  860. search_procdef_byprocvardef:=bestpd;
  861. end;
  862. function Tprocsym.search_procdef_assignment_operator(fromdef,todef:tdef):Tprocdef;
  863. var
  864. convtyp : tconverttype;
  865. pd : pprocdeflist;
  866. bestpd : tprocdef;
  867. eq,
  868. besteq : tequaltype;
  869. hpd : tprocdef;
  870. i : byte;
  871. begin
  872. result:=nil;
  873. bestpd:=nil;
  874. besteq:=te_incompatible;
  875. pd:=pdlistfirst;
  876. while assigned(pd) do
  877. begin
  878. if equal_defs(todef,pd^.def.rettype.def) then
  879. begin
  880. i:=0;
  881. { ignore vs_hidden parameters }
  882. while assigned(pd^.def.paras[i]) and
  883. (vo_is_hidden_para in tparavarsym(pd^.def.paras[i]).varoptions) do
  884. inc(i);
  885. if assigned(pd^.def.paras[i]) then
  886. begin
  887. eq:=compare_defs_ext(fromdef,tparavarsym(pd^.def.paras[i]).vartype.def,nothingn,convtyp,hpd,[]);
  888. if eq=te_exact then
  889. begin
  890. result:=pd^.def;
  891. exit;
  892. end;
  893. if eq>besteq then
  894. begin
  895. bestpd:=pd^.def;
  896. besteq:=eq;
  897. end;
  898. end;
  899. end;
  900. pd:=pd^.next;
  901. end;
  902. result:=bestpd;
  903. end;
  904. function tprocsym.write_references(ppufile:tcompilerppufile;locals:boolean) : boolean;
  905. var
  906. p : pprocdeflist;
  907. begin
  908. write_references:=false;
  909. if not inherited write_references(ppufile,locals) then
  910. exit;
  911. write_references:=true;
  912. p:=pdlistfirst;
  913. while assigned(p) do
  914. begin
  915. if p^.own then
  916. p^.def.write_references(ppufile,locals);
  917. p:=p^.next;
  918. end;
  919. end;
  920. procedure tprocsym.unchain_overload;
  921. var
  922. p,hp : pprocdeflist;
  923. begin
  924. { remove all overloaded procdefs from the
  925. procdeflist that are not in the current symtable }
  926. overloadchecked:=false;
  927. p:=pdlistfirst;
  928. { reset new lists }
  929. pdlistfirst:=nil;
  930. pdlistlast:=nil;
  931. while assigned(p) do
  932. begin
  933. hp:=p^.next;
  934. if p^.own then
  935. begin
  936. { keep, add to list }
  937. if assigned(pdlistlast) then
  938. begin
  939. pdlistlast^.next:=p;
  940. pdlistlast:=p;
  941. end
  942. else
  943. begin
  944. pdlistfirst:=p;
  945. pdlistlast:=p;
  946. end;
  947. p^.next:=nil;
  948. end
  949. else
  950. begin
  951. { remove }
  952. dispose(p);
  953. dec(procdef_count);
  954. end;
  955. p:=hp;
  956. end;
  957. end;
  958. function tprocsym.is_visible_for_object(currobjdef:tdef):boolean;
  959. var
  960. p : pprocdeflist;
  961. begin
  962. { This procsym is visible, when there is at least
  963. one of the procdefs visible }
  964. result:=false;
  965. p:=pdlistfirst;
  966. while assigned(p) do
  967. begin
  968. if p^.own and
  969. p^.def.is_visible_for_object(tobjectdef(currobjdef)) then
  970. begin
  971. result:=true;
  972. exit;
  973. end;
  974. p:=p^.next;
  975. end;
  976. end;
  977. {$ifdef GDB}
  978. function tprocsym.stabstring : pchar;
  979. begin
  980. internalerror(200111171);
  981. result:=nil;
  982. end;
  983. {$endif GDB}
  984. {****************************************************************************
  985. TERRORSYM
  986. ****************************************************************************}
  987. constructor terrorsym.create;
  988. begin
  989. inherited create('');
  990. typ:=errorsym;
  991. end;
  992. {****************************************************************************
  993. TPROPERTYSYM
  994. ****************************************************************************}
  995. constructor tpropertysym.create(const n : string);
  996. begin
  997. inherited create(n);
  998. typ:=propertysym;
  999. propoptions:=[];
  1000. index:=0;
  1001. default:=0;
  1002. proptype.reset;
  1003. indextype.reset;
  1004. readaccess:=tsymlist.create;
  1005. writeaccess:=tsymlist.create;
  1006. storedaccess:=tsymlist.create;
  1007. end;
  1008. constructor tpropertysym.ppuload(ppufile:tcompilerppufile);
  1009. begin
  1010. inherited ppuload(ppufile);
  1011. typ:=propertysym;
  1012. ppufile.getsmallset(propoptions);
  1013. if (ppo_is_override in propoptions) then
  1014. begin
  1015. ppufile.getderef(propoverridenderef);
  1016. { we need to have these objects initialized }
  1017. readaccess:=tsymlist.create;
  1018. writeaccess:=tsymlist.create;
  1019. storedaccess:=tsymlist.create;
  1020. end
  1021. else
  1022. begin
  1023. ppufile.gettype(proptype);
  1024. index:=ppufile.getlongint;
  1025. default:=ppufile.getlongint;
  1026. ppufile.gettype(indextype);
  1027. readaccess:=ppufile.getsymlist;
  1028. writeaccess:=ppufile.getsymlist;
  1029. storedaccess:=ppufile.getsymlist;
  1030. end;
  1031. end;
  1032. destructor tpropertysym.destroy;
  1033. begin
  1034. readaccess.free;
  1035. writeaccess.free;
  1036. storedaccess.free;
  1037. inherited destroy;
  1038. end;
  1039. function tpropertysym.gettypedef:tdef;
  1040. begin
  1041. gettypedef:=proptype.def;
  1042. end;
  1043. procedure tpropertysym.buildderef;
  1044. begin
  1045. if (ppo_is_override in propoptions) then
  1046. begin
  1047. propoverridenderef.build(propoverriden);
  1048. end
  1049. else
  1050. begin
  1051. proptype.buildderef;
  1052. indextype.buildderef;
  1053. readaccess.buildderef;
  1054. writeaccess.buildderef;
  1055. storedaccess.buildderef;
  1056. end;
  1057. end;
  1058. procedure tpropertysym.deref;
  1059. begin
  1060. if (ppo_is_override in propoptions) then
  1061. begin
  1062. propoverriden:=tpropertysym(propoverridenderef.resolve);
  1063. dooverride(propoverriden);
  1064. end
  1065. else
  1066. begin
  1067. proptype.resolve;
  1068. indextype.resolve;
  1069. readaccess.resolve;
  1070. writeaccess.resolve;
  1071. storedaccess.resolve;
  1072. end;
  1073. end;
  1074. function tpropertysym.getsize : longint;
  1075. begin
  1076. getsize:=0;
  1077. end;
  1078. procedure tpropertysym.ppuwrite(ppufile:tcompilerppufile);
  1079. begin
  1080. inherited ppuwrite(ppufile);
  1081. ppufile.putsmallset(propoptions);
  1082. if (ppo_is_override in propoptions) then
  1083. ppufile.putderef(propoverridenderef)
  1084. else
  1085. begin
  1086. ppufile.puttype(proptype);
  1087. ppufile.putlongint(index);
  1088. ppufile.putlongint(default);
  1089. ppufile.puttype(indextype);
  1090. ppufile.putsymlist(readaccess);
  1091. ppufile.putsymlist(writeaccess);
  1092. ppufile.putsymlist(storedaccess);
  1093. end;
  1094. ppufile.writeentry(ibpropertysym);
  1095. end;
  1096. procedure tpropertysym.dooverride(overriden:tpropertysym);
  1097. begin
  1098. propoverriden:=overriden;
  1099. proptype:=overriden.proptype;
  1100. propoptions:=overriden.propoptions+[ppo_is_override];
  1101. index:=overriden.index;
  1102. default:=overriden.default;
  1103. indextype:=overriden.indextype;
  1104. readaccess.free;
  1105. readaccess:=overriden.readaccess.getcopy;
  1106. writeaccess.free;
  1107. writeaccess:=overriden.writeaccess.getcopy;
  1108. storedaccess.free;
  1109. storedaccess:=overriden.storedaccess.getcopy;
  1110. end;
  1111. {****************************************************************************
  1112. TABSTRACTVARSYM
  1113. ****************************************************************************}
  1114. constructor tabstractvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
  1115. begin
  1116. inherited create(n);
  1117. vartype:=tt;
  1118. varspez:=vsp;
  1119. varstate:=vs_declared;
  1120. varoptions:=vopts;
  1121. end;
  1122. constructor tabstractvarsym.ppuload(ppufile:tcompilerppufile);
  1123. begin
  1124. inherited ppuload(ppufile);
  1125. varstate:=vs_used;
  1126. varspez:=tvarspez(ppufile.getbyte);
  1127. varregable:=tvarregable(ppufile.getbyte);
  1128. ppufile.gettype(_vartype);
  1129. ppufile.getsmallset(varoptions);
  1130. end;
  1131. destructor tabstractvarsym.destroy;
  1132. begin
  1133. if assigned(notifications) then
  1134. notifications.destroy;
  1135. inherited destroy;
  1136. end;
  1137. procedure tabstractvarsym.buildderef;
  1138. begin
  1139. vartype.buildderef;
  1140. end;
  1141. procedure tabstractvarsym.deref;
  1142. begin
  1143. vartype.resolve;
  1144. end;
  1145. procedure tabstractvarsym.ppuwrite(ppufile:tcompilerppufile);
  1146. var
  1147. oldintfcrc : boolean;
  1148. begin
  1149. inherited ppuwrite(ppufile);
  1150. ppufile.putbyte(byte(varspez));
  1151. oldintfcrc:=ppufile.do_crc;
  1152. ppufile.do_crc:=false;
  1153. ppufile.putbyte(byte(varregable));
  1154. ppufile.do_crc:=oldintfcrc;
  1155. ppufile.puttype(vartype);
  1156. ppufile.putsmallset(varoptions);
  1157. end;
  1158. function tabstractvarsym.getsize : longint;
  1159. begin
  1160. if assigned(vartype.def) and
  1161. ((vartype.def.deftype<>arraydef) or
  1162. tarraydef(vartype.def).isDynamicArray or
  1163. (tarraydef(vartype.def).highrange>=tarraydef(vartype.def).lowrange)) then
  1164. result:=vartype.def.size
  1165. else
  1166. result:=0;
  1167. end;
  1168. function tabstractvarsym.is_regvar:boolean;
  1169. begin
  1170. { Register variables are not allowed in the following cases:
  1171. - regvars are disabled
  1172. - exceptions are used (after an exception is raised the contents of the
  1173. registers is not valid anymore)
  1174. - it has a local copy
  1175. - the value needs to be in memory (i.e. reference counted) }
  1176. result:=(cs_regvars in aktglobalswitches) and
  1177. not(pi_has_assembler_block in current_procinfo.flags) and
  1178. not(pi_uses_exceptions in current_procinfo.flags) and
  1179. not(vo_has_local_copy in varoptions) and
  1180. (varregable<>vr_none);
  1181. end;
  1182. procedure tabstractvarsym.trigger_notifications(what:Tnotification_flag);
  1183. var n:Tnotification;
  1184. begin
  1185. if assigned(notifications) then
  1186. begin
  1187. n:=Tnotification(notifications.first);
  1188. while assigned(n) do
  1189. begin
  1190. if what in n.flags then
  1191. n.callback(what,self);
  1192. n:=Tnotification(n.next);
  1193. end;
  1194. end;
  1195. end;
  1196. function Tabstractvarsym.register_notification(flags:Tnotification_flags;callback:
  1197. Tnotification_callback):cardinal;
  1198. var n:Tnotification;
  1199. begin
  1200. if not assigned(notifications) then
  1201. notifications:=Tlinkedlist.create;
  1202. n:=Tnotification.create(flags,callback);
  1203. register_notification:=n.id;
  1204. notifications.concat(n);
  1205. end;
  1206. procedure Tabstractvarsym.unregister_notification(id:cardinal);
  1207. var n:Tnotification;
  1208. begin
  1209. if not assigned(notifications) then
  1210. internalerror(200212311)
  1211. else
  1212. begin
  1213. n:=Tnotification(notifications.first);
  1214. while assigned(n) do
  1215. begin
  1216. if n.id=id then
  1217. begin
  1218. notifications.remove(n);
  1219. n.destroy;
  1220. exit;
  1221. end;
  1222. n:=Tnotification(n.next);
  1223. end;
  1224. internalerror(200212311)
  1225. end;
  1226. end;
  1227. procedure tabstractvarsym.setvartype(const newtype: ttype);
  1228. begin
  1229. _vartype := newtype;
  1230. { can we load the value into a register ? }
  1231. if not assigned(owner) or
  1232. (owner.symtabletype in [localsymtable,parasymtable]) or
  1233. (
  1234. (owner.symtabletype=staticsymtable) and
  1235. not(cs_create_pic in aktmoduleswitches)
  1236. ) then
  1237. begin
  1238. if tstoreddef(vartype.def).is_intregable then
  1239. varregable:=vr_intreg
  1240. else
  1241. {$warning TODO: no fpu regvar in staticsymtable yet, need initialization with 0}
  1242. if (
  1243. not assigned(owner) or
  1244. (owner.symtabletype<>staticsymtable)
  1245. ) and
  1246. tstoreddef(vartype.def).is_fpuregable then
  1247. varregable:=vr_fpureg;
  1248. end;
  1249. end;
  1250. {****************************************************************************
  1251. TFIELDVARSYM
  1252. ****************************************************************************}
  1253. constructor tfieldvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
  1254. begin
  1255. inherited create(n,vsp,tt,vopts);
  1256. typ:=fieldvarsym;
  1257. fieldoffset:=0;
  1258. end;
  1259. constructor tfieldvarsym.ppuload(ppufile:tcompilerppufile);
  1260. begin
  1261. inherited ppuload(ppufile);
  1262. typ:=fieldvarsym;
  1263. fieldoffset:=ppufile.getaint;
  1264. end;
  1265. procedure tfieldvarsym.ppuwrite(ppufile:tcompilerppufile);
  1266. begin
  1267. inherited ppuwrite(ppufile);
  1268. ppufile.putaint(fieldoffset);
  1269. ppufile.writeentry(ibfieldvarsym);
  1270. end;
  1271. {$ifdef GDB}
  1272. function tfieldvarsym.stabstring:Pchar;
  1273. var
  1274. st : string;
  1275. begin
  1276. stabstring:=nil;
  1277. case owner.symtabletype of
  1278. objectsymtable :
  1279. begin
  1280. if (sp_static in symoptions) then
  1281. begin
  1282. st:=tstoreddef(vartype.def).numberstring;
  1283. if (cs_gdb_gsym in aktglobalswitches) then
  1284. st:='G'+st
  1285. else
  1286. st:='S'+st;
  1287. stabstring:=stabstr_evaluate('"${ownername}__${name}:$1",${N_LCSYM},0,${line},${mangledname}',[st]);
  1288. end;
  1289. end;
  1290. end;
  1291. end;
  1292. {$endif GDB}
  1293. {****************************************************************************
  1294. TABSTRACTNORMALVARSYM
  1295. ****************************************************************************}
  1296. constructor tabstractnormalvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
  1297. begin
  1298. inherited create(n,vsp,tt,vopts);
  1299. fillchar(localloc,sizeof(localloc),0);
  1300. defaultconstsym:=nil;
  1301. end;
  1302. constructor tabstractnormalvarsym.ppuload(ppufile:tcompilerppufile);
  1303. begin
  1304. inherited ppuload(ppufile);
  1305. fillchar(localloc,sizeof(localloc),0);
  1306. ppufile.getderef(defaultconstsymderef);
  1307. end;
  1308. procedure tabstractnormalvarsym.buildderef;
  1309. begin
  1310. inherited buildderef;
  1311. defaultconstsymderef.build(defaultconstsym);
  1312. end;
  1313. procedure tabstractnormalvarsym.deref;
  1314. begin
  1315. inherited deref;
  1316. defaultconstsym:=tsym(defaultconstsymderef.resolve);
  1317. end;
  1318. procedure tabstractnormalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1319. begin
  1320. inherited ppuwrite(ppufile);
  1321. ppufile.putderef(defaultconstsymderef);
  1322. end;
  1323. {****************************************************************************
  1324. TGLOBALVARSYM
  1325. ****************************************************************************}
  1326. constructor tglobalvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
  1327. begin
  1328. inherited create(n,vsp,tt,vopts);
  1329. typ:=globalvarsym;
  1330. _mangledname:=nil;
  1331. end;
  1332. constructor tglobalvarsym.create_dll(const n : string;vsp:tvarspez;const tt : ttype);
  1333. begin
  1334. tglobalvarsym(self).create(n,vsp,tt,[vo_is_dll_var]);
  1335. end;
  1336. constructor tglobalvarsym.create_C(const n,mangled : string;vsp:tvarspez;const tt : ttype);
  1337. begin
  1338. tglobalvarsym(self).create(n,vsp,tt,[]);
  1339. set_mangledname(mangled);
  1340. end;
  1341. constructor tglobalvarsym.ppuload(ppufile:tcompilerppufile);
  1342. begin
  1343. inherited ppuload(ppufile);
  1344. typ:=globalvarsym;
  1345. if vo_has_mangledname in varoptions then
  1346. _mangledname:=stringdup(ppufile.getstring)
  1347. else
  1348. _mangledname:=nil;
  1349. end;
  1350. destructor tglobalvarsym.destroy;
  1351. begin
  1352. if assigned(_mangledname) then
  1353. begin
  1354. {$ifdef MEMDEBUG}
  1355. memmanglednames.start;
  1356. {$endif MEMDEBUG}
  1357. stringdispose(_mangledname);
  1358. {$ifdef MEMDEBUG}
  1359. memmanglednames.stop;
  1360. {$endif MEMDEBUG}
  1361. end;
  1362. inherited destroy;
  1363. end;
  1364. procedure tglobalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1365. begin
  1366. inherited ppuwrite(ppufile);
  1367. if vo_has_mangledname in varoptions then
  1368. ppufile.putstring(_mangledname^);
  1369. ppufile.writeentry(ibglobalvarsym);
  1370. end;
  1371. function tglobalvarsym.mangledname:string;
  1372. begin
  1373. if not assigned(_mangledname) then
  1374. begin
  1375. {$ifdef compress}
  1376. _mangledname:=stringdup(minilzw_encode(make_mangledname('U',owner,name)));
  1377. {$else}
  1378. _mangledname:=stringdup(make_mangledname('U',owner,name));
  1379. {$endif}
  1380. end;
  1381. result:=_mangledname^;
  1382. end;
  1383. procedure tglobalvarsym.set_mangledname(const s:string);
  1384. begin
  1385. stringdispose(_mangledname);
  1386. {$ifdef compress}
  1387. _mangledname:=stringdup(minilzw_encode(s));
  1388. {$else}
  1389. _mangledname:=stringdup(s);
  1390. {$endif}
  1391. include(varoptions,vo_has_mangledname);
  1392. end;
  1393. {$ifdef GDB}
  1394. function Tglobalvarsym.stabstring:Pchar;
  1395. var st:string;
  1396. threadvaroffset:string;
  1397. regidx:Tregisterindex;
  1398. begin
  1399. result:=nil;
  1400. st:=tstoreddef(vartype.def).numberstring;
  1401. case localloc.loc of
  1402. LOC_REGISTER,
  1403. LOC_CREGISTER,
  1404. LOC_MMREGISTER,
  1405. LOC_CMMREGISTER,
  1406. LOC_FPUREGISTER,
  1407. LOC_CFPUREGISTER :
  1408. begin
  1409. regidx:=findreg_by_number(localloc.register);
  1410. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1411. { this is the register order for GDB}
  1412. if regidx<>0 then
  1413. stabstring:=stabstr_evaluate('"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(regstabs_table[regidx])]);
  1414. end;
  1415. else
  1416. begin
  1417. if (vo_is_thread_var in varoptions) then
  1418. threadvaroffset:='+'+tostr(sizeof(aint))
  1419. else
  1420. threadvaroffset:='';
  1421. { Here we used S instead of
  1422. because with G GDB doesn't look at the address field
  1423. but searches the same name or with a leading underscore
  1424. but these names don't exist in pascal !}
  1425. if (cs_gdb_gsym in aktglobalswitches) then
  1426. st:='G'+st
  1427. else
  1428. st:='S'+st;
  1429. stabstring:=stabstr_evaluate('"${name}:$1",${N_LCSYM},0,${line},${mangledname}$2',[st,threadvaroffset]);
  1430. end;
  1431. end;
  1432. end;
  1433. {$endif GDB}
  1434. {****************************************************************************
  1435. TLOCALVARSYM
  1436. ****************************************************************************}
  1437. constructor tlocalvarsym.create(const n : string;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
  1438. begin
  1439. inherited create(n,vsp,tt,vopts);
  1440. typ:=localvarsym;
  1441. end;
  1442. constructor tlocalvarsym.ppuload(ppufile:tcompilerppufile);
  1443. begin
  1444. inherited ppuload(ppufile);
  1445. typ:=localvarsym;
  1446. end;
  1447. procedure tlocalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1448. begin
  1449. inherited ppuwrite(ppufile);
  1450. ppufile.writeentry(iblocalvarsym);
  1451. end;
  1452. {$ifdef GDB}
  1453. function tlocalvarsym.stabstring:Pchar;
  1454. var st:string;
  1455. regidx:Tregisterindex;
  1456. begin
  1457. stabstring:=nil;
  1458. { There is no space allocated for not referenced locals }
  1459. if (owner.symtabletype=localsymtable) and (refs=0) then
  1460. exit;
  1461. st:=tstoreddef(vartype.def).numberstring;
  1462. case localloc.loc of
  1463. LOC_REGISTER,
  1464. LOC_CREGISTER,
  1465. LOC_MMREGISTER,
  1466. LOC_CMMREGISTER,
  1467. LOC_FPUREGISTER,
  1468. LOC_CFPUREGISTER :
  1469. begin
  1470. regidx:=findreg_by_number(localloc.register);
  1471. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1472. { this is the register order for GDB}
  1473. if regidx<>0 then
  1474. stabstring:=stabstr_evaluate('"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(regstabs_table[regidx])]);
  1475. end;
  1476. LOC_REFERENCE :
  1477. { offset to ebp => will not work if the framepointer is esp
  1478. so some optimizing will make things harder to debug }
  1479. stabstring:=stabstr_evaluate('"${name}:$1",${N_TSYM},0,${line},$2',[st,tostr(localloc.reference.offset)])
  1480. else
  1481. internalerror(2003091814);
  1482. end;
  1483. end;
  1484. {$endif GDB}
  1485. {****************************************************************************
  1486. TPARAVARSYM
  1487. ****************************************************************************}
  1488. constructor tparavarsym.create(const n : string;nr:word;vsp:tvarspez;const tt : ttype;vopts:tvaroptions);
  1489. begin
  1490. inherited create(n,vsp,tt,vopts);
  1491. typ:=paravarsym;
  1492. paranr:=nr;
  1493. paraloc[calleeside].init;
  1494. paraloc[callerside].init;
  1495. end;
  1496. destructor tparavarsym.destroy;
  1497. begin
  1498. paraloc[calleeside].done;
  1499. paraloc[callerside].done;
  1500. inherited destroy;
  1501. end;
  1502. constructor tparavarsym.ppuload(ppufile:tcompilerppufile);
  1503. var
  1504. b : byte;
  1505. begin
  1506. inherited ppuload(ppufile);
  1507. paranr:=ppufile.getword;
  1508. paraloc[calleeside].init;
  1509. paraloc[callerside].init;
  1510. if vo_has_explicit_paraloc in varoptions then
  1511. begin
  1512. b:=ppufile.getbyte;
  1513. if b<>sizeof(paraloc[callerside].location^) then
  1514. internalerror(200411154);
  1515. ppufile.getdata(paraloc[callerside].add_location^,sizeof(paraloc[callerside].location^));
  1516. paraloc[callerside].size:=paraloc[callerside].location^.size;
  1517. end;
  1518. typ:=paravarsym;
  1519. end;
  1520. procedure tparavarsym.ppuwrite(ppufile:tcompilerppufile);
  1521. begin
  1522. inherited ppuwrite(ppufile);
  1523. ppufile.putword(paranr);
  1524. if vo_has_explicit_paraloc in varoptions then
  1525. begin
  1526. paraloc[callerside].check_simple_location;
  1527. ppufile.putbyte(sizeof(paraloc[callerside].location^));
  1528. ppufile.putdata(paraloc[callerside].location^,sizeof(paraloc[callerside].location^));
  1529. end;
  1530. ppufile.writeentry(ibparavarsym);
  1531. end;
  1532. {$ifdef GDB}
  1533. function tparavarsym.stabstring:Pchar;
  1534. var st:string;
  1535. regidx:Tregisterindex;
  1536. c:char;
  1537. begin
  1538. result:=nil;
  1539. { set loc to LOC_REFERENCE to get somewhat usable debugging info for -Or }
  1540. { while stabs aren't adapted for regvars yet }
  1541. if (vo_is_self in varoptions) then
  1542. begin
  1543. case localloc.loc of
  1544. LOC_REGISTER,
  1545. LOC_CREGISTER:
  1546. regidx:=findreg_by_number(localloc.register);
  1547. LOC_REFERENCE: ;
  1548. else
  1549. internalerror(2003091815);
  1550. end;
  1551. if (po_classmethod in current_procinfo.procdef.procoptions) or
  1552. (po_staticmethod in current_procinfo.procdef.procoptions) then
  1553. begin
  1554. if (localloc.loc=LOC_REFERENCE) then
  1555. stabstring:=stabstr_evaluate('"pvmt:p$1",${N_TSYM},0,0,$2',
  1556. [Tstoreddef(pvmttype.def).numberstring,tostr(localloc.reference.offset)]);
  1557. (* else
  1558. stabstring:=stabstr_evaluate('"pvmt:r$1",${N_RSYM},0,0,$2',
  1559. [Tstoreddef(pvmttype.def).numberstring,tostr(regstabs_table[regidx])]) *)
  1560. end
  1561. else
  1562. begin
  1563. if not(is_class(current_procinfo.procdef._class)) then
  1564. c:='v'
  1565. else
  1566. c:='p';
  1567. if (localloc.loc=LOC_REFERENCE) then
  1568. stabstring:=stabstr_evaluate('"$$t:$1",${N_TSYM},0,0,$2',
  1569. [c+current_procinfo.procdef._class.numberstring,tostr(localloc.reference.offset)]);
  1570. (* else
  1571. stabstring:=stabstr_evaluate('"$$t:r$1",${N_RSYM},0,0,$2',
  1572. [c+current_procinfo.procdef._class.numberstring,tostr(regstabs_table[regidx])]); *)
  1573. end;
  1574. end
  1575. else
  1576. begin
  1577. st:=tstoreddef(vartype.def).numberstring;
  1578. if paramanager.push_addr_param(varspez,vartype.def,tprocdef(owner.defowner).proccalloption) and
  1579. not(vo_has_local_copy in varoptions) and
  1580. not is_open_string(vartype.def) then
  1581. st := 'v'+st { should be 'i' but 'i' doesn't work }
  1582. else
  1583. st := 'p'+st;
  1584. case localloc.loc of
  1585. LOC_REGISTER,
  1586. LOC_CREGISTER,
  1587. LOC_MMREGISTER,
  1588. LOC_CMMREGISTER,
  1589. LOC_FPUREGISTER,
  1590. LOC_CFPUREGISTER :
  1591. begin
  1592. regidx:=findreg_by_number(localloc.register);
  1593. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1594. { this is the register order for GDB}
  1595. if regidx<>0 then
  1596. stabstring:=stabstr_evaluate('"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(regstabs_table[regidx])]);
  1597. end;
  1598. LOC_REFERENCE :
  1599. { offset to ebp => will not work if the framepointer is esp
  1600. so some optimizing will make things harder to debug }
  1601. stabstring:=stabstr_evaluate('"${name}:$1",${N_TSYM},0,${line},$2',[st,tostr(localloc.reference.offset)])
  1602. else
  1603. internalerror(2003091814);
  1604. end;
  1605. end;
  1606. end;
  1607. {$endif GDB}
  1608. {****************************************************************************
  1609. TABSOLUTEVARSYM
  1610. ****************************************************************************}
  1611. constructor tabsolutevarsym.create(const n : string;const tt : ttype);
  1612. begin
  1613. inherited create(n,vs_value,tt,[]);
  1614. typ:=absolutevarsym;
  1615. ref:=nil;
  1616. end;
  1617. constructor tabsolutevarsym.create_ref(const n : string;const tt : ttype;_ref:tsymlist);
  1618. begin
  1619. inherited create(n,vs_value,tt,[]);
  1620. typ:=absolutevarsym;
  1621. ref:=_ref;
  1622. end;
  1623. destructor tabsolutevarsym.destroy;
  1624. begin
  1625. if assigned(ref) then
  1626. ref.free;
  1627. inherited destroy;
  1628. end;
  1629. constructor tabsolutevarsym.ppuload(ppufile:tcompilerppufile);
  1630. begin
  1631. inherited ppuload(ppufile);
  1632. typ:=absolutevarsym;
  1633. ref:=nil;
  1634. asmname:=nil;
  1635. abstyp:=absolutetyp(ppufile.getbyte);
  1636. {$ifdef i386}
  1637. absseg:=false;
  1638. {$endif i386}
  1639. case abstyp of
  1640. tovar :
  1641. ref:=ppufile.getsymlist;
  1642. toasm :
  1643. asmname:=stringdup(ppufile.getstring);
  1644. toaddr :
  1645. begin
  1646. addroffset:=ppufile.getaint;
  1647. {$ifdef i386}
  1648. absseg:=boolean(ppufile.getbyte);
  1649. {$endif i386}
  1650. end;
  1651. end;
  1652. end;
  1653. procedure tabsolutevarsym.ppuwrite(ppufile:tcompilerppufile);
  1654. begin
  1655. inherited ppuwrite(ppufile);
  1656. ppufile.putbyte(byte(abstyp));
  1657. case abstyp of
  1658. tovar :
  1659. ppufile.putsymlist(ref);
  1660. toasm :
  1661. ppufile.putstring(asmname^);
  1662. toaddr :
  1663. begin
  1664. ppufile.putaint(addroffset);
  1665. {$ifdef i386}
  1666. ppufile.putbyte(byte(absseg));
  1667. {$endif i386}
  1668. end;
  1669. end;
  1670. ppufile.writeentry(ibabsolutevarsym);
  1671. end;
  1672. procedure tabsolutevarsym.buildderef;
  1673. begin
  1674. inherited buildderef;
  1675. if (abstyp=tovar) then
  1676. ref.buildderef;
  1677. end;
  1678. procedure tabsolutevarsym.deref;
  1679. begin
  1680. inherited deref;
  1681. { own absolute deref }
  1682. if (abstyp=tovar) then
  1683. ref.resolve;
  1684. end;
  1685. function tabsolutevarsym.mangledname : string;
  1686. begin
  1687. case abstyp of
  1688. toasm :
  1689. mangledname:=asmname^;
  1690. toaddr :
  1691. mangledname:='$'+tostr(addroffset);
  1692. else
  1693. internalerror(200411061);
  1694. end;
  1695. end;
  1696. {$ifdef GDB}
  1697. function tabsolutevarsym.stabstring:Pchar;
  1698. begin
  1699. stabstring:=nil;
  1700. end;
  1701. {$endif GDB}
  1702. {****************************************************************************
  1703. TTYPEDCONSTSYM
  1704. *****************************************************************************}
  1705. constructor ttypedconstsym.create(const n : string;p : tdef;writable : boolean);
  1706. begin
  1707. inherited create(n);
  1708. typ:=typedconstsym;
  1709. typedconsttype.setdef(p);
  1710. is_writable:=writable;
  1711. end;
  1712. constructor ttypedconstsym.createtype(const n : string;const tt : ttype;writable : boolean);
  1713. begin
  1714. inherited create(n);
  1715. typ:=typedconstsym;
  1716. typedconsttype:=tt;
  1717. is_writable:=writable;
  1718. end;
  1719. constructor ttypedconstsym.ppuload(ppufile:tcompilerppufile);
  1720. begin
  1721. inherited ppuload(ppufile);
  1722. typ:=typedconstsym;
  1723. ppufile.gettype(typedconsttype);
  1724. is_writable:=boolean(ppufile.getbyte);
  1725. end;
  1726. destructor ttypedconstsym.destroy;
  1727. begin
  1728. if assigned(_mangledname) then
  1729. begin
  1730. {$ifdef MEMDEBUG}
  1731. memmanglednames.start;
  1732. {$endif MEMDEBUG}
  1733. stringdispose(_mangledname);
  1734. {$ifdef MEMDEBUG}
  1735. memmanglednames.stop;
  1736. {$endif MEMDEBUG}
  1737. end;
  1738. inherited destroy;
  1739. end;
  1740. function ttypedconstsym.mangledname:string;
  1741. begin
  1742. if not assigned(_mangledname) then
  1743. begin
  1744. {$ifdef compress}
  1745. _mangledname:=stringdup(make_mangledname('TC',owner,name));
  1746. {$else}
  1747. _mangledname:=stringdup(make_mangledname('TC',owner,name));
  1748. {$endif}
  1749. end;
  1750. result:=_mangledname^;
  1751. end;
  1752. function ttypedconstsym.getsize : longint;
  1753. begin
  1754. if assigned(typedconsttype.def) then
  1755. getsize:=typedconsttype.def.size
  1756. else
  1757. getsize:=0;
  1758. end;
  1759. procedure ttypedconstsym.buildderef;
  1760. begin
  1761. typedconsttype.buildderef;
  1762. end;
  1763. procedure ttypedconstsym.deref;
  1764. begin
  1765. typedconsttype.resolve;
  1766. end;
  1767. procedure ttypedconstsym.ppuwrite(ppufile:tcompilerppufile);
  1768. begin
  1769. inherited ppuwrite(ppufile);
  1770. ppufile.puttype(typedconsttype);
  1771. ppufile.putbyte(byte(is_writable));
  1772. ppufile.writeentry(ibtypedconstsym);
  1773. end;
  1774. {$ifdef GDB}
  1775. function ttypedconstsym.stabstring : pchar;
  1776. var st:char;
  1777. begin
  1778. if (cs_gdb_gsym in aktglobalswitches) and (owner.symtabletype=globalsymtable) then
  1779. st:='G'
  1780. else
  1781. st:='S';
  1782. stabstring:=stabstr_evaluate('"${name}:$1$2",${N_STSYM},0,${line},${mangledname}',
  1783. [st,Tstoreddef(typedconsttype.def).numberstring]);
  1784. end;
  1785. {$endif GDB}
  1786. {****************************************************************************
  1787. TCONSTSYM
  1788. ****************************************************************************}
  1789. constructor tconstsym.create_ord(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  1790. begin
  1791. inherited create(n);
  1792. fillchar(value, sizeof(value), #0);
  1793. typ:=constsym;
  1794. consttyp:=t;
  1795. value.valueord:=v;
  1796. ResStrIndex:=0;
  1797. consttype:=tt;
  1798. end;
  1799. constructor tconstsym.create_ordptr(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  1800. begin
  1801. inherited create(n);
  1802. fillchar(value, sizeof(value), #0);
  1803. typ:=constsym;
  1804. consttyp:=t;
  1805. value.valueordptr:=v;
  1806. ResStrIndex:=0;
  1807. consttype:=tt;
  1808. end;
  1809. constructor tconstsym.create_ptr(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  1810. begin
  1811. inherited create(n);
  1812. fillchar(value, sizeof(value), #0);
  1813. typ:=constsym;
  1814. consttyp:=t;
  1815. value.valueptr:=v;
  1816. ResStrIndex:=0;
  1817. consttype:=tt;
  1818. end;
  1819. constructor tconstsym.create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  1820. begin
  1821. inherited create(n);
  1822. fillchar(value, sizeof(value), #0);
  1823. typ:=constsym;
  1824. consttyp:=t;
  1825. value.valueptr:=str;
  1826. consttype.reset;
  1827. value.len:=l;
  1828. if t=constresourcestring then
  1829. ResStrIndex:=ResourceStrings.Register(name,pchar(value.valueptr),value.len);
  1830. end;
  1831. constructor tconstsym.ppuload(ppufile:tcompilerppufile);
  1832. var
  1833. pd : pbestreal;
  1834. ps : pnormalset;
  1835. pc : pchar;
  1836. begin
  1837. inherited ppuload(ppufile);
  1838. typ:=constsym;
  1839. consttype.reset;
  1840. consttyp:=tconsttyp(ppufile.getbyte);
  1841. fillchar(value, sizeof(value), #0);
  1842. case consttyp of
  1843. constord :
  1844. begin
  1845. ppufile.gettype(consttype);
  1846. value.valueord:=ppufile.getexprint;
  1847. end;
  1848. constpointer :
  1849. begin
  1850. ppufile.gettype(consttype);
  1851. value.valueordptr:=ppufile.getptruint;
  1852. end;
  1853. conststring,
  1854. constresourcestring :
  1855. begin
  1856. value.len:=ppufile.getlongint;
  1857. getmem(pc,value.len+1);
  1858. ppufile.getdata(pc^,value.len);
  1859. if consttyp=constresourcestring then
  1860. ResStrIndex:=ppufile.getlongint;
  1861. value.valueptr:=pc;
  1862. end;
  1863. constreal :
  1864. begin
  1865. new(pd);
  1866. pd^:=ppufile.getreal;
  1867. value.valueptr:=pd;
  1868. end;
  1869. constset :
  1870. begin
  1871. ppufile.gettype(consttype);
  1872. new(ps);
  1873. ppufile.getnormalset(ps^);
  1874. value.valueptr:=ps;
  1875. end;
  1876. constguid :
  1877. begin
  1878. new(pguid(value.valueptr));
  1879. ppufile.getdata(value.valueptr^,sizeof(tguid));
  1880. end;
  1881. constnil : ;
  1882. else
  1883. Message1(unit_f_ppu_invalid_entry,tostr(ord(consttyp)));
  1884. end;
  1885. end;
  1886. destructor tconstsym.destroy;
  1887. begin
  1888. case consttyp of
  1889. conststring,
  1890. constresourcestring :
  1891. freemem(pchar(value.valueptr),value.len+1);
  1892. constreal :
  1893. dispose(pbestreal(value.valueptr));
  1894. constset :
  1895. dispose(pnormalset(value.valueptr));
  1896. constguid :
  1897. dispose(pguid(value.valueptr));
  1898. end;
  1899. inherited destroy;
  1900. end;
  1901. procedure tconstsym.buildderef;
  1902. begin
  1903. if consttyp in [constord,constpointer,constset] then
  1904. consttype.buildderef;
  1905. end;
  1906. procedure tconstsym.deref;
  1907. begin
  1908. if consttyp in [constord,constpointer,constset] then
  1909. consttype.resolve;
  1910. end;
  1911. procedure tconstsym.ppuwrite(ppufile:tcompilerppufile);
  1912. begin
  1913. inherited ppuwrite(ppufile);
  1914. ppufile.putbyte(byte(consttyp));
  1915. case consttyp of
  1916. constnil : ;
  1917. constord :
  1918. begin
  1919. ppufile.puttype(consttype);
  1920. ppufile.putexprint(value.valueord);
  1921. end;
  1922. constpointer :
  1923. begin
  1924. ppufile.puttype(consttype);
  1925. ppufile.putptruint(value.valueordptr);
  1926. end;
  1927. conststring,
  1928. constresourcestring :
  1929. begin
  1930. ppufile.putlongint(value.len);
  1931. ppufile.putdata(pchar(value.valueptr)^,value.len);
  1932. if consttyp=constresourcestring then
  1933. ppufile.putlongint(ResStrIndex);
  1934. end;
  1935. constreal :
  1936. ppufile.putreal(pbestreal(value.valueptr)^);
  1937. constset :
  1938. begin
  1939. ppufile.puttype(consttype);
  1940. ppufile.putnormalset(value.valueptr^);
  1941. end;
  1942. constguid :
  1943. ppufile.putdata(value.valueptr^,sizeof(tguid));
  1944. else
  1945. internalerror(13);
  1946. end;
  1947. ppufile.writeentry(ibconstsym);
  1948. end;
  1949. {$ifdef GDB}
  1950. function Tconstsym.stabstring:Pchar;
  1951. var st : string;
  1952. begin
  1953. {even GDB v4.16 only now 'i' 'r' and 'e' !!!}
  1954. case consttyp of
  1955. conststring:
  1956. st:='s'''+backspace_quote(octal_quote(strpas(pchar(value.valueptr)),[#0..#9,#11,#12,#14..#31,'''']),['"','\',#10,#13])+'''';
  1957. constord:
  1958. st:='i'+tostr(value.valueord);
  1959. constpointer:
  1960. st:='i'+tostr(value.valueordptr);
  1961. constreal:
  1962. begin
  1963. system.str(pbestreal(value.valueptr)^,st);
  1964. st := 'r'+st;
  1965. end;
  1966. { if we don't know just put zero !! }
  1967. else st:='i0';
  1968. {***SETCONST}
  1969. {constset:;} {*** I don't know what to do with a set.}
  1970. { sets are not recognized by GDB}
  1971. {***}
  1972. end;
  1973. { valgrind does not support constants }
  1974. if cs_gdb_valgrind in aktglobalswitches then
  1975. stabstring:=nil
  1976. else
  1977. stabstring:=stabstr_evaluate('"${name}:c=$1;",${N_FUNCTION},0,${line},0',[st]);
  1978. end;
  1979. {$endif GDB}
  1980. {****************************************************************************
  1981. TENUMSYM
  1982. ****************************************************************************}
  1983. constructor tenumsym.create(const n : string;def : tenumdef;v : longint);
  1984. begin
  1985. inherited create(n);
  1986. typ:=enumsym;
  1987. definition:=def;
  1988. value:=v;
  1989. { check for jumps }
  1990. if v>def.max+1 then
  1991. def.has_jumps:=true;
  1992. { update low and high }
  1993. if def.min>v then
  1994. def.setmin(v);
  1995. if def.max<v then
  1996. def.setmax(v);
  1997. order;
  1998. { nextenum:=Tenumsym(def.firstenum);
  1999. def.firstenum:=self;}
  2000. end;
  2001. constructor tenumsym.ppuload(ppufile:tcompilerppufile);
  2002. begin
  2003. inherited ppuload(ppufile);
  2004. typ:=enumsym;
  2005. ppufile.getderef(definitionderef);
  2006. value:=ppufile.getlongint;
  2007. nextenum := Nil;
  2008. end;
  2009. procedure tenumsym.buildderef;
  2010. begin
  2011. definitionderef.build(definition);
  2012. end;
  2013. procedure tenumsym.deref;
  2014. begin
  2015. definition:=tenumdef(definitionderef.resolve);
  2016. order;
  2017. end;
  2018. procedure tenumsym.order;
  2019. var
  2020. sym : tenumsym;
  2021. begin
  2022. sym := tenumsym(definition.firstenum);
  2023. if sym = nil then
  2024. begin
  2025. definition.firstenum := self;
  2026. nextenum := nil;
  2027. exit;
  2028. end;
  2029. { reorder the symbols in increasing value }
  2030. if value < sym.value then
  2031. begin
  2032. nextenum := sym;
  2033. definition.firstenum := self;
  2034. end
  2035. else
  2036. begin
  2037. while (sym.value <= value) and assigned(sym.nextenum) do
  2038. sym := sym.nextenum;
  2039. nextenum := sym.nextenum;
  2040. sym.nextenum := self;
  2041. end;
  2042. end;
  2043. procedure tenumsym.ppuwrite(ppufile:tcompilerppufile);
  2044. begin
  2045. inherited ppuwrite(ppufile);
  2046. ppufile.putderef(definitionderef);
  2047. ppufile.putlongint(value);
  2048. ppufile.writeentry(ibenumsym);
  2049. end;
  2050. {****************************************************************************
  2051. TTYPESYM
  2052. ****************************************************************************}
  2053. constructor ttypesym.create(const n : string;const tt : ttype);
  2054. begin
  2055. inherited create(n);
  2056. typ:=typesym;
  2057. restype:=tt;
  2058. { register the typesym for the definition }
  2059. if assigned(restype.def) and
  2060. (restype.def.deftype<>errordef) and
  2061. not(assigned(restype.def.typesym)) then
  2062. restype.def.typesym:=self;
  2063. end;
  2064. constructor ttypesym.ppuload(ppufile:tcompilerppufile);
  2065. begin
  2066. inherited ppuload(ppufile);
  2067. typ:=typesym;
  2068. ppufile.gettype(restype);
  2069. end;
  2070. function ttypesym.gettypedef:tdef;
  2071. begin
  2072. gettypedef:=restype.def;
  2073. end;
  2074. procedure ttypesym.buildderef;
  2075. begin
  2076. restype.buildderef;
  2077. end;
  2078. procedure ttypesym.deref;
  2079. begin
  2080. restype.resolve;
  2081. end;
  2082. procedure ttypesym.ppuwrite(ppufile:tcompilerppufile);
  2083. begin
  2084. inherited ppuwrite(ppufile);
  2085. ppufile.puttype(restype);
  2086. ppufile.writeentry(ibtypesym);
  2087. end;
  2088. procedure ttypesym.load_references(ppufile:tcompilerppufile;locals:boolean);
  2089. begin
  2090. inherited load_references(ppufile,locals);
  2091. if (restype.def.deftype=recorddef) then
  2092. tstoredsymtable(trecorddef(restype.def).symtable).load_references(ppufile,locals);
  2093. if (restype.def.deftype=objectdef) then
  2094. tstoredsymtable(tobjectdef(restype.def).symtable).load_references(ppufile,locals);
  2095. end;
  2096. function ttypesym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  2097. var
  2098. d : tderef;
  2099. begin
  2100. d.reset;
  2101. if not inherited write_references(ppufile,locals) then
  2102. begin
  2103. { write address of this symbol if record or object
  2104. even if no real refs are there
  2105. because we need it for the symtable }
  2106. if (restype.def.deftype in [recorddef,objectdef]) then
  2107. begin
  2108. d.build(self);
  2109. ppufile.putderef(d);
  2110. ppufile.writeentry(ibsymref);
  2111. end;
  2112. end;
  2113. write_references:=true;
  2114. if (restype.def.deftype=recorddef) then
  2115. tstoredsymtable(trecorddef(restype.def).symtable).write_references(ppufile,locals);
  2116. if (restype.def.deftype=objectdef) then
  2117. tstoredsymtable(tobjectdef(restype.def).symtable).write_references(ppufile,locals);
  2118. end;
  2119. {$ifdef GDB}
  2120. function ttypesym.stabstring : pchar;
  2121. var stabchar:string[2];
  2122. begin
  2123. stabstring:=nil;
  2124. if restype.def<>nil then
  2125. begin
  2126. if restype.def.deftype in tagtypes then
  2127. stabchar:='Tt'
  2128. else
  2129. stabchar:='t';
  2130. stabstring:=stabstr_evaluate('"${name}:$1$2",${N_LSYM},0,${line},0',[stabchar,tstoreddef(restype.def).numberstring]);
  2131. end;
  2132. end;
  2133. {$endif GDB}
  2134. {****************************************************************************
  2135. TSYSSYM
  2136. ****************************************************************************}
  2137. constructor tsyssym.create(const n : string;l : longint);
  2138. begin
  2139. inherited create(n);
  2140. typ:=syssym;
  2141. number:=l;
  2142. end;
  2143. constructor tsyssym.ppuload(ppufile:tcompilerppufile);
  2144. begin
  2145. inherited ppuload(ppufile);
  2146. typ:=syssym;
  2147. number:=ppufile.getlongint;
  2148. end;
  2149. destructor tsyssym.destroy;
  2150. begin
  2151. inherited destroy;
  2152. end;
  2153. procedure tsyssym.ppuwrite(ppufile:tcompilerppufile);
  2154. begin
  2155. inherited ppuwrite(ppufile);
  2156. ppufile.putlongint(number);
  2157. ppufile.writeentry(ibsyssym);
  2158. end;
  2159. {****************************************************************************
  2160. TRTTISYM
  2161. ****************************************************************************}
  2162. constructor trttisym.create(const n:string;rt:trttitype);
  2163. const
  2164. prefix : array[trttitype] of string[5]=('$rtti','$init');
  2165. begin
  2166. inherited create(prefix[rt]+n);
  2167. include(symoptions,sp_internal);
  2168. typ:=rttisym;
  2169. lab:=nil;
  2170. rttityp:=rt;
  2171. end;
  2172. destructor trttisym.destroy;
  2173. begin
  2174. if assigned(_mangledname) then
  2175. begin
  2176. {$ifdef MEMDEBUG}
  2177. memmanglednames.start;
  2178. {$endif MEMDEBUG}
  2179. stringdispose(_mangledname);
  2180. {$ifdef MEMDEBUG}
  2181. memmanglednames.stop;
  2182. {$endif MEMDEBUG}
  2183. end;
  2184. inherited destroy;
  2185. end;
  2186. constructor trttisym.ppuload(ppufile:tcompilerppufile);
  2187. begin
  2188. inherited ppuload(ppufile);
  2189. typ:=rttisym;
  2190. lab:=nil;
  2191. rttityp:=trttitype(ppufile.getbyte);
  2192. end;
  2193. procedure trttisym.ppuwrite(ppufile:tcompilerppufile);
  2194. begin
  2195. inherited ppuwrite(ppufile);
  2196. ppufile.putbyte(byte(rttityp));
  2197. ppufile.writeentry(ibrttisym);
  2198. end;
  2199. function trttisym.mangledname : string;
  2200. const
  2201. prefix : array[trttitype] of string[5]=('RTTI_','INIT_');
  2202. begin
  2203. if not assigned(_mangledname) then
  2204. _mangledname:=stringdup(make_mangledname(prefix[rttityp],owner,Copy(name,5,255)));
  2205. result:=_mangledname^;
  2206. end;
  2207. function trttisym.get_label:tasmsymbol;
  2208. begin
  2209. { the label is always a global label }
  2210. if not assigned(lab) then
  2211. lab:=objectlibrary.newasmsymbol(mangledname,AB_EXTERNAL,AT_DATA);
  2212. get_label:=lab;
  2213. end;
  2214. end.
  2215. {
  2216. $Log$
  2217. Revision 1.197 2005-01-03 22:27:56 peter
  2218. * insert stack_check helper call before doing register allocation
  2219. so the used registers can't be reused when parameters are loaded
  2220. into register variables
  2221. Revision 1.196 2004/12/07 16:11:52 peter
  2222. * set vo_explicit_paraloc flag
  2223. Revision 1.195 2004/11/29 20:50:37 peter
  2224. * uninited results
  2225. Revision 1.194 2004/11/17 22:21:35 peter
  2226. mangledname setting moved to place after the complete proc declaration is read
  2227. import generation moved to place where body is also parsed (still gives problems with win32)
  2228. Revision 1.193 2004/11/16 22:09:57 peter
  2229. * _mangledname for symbols moved only to symbols that really need it
  2230. * overload number removed, add function result type to the mangledname fo
  2231. procdefs
  2232. Revision 1.192 2004/11/15 23:35:31 peter
  2233. * tparaitem removed, use tparavarsym instead
  2234. * parameter order is now calculated from paranr value in tparavarsym
  2235. Revision 1.191 2004/11/08 22:09:59 peter
  2236. * tvarsym splitted
  2237. Revision 1.190 2004/11/04 17:09:54 peter
  2238. fixed debuginfo for variables in staticsymtable
  2239. Revision 1.189 2004/10/31 21:45:03 peter
  2240. * generic tlocation
  2241. * move tlocation to cgutils
  2242. Revision 1.188 2004/10/15 09:14:17 mazen
  2243. - remove $IFDEF DELPHI and related code
  2244. - remove $IFDEF FPCPROCVAR and related code
  2245. Revision 1.187 2004/10/13 18:47:45 peter
  2246. * fix misplaced begin..end for self stabs
  2247. * no fpu regable for staticsymtable
  2248. Revision 1.186 2004/10/12 14:34:49 peter
  2249. * fixed visibility for procsyms
  2250. * fixed override check when there was no entry yet
  2251. Revision 1.185 2004/10/11 20:48:34 peter
  2252. * don't generate stabs for self when it is in a regvar
  2253. Revision 1.184 2004/10/11 15:48:15 peter
  2254. * small regvar for para fixes
  2255. * function tvarsym.is_regvar added
  2256. * tvarsym.getvaluesize removed, use getsize instead
  2257. Revision 1.183 2004/10/10 21:08:55 peter
  2258. * parameter regvar fixes
  2259. Revision 1.182 2004/10/10 20:22:53 peter
  2260. * symtable allocation rewritten
  2261. * loading of parameters to local temps/regs cleanup
  2262. * regvar support for parameters
  2263. * regvar support for staticsymtable (main body)
  2264. Revision 1.181 2004/10/10 09:31:28 peter
  2265. regvar ppu writing doesn't affect any crc
  2266. Revision 1.180 2004/10/08 17:09:43 peter
  2267. * tvarsym.varregable added, split vo_regable from varoptions
  2268. Revision 1.179 2004/10/06 19:26:50 jonas
  2269. * regvar fixes from Peter
  2270. Revision 1.178 2004/10/01 15:22:22 peter
  2271. * don't add stabs for register variables
  2272. Revision 1.177 2004/09/26 17:45:30 peter
  2273. * simple regvar support, not yet finished
  2274. Revision 1.176 2004/09/21 17:25:12 peter
  2275. * paraloc branch merged
  2276. Revision 1.175.4.1 2004/08/31 20:43:06 peter
  2277. * paraloc patch
  2278. Revision 1.175 2004/08/15 12:06:03 jonas
  2279. * add cprefix to procedures which are autoamtically marked as external in
  2280. macpas mode
  2281. Revision 1.174 2004/06/20 08:55:30 florian
  2282. * logs truncated
  2283. Revision 1.173 2004/06/16 20:07:09 florian
  2284. * dwarf branch merged
  2285. Revision 1.172 2004/05/22 23:32:52 peter
  2286. quote all low ascii chars in stabs
  2287. Revision 1.171 2004/05/11 22:52:48 olle
  2288. * Moved import_implicit_external to symsym
  2289. Revision 1.170 2004/05/11 18:29:41 olle
  2290. + mode macpas: support for implicit external
  2291. Revision 1.169.2.3 2004/05/01 16:02:09 peter
  2292. * POINTER_SIZE replaced with sizeof(aint)
  2293. * aint,aword,tconst*int moved to globtype
  2294. }