symsym.pas 64 KB

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