symsym.pas 70 KB

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