symsym.pas 82 KB

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