symsym.pas 68 KB

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