symsym.pas 75 KB

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