symsym.pas 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229
  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,constexp,
  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,
  46. nonlocal : boolean;
  47. { points to the matching node, only valid resultdef pass is run and
  48. the goto<->label relation in the node tree is created, should
  49. be a tnode }
  50. code : pointer;
  51. { points to the jump buffer }
  52. jumpbuf : tstoredsym;
  53. { when the label is defined in an asm block, this points to the
  54. generated asmlabel }
  55. asmblocklabel : tasmlabel;
  56. constructor create(const n : string);
  57. constructor ppuload(ppufile:tcompilerppufile);
  58. procedure ppuwrite(ppufile:tcompilerppufile);override;
  59. function mangledname:TSymStr;override;
  60. end;
  61. tunitsym = class(Tstoredsym)
  62. module : tobject; { tmodule }
  63. constructor create(const n : string;amodule : tobject);
  64. constructor ppuload(ppufile:tcompilerppufile);
  65. destructor destroy;override;
  66. procedure ppuwrite(ppufile:tcompilerppufile);override;
  67. end;
  68. terrorsym = class(Tsym)
  69. constructor create;
  70. end;
  71. { tprocsym }
  72. tprocsym = class(tstoredsym)
  73. protected
  74. FProcdefList : TFPObjectList;
  75. FProcdefDerefList : TFPList;
  76. public
  77. constructor create(const n : string);
  78. constructor ppuload(ppufile:tcompilerppufile);
  79. destructor destroy;override;
  80. { writes all declarations except the specified one }
  81. procedure write_parameter_lists(skipdef:tprocdef);
  82. { tests, if all procedures definitions are defined and not }
  83. { only forward }
  84. procedure check_forward;
  85. procedure ppuwrite(ppufile:tcompilerppufile);override;
  86. procedure buildderef;override;
  87. procedure deref;override;
  88. function find_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  89. function find_bytype_parameterless(pt:Tproctypeoption):Tprocdef;
  90. function find_procdef_bypara(para:TFPObjectList;retdef:tdef;cpoptions:tcompare_paras_options):Tprocdef;
  91. function find_procdef_bytype_and_para(pt:Tproctypeoption;para:TFPObjectList;retdef:tdef;cpoptions:tcompare_paras_options):Tprocdef;
  92. function find_procdef_byoptions(ops:tprocoptions): Tprocdef;
  93. function find_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  94. function find_procdef_assignment_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
  95. function find_procdef_enumerator_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
  96. property ProcdefList:TFPObjectList read FProcdefList;
  97. end;
  98. ttypesym = class(Tstoredsym)
  99. typedef : tdef;
  100. typedefderef : tderef;
  101. fprettyname : ansistring;
  102. constructor create(const n : string;def:tdef);
  103. constructor ppuload(ppufile:tcompilerppufile);
  104. procedure ppuwrite(ppufile:tcompilerppufile);override;
  105. procedure buildderef;override;
  106. procedure deref;override;
  107. function prettyname : string;override;
  108. end;
  109. tabstractvarsym = class(tstoredsym)
  110. varoptions : tvaroptions;
  111. notifications : Tlinkedlist;
  112. varspez : tvarspez; { sets the type of access }
  113. varregable : tvarregable;
  114. varstate : tvarstate;
  115. { Has the address of this variable potentially escaped the }
  116. { block in which is was declared? }
  117. { could also be part of tabstractnormalvarsym, but there's }
  118. { one byte left here till the next 4 byte alignment }
  119. addr_taken : boolean;
  120. constructor create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  121. constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  122. destructor destroy;override;
  123. procedure ppuwrite(ppufile:tcompilerppufile);override;
  124. procedure buildderef;override;
  125. procedure deref;override;
  126. function getsize : asizeint;
  127. function getpackedbitsize : longint;
  128. function is_regvar(refpara: boolean):boolean;
  129. procedure trigger_notifications(what:Tnotification_flag);
  130. function register_notification(flags:Tnotification_flags;
  131. callback:Tnotification_callback):cardinal;
  132. procedure unregister_notification(id:cardinal);
  133. private
  134. _vardef : tdef;
  135. vardefderef : tderef;
  136. procedure setvardef(def:tdef);
  137. public
  138. property vardef: tdef read _vardef write setvardef;
  139. end;
  140. tfieldvarsym = class(tabstractvarsym)
  141. fieldoffset : asizeint; { offset in record/object }
  142. externalname : pshortstring;
  143. {$ifdef symansistr}
  144. cachedmangledname: TSymStr; { mangled name for ObjC or Java }
  145. {$else symansistr}
  146. cachedmangledname: pshortstring; { mangled name for ObjC or Java }
  147. {$endif symansistr}
  148. constructor create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  149. constructor ppuload(ppufile:tcompilerppufile);
  150. procedure ppuwrite(ppufile:tcompilerppufile);override;
  151. procedure set_externalname(const s:string);
  152. function mangledname:TSymStr;override;
  153. destructor destroy;override;
  154. end;
  155. tabstractnormalvarsym = class(tabstractvarsym)
  156. defaultconstsym : tsym;
  157. defaultconstsymderef : tderef;
  158. localloc : TLocation; { register/reference for local var }
  159. initialloc : TLocation; { initial location so it can still be initialized later after the location was changed by SSA }
  160. inparentfpstruct : boolean; { migrated to a parentfpstruct because of nested access (not written to ppu, because not important and would change interface crc) }
  161. constructor create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  162. constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  163. procedure ppuwrite(ppufile:tcompilerppufile);override;
  164. procedure buildderef;override;
  165. procedure deref;override;
  166. end;
  167. tlocalvarsym = class(tabstractnormalvarsym)
  168. constructor create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  169. constructor ppuload(ppufile:tcompilerppufile);
  170. procedure ppuwrite(ppufile:tcompilerppufile);override;
  171. end;
  172. tparavarsym = class(tabstractnormalvarsym)
  173. paraloc : array[tcallercallee] of TCGPara;
  174. paranr : word; { position of this parameter }
  175. { in MacPas mode, "univ" parameters mean that type checking should
  176. be disabled, except that the size of the passed parameter must
  177. match the size of the formal parameter }
  178. univpara : boolean;
  179. {$ifdef EXTDEBUG}
  180. eqval : tequaltype;
  181. {$endif EXTDEBUG}
  182. constructor create(const n : string;nr:word;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  183. constructor ppuload(ppufile:tcompilerppufile);
  184. destructor destroy;override;
  185. procedure ppuwrite(ppufile:tcompilerppufile);override;
  186. end;
  187. tstaticvarsym = class(tabstractnormalvarsym)
  188. private
  189. {$ifdef symansistr}
  190. _mangledbasename,
  191. _mangledname : TSymStr;
  192. {$else symansistr}
  193. _mangledbasename,
  194. _mangledname : pshortstring;
  195. {$endif symansistr}
  196. public
  197. section : ansistring;
  198. constructor create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  199. constructor create_dll(const n : string;vsp:tvarspez;def:tdef);
  200. constructor create_C(const n: string; const mangled : TSymStr;vsp:tvarspez;def:tdef);
  201. constructor ppuload(ppufile:tcompilerppufile);
  202. destructor destroy;override;
  203. procedure ppuwrite(ppufile:tcompilerppufile);override;
  204. function mangledname:TSymStr;override;
  205. procedure set_mangledbasename(const s: TSymStr);
  206. procedure set_mangledname(const s:TSymStr);
  207. end;
  208. tabsolutevarsym = class(tabstractvarsym)
  209. public
  210. abstyp : absolutetyp;
  211. {$ifdef i386}
  212. absseg : boolean;
  213. {$endif i386}
  214. asmname : pshortstring;
  215. addroffset : aword;
  216. ref : tpropaccesslist;
  217. constructor create(const n : string;def:tdef);
  218. constructor create_ref(const n : string;def:tdef;_ref:tpropaccesslist);
  219. destructor destroy;override;
  220. constructor ppuload(ppufile:tcompilerppufile);
  221. procedure buildderef;override;
  222. procedure deref;override;
  223. function mangledname : TSymStr;override;
  224. procedure ppuwrite(ppufile:tcompilerppufile);override;
  225. end;
  226. tpropaccesslisttypes=(palt_none,palt_read,palt_write,palt_stored);
  227. tpropertysym = class(Tstoredsym)
  228. propoptions : tpropertyoptions;
  229. overriddenpropsym : tpropertysym;
  230. overriddenpropsymderef : tderef;
  231. propdef : tdef;
  232. propdefderef : tderef;
  233. indexdef : tdef;
  234. indexdefderef : tderef;
  235. index,
  236. default : longint;
  237. dispid : longint;
  238. propaccesslist: array[tpropaccesslisttypes] of tpropaccesslist;
  239. constructor create(const n : string);
  240. destructor destroy;override;
  241. constructor ppuload(ppufile:tcompilerppufile);
  242. function getsize : asizeint;
  243. procedure ppuwrite(ppufile:tcompilerppufile);override;
  244. procedure buildderef;override;
  245. procedure deref;override;
  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. constdef : tdef;
  255. constdefderef : tderef;
  256. consttyp : tconsttyp;
  257. value : tconstvalue;
  258. constructor create_ord(const n : string;t : tconsttyp;v : tconstexprint;def:tdef);
  259. constructor create_ordptr(const n : string;t : tconsttyp;v : tconstptruint;def:tdef);
  260. constructor create_ptr(const n : string;t : tconsttyp;v : pointer;def:tdef);
  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. constructor create(const n : string;def : tenumdef;v : longint);
  274. constructor ppuload(ppufile:tcompilerppufile);
  275. procedure ppuwrite(ppufile:tcompilerppufile);override;
  276. procedure buildderef;override;
  277. procedure deref;override;
  278. end;
  279. tsyssym = class(Tstoredsym)
  280. number : longint;
  281. constructor create(const n : string;l : longint);
  282. constructor ppuload(ppufile:tcompilerppufile);
  283. destructor destroy;override;
  284. procedure ppuwrite(ppufile:tcompilerppufile);override;
  285. end;
  286. const
  287. maxmacrolen=16*1024;
  288. type
  289. pmacrobuffer = ^tmacrobuffer;
  290. tmacrobuffer = array[0..maxmacrolen-1] of char;
  291. tmacro = class(tstoredsym)
  292. {Normally true, but false when a previously defined macro is undef-ed}
  293. defined : boolean;
  294. {True if this is a mac style compiler variable, in which case no macro
  295. substitutions shall be done.}
  296. is_compiler_var : boolean;
  297. {Whether the macro was used. NOTE: A use of a macro which was never defined}
  298. {e. g. an IFDEF which returns false, will not be registered as used,}
  299. {since there is no place to register its use. }
  300. is_used : boolean;
  301. buftext : pchar;
  302. buflen : longint;
  303. constructor create(const n : string);
  304. constructor ppuload(ppufile:tcompilerppufile);
  305. procedure ppuwrite(ppufile:tcompilerppufile);override;
  306. destructor destroy;override;
  307. function GetCopy:tmacro;
  308. end;
  309. var
  310. generrorsym : tsym;
  311. { generate internal static field name based on regular field name }
  312. function internal_static_field_name(const fieldname: TSymStr): TSymStr;
  313. procedure check_hints(const srsym: tsym; const symoptions: tsymoptions; const deprecatedmsg : pshortstring);
  314. implementation
  315. uses
  316. { global }
  317. verbose,
  318. { target }
  319. systems,
  320. { symtable }
  321. defutil,symtable,
  322. {$ifdef jvm}
  323. jvmdef,
  324. {$endif}
  325. fmodule,
  326. { tree }
  327. node,
  328. { aasm }
  329. aasmtai,aasmdata,
  330. { codegen }
  331. paramgr,
  332. procinfo
  333. ;
  334. {****************************************************************************
  335. Helpers
  336. ****************************************************************************}
  337. function internal_static_field_name(const fieldname: TSymStr): TSymStr;
  338. begin
  339. result:='$_static_'+fieldname;
  340. end;
  341. procedure check_hints(const srsym: tsym; const symoptions: tsymoptions; const deprecatedmsg : pshortstring);
  342. begin
  343. if not assigned(srsym) then
  344. internalerror(200602051);
  345. if sp_hint_deprecated in symoptions then
  346. if (sp_has_deprecated_msg in symoptions) and (deprecatedmsg <> nil) then
  347. Message2(sym_w_deprecated_symbol_with_msg,srsym.realname,deprecatedmsg^)
  348. else
  349. Message1(sym_w_deprecated_symbol,srsym.realname);
  350. if sp_hint_experimental in symoptions then
  351. Message1(sym_w_experimental_symbol,srsym.realname);
  352. if sp_hint_platform in symoptions then
  353. Message1(sym_w_non_portable_symbol,srsym.realname);
  354. if sp_hint_library in symoptions then
  355. Message1(sym_w_library_symbol,srsym.realname);
  356. if sp_hint_unimplemented in symoptions then
  357. Message1(sym_w_non_implemented_symbol,srsym.realname);
  358. end;
  359. {****************************************************************************
  360. TSYM (base for all symtypes)
  361. ****************************************************************************}
  362. constructor tstoredsym.create(st:tsymtyp;const n : string);
  363. begin
  364. inherited create(st,n);
  365. { Register in current_module }
  366. if assigned(current_module) then
  367. begin
  368. current_module.symlist.Add(self);
  369. SymId:=current_module.symlist.Count-1;
  370. end;
  371. end;
  372. constructor tstoredsym.ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  373. begin
  374. SymId:=ppufile.getlongint;
  375. inherited Create(st,ppufile.getstring);
  376. { Register symbol }
  377. current_module.symlist[SymId]:=self;
  378. ppufile.getposinfo(fileinfo);
  379. visibility:=tvisibility(ppufile.getbyte);
  380. ppufile.getsmallset(symoptions);
  381. if sp_has_deprecated_msg in symoptions then
  382. deprecatedmsg:=stringdup(ppufile.getstring)
  383. else
  384. deprecatedmsg:=nil;
  385. end;
  386. procedure tstoredsym.ppuwrite(ppufile:tcompilerppufile);
  387. begin
  388. ppufile.putlongint(SymId);
  389. ppufile.putstring(realname);
  390. ppufile.putposinfo(fileinfo);
  391. ppufile.putbyte(byte(visibility));
  392. ppufile.putsmallset(symoptions);
  393. if sp_has_deprecated_msg in symoptions then
  394. ppufile.putstring(deprecatedmsg^);
  395. end;
  396. destructor tstoredsym.destroy;
  397. begin
  398. inherited destroy;
  399. end;
  400. {****************************************************************************
  401. TLABELSYM
  402. ****************************************************************************}
  403. constructor tlabelsym.create(const n : string);
  404. begin
  405. inherited create(labelsym,n);
  406. used:=false;
  407. defined:=false;
  408. nonlocal:=false;
  409. code:=nil;
  410. end;
  411. constructor tlabelsym.ppuload(ppufile:tcompilerppufile);
  412. begin
  413. inherited ppuload(labelsym,ppufile);
  414. code:=nil;
  415. used:=false;
  416. nonlocal:=false;
  417. defined:=true;
  418. end;
  419. procedure tlabelsym.ppuwrite(ppufile:tcompilerppufile);
  420. begin
  421. if owner.symtabletype=globalsymtable then
  422. Message(sym_e_ill_label_decl)
  423. else
  424. begin
  425. inherited ppuwrite(ppufile);
  426. ppufile.writeentry(iblabelsym);
  427. end;
  428. end;
  429. function tlabelsym.mangledname:TSymStr;
  430. begin
  431. if not(defined) then
  432. begin
  433. defined:=true;
  434. if nonlocal then
  435. current_asmdata.getglobaljumplabel(asmblocklabel)
  436. else
  437. current_asmdata.getjumplabel(asmblocklabel);
  438. end;
  439. result:=asmblocklabel.name;
  440. end;
  441. {****************************************************************************
  442. TUNITSYM
  443. ****************************************************************************}
  444. constructor tunitsym.create(const n : string;amodule : tobject);
  445. begin
  446. inherited create(unitsym,n);
  447. module:=amodule;
  448. end;
  449. constructor tunitsym.ppuload(ppufile:tcompilerppufile);
  450. begin
  451. inherited ppuload(unitsym,ppufile);
  452. module:=nil;
  453. end;
  454. destructor tunitsym.destroy;
  455. begin
  456. inherited destroy;
  457. end;
  458. procedure tunitsym.ppuwrite(ppufile:tcompilerppufile);
  459. begin
  460. inherited ppuwrite(ppufile);
  461. ppufile.writeentry(ibunitsym);
  462. end;
  463. {****************************************************************************
  464. TPROCSYM
  465. ****************************************************************************}
  466. constructor tprocsym.create(const n : string);
  467. begin
  468. inherited create(procsym,n);
  469. FProcdefList:=TFPObjectList.Create(false);
  470. FProcdefderefList:=nil;
  471. { the tprocdef have their own symoptions, make the procsym
  472. always visible }
  473. visibility:=vis_public;
  474. end;
  475. constructor tprocsym.ppuload(ppufile:tcompilerppufile);
  476. var
  477. pdderef : tderef;
  478. i,
  479. pdcnt : longint;
  480. begin
  481. inherited ppuload(procsym,ppufile);
  482. FProcdefList:=TFPObjectList.Create(false);
  483. FProcdefDerefList:=TFPList.Create;
  484. pdcnt:=ppufile.getword;
  485. for i:=1 to pdcnt do
  486. begin
  487. ppufile.getderef(pdderef);
  488. FProcdefDerefList.Add(Pointer(PtrInt(pdderef.dataidx)));
  489. end;
  490. end;
  491. destructor tprocsym.destroy;
  492. begin
  493. FProcdefList.Free;
  494. if assigned(FProcdefDerefList) then
  495. FProcdefDerefList.Free;
  496. inherited destroy;
  497. end;
  498. procedure tprocsym.ppuwrite(ppufile:tcompilerppufile);
  499. var
  500. i : longint;
  501. d : tderef;
  502. begin
  503. inherited ppuwrite(ppufile);
  504. ppufile.putword(FProcdefDerefList.Count);
  505. for i:=0 to FProcdefDerefList.Count-1 do
  506. begin
  507. d.dataidx:=PtrInt(FProcdefDerefList[i]);
  508. ppufile.putderef(d);
  509. end;
  510. ppufile.writeentry(ibprocsym);
  511. end;
  512. procedure tprocsym.write_parameter_lists(skipdef:tprocdef);
  513. var
  514. i : longint;
  515. pd : tprocdef;
  516. begin
  517. for i:=0 to ProcdefList.Count-1 do
  518. begin
  519. pd:=tprocdef(ProcdefList[i]);
  520. if pd<>skipdef then
  521. MessagePos1(pd.fileinfo,sym_h_param_list,pd.fullprocname(false));
  522. end;
  523. end;
  524. procedure tprocsym.check_forward;
  525. var
  526. i : longint;
  527. pd : tprocdef;
  528. begin
  529. for i:=0 to ProcdefList.Count-1 do
  530. begin
  531. pd:=tprocdef(ProcdefList[i]);
  532. if (pd.owner=owner) and (pd.forwarddef) then
  533. begin
  534. { For mode macpas. Make implicit externals (procedures declared in the interface
  535. section which do not have a counterpart in the implementation)
  536. to be an imported procedure }
  537. if (m_mac in current_settings.modeswitches) and
  538. (pd.interfacedef) then
  539. begin
  540. pd.setmangledname(target_info.CPrefix+tprocdef(pd).procsym.realname);
  541. if (not current_module.interface_only) then
  542. MessagePos1(pd.fileinfo,sym_w_forward_not_resolved,pd.fullprocname(false));
  543. end
  544. else
  545. begin
  546. MessagePos1(pd.fileinfo,sym_e_forward_not_resolved,pd.fullprocname(false));
  547. end;
  548. { Turn further error messages off }
  549. pd.forwarddef:=false;
  550. end;
  551. end;
  552. end;
  553. procedure tprocsym.buildderef;
  554. var
  555. i : longint;
  556. pd : tprocdef;
  557. d : tderef;
  558. begin
  559. if not assigned(FProcdefDerefList) then
  560. FProcdefDerefList:=TFPList.Create
  561. else
  562. FProcdefDerefList.Clear;
  563. for i:=0 to ProcdefList.Count-1 do
  564. begin
  565. pd:=tprocdef(ProcdefList[i]);
  566. { only write the proc definitions that belong
  567. to this procsym and are in the global symtable }
  568. if pd.owner=owner then
  569. begin
  570. d.build(pd);
  571. FProcdefDerefList.Add(Pointer(PtrInt(d.dataidx)));
  572. end;
  573. end;
  574. end;
  575. procedure tprocsym.deref;
  576. var
  577. i : longint;
  578. pd : tprocdef;
  579. d : tderef;
  580. begin
  581. { Clear all procdefs }
  582. ProcdefList.Clear;
  583. if not assigned(FProcdefDerefList) then
  584. internalerror(200611031);
  585. for i:=0 to FProcdefDerefList.Count-1 do
  586. begin
  587. d.dataidx:=PtrInt(FProcdefDerefList[i]);
  588. pd:=tprocdef(d.resolve);
  589. ProcdefList.Add(pd);
  590. end;
  591. end;
  592. function Tprocsym.Find_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  593. var
  594. i : longint;
  595. pd : tprocdef;
  596. begin
  597. result:=nil;
  598. for i:=0 to ProcdefList.Count-1 do
  599. begin
  600. pd:=tprocdef(ProcdefList[i]);
  601. if pd.proctypeoption=pt then
  602. begin
  603. result:=pd;
  604. exit;
  605. end;
  606. end;
  607. end;
  608. function tprocsym.find_bytype_parameterless(pt: Tproctypeoption): Tprocdef;
  609. var
  610. i,j : longint;
  611. pd : tprocdef;
  612. found : boolean;
  613. begin
  614. result:=nil;
  615. for i:=0 to ProcdefList.Count-1 do
  616. begin
  617. pd:=tprocdef(ProcdefList[i]);
  618. if (pd.proctypeoption=pt) then
  619. begin
  620. found:=true;
  621. for j:=0 to pd.paras.count-1 do
  622. begin
  623. if not(vo_is_hidden_para in tparavarsym(pd.paras[j]).varoptions) then
  624. begin
  625. found:=false;
  626. break;
  627. end;
  628. end;
  629. if found then
  630. begin
  631. result:=pd;
  632. exit;
  633. end;
  634. end;
  635. end;
  636. end;
  637. function check_procdef_paras(pd:tprocdef;para:TFPObjectList;retdef:tdef;
  638. cpoptions:tcompare_paras_options): tprocdef;
  639. var
  640. eq: tequaltype;
  641. begin
  642. result:=nil;
  643. if assigned(retdef) then
  644. eq:=compare_defs(retdef,pd.returndef,nothingn)
  645. else
  646. eq:=te_equal;
  647. if (eq>=te_equal) or
  648. ((cpo_allowconvert in cpoptions) and (eq>te_incompatible)) then
  649. begin
  650. eq:=compare_paras(para,pd.paras,cp_value_equal_const,cpoptions);
  651. if (eq>=te_equal) or
  652. ((cpo_allowconvert in cpoptions) and (eq>te_incompatible)) then
  653. begin
  654. result:=pd;
  655. exit;
  656. end;
  657. end;
  658. end;
  659. function Tprocsym.Find_procdef_bypara(para:TFPObjectList;retdef:tdef;
  660. cpoptions:tcompare_paras_options):Tprocdef;
  661. var
  662. i : longint;
  663. pd : tprocdef;
  664. begin
  665. result:=nil;
  666. for i:=0 to ProcdefList.Count-1 do
  667. begin
  668. pd:=tprocdef(ProcdefList[i]);
  669. result:=check_procdef_paras(pd,para,retdef,cpoptions);
  670. if assigned(result) then
  671. exit;
  672. end;
  673. end;
  674. function Tprocsym.find_procdef_bytype_and_para(pt:Tproctypeoption;
  675. para:TFPObjectList;retdef:tdef;cpoptions:tcompare_paras_options):Tprocdef;
  676. var
  677. i : longint;
  678. pd : tprocdef;
  679. begin
  680. result:=nil;
  681. for i:=0 to ProcdefList.Count-1 do
  682. begin
  683. pd:=tprocdef(ProcdefList[i]);
  684. if pd.proctypeoption=pt then
  685. begin
  686. result:=check_procdef_paras(pd,para,retdef,cpoptions);
  687. if assigned(result) then
  688. exit;
  689. end;
  690. end;
  691. end;
  692. function tprocsym.find_procdef_byoptions(ops: tprocoptions): Tprocdef;
  693. var
  694. i : longint;
  695. pd : tprocdef;
  696. begin
  697. result:=nil;
  698. for i:=0 to ProcdefList.Count-1 do
  699. begin
  700. pd:=tprocdef(ProcdefList[i]);
  701. if ops * pd.procoptions = ops then
  702. begin
  703. result:=pd;
  704. exit;
  705. end;
  706. end;
  707. end;
  708. function Tprocsym.Find_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  709. var
  710. i : longint;
  711. bestpd,
  712. pd : tprocdef;
  713. eq,besteq : tequaltype;
  714. begin
  715. { This function will return the pprocdef of pprocsym that
  716. is the best match for procvardef. When there are multiple
  717. matches it returns nil.}
  718. result:=nil;
  719. bestpd:=nil;
  720. besteq:=te_incompatible;
  721. for i:=0 to ProcdefList.Count-1 do
  722. begin
  723. pd:=tprocdef(ProcdefList[i]);
  724. eq:=proc_to_procvar_equal(pd,d,false);
  725. if eq>=te_convert_l1 then
  726. begin
  727. { multiple procvars with the same equal level }
  728. if assigned(bestpd) and
  729. (besteq=eq) then
  730. exit;
  731. if eq>besteq then
  732. begin
  733. besteq:=eq;
  734. bestpd:=pd;
  735. end;
  736. end;
  737. end;
  738. result:=bestpd;
  739. end;
  740. function Tprocsym.Find_procdef_assignment_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
  741. var
  742. paraidx, realparamcount,
  743. i, j : longint;
  744. bestpd,
  745. hpd,
  746. pd : tprocdef;
  747. convtyp : tconverttype;
  748. eq : tequaltype;
  749. begin
  750. { This function will return the pprocdef of pprocsym that
  751. is the best match for fromdef and todef. }
  752. result:=nil;
  753. bestpd:=nil;
  754. besteq:=te_incompatible;
  755. for i:=0 to ProcdefList.Count-1 do
  756. begin
  757. pd:=tprocdef(ProcdefList[i]);
  758. if (pd.owner.symtabletype=staticsymtable) and not pd.owner.iscurrentunit then
  759. continue;
  760. if (equal_defs(todef,pd.returndef) or
  761. { shortstrings of different lengths are ok as result }
  762. (is_shortstring(todef) and is_shortstring(pd.returndef))) and
  763. { the result type must be always really equal and not an alias,
  764. if you mess with this code, check tw4093 }
  765. ((todef=pd.returndef) or
  766. (
  767. not(df_unique in todef.defoptions) and
  768. not(df_unique in pd.returndef.defoptions)
  769. )
  770. ) then
  771. begin
  772. paraidx:=0;
  773. { ignore vs_hidden parameters }
  774. while (paraidx<pd.paras.count) and
  775. assigned(pd.paras[paraidx]) and
  776. (vo_is_hidden_para in tparavarsym(pd.paras[paraidx]).varoptions) do
  777. inc(paraidx);
  778. realparamcount:=0;
  779. for j := 0 to pd.paras.Count-1 do
  780. if assigned(pd.paras[j]) and not (vo_is_hidden_para in tparavarsym(pd.paras[j]).varoptions) then
  781. inc(realparamcount);
  782. if (paraidx<pd.paras.count) and
  783. assigned(pd.paras[paraidx]) and
  784. (realparamcount = 1) then
  785. begin
  786. eq:=compare_defs_ext(fromdef,tparavarsym(pd.paras[paraidx]).vardef,nothingn,convtyp,hpd,[]);
  787. { alias? if yes, only l1 choice,
  788. if you mess with this code, check tw4093 }
  789. if (eq=te_exact) and
  790. (fromdef<>tparavarsym(pd.paras[paraidx]).vardef) and
  791. ((df_unique in fromdef.defoptions) or
  792. (df_unique in tparavarsym(pd.paras[paraidx]).vardef.defoptions)) then
  793. eq:=te_convert_l1;
  794. if eq=te_exact then
  795. begin
  796. besteq:=eq;
  797. result:=pd;
  798. exit;
  799. end;
  800. if eq>besteq then
  801. begin
  802. bestpd:=pd;
  803. besteq:=eq;
  804. end;
  805. end;
  806. end;
  807. end;
  808. result:=bestpd;
  809. end;
  810. function Tprocsym.find_procdef_enumerator_operator(fromdef,todef:tdef;var besteq:tequaltype):Tprocdef;
  811. var
  812. paraidx, realparamcount,
  813. i, j : longint;
  814. bestpd,
  815. hpd,
  816. pd : tprocdef;
  817. current : tpropertysym;
  818. convtyp : tconverttype;
  819. eq : tequaltype;
  820. begin
  821. { This function will return the pprocdef of pprocsym that
  822. is the best match for fromdef and todef. }
  823. result:=nil;
  824. bestpd:=nil;
  825. besteq:=te_incompatible;
  826. for i:=0 to ProcdefList.Count-1 do
  827. begin
  828. pd:=tprocdef(ProcdefList[i]);
  829. if (pd.owner.symtabletype=staticsymtable) and not pd.owner.iscurrentunit then
  830. continue;
  831. if not (is_class_or_interface_or_object(pd.returndef) or is_record(pd.returndef)) then
  832. continue;
  833. current := tpropertysym(tabstractrecorddef(pd.returndef).search_enumerator_current);
  834. if (current = nil) then
  835. continue;
  836. // compare current result def with the todef
  837. if (equal_defs(todef, current.propdef) or
  838. { shortstrings of different lengths are ok as result }
  839. (is_shortstring(todef) and is_shortstring(current.propdef))) and
  840. { the result type must be always really equal and not an alias,
  841. if you mess with this code, check tw4093 }
  842. ((todef=current.propdef) or
  843. (
  844. not(df_unique in todef.defoptions) and
  845. not(df_unique in current.propdef.defoptions)
  846. )
  847. ) then
  848. begin
  849. paraidx:=0;
  850. { ignore vs_hidden parameters }
  851. while (paraidx<pd.paras.count) and
  852. assigned(pd.paras[paraidx]) and
  853. (vo_is_hidden_para in tparavarsym(pd.paras[paraidx]).varoptions) do
  854. inc(paraidx);
  855. realparamcount:=0;
  856. for j := 0 to pd.paras.Count-1 do
  857. if assigned(pd.paras[j]) and not (vo_is_hidden_para in tparavarsym(pd.paras[j]).varoptions) then
  858. inc(realparamcount);
  859. if (paraidx<pd.paras.count) and
  860. assigned(pd.paras[paraidx]) and
  861. (realparamcount = 1) then
  862. begin
  863. eq:=compare_defs_ext(fromdef,tparavarsym(pd.paras[paraidx]).vardef,nothingn,convtyp,hpd,[]);
  864. { alias? if yes, only l1 choice,
  865. if you mess with this code, check tw4093 }
  866. if (eq=te_exact) and
  867. (fromdef<>tparavarsym(pd.paras[paraidx]).vardef) and
  868. ((df_unique in fromdef.defoptions) or
  869. (df_unique in tparavarsym(pd.paras[paraidx]).vardef.defoptions)) then
  870. eq:=te_convert_l1;
  871. if eq=te_exact then
  872. begin
  873. besteq:=eq;
  874. result:=pd;
  875. exit;
  876. end;
  877. if eq>besteq then
  878. begin
  879. bestpd:=pd;
  880. besteq:=eq;
  881. end;
  882. end;
  883. end;
  884. end;
  885. result:=bestpd;
  886. end;
  887. {****************************************************************************
  888. TERRORSYM
  889. ****************************************************************************}
  890. constructor terrorsym.create;
  891. begin
  892. inherited create(errorsym,'');
  893. end;
  894. {****************************************************************************
  895. TPROPERTYSYM
  896. ****************************************************************************}
  897. constructor tpropertysym.create(const n : string);
  898. var
  899. pap : tpropaccesslisttypes;
  900. begin
  901. inherited create(propertysym,n);
  902. propoptions:=[];
  903. index:=0;
  904. default:=0;
  905. propdef:=nil;
  906. indexdef:=nil;
  907. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  908. propaccesslist[pap]:=tpropaccesslist.create;
  909. end;
  910. constructor tpropertysym.ppuload(ppufile:tcompilerppufile);
  911. var
  912. pap : tpropaccesslisttypes;
  913. begin
  914. inherited ppuload(propertysym,ppufile);
  915. ppufile.getsmallset(propoptions);
  916. ppufile.getderef(overriddenpropsymderef);
  917. ppufile.getderef(propdefderef);
  918. index:=ppufile.getlongint;
  919. default:=ppufile.getlongint;
  920. ppufile.getderef(indexdefderef);
  921. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  922. propaccesslist[pap]:=ppufile.getpropaccesslist;
  923. end;
  924. destructor tpropertysym.destroy;
  925. var
  926. pap : tpropaccesslisttypes;
  927. begin
  928. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  929. propaccesslist[pap].free;
  930. inherited destroy;
  931. end;
  932. procedure tpropertysym.buildderef;
  933. var
  934. pap : tpropaccesslisttypes;
  935. begin
  936. overriddenpropsymderef.build(overriddenpropsym);
  937. propdefderef.build(propdef);
  938. indexdefderef.build(indexdef);
  939. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  940. propaccesslist[pap].buildderef;
  941. end;
  942. procedure tpropertysym.deref;
  943. var
  944. pap : tpropaccesslisttypes;
  945. begin
  946. overriddenpropsym:=tpropertysym(overriddenpropsymderef.resolve);
  947. indexdef:=tdef(indexdefderef.resolve);
  948. propdef:=tdef(propdefderef.resolve);
  949. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  950. propaccesslist[pap].resolve;
  951. end;
  952. function tpropertysym.getsize : asizeint;
  953. begin
  954. getsize:=0;
  955. end;
  956. procedure tpropertysym.ppuwrite(ppufile:tcompilerppufile);
  957. var
  958. pap : tpropaccesslisttypes;
  959. begin
  960. inherited ppuwrite(ppufile);
  961. ppufile.putsmallset(propoptions);
  962. ppufile.putderef(overriddenpropsymderef);
  963. ppufile.putderef(propdefderef);
  964. ppufile.putlongint(index);
  965. ppufile.putlongint(default);
  966. ppufile.putderef(indexdefderef);
  967. for pap:=low(tpropaccesslisttypes) to high(tpropaccesslisttypes) do
  968. ppufile.putpropaccesslist(propaccesslist[pap]);
  969. ppufile.writeentry(ibpropertysym);
  970. end;
  971. {****************************************************************************
  972. TABSTRACTVARSYM
  973. ****************************************************************************}
  974. constructor tabstractvarsym.create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  975. begin
  976. inherited create(st,n);
  977. vardef:=def;
  978. varspez:=vsp;
  979. varstate:=vs_declared;
  980. varoptions:=vopts;
  981. end;
  982. constructor tabstractvarsym.ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  983. begin
  984. inherited ppuload(st,ppufile);
  985. varstate:=vs_readwritten;
  986. varspez:=tvarspez(ppufile.getbyte);
  987. varregable:=tvarregable(ppufile.getbyte);
  988. addr_taken:=boolean(ppufile.getbyte);
  989. ppufile.getderef(vardefderef);
  990. ppufile.getsmallset(varoptions);
  991. end;
  992. destructor tabstractvarsym.destroy;
  993. begin
  994. if assigned(notifications) then
  995. notifications.destroy;
  996. inherited destroy;
  997. end;
  998. procedure tabstractvarsym.buildderef;
  999. begin
  1000. vardefderef.build(vardef);
  1001. end;
  1002. procedure tabstractvarsym.deref;
  1003. var
  1004. oldvarregable: tvarregable;
  1005. begin
  1006. { setting the vardef also updates varregable. We just loaded this }
  1007. { value from a ppu, so it must not be changed (e.g. tw7817a.pp/ }
  1008. { tw7817b.pp: the address is taken of a local variable in an }
  1009. { inlined procedure -> must remain non-regable when inlining) }
  1010. oldvarregable:=varregable;
  1011. vardef:=tdef(vardefderef.resolve);
  1012. varregable:=oldvarregable;
  1013. end;
  1014. procedure tabstractvarsym.ppuwrite(ppufile:tcompilerppufile);
  1015. var
  1016. oldintfcrc : boolean;
  1017. begin
  1018. inherited ppuwrite(ppufile);
  1019. ppufile.putbyte(byte(varspez));
  1020. oldintfcrc:=ppufile.do_crc;
  1021. ppufile.do_crc:=false;
  1022. ppufile.putbyte(byte(varregable));
  1023. ppufile.putbyte(byte(addr_taken));
  1024. ppufile.do_crc:=oldintfcrc;
  1025. ppufile.putderef(vardefderef);
  1026. ppufile.putsmallset(varoptions);
  1027. end;
  1028. function tabstractvarsym.getsize : asizeint;
  1029. begin
  1030. if assigned(vardef) and
  1031. ((vardef.typ<>arraydef) or
  1032. is_dynamic_array(vardef) or
  1033. (tarraydef(vardef).highrange>=tarraydef(vardef).lowrange)) then
  1034. result:=vardef.size
  1035. else
  1036. result:=0;
  1037. end;
  1038. function tabstractvarsym.getpackedbitsize : longint;
  1039. begin
  1040. { bitpacking is only done for ordinals }
  1041. if not is_ordinal(vardef) then
  1042. internalerror(2006082010);
  1043. result:=vardef.packedbitsize;
  1044. end;
  1045. function tabstractvarsym.is_regvar(refpara: boolean):boolean;
  1046. begin
  1047. { Register variables are not allowed in the following cases:
  1048. - regvars are disabled
  1049. - exceptions are used (after an exception is raised the contents of the
  1050. registers is not valid anymore)
  1051. - it has a local copy
  1052. - the value needs to be in memory (i.e. reference counted) }
  1053. result:=(cs_opt_regvar in current_settings.optimizerswitches) and
  1054. not(pi_has_assembler_block in current_procinfo.flags) and
  1055. not(pi_uses_exceptions in current_procinfo.flags) and
  1056. not(pi_has_interproclabel in current_procinfo.flags) and
  1057. not(vo_has_local_copy in varoptions) and
  1058. ((refpara and
  1059. (varregable <> vr_none)) or
  1060. (not refpara and
  1061. not(varregable in [vr_none,vr_addr])))
  1062. {$if not defined(powerpc) and not defined(powerpc64)}
  1063. and ((vardef.typ <> recorddef) or
  1064. (varregable = vr_addr) or
  1065. not(varstate in [vs_written,vs_readwritten]));
  1066. {$endif}
  1067. end;
  1068. procedure tabstractvarsym.trigger_notifications(what:Tnotification_flag);
  1069. var n:Tnotification;
  1070. begin
  1071. if assigned(notifications) then
  1072. begin
  1073. n:=Tnotification(notifications.first);
  1074. while assigned(n) do
  1075. begin
  1076. if what in n.flags then
  1077. n.callback(what,self);
  1078. n:=Tnotification(n.next);
  1079. end;
  1080. end;
  1081. end;
  1082. function Tabstractvarsym.register_notification(flags:Tnotification_flags;callback:
  1083. Tnotification_callback):cardinal;
  1084. var n:Tnotification;
  1085. begin
  1086. if not assigned(notifications) then
  1087. notifications:=Tlinkedlist.create;
  1088. n:=Tnotification.create(flags,callback);
  1089. register_notification:=n.id;
  1090. notifications.concat(n);
  1091. end;
  1092. procedure Tabstractvarsym.unregister_notification(id:cardinal);
  1093. var n:Tnotification;
  1094. begin
  1095. if not assigned(notifications) then
  1096. internalerror(200212311)
  1097. else
  1098. begin
  1099. n:=Tnotification(notifications.first);
  1100. while assigned(n) do
  1101. begin
  1102. if n.id=id then
  1103. begin
  1104. notifications.remove(n);
  1105. n.destroy;
  1106. exit;
  1107. end;
  1108. n:=Tnotification(n.next);
  1109. end;
  1110. internalerror(200212311)
  1111. end;
  1112. end;
  1113. procedure tabstractvarsym.setvardef(def:tdef);
  1114. begin
  1115. _vardef := def;
  1116. { can we load the value into a register ? }
  1117. if not assigned(owner) or
  1118. (owner.symtabletype in [localsymtable,parasymtable]) or
  1119. (
  1120. (owner.symtabletype=staticsymtable) and
  1121. not(cs_create_pic in current_settings.moduleswitches)
  1122. ) then
  1123. begin
  1124. if tstoreddef(vardef).is_intregable then
  1125. varregable:=vr_intreg
  1126. else
  1127. { $warning TODO: no fpu regvar in staticsymtable yet, need initialization with 0 }
  1128. if {(
  1129. not assigned(owner) or
  1130. (owner.symtabletype<>staticsymtable)
  1131. ) and }
  1132. tstoreddef(vardef).is_fpuregable then
  1133. begin
  1134. if use_vectorfpu(vardef) then
  1135. varregable:=vr_mmreg
  1136. else
  1137. varregable:=vr_fpureg;
  1138. end;
  1139. end;
  1140. end;
  1141. {****************************************************************************
  1142. TFIELDVARSYM
  1143. ****************************************************************************}
  1144. constructor tfieldvarsym.create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1145. begin
  1146. inherited create(fieldvarsym,n,vsp,def,vopts);
  1147. fieldoffset:=-1;
  1148. end;
  1149. constructor tfieldvarsym.ppuload(ppufile:tcompilerppufile);
  1150. begin
  1151. inherited ppuload(fieldvarsym,ppufile);
  1152. fieldoffset:=ppufile.getaint;
  1153. if (vo_has_mangledname in varoptions) then
  1154. externalname:=stringdup(ppufile.getstring)
  1155. else
  1156. externalname:=nil;
  1157. end;
  1158. procedure tfieldvarsym.ppuwrite(ppufile:tcompilerppufile);
  1159. begin
  1160. inherited ppuwrite(ppufile);
  1161. ppufile.putaint(fieldoffset);
  1162. if (vo_has_mangledname in varoptions) then
  1163. ppufile.putstring(externalname^);
  1164. ppufile.writeentry(ibfieldvarsym);
  1165. end;
  1166. procedure tfieldvarsym.set_externalname(const s: string);
  1167. begin
  1168. { make sure it is recalculated }
  1169. {$ifdef symansistr}
  1170. cachedmangledname:='';
  1171. {$else symansistr}
  1172. stringdispose(cachedmangledname);
  1173. {$endif symansistr}
  1174. {$ifdef jvm}
  1175. if is_java_class_or_interface(tdef(owner.defowner)) then
  1176. begin
  1177. externalname:=stringdup(s);
  1178. include(varoptions,vo_has_mangledname);
  1179. end
  1180. else
  1181. {$endif jvm}
  1182. internalerror(2011031201);
  1183. end;
  1184. function tfieldvarsym.mangledname:TSymStr;
  1185. var
  1186. srsym : tsym;
  1187. srsymtable : tsymtable;
  1188. begin
  1189. {$ifdef jvm}
  1190. if is_java_class_or_interface(tdef(owner.defowner)) or
  1191. (tdef(owner.defowner).typ=recorddef) then
  1192. begin
  1193. if cachedmangledname<>'' then
  1194. result:=cachedmangledname
  1195. else
  1196. begin
  1197. result:=jvmmangledbasename(self,false);
  1198. jvmaddtypeownerprefix(owner,result);
  1199. cachedmangledname:=result;
  1200. end;
  1201. end
  1202. else
  1203. {$endif jvm}
  1204. if sp_static in symoptions then
  1205. begin
  1206. if searchsym(lower(owner.name^)+'_'+name,srsym,srsymtable) then
  1207. result:=srsym.mangledname
  1208. { when generating the debug info for the module in which the }
  1209. { symbol is defined, the localsymtable of that module is }
  1210. { already popped from the symtablestack }
  1211. else if searchsym_in_module(current_module,lower(owner.name^)+'_'+name,srsym,srsymtable) then
  1212. result:=srsym.mangledname
  1213. else
  1214. internalerror(2007012501);
  1215. end
  1216. else if is_objcclass(tdef(owner.defowner)) then
  1217. begin
  1218. {$ifdef symansistr}
  1219. if cachedmangledname<>'' then
  1220. result:=cachedmangledname
  1221. {$else symansistr}
  1222. if assigned(cachedmangledname) then
  1223. result:=cachedmangledname^
  1224. {$endif symansistr}
  1225. else
  1226. begin
  1227. result:=target_info.cprefix+'OBJC_IVAR_$_'+tobjectdef(owner.defowner).objextname^+'.'+RealName;
  1228. {$ifdef symansistr}
  1229. cachedmangledname:=result;
  1230. {$else symansistr}
  1231. cachedmangledname:=stringdup(result);
  1232. {$endif symansistr}
  1233. end;
  1234. end
  1235. else
  1236. result:=inherited mangledname;
  1237. end;
  1238. destructor tfieldvarsym.destroy;
  1239. begin
  1240. {$ifndef symansistr}
  1241. stringdispose(cachedmangledname);
  1242. {$endif symansistr}
  1243. inherited destroy;
  1244. end;
  1245. {****************************************************************************
  1246. TABSTRACTNORMALVARSYM
  1247. ****************************************************************************}
  1248. constructor tabstractnormalvarsym.create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1249. begin
  1250. inherited create(st,n,vsp,def,vopts);
  1251. fillchar(localloc,sizeof(localloc),0);
  1252. fillchar(initialloc,sizeof(initialloc),0);
  1253. defaultconstsym:=nil;
  1254. end;
  1255. constructor tabstractnormalvarsym.ppuload(st:tsymtyp;ppufile:tcompilerppufile);
  1256. begin
  1257. inherited ppuload(st,ppufile);
  1258. fillchar(localloc,sizeof(localloc),0);
  1259. fillchar(initialloc,sizeof(initialloc),0);
  1260. ppufile.getderef(defaultconstsymderef);
  1261. end;
  1262. procedure tabstractnormalvarsym.buildderef;
  1263. begin
  1264. inherited buildderef;
  1265. defaultconstsymderef.build(defaultconstsym);
  1266. end;
  1267. procedure tabstractnormalvarsym.deref;
  1268. begin
  1269. inherited deref;
  1270. defaultconstsym:=tsym(defaultconstsymderef.resolve);
  1271. end;
  1272. procedure tabstractnormalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1273. begin
  1274. inherited ppuwrite(ppufile);
  1275. ppufile.putderef(defaultconstsymderef);
  1276. end;
  1277. {****************************************************************************
  1278. Tstaticvarsym
  1279. ****************************************************************************}
  1280. constructor tstaticvarsym.create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1281. begin
  1282. inherited create(staticvarsym,n,vsp,def,vopts);
  1283. {$ifdef symansistr}
  1284. _mangledname:='';
  1285. {$else symansistr}
  1286. _mangledname:=nil;
  1287. {$endif symansistr}
  1288. end;
  1289. constructor tstaticvarsym.create_dll(const n : string;vsp:tvarspez;def:tdef);
  1290. begin
  1291. tstaticvarsym(self).create(n,vsp,def,[vo_is_dll_var]);
  1292. end;
  1293. constructor tstaticvarsym.create_C(const n: string; const mangled : TSymStr;vsp:tvarspez;def:tdef);
  1294. begin
  1295. tstaticvarsym(self).create(n,vsp,def,[]);
  1296. set_mangledname(mangled);
  1297. end;
  1298. constructor tstaticvarsym.ppuload(ppufile:tcompilerppufile);
  1299. begin
  1300. inherited ppuload(staticvarsym,ppufile);
  1301. {$ifdef symansistr}
  1302. if vo_has_mangledname in varoptions then
  1303. _mangledname:=ppufile.getansistring
  1304. else
  1305. _mangledname:='';
  1306. {$else symansistr}
  1307. if vo_has_mangledname in varoptions then
  1308. _mangledname:=stringdup(ppufile.getstring)
  1309. else
  1310. _mangledname:=nil;
  1311. if vo_has_section in varoptions then
  1312. section:=ppufile.getansistring;
  1313. {$endif symansistr}
  1314. end;
  1315. destructor tstaticvarsym.destroy;
  1316. begin
  1317. {$ifndef symansistr}
  1318. if assigned(_mangledname) then
  1319. begin
  1320. {$ifdef MEMDEBUG}
  1321. memmanglednames.start;
  1322. {$endif MEMDEBUG}
  1323. stringdispose(_mangledname);
  1324. {$ifdef MEMDEBUG}
  1325. memmanglednames.stop;
  1326. {$endif MEMDEBUG}
  1327. end;
  1328. stringdispose(_mangledbasename);
  1329. {$endif}
  1330. inherited destroy;
  1331. end;
  1332. procedure tstaticvarsym.ppuwrite(ppufile:tcompilerppufile);
  1333. begin
  1334. inherited ppuwrite(ppufile);
  1335. { write mangledname rather than _mangledname in case the mangledname
  1336. has not been calculated yet (can happen in case only the
  1337. mangledbasename has been set) }
  1338. if vo_has_mangledname in varoptions then
  1339. {$ifdef symansistr}
  1340. ppufile.putansistring(mangledname);
  1341. {$else symansistr}
  1342. ppufile.putstring(mangledname);
  1343. {$endif symansistr}
  1344. if vo_has_section in varoptions then
  1345. ppufile.putansistring(section);
  1346. ppufile.writeentry(ibstaticvarsym);
  1347. end;
  1348. function tstaticvarsym.mangledname:TSymStr;
  1349. {$ifndef jvm}
  1350. var
  1351. usename,
  1352. prefix : TSymStr;
  1353. {$endif jvm}
  1354. begin
  1355. {$ifdef symansistr}
  1356. if _mangledname='' then
  1357. {$else symansistr}
  1358. if not assigned(_mangledname) then
  1359. {$endif symansistr}
  1360. begin
  1361. {$ifdef jvm}
  1362. if _mangledbasename='' then
  1363. _mangledname:=jvmmangledbasename(self,false)
  1364. else
  1365. _mangledname:=jvmmangledbasename(self,_mangledbasename,false);
  1366. jvmaddtypeownerprefix(owner,_mangledname);
  1367. {$else jvm}
  1368. if (vo_is_typed_const in varoptions) then
  1369. prefix:='TC'
  1370. else
  1371. prefix:='U';
  1372. {$ifdef symansistr}
  1373. if _mangledbasename='' then
  1374. usename:=name
  1375. else
  1376. usename:=_mangledbasename;
  1377. {$else symansistr}
  1378. if not assigned(_mangledbasename) then
  1379. usename:=name
  1380. else
  1381. usename:=_mangledbasename^;
  1382. {$endif symansistr}
  1383. {$ifdef compress}
  1384. {$error add ansistring support for symansistr}
  1385. _mangledname:=stringdup(minilzw_encode(make_mangledname(prefix,owner,usename)));
  1386. {$else compress}
  1387. {$ifdef symansistr}
  1388. _mangledname:=make_mangledname(prefix,owner,usename);
  1389. {$else symansistr}
  1390. _mangledname:=stringdup(make_mangledname(prefix,owner,usename));
  1391. {$endif symansistr}
  1392. {$endif compress}
  1393. {$endif jvm}
  1394. end;
  1395. {$ifdef symansistr}
  1396. result:=_mangledname;
  1397. {$else symansistr}
  1398. result:=_mangledname^;
  1399. {$endif symansistr}
  1400. end;
  1401. procedure tstaticvarsym.set_mangledbasename(const s: TSymStr);
  1402. begin
  1403. {$ifdef symansistr}
  1404. _mangledbasename:=s;
  1405. {$else symansistr}
  1406. stringdispose(_mangledbasename);
  1407. _mangledbasename:=stringdup(s);
  1408. {$endif symansistr}
  1409. include(varoptions,vo_has_mangledname);
  1410. end;
  1411. procedure tstaticvarsym.set_mangledname(const s:TSymStr);
  1412. begin
  1413. {$ifndef symansistr}
  1414. stringdispose(_mangledname);
  1415. {$endif}
  1416. {$if defined(jvm)}
  1417. _mangledname:=jvmmangledbasename(self,s,false);
  1418. jvmaddtypeownerprefix(owner,_mangledname);
  1419. {$elseif defined(compress)}
  1420. _mangledname:=stringdup(minilzw_encode(s));
  1421. {$else}
  1422. {$ifdef symansistr}
  1423. _mangledname:=s;
  1424. {$else symansistr}
  1425. _mangledname:=stringdup(s);
  1426. {$endif symansistr}
  1427. {$endif}
  1428. include(varoptions,vo_has_mangledname);
  1429. end;
  1430. {****************************************************************************
  1431. TLOCALVARSYM
  1432. ****************************************************************************}
  1433. constructor tlocalvarsym.create(const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1434. begin
  1435. inherited create(localvarsym,n,vsp,def,vopts);
  1436. end;
  1437. constructor tlocalvarsym.ppuload(ppufile:tcompilerppufile);
  1438. begin
  1439. inherited ppuload(localvarsym,ppufile);
  1440. end;
  1441. procedure tlocalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1442. begin
  1443. inherited ppuwrite(ppufile);
  1444. ppufile.writeentry(iblocalvarsym);
  1445. end;
  1446. {****************************************************************************
  1447. TPARAVARSYM
  1448. ****************************************************************************}
  1449. constructor tparavarsym.create(const n : string;nr:word;vsp:tvarspez;def:tdef;vopts:tvaroptions);
  1450. begin
  1451. inherited create(paravarsym,n,vsp,def,vopts);
  1452. if (vsp in [vs_var,vs_value,vs_const,vs_constref]) then
  1453. varstate := vs_initialised;
  1454. paranr:=nr;
  1455. paraloc[calleeside].init;
  1456. paraloc[callerside].init;
  1457. end;
  1458. destructor tparavarsym.destroy;
  1459. begin
  1460. paraloc[calleeside].done;
  1461. paraloc[callerside].done;
  1462. inherited destroy;
  1463. end;
  1464. constructor tparavarsym.ppuload(ppufile:tcompilerppufile);
  1465. var
  1466. b : byte;
  1467. begin
  1468. inherited ppuload(paravarsym,ppufile);
  1469. paranr:=ppufile.getword;
  1470. univpara:=boolean(ppufile.getbyte);
  1471. { The var state of parameter symbols is fixed after writing them so
  1472. we write them to the unit file.
  1473. This enables constant folding for inline procedures loaded from units
  1474. }
  1475. varstate:=tvarstate(ppufile.getbyte);
  1476. paraloc[calleeside].init;
  1477. paraloc[callerside].init;
  1478. if vo_has_explicit_paraloc in varoptions then
  1479. begin
  1480. paraloc[callerside].alignment:=ppufile.getbyte;
  1481. b:=ppufile.getbyte;
  1482. if b<>sizeof(paraloc[callerside].location^) then
  1483. internalerror(200411154);
  1484. ppufile.getdata(paraloc[callerside].add_location^,sizeof(paraloc[callerside].location^));
  1485. paraloc[callerside].size:=paraloc[callerside].location^.size;
  1486. paraloc[callerside].intsize:=tcgsize2size[paraloc[callerside].size];
  1487. end;
  1488. end;
  1489. procedure tparavarsym.ppuwrite(ppufile:tcompilerppufile);
  1490. var
  1491. oldintfcrc : boolean;
  1492. begin
  1493. inherited ppuwrite(ppufile);
  1494. ppufile.putword(paranr);
  1495. ppufile.putbyte(byte(univpara));
  1496. { The var state of parameter symbols is fixed after writing them so
  1497. we write them to the unit file.
  1498. This enables constant folding for inline procedures loaded from units
  1499. }
  1500. oldintfcrc:=ppufile.do_crc;
  1501. ppufile.do_crc:=false;
  1502. ppufile.putbyte(ord(varstate));
  1503. ppufile.do_crc:=oldintfcrc;
  1504. if vo_has_explicit_paraloc in varoptions then
  1505. begin
  1506. paraloc[callerside].check_simple_location;
  1507. ppufile.putbyte(sizeof(paraloc[callerside].alignment));
  1508. ppufile.putbyte(sizeof(paraloc[callerside].location^));
  1509. ppufile.putdata(paraloc[callerside].location^,sizeof(paraloc[callerside].location^));
  1510. end;
  1511. ppufile.writeentry(ibparavarsym);
  1512. end;
  1513. {****************************************************************************
  1514. TABSOLUTEVARSYM
  1515. ****************************************************************************}
  1516. constructor tabsolutevarsym.create(const n : string;def:tdef);
  1517. begin
  1518. inherited create(absolutevarsym,n,vs_value,def,[]);
  1519. ref:=nil;
  1520. end;
  1521. constructor tabsolutevarsym.create_ref(const n : string;def:tdef;_ref:tpropaccesslist);
  1522. begin
  1523. inherited create(absolutevarsym,n,vs_value,def,[]);
  1524. ref:=_ref;
  1525. end;
  1526. destructor tabsolutevarsym.destroy;
  1527. begin
  1528. if assigned(ref) then
  1529. ref.free;
  1530. inherited destroy;
  1531. end;
  1532. constructor tabsolutevarsym.ppuload(ppufile:tcompilerppufile);
  1533. begin
  1534. inherited ppuload(absolutevarsym,ppufile);
  1535. ref:=nil;
  1536. asmname:=nil;
  1537. abstyp:=absolutetyp(ppufile.getbyte);
  1538. {$ifdef i386}
  1539. absseg:=false;
  1540. {$endif i386}
  1541. case abstyp of
  1542. tovar :
  1543. ref:=ppufile.getpropaccesslist;
  1544. toasm :
  1545. asmname:=stringdup(ppufile.getstring);
  1546. toaddr :
  1547. begin
  1548. addroffset:=ppufile.getaword;
  1549. {$ifdef i386}
  1550. absseg:=boolean(ppufile.getbyte);
  1551. {$endif i386}
  1552. end;
  1553. end;
  1554. end;
  1555. procedure tabsolutevarsym.ppuwrite(ppufile:tcompilerppufile);
  1556. begin
  1557. inherited ppuwrite(ppufile);
  1558. ppufile.putbyte(byte(abstyp));
  1559. case abstyp of
  1560. tovar :
  1561. ppufile.putpropaccesslist(ref);
  1562. toasm :
  1563. ppufile.putstring(asmname^);
  1564. toaddr :
  1565. begin
  1566. ppufile.putaword(addroffset);
  1567. {$ifdef i386}
  1568. ppufile.putbyte(byte(absseg));
  1569. {$endif i386}
  1570. end;
  1571. end;
  1572. ppufile.writeentry(ibabsolutevarsym);
  1573. end;
  1574. procedure tabsolutevarsym.buildderef;
  1575. begin
  1576. inherited buildderef;
  1577. if (abstyp=tovar) then
  1578. ref.buildderef;
  1579. end;
  1580. procedure tabsolutevarsym.deref;
  1581. begin
  1582. inherited deref;
  1583. { own absolute deref }
  1584. if (abstyp=tovar) then
  1585. ref.resolve;
  1586. end;
  1587. function tabsolutevarsym.mangledname : TSymStr;
  1588. begin
  1589. case abstyp of
  1590. toasm :
  1591. mangledname:=asmname^;
  1592. toaddr :
  1593. mangledname:='$'+tostr(addroffset);
  1594. else
  1595. internalerror(200411062);
  1596. end;
  1597. end;
  1598. {****************************************************************************
  1599. TCONSTSYM
  1600. ****************************************************************************}
  1601. constructor tconstsym.create_ord(const n : string;t : tconsttyp;v : tconstexprint;def:tdef);
  1602. begin
  1603. inherited create(constsym,n);
  1604. fillchar(value, sizeof(value), #0);
  1605. consttyp:=t;
  1606. value.valueord:=v;
  1607. constdef:=def;
  1608. end;
  1609. constructor tconstsym.create_ordptr(const n : string;t : tconsttyp;v : tconstptruint;def:tdef);
  1610. begin
  1611. inherited create(constsym,n);
  1612. fillchar(value, sizeof(value), #0);
  1613. consttyp:=t;
  1614. value.valueordptr:=v;
  1615. constdef:=def;
  1616. end;
  1617. constructor tconstsym.create_ptr(const n : string;t : tconsttyp;v : pointer;def:tdef);
  1618. begin
  1619. inherited create(constsym,n);
  1620. fillchar(value, sizeof(value), #0);
  1621. consttyp:=t;
  1622. value.valueptr:=v;
  1623. constdef:=def;
  1624. end;
  1625. constructor tconstsym.create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  1626. begin
  1627. inherited create(constsym,n);
  1628. fillchar(value, sizeof(value), #0);
  1629. consttyp:=t;
  1630. value.valueptr:=str;
  1631. constdef:=nil;
  1632. value.len:=l;
  1633. end;
  1634. constructor tconstsym.create_wstring(const n : string;t : tconsttyp;pw:pcompilerwidestring);
  1635. begin
  1636. inherited create(constsym,n);
  1637. fillchar(value, sizeof(value), #0);
  1638. consttyp:=t;
  1639. pcompilerwidestring(value.valueptr):=pw;
  1640. constdef:=nil;
  1641. value.len:=getlengthwidestring(pw);
  1642. end;
  1643. constructor tconstsym.ppuload(ppufile:tcompilerppufile);
  1644. var
  1645. pd : pbestreal;
  1646. ps : pnormalset;
  1647. pc : pchar;
  1648. pw : pcompilerwidestring;
  1649. i : longint;
  1650. begin
  1651. inherited ppuload(constsym,ppufile);
  1652. constdef:=nil;
  1653. consttyp:=tconsttyp(ppufile.getbyte);
  1654. fillchar(value, sizeof(value), #0);
  1655. case consttyp of
  1656. constord :
  1657. begin
  1658. ppufile.getderef(constdefderef);
  1659. value.valueord:=ppufile.getexprint;
  1660. end;
  1661. constpointer :
  1662. begin
  1663. ppufile.getderef(constdefderef);
  1664. value.valueordptr:=ppufile.getptruint;
  1665. end;
  1666. constwstring :
  1667. begin
  1668. initwidestring(pw);
  1669. setlengthwidestring(pw,ppufile.getlongint);
  1670. { don't use getdata, because the compilerwidechars may have to
  1671. be byteswapped
  1672. }
  1673. {$if sizeof(tcompilerwidechar) = 2}
  1674. for i:=0 to pw^.len-1 do
  1675. pw^.data[i]:=ppufile.getword;
  1676. {$elseif sizeof(tcompilerwidechar) = 4}
  1677. for i:=0 to pw^.len-1 do
  1678. pw^.data[i]:=cardinal(ppufile.getlongint);
  1679. {$else}
  1680. {$error Unsupported tcompilerwidechar size}
  1681. {$endif}
  1682. pcompilerwidestring(value.valueptr):=pw;
  1683. end;
  1684. conststring,
  1685. constresourcestring :
  1686. begin
  1687. value.len:=ppufile.getlongint;
  1688. getmem(pc,value.len+1);
  1689. ppufile.getdata(pc^,value.len);
  1690. pc[value.len]:=#0;
  1691. value.valueptr:=pc;
  1692. end;
  1693. constreal :
  1694. begin
  1695. new(pd);
  1696. pd^:=ppufile.getreal;
  1697. value.valueptr:=pd;
  1698. end;
  1699. constset :
  1700. begin
  1701. ppufile.getderef(constdefderef);
  1702. new(ps);
  1703. ppufile.getnormalset(ps^);
  1704. value.valueptr:=ps;
  1705. end;
  1706. constguid :
  1707. begin
  1708. new(pguid(value.valueptr));
  1709. ppufile.getdata(value.valueptr^,sizeof(tguid));
  1710. end;
  1711. constnil : ;
  1712. else
  1713. Message1(unit_f_ppu_invalid_entry,tostr(ord(consttyp)));
  1714. end;
  1715. end;
  1716. destructor tconstsym.destroy;
  1717. begin
  1718. case consttyp of
  1719. conststring,
  1720. constresourcestring :
  1721. freemem(pchar(value.valueptr),value.len+1);
  1722. constwstring :
  1723. donewidestring(pcompilerwidestring(value.valueptr));
  1724. constreal :
  1725. dispose(pbestreal(value.valueptr));
  1726. constset :
  1727. dispose(pnormalset(value.valueptr));
  1728. constguid :
  1729. dispose(pguid(value.valueptr));
  1730. end;
  1731. inherited destroy;
  1732. end;
  1733. procedure tconstsym.buildderef;
  1734. begin
  1735. if consttyp in [constord,constpointer,constset] then
  1736. constdefderef.build(constdef);
  1737. end;
  1738. procedure tconstsym.deref;
  1739. begin
  1740. if consttyp in [constord,constpointer,constset] then
  1741. constdef:=tdef(constdefderef.resolve);
  1742. end;
  1743. procedure tconstsym.ppuwrite(ppufile:tcompilerppufile);
  1744. begin
  1745. inherited ppuwrite(ppufile);
  1746. ppufile.putbyte(byte(consttyp));
  1747. case consttyp of
  1748. constnil : ;
  1749. constord :
  1750. begin
  1751. ppufile.putderef(constdefderef);
  1752. ppufile.putexprint(value.valueord);
  1753. end;
  1754. constpointer :
  1755. begin
  1756. ppufile.putderef(constdefderef);
  1757. ppufile.putptruint(value.valueordptr);
  1758. end;
  1759. constwstring :
  1760. begin
  1761. ppufile.putlongint(getlengthwidestring(pcompilerwidestring(value.valueptr)));
  1762. ppufile.putdata(pcompilerwidestring(value.valueptr)^.data^,pcompilerwidestring(value.valueptr)^.len*sizeof(tcompilerwidechar));
  1763. end;
  1764. conststring,
  1765. constresourcestring :
  1766. begin
  1767. ppufile.putlongint(value.len);
  1768. ppufile.putdata(pchar(value.valueptr)^,value.len);
  1769. end;
  1770. constreal :
  1771. ppufile.putreal(pbestreal(value.valueptr)^);
  1772. constset :
  1773. begin
  1774. ppufile.putderef(constdefderef);
  1775. ppufile.putnormalset(value.valueptr^);
  1776. end;
  1777. constguid :
  1778. ppufile.putdata(value.valueptr^,sizeof(tguid));
  1779. else
  1780. internalerror(13);
  1781. end;
  1782. ppufile.writeentry(ibconstsym);
  1783. end;
  1784. {****************************************************************************
  1785. TENUMSYM
  1786. ****************************************************************************}
  1787. constructor tenumsym.create(const n : string;def : tenumdef;v : longint);
  1788. begin
  1789. inherited create(enumsym,n);
  1790. definition:=def;
  1791. value:=v;
  1792. end;
  1793. constructor tenumsym.ppuload(ppufile:tcompilerppufile);
  1794. begin
  1795. inherited ppuload(enumsym,ppufile);
  1796. ppufile.getderef(definitionderef);
  1797. value:=ppufile.getlongint;
  1798. end;
  1799. procedure tenumsym.buildderef;
  1800. begin
  1801. definitionderef.build(definition);
  1802. end;
  1803. procedure tenumsym.deref;
  1804. begin
  1805. definition:=tenumdef(definitionderef.resolve);
  1806. end;
  1807. procedure tenumsym.ppuwrite(ppufile:tcompilerppufile);
  1808. begin
  1809. inherited ppuwrite(ppufile);
  1810. ppufile.putderef(definitionderef);
  1811. ppufile.putlongint(value);
  1812. ppufile.writeentry(ibenumsym);
  1813. end;
  1814. {****************************************************************************
  1815. TTYPESYM
  1816. ****************************************************************************}
  1817. constructor ttypesym.create(const n : string;def:tdef);
  1818. begin
  1819. inherited create(typesym,n);
  1820. typedef:=def;
  1821. { register the typesym for the definition }
  1822. if assigned(typedef) and
  1823. (typedef.typ<>errordef) and
  1824. not(assigned(typedef.typesym)) then
  1825. typedef.typesym:=self;
  1826. end;
  1827. constructor ttypesym.ppuload(ppufile:tcompilerppufile);
  1828. begin
  1829. inherited ppuload(typesym,ppufile);
  1830. ppufile.getderef(typedefderef);
  1831. fprettyname:=ppufile.getansistring;
  1832. end;
  1833. procedure ttypesym.buildderef;
  1834. begin
  1835. typedefderef.build(typedef);
  1836. end;
  1837. procedure ttypesym.deref;
  1838. begin
  1839. typedef:=tdef(typedefderef.resolve);
  1840. end;
  1841. procedure ttypesym.ppuwrite(ppufile:tcompilerppufile);
  1842. begin
  1843. inherited ppuwrite(ppufile);
  1844. ppufile.putderef(typedefderef);
  1845. ppufile.putansistring(fprettyname);
  1846. ppufile.writeentry(ibtypesym);
  1847. end;
  1848. function ttypesym.prettyname : string;
  1849. begin
  1850. if fprettyname<>'' then
  1851. result:=fprettyname
  1852. else
  1853. result:=inherited prettyname;
  1854. end;
  1855. {****************************************************************************
  1856. TSYSSYM
  1857. ****************************************************************************}
  1858. constructor tsyssym.create(const n : string;l : longint);
  1859. begin
  1860. inherited create(syssym,n);
  1861. number:=l;
  1862. end;
  1863. constructor tsyssym.ppuload(ppufile:tcompilerppufile);
  1864. begin
  1865. inherited ppuload(syssym,ppufile);
  1866. number:=ppufile.getlongint;
  1867. end;
  1868. destructor tsyssym.destroy;
  1869. begin
  1870. inherited destroy;
  1871. end;
  1872. procedure tsyssym.ppuwrite(ppufile:tcompilerppufile);
  1873. begin
  1874. inherited ppuwrite(ppufile);
  1875. ppufile.putlongint(number);
  1876. ppufile.writeentry(ibsyssym);
  1877. end;
  1878. {*****************************************************************************
  1879. TMacro
  1880. *****************************************************************************}
  1881. constructor tmacro.create(const n : string);
  1882. begin
  1883. inherited create(macrosym,n);
  1884. owner:=nil;
  1885. defined:=false;
  1886. is_used:=false;
  1887. is_compiler_var:=false;
  1888. buftext:=nil;
  1889. buflen:=0;
  1890. end;
  1891. constructor tmacro.ppuload(ppufile:tcompilerppufile);
  1892. begin
  1893. inherited ppuload(macrosym,ppufile);
  1894. defined:=boolean(ppufile.getbyte);
  1895. is_compiler_var:=boolean(ppufile.getbyte);
  1896. is_used:=false;
  1897. buflen:= ppufile.getlongint;
  1898. if buflen > 0 then
  1899. begin
  1900. getmem(buftext, buflen);
  1901. ppufile.getdata(buftext^, buflen)
  1902. end
  1903. else
  1904. buftext:=nil;
  1905. end;
  1906. destructor tmacro.destroy;
  1907. begin
  1908. if assigned(buftext) then
  1909. freemem(buftext);
  1910. inherited destroy;
  1911. end;
  1912. procedure tmacro.ppuwrite(ppufile:tcompilerppufile);
  1913. begin
  1914. inherited ppuwrite(ppufile);
  1915. ppufile.putbyte(byte(defined));
  1916. ppufile.putbyte(byte(is_compiler_var));
  1917. ppufile.putlongint(buflen);
  1918. if buflen > 0 then
  1919. ppufile.putdata(buftext^,buflen);
  1920. ppufile.writeentry(ibmacrosym);
  1921. end;
  1922. function tmacro.GetCopy:tmacro;
  1923. var
  1924. p : tmacro;
  1925. begin
  1926. p:=tmacro.create(realname);
  1927. p.defined:=defined;
  1928. p.is_used:=is_used;
  1929. p.is_compiler_var:=is_compiler_var;
  1930. p.buflen:=buflen;
  1931. if assigned(buftext) then
  1932. begin
  1933. getmem(p.buftext,buflen);
  1934. move(buftext^,p.buftext^,buflen);
  1935. end;
  1936. Result:=p;
  1937. end;
  1938. end.