symsym.pas 71 KB

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