symsym.pas 77 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654
  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. globtype,globals,
  26. { symtable }
  27. symconst,symbase,symtype,symdef,defcmp,
  28. { ppu }
  29. ppu,
  30. cclasses,symnot,
  31. { aasm }
  32. aasmbase,aasmtai,
  33. cpuinfo,cpubase,cgbase,cgutils,parabase
  34. ;
  35. type
  36. { this class is the base for all symbol objects }
  37. tstoredsym = class(tsym)
  38. public
  39. constructor create(const n : string);
  40. constructor ppuload(ppufile:tcompilerppufile);
  41. destructor destroy;override;
  42. procedure ppuwrite(ppufile:tcompilerppufile);virtual;
  43. {$ifdef GDB}
  44. function get_var_value(const s:string):string;
  45. function stabstr_evaluate(const s:string;vars:array of string):Pchar;
  46. procedure concatstabto(asmlist : taasmoutput);
  47. {$endif GDB}
  48. function mangledname : string; virtual;
  49. end;
  50. tlabelsym = class(tstoredsym)
  51. lab : tasmlabel;
  52. used,
  53. defined : boolean;
  54. code : pointer; { should be tnode }
  55. constructor create(const n : string; l : tasmlabel);
  56. constructor ppuload(ppufile:tcompilerppufile);
  57. function mangledname:string;override;
  58. procedure ppuwrite(ppufile:tcompilerppufile);override;
  59. {$ifdef GDB}
  60. function stabstring : pchar;override;
  61. {$endif GDB}
  62. end;
  63. tunitsym = class(Tstoredsym)
  64. unitsymtable : tsymtable;
  65. constructor create(const n : string;ref : tsymtable);
  66. constructor ppuload(ppufile:tcompilerppufile);
  67. destructor destroy;override;
  68. procedure ppuwrite(ppufile:tcompilerppufile);override;
  69. end;
  70. terrorsym = class(Tsym)
  71. constructor create;
  72. end;
  73. Tprocdefcallback = procedure(p:Tprocdef;arg:pointer);
  74. tprocsym = class(tstoredsym)
  75. protected
  76. pdlistfirst,
  77. pdlistlast : pprocdeflist; { linked list of overloaded procdefs }
  78. function getprocdef(nr:cardinal):Tprocdef;
  79. public
  80. procdef_count : byte;
  81. {$ifdef GDB}
  82. is_global : boolean;
  83. {$endif GDB}
  84. overloadchecked : boolean;
  85. property procdef[nr:cardinal]:Tprocdef read getprocdef;
  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 unchain_overload;
  95. procedure ppuwrite(ppufile:tcompilerppufile);override;
  96. procedure buildderef;override;
  97. procedure deref;override;
  98. procedure addprocdef(p:tprocdef);
  99. procedure addprocdef_deref(const d:tderef);
  100. procedure add_para_match_to(Aprocsym:Tprocsym;cpoptions:tcompare_paras_options);
  101. procedure concat_procdefs_to(s:Tprocsym);
  102. procedure foreach_procdef_static(proc2call:Tprocdefcallback;arg:pointer);
  103. function first_procdef:Tprocdef;
  104. function last_procdef:Tprocdef;
  105. function search_procdef_nopara_boolret:Tprocdef;
  106. function search_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  107. function search_procdef_bypara(para:tlist;retdef:tdef;cpoptions:tcompare_paras_options):Tprocdef;
  108. function search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  109. function search_procdef_assignment_operator(fromdef,todef:tdef):Tprocdef;
  110. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  111. function is_visible_for_object(currobjdef:tdef):boolean;override;
  112. {$ifdef GDB}
  113. function stabstring : pchar;override;
  114. {$endif GDB}
  115. end;
  116. ttypesym = class(Tstoredsym)
  117. restype : ttype;
  118. constructor create(const n : string;const tt : ttype);
  119. constructor ppuload(ppufile:tcompilerppufile);
  120. procedure ppuwrite(ppufile:tcompilerppufile);override;
  121. procedure buildderef;override;
  122. procedure deref;override;
  123. function gettypedef:tdef;override;
  124. procedure load_references(ppufile:tcompilerppufile;locals:boolean);override;
  125. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;override;
  126. {$ifdef GDB}
  127. function stabstring : pchar;override;
  128. {$endif GDB}
  129. end;
  130. tabstractvarsym = class(tstoredsym)
  131. varoptions : tvaroptions;
  132. varspez : tvarspez; { sets the type of access }
  133. varregable : tvarregable;
  134. varstate : tvarstate;
  135. notifications : Tlinkedlist;
  136. constructor create(const n : string;vsp:tvarspez;const tt : ttype);
  137. constructor ppuload(ppufile:tcompilerppufile);
  138. destructor destroy;override;
  139. procedure ppuwrite(ppufile:tcompilerppufile);override;
  140. procedure buildderef;override;
  141. procedure deref;override;
  142. function getsize : longint;
  143. function is_regvar:boolean;
  144. procedure trigger_notifications(what:Tnotification_flag);
  145. function register_notification(flags:Tnotification_flags;
  146. callback:Tnotification_callback):cardinal;
  147. procedure unregister_notification(id:cardinal);
  148. private
  149. procedure setvartype(const newtype: ttype);
  150. _vartype : ttype;
  151. public
  152. property vartype: ttype read _vartype write setvartype;
  153. end;
  154. tvarsymclass = class of tabstractvarsym;
  155. tfieldvarsym = class(tabstractvarsym)
  156. fieldoffset : aint; { offset in record/object }
  157. constructor create(const n : string;vsp:tvarspez;const tt : ttype);
  158. constructor ppuload(ppufile:tcompilerppufile);
  159. procedure ppuwrite(ppufile:tcompilerppufile);override;
  160. {$ifdef GDB}
  161. function stabstring : pchar;override;
  162. {$endif GDB}
  163. end;
  164. tabstractnormalvarsym = class(tabstractvarsym)
  165. defaultconstsym : tsym;
  166. defaultconstsymderef : tderef;
  167. localloc : TLocation; { register/reference for local var }
  168. constructor create(const n : string;vsp:tvarspez;const tt : ttype);
  169. constructor ppuload(ppufile:tcompilerppufile);
  170. procedure ppuwrite(ppufile:tcompilerppufile);override;
  171. procedure buildderef;override;
  172. procedure deref;override;
  173. end;
  174. tlocalvarsym = class(tabstractnormalvarsym)
  175. constructor create(const n : string;vsp:tvarspez;const tt : ttype);
  176. constructor ppuload(ppufile:tcompilerppufile);
  177. procedure ppuwrite(ppufile:tcompilerppufile);override;
  178. {$ifdef GDB}
  179. function stabstring : pchar;override;
  180. {$endif GDB}
  181. end;
  182. tparavarsym = class(tabstractnormalvarsym)
  183. paraloc : array[tcallercallee] of TCGPara;
  184. paranr : word; { position of this parameter }
  185. {$ifdef EXTDEBUG}
  186. eqval : tequaltype;
  187. {$endif EXTDEBUG}
  188. constructor create(const n : string;nr:word;vsp:tvarspez;const tt : ttype);
  189. constructor ppuload(ppufile:tcompilerppufile);
  190. destructor destroy;override;
  191. procedure ppuwrite(ppufile:tcompilerppufile);override;
  192. {$ifdef GDB}
  193. function stabstring : pchar;override;
  194. {$endif GDB}
  195. end;
  196. tglobalvarsym = class(tabstractnormalvarsym)
  197. private
  198. _mangledname : pstring;
  199. public
  200. constructor create(const n : string;vsp:tvarspez;const tt : ttype);
  201. constructor create_dll(const n : string;vsp:tvarspez;const tt : ttype);
  202. constructor create_C(const n,mangled : string;vsp:tvarspez;const tt : ttype);
  203. constructor ppuload(ppufile:tcompilerppufile);
  204. destructor destroy;override;
  205. procedure ppuwrite(ppufile:tcompilerppufile);override;
  206. function mangledname:string;override;
  207. procedure set_mangledname(const s:string);
  208. {$ifdef GDB}
  209. function stabstring : pchar;override;
  210. {$endif GDB}
  211. end;
  212. tabsolutevarsym = class(tabstractvarsym)
  213. public
  214. abstyp : absolutetyp;
  215. {$ifdef i386}
  216. absseg : boolean;
  217. {$endif i386}
  218. asmname : pstring;
  219. addroffset : aint;
  220. ref : tsymlist;
  221. constructor create(const n : string;const tt : ttype);
  222. constructor create_ref(const n : string;const tt : ttype;_ref:tsymlist);
  223. destructor destroy;override;
  224. constructor ppuload(ppufile:tcompilerppufile);
  225. procedure buildderef;override;
  226. procedure deref;override;
  227. function mangledname : string;
  228. procedure ppuwrite(ppufile:tcompilerppufile);override;
  229. {$ifdef gdb}
  230. function stabstring:Pchar;override;
  231. {$endif gdb}
  232. end;
  233. tpropertysym = class(Tstoredsym)
  234. propoptions : tpropertyoptions;
  235. propoverriden : tpropertysym;
  236. propoverridenderef : tderef;
  237. proptype,
  238. indextype : ttype;
  239. index,
  240. default : longint;
  241. readaccess,
  242. writeaccess,
  243. storedaccess : tsymlist;
  244. constructor create(const n : string);
  245. destructor destroy;override;
  246. constructor ppuload(ppufile:tcompilerppufile);
  247. function getsize : longint;
  248. procedure ppuwrite(ppufile:tcompilerppufile);override;
  249. function gettypedef:tdef;override;
  250. procedure buildderef;override;
  251. procedure deref;override;
  252. procedure dooverride(overriden:tpropertysym);
  253. end;
  254. ttypedconstsym = class(tstoredsym)
  255. private
  256. _mangledname : pstring;
  257. public
  258. typedconsttype : ttype;
  259. is_writable : boolean;
  260. constructor create(const n : string;p : tdef;writable : boolean);
  261. constructor createtype(const n : string;const tt : ttype;writable : boolean);
  262. constructor ppuload(ppufile:tcompilerppufile);
  263. destructor destroy;override;
  264. function mangledname : string;override;
  265. procedure ppuwrite(ppufile:tcompilerppufile);override;
  266. procedure buildderef;override;
  267. procedure deref;override;
  268. function getsize:longint;
  269. {$ifdef GDB}
  270. function stabstring : pchar;override;
  271. {$endif GDB}
  272. end;
  273. tconstvalue = record
  274. case integer of
  275. 0: (valueord : tconstexprint);
  276. 1: (valueordptr : tconstptruint);
  277. 2: (valueptr : pointer; len : longint);
  278. end;
  279. tconstsym = class(tstoredsym)
  280. consttype : ttype;
  281. consttyp : tconsttyp;
  282. value : tconstvalue;
  283. resstrindex : longint; { needed for resource strings }
  284. constructor create_ord(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  285. constructor create_ordptr(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  286. constructor create_ptr(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  287. constructor create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  288. constructor ppuload(ppufile:tcompilerppufile);
  289. destructor destroy;override;
  290. procedure buildderef;override;
  291. procedure deref;override;
  292. procedure ppuwrite(ppufile:tcompilerppufile);override;
  293. {$ifdef GDB}
  294. function stabstring : pchar;override;
  295. {$endif GDB}
  296. end;
  297. tenumsym = class(Tstoredsym)
  298. value : longint;
  299. definition : tenumdef;
  300. definitionderef : tderef;
  301. nextenum : tenumsym;
  302. constructor create(const n : string;def : tenumdef;v : longint);
  303. constructor ppuload(ppufile:tcompilerppufile);
  304. procedure ppuwrite(ppufile:tcompilerppufile);override;
  305. procedure buildderef;override;
  306. procedure deref;override;
  307. procedure order;
  308. end;
  309. tsyssym = class(Tstoredsym)
  310. number : longint;
  311. constructor create(const n : string;l : longint);
  312. constructor ppuload(ppufile:tcompilerppufile);
  313. destructor destroy;override;
  314. procedure ppuwrite(ppufile:tcompilerppufile);override;
  315. end;
  316. { compiler generated symbol to point to rtti and init/finalize tables }
  317. trttisym = class(tstoredsym)
  318. private
  319. _mangledname : pstring;
  320. public
  321. lab : tasmsymbol;
  322. rttityp : trttitype;
  323. constructor create(const n:string;rt:trttitype);
  324. constructor ppuload(ppufile:tcompilerppufile);
  325. destructor destroy;override;
  326. procedure ppuwrite(ppufile:tcompilerppufile);override;
  327. function mangledname:string;
  328. function get_label:tasmsymbol;
  329. end;
  330. var
  331. generrorsym : tsym;
  332. implementation
  333. uses
  334. { global }
  335. verbose,
  336. { target }
  337. systems,
  338. { symtable }
  339. defutil,symtable,
  340. { tree }
  341. node,
  342. { aasm }
  343. {$ifdef gdb}
  344. gdb,
  345. {$endif gdb}
  346. { codegen }
  347. paramgr,cresstr,
  348. procinfo
  349. ;
  350. {****************************************************************************
  351. Helpers
  352. ****************************************************************************}
  353. {****************************************************************************
  354. TSYM (base for all symtypes)
  355. ****************************************************************************}
  356. constructor tstoredsym.create(const n : string);
  357. begin
  358. inherited create(n);
  359. end;
  360. constructor tstoredsym.ppuload(ppufile:tcompilerppufile);
  361. var
  362. nr : word;
  363. s : string;
  364. begin
  365. nr:=ppufile.getword;
  366. s:=ppufile.getstring;
  367. if s[1]='$' then
  368. inherited createname(copy(s,2,255))
  369. else
  370. inherited createname(upper(s));
  371. _realname:=stringdup(s);
  372. typ:=abstractsym;
  373. { force the correct indexnr. must be after create! }
  374. indexnr:=nr;
  375. ppufile.getposinfo(fileinfo);
  376. ppufile.getsmallset(symoptions);
  377. lastref:=nil;
  378. defref:=nil;
  379. refs:=0;
  380. lastwritten:=nil;
  381. refcount:=0;
  382. {$ifdef GDB}
  383. isstabwritten := false;
  384. {$endif GDB}
  385. end;
  386. procedure tstoredsym.ppuwrite(ppufile:tcompilerppufile);
  387. begin
  388. ppufile.putword(indexnr);
  389. ppufile.putstring(_realname^);
  390. ppufile.putposinfo(fileinfo);
  391. ppufile.putsmallset(symoptions);
  392. end;
  393. destructor tstoredsym.destroy;
  394. begin
  395. if assigned(defref) then
  396. begin
  397. {$ifdef MEMDEBUG}
  398. membrowser.start;
  399. {$endif MEMDEBUG}
  400. defref.freechain;
  401. defref.free;
  402. {$ifdef MEMDEBUG}
  403. membrowser.stop;
  404. {$endif MEMDEBUG}
  405. end;
  406. inherited destroy;
  407. end;
  408. {$ifdef GDB}
  409. function Tstoredsym.get_var_value(const s:string):string;
  410. begin
  411. if s='mangledname' then
  412. get_var_value:=mangledname
  413. else
  414. get_var_value:=inherited get_var_value(s);
  415. end;
  416. function Tstoredsym.stabstr_evaluate(const s:string;vars:array of string):Pchar;
  417. begin
  418. stabstr_evaluate:=string_evaluate(s,@get_var_value,vars);
  419. end;
  420. procedure tstoredsym.concatstabto(asmlist : taasmoutput);
  421. var
  422. stabstr : Pchar;
  423. begin
  424. stabstr:=stabstring;
  425. if stabstr<>nil then
  426. asmlist.concat(Tai_stabs.create(stabstr));
  427. end;
  428. {$endif GDB}
  429. function tstoredsym.mangledname : string;
  430. begin
  431. internalerror(200204171);
  432. end;
  433. {****************************************************************************
  434. TLABELSYM
  435. ****************************************************************************}
  436. constructor tlabelsym.create(const n : string; l : tasmlabel);
  437. begin
  438. inherited create(n);
  439. typ:=labelsym;
  440. lab:=l;
  441. used:=false;
  442. defined:=false;
  443. code:=nil;
  444. end;
  445. constructor tlabelsym.ppuload(ppufile:tcompilerppufile);
  446. begin
  447. inherited ppuload(ppufile);
  448. typ:=labelsym;
  449. { this is all dummy
  450. it is only used for local browsing }
  451. lab:=nil;
  452. code:=nil;
  453. used:=false;
  454. defined:=true;
  455. end;
  456. function tlabelsym.mangledname:string;
  457. begin
  458. result:=lab.name;
  459. end;
  460. procedure tlabelsym.ppuwrite(ppufile:tcompilerppufile);
  461. begin
  462. if owner.symtabletype=globalsymtable then
  463. Message(sym_e_ill_label_decl)
  464. else
  465. begin
  466. inherited ppuwrite(ppufile);
  467. ppufile.writeentry(iblabelsym);
  468. end;
  469. end;
  470. {$ifdef GDB}
  471. function Tlabelsym.stabstring : pchar;
  472. begin
  473. stabstring:=stabstr_evaluate('"${name}",${N_LSYM},0,${line},0',[]);
  474. end;
  475. {$endif GDB}
  476. {****************************************************************************
  477. TUNITSYM
  478. ****************************************************************************}
  479. constructor tunitsym.create(const n : string;ref : tsymtable);
  480. var
  481. old_make_ref : boolean;
  482. begin
  483. old_make_ref:=make_ref;
  484. make_ref:=false;
  485. inherited create(n);
  486. make_ref:=old_make_ref;
  487. typ:=unitsym;
  488. unitsymtable:=ref;
  489. end;
  490. constructor tunitsym.ppuload(ppufile:tcompilerppufile);
  491. begin
  492. inherited ppuload(ppufile);
  493. typ:=unitsym;
  494. unitsymtable:=nil;
  495. end;
  496. destructor tunitsym.destroy;
  497. begin
  498. inherited destroy;
  499. end;
  500. procedure tunitsym.ppuwrite(ppufile:tcompilerppufile);
  501. begin
  502. inherited ppuwrite(ppufile);
  503. ppufile.writeentry(ibunitsym);
  504. end;
  505. {****************************************************************************
  506. TPROCSYM
  507. ****************************************************************************}
  508. constructor tprocsym.create(const n : string);
  509. begin
  510. inherited create(n);
  511. typ:=procsym;
  512. pdlistfirst:=nil;
  513. pdlistlast:=nil;
  514. owner:=nil;
  515. {$ifdef GDB}
  516. is_global:=false;
  517. {$endif GDB}
  518. { the tprocdef have their own symoptions, make the procsym
  519. always visible }
  520. symoptions:=[sp_public];
  521. overloadchecked:=false;
  522. procdef_count:=0;
  523. end;
  524. constructor tprocsym.ppuload(ppufile:tcompilerppufile);
  525. var
  526. pdderef : tderef;
  527. i,n : longint;
  528. begin
  529. inherited ppuload(ppufile);
  530. typ:=procsym;
  531. pdlistfirst:=nil;
  532. pdlistlast:=nil;
  533. procdef_count:=0;
  534. n:=ppufile.getword;
  535. for i:=1to n do
  536. begin
  537. ppufile.getderef(pdderef);
  538. addprocdef_deref(pdderef);
  539. end;
  540. {$ifdef GDB}
  541. is_global:=false;
  542. {$endif GDB}
  543. overloadchecked:=false;
  544. end;
  545. destructor tprocsym.destroy;
  546. var
  547. hp,p : pprocdeflist;
  548. begin
  549. p:=pdlistfirst;
  550. while assigned(p) do
  551. begin
  552. hp:=p^.next;
  553. dispose(p);
  554. p:=hp;
  555. end;
  556. inherited destroy;
  557. end;
  558. procedure tprocsym.ppuwrite(ppufile:tcompilerppufile);
  559. var
  560. p : pprocdeflist;
  561. n : word;
  562. begin
  563. inherited ppuwrite(ppufile);
  564. { count procdefs }
  565. n:=0;
  566. p:=pdlistfirst;
  567. while assigned(p) do
  568. begin
  569. { only write the proc definitions that belong
  570. to this procsym and are in the global symtable }
  571. if p^.own and
  572. (p^.def.owner.symtabletype in [globalsymtable,objectsymtable]) then
  573. inc(n);
  574. p:=p^.next;
  575. end;
  576. ppufile.putword(n);
  577. { write procdefs }
  578. p:=pdlistfirst;
  579. while assigned(p) do
  580. begin
  581. { only write the proc definitions that belong
  582. to this procsym and are in the global symtable }
  583. if p^.own and
  584. (p^.def.owner.symtabletype in [globalsymtable,objectsymtable]) then
  585. ppufile.putderef(p^.defderef);
  586. p:=p^.next;
  587. end;
  588. ppufile.writeentry(ibprocsym);
  589. end;
  590. procedure tprocsym.write_parameter_lists(skipdef:tprocdef);
  591. var
  592. p : pprocdeflist;
  593. begin
  594. p:=pdlistfirst;
  595. while assigned(p) do
  596. begin
  597. if p^.def<>skipdef then
  598. MessagePos1(p^.def.fileinfo,sym_h_param_list,p^.def.fullprocname(false));
  599. p:=p^.next;
  600. end;
  601. end;
  602. {Makes implicit externals (procedures declared in the interface
  603. section which do not have a counterpart in the implementation)
  604. to be an imported procedure. For mode macpas.}
  605. procedure import_implict_external(pd:tabstractprocdef);
  606. begin
  607. tprocdef(pd).forwarddef:=false;
  608. tprocdef(pd).setmangledname(target_info.CPrefix+tprocdef(pd).procsym.realname);
  609. end;
  610. procedure tprocsym.check_forward;
  611. var
  612. p : pprocdeflist;
  613. begin
  614. p:=pdlistfirst;
  615. while assigned(p) do
  616. begin
  617. if p^.own and (p^.def.forwarddef) then
  618. begin
  619. if (m_mac in aktmodeswitches) and (p^.def.interfacedef) then
  620. import_implict_external(p^.def)
  621. else
  622. begin
  623. MessagePos1(p^.def.fileinfo,sym_e_forward_not_resolved,p^.def.fullprocname(false));
  624. { Turn further error messages off }
  625. p^.def.forwarddef:=false;
  626. end
  627. end;
  628. p:=p^.next;
  629. end;
  630. end;
  631. procedure tprocsym.buildderef;
  632. var
  633. p : pprocdeflist;
  634. begin
  635. p:=pdlistfirst;
  636. while assigned(p) do
  637. begin
  638. if p^.own then
  639. p^.defderef.build(p^.def);
  640. p:=p^.next;
  641. end;
  642. end;
  643. procedure tprocsym.deref;
  644. var
  645. p : pprocdeflist;
  646. begin
  647. { We have removed the overloaded entries, because they
  648. are not valid anymore and we can't deref them because
  649. the unit were they come from is not necessary in
  650. our uses clause (PFV) }
  651. unchain_overload;
  652. { Deref our own procdefs }
  653. p:=pdlistfirst;
  654. while assigned(p) do
  655. begin
  656. if not p^.own then
  657. internalerror(200310291);
  658. p^.def:=tprocdef(p^.defderef.resolve);
  659. p:=p^.next;
  660. end;
  661. end;
  662. procedure tprocsym.addprocdef(p:tprocdef);
  663. var
  664. pd : pprocdeflist;
  665. begin
  666. new(pd);
  667. pd^.def:=p;
  668. pd^.defderef.reset;
  669. pd^.next:=nil;
  670. pd^.own:=(pd^.def.procsym=self);
  671. { Add at end of list to keep always
  672. a correct order, also after loading from ppu }
  673. if assigned(pdlistlast) then
  674. begin
  675. pdlistlast^.next:=pd;
  676. pdlistlast:=pd;
  677. end
  678. else
  679. begin
  680. pdlistfirst:=pd;
  681. pdlistlast:=pd;
  682. end;
  683. inc(procdef_count);
  684. end;
  685. procedure tprocsym.addprocdef_deref(const d:tderef);
  686. var
  687. pd : pprocdeflist;
  688. begin
  689. new(pd);
  690. pd^.def:=nil;
  691. pd^.defderef:=d;
  692. pd^.next:=nil;
  693. pd^.own:=true;
  694. { Add at end of list to keep always
  695. a correct order, also after loading from ppu }
  696. if assigned(pdlistlast) then
  697. begin
  698. pdlistlast^.next:=pd;
  699. pdlistlast:=pd;
  700. end
  701. else
  702. begin
  703. pdlistfirst:=pd;
  704. pdlistlast:=pd;
  705. end;
  706. inc(procdef_count);
  707. end;
  708. function Tprocsym.getprocdef(nr:cardinal):Tprocdef;
  709. var
  710. i : cardinal;
  711. pd : pprocdeflist;
  712. begin
  713. pd:=pdlistfirst;
  714. for i:=2 to nr do
  715. begin
  716. if not assigned(pd) then
  717. internalerror(200209051);
  718. pd:=pd^.next;
  719. end;
  720. getprocdef:=pd^.def;
  721. end;
  722. procedure Tprocsym.add_para_match_to(Aprocsym:Tprocsym;cpoptions:tcompare_paras_options);
  723. var
  724. pd:pprocdeflist;
  725. begin
  726. pd:=pdlistfirst;
  727. while assigned(pd) do
  728. begin
  729. if Aprocsym.search_procdef_bypara(pd^.def.paras,nil,cpoptions)=nil then
  730. Aprocsym.addprocdef(pd^.def);
  731. pd:=pd^.next;
  732. end;
  733. end;
  734. procedure Tprocsym.concat_procdefs_to(s:Tprocsym);
  735. var
  736. pd : pprocdeflist;
  737. begin
  738. pd:=pdlistfirst;
  739. while assigned(pd) do
  740. begin
  741. s.addprocdef(pd^.def);
  742. pd:=pd^.next;
  743. end;
  744. end;
  745. function Tprocsym.first_procdef:Tprocdef;
  746. begin
  747. if assigned(pdlistfirst) then
  748. first_procdef:=pdlistfirst^.def
  749. else
  750. first_procdef:=nil;
  751. end;
  752. function Tprocsym.last_procdef:Tprocdef;
  753. begin
  754. if assigned(pdlistlast) then
  755. last_procdef:=pdlistlast^.def
  756. else
  757. last_procdef:=nil;
  758. end;
  759. procedure Tprocsym.foreach_procdef_static(proc2call:Tprocdefcallback;arg:pointer);
  760. var
  761. p : pprocdeflist;
  762. begin
  763. p:=pdlistfirst;
  764. while assigned(p) do
  765. begin
  766. proc2call(p^.def,arg);
  767. p:=p^.next;
  768. end;
  769. end;
  770. function Tprocsym.search_procdef_nopara_boolret:Tprocdef;
  771. var
  772. p : pprocdeflist;
  773. begin
  774. search_procdef_nopara_boolret:=nil;
  775. p:=pdlistfirst;
  776. while p<>nil do
  777. begin
  778. if (p^.def.maxparacount=0) and
  779. is_boolean(p^.def.rettype.def) then
  780. begin
  781. search_procdef_nopara_boolret:=p^.def;
  782. break;
  783. end;
  784. p:=p^.next;
  785. end;
  786. end;
  787. function Tprocsym.search_procdef_bytype(pt:Tproctypeoption):Tprocdef;
  788. var
  789. p : pprocdeflist;
  790. begin
  791. search_procdef_bytype:=nil;
  792. p:=pdlistfirst;
  793. while p<>nil do
  794. begin
  795. if p^.def.proctypeoption=pt then
  796. begin
  797. search_procdef_bytype:=p^.def;
  798. break;
  799. end;
  800. p:=p^.next;
  801. end;
  802. end;
  803. function Tprocsym.search_procdef_bypara(para:tlist;retdef:tdef;
  804. cpoptions:tcompare_paras_options):Tprocdef;
  805. var
  806. pd : pprocdeflist;
  807. eq : tequaltype;
  808. begin
  809. search_procdef_bypara:=nil;
  810. pd:=pdlistfirst;
  811. while assigned(pd) do
  812. begin
  813. if assigned(retdef) then
  814. eq:=compare_defs(retdef,pd^.def.rettype.def,nothingn)
  815. else
  816. eq:=te_equal;
  817. if (eq>=te_equal) or
  818. ((cpo_allowconvert in cpoptions) and (eq>te_incompatible)) then
  819. begin
  820. eq:=compare_paras(para,pd^.def.paras,cp_value_equal_const,cpoptions);
  821. if (eq>=te_equal) or
  822. ((cpo_allowconvert in cpoptions) and (eq>te_incompatible)) then
  823. begin
  824. search_procdef_bypara:=pd^.def;
  825. break;
  826. end;
  827. end;
  828. pd:=pd^.next;
  829. end;
  830. end;
  831. function Tprocsym.search_procdef_byprocvardef(d:Tprocvardef):Tprocdef;
  832. var
  833. pd : pprocdeflist;
  834. eq,besteq : tequaltype;
  835. bestpd : tprocdef;
  836. begin
  837. { This function will return the pprocdef of pprocsym that
  838. is the best match for procvardef. When there are multiple
  839. matches it returns nil.}
  840. search_procdef_byprocvardef:=nil;
  841. bestpd:=nil;
  842. besteq:=te_incompatible;
  843. pd:=pdlistfirst;
  844. while assigned(pd) do
  845. begin
  846. eq:=proc_to_procvar_equal(pd^.def,d,false);
  847. if eq>=te_equal then
  848. begin
  849. { multiple procvars with the same equal level }
  850. if assigned(bestpd) and
  851. (besteq=eq) then
  852. exit;
  853. if eq>besteq then
  854. begin
  855. besteq:=eq;
  856. bestpd:=pd^.def;
  857. end;
  858. end;
  859. pd:=pd^.next;
  860. end;
  861. search_procdef_byprocvardef:=bestpd;
  862. end;
  863. function Tprocsym.search_procdef_assignment_operator(fromdef,todef:tdef):Tprocdef;
  864. var
  865. convtyp : tconverttype;
  866. pd : pprocdeflist;
  867. bestpd : tprocdef;
  868. eq,
  869. besteq : tequaltype;
  870. hpd : tprocdef;
  871. i : byte;
  872. begin
  873. result:=nil;
  874. bestpd:=nil;
  875. besteq:=te_incompatible;
  876. pd:=pdlistfirst;
  877. while assigned(pd) do
  878. begin
  879. if equal_defs(todef,pd^.def.rettype.def) then
  880. begin
  881. i:=0;
  882. { ignore vs_hidden parameters }
  883. while assigned(pd^.def.paras[i]) and
  884. (vo_is_hidden_para in tparavarsym(pd^.def.paras[i]).varoptions) do
  885. inc(i);
  886. if assigned(pd^.def.paras[i]) then
  887. begin
  888. eq:=compare_defs_ext(fromdef,tparavarsym(pd^.def.paras[i]).vartype.def,nothingn,convtyp,hpd,[]);
  889. if eq=te_exact then
  890. begin
  891. result:=pd^.def;
  892. exit;
  893. end;
  894. if eq>besteq then
  895. begin
  896. bestpd:=pd^.def;
  897. besteq:=eq;
  898. end;
  899. end;
  900. end;
  901. pd:=pd^.next;
  902. end;
  903. result:=bestpd;
  904. end;
  905. function tprocsym.write_references(ppufile:tcompilerppufile;locals:boolean) : boolean;
  906. var
  907. p : pprocdeflist;
  908. begin
  909. write_references:=false;
  910. if not inherited write_references(ppufile,locals) then
  911. exit;
  912. write_references:=true;
  913. p:=pdlistfirst;
  914. while assigned(p) do
  915. begin
  916. if p^.own then
  917. p^.def.write_references(ppufile,locals);
  918. p:=p^.next;
  919. end;
  920. end;
  921. procedure tprocsym.unchain_overload;
  922. var
  923. p,hp : pprocdeflist;
  924. begin
  925. { remove all overloaded procdefs from the
  926. procdeflist that are not in the current symtable }
  927. overloadchecked:=false;
  928. p:=pdlistfirst;
  929. { reset new lists }
  930. pdlistfirst:=nil;
  931. pdlistlast:=nil;
  932. while assigned(p) do
  933. begin
  934. hp:=p^.next;
  935. if p^.own then
  936. begin
  937. { keep, add to list }
  938. if assigned(pdlistlast) then
  939. begin
  940. pdlistlast^.next:=p;
  941. pdlistlast:=p;
  942. end
  943. else
  944. begin
  945. pdlistfirst:=p;
  946. pdlistlast:=p;
  947. end;
  948. p^.next:=nil;
  949. end
  950. else
  951. begin
  952. { remove }
  953. dispose(p);
  954. dec(procdef_count);
  955. end;
  956. p:=hp;
  957. end;
  958. end;
  959. function tprocsym.is_visible_for_object(currobjdef:tdef):boolean;
  960. var
  961. p : pprocdeflist;
  962. begin
  963. { This procsym is visible, when there is at least
  964. one of the procdefs visible }
  965. result:=false;
  966. p:=pdlistfirst;
  967. while assigned(p) do
  968. begin
  969. if p^.own and
  970. p^.def.is_visible_for_object(tobjectdef(currobjdef)) then
  971. begin
  972. result:=true;
  973. exit;
  974. end;
  975. p:=p^.next;
  976. end;
  977. end;
  978. {$ifdef GDB}
  979. function tprocsym.stabstring : pchar;
  980. begin
  981. internalerror(200111171);
  982. result:=nil;
  983. end;
  984. {$endif GDB}
  985. {****************************************************************************
  986. TERRORSYM
  987. ****************************************************************************}
  988. constructor terrorsym.create;
  989. begin
  990. inherited create('');
  991. typ:=errorsym;
  992. end;
  993. {****************************************************************************
  994. TPROPERTYSYM
  995. ****************************************************************************}
  996. constructor tpropertysym.create(const n : string);
  997. begin
  998. inherited create(n);
  999. typ:=propertysym;
  1000. propoptions:=[];
  1001. index:=0;
  1002. default:=0;
  1003. proptype.reset;
  1004. indextype.reset;
  1005. readaccess:=tsymlist.create;
  1006. writeaccess:=tsymlist.create;
  1007. storedaccess:=tsymlist.create;
  1008. end;
  1009. constructor tpropertysym.ppuload(ppufile:tcompilerppufile);
  1010. begin
  1011. inherited ppuload(ppufile);
  1012. typ:=propertysym;
  1013. ppufile.getsmallset(propoptions);
  1014. if (ppo_is_override in propoptions) then
  1015. begin
  1016. ppufile.getderef(propoverridenderef);
  1017. { we need to have these objects initialized }
  1018. readaccess:=tsymlist.create;
  1019. writeaccess:=tsymlist.create;
  1020. storedaccess:=tsymlist.create;
  1021. end
  1022. else
  1023. begin
  1024. ppufile.gettype(proptype);
  1025. index:=ppufile.getlongint;
  1026. default:=ppufile.getlongint;
  1027. ppufile.gettype(indextype);
  1028. readaccess:=ppufile.getsymlist;
  1029. writeaccess:=ppufile.getsymlist;
  1030. storedaccess:=ppufile.getsymlist;
  1031. end;
  1032. end;
  1033. destructor tpropertysym.destroy;
  1034. begin
  1035. readaccess.free;
  1036. writeaccess.free;
  1037. storedaccess.free;
  1038. inherited destroy;
  1039. end;
  1040. function tpropertysym.gettypedef:tdef;
  1041. begin
  1042. gettypedef:=proptype.def;
  1043. end;
  1044. procedure tpropertysym.buildderef;
  1045. begin
  1046. if (ppo_is_override in propoptions) then
  1047. begin
  1048. propoverridenderef.build(propoverriden);
  1049. end
  1050. else
  1051. begin
  1052. proptype.buildderef;
  1053. indextype.buildderef;
  1054. readaccess.buildderef;
  1055. writeaccess.buildderef;
  1056. storedaccess.buildderef;
  1057. end;
  1058. end;
  1059. procedure tpropertysym.deref;
  1060. begin
  1061. if (ppo_is_override in propoptions) then
  1062. begin
  1063. propoverriden:=tpropertysym(propoverridenderef.resolve);
  1064. dooverride(propoverriden);
  1065. end
  1066. else
  1067. begin
  1068. proptype.resolve;
  1069. indextype.resolve;
  1070. readaccess.resolve;
  1071. writeaccess.resolve;
  1072. storedaccess.resolve;
  1073. end;
  1074. end;
  1075. function tpropertysym.getsize : longint;
  1076. begin
  1077. getsize:=0;
  1078. end;
  1079. procedure tpropertysym.ppuwrite(ppufile:tcompilerppufile);
  1080. begin
  1081. inherited ppuwrite(ppufile);
  1082. ppufile.putsmallset(propoptions);
  1083. if (ppo_is_override in propoptions) then
  1084. ppufile.putderef(propoverridenderef)
  1085. else
  1086. begin
  1087. ppufile.puttype(proptype);
  1088. ppufile.putlongint(index);
  1089. ppufile.putlongint(default);
  1090. ppufile.puttype(indextype);
  1091. ppufile.putsymlist(readaccess);
  1092. ppufile.putsymlist(writeaccess);
  1093. ppufile.putsymlist(storedaccess);
  1094. end;
  1095. ppufile.writeentry(ibpropertysym);
  1096. end;
  1097. procedure tpropertysym.dooverride(overriden:tpropertysym);
  1098. begin
  1099. propoverriden:=overriden;
  1100. proptype:=overriden.proptype;
  1101. propoptions:=overriden.propoptions+[ppo_is_override];
  1102. index:=overriden.index;
  1103. default:=overriden.default;
  1104. indextype:=overriden.indextype;
  1105. readaccess.free;
  1106. readaccess:=overriden.readaccess.getcopy;
  1107. writeaccess.free;
  1108. writeaccess:=overriden.writeaccess.getcopy;
  1109. storedaccess.free;
  1110. storedaccess:=overriden.storedaccess.getcopy;
  1111. end;
  1112. {****************************************************************************
  1113. TABSTRACTVARSYM
  1114. ****************************************************************************}
  1115. constructor tabstractvarsym.create(const n : string;vsp:tvarspez;const tt : ttype);
  1116. begin
  1117. inherited create(n);
  1118. vartype:=tt;
  1119. varspez:=vsp;
  1120. varstate:=vs_declared;
  1121. varoptions:=[];
  1122. end;
  1123. constructor tabstractvarsym.ppuload(ppufile:tcompilerppufile);
  1124. begin
  1125. inherited ppuload(ppufile);
  1126. varstate:=vs_used;
  1127. varspez:=tvarspez(ppufile.getbyte);
  1128. varregable:=tvarregable(ppufile.getbyte);
  1129. ppufile.gettype(_vartype);
  1130. ppufile.getsmallset(varoptions);
  1131. end;
  1132. destructor tabstractvarsym.destroy;
  1133. begin
  1134. if assigned(notifications) then
  1135. notifications.destroy;
  1136. inherited destroy;
  1137. end;
  1138. procedure tabstractvarsym.buildderef;
  1139. begin
  1140. vartype.buildderef;
  1141. end;
  1142. procedure tabstractvarsym.deref;
  1143. begin
  1144. vartype.resolve;
  1145. end;
  1146. procedure tabstractvarsym.ppuwrite(ppufile:tcompilerppufile);
  1147. var
  1148. oldintfcrc : boolean;
  1149. begin
  1150. inherited ppuwrite(ppufile);
  1151. ppufile.putbyte(byte(varspez));
  1152. oldintfcrc:=ppufile.do_crc;
  1153. ppufile.do_crc:=false;
  1154. ppufile.putbyte(byte(varregable));
  1155. ppufile.do_crc:=oldintfcrc;
  1156. ppufile.puttype(vartype);
  1157. ppufile.putsmallset(varoptions);
  1158. end;
  1159. function tabstractvarsym.getsize : longint;
  1160. begin
  1161. if assigned(vartype.def) and
  1162. ((vartype.def.deftype<>arraydef) or
  1163. tarraydef(vartype.def).isDynamicArray or
  1164. (tarraydef(vartype.def).highrange>=tarraydef(vartype.def).lowrange)) then
  1165. result:=vartype.def.size
  1166. else
  1167. result:=0;
  1168. end;
  1169. function tabstractvarsym.is_regvar:boolean;
  1170. begin
  1171. result:=(cs_regvars in aktglobalswitches) and
  1172. not(pi_has_assembler_block in current_procinfo.flags) and
  1173. not(pi_uses_exceptions in current_procinfo.flags) and
  1174. not(vo_has_local_copy in varoptions) and
  1175. (varregable<>vr_none);
  1176. end;
  1177. procedure tabstractvarsym.trigger_notifications(what:Tnotification_flag);
  1178. var n:Tnotification;
  1179. begin
  1180. if assigned(notifications) then
  1181. begin
  1182. n:=Tnotification(notifications.first);
  1183. while assigned(n) do
  1184. begin
  1185. if what in n.flags then
  1186. n.callback(what,self);
  1187. n:=Tnotification(n.next);
  1188. end;
  1189. end;
  1190. end;
  1191. function Tabstractvarsym.register_notification(flags:Tnotification_flags;callback:
  1192. Tnotification_callback):cardinal;
  1193. var n:Tnotification;
  1194. begin
  1195. if not assigned(notifications) then
  1196. notifications:=Tlinkedlist.create;
  1197. n:=Tnotification.create(flags,callback);
  1198. register_notification:=n.id;
  1199. notifications.concat(n);
  1200. end;
  1201. procedure Tabstractvarsym.unregister_notification(id:cardinal);
  1202. var n:Tnotification;
  1203. begin
  1204. if not assigned(notifications) then
  1205. internalerror(200212311)
  1206. else
  1207. begin
  1208. n:=Tnotification(notifications.first);
  1209. while assigned(n) do
  1210. begin
  1211. if n.id=id then
  1212. begin
  1213. notifications.remove(n);
  1214. n.destroy;
  1215. exit;
  1216. end;
  1217. n:=Tnotification(n.next);
  1218. end;
  1219. internalerror(200212311)
  1220. end;
  1221. end;
  1222. procedure tabstractvarsym.setvartype(const newtype: ttype);
  1223. begin
  1224. _vartype := newtype;
  1225. { can we load the value into a register ? }
  1226. if not assigned(owner) or
  1227. (owner.symtabletype in [localsymtable,parasymtable]) or
  1228. (
  1229. (owner.symtabletype=staticsymtable) and
  1230. not(cs_create_pic in aktmoduleswitches)
  1231. ) then
  1232. begin
  1233. if tstoreddef(vartype.def).is_intregable then
  1234. varregable:=vr_intreg
  1235. else
  1236. {$warning TODO: no fpu regvar in staticsymtable yet, need initialization with 0}
  1237. if (
  1238. not assigned(owner) or
  1239. (owner.symtabletype<>staticsymtable)
  1240. ) and
  1241. tstoreddef(vartype.def).is_fpuregable then
  1242. varregable:=vr_fpureg;
  1243. end;
  1244. end;
  1245. {****************************************************************************
  1246. TFIELDVARSYM
  1247. ****************************************************************************}
  1248. constructor tfieldvarsym.create(const n : string;vsp:tvarspez;const tt : ttype);
  1249. begin
  1250. inherited create(n,vsp,tt);
  1251. typ:=fieldvarsym;
  1252. fieldoffset:=0;
  1253. end;
  1254. constructor tfieldvarsym.ppuload(ppufile:tcompilerppufile);
  1255. begin
  1256. inherited ppuload(ppufile);
  1257. typ:=fieldvarsym;
  1258. fieldoffset:=ppufile.getaint;
  1259. end;
  1260. procedure tfieldvarsym.ppuwrite(ppufile:tcompilerppufile);
  1261. begin
  1262. inherited ppuwrite(ppufile);
  1263. ppufile.putaint(fieldoffset);
  1264. ppufile.writeentry(ibfieldvarsym);
  1265. end;
  1266. {$ifdef GDB}
  1267. function tfieldvarsym.stabstring:Pchar;
  1268. var
  1269. st : string;
  1270. begin
  1271. stabstring:=nil;
  1272. case owner.symtabletype of
  1273. objectsymtable :
  1274. begin
  1275. if (sp_static in symoptions) then
  1276. begin
  1277. st:=tstoreddef(vartype.def).numberstring;
  1278. if (cs_gdb_gsym in aktglobalswitches) then
  1279. st:='G'+st
  1280. else
  1281. st:='S'+st;
  1282. stabstring:=stabstr_evaluate('"${ownername}__${name}:$1",${N_LCSYM},0,${line},${mangledname}',[st]);
  1283. end;
  1284. end;
  1285. end;
  1286. end;
  1287. {$endif GDB}
  1288. {****************************************************************************
  1289. TABSTRACTNORMALVARSYM
  1290. ****************************************************************************}
  1291. constructor tabstractnormalvarsym.create(const n : string;vsp:tvarspez;const tt : ttype);
  1292. begin
  1293. inherited create(n,vsp,tt);
  1294. fillchar(localloc,sizeof(localloc),0);
  1295. defaultconstsym:=nil;
  1296. end;
  1297. constructor tabstractnormalvarsym.ppuload(ppufile:tcompilerppufile);
  1298. begin
  1299. inherited ppuload(ppufile);
  1300. fillchar(localloc,sizeof(localloc),0);
  1301. ppufile.getderef(defaultconstsymderef);
  1302. end;
  1303. procedure tabstractnormalvarsym.buildderef;
  1304. begin
  1305. inherited buildderef;
  1306. defaultconstsymderef.build(defaultconstsym);
  1307. end;
  1308. procedure tabstractnormalvarsym.deref;
  1309. begin
  1310. inherited deref;
  1311. defaultconstsym:=tsym(defaultconstsymderef.resolve);
  1312. end;
  1313. procedure tabstractnormalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1314. begin
  1315. inherited ppuwrite(ppufile);
  1316. ppufile.putderef(defaultconstsymderef);
  1317. end;
  1318. {****************************************************************************
  1319. TGLOBALVARSYM
  1320. ****************************************************************************}
  1321. constructor tglobalvarsym.create(const n : string;vsp:tvarspez;const tt : ttype);
  1322. begin
  1323. inherited create(n,vsp,tt);
  1324. typ:=globalvarsym;
  1325. _mangledname:=nil;
  1326. end;
  1327. constructor tglobalvarsym.create_dll(const n : string;vsp:tvarspez;const tt : ttype);
  1328. begin
  1329. tglobalvarsym(self).create(n,vsp,tt);
  1330. include(varoptions,vo_is_dll_var);
  1331. end;
  1332. constructor tglobalvarsym.create_C(const n,mangled : string;vsp:tvarspez;const tt : ttype);
  1333. begin
  1334. tglobalvarsym(self).create(n,vsp,tt);
  1335. set_mangledname(mangled);
  1336. end;
  1337. constructor tglobalvarsym.ppuload(ppufile:tcompilerppufile);
  1338. begin
  1339. inherited ppuload(ppufile);
  1340. typ:=globalvarsym;
  1341. if vo_has_mangledname in varoptions then
  1342. _mangledname:=stringdup(ppufile.getstring)
  1343. else
  1344. _mangledname:=nil;
  1345. end;
  1346. destructor tglobalvarsym.destroy;
  1347. begin
  1348. if assigned(_mangledname) then
  1349. begin
  1350. {$ifdef MEMDEBUG}
  1351. memmanglednames.start;
  1352. {$endif MEMDEBUG}
  1353. stringdispose(_mangledname);
  1354. {$ifdef MEMDEBUG}
  1355. memmanglednames.stop;
  1356. {$endif MEMDEBUG}
  1357. end;
  1358. inherited destroy;
  1359. end;
  1360. procedure tglobalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1361. begin
  1362. inherited ppuwrite(ppufile);
  1363. if vo_has_mangledname in varoptions then
  1364. ppufile.putstring(_mangledname^);
  1365. ppufile.writeentry(ibglobalvarsym);
  1366. end;
  1367. function tglobalvarsym.mangledname:string;
  1368. begin
  1369. if not assigned(_mangledname) then
  1370. begin
  1371. {$ifdef compress}
  1372. _mangledname:=stringdup(minilzw_encode(make_mangledname('U',owner,name)));
  1373. {$else}
  1374. _mangledname:=stringdup(make_mangledname('U',owner,name));
  1375. {$endif}
  1376. end;
  1377. result:=_mangledname^;
  1378. end;
  1379. procedure tglobalvarsym.set_mangledname(const s:string);
  1380. begin
  1381. stringdispose(_mangledname);
  1382. {$ifdef compress}
  1383. _mangledname:=stringdup(minilzw_encode(s));
  1384. {$else}
  1385. _mangledname:=stringdup(s);
  1386. {$endif}
  1387. include(varoptions,vo_has_mangledname);
  1388. end;
  1389. {$ifdef GDB}
  1390. function Tglobalvarsym.stabstring:Pchar;
  1391. var st:string;
  1392. threadvaroffset:string;
  1393. regidx:Tregisterindex;
  1394. begin
  1395. st:=tstoreddef(vartype.def).numberstring;
  1396. case localloc.loc of
  1397. LOC_REGISTER,
  1398. LOC_CREGISTER,
  1399. LOC_MMREGISTER,
  1400. LOC_CMMREGISTER,
  1401. LOC_FPUREGISTER,
  1402. LOC_CFPUREGISTER :
  1403. begin
  1404. regidx:=findreg_by_number(localloc.register);
  1405. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1406. { this is the register order for GDB}
  1407. if regidx<>0 then
  1408. stabstring:=stabstr_evaluate('"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(regstabs_table[regidx])]);
  1409. end;
  1410. else
  1411. begin
  1412. if (vo_is_thread_var in varoptions) then
  1413. threadvaroffset:='+'+tostr(sizeof(aint))
  1414. else
  1415. threadvaroffset:='';
  1416. { Here we used S instead of
  1417. because with G GDB doesn't look at the address field
  1418. but searches the same name or with a leading underscore
  1419. but these names don't exist in pascal !}
  1420. if (cs_gdb_gsym in aktglobalswitches) then
  1421. st:='G'+st
  1422. else
  1423. st:='S'+st;
  1424. stabstring:=stabstr_evaluate('"${name}:$1",${N_LCSYM},0,${line},${mangledname}$2',[st,threadvaroffset]);
  1425. end;
  1426. end;
  1427. end;
  1428. {$endif GDB}
  1429. {****************************************************************************
  1430. TLOCALVARSYM
  1431. ****************************************************************************}
  1432. constructor tlocalvarsym.create(const n : string;vsp:tvarspez;const tt : ttype);
  1433. begin
  1434. inherited create(n,vsp,tt);
  1435. typ:=localvarsym;
  1436. end;
  1437. constructor tlocalvarsym.ppuload(ppufile:tcompilerppufile);
  1438. begin
  1439. inherited ppuload(ppufile);
  1440. typ:=localvarsym;
  1441. end;
  1442. procedure tlocalvarsym.ppuwrite(ppufile:tcompilerppufile);
  1443. begin
  1444. inherited ppuwrite(ppufile);
  1445. ppufile.writeentry(iblocalvarsym);
  1446. end;
  1447. {$ifdef GDB}
  1448. function tlocalvarsym.stabstring:Pchar;
  1449. var st:string;
  1450. regidx:Tregisterindex;
  1451. begin
  1452. stabstring:=nil;
  1453. { There is no space allocated for not referenced locals }
  1454. if (owner.symtabletype=localsymtable) and (refs=0) then
  1455. exit;
  1456. st:=tstoreddef(vartype.def).numberstring;
  1457. case localloc.loc of
  1458. LOC_REGISTER,
  1459. LOC_CREGISTER,
  1460. LOC_MMREGISTER,
  1461. LOC_CMMREGISTER,
  1462. LOC_FPUREGISTER,
  1463. LOC_CFPUREGISTER :
  1464. begin
  1465. regidx:=findreg_by_number(localloc.register);
  1466. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1467. { this is the register order for GDB}
  1468. if regidx<>0 then
  1469. stabstring:=stabstr_evaluate('"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(regstabs_table[regidx])]);
  1470. end;
  1471. LOC_REFERENCE :
  1472. { offset to ebp => will not work if the framepointer is esp
  1473. so some optimizing will make things harder to debug }
  1474. stabstring:=stabstr_evaluate('"${name}:$1",${N_TSYM},0,${line},$2',[st,tostr(localloc.reference.offset)])
  1475. else
  1476. internalerror(2003091814);
  1477. end;
  1478. end;
  1479. {$endif GDB}
  1480. {****************************************************************************
  1481. TPARAVARSYM
  1482. ****************************************************************************}
  1483. constructor tparavarsym.create(const n : string;nr:word;vsp:tvarspez;const tt : ttype);
  1484. begin
  1485. inherited create(n,vsp,tt);
  1486. typ:=paravarsym;
  1487. paranr:=nr;
  1488. paraloc[calleeside].init;
  1489. paraloc[callerside].init;
  1490. end;
  1491. destructor tparavarsym.destroy;
  1492. begin
  1493. paraloc[calleeside].done;
  1494. paraloc[callerside].done;
  1495. inherited destroy;
  1496. end;
  1497. constructor tparavarsym.ppuload(ppufile:tcompilerppufile);
  1498. var
  1499. b : byte;
  1500. begin
  1501. inherited ppuload(ppufile);
  1502. paranr:=ppufile.getword;
  1503. paraloc[calleeside].init;
  1504. paraloc[callerside].init;
  1505. if vo_has_explicit_paraloc in varoptions then
  1506. begin
  1507. b:=ppufile.getbyte;
  1508. if b<>sizeof(paraloc[callerside].location^) then
  1509. internalerror(200411154);
  1510. ppufile.getdata(paraloc[callerside].add_location^,sizeof(paraloc[callerside].location^));
  1511. paraloc[callerside].size:=paraloc[callerside].location^.size;
  1512. end;
  1513. typ:=paravarsym;
  1514. end;
  1515. procedure tparavarsym.ppuwrite(ppufile:tcompilerppufile);
  1516. begin
  1517. inherited ppuwrite(ppufile);
  1518. ppufile.putword(paranr);
  1519. if vo_has_explicit_paraloc in varoptions then
  1520. begin
  1521. paraloc[callerside].check_simple_location;
  1522. ppufile.putbyte(sizeof(paraloc[callerside].location^));
  1523. ppufile.putdata(paraloc[callerside].location^,sizeof(paraloc[callerside].location^));
  1524. end;
  1525. ppufile.writeentry(ibparavarsym);
  1526. end;
  1527. {$ifdef GDB}
  1528. function tparavarsym.stabstring:Pchar;
  1529. var st:string;
  1530. regidx:Tregisterindex;
  1531. c:char;
  1532. begin
  1533. { set loc to LOC_REFERENCE to get somewhat usable debugging info for -Or }
  1534. { while stabs aren't adapted for regvars yet }
  1535. if (vo_is_self in varoptions) then
  1536. begin
  1537. case localloc.loc of
  1538. LOC_REGISTER,
  1539. LOC_CREGISTER:
  1540. regidx:=findreg_by_number(localloc.register);
  1541. LOC_REFERENCE: ;
  1542. else
  1543. internalerror(2003091815);
  1544. end;
  1545. if (po_classmethod in current_procinfo.procdef.procoptions) or
  1546. (po_staticmethod in current_procinfo.procdef.procoptions) then
  1547. begin
  1548. if (localloc.loc=LOC_REFERENCE) then
  1549. stabstring:=stabstr_evaluate('"pvmt:p$1",${N_TSYM},0,0,$2',
  1550. [Tstoreddef(pvmttype.def).numberstring,tostr(localloc.reference.offset)]);
  1551. (* else
  1552. stabstring:=stabstr_evaluate('"pvmt:r$1",${N_RSYM},0,0,$2',
  1553. [Tstoreddef(pvmttype.def).numberstring,tostr(regstabs_table[regidx])]) *)
  1554. end
  1555. else
  1556. begin
  1557. if not(is_class(current_procinfo.procdef._class)) then
  1558. c:='v'
  1559. else
  1560. c:='p';
  1561. if (localloc.loc=LOC_REFERENCE) then
  1562. stabstring:=stabstr_evaluate('"$$t:$1",${N_TSYM},0,0,$2',
  1563. [c+current_procinfo.procdef._class.numberstring,tostr(localloc.reference.offset)]);
  1564. (* else
  1565. stabstring:=stabstr_evaluate('"$$t:r$1",${N_RSYM},0,0,$2',
  1566. [c+current_procinfo.procdef._class.numberstring,tostr(regstabs_table[regidx])]); *)
  1567. end;
  1568. end
  1569. else
  1570. begin
  1571. st:=tstoreddef(vartype.def).numberstring;
  1572. if paramanager.push_addr_param(varspez,vartype.def,tprocdef(owner.defowner).proccalloption) and
  1573. not(vo_has_local_copy in varoptions) and
  1574. not is_open_string(vartype.def) then
  1575. st := 'v'+st { should be 'i' but 'i' doesn't work }
  1576. else
  1577. st := 'p'+st;
  1578. case localloc.loc of
  1579. LOC_REGISTER,
  1580. LOC_CREGISTER,
  1581. LOC_MMREGISTER,
  1582. LOC_CMMREGISTER,
  1583. LOC_FPUREGISTER,
  1584. LOC_CFPUREGISTER :
  1585. begin
  1586. regidx:=findreg_by_number(localloc.register);
  1587. { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", "ps", "cs", "ss", "ds", "es", "fs", "gs", }
  1588. { this is the register order for GDB}
  1589. if regidx<>0 then
  1590. stabstring:=stabstr_evaluate('"${name}:r$1",${N_RSYM},0,${line},$2',[st,tostr(regstabs_table[regidx])]);
  1591. end;
  1592. LOC_REFERENCE :
  1593. { offset to ebp => will not work if the framepointer is esp
  1594. so some optimizing will make things harder to debug }
  1595. stabstring:=stabstr_evaluate('"${name}:$1",${N_TSYM},0,${line},$2',[st,tostr(localloc.reference.offset)])
  1596. else
  1597. internalerror(2003091814);
  1598. end;
  1599. end;
  1600. end;
  1601. {$endif GDB}
  1602. {****************************************************************************
  1603. TABSOLUTEVARSYM
  1604. ****************************************************************************}
  1605. constructor tabsolutevarsym.create(const n : string;const tt : ttype);
  1606. begin
  1607. inherited create(n,vs_value,tt);
  1608. typ:=absolutevarsym;
  1609. ref:=nil;
  1610. end;
  1611. constructor tabsolutevarsym.create_ref(const n : string;const tt : ttype;_ref:tsymlist);
  1612. begin
  1613. inherited create(n,vs_value,tt);
  1614. typ:=absolutevarsym;
  1615. ref:=_ref;
  1616. end;
  1617. destructor tabsolutevarsym.destroy;
  1618. begin
  1619. if assigned(ref) then
  1620. ref.free;
  1621. inherited destroy;
  1622. end;
  1623. constructor tabsolutevarsym.ppuload(ppufile:tcompilerppufile);
  1624. begin
  1625. inherited ppuload(ppufile);
  1626. typ:=absolutevarsym;
  1627. ref:=nil;
  1628. asmname:=nil;
  1629. abstyp:=absolutetyp(ppufile.getbyte);
  1630. {$ifdef i386}
  1631. absseg:=false;
  1632. {$endif i386}
  1633. case abstyp of
  1634. tovar :
  1635. ref:=ppufile.getsymlist;
  1636. toasm :
  1637. asmname:=stringdup(ppufile.getstring);
  1638. toaddr :
  1639. begin
  1640. addroffset:=ppufile.getaint;
  1641. {$ifdef i386}
  1642. absseg:=boolean(ppufile.getbyte);
  1643. {$endif i386}
  1644. end;
  1645. end;
  1646. end;
  1647. procedure tabsolutevarsym.ppuwrite(ppufile:tcompilerppufile);
  1648. begin
  1649. inherited ppuwrite(ppufile);
  1650. ppufile.putbyte(byte(abstyp));
  1651. case abstyp of
  1652. tovar :
  1653. ppufile.putsymlist(ref);
  1654. toasm :
  1655. ppufile.putstring(asmname^);
  1656. toaddr :
  1657. begin
  1658. ppufile.putaint(addroffset);
  1659. {$ifdef i386}
  1660. ppufile.putbyte(byte(absseg));
  1661. {$endif i386}
  1662. end;
  1663. end;
  1664. ppufile.writeentry(ibabsolutevarsym);
  1665. end;
  1666. procedure tabsolutevarsym.buildderef;
  1667. begin
  1668. inherited buildderef;
  1669. if (abstyp=tovar) then
  1670. ref.buildderef;
  1671. end;
  1672. procedure tabsolutevarsym.deref;
  1673. begin
  1674. inherited deref;
  1675. { own absolute deref }
  1676. if (abstyp=tovar) then
  1677. ref.resolve;
  1678. end;
  1679. function tabsolutevarsym.mangledname : string;
  1680. begin
  1681. case abstyp of
  1682. toasm :
  1683. mangledname:=asmname^;
  1684. toaddr :
  1685. mangledname:='$'+tostr(addroffset);
  1686. else
  1687. internalerror(200411061);
  1688. end;
  1689. end;
  1690. {$ifdef GDB}
  1691. function tabsolutevarsym.stabstring:Pchar;
  1692. begin
  1693. stabstring:=nil;
  1694. end;
  1695. {$endif GDB}
  1696. {****************************************************************************
  1697. TTYPEDCONSTSYM
  1698. *****************************************************************************}
  1699. constructor ttypedconstsym.create(const n : string;p : tdef;writable : boolean);
  1700. begin
  1701. inherited create(n);
  1702. typ:=typedconstsym;
  1703. typedconsttype.setdef(p);
  1704. is_writable:=writable;
  1705. end;
  1706. constructor ttypedconstsym.createtype(const n : string;const tt : ttype;writable : boolean);
  1707. begin
  1708. inherited create(n);
  1709. typ:=typedconstsym;
  1710. typedconsttype:=tt;
  1711. is_writable:=writable;
  1712. end;
  1713. constructor ttypedconstsym.ppuload(ppufile:tcompilerppufile);
  1714. begin
  1715. inherited ppuload(ppufile);
  1716. typ:=typedconstsym;
  1717. ppufile.gettype(typedconsttype);
  1718. is_writable:=boolean(ppufile.getbyte);
  1719. end;
  1720. destructor ttypedconstsym.destroy;
  1721. begin
  1722. if assigned(_mangledname) then
  1723. begin
  1724. {$ifdef MEMDEBUG}
  1725. memmanglednames.start;
  1726. {$endif MEMDEBUG}
  1727. stringdispose(_mangledname);
  1728. {$ifdef MEMDEBUG}
  1729. memmanglednames.stop;
  1730. {$endif MEMDEBUG}
  1731. end;
  1732. inherited destroy;
  1733. end;
  1734. function ttypedconstsym.mangledname:string;
  1735. begin
  1736. if not assigned(_mangledname) then
  1737. begin
  1738. {$ifdef compress}
  1739. _mangledname:=stringdup(make_mangledname('TC',owner,name));
  1740. {$else}
  1741. _mangledname:=stringdup(make_mangledname('TC',owner,name));
  1742. {$endif}
  1743. end;
  1744. result:=_mangledname^;
  1745. end;
  1746. function ttypedconstsym.getsize : longint;
  1747. begin
  1748. if assigned(typedconsttype.def) then
  1749. getsize:=typedconsttype.def.size
  1750. else
  1751. getsize:=0;
  1752. end;
  1753. procedure ttypedconstsym.buildderef;
  1754. begin
  1755. typedconsttype.buildderef;
  1756. end;
  1757. procedure ttypedconstsym.deref;
  1758. begin
  1759. typedconsttype.resolve;
  1760. end;
  1761. procedure ttypedconstsym.ppuwrite(ppufile:tcompilerppufile);
  1762. begin
  1763. inherited ppuwrite(ppufile);
  1764. ppufile.puttype(typedconsttype);
  1765. ppufile.putbyte(byte(is_writable));
  1766. ppufile.writeentry(ibtypedconstsym);
  1767. end;
  1768. {$ifdef GDB}
  1769. function ttypedconstsym.stabstring : pchar;
  1770. var st:char;
  1771. begin
  1772. if (cs_gdb_gsym in aktglobalswitches) and (owner.symtabletype=globalsymtable) then
  1773. st:='G'
  1774. else
  1775. st:='S';
  1776. stabstring:=stabstr_evaluate('"${name}:$1$2",${N_STSYM},0,${line},${mangledname}',
  1777. [st,Tstoreddef(typedconsttype.def).numberstring]);
  1778. end;
  1779. {$endif GDB}
  1780. {****************************************************************************
  1781. TCONSTSYM
  1782. ****************************************************************************}
  1783. constructor tconstsym.create_ord(const n : string;t : tconsttyp;v : tconstexprint;const tt:ttype);
  1784. begin
  1785. inherited create(n);
  1786. fillchar(value, sizeof(value), #0);
  1787. typ:=constsym;
  1788. consttyp:=t;
  1789. value.valueord:=v;
  1790. ResStrIndex:=0;
  1791. consttype:=tt;
  1792. end;
  1793. constructor tconstsym.create_ordptr(const n : string;t : tconsttyp;v : tconstptruint;const tt:ttype);
  1794. begin
  1795. inherited create(n);
  1796. fillchar(value, sizeof(value), #0);
  1797. typ:=constsym;
  1798. consttyp:=t;
  1799. value.valueordptr:=v;
  1800. ResStrIndex:=0;
  1801. consttype:=tt;
  1802. end;
  1803. constructor tconstsym.create_ptr(const n : string;t : tconsttyp;v : pointer;const tt:ttype);
  1804. begin
  1805. inherited create(n);
  1806. fillchar(value, sizeof(value), #0);
  1807. typ:=constsym;
  1808. consttyp:=t;
  1809. value.valueptr:=v;
  1810. ResStrIndex:=0;
  1811. consttype:=tt;
  1812. end;
  1813. constructor tconstsym.create_string(const n : string;t : tconsttyp;str:pchar;l:longint);
  1814. begin
  1815. inherited create(n);
  1816. fillchar(value, sizeof(value), #0);
  1817. typ:=constsym;
  1818. consttyp:=t;
  1819. value.valueptr:=str;
  1820. consttype.reset;
  1821. value.len:=l;
  1822. if t=constresourcestring then
  1823. ResStrIndex:=ResourceStrings.Register(name,pchar(value.valueptr),value.len);
  1824. end;
  1825. constructor tconstsym.ppuload(ppufile:tcompilerppufile);
  1826. var
  1827. pd : pbestreal;
  1828. ps : pnormalset;
  1829. pc : pchar;
  1830. begin
  1831. inherited ppuload(ppufile);
  1832. typ:=constsym;
  1833. consttype.reset;
  1834. consttyp:=tconsttyp(ppufile.getbyte);
  1835. fillchar(value, sizeof(value), #0);
  1836. case consttyp of
  1837. constord :
  1838. begin
  1839. ppufile.gettype(consttype);
  1840. value.valueord:=ppufile.getexprint;
  1841. end;
  1842. constpointer :
  1843. begin
  1844. ppufile.gettype(consttype);
  1845. value.valueordptr:=ppufile.getptruint;
  1846. end;
  1847. conststring,
  1848. constresourcestring :
  1849. begin
  1850. value.len:=ppufile.getlongint;
  1851. getmem(pc,value.len+1);
  1852. ppufile.getdata(pc^,value.len);
  1853. if consttyp=constresourcestring then
  1854. ResStrIndex:=ppufile.getlongint;
  1855. value.valueptr:=pc;
  1856. end;
  1857. constreal :
  1858. begin
  1859. new(pd);
  1860. pd^:=ppufile.getreal;
  1861. value.valueptr:=pd;
  1862. end;
  1863. constset :
  1864. begin
  1865. ppufile.gettype(consttype);
  1866. new(ps);
  1867. ppufile.getnormalset(ps^);
  1868. value.valueptr:=ps;
  1869. end;
  1870. constguid :
  1871. begin
  1872. new(pguid(value.valueptr));
  1873. ppufile.getdata(value.valueptr^,sizeof(tguid));
  1874. end;
  1875. constnil : ;
  1876. else
  1877. Message1(unit_f_ppu_invalid_entry,tostr(ord(consttyp)));
  1878. end;
  1879. end;
  1880. destructor tconstsym.destroy;
  1881. begin
  1882. case consttyp of
  1883. conststring,
  1884. constresourcestring :
  1885. freemem(pchar(value.valueptr),value.len+1);
  1886. constreal :
  1887. dispose(pbestreal(value.valueptr));
  1888. constset :
  1889. dispose(pnormalset(value.valueptr));
  1890. constguid :
  1891. dispose(pguid(value.valueptr));
  1892. end;
  1893. inherited destroy;
  1894. end;
  1895. procedure tconstsym.buildderef;
  1896. begin
  1897. if consttyp in [constord,constpointer,constset] then
  1898. consttype.buildderef;
  1899. end;
  1900. procedure tconstsym.deref;
  1901. begin
  1902. if consttyp in [constord,constpointer,constset] then
  1903. consttype.resolve;
  1904. end;
  1905. procedure tconstsym.ppuwrite(ppufile:tcompilerppufile);
  1906. begin
  1907. inherited ppuwrite(ppufile);
  1908. ppufile.putbyte(byte(consttyp));
  1909. case consttyp of
  1910. constnil : ;
  1911. constord :
  1912. begin
  1913. ppufile.puttype(consttype);
  1914. ppufile.putexprint(value.valueord);
  1915. end;
  1916. constpointer :
  1917. begin
  1918. ppufile.puttype(consttype);
  1919. ppufile.putptruint(value.valueordptr);
  1920. end;
  1921. conststring,
  1922. constresourcestring :
  1923. begin
  1924. ppufile.putlongint(value.len);
  1925. ppufile.putdata(pchar(value.valueptr)^,value.len);
  1926. if consttyp=constresourcestring then
  1927. ppufile.putlongint(ResStrIndex);
  1928. end;
  1929. constreal :
  1930. ppufile.putreal(pbestreal(value.valueptr)^);
  1931. constset :
  1932. begin
  1933. ppufile.puttype(consttype);
  1934. ppufile.putnormalset(value.valueptr^);
  1935. end;
  1936. constguid :
  1937. ppufile.putdata(value.valueptr^,sizeof(tguid));
  1938. else
  1939. internalerror(13);
  1940. end;
  1941. ppufile.writeentry(ibconstsym);
  1942. end;
  1943. {$ifdef GDB}
  1944. function Tconstsym.stabstring:Pchar;
  1945. var st : string;
  1946. begin
  1947. {even GDB v4.16 only now 'i' 'r' and 'e' !!!}
  1948. case consttyp of
  1949. conststring:
  1950. st:='s'''+backspace_quote(octal_quote(strpas(pchar(value.valueptr)),[#0..#9,#11,#12,#14..#31,'''']),['"','\',#10,#13])+'''';
  1951. constord:
  1952. st:='i'+tostr(value.valueord);
  1953. constpointer:
  1954. st:='i'+tostr(value.valueordptr);
  1955. constreal:
  1956. begin
  1957. system.str(pbestreal(value.valueptr)^,st);
  1958. st := 'r'+st;
  1959. end;
  1960. { if we don't know just put zero !! }
  1961. else st:='i0';
  1962. {***SETCONST}
  1963. {constset:;} {*** I don't know what to do with a set.}
  1964. { sets are not recognized by GDB}
  1965. {***}
  1966. end;
  1967. { valgrind does not support constants }
  1968. if cs_gdb_valgrind in aktglobalswitches then
  1969. stabstring:=nil
  1970. else
  1971. stabstring:=stabstr_evaluate('"${name}:c=$1;",${N_FUNCTION},0,${line},0',[st]);
  1972. end;
  1973. {$endif GDB}
  1974. {****************************************************************************
  1975. TENUMSYM
  1976. ****************************************************************************}
  1977. constructor tenumsym.create(const n : string;def : tenumdef;v : longint);
  1978. begin
  1979. inherited create(n);
  1980. typ:=enumsym;
  1981. definition:=def;
  1982. value:=v;
  1983. { check for jumps }
  1984. if v>def.max+1 then
  1985. def.has_jumps:=true;
  1986. { update low and high }
  1987. if def.min>v then
  1988. def.setmin(v);
  1989. if def.max<v then
  1990. def.setmax(v);
  1991. order;
  1992. { nextenum:=Tenumsym(def.firstenum);
  1993. def.firstenum:=self;}
  1994. end;
  1995. constructor tenumsym.ppuload(ppufile:tcompilerppufile);
  1996. begin
  1997. inherited ppuload(ppufile);
  1998. typ:=enumsym;
  1999. ppufile.getderef(definitionderef);
  2000. value:=ppufile.getlongint;
  2001. nextenum := Nil;
  2002. end;
  2003. procedure tenumsym.buildderef;
  2004. begin
  2005. definitionderef.build(definition);
  2006. end;
  2007. procedure tenumsym.deref;
  2008. begin
  2009. definition:=tenumdef(definitionderef.resolve);
  2010. order;
  2011. end;
  2012. procedure tenumsym.order;
  2013. var
  2014. sym : tenumsym;
  2015. begin
  2016. sym := tenumsym(definition.firstenum);
  2017. if sym = nil then
  2018. begin
  2019. definition.firstenum := self;
  2020. nextenum := nil;
  2021. exit;
  2022. end;
  2023. { reorder the symbols in increasing value }
  2024. if value < sym.value then
  2025. begin
  2026. nextenum := sym;
  2027. definition.firstenum := self;
  2028. end
  2029. else
  2030. begin
  2031. while (sym.value <= value) and assigned(sym.nextenum) do
  2032. sym := sym.nextenum;
  2033. nextenum := sym.nextenum;
  2034. sym.nextenum := self;
  2035. end;
  2036. end;
  2037. procedure tenumsym.ppuwrite(ppufile:tcompilerppufile);
  2038. begin
  2039. inherited ppuwrite(ppufile);
  2040. ppufile.putderef(definitionderef);
  2041. ppufile.putlongint(value);
  2042. ppufile.writeentry(ibenumsym);
  2043. end;
  2044. {****************************************************************************
  2045. TTYPESYM
  2046. ****************************************************************************}
  2047. constructor ttypesym.create(const n : string;const tt : ttype);
  2048. begin
  2049. inherited create(n);
  2050. typ:=typesym;
  2051. restype:=tt;
  2052. { register the typesym for the definition }
  2053. if assigned(restype.def) and
  2054. (restype.def.deftype<>errordef) and
  2055. not(assigned(restype.def.typesym)) then
  2056. restype.def.typesym:=self;
  2057. end;
  2058. constructor ttypesym.ppuload(ppufile:tcompilerppufile);
  2059. begin
  2060. inherited ppuload(ppufile);
  2061. typ:=typesym;
  2062. ppufile.gettype(restype);
  2063. end;
  2064. function ttypesym.gettypedef:tdef;
  2065. begin
  2066. gettypedef:=restype.def;
  2067. end;
  2068. procedure ttypesym.buildderef;
  2069. begin
  2070. restype.buildderef;
  2071. end;
  2072. procedure ttypesym.deref;
  2073. begin
  2074. restype.resolve;
  2075. end;
  2076. procedure ttypesym.ppuwrite(ppufile:tcompilerppufile);
  2077. begin
  2078. inherited ppuwrite(ppufile);
  2079. ppufile.puttype(restype);
  2080. ppufile.writeentry(ibtypesym);
  2081. end;
  2082. procedure ttypesym.load_references(ppufile:tcompilerppufile;locals:boolean);
  2083. begin
  2084. inherited load_references(ppufile,locals);
  2085. if (restype.def.deftype=recorddef) then
  2086. tstoredsymtable(trecorddef(restype.def).symtable).load_references(ppufile,locals);
  2087. if (restype.def.deftype=objectdef) then
  2088. tstoredsymtable(tobjectdef(restype.def).symtable).load_references(ppufile,locals);
  2089. end;
  2090. function ttypesym.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  2091. var
  2092. d : tderef;
  2093. begin
  2094. d.reset;
  2095. if not inherited write_references(ppufile,locals) then
  2096. begin
  2097. { write address of this symbol if record or object
  2098. even if no real refs are there
  2099. because we need it for the symtable }
  2100. if (restype.def.deftype in [recorddef,objectdef]) then
  2101. begin
  2102. d.build(self);
  2103. ppufile.putderef(d);
  2104. ppufile.writeentry(ibsymref);
  2105. end;
  2106. end;
  2107. write_references:=true;
  2108. if (restype.def.deftype=recorddef) then
  2109. tstoredsymtable(trecorddef(restype.def).symtable).write_references(ppufile,locals);
  2110. if (restype.def.deftype=objectdef) then
  2111. tstoredsymtable(tobjectdef(restype.def).symtable).write_references(ppufile,locals);
  2112. end;
  2113. {$ifdef GDB}
  2114. function ttypesym.stabstring : pchar;
  2115. var stabchar:string[2];
  2116. begin
  2117. stabstring:=nil;
  2118. if restype.def<>nil then
  2119. begin
  2120. if restype.def.deftype in tagtypes then
  2121. stabchar:='Tt'
  2122. else
  2123. stabchar:='t';
  2124. stabstring:=stabstr_evaluate('"${name}:$1$2",${N_LSYM},0,${line},0',[stabchar,tstoreddef(restype.def).numberstring]);
  2125. end;
  2126. end;
  2127. {$endif GDB}
  2128. {****************************************************************************
  2129. TSYSSYM
  2130. ****************************************************************************}
  2131. constructor tsyssym.create(const n : string;l : longint);
  2132. begin
  2133. inherited create(n);
  2134. typ:=syssym;
  2135. number:=l;
  2136. end;
  2137. constructor tsyssym.ppuload(ppufile:tcompilerppufile);
  2138. begin
  2139. inherited ppuload(ppufile);
  2140. typ:=syssym;
  2141. number:=ppufile.getlongint;
  2142. end;
  2143. destructor tsyssym.destroy;
  2144. begin
  2145. inherited destroy;
  2146. end;
  2147. procedure tsyssym.ppuwrite(ppufile:tcompilerppufile);
  2148. begin
  2149. inherited ppuwrite(ppufile);
  2150. ppufile.putlongint(number);
  2151. ppufile.writeentry(ibsyssym);
  2152. end;
  2153. {****************************************************************************
  2154. TRTTISYM
  2155. ****************************************************************************}
  2156. constructor trttisym.create(const n:string;rt:trttitype);
  2157. const
  2158. prefix : array[trttitype] of string[5]=('$rtti','$init');
  2159. begin
  2160. inherited create(prefix[rt]+n);
  2161. include(symoptions,sp_internal);
  2162. typ:=rttisym;
  2163. lab:=nil;
  2164. rttityp:=rt;
  2165. end;
  2166. destructor trttisym.destroy;
  2167. begin
  2168. if assigned(_mangledname) then
  2169. begin
  2170. {$ifdef MEMDEBUG}
  2171. memmanglednames.start;
  2172. {$endif MEMDEBUG}
  2173. stringdispose(_mangledname);
  2174. {$ifdef MEMDEBUG}
  2175. memmanglednames.stop;
  2176. {$endif MEMDEBUG}
  2177. end;
  2178. inherited destroy;
  2179. end;
  2180. constructor trttisym.ppuload(ppufile:tcompilerppufile);
  2181. begin
  2182. inherited ppuload(ppufile);
  2183. typ:=rttisym;
  2184. lab:=nil;
  2185. rttityp:=trttitype(ppufile.getbyte);
  2186. end;
  2187. procedure trttisym.ppuwrite(ppufile:tcompilerppufile);
  2188. begin
  2189. inherited ppuwrite(ppufile);
  2190. ppufile.putbyte(byte(rttityp));
  2191. ppufile.writeentry(ibrttisym);
  2192. end;
  2193. function trttisym.mangledname : string;
  2194. const
  2195. prefix : array[trttitype] of string[5]=('RTTI_','INIT_');
  2196. begin
  2197. if not assigned(_mangledname) then
  2198. _mangledname:=stringdup(make_mangledname(prefix[rttityp],owner,Copy(name,5,255)));
  2199. result:=_mangledname^;
  2200. end;
  2201. function trttisym.get_label:tasmsymbol;
  2202. begin
  2203. { the label is always a global label }
  2204. if not assigned(lab) then
  2205. lab:=objectlibrary.newasmsymbol(mangledname,AB_EXTERNAL,AT_DATA);
  2206. get_label:=lab;
  2207. end;
  2208. end.
  2209. {
  2210. $Log$
  2211. Revision 1.194 2004-11-17 22:21:35 peter
  2212. mangledname setting moved to place after the complete proc declaration is read
  2213. import generation moved to place where body is also parsed (still gives problems with win32)
  2214. Revision 1.193 2004/11/16 22:09:57 peter
  2215. * _mangledname for symbols moved only to symbols that really need it
  2216. * overload number removed, add function result type to the mangledname fo
  2217. procdefs
  2218. Revision 1.192 2004/11/15 23:35:31 peter
  2219. * tparaitem removed, use tparavarsym instead
  2220. * parameter order is now calculated from paranr value in tparavarsym
  2221. Revision 1.191 2004/11/08 22:09:59 peter
  2222. * tvarsym splitted
  2223. Revision 1.190 2004/11/04 17:09:54 peter
  2224. fixed debuginfo for variables in staticsymtable
  2225. Revision 1.189 2004/10/31 21:45:03 peter
  2226. * generic tlocation
  2227. * move tlocation to cgutils
  2228. Revision 1.188 2004/10/15 09:14:17 mazen
  2229. - remove $IFDEF DELPHI and related code
  2230. - remove $IFDEF FPCPROCVAR and related code
  2231. Revision 1.187 2004/10/13 18:47:45 peter
  2232. * fix misplaced begin..end for self stabs
  2233. * no fpu regable for staticsymtable
  2234. Revision 1.186 2004/10/12 14:34:49 peter
  2235. * fixed visibility for procsyms
  2236. * fixed override check when there was no entry yet
  2237. Revision 1.185 2004/10/11 20:48:34 peter
  2238. * don't generate stabs for self when it is in a regvar
  2239. Revision 1.184 2004/10/11 15:48:15 peter
  2240. * small regvar for para fixes
  2241. * function tvarsym.is_regvar added
  2242. * tvarsym.getvaluesize removed, use getsize instead
  2243. Revision 1.183 2004/10/10 21:08:55 peter
  2244. * parameter regvar fixes
  2245. Revision 1.182 2004/10/10 20:22:53 peter
  2246. * symtable allocation rewritten
  2247. * loading of parameters to local temps/regs cleanup
  2248. * regvar support for parameters
  2249. * regvar support for staticsymtable (main body)
  2250. Revision 1.181 2004/10/10 09:31:28 peter
  2251. regvar ppu writing doesn't affect any crc
  2252. Revision 1.180 2004/10/08 17:09:43 peter
  2253. * tvarsym.varregable added, split vo_regable from varoptions
  2254. Revision 1.179 2004/10/06 19:26:50 jonas
  2255. * regvar fixes from Peter
  2256. Revision 1.178 2004/10/01 15:22:22 peter
  2257. * don't add stabs for register variables
  2258. Revision 1.177 2004/09/26 17:45:30 peter
  2259. * simple regvar support, not yet finished
  2260. Revision 1.176 2004/09/21 17:25:12 peter
  2261. * paraloc branch merged
  2262. Revision 1.175.4.1 2004/08/31 20:43:06 peter
  2263. * paraloc patch
  2264. Revision 1.175 2004/08/15 12:06:03 jonas
  2265. * add cprefix to procedures which are autoamtically marked as external in
  2266. macpas mode
  2267. Revision 1.174 2004/06/20 08:55:30 florian
  2268. * logs truncated
  2269. Revision 1.173 2004/06/16 20:07:09 florian
  2270. * dwarf branch merged
  2271. Revision 1.172 2004/05/22 23:32:52 peter
  2272. quote all low ascii chars in stabs
  2273. Revision 1.171 2004/05/11 22:52:48 olle
  2274. * Moved import_implicit_external to symsym
  2275. Revision 1.170 2004/05/11 18:29:41 olle
  2276. + mode macpas: support for implicit external
  2277. Revision 1.169.2.3 2004/05/01 16:02:09 peter
  2278. * POINTER_SIZE replaced with sizeof(aint)
  2279. * aint,aword,tconst*int moved to globtype
  2280. }