symsym.pas 77 KB

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