symsym.pas 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 by Florian Klaempfl, Pierre Muller
  4. Implementation for the symbols types of the symtable
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit symsym;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,
  24. { target }
  25. cpuinfo,globtype,
  26. { symtable }
  27. symconst,symbase,symtype,symdef,
  28. { ppu }
  29. ppu,symppu,
  30. {$ifdef var_notification}
  31. cclasses,symnot,
  32. {$endif}
  33. { aasm }
  34. aasmbase,aasmtai,cpubase,
  35. globals
  36. ;
  37. type
  38. {************************************************
  39. TSym
  40. ************************************************}
  41. { this object is the base for all symbol objects }
  42. tstoredsym = class(tsym)
  43. protected
  44. _mangledname : pstring;
  45. public
  46. {$ifdef GDB}
  47. isstabwritten : boolean;
  48. {$endif GDB}
  49. refs : longint;
  50. lastref,
  51. defref,
  52. lastwritten : tref;
  53. refcount : longint;
  54. constructor create(const n : string);
  55. constructor loadsym(ppufile:tcompilerppufile);
  56. destructor destroy;override;
  57. procedure ppuwrite(ppufile:tcompilerppufile);virtual;abstract;
  58. procedure writesym(ppufile:tcompilerppufile);
  59. procedure deref;override;
  60. {$ifdef GDB}
  61. function stabstring : pchar;virtual;
  62. procedure concatstabto(asmlist : taasmoutput);virtual;
  63. {$endif GDB}
  64. procedure load_references(ppufile:tcompilerppufile;locals:boolean);virtual;
  65. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;virtual;
  66. function is_visible_for_proc(currprocdef:tprocdef):boolean;
  67. function is_visible_for_object(currobjdef:tobjectdef):boolean;
  68. function mangledname : string;
  69. procedure generate_mangledname;virtual;abstract;
  70. end;
  71. tlabelsym = class(tstoredsym)
  72. lab : tasmlabel;
  73. used,
  74. defined : boolean;
  75. code : pointer; { should be tnode }
  76. constructor create(const n : string; l : tasmlabel);
  77. destructor destroy;override;
  78. constructor ppuload(ppufile:tcompilerppufile);
  79. procedure generate_mangledname;override;
  80. procedure ppuwrite(ppufile:tcompilerppufile);override;
  81. end;
  82. tunitsym = class(tstoredsym)
  83. unitsymtable : tsymtable;
  84. prevsym : tunitsym;
  85. constructor create(const n : string;ref : tsymtable);
  86. constructor ppuload(ppufile:tcompilerppufile);
  87. destructor destroy;override;
  88. procedure ppuwrite(ppufile:tcompilerppufile);override;
  89. procedure restoreunitsym;
  90. {$ifdef GDB}
  91. procedure concatstabto(asmlist : taasmoutput);override;
  92. {$endif GDB}
  93. end;
  94. terrorsym = class(tstoredsym)
  95. constructor create;
  96. end;
  97. Tprocdefcallback = procedure(p:Tprocdef;arg:pointer);
  98. tprocsym = class(tstoredsym)
  99. protected
  100. defs : pprocdeflist; { linked list of overloaded procdefs }
  101. function getprocdef(nr:cardinal):Tprocdef;
  102. public
  103. procdef_count : byte;
  104. is_global : boolean;
  105. overloadchecked : boolean;
  106. overloadcount : word; { amount of overloaded functions in this module }
  107. property procdef[nr:cardinal]:Tprocdef read getprocdef;
  108. constructor create(const n : string);
  109. constructor ppuload(ppufile:tcompilerppufile);
  110. destructor destroy;override;
  111. { writes all declarations except the specified one }
  112. procedure write_parameter_lists(skipdef:tprocdef);
  113. { tests, if all procedures definitions are defined and not }
  114. { only forward }
  115. procedure check_forward;
  116. procedure unchain_overload;
  117. procedure ppuwrite(ppufile:tcompilerppufile);override;
  118. procedure deref;override;
  119. procedure addprocdef(p:tprocdef);
  120. procedure add_para_match_to(Aprocsym:Tprocsym);
  121. procedure concat_procdefs_to(s:Tprocsym);
  122. procedure foreach_procdef_static(proc2call:Tprocdefcallback;arg:pointer);
  123. function first_procdef:Tprocdef;
  124. function last_procdef:Tprocdef;
  125. function search_procdef_nopara_boolret:Tprocdef;
  126. function search_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  127. function search_procdef_bypara(params:Tparalinkedlist;
  128. allowconvert,
  129. allowdefault:boolean):Tprocdef;
  130. function search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  131. function search_procdef_by1paradef(firstpara:Tdef):Tprocdef;
  132. function search_procdef_assignment_operator(fromdef,todef:tdef):Tprocdef;
  133. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  134. {$ifdef GDB}
  135. function stabstring : pchar;override;
  136. procedure concatstabto(asmlist : taasmoutput);override;
  137. {$endif GDB}
  138. end;
  139. ttypesym = class(tstoredsym)
  140. restype : ttype;
  141. {$ifdef GDB}
  142. isusedinstab : boolean;
  143. {$endif GDB}
  144. constructor create(const n : string;const tt : ttype);
  145. constructor ppuload(ppufile:tcompilerppufile);
  146. procedure ppuwrite(ppufile:tcompilerppufile);override;
  147. procedure deref;override;
  148. function gettypedef:tdef;override;
  149. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  150. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  151. {$ifdef GDB}
  152. function stabstring : pchar;override;
  153. procedure concatstabto(asmlist : taasmoutput);override;
  154. {$endif GDB}
  155. end;
  156. tvarsym = class(tstoredsym)
  157. address : longint;
  158. localvarsym : tvarsym;
  159. vartype : ttype;
  160. varoptions : tvaroptions;
  161. reg : tregister; { if reg<>R_NO, then the variable is an register variable }
  162. varspez : tvarspez; { sets the type of access }
  163. varstate : tvarstate;
  164. paraitem : tparaitem;
  165. {$ifdef var_notification}
  166. notifications : Tlinkedlist;
  167. {$endif}
  168. constructor create(const n : string;const tt : ttype);
  169. constructor create_dll(const n : string;const tt : ttype);
  170. constructor create_C(const n,mangled : string;const tt : ttype);
  171. constructor ppuload(ppufile:tcompilerppufile);
  172. destructor destroy;override;
  173. procedure ppuwrite(ppufile:tcompilerppufile);override;
  174. procedure deref;override;
  175. procedure generate_mangledname;override;
  176. procedure set_mangledname(const s:string);
  177. function getsize : longint;
  178. function getvaluesize : longint;
  179. function getpushsize(calloption:tproccalloption): longint;
  180. {$ifdef var_notification}
  181. function register_notification(flags:Tnotification_flags;
  182. callback:Tnotification_callback):cardinal;
  183. {$endif}
  184. {$ifdef GDB}
  185. function stabstring : pchar;override;
  186. procedure concatstabto(asmlist : taasmoutput);override;
  187. {$endif GDB}
  188. end;
  189. tpropertysym = class(tstoredsym)
  190. propoptions : tpropertyoptions;
  191. propoverriden : tpropertysym;
  192. proptype,
  193. indextype : ttype;
  194. index,
  195. default : longint;
  196. readaccess,
  197. writeaccess,
  198. storedaccess : tsymlist;
  199. constructor create(const n : string);
  200. destructor destroy;override;
  201. constructor ppuload(ppufile:tcompilerppufile);
  202. function getsize : longint;
  203. procedure ppuwrite(ppufile:tcompilerppufile);override;
  204. function gettypedef:tdef;override;
  205. procedure deref;override;
  206. procedure dooverride(overriden:tpropertysym);
  207. {$ifdef GDB}
  208. function stabstring : pchar;override;
  209. procedure concatstabto(asmlist : taasmoutput);override;
  210. {$endif GDB}
  211. end;
  212. tfuncretsym = class(tstoredsym)
  213. returntype : ttype;
  214. address : longint;
  215. funcretstate : tvarstate;
  216. constructor create(const n : string;const tt : ttype);
  217. constructor ppuload(ppufile:tcompilerppufile);
  218. destructor destroy;override;
  219. procedure ppuwrite(ppufile:tcompilerppufile);override;
  220. procedure deref;override;
  221. {$ifdef GDB}
  222. procedure concatstabto(asmlist : taasmoutput);override;
  223. {$endif GDB}
  224. end;
  225. tabsolutesym = class(tvarsym)
  226. abstyp : absolutetyp;
  227. absseg : boolean;
  228. ref : tstoredsym;
  229. asmname : pstring;
  230. constructor create(const n : string;const tt : ttype);
  231. constructor ppuload(ppufile:tcompilerppufile);
  232. procedure deref;override;
  233. function mangledname : string;
  234. procedure ppuwrite(ppufile:tcompilerppufile);override;
  235. {$ifdef GDB}
  236. procedure concatstabto(asmlist : taasmoutput);override;
  237. {$endif GDB}
  238. end;
  239. ttypedconstsym = class(tstoredsym)
  240. typedconsttype : ttype;
  241. is_writable : boolean;
  242. constructor create(const n : string;p : tdef;writable : boolean);
  243. constructor createtype(const n : string;const tt : ttype;writable : boolean);
  244. constructor ppuload(ppufile:tcompilerppufile);
  245. destructor destroy;override;
  246. procedure generate_mangledname;override;
  247. procedure ppuwrite(ppufile:tcompilerppufile);override;
  248. procedure deref;override;
  249. function getsize:longint;
  250. {$ifdef GDB}
  251. function stabstring : pchar;override;
  252. {$endif GDB}
  253. end;
  254. tconstvalue = record
  255. case integer of
  256. 0: (valueord : tconstexprint);
  257. 1: (valueordptr : tconstptruint);
  258. 2: (valueptr : pointer; len : longint);
  259. end;
  260. tconstsym = class(tstoredsym)
  261. consttype : ttype;
  262. consttyp : tconsttyp;
  263. value : tconstvalue;
  264. resstrindex : longint; { needed for resource strings }
  265. (* valueord : tconstexprint; { used for ordinal values }
  266. valueordptr : TConstPtrUInt; { used for pointer values }
  267. valueptr : pointer; { used for string, set, real values }
  268. len : longint; { len is needed for string length }*)
  269. constructor create_ord(const n : string;t : tconsttyp;v : tconstexprint);
  270. constructor create_ord_typed(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  271. constructor create_ordptr_typed(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  272. constructor create_ptr(const n : string;t : tconsttyp;v : pointer);
  273. constructor create_ptr_typed(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  274. constructor create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  275. constructor ppuload(ppufile:tcompilerppufile);
  276. destructor destroy;override;
  277. function mangledname : string;
  278. procedure deref;override;
  279. procedure ppuwrite(ppufile:tcompilerppufile);override;
  280. {$ifdef GDB}
  281. function stabstring : pchar;override;
  282. procedure concatstabto(asmlist : taasmoutput);override;
  283. {$endif GDB}
  284. end;
  285. tenumsym = class(tstoredsym)
  286. value : longint;
  287. definition : tenumdef;
  288. nextenum : tenumsym;
  289. constructor create(const n : string;def : tenumdef;v : longint);
  290. constructor ppuload(ppufile:tcompilerppufile);
  291. procedure ppuwrite(ppufile:tcompilerppufile);override;
  292. procedure deref;override;
  293. procedure order;
  294. {$ifdef GDB}
  295. procedure concatstabto(asmlist : taasmoutput);override;
  296. {$endif GDB}
  297. end;
  298. tsyssym = class(tstoredsym)
  299. number : longint;
  300. constructor create(const n : string;l : longint);
  301. constructor ppuload(ppufile:tcompilerppufile);
  302. destructor destroy;override;
  303. procedure ppuwrite(ppufile:tcompilerppufile);override;
  304. {$ifdef GDB}
  305. procedure concatstabto(asmlist : taasmoutput);override;
  306. {$endif GDB}
  307. end;
  308. { compiler generated symbol to point to rtti and init/finalize tables }
  309. trttisym = class(tstoredsym)
  310. lab : tasmsymbol;
  311. rttityp : trttitype;
  312. constructor create(const n:string;rt:trttitype);
  313. constructor ppuload(ppufile:tcompilerppufile);
  314. procedure ppuwrite(ppufile:tcompilerppufile);override;
  315. function mangledname:string;
  316. function get_label:tasmsymbol;
  317. end;
  318. { register variables }
  319. pregvarinfo = ^tregvarinfo;
  320. tregvarinfo = record
  321. regvars : array[1..maxvarregs] of tvarsym;
  322. regvars_para : array[1..maxvarregs] of boolean;
  323. regvars_refs : array[1..maxvarregs] of longint;
  324. fpuregvars : array[1..maxfpuvarregs] of tvarsym;
  325. fpuregvars_para : array[1..maxfpuvarregs] of boolean;
  326. fpuregvars_refs : array[1..maxfpuvarregs] of longint;
  327. end;
  328. var
  329. aktprocsym : tprocsym; { pointer to the symbol for the
  330. currently be parsed procedure }
  331. aktprocdef : tprocdef;
  332. aktcallprocdef : tabstractprocdef; { pointer to the definition of the
  333. currently called procedure,
  334. only set/unset in ncal }
  335. generrorsym : tsym;
  336. otsym : tvarsym;
  337. const
  338. current_object_option : tsymoptions = [sp_public];
  339. { rtti and init/final }
  340. procedure generate_rtti(p:tsym);
  341. procedure generate_inittable(p:tsym);
  342. implementation
  343. uses
  344. {$ifdef Delphi}
  345. sysutils,
  346. {$else Delphi}
  347. strings,
  348. {$endif Delphi}
  349. { global }
  350. verbose,
  351. { target }
  352. systems,
  353. { symtable }
  354. symtable,defutil,defcmp,
  355. {$ifdef GDB}
  356. gdb,
  357. {$endif GDB}
  358. { tree }
  359. node,
  360. { aasm }
  361. aasmcpu,
  362. { module }
  363. fmodule,
  364. { codegen }
  365. paramgr,cgbase,cresstr
  366. ;
  367. {****************************************************************************
  368. Helpers
  369. ****************************************************************************}
  370. {****************************************************************************
  371. TSYM (base for all symtypes)
  372. ****************************************************************************}
  373. constructor tstoredsym.create(const n : string);
  374. begin
  375. inherited create(n);
  376. symoptions:=current_object_option;
  377. {$ifdef GDB}
  378. isstabwritten := false;
  379. {$endif GDB}
  380. fileinfo:=akttokenpos;
  381. defref:=nil;
  382. refs:=0;
  383. lastwritten:=nil;
  384. refcount:=0;
  385. if (cs_browser in aktmoduleswitches) and make_ref then
  386. begin
  387. defref:=tref.create(defref,@akttokenpos);
  388. inc(refcount);
  389. end;
  390. lastref:=defref;
  391. _mangledname:=nil;
  392. end;
  393. constructor tstoredsym.loadsym(ppufile:tcompilerppufile);
  394. var
  395. s : string;
  396. nr : word;
  397. begin
  398. nr:=ppufile.getword;
  399. s:=ppufile.getstring;
  400. inherited create(s);
  401. { force the correct indexnr. must be after create! }
  402. indexnr:=nr;
  403. ppufile.getsmallset(symoptions);
  404. ppufile.getposinfo(fileinfo);
  405. lastref:=nil;
  406. defref:=nil;
  407. refs:=0;
  408. lastwritten:=nil;
  409. refcount:=0;
  410. _mangledname:=nil;
  411. {$ifdef GDB}
  412. isstabwritten := false;
  413. {$endif GDB}
  414. end;
  415. procedure tstoredsym.deref;
  416. begin
  417. end;
  418. procedure tstoredsym.load_references(ppufile:tcompilerppufile;locals:boolean);
  419. var
  420. pos : tfileposinfo;
  421. move_last : boolean;
  422. begin
  423. move_last:=lastwritten=lastref;
  424. while (not ppufile.endofentry) do
  425. begin
  426. ppufile.getposinfo(pos);
  427. inc(refcount);
  428. lastref:=tref.create(lastref,@pos);
  429. lastref.is_written:=true;
  430. if refcount=1 then
  431. defref:=lastref;
  432. end;
  433. if move_last then
  434. lastwritten:=lastref;
  435. end;
  436. { big problem here :
  437. wrong refs were written because of
  438. interface parsing of other units PM
  439. moduleindex must be checked !! }
  440. function tstoredsym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  441. var
  442. ref : tref;
  443. symref_written,move_last : boolean;
  444. begin
  445. write_references:=false;
  446. if lastwritten=lastref then
  447. exit;
  448. { should we update lastref }
  449. move_last:=true;
  450. symref_written:=false;
  451. { write symbol refs }
  452. if assigned(lastwritten) then
  453. ref:=lastwritten
  454. else
  455. ref:=defref;
  456. while assigned(ref) do
  457. begin
  458. if ref.moduleindex=current_module.unit_index then
  459. begin
  460. { write address to this symbol }
  461. if not symref_written then
  462. begin
  463. ppufile.putderef(self);
  464. symref_written:=true;
  465. end;
  466. ppufile.putposinfo(ref.posinfo);
  467. ref.is_written:=true;
  468. if move_last then
  469. lastwritten:=ref;
  470. end
  471. else if not ref.is_written then
  472. move_last:=false
  473. else if move_last then
  474. lastwritten:=ref;
  475. ref:=ref.nextref;
  476. end;
  477. if symref_written then
  478. ppufile.writeentry(ibsymref);
  479. write_references:=symref_written;
  480. end;
  481. destructor tstoredsym.destroy;
  482. begin
  483. if assigned(_mangledname) then
  484. begin
  485. {$ifdef MEMDEBUG}
  486. memmanglednames.start;
  487. {$endif MEMDEBUG}
  488. stringdispose(_mangledname);
  489. {$ifdef MEMDEBUG}
  490. memmanglednames.stop;
  491. {$endif MEMDEBUG}
  492. end;
  493. if assigned(defref) then
  494. begin
  495. {$ifdef MEMDEBUG}
  496. membrowser.start;
  497. {$endif MEMDEBUG}
  498. defref.freechain;
  499. defref.free;
  500. {$ifdef MEMDEBUG}
  501. membrowser.stop;
  502. {$endif MEMDEBUG}
  503. end;
  504. inherited destroy;
  505. end;
  506. procedure tstoredsym.writesym(ppufile:tcompilerppufile);
  507. begin
  508. ppufile.putword(indexnr);
  509. ppufile.putstring(_realname^);
  510. ppufile.putsmallset(symoptions);
  511. ppufile.putposinfo(fileinfo);
  512. end;
  513. {$ifdef GDB}
  514. function tstoredsym.stabstring : pchar;
  515. begin
  516. stabstring:=strpnew('"'+name+'",'+tostr(N_LSYM)+',0,'+
  517. tostr(fileinfo.line)+',0');
  518. end;
  519. procedure tstoredsym.concatstabto(asmlist : taasmoutput);
  520. var
  521. stab_str : pchar;
  522. begin
  523. if not isstabwritten then
  524. begin
  525. stab_str := stabstring;
  526. { count_dbx(stab_str); moved to GDB.PAS }
  527. asmList.concat(Tai_stabs.Create(stab_str));
  528. isstabwritten:=true;
  529. end;
  530. end;
  531. {$endif GDB}
  532. function tstoredsym.is_visible_for_proc(currprocdef:tprocdef):boolean;
  533. begin
  534. is_visible_for_proc:=false;
  535. { private symbols are allowed when we are in the same
  536. module as they are defined }
  537. if (sp_private in symoptions) and
  538. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  539. (owner.defowner.owner.unitid<>0) then
  540. exit;
  541. { protected symbols are vissible in the module that defines them and
  542. also visible to related objects }
  543. if (sp_protected in symoptions) and
  544. (
  545. (
  546. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  547. (owner.defowner.owner.unitid<>0)
  548. ) and
  549. not(
  550. assigned(currprocdef) and
  551. assigned(currprocdef._class) and
  552. currprocdef._class.is_related(tobjectdef(owner.defowner))
  553. )
  554. ) then
  555. exit;
  556. is_visible_for_proc:=true;
  557. end;
  558. function tstoredsym.is_visible_for_object(currobjdef:tobjectdef):boolean;
  559. begin
  560. is_visible_for_object:=false;
  561. { private symbols are allowed when we are in the same
  562. module as they are defined }
  563. if (sp_private in symoptions) and
  564. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  565. (owner.defowner.owner.unitid<>0) then
  566. exit;
  567. { protected symbols are vissible in the module that defines them and
  568. also visible to related objects }
  569. if (sp_protected in symoptions) and
  570. (
  571. (
  572. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  573. (owner.defowner.owner.unitid<>0)
  574. ) and
  575. not(
  576. assigned(currobjdef) and
  577. currobjdef.is_related(tobjectdef(owner.defowner))
  578. )
  579. ) then
  580. exit;
  581. is_visible_for_object:=true;
  582. end;
  583. function tstoredsym.mangledname : string;
  584. begin
  585. if not assigned(_mangledname) then
  586. begin
  587. generate_mangledname;
  588. if not assigned(_mangledname) then
  589. internalerror(200204171);
  590. end;
  591. mangledname:=_mangledname^
  592. end;
  593. {****************************************************************************
  594. TLABELSYM
  595. ****************************************************************************}
  596. constructor tlabelsym.create(const n : string; l : tasmlabel);
  597. begin
  598. inherited create(n);
  599. typ:=labelsym;
  600. lab:=l;
  601. used:=false;
  602. defined:=false;
  603. code:=nil;
  604. end;
  605. constructor tlabelsym.ppuload(ppufile:tcompilerppufile);
  606. begin
  607. inherited loadsym(ppufile);
  608. typ:=labelsym;
  609. { this is all dummy
  610. it is only used for local browsing }
  611. lab:=nil;
  612. code:=nil;
  613. used:=false;
  614. defined:=true;
  615. end;
  616. destructor tlabelsym.destroy;
  617. begin
  618. inherited destroy;
  619. end;
  620. procedure tlabelsym.generate_mangledname;
  621. begin
  622. _mangledname:=stringdup(lab.name);
  623. end;
  624. procedure tlabelsym.ppuwrite(ppufile:tcompilerppufile);
  625. begin
  626. if owner.symtabletype=globalsymtable then
  627. Message(sym_e_ill_label_decl)
  628. else
  629. begin
  630. inherited writesym(ppufile);
  631. ppufile.writeentry(iblabelsym);
  632. end;
  633. end;
  634. {****************************************************************************
  635. TUNITSYM
  636. ****************************************************************************}
  637. constructor tunitsym.create(const n : string;ref : tsymtable);
  638. var
  639. old_make_ref : boolean;
  640. begin
  641. old_make_ref:=make_ref;
  642. make_ref:=false;
  643. inherited create(n);
  644. make_ref:=old_make_ref;
  645. typ:=unitsym;
  646. unitsymtable:=ref;
  647. if assigned(ref) and
  648. (ref.symtabletype=globalsymtable) then
  649. begin
  650. prevsym:=tglobalsymtable(ref).unitsym;
  651. tglobalsymtable(ref).unitsym:=self;
  652. end;
  653. end;
  654. constructor tunitsym.ppuload(ppufile:tcompilerppufile);
  655. begin
  656. inherited loadsym(ppufile);
  657. typ:=unitsym;
  658. unitsymtable:=nil;
  659. prevsym:=nil;
  660. refs:=0;
  661. end;
  662. { we need to remove it from the prevsym chain ! }
  663. procedure tunitsym.restoreunitsym;
  664. var pus,ppus : tunitsym;
  665. begin
  666. if assigned(unitsymtable) and
  667. (unitsymtable.symtabletype=globalsymtable) then
  668. begin
  669. ppus:=nil;
  670. pus:=tglobalsymtable(unitsymtable).unitsym;
  671. if pus=self then
  672. tglobalsymtable(unitsymtable).unitsym:=prevsym
  673. else while assigned(pus) do
  674. begin
  675. if pus=self then
  676. begin
  677. ppus.prevsym:=prevsym;
  678. break;
  679. end
  680. else
  681. begin
  682. ppus:=pus;
  683. pus:=ppus.prevsym;
  684. end;
  685. end;
  686. end;
  687. unitsymtable:=nil;
  688. prevsym:=nil;
  689. end;
  690. destructor tunitsym.destroy;
  691. begin
  692. restoreunitsym;
  693. inherited destroy;
  694. end;
  695. procedure tunitsym.ppuwrite(ppufile:tcompilerppufile);
  696. begin
  697. inherited writesym(ppufile);
  698. ppufile.writeentry(ibunitsym);
  699. end;
  700. {$ifdef GDB}
  701. procedure tunitsym.concatstabto(asmlist : taasmoutput);
  702. begin
  703. {Nothing to write to stabs !}
  704. end;
  705. {$endif GDB}
  706. {****************************************************************************
  707. TPROCSYM
  708. ****************************************************************************}
  709. constructor tprocsym.create(const n : string);
  710. begin
  711. inherited create(n);
  712. typ:=procsym;
  713. defs:=nil;
  714. owner:=nil;
  715. is_global:=false;
  716. overloadchecked:=false;
  717. overloadcount:=0;
  718. procdef_count:=0;
  719. end;
  720. constructor tprocsym.ppuload(ppufile:tcompilerppufile);
  721. var
  722. pd : tprocdef;
  723. begin
  724. inherited loadsym(ppufile);
  725. typ:=procsym;
  726. defs:=nil;
  727. procdef_count:=0;
  728. repeat
  729. pd:=tprocdef(ppufile.getderef);
  730. if pd=nil then
  731. break;
  732. addprocdef(pd);
  733. until false;
  734. is_global:=false;
  735. overloadchecked:=false;
  736. overloadcount:=$ffff; { invalid, not used anymore }
  737. end;
  738. destructor tprocsym.destroy;
  739. var
  740. hp,p : pprocdeflist;
  741. begin
  742. p:=defs;
  743. while assigned(p) do
  744. begin
  745. hp:=p^.next;
  746. dispose(p);
  747. p:=hp;
  748. end;
  749. inherited destroy;
  750. end;
  751. procedure tprocsym.write_parameter_lists(skipdef:tprocdef);
  752. var
  753. p : pprocdeflist;
  754. begin
  755. p:=defs;
  756. while assigned(p) do
  757. begin
  758. if p^.def<>skipdef then
  759. MessagePos1(p^.def.fileinfo,sym_b_param_list,p^.def.fullprocname);
  760. p:=p^.next;
  761. end;
  762. end;
  763. procedure tprocsym.check_forward;
  764. var
  765. p : pprocdeflist;
  766. begin
  767. p:=defs;
  768. while assigned(p) do
  769. begin
  770. if (p^.def.procsym=self) and
  771. (p^.def.forwarddef) then
  772. begin
  773. MessagePos1(p^.def.fileinfo,sym_e_forward_not_resolved,p^.def.fullprocname);
  774. { Turn futher error messages off }
  775. p^.def.forwarddef:=false;
  776. end;
  777. p:=p^.next;
  778. end;
  779. end;
  780. procedure tprocsym.deref;
  781. var
  782. p : pprocdeflist;
  783. begin
  784. p:=defs;
  785. while assigned(p) do
  786. begin
  787. resolvedef(pointer(p^.def));
  788. p:=p^.next;
  789. end;
  790. end;
  791. procedure tprocsym.addprocdef(p:tprocdef);
  792. var
  793. pd : pprocdeflist;
  794. begin
  795. new(pd);
  796. pd^.def:=p;
  797. pd^.next:=defs;
  798. defs:=pd;
  799. inc(procdef_count);
  800. end;
  801. function Tprocsym.getprocdef(nr:cardinal):Tprocdef;
  802. var
  803. i : cardinal;
  804. pd : Pprocdeflist;
  805. begin
  806. pd:=defs;
  807. for i:=2 to nr do
  808. begin
  809. if not assigned(pd) then
  810. internalerror(200209051);
  811. pd:=pd^.next;
  812. end;
  813. getprocdef:=pd^.def;
  814. end;
  815. procedure Tprocsym.add_para_match_to(Aprocsym:Tprocsym);
  816. var
  817. pd:Pprocdeflist;
  818. begin
  819. pd:=defs;
  820. while assigned(pd) do
  821. begin
  822. if Aprocsym.search_procdef_bypara(pd^.def.para,false,true)=nil then
  823. Aprocsym.addprocdef(pd^.def);
  824. pd:=pd^.next;
  825. end;
  826. end;
  827. procedure Tprocsym.concat_procdefs_to(s:Tprocsym);
  828. var pd:Pprocdeflist;
  829. begin
  830. pd:=defs;
  831. while assigned(pd) do
  832. begin
  833. s.addprocdef(pd^.def);
  834. pd:=pd^.next;
  835. end;
  836. end;
  837. function Tprocsym.first_procdef:Tprocdef;
  838. begin
  839. first_procdef:=defs^.def;
  840. end;
  841. function Tprocsym.last_procdef:Tprocdef;
  842. var pd:Pprocdeflist;
  843. begin
  844. pd:=defs;
  845. while assigned(pd) do
  846. begin
  847. last_procdef:=pd^.def;
  848. pd:=pd^.next;
  849. end;
  850. end;
  851. procedure Tprocsym.foreach_procdef_static(proc2call:Tprocdefcallback;arg:pointer);
  852. var p:Pprocdeflist;
  853. begin
  854. p:=defs;
  855. while assigned(p) do
  856. begin
  857. proc2call(p^.def,arg);
  858. p:=p^.next;
  859. end;
  860. end;
  861. function Tprocsym.search_procdef_nopara_boolret:Tprocdef;
  862. var p:Pprocdeflist;
  863. begin
  864. search_procdef_nopara_boolret:=nil;
  865. p:=defs;
  866. while p<>nil do
  867. begin
  868. if p^.def.para.empty and is_boolean(p^.def.rettype.def) then
  869. begin
  870. search_procdef_nopara_boolret:=p^.def;
  871. break;
  872. end;
  873. p:=p^.next;
  874. end;
  875. end;
  876. function Tprocsym.search_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  877. var p:Pprocdeflist;
  878. begin
  879. search_procdef_bytype:=nil;
  880. p:=defs;
  881. while p<>nil do
  882. begin
  883. if p^.def.proctypeoption=pt then
  884. begin
  885. search_procdef_bytype:=p^.def;
  886. break;
  887. end;
  888. p:=p^.next;
  889. end;
  890. end;
  891. function Tprocsym.search_procdef_bypara(params:Tparalinkedlist;
  892. allowconvert,
  893. allowdefault:boolean):Tprocdef;
  894. var
  895. pd:Pprocdeflist;
  896. eq : tequaltype;
  897. begin
  898. search_procdef_bypara:=nil;
  899. pd:=defs;
  900. while assigned(pd) do
  901. begin
  902. eq:=compare_paras(pd^.def.para,params,cp_value_equal_const,allowdefault);
  903. if (eq>=te_equal) or
  904. (allowconvert and (eq>te_incompatible)) then
  905. begin
  906. search_procdef_bypara:=pd^.def;
  907. break;
  908. end;
  909. pd:=pd^.next;
  910. end;
  911. end;
  912. function Tprocsym.search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  913. var
  914. pd : Pprocdeflist;
  915. eq,besteq : tequaltype;
  916. bestpd : tprocdef;
  917. begin
  918. { This function will return the pprocdef of pprocsym that
  919. is the best match for procvardef. When there are multiple
  920. matches it returns nil.}
  921. search_procdef_byprocvardef:=nil;
  922. bestpd:=nil;
  923. besteq:=te_incompatible;
  924. pd:=defs;
  925. while assigned(pd) do
  926. begin
  927. eq:=proc_to_procvar_equal(pd^.def,d);
  928. if eq>te_incompatible then
  929. begin
  930. { multiple procvars with the same equal level }
  931. if assigned(bestpd) and
  932. (besteq=eq) then
  933. exit;
  934. if eq>besteq then
  935. begin
  936. besteq:=eq;
  937. bestpd:=pd^.def;
  938. end;
  939. end;
  940. pd:=pd^.next;
  941. end;
  942. search_procdef_byprocvardef:=bestpd;
  943. end;
  944. function Tprocsym.search_procdef_by1paradef(firstpara:Tdef):Tprocdef;
  945. var
  946. pd:Pprocdeflist;
  947. begin
  948. search_procdef_by1paradef:=nil;
  949. pd:=defs;
  950. while assigned(pd) do
  951. begin
  952. if equal_defs(Tparaitem(pd^.def.para.first).paratype.def,firstpara) and
  953. (Tparaitem(pd^.def.para.first).next=nil) then
  954. begin
  955. search_procdef_by1paradef:=pd^.def;
  956. break;
  957. end;
  958. pd:=pd^.next;
  959. end;
  960. end;
  961. function Tprocsym.search_procdef_assignment_operator(fromdef,todef:tdef):Tprocdef;
  962. var
  963. convtyp : tconverttype;
  964. pd : pprocdeflist;
  965. bestpd : tprocdef;
  966. eq,
  967. besteq : tequaltype;
  968. hpd : tprocdef;
  969. begin
  970. search_procdef_assignment_operator:=nil;
  971. bestpd:=nil;
  972. besteq:=te_incompatible;
  973. pd:=defs;
  974. while assigned(pd) do
  975. begin
  976. if equal_defs(todef,pd^.def.rettype.def) then
  977. begin
  978. eq:=compare_defs_ext(fromdef,Tparaitem(pd^.def.para.first).paratype.def,
  979. nothingn,false,false,convtyp,hpd);
  980. if eq=te_exact then
  981. begin
  982. search_procdef_assignment_operator:=pd^.def;
  983. exit;
  984. end;
  985. if eq>besteq then
  986. begin
  987. bestpd:=pd^.def;
  988. besteq:=eq;
  989. end;
  990. end;
  991. pd:=pd^.next;
  992. end;
  993. search_procdef_assignment_operator:=bestpd;
  994. end;
  995. procedure tprocsym.ppuwrite(ppufile:tcompilerppufile);
  996. var
  997. p : pprocdeflist;
  998. begin
  999. inherited writesym(ppufile);
  1000. p:=defs;
  1001. while assigned(p) do
  1002. begin
  1003. { only write the proc definitions that belong
  1004. to this procsym }
  1005. if (p^.def.procsym=self) then
  1006. ppufile.putderef(p^.def);
  1007. p:=p^.next;
  1008. end;
  1009. ppufile.putderef(nil);
  1010. ppufile.writeentry(ibprocsym);
  1011. end;
  1012. function tprocsym.write_references(ppufile:tcompilerppufile;locals:boolean) : boolean;
  1013. var
  1014. p : pprocdeflist;
  1015. begin
  1016. write_references:=false;
  1017. if not inherited write_references(ppufile,locals) then
  1018. exit;
  1019. write_references:=true;
  1020. p:=defs;
  1021. while assigned(p) do
  1022. begin
  1023. if (p^.def.procsym=self) then
  1024. p^.def.write_references(ppufile,locals);
  1025. p:=p^.next;
  1026. end;
  1027. end;
  1028. procedure tprocsym.unchain_overload;
  1029. var
  1030. p,hp,
  1031. first,
  1032. last : pprocdeflist;
  1033. begin
  1034. { remove all overloaded procdefs from the
  1035. procdeflist that are not in the current symtable }
  1036. first:=nil;
  1037. last:=nil;
  1038. p:=defs;
  1039. while assigned(p) do
  1040. begin
  1041. hp:=p^.next;
  1042. if (p^.def.procsym=self) then
  1043. begin
  1044. { keep in list }
  1045. if not assigned(first) then
  1046. begin
  1047. first:=p;
  1048. last:=p;
  1049. end
  1050. else
  1051. last^.next:=p;
  1052. last:=p;
  1053. p^.next:=nil;
  1054. end
  1055. else
  1056. begin
  1057. { remove }
  1058. dispose(p);
  1059. dec(procdef_count);
  1060. end;
  1061. p:=hp;
  1062. end;
  1063. defs:=first;
  1064. end;
  1065. {$ifdef GDB}
  1066. function tprocsym.stabstring : pchar;
  1067. begin
  1068. internalerror(200111171);
  1069. stabstring:=nil;
  1070. end;
  1071. procedure tprocsym.concatstabto(asmlist : taasmoutput);
  1072. begin
  1073. internalerror(200111172);
  1074. end;
  1075. {$endif GDB}
  1076. {****************************************************************************
  1077. TERRORSYM
  1078. ****************************************************************************}
  1079. constructor terrorsym.create;
  1080. begin
  1081. inherited create('');
  1082. typ:=errorsym;
  1083. end;
  1084. {****************************************************************************
  1085. TPROPERTYSYM
  1086. ****************************************************************************}
  1087. constructor tpropertysym.create(const n : string);
  1088. begin
  1089. inherited create(n);
  1090. typ:=propertysym;
  1091. propoptions:=[];
  1092. index:=0;
  1093. default:=0;
  1094. proptype.reset;
  1095. indextype.reset;
  1096. readaccess:=tsymlist.create;
  1097. writeaccess:=tsymlist.create;
  1098. storedaccess:=tsymlist.create;
  1099. end;
  1100. constructor tpropertysym.ppuload(ppufile:tcompilerppufile);
  1101. begin
  1102. inherited loadsym(ppufile);
  1103. typ:=propertysym;
  1104. ppufile.getsmallset(propoptions);
  1105. if (ppo_is_override in propoptions) then
  1106. begin
  1107. propoverriden:=tpropertysym(ppufile.getderef);
  1108. { we need to have these objects initialized }
  1109. readaccess:=tsymlist.create;
  1110. writeaccess:=tsymlist.create;
  1111. storedaccess:=tsymlist.create;
  1112. end
  1113. else
  1114. begin
  1115. ppufile.gettype(proptype);
  1116. index:=ppufile.getlongint;
  1117. default:=ppufile.getlongint;
  1118. ppufile.gettype(indextype);
  1119. readaccess:=ppufile.getsymlist;
  1120. writeaccess:=ppufile.getsymlist;
  1121. storedaccess:=ppufile.getsymlist;
  1122. end;
  1123. end;
  1124. destructor tpropertysym.destroy;
  1125. begin
  1126. readaccess.free;
  1127. writeaccess.free;
  1128. storedaccess.free;
  1129. inherited destroy;
  1130. end;
  1131. function tpropertysym.gettypedef:tdef;
  1132. begin
  1133. gettypedef:=proptype.def;
  1134. end;
  1135. procedure tpropertysym.deref;
  1136. begin
  1137. if (ppo_is_override in propoptions) then
  1138. begin
  1139. resolvesym(pointer(propoverriden));
  1140. dooverride(propoverriden);
  1141. end
  1142. else
  1143. begin
  1144. proptype.resolve;
  1145. indextype.resolve;
  1146. readaccess.resolve;
  1147. writeaccess.resolve;
  1148. storedaccess.resolve;
  1149. end;
  1150. end;
  1151. function tpropertysym.getsize : longint;
  1152. begin
  1153. getsize:=0;
  1154. end;
  1155. procedure tpropertysym.ppuwrite(ppufile:tcompilerppufile);
  1156. begin
  1157. inherited writesym(ppufile);
  1158. ppufile.putsmallset(propoptions);
  1159. if (ppo_is_override in propoptions) then
  1160. ppufile.putderef(propoverriden)
  1161. else
  1162. begin
  1163. ppufile.puttype(proptype);
  1164. ppufile.putlongint(index);
  1165. ppufile.putlongint(default);
  1166. ppufile.puttype(indextype);
  1167. ppufile.putsymlist(readaccess);
  1168. ppufile.putsymlist(writeaccess);
  1169. ppufile.putsymlist(storedaccess);
  1170. end;
  1171. ppufile.writeentry(ibpropertysym);
  1172. end;
  1173. procedure tpropertysym.dooverride(overriden:tpropertysym);
  1174. begin
  1175. propoverriden:=overriden;
  1176. proptype:=overriden.proptype;
  1177. propoptions:=overriden.propoptions+[ppo_is_override];
  1178. index:=overriden.index;
  1179. default:=overriden.default;
  1180. indextype:=overriden.indextype;
  1181. readaccess.free;
  1182. readaccess:=overriden.readaccess.getcopy;
  1183. writeaccess.free;
  1184. writeaccess:=overriden.writeaccess.getcopy;
  1185. storedaccess.free;
  1186. storedaccess:=overriden.storedaccess.getcopy;
  1187. end;
  1188. {$ifdef GDB}
  1189. function tpropertysym.stabstring : pchar;
  1190. begin
  1191. { !!!! don't know how to handle }
  1192. stabstring:=strpnew('');
  1193. end;
  1194. procedure tpropertysym.concatstabto(asmlist : taasmoutput);
  1195. begin
  1196. { !!!! don't know how to handle }
  1197. end;
  1198. {$endif GDB}
  1199. {****************************************************************************
  1200. TFUNCRETSYM
  1201. ****************************************************************************}
  1202. constructor tfuncretsym.create(const n : string;const tt:ttype);
  1203. begin
  1204. inherited create(n);
  1205. typ:=funcretsym;
  1206. returntype:=tt;
  1207. funcretstate:=vs_declared;
  1208. { address valid for ret in param only }
  1209. { otherwise set by insert }
  1210. address:=procinfo.return_offset;
  1211. end;
  1212. constructor tfuncretsym.ppuload(ppufile:tcompilerppufile);
  1213. begin
  1214. inherited loadsym(ppufile);
  1215. ppufile.gettype(returntype);
  1216. address:=ppufile.getlongint;
  1217. typ:=funcretsym;
  1218. end;
  1219. destructor tfuncretsym.destroy;
  1220. begin
  1221. inherited destroy;
  1222. end;
  1223. procedure tfuncretsym.ppuwrite(ppufile:tcompilerppufile);
  1224. begin
  1225. inherited writesym(ppufile);
  1226. ppufile.puttype(returntype);
  1227. ppufile.putlongint(address);
  1228. ppufile.writeentry(ibfuncretsym);
  1229. funcretstate:=vs_used;
  1230. end;
  1231. procedure tfuncretsym.deref;
  1232. begin
  1233. returntype.resolve;
  1234. end;
  1235. {$ifdef GDB}
  1236. procedure tfuncretsym.concatstabto(asmlist : taasmoutput);
  1237. begin
  1238. { Nothing to do here, it is done in genexitcode }
  1239. end;
  1240. {$endif GDB}
  1241. {****************************************************************************
  1242. TABSOLUTESYM
  1243. ****************************************************************************}
  1244. constructor tabsolutesym.create(const n : string;const tt : ttype);
  1245. begin
  1246. inherited create(n,tt);
  1247. typ:=absolutesym;
  1248. end;
  1249. constructor tabsolutesym.ppuload(ppufile:tcompilerppufile);
  1250. begin
  1251. { Note: This needs to load everything of tvarsym.write }
  1252. inherited ppuload(ppufile);
  1253. { load absolute }
  1254. typ:=absolutesym;
  1255. ref:=nil;
  1256. address:=0;
  1257. asmname:=nil;
  1258. abstyp:=absolutetyp(ppufile.getbyte);
  1259. absseg:=false;
  1260. case abstyp of
  1261. tovar :
  1262. asmname:=stringdup(ppufile.getstring);
  1263. toasm :
  1264. asmname:=stringdup(ppufile.getstring);
  1265. toaddr :
  1266. begin
  1267. address:=ppufile.getlongint;
  1268. absseg:=boolean(ppufile.getbyte);
  1269. end;
  1270. end;
  1271. end;
  1272. procedure tabsolutesym.ppuwrite(ppufile:tcompilerppufile);
  1273. var
  1274. hvo : tvaroptions;
  1275. begin
  1276. { Note: This needs to write everything of tvarsym.write }
  1277. inherited writesym(ppufile);
  1278. ppufile.putbyte(byte(varspez));
  1279. ppufile.putlongint(address);
  1280. { write only definition or definitionsym }
  1281. ppufile.puttype(vartype);
  1282. hvo:=varoptions-[vo_regable];
  1283. ppufile.putsmallset(hvo);
  1284. ppufile.putbyte(byte(abstyp));
  1285. case abstyp of
  1286. tovar :
  1287. ppufile.putstring(ref.name);
  1288. toasm :
  1289. ppufile.putstring(asmname^);
  1290. toaddr :
  1291. begin
  1292. ppufile.putlongint(address);
  1293. ppufile.putbyte(byte(absseg));
  1294. end;
  1295. end;
  1296. ppufile.writeentry(ibabsolutesym);
  1297. end;
  1298. procedure tabsolutesym.deref;
  1299. var
  1300. srsym : tsym;
  1301. srsymtable : tsymtable;
  1302. begin
  1303. { inheritance of varsym.deref ! }
  1304. vartype.resolve;
  1305. { own absolute deref }
  1306. if (abstyp=tovar) and (asmname<>nil) then
  1307. begin
  1308. { search previous loaded symtables }
  1309. searchsym(asmname^,srsym,srsymtable);
  1310. if not assigned(srsym) then
  1311. srsym:=searchsymonlyin(owner,asmname^);
  1312. if not assigned(srsym) then
  1313. srsym:=generrorsym;
  1314. ref:=tstoredsym(srsym);
  1315. stringdispose(asmname);
  1316. end;
  1317. end;
  1318. function tabsolutesym.mangledname : string;
  1319. begin
  1320. case abstyp of
  1321. tovar :
  1322. begin
  1323. case ref.typ of
  1324. varsym :
  1325. mangledname:=tvarsym(ref).mangledname;
  1326. else
  1327. internalerror(200111011);
  1328. end;
  1329. end;
  1330. toasm :
  1331. mangledname:=asmname^;
  1332. toaddr :
  1333. mangledname:='$'+tostr(address);
  1334. else
  1335. internalerror(10002);
  1336. end;
  1337. end;
  1338. {$ifdef GDB}
  1339. procedure tabsolutesym.concatstabto(asmlist : taasmoutput);
  1340. begin
  1341. { I don't know how to handle this !! }
  1342. end;
  1343. {$endif GDB}
  1344. {****************************************************************************
  1345. TVARSYM
  1346. ****************************************************************************}
  1347. constructor tvarsym.create(const n : string;const tt : ttype);
  1348. begin
  1349. inherited create(n);
  1350. typ:=varsym;
  1351. vartype:=tt;
  1352. _mangledname:=nil;
  1353. varspez:=vs_value;
  1354. address:=0;
  1355. localvarsym:=nil;
  1356. refs:=0;
  1357. varstate:=vs_used;
  1358. varoptions:=[];
  1359. { can we load the value into a register ? }
  1360. if tstoreddef(tt.def).is_intregable then
  1361. include(varoptions,vo_regable)
  1362. else
  1363. exclude(varoptions,vo_regable);
  1364. if tstoreddef(tt.def).is_fpuregable then
  1365. include(varoptions,vo_fpuregable)
  1366. else
  1367. exclude(varoptions,vo_fpuregable);
  1368. reg:=R_NO;
  1369. end;
  1370. constructor tvarsym.create_dll(const n : string;const tt : ttype);
  1371. begin
  1372. tvarsym(self).create(n,tt);
  1373. include(varoptions,vo_is_dll_var);
  1374. end;
  1375. constructor tvarsym.create_C(const n,mangled : string;const tt : ttype);
  1376. begin
  1377. tvarsym(self).create(n,tt);
  1378. stringdispose(_mangledname);
  1379. _mangledname:=stringdup(mangled);
  1380. end;
  1381. constructor tvarsym.ppuload(ppufile:tcompilerppufile);
  1382. begin
  1383. inherited loadsym(ppufile);
  1384. typ:=varsym;
  1385. reg:=R_NO;
  1386. refs := 0;
  1387. varstate:=vs_used;
  1388. varspez:=tvarspez(ppufile.getbyte);
  1389. address:=ppufile.getlongint;
  1390. localvarsym:=nil;
  1391. ppufile.gettype(vartype);
  1392. ppufile.getsmallset(varoptions);
  1393. if (vo_is_C_var in varoptions) then
  1394. _mangledname:=stringdup(ppufile.getstring);
  1395. end;
  1396. destructor tvarsym.destroy;
  1397. begin
  1398. {$ifdef var_notification}
  1399. if assigned(notifications) then
  1400. notifications.destroy;
  1401. {$endif}
  1402. inherited destroy;
  1403. end;
  1404. procedure tvarsym.deref;
  1405. begin
  1406. vartype.resolve;
  1407. end;
  1408. procedure tvarsym.ppuwrite(ppufile:tcompilerppufile);
  1409. var
  1410. hvo : tvaroptions;
  1411. begin
  1412. inherited writesym(ppufile);
  1413. ppufile.putbyte(byte(varspez));
  1414. ppufile.putlongint(address);
  1415. ppufile.puttype(vartype);
  1416. { symbols which are load are never candidates for a register,
  1417. turn off the regable }
  1418. hvo:=varoptions-[vo_regable,vo_fpuregable];
  1419. ppufile.putsmallset(hvo);
  1420. if (vo_is_C_var in varoptions) then
  1421. ppufile.putstring(mangledname);
  1422. ppufile.writeentry(ibvarsym);
  1423. end;
  1424. procedure tvarsym.generate_mangledname;
  1425. begin
  1426. _mangledname:=stringdup(mangledname_prefix('U',owner)+name);
  1427. end;
  1428. procedure tvarsym.set_mangledname(const s:string);
  1429. begin
  1430. stringdispose(_mangledname);
  1431. _mangledname:=stringdup(s);
  1432. end;
  1433. function tvarsym.getsize : longint;
  1434. begin
  1435. if assigned(vartype.def) then
  1436. getsize:=vartype.def.size
  1437. else
  1438. getsize:=0;
  1439. end;
  1440. function tvarsym.getvaluesize : longint;
  1441. begin
  1442. if assigned(vartype.def) and
  1443. (varspez=vs_value) and
  1444. ((vartype.def.deftype<>arraydef) or
  1445. tarraydef(vartype.def).isDynamicArray or
  1446. (tarraydef(vartype.def).highrange>=tarraydef(vartype.def).lowrange)) then
  1447. getvaluesize:=vartype.def.size
  1448. else
  1449. getvaluesize:=0;
  1450. end;
  1451. function tvarsym.getpushsize(calloption:tproccalloption) : longint;
  1452. begin
  1453. getpushsize:=-1;
  1454. if assigned(vartype.def) then
  1455. begin
  1456. case varspez of
  1457. vs_out,
  1458. vs_var :
  1459. getpushsize:=pointer_size;
  1460. vs_value,
  1461. vs_const :
  1462. begin
  1463. if paramanager.push_addr_param(vartype.def,calloption) then
  1464. getpushsize:=pointer_size
  1465. else
  1466. getpushsize:=vartype.def.size;
  1467. end;
  1468. end;
  1469. end;
  1470. end;
  1471. {$ifdef var_notification}
  1472. function Tvarsym.register_notification(flags:Tnotification_flags;callback:
  1473. Tnotification_callback):cardinal;
  1474. var n:Tnotification;
  1475. begin
  1476. if not assigned(notifications) then
  1477. notifications:=Tlinkedlist.create;
  1478. n:=Tnotification.create(flags,callback);
  1479. register_notification:=n.id;
  1480. notifications.concat(n);
  1481. end;
  1482. {$endif}
  1483. {$ifdef GDB}
  1484. function tvarsym.stabstring : pchar;
  1485. var
  1486. st : string;
  1487. begin
  1488. st:=tstoreddef(vartype.def).numberstring;
  1489. if (owner.symtabletype = objectsymtable) and
  1490. (sp_static in symoptions) then
  1491. begin
  1492. if (cs_gdb_gsym in aktglobalswitches) then st := 'G'+st else st := 'S'+st;
  1493. stabstring := strpnew('"'+owner.name^+'__'+name+':'+st+
  1494. '",'+
  1495. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1496. end
  1497. else if (owner.symtabletype = globalsymtable) then
  1498. begin
  1499. { Here we used S instead of
  1500. because with G GDB doesn't look at the address field
  1501. but searches the same name or with a leading underscore
  1502. but these names don't exist in pascal !}
  1503. if (cs_gdb_gsym in aktglobalswitches) then st := 'G'+st else st := 'S'+st;
  1504. stabstring := strpnew('"'+name+':'+st+'",'+
  1505. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1506. end
  1507. else if owner.symtabletype = staticsymtable then
  1508. begin
  1509. stabstring := strpnew('"'+name+':S'+st+'",'+
  1510. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname);
  1511. end
  1512. else if (owner.symtabletype in [parasymtable,inlineparasymtable]) then
  1513. begin
  1514. case varspez of
  1515. vs_out,
  1516. vs_var : st := 'v'+st;
  1517. vs_value,
  1518. vs_const : if paramanager.push_addr_param(vartype.def,tprocdef(owner.defowner).proccalloption) then
  1519. st := 'v'+st { should be 'i' but 'i' doesn't work }
  1520. else
  1521. st := 'p'+st;
  1522. end;
  1523. stabstring := strpnew('"'+name+':'+st+'",'+
  1524. tostr(N_tsym)+',0,'+tostr(fileinfo.line)+','+
  1525. tostr(address+owner.address_fixup));
  1526. {offset to ebp => will not work if the framepointer is esp
  1527. so some optimizing will make things harder to debug }
  1528. end
  1529. else if (owner.symtabletype in [localsymtable,inlinelocalsymtable]) then
  1530. if reg<>R_NO then
  1531. begin
  1532. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1533. { this is the register order for GDB}
  1534. stabstring:=strpnew('"'+name+':r'+st+'",'+
  1535. tostr(N_RSYM)+',0,'+
  1536. tostr(fileinfo.line)+','+tostr(stab_regindex[reg]));
  1537. end
  1538. else
  1539. { I don't know if this will work (PM) }
  1540. if (vo_is_C_var in varoptions) then
  1541. stabstring := strpnew('"'+name+':S'+st+'",'+
  1542. tostr(N_LCSYM)+',0,'+tostr(fileinfo.line)+','+mangledname)
  1543. else
  1544. stabstring := strpnew('"'+name+':'+st+'",'+
  1545. tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',-'+tostr(address-owner.address_fixup))
  1546. else
  1547. stabstring := inherited stabstring;
  1548. end;
  1549. procedure tvarsym.concatstabto(asmlist : taasmoutput);
  1550. var stab_str : pchar;
  1551. begin
  1552. inherited concatstabto(asmlist);
  1553. if (owner.symtabletype=parasymtable) and
  1554. (reg<>R_NO) then
  1555. begin
  1556. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1557. { this is the register order for GDB}
  1558. stab_str:=strpnew('"'+name+':r'
  1559. +tstoreddef(vartype.def).numberstring+'",'+
  1560. tostr(N_RSYM)+',0,'+
  1561. tostr(fileinfo.line)+','+tostr(stab_regindex[reg]));
  1562. asmList.concat(Tai_stabs.Create(stab_str));
  1563. end;
  1564. end;
  1565. {$endif GDB}
  1566. {****************************************************************************
  1567. TTYPEDCONSTSYM
  1568. *****************************************************************************}
  1569. constructor ttypedconstsym.create(const n : string;p : tdef;writable : boolean);
  1570. begin
  1571. inherited create(n);
  1572. typ:=typedconstsym;
  1573. typedconsttype.setdef(p);
  1574. is_writable:=writable;
  1575. end;
  1576. constructor ttypedconstsym.createtype(const n : string;const tt : ttype;writable : boolean);
  1577. begin
  1578. inherited create(n);
  1579. typ:=typedconstsym;
  1580. typedconsttype:=tt;
  1581. is_writable:=writable;
  1582. end;
  1583. constructor ttypedconstsym.ppuload(ppufile:tcompilerppufile);
  1584. begin
  1585. inherited loadsym(ppufile);
  1586. typ:=typedconstsym;
  1587. ppufile.gettype(typedconsttype);
  1588. is_writable:=boolean(ppufile.getbyte);
  1589. end;
  1590. destructor ttypedconstsym.destroy;
  1591. begin
  1592. inherited destroy;
  1593. end;
  1594. procedure ttypedconstsym.generate_mangledname;
  1595. begin
  1596. _mangledname:=stringdup(mangledname_prefix('TC',owner)+name);
  1597. end;
  1598. function ttypedconstsym.getsize : longint;
  1599. begin
  1600. if assigned(typedconsttype.def) then
  1601. getsize:=typedconsttype.def.size
  1602. else
  1603. getsize:=0;
  1604. end;
  1605. procedure ttypedconstsym.deref;
  1606. begin
  1607. typedconsttype.resolve;
  1608. end;
  1609. procedure ttypedconstsym.ppuwrite(ppufile:tcompilerppufile);
  1610. begin
  1611. inherited writesym(ppufile);
  1612. ppufile.puttype(typedconsttype);
  1613. ppufile.putbyte(byte(is_writable));
  1614. ppufile.writeentry(ibtypedconstsym);
  1615. end;
  1616. {$ifdef GDB}
  1617. function ttypedconstsym.stabstring : pchar;
  1618. var
  1619. st : char;
  1620. begin
  1621. if (cs_gdb_gsym in aktglobalswitches) and (owner.symtabletype=globalsymtable) then
  1622. st := 'G'
  1623. else
  1624. st := 'S';
  1625. stabstring := strpnew('"'+name+':'+st+
  1626. tstoreddef(typedconsttype.def).numberstring+'",'+tostr(n_STSYM)+',0,'+
  1627. tostr(fileinfo.line)+','+mangledname);
  1628. end;
  1629. {$endif GDB}
  1630. {****************************************************************************
  1631. TCONSTSYM
  1632. ****************************************************************************}
  1633. constructor tconstsym.create_ord(const n : string;t : tconsttyp;v : TConstExprInt);
  1634. begin
  1635. inherited create(n);
  1636. fillchar(value, sizeof(value), #0);
  1637. typ:=constsym;
  1638. consttyp:=t;
  1639. value.valueord:=v;
  1640. ResStrIndex:=0;
  1641. consttype.reset;
  1642. end;
  1643. constructor tconstsym.create_ord_typed(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  1644. begin
  1645. inherited create(n);
  1646. fillchar(value, sizeof(value), #0);
  1647. typ:=constsym;
  1648. consttyp:=t;
  1649. value.valueord:=v;
  1650. ResStrIndex:=0;
  1651. consttype:=tt;
  1652. end;
  1653. constructor tconstsym.create_ordptr_typed(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  1654. begin
  1655. inherited create(n);
  1656. fillchar(value, sizeof(value), #0);
  1657. typ:=constsym;
  1658. consttyp:=t;
  1659. value.valueordptr:=v;
  1660. ResStrIndex:=0;
  1661. consttype:=tt;
  1662. end;
  1663. constructor tconstsym.create_ptr(const n : string;t : tconsttyp;v : pointer);
  1664. begin
  1665. inherited create(n);
  1666. fillchar(value, sizeof(value), #0);
  1667. typ:=constsym;
  1668. consttyp:=t;
  1669. value.valueptr:=v;
  1670. ResStrIndex:=0;
  1671. consttype.reset;
  1672. end;
  1673. constructor tconstsym.create_ptr_typed(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  1674. begin
  1675. inherited create(n);
  1676. fillchar(value, sizeof(value), #0);
  1677. typ:=constsym;
  1678. consttyp:=t;
  1679. value.valueptr:=v;
  1680. ResStrIndex:=0;
  1681. consttype:=tt;
  1682. end;
  1683. constructor tconstsym.create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  1684. begin
  1685. inherited create(n);
  1686. fillchar(value, sizeof(value), #0);
  1687. typ:=constsym;
  1688. consttyp:=t;
  1689. value.valueptr:=str;
  1690. consttype.reset;
  1691. value.len:=l;
  1692. if t=constresourcestring then
  1693. ResStrIndex:=ResourceStrings.Register(name,pchar(value.valueptr),value.len);
  1694. end;
  1695. constructor tconstsym.ppuload(ppufile:tcompilerppufile);
  1696. var
  1697. pd : pbestreal;
  1698. ps : pnormalset;
  1699. pc : pchar;
  1700. begin
  1701. inherited loadsym(ppufile);
  1702. typ:=constsym;
  1703. consttype.reset;
  1704. consttyp:=tconsttyp(ppufile.getbyte);
  1705. fillchar(value, sizeof(value), #0);
  1706. case consttyp of
  1707. constint:
  1708. value.valueord:=ppufile.getexprint;
  1709. constwchar,
  1710. constbool,
  1711. constchar :
  1712. value.valueord:=ppufile.getlongint;
  1713. constord :
  1714. begin
  1715. ppufile.gettype(consttype);
  1716. value.valueord:=ppufile.getexprint;
  1717. end;
  1718. constpointer :
  1719. begin
  1720. ppufile.gettype(consttype);
  1721. value.valueordptr:=ppufile.getptruint;
  1722. end;
  1723. conststring,
  1724. constresourcestring :
  1725. begin
  1726. value.len:=ppufile.getlongint;
  1727. getmem(pc,value.len+1);
  1728. ppufile.getdata(pc^,value.len);
  1729. if consttyp=constresourcestring then
  1730. ResStrIndex:=ppufile.getlongint;
  1731. value.valueptr:=pc;
  1732. end;
  1733. constreal :
  1734. begin
  1735. new(pd);
  1736. pd^:=ppufile.getreal;
  1737. value.valueptr:=pd;
  1738. end;
  1739. constset :
  1740. begin
  1741. ppufile.gettype(consttype);
  1742. new(ps);
  1743. ppufile.getnormalset(ps^);
  1744. value.valueptr:=ps;
  1745. end;
  1746. constguid :
  1747. begin
  1748. new(pguid(value.valueptr));
  1749. ppufile.getdata(value.valueptr^,sizeof(tguid));
  1750. end;
  1751. constnil : ;
  1752. else
  1753. Message1(unit_f_ppu_invalid_entry,tostr(ord(consttyp)));
  1754. end;
  1755. end;
  1756. destructor tconstsym.destroy;
  1757. begin
  1758. case consttyp of
  1759. conststring,
  1760. constresourcestring :
  1761. freemem(pchar(value.valueptr),value.len+1);
  1762. constreal :
  1763. dispose(pbestreal(value.valueptr));
  1764. constset :
  1765. dispose(pnormalset(value.valueptr));
  1766. constguid :
  1767. dispose(pguid(value.valueptr));
  1768. end;
  1769. inherited destroy;
  1770. end;
  1771. function tconstsym.mangledname : string;
  1772. begin
  1773. mangledname:=name;
  1774. end;
  1775. procedure tconstsym.deref;
  1776. begin
  1777. if consttyp in [constord,constpointer,constset] then
  1778. consttype.resolve;
  1779. end;
  1780. procedure tconstsym.ppuwrite(ppufile:tcompilerppufile);
  1781. begin
  1782. inherited writesym(ppufile);
  1783. ppufile.putbyte(byte(consttyp));
  1784. case consttyp of
  1785. constnil : ;
  1786. constint:
  1787. ppufile.putexprint(value.valueord);
  1788. constbool,
  1789. constchar :
  1790. ppufile.putlongint(value.valueord);
  1791. constord :
  1792. begin
  1793. ppufile.puttype(consttype);
  1794. ppufile.putexprint(value.valueord);
  1795. end;
  1796. constpointer :
  1797. begin
  1798. ppufile.puttype(consttype);
  1799. ppufile.putptruint(value.valueordptr);
  1800. end;
  1801. conststring,
  1802. constresourcestring :
  1803. begin
  1804. ppufile.putlongint(value.len);
  1805. ppufile.putdata(pchar(value.valueptr)^,value.len);
  1806. if consttyp=constresourcestring then
  1807. ppufile.putlongint(ResStrIndex);
  1808. end;
  1809. constreal :
  1810. ppufile.putreal(pbestreal(value.valueptr)^);
  1811. constset :
  1812. begin
  1813. ppufile.puttype(consttype);
  1814. ppufile.putnormalset(value.valueptr^);
  1815. end;
  1816. constguid :
  1817. ppufile.putdata(value.valueptr^,sizeof(tguid));
  1818. else
  1819. internalerror(13);
  1820. end;
  1821. ppufile.writeentry(ibconstsym);
  1822. end;
  1823. {$ifdef GDB}
  1824. function tconstsym.stabstring : pchar;
  1825. var st : string;
  1826. begin
  1827. {even GDB v4.16 only now 'i' 'r' and 'e' !!!}
  1828. case consttyp of
  1829. conststring : begin
  1830. st := 's'''+strpas(pchar(value.valueptr))+'''';
  1831. end;
  1832. constbool,
  1833. constint,
  1834. constord,
  1835. constchar : st := 'i'+int64tostr(value.valueord);
  1836. constpointer :
  1837. st := 'i'+int64tostr(value.valueordptr);
  1838. constreal : begin
  1839. system.str(pbestreal(value.valueptr)^,st);
  1840. st := 'r'+st;
  1841. end;
  1842. { if we don't know just put zero !! }
  1843. else st:='i0';
  1844. {***SETCONST}
  1845. {constset:;} {*** I don't know what to do with a set.}
  1846. { sets are not recognized by GDB}
  1847. {***}
  1848. end;
  1849. stabstring := strpnew('"'+name+':c='+st+'",'+tostr(N_function)+',0,'+
  1850. tostr(fileinfo.line)+',0');
  1851. end;
  1852. procedure tconstsym.concatstabto(asmlist : taasmoutput);
  1853. begin
  1854. if consttyp <> conststring then
  1855. inherited concatstabto(asmlist);
  1856. end;
  1857. {$endif GDB}
  1858. {****************************************************************************
  1859. TENUMSYM
  1860. ****************************************************************************}
  1861. constructor tenumsym.create(const n : string;def : tenumdef;v : longint);
  1862. begin
  1863. inherited create(n);
  1864. typ:=enumsym;
  1865. definition:=def;
  1866. value:=v;
  1867. { check for jumps }
  1868. if v>def.max+1 then
  1869. def.has_jumps:=true;
  1870. { update low and high }
  1871. if def.min>v then
  1872. def.setmin(v);
  1873. if def.max<v then
  1874. def.setmax(v);
  1875. order;
  1876. end;
  1877. constructor tenumsym.ppuload(ppufile:tcompilerppufile);
  1878. begin
  1879. inherited loadsym(ppufile);
  1880. typ:=enumsym;
  1881. definition:=tenumdef(ppufile.getderef);
  1882. value:=ppufile.getlongint;
  1883. nextenum := Nil;
  1884. end;
  1885. procedure tenumsym.deref;
  1886. begin
  1887. resolvedef(pointer(definition));
  1888. order;
  1889. end;
  1890. procedure tenumsym.order;
  1891. var
  1892. sym : tenumsym;
  1893. begin
  1894. sym := tenumsym(definition.firstenum);
  1895. if sym = nil then
  1896. begin
  1897. definition.firstenum := self;
  1898. nextenum := nil;
  1899. exit;
  1900. end;
  1901. { reorder the symbols in increasing value }
  1902. if value < sym.value then
  1903. begin
  1904. nextenum := sym;
  1905. definition.firstenum := self;
  1906. end
  1907. else
  1908. begin
  1909. while (sym.value <= value) and assigned(sym.nextenum) do
  1910. sym := sym.nextenum;
  1911. nextenum := sym.nextenum;
  1912. sym.nextenum := self;
  1913. end;
  1914. end;
  1915. procedure tenumsym.ppuwrite(ppufile:tcompilerppufile);
  1916. begin
  1917. inherited writesym(ppufile);
  1918. ppufile.putderef(definition);
  1919. ppufile.putlongint(value);
  1920. ppufile.writeentry(ibenumsym);
  1921. end;
  1922. {$ifdef GDB}
  1923. procedure tenumsym.concatstabto(asmlist : taasmoutput);
  1924. begin
  1925. {enum elements have no stab !}
  1926. end;
  1927. {$EndIf GDB}
  1928. {****************************************************************************
  1929. TTYPESYM
  1930. ****************************************************************************}
  1931. constructor ttypesym.create(const n : string;const tt : ttype);
  1932. begin
  1933. inherited create(n);
  1934. typ:=typesym;
  1935. restype:=tt;
  1936. {$ifdef GDB}
  1937. isusedinstab := false;
  1938. {$endif GDB}
  1939. { register the typesym for the definition }
  1940. if assigned(restype.def) and
  1941. (restype.def.deftype<>errordef) and
  1942. not(assigned(restype.def.typesym)) then
  1943. restype.def.typesym:=self;
  1944. end;
  1945. constructor ttypesym.ppuload(ppufile:tcompilerppufile);
  1946. begin
  1947. inherited loadsym(ppufile);
  1948. typ:=typesym;
  1949. {$ifdef GDB}
  1950. isusedinstab := false;
  1951. {$endif GDB}
  1952. ppufile.gettype(restype);
  1953. end;
  1954. function ttypesym.gettypedef:tdef;
  1955. begin
  1956. gettypedef:=restype.def;
  1957. end;
  1958. procedure ttypesym.deref;
  1959. begin
  1960. restype.resolve;
  1961. end;
  1962. procedure ttypesym.ppuwrite(ppufile:tcompilerppufile);
  1963. begin
  1964. inherited writesym(ppufile);
  1965. ppufile.puttype(restype);
  1966. ppufile.writeentry(ibtypesym);
  1967. end;
  1968. procedure ttypesym.load_references(ppufile:tcompilerppufile;locals:boolean);
  1969. begin
  1970. inherited load_references(ppufile,locals);
  1971. if (restype.def.deftype=recorddef) then
  1972. tstoredsymtable(trecorddef(restype.def).symtable).load_references(ppufile,locals);
  1973. if (restype.def.deftype=objectdef) then
  1974. tstoredsymtable(tobjectdef(restype.def).symtable).load_references(ppufile,locals);
  1975. end;
  1976. function ttypesym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  1977. begin
  1978. if not inherited write_references(ppufile,locals) then
  1979. begin
  1980. { write address of this symbol if record or object
  1981. even if no real refs are there
  1982. because we need it for the symtable }
  1983. if (restype.def.deftype in [recorddef,objectdef]) then
  1984. begin
  1985. ppufile.putderef(self);
  1986. ppufile.writeentry(ibsymref);
  1987. end;
  1988. end;
  1989. write_references:=true;
  1990. if (restype.def.deftype=recorddef) then
  1991. tstoredsymtable(trecorddef(restype.def).symtable).write_references(ppufile,locals);
  1992. if (restype.def.deftype=objectdef) then
  1993. tstoredsymtable(tobjectdef(restype.def).symtable).write_references(ppufile,locals);
  1994. end;
  1995. {$ifdef GDB}
  1996. function ttypesym.stabstring : pchar;
  1997. var
  1998. stabchar : string[2];
  1999. short : string;
  2000. begin
  2001. if restype.def.deftype in tagtypes then
  2002. stabchar := 'Tt'
  2003. else
  2004. stabchar := 't';
  2005. short := '"'+name+':'+stabchar+tstoreddef(restype.def).numberstring
  2006. +'",'+tostr(N_LSYM)+',0,'+tostr(fileinfo.line)+',0';
  2007. stabstring := strpnew(short);
  2008. end;
  2009. procedure ttypesym.concatstabto(asmlist : taasmoutput);
  2010. begin
  2011. {not stabs for forward defs }
  2012. if assigned(restype.def) then
  2013. if (restype.def.typesym = self) then
  2014. tstoreddef(restype.def).concatstabto(asmlist)
  2015. else
  2016. inherited concatstabto(asmlist);
  2017. end;
  2018. {$endif GDB}
  2019. {****************************************************************************
  2020. TSYSSYM
  2021. ****************************************************************************}
  2022. constructor tsyssym.create(const n : string;l : longint);
  2023. begin
  2024. inherited create(n);
  2025. typ:=syssym;
  2026. number:=l;
  2027. end;
  2028. constructor tsyssym.ppuload(ppufile:tcompilerppufile);
  2029. begin
  2030. inherited loadsym(ppufile);
  2031. typ:=syssym;
  2032. number:=ppufile.getlongint;
  2033. end;
  2034. destructor tsyssym.destroy;
  2035. begin
  2036. inherited destroy;
  2037. end;
  2038. procedure tsyssym.ppuwrite(ppufile:tcompilerppufile);
  2039. begin
  2040. inherited writesym(ppufile);
  2041. ppufile.putlongint(number);
  2042. ppufile.writeentry(ibsyssym);
  2043. end;
  2044. {$ifdef GDB}
  2045. procedure tsyssym.concatstabto(asmlist : taasmoutput);
  2046. begin
  2047. end;
  2048. {$endif GDB}
  2049. {****************************************************************************
  2050. TRTTISYM
  2051. ****************************************************************************}
  2052. constructor trttisym.create(const n:string;rt:trttitype);
  2053. const
  2054. prefix : array[trttitype] of string[5]=('$rtti','$init');
  2055. begin
  2056. inherited create(prefix[rt]+n);
  2057. typ:=rttisym;
  2058. lab:=nil;
  2059. rttityp:=rt;
  2060. end;
  2061. constructor trttisym.ppuload(ppufile:tcompilerppufile);
  2062. begin
  2063. inherited loadsym(ppufile);
  2064. typ:=rttisym;
  2065. lab:=nil;
  2066. rttityp:=trttitype(ppufile.getbyte);
  2067. end;
  2068. procedure trttisym.ppuwrite(ppufile:tcompilerppufile);
  2069. begin
  2070. inherited writesym(ppufile);
  2071. ppufile.putbyte(byte(rttityp));
  2072. ppufile.writeentry(ibrttisym);
  2073. end;
  2074. function trttisym.mangledname : string;
  2075. const
  2076. prefix : array[trttitype] of string[5]=('RTTI_','INIT_');
  2077. var
  2078. s : string;
  2079. p : tsymtable;
  2080. begin
  2081. s:='';
  2082. p:=owner;
  2083. while assigned(p) and (p.symtabletype=localsymtable) do
  2084. begin
  2085. s:=s+'_'+p.defowner.name;
  2086. p:=p.defowner.owner;
  2087. end;
  2088. if not(p.symtabletype in [globalsymtable,staticsymtable]) then
  2089. internalerror(200108265);
  2090. mangledname:=prefix[rttityp]+p.name^+s+'$_'+Copy(name,5,255);
  2091. end;
  2092. function trttisym.get_label:tasmsymbol;
  2093. begin
  2094. { the label is always a global label }
  2095. if not assigned(lab) then
  2096. lab:=objectlibrary.newasmsymboltype(mangledname,AB_GLOBAL,AT_DATA);
  2097. get_label:=lab;
  2098. end;
  2099. { persistent rtti generation }
  2100. procedure generate_rtti(p:tsym);
  2101. var
  2102. rsym : trttisym;
  2103. def : tstoreddef;
  2104. begin
  2105. { rtti can only be generated for classes that are always typesyms }
  2106. if not(p.typ=typesym) then
  2107. internalerror(200108261);
  2108. def:=tstoreddef(ttypesym(p).restype.def);
  2109. { only create rtti once for each definition }
  2110. if not(df_has_rttitable in def.defoptions) then
  2111. begin
  2112. { definition should be in the same symtable as the symbol }
  2113. if p.owner<>def.owner then
  2114. internalerror(200108262);
  2115. { create rttisym }
  2116. rsym:=trttisym.create(p.name,fullrtti);
  2117. p.owner.insert(rsym);
  2118. { register rttisym in definition }
  2119. include(def.defoptions,df_has_rttitable);
  2120. def.rttitablesym:=rsym;
  2121. { write rtti data }
  2122. def.write_child_rtti_data(fullrtti);
  2123. if (cs_create_smart in aktmoduleswitches) then
  2124. rttiList.concat(Tai_cut.Create);
  2125. rttilist.concat(tai_align.create(const_align(pointer_size)));
  2126. rttiList.concat(Tai_symbol.Create(rsym.get_label,0));
  2127. def.write_rtti_data(fullrtti);
  2128. rttiList.concat(Tai_symbol_end.Create(rsym.get_label));
  2129. end;
  2130. end;
  2131. { persistent init table generation }
  2132. procedure generate_inittable(p:tsym);
  2133. var
  2134. rsym : trttisym;
  2135. def : tstoreddef;
  2136. begin
  2137. { anonymous types are also allowed for records that can be varsym }
  2138. case p.typ of
  2139. typesym :
  2140. def:=tstoreddef(ttypesym(p).restype.def);
  2141. varsym :
  2142. def:=tstoreddef(tvarsym(p).vartype.def);
  2143. else
  2144. internalerror(200108263);
  2145. end;
  2146. { only create inittable once for each definition }
  2147. if not(df_has_inittable in def.defoptions) then
  2148. begin
  2149. { definition should be in the same symtable as the symbol }
  2150. if p.owner<>def.owner then
  2151. internalerror(200108264);
  2152. { create rttisym }
  2153. rsym:=trttisym.create(p.name,initrtti);
  2154. p.owner.insert(rsym);
  2155. { register rttisym in definition }
  2156. include(def.defoptions,df_has_inittable);
  2157. def.inittablesym:=rsym;
  2158. { write inittable data }
  2159. def.write_child_rtti_data(initrtti);
  2160. if (cs_create_smart in aktmoduleswitches) then
  2161. rttiList.concat(Tai_cut.Create);
  2162. rttilist.concat(tai_align.create(const_align(pointer_size)));
  2163. rttiList.concat(Tai_symbol.Create(rsym.get_label,0));
  2164. def.write_rtti_data(initrtti);
  2165. rttiList.concat(Tai_symbol_end.Create(rsym.get_label));
  2166. end;
  2167. end;
  2168. end.
  2169. {
  2170. $Log$
  2171. Revision 1.76 2002-11-25 17:43:26 peter
  2172. * splitted defbase in defutil,symutil,defcmp
  2173. * merged isconvertable and is_equal into compare_defs(_ext)
  2174. * made operator search faster by walking the list only once
  2175. Revision 1.75 2002/11/23 22:50:09 carl
  2176. * some small speed optimizations
  2177. + added several new warnings/hints
  2178. Revision 1.74 2002/11/22 22:48:11 carl
  2179. * memory optimization with tconstsym (1.5%)
  2180. Revision 1.73 2002/11/18 17:31:59 peter
  2181. * pass proccalloption to ret_in_xxx and push_xxx functions
  2182. Revision 1.72 2002/11/17 16:31:57 carl
  2183. * memory optimization (3-4%) : cleanup of tai fields,
  2184. cleanup of tdef and tsym fields.
  2185. * make it work for m68k
  2186. Revision 1.71 2002/11/09 15:30:07 carl
  2187. + align RTTI tables
  2188. Revision 1.70 2002/10/13 21:33:37 peter
  2189. * give correct fileposition for undefined forward procs
  2190. Revision 1.69 2002/10/05 12:43:29 carl
  2191. * fixes for Delphi 6 compilation
  2192. (warning : Some features do not work under Delphi)
  2193. Revision 1.68 2002/10/05 00:52:20 peter
  2194. * split boolean check in two lines for easier debugging
  2195. Revision 1.67 2002/09/26 12:04:53 florian
  2196. + constsym with type=constguid can be written to ppu now,
  2197. fixes web bug 1820
  2198. Revision 1.66 2002/09/16 14:11:13 peter
  2199. * add argument to equal_paras() to support default values or not
  2200. Revision 1.65 2002/09/09 17:34:16 peter
  2201. * tdicationary.replace added to replace and item in a dictionary. This
  2202. is only allowed for the same name
  2203. * varsyms are inserted in symtable before the types are parsed. This
  2204. fixes the long standing "var longint : longint" bug
  2205. - consume_idlist and idstringlist removed. The loops are inserted
  2206. at the callers place and uses the symtable for duplicate id checking
  2207. Revision 1.64 2002/09/08 11:10:17 carl
  2208. * bugfix 2109 (bad imho, but only way)
  2209. Revision 1.63 2002/09/07 18:17:41 florian
  2210. + tvarsym.paraitem added
  2211. Revision 1.62 2002/09/07 15:25:10 peter
  2212. * old logs removed and tabs fixed
  2213. Revision 1.61 2002/09/05 19:29:45 peter
  2214. * memdebug enhancements
  2215. Revision 1.60 2002/09/05 14:51:42 peter
  2216. * internalerror instead of crash in getprocdef
  2217. Revision 1.59 2002/09/03 16:26:27 daniel
  2218. * Make Tprocdef.defs protected
  2219. Revision 1.58 2002/09/01 08:01:16 daniel
  2220. * Removed sets from Tcallnode.det_resulttype
  2221. + Added read/write notifications of variables. These will be usefull
  2222. for providing information for several optimizations. For example
  2223. the value of the loop variable of a for loop does matter is the
  2224. variable is read after the for loop, but if it's no longer used
  2225. or written, it doesn't matter and this can be used to optimize
  2226. the loop code generation.
  2227. Revision 1.57 2002/08/25 19:25:21 peter
  2228. * sym.insert_in_data removed
  2229. * symtable.insertvardata/insertconstdata added
  2230. * removed insert_in_data call from symtable.insert, it needs to be
  2231. called separatly. This allows to deref the address calculation
  2232. * procedures now calculate the parast addresses after the procedure
  2233. directives are parsed. This fixes the cdecl parast problem
  2234. * push_addr_param has an extra argument that specifies if cdecl is used
  2235. or not
  2236. Revision 1.56 2002/08/25 09:06:21 peter
  2237. * fixed loop in concat_procdefs
  2238. Revision 1.55 2002/08/20 16:54:40 peter
  2239. * write address of varsym always
  2240. Revision 1.54 2002/08/20 10:31:26 daniel
  2241. * Tcallnode.det_resulttype rewritten
  2242. Revision 1.53 2002/08/18 20:06:27 peter
  2243. * inlining is now also allowed in interface
  2244. * renamed write/load to ppuwrite/ppuload
  2245. * tnode storing in ppu
  2246. * nld,ncon,nbas are already updated for storing in ppu
  2247. Revision 1.52 2002/08/17 09:23:42 florian
  2248. * first part of procinfo rewrite
  2249. Revision 1.51 2002/08/16 14:24:59 carl
  2250. * issameref() to test if two references are the same (then emit no opcodes)
  2251. + ret_in_reg to replace ret_in_acc
  2252. (fix some register allocation bugs at the same time)
  2253. + save_std_register now has an extra parameter which is the
  2254. usedinproc registers
  2255. Revision 1.50 2002/08/13 21:40:57 florian
  2256. * more fixes for ppc calling conventions
  2257. Revision 1.49 2002/08/12 15:08:40 carl
  2258. + stab register indexes for powerpc (moved from gdb to cpubase)
  2259. + tprocessor enumeration moved to cpuinfo
  2260. + linker in target_info is now a class
  2261. * many many updates for m68k (will soon start to compile)
  2262. - removed some ifdef or correct them for correct cpu
  2263. Revision 1.48 2002/08/11 14:32:28 peter
  2264. * renamed current_library to objectlibrary
  2265. Revision 1.47 2002/08/11 13:24:14 peter
  2266. * saving of asmsymbols in ppu supported
  2267. * asmsymbollist global is removed and moved into a new class
  2268. tasmlibrarydata that will hold the info of a .a file which
  2269. corresponds with a single module. Added librarydata to tmodule
  2270. to keep the library info stored for the module. In the future the
  2271. objectfiles will also be stored to the tasmlibrarydata class
  2272. * all getlabel/newasmsymbol and friends are moved to the new class
  2273. Revision 1.46 2002/07/23 10:13:23 daniel
  2274. * Added important comment
  2275. Revision 1.45 2002/07/23 09:51:26 daniel
  2276. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  2277. are worth comitting.
  2278. Revision 1.44 2002/07/20 17:45:29 daniel
  2279. * Register variables are now possible for global variables too. This is
  2280. important for small programs without procedures.
  2281. Revision 1.43 2002/07/20 11:57:58 florian
  2282. * types.pas renamed to defbase.pas because D6 contains a types
  2283. unit so this would conflicts if D6 programms are compiled
  2284. + Willamette/SSE2 instructions to assembler added
  2285. Revision 1.42 2002/07/11 14:41:31 florian
  2286. * start of the new generic parameter handling
  2287. }