defs.pas 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546
  1. {
  2. $Id$
  3. This unit handles definitions
  4. Copyright (C) 1998-2000 by Daniel Mantione,
  5. member of the Free Pascal development team
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. {$ifdef TP}
  20. {$N+,E+,F+}
  21. {$endif}
  22. unit defs;
  23. interface
  24. uses symtable,objects,cobjects,symtablt,globtype
  25. {$ifdef i386}
  26. ,i386base
  27. {$endif}
  28. {$ifdef m68k}
  29. ,m68k
  30. {$endif}
  31. {$ifdef alpha}
  32. ,alpha
  33. {$endif};
  34. type Targconvtyp=(act_convertable,act_equal,act_exact);
  35. Tvarspez=(vs_value,vs_const,vs_var);
  36. Tobjprop=(sp_public,sp_private,sp_protected,
  37. sp_forwarddef,sp_static);
  38. Tobjpropset=set of Tobjprop;
  39. Tobjoption=(oo_is_abstract, {The object/class has
  40. an abstract method => no
  41. instances can be created.}
  42. oo_is_class, {The object is a class.}
  43. oo_has_virtual, {The object/class has
  44. virtual methods.}
  45. oo_has_private, {The object has private members.}
  46. oo_has_protected, {The obejct has protected
  47. members.}
  48. oo_isforward, {The class is only a forward
  49. declared yet.}
  50. oo_can_have_published, {True, if the class has rtti, i.e.
  51. you can publish properties.}
  52. oo_has_constructor, {The object/class has a
  53. constructor.}
  54. oo_has_destructor, {The object/class has a
  55. destructor.}
  56. oo_has_vmt, {The object/class has a vmt.}
  57. oo_has_msgstr,
  58. oo_has_msgint,
  59. oo_cppvmt); {The object/class uses an C++
  60. compatible vmt, all members of
  61. the same class tree, must use
  62. then a C++ compatible vmt.}
  63. Tobjoptionset=set of Tobjoption;
  64. {Options for Tprocdef and Tprocvardef}
  65. Tprocoption=(povirtualmethod, {Procedure is a virtual method.}
  66. poclearstack, {Use IBM flat calling convention.
  67. (Used by GCC.)}
  68. poconstructor, {Procedure is a constructor.}
  69. podestructor, {Procedure is a destructor.}
  70. pointernproc, {Procedure has compiler magic.}
  71. poexports, {Procedure is exported.}
  72. poiocheck, {IO checking should be done after
  73. a call to the procedure.}
  74. poabstractmethod, {Procedure is an abstract method.}
  75. pointerrupt, {Procedure is an interrupt handler.}
  76. poinline, {Procedure is an assembler macro.}
  77. poassembler, {Procedure is written in assembler.}
  78. pooperator, {Procedure defines an operator.}
  79. poexternal, {Procedure is external (in other
  80. object or lib)}
  81. poleftright, {Push parameters from left to right.}
  82. poprocinit, {Program initialization.}
  83. postaticmethod, {Static method.}
  84. pooveridingmethod, {Method with override directive }
  85. poclassmethod, {Class method.}
  86. pounitinit, {Unit initialization }
  87. pomethodpointer, {Method pointer, only in procvardef,
  88. also used for 'with object do' }
  89. pocdecl, {Procedure uses C styled calling }
  90. popalmossyscall, {Procedure is a PalmOS system call }
  91. pointernconst, {Procedure has constant evaluator
  92. intern.}
  93. poregister, {Procedure uses register (fastcall)
  94. calling }
  95. pounitfinalize, {Unit finalization }
  96. postdcall, {Procedure uses stdcall
  97. call.}
  98. pomsgstr, {Method for string message
  99. handling.}
  100. pomsgint, {Method for int message handling.}
  101. posavestdregs, {Save std regs cdecl and stdcall
  102. need that !}
  103. pocontainsself, {Self is passed explicit to the
  104. compiler.}
  105. posafecall); {Safe call calling conventions }
  106. Tprocoptionset=set of Tprocoption;
  107. Tarrayoption=(ap_variant,ap_constructor,ap_arrayofconst);
  108. Tarrayoptionset=set of Tarrayoption;
  109. Pparameter=^Tparameter;
  110. Tparameter=object(Tobject)
  111. data:Psym;
  112. paratyp:Tvarspez;
  113. argconvtyp:Targconvtyp;
  114. convertlevel:byte;
  115. register:Tregister;
  116. end;
  117. Tfiletype=(ft_text,ft_typed,ft_untyped);
  118. Pfiledef=^Tfiledef;
  119. Tfiledef=object(Tdef)
  120. filetype:Tfiletype;
  121. typed_as:Pdef;
  122. constructor init(Aowner:Pcontainingsymtable;
  123. ft:Tfiletype;tas:Pdef);
  124. constructor load(var s:Tstream);
  125. procedure deref;virtual;
  126. function gettypename:string;virtual;
  127. procedure setsize;
  128. {$ifdef GDB}
  129. function stabstring:Pchar;virtual;
  130. procedure concatstabto(asmlist:Paasmoutput);virtual;
  131. {$endif GDB}
  132. procedure store(var s:Tstream);virtual;
  133. end;
  134. Pformaldef=^Tformaldef;
  135. Tformaldef=object(Tdef)
  136. constructor init(Aowner:Pcontainingsymtable);
  137. constructor load(var s:Tstream);
  138. procedure store(var s:Tstream);virtual;
  139. {$ifdef GDB}
  140. function stabstring:Pchar;virtual;
  141. procedure concatstabto(asmlist:Paasmoutput);virtual;
  142. {$endif GDB}
  143. function gettypename:string;virtual;
  144. end;
  145. Perrordef=^Terrordef;
  146. Terrordef=object(Tdef)
  147. {$ifdef GDB}
  148. function stabstring:Pchar;virtual;
  149. {$endif GDB}
  150. function gettypename:string;virtual;
  151. end;
  152. Pabstractpointerdef=^Tabstractpointerdef;
  153. Tabstractpointerdef=object(Tdef)
  154. definition:Pdef;
  155. defsym:Psym;
  156. constructor init(Aowner:Pcontainingsymtable;def:Pdef);
  157. constructor load(var s:Tstream);
  158. procedure deref;virtual;
  159. procedure store(var s:Tstream);virtual;
  160. {$ifdef GDB}
  161. function stabstring:Pchar;virtual;
  162. procedure concatstabto(asmlist:Paasmoutput);virtual;
  163. {$endif GDB}
  164. end;
  165. Ppointerdef=^Tpointerdef;
  166. Tpointerdef=object(Tabstractpointerdef)
  167. is_far:boolean;
  168. constructor initfar(Aowner:Pcontainingsymtable;def:Pdef);
  169. constructor load(var s:Tstream);
  170. procedure store(var s:Tstream);virtual;
  171. function gettypename:string;virtual;
  172. end;
  173. Pclassrefdef=^Tclassrefdef;
  174. Tclassrefdef=object(Tpointerdef)
  175. {$ifdef GDB}
  176. function stabstring : pchar;virtual;
  177. procedure concatstabto(asmlist : paasmoutput);virtual;
  178. {$endif GDB}
  179. function gettypename:string;virtual;
  180. end;
  181. Pobjectdef=^Tobjectdef;
  182. Tobjectdef=object(Tdef)
  183. childof:Pobjectdef;
  184. objname:Pstring;
  185. privatesyms,
  186. protectedsyms,
  187. publicsyms:Pobjectsymtable;
  188. options:Tobjoptionset;
  189. {To be able to have a variable vmt position
  190. and no vmt field for objects without virtuals }
  191. vmt_offset:longint;
  192. constructor init(const n:string;Aowner:Pcontainingsymtable;
  193. parent:Pobjectdef);
  194. constructor load(var s:Tstream);
  195. procedure check_forwards;
  196. procedure insertvmt;
  197. function isrelated(d:Pobjectdef):boolean;
  198. function search(const s:string):Psym;
  199. function speedsearch(const s:string;
  200. speedvalue:longint):Psym;virtual;
  201. function size:longint;virtual;
  202. procedure store(var s:Tstream);virtual;
  203. function vmt_mangledname : string;
  204. function rtti_name : string;
  205. procedure set_parent(parent:Pobjectdef);
  206. {$ifdef GDB}
  207. function stabstring : pchar;virtual;
  208. {$endif GDB}
  209. procedure deref;virtual;
  210. function needs_inittable:boolean;virtual;
  211. procedure write_init_data;virtual;
  212. procedure write_child_init_data;virtual;
  213. {Rtti }
  214. function get_rtti_label:string;virtual;
  215. procedure generate_rtti;virtual;
  216. procedure write_rtti_data;virtual;
  217. procedure write_child_rtti_data;virtual;
  218. function next_free_name_index:longint;
  219. function is_publishable:boolean;virtual;
  220. destructor done;virtual;
  221. end;
  222. Parraydef=^Tarraydef;
  223. Tarraydef=object(Tdef)
  224. lowrange,
  225. highrange:Tconstant;
  226. definition:Pdef;
  227. rangedef:Pdef;
  228. options:Tarrayoptionset;
  229. constructor init(const l,h:Tconstant;rd:Pdef;
  230. Aowner:Pcontainingsymtable);
  231. constructor load(var s:Tstream);
  232. function elesize:longint;
  233. function gettypename:string;virtual;
  234. procedure store(var s:Tstream);virtual;
  235. {$ifdef GDB}
  236. function stabstring : pchar;virtual;
  237. procedure concatstabto(asmlist : paasmoutput);virtual;
  238. {$endif GDB}
  239. procedure deref;virtual;
  240. function size : longint;virtual;
  241. { generates the ranges needed by the asm instruction BOUND (i386)
  242. or CMP2 (Motorola) }
  243. procedure genrangecheck;
  244. { returns the label of the range check string }
  245. function getrangecheckstring : string;
  246. function needs_inittable : boolean;virtual;
  247. procedure write_rtti_data;virtual;
  248. procedure write_child_rtti_data;virtual;
  249. private
  250. rangenr:longint;
  251. end;
  252. Penumdef=^Tenumdef;
  253. Tenumdef=object(Tdef)
  254. rangenr,
  255. minval,
  256. maxval:longint;
  257. has_jumps:boolean;
  258. symbols:Pcollection;
  259. basedef:Penumdef;
  260. constructor init(Aowner:Pcontainingsymtable);
  261. constructor init_subrange(Abasedef:Penumdef;Amin,Amax:longint;
  262. Aowner:Pcontainingsymtable);
  263. constructor load(var s:Tstream);
  264. procedure deref;virtual;
  265. procedure calcsavesize;
  266. function getrangecheckstring:string;
  267. procedure genrangecheck;
  268. procedure setmax(Amax:longint);
  269. procedure setmin(Amin:longint);
  270. procedure store(var s:Tstream);virtual;
  271. {$ifdef GDB}
  272. function stabstring:Pchar;virtual;
  273. {$endif GDB}
  274. procedure write_child_rtti_data;virtual;
  275. procedure write_rtti_data;virtual;
  276. function is_publishable : boolean;virtual;
  277. function gettypename:string;virtual;
  278. end;
  279. Tbasetype=(uauto,uvoid,uchar,
  280. u8bit,u16bit,u32bit,
  281. s8bit,s16bit,s32bit,
  282. bool8bit,bool16bit,bool32bit { uwchar,bool1bit,bitfield},
  283. u64bit,s64bitint);
  284. Porddef=^Torddef;
  285. Torddef=object(Tdef)
  286. low,high:Tconstant;
  287. rangenr:longint;
  288. typ:Tbasetype;
  289. constructor init(t:tbasetype;l,h:Tconstant;
  290. Aowner:Pcontainingsymtable);
  291. constructor load(var s:Tstream);
  292. procedure store(var s:Tstream);virtual;
  293. procedure setsize;
  294. { generates the ranges needed by the asm instruction BOUND }
  295. { or CMP2 (Motorola) }
  296. procedure genrangecheck;
  297. { returns the label of the range check string }
  298. function getrangecheckstring : string;
  299. procedure write_rtti_data;virtual;
  300. function is_publishable:boolean;virtual;
  301. function gettypename:string;virtual;
  302. {$ifdef GDB}
  303. function stabstring:Pchar;virtual;
  304. {$endif GDB}
  305. end;
  306. {S80real is dependant on the cpu, s64comp is also
  307. dependant on the size (tp = 80bit for both)
  308. The EXTENDED format exists on the motorola FPU
  309. but it uses 96 bits instead of 80, with some
  310. unused bits within the number itself! Pretty
  311. complicated to support, so no support for the
  312. moment.
  313. S64comp is considered as a real because all
  314. calculations are done by the fpu.}
  315. Tfloattype=(s32real,s64real,s80real,s64comp,f16bit,f32bit);
  316. Pfloatdef=^Tfloatdef;
  317. Tfloatdef=object(tdef)
  318. typ:Tfloattype;
  319. constructor init(t:Tfloattype;Aowner:Pcontainingsymtable);
  320. constructor load(var s:Tstream);
  321. function is_publishable : boolean;virtual;
  322. procedure setsize;
  323. {$ifdef GDB}
  324. function stabstring:Pchar;virtual;
  325. {$endif GDB}
  326. procedure store(var s:Tstream);virtual;
  327. procedure write_rtti_data;virtual;
  328. function gettypename:string;virtual;
  329. end;
  330. Tsettype=(normset,smallset,varset);
  331. Psetdef=^Tsetdef;
  332. Tsetdef=object(Tdef)
  333. setof:Pdef;
  334. settype:Tsettype;
  335. constructor init(s:Pdef;high:longint;Aowner:Pcontainingsymtable);
  336. constructor load(var s:Tstream);
  337. procedure store(var s:Tstream);virtual;
  338. {$ifdef GDB}
  339. function stabstring : pchar;virtual;
  340. procedure concatstabto(asmlist : paasmoutput);virtual;
  341. {$endif GDB}
  342. procedure deref;virtual;
  343. function is_publishable : boolean;virtual;
  344. procedure write_rtti_data;virtual;
  345. procedure write_child_rtti_data;virtual;
  346. function gettypename:string;virtual;
  347. end;
  348. Precorddef=^Trecorddef;
  349. Trecorddef=object(Tdef)
  350. symtable:Precordsymtable;
  351. constructor init(s:Precordsymtable;Aowner:Pcontainingsymtable);
  352. constructor load(var s:Tstream);
  353. procedure store(var s:Tstream);virtual;
  354. {$ifdef GDB}
  355. function stabstring : pchar;virtual;
  356. procedure concatstabto(asmlist : paasmoutput);virtual;
  357. {$endif GDB}
  358. procedure deref;virtual;
  359. function needs_inittable : boolean;virtual;
  360. procedure write_rtti_data;virtual;
  361. procedure write_init_data;virtual;
  362. procedure write_child_rtti_data;virtual;
  363. procedure write_child_init_data;virtual;
  364. function gettypename:string;virtual;
  365. destructor done;virtual;
  366. end;
  367. Pabstractprocdef=^Pabstractprocdef;
  368. Tabstractprocdef=object(Tdef)
  369. {Saves a definition to the return type }
  370. retdef:Pdef;
  371. fpu_used:byte; {How many stack fpu must be empty.}
  372. options:Tprocoptionset; {Save the procedure options.}
  373. parameters:Pcollection;
  374. constructor init(Aowner:Pcontainingsymtable);
  375. constructor load(var s:Tstream);
  376. destructor done;virtual;
  377. procedure deref;virtual;
  378. function demangled_paras:string;
  379. function para_size:longint;
  380. procedure store(var s:Tstream);virtual;
  381. procedure test_if_fpu_result;
  382. {$ifdef GDB}
  383. function stabstring : pchar;virtual;
  384. procedure concatstabto(asmlist : paasmoutput);virtual;
  385. {$endif GDB}
  386. end;
  387. Pprocvardef=^Pprocvardef;
  388. Tprocvardef=object(Tabstractprocdef)
  389. function size:longint;virtual;
  390. {$ifdef GDB}
  391. function stabstring:Pchar;virtual;
  392. procedure concatstabto(asmlist:Paasmoutput); virtual;
  393. {$endif GDB}
  394. procedure write_child_rtti_data;virtual;
  395. function is_publishable:boolean;virtual;
  396. procedure write_rtti_data;virtual;
  397. function gettypename:string;virtual;
  398. end;
  399. Pprocdef = ^Tprocdef;
  400. Tprocdef = object(tabstractprocdef)
  401. objprop:Tobjpropset;
  402. extnumber:longint;
  403. { where is this function defined, needed here because there
  404. is only one symbol for all overloaded functions }
  405. fileinfo:Tfileposinfo;
  406. { pointer to the local symbol table }
  407. localst:Pprocsymtable;
  408. _mangledname:Pstring;
  409. { it's a tree, but this not easy to handle }
  410. { used for inlined procs }
  411. code : pointer;
  412. { true, if the procedure is only declared }
  413. { (forward procedure) }
  414. references:Pcollection;
  415. forwarddef,
  416. { true if the procedure is declared in the interface }
  417. interfacedef : boolean;
  418. { check the problems of manglednames }
  419. count : boolean;
  420. is_used : boolean;
  421. { set which contains the modified registers }
  422. usedregisters:Tregisterset;
  423. constructor init(Aowner:Pcontainingsymtable);
  424. constructor load(var s:Tstream);
  425. procedure store(var s:Tstream);virtual;
  426. {$ifdef GDB}
  427. function cplusplusmangledname : string;
  428. function stabstring : pchar;virtual;
  429. procedure concatstabto(asmlist : paasmoutput);virtual;
  430. {$endif GDB}
  431. procedure deref;virtual;
  432. function mangledname:string;
  433. procedure setmangledname(const s:string);
  434. procedure load_references;
  435. function write_references : boolean;
  436. destructor done;virtual;
  437. end;
  438. var cformaldef:Pformaldef; {Unique formal definition.}
  439. voiddef:Porddef; {Pointer to void (procedure) type }
  440. cchardef:Porddef; {Pointer to char type.}
  441. booldef:Porddef; {Pointer to boolean type.}
  442. u8bitdef:Porddef; {Pointer to 8-bit unsigned type.}
  443. u16bitdef:Porddef; {Pointer to 16-bit unsigned type.}
  444. u32bitdef:Porddef; {Pointer to 32-bit unsigned type.}
  445. s32bitdef:Porddef; {Pointer to 32-bit signed type.}
  446. implementation
  447. uses systems,symbols,verbose,globals,aasm,files;
  448. const {If you change one of the following contants,
  449. you have also to change the typinfo unit
  450. and the rtl/i386,template/rttip.inc files.}
  451. tkunknown = 0;
  452. tkinteger = 1;
  453. tkchar = 2;
  454. tkenumeration = 3;
  455. tkfloat = 4;
  456. tkset = 5;
  457. tkmethod = 6;
  458. tksstring = 7;
  459. tkstring = tksstring;
  460. tklstring = 8;
  461. tkastring = 9;
  462. tkwstring = 10;
  463. tkvariant = 11;
  464. tkarray = 12;
  465. tkrecord = 13;
  466. tkinterface = 14;
  467. tkclass = 15;
  468. tkobject = 16;
  469. tkwchar = 17;
  470. tkbool = 18;
  471. otsbyte = 0;
  472. otubyte = 1;
  473. otsword = 2;
  474. otuword = 3;
  475. otslong = 4;
  476. otulong = 5;
  477. ftsingle = 0;
  478. ftdouble = 1;
  479. ftextended = 2;
  480. ftcomp = 3;
  481. ftcurr = 4;
  482. ftfixed16 = 5;
  483. ftfixed32 = 6;
  484. {****************************************************************************
  485. Tfiledef
  486. ****************************************************************************}
  487. constructor Tfiledef.init(Aowner:Pcontainingsymtable;ft:Tfiletype;tas:Pdef);
  488. begin
  489. inherited init(Aowner);
  490. filetype:=ft;
  491. typed_as:=tas;
  492. setsize;
  493. end;
  494. constructor Tfiledef.load(var s:Tstream);
  495. begin
  496. inherited load(s);
  497. { filetype:=tfiletype(readbyte);
  498. if filetype=ft_typed then
  499. typed_as:=readdefref
  500. else
  501. typed_as:=nil;}
  502. setsize;
  503. end;
  504. procedure Tfiledef.deref;
  505. begin
  506. { if filetype=ft_typed then
  507. resolvedef(typed_as);}
  508. end;
  509. procedure Tfiledef.setsize;
  510. begin
  511. case filetype of
  512. ft_text:
  513. savesize:=572;
  514. ft_typed,ft_untyped:
  515. savesize:=316;
  516. end;
  517. end;
  518. procedure Tfiledef.store(var s:Tstream);
  519. begin
  520. { inherited store(s);
  521. writebyte(byte(filetype));
  522. if filetype=ft_typed then
  523. writedefref(typed_as);
  524. current_ppu^.writeentry(ibfiledef);}
  525. end;
  526. function Tfiledef.gettypename : string;
  527. begin
  528. case filetype of
  529. ft_untyped:
  530. gettypename:='File';
  531. ft_typed:
  532. gettypename:='File Of '+typed_as^.typename;
  533. ft_text:
  534. gettypename:='Text'
  535. end;
  536. end;
  537. {****************************************************************************
  538. Tformaldef
  539. ****************************************************************************}
  540. {Tformaldef is used for var parameters without a type.}
  541. constructor Tformaldef.init(Aowner:Pcontainingsymtable);
  542. begin
  543. inherited init(Aowner);
  544. savesize:=target_os.size_of_pointer;
  545. end;
  546. constructor Tformaldef.load(var s:Tstream);
  547. begin
  548. inherited load(s);
  549. savesize:=target_os.size_of_pointer;
  550. end;
  551. procedure Tformaldef.store(var s:Tstream);
  552. begin
  553. inherited store(s);
  554. { current_ppu^.writeentry(ibformaldef);}
  555. end;
  556. function Tformaldef.gettypename:string;
  557. begin
  558. gettypename:='Var';
  559. end;
  560. {****************************************************************************
  561. Terrordef
  562. ****************************************************************************}
  563. function Terrordef.gettypename:string;
  564. begin
  565. gettypename:='<erroneous type>';
  566. end;
  567. {****************************************************************************
  568. Tabstractpointerdef
  569. ****************************************************************************}
  570. constructor Tabstractpointerdef.init(Aowner:Pcontainingsymtable;def:Pdef);
  571. begin
  572. inherited init(Aowner);
  573. definition:=def;
  574. savesize:=target_os.size_of_pointer;
  575. end;
  576. constructor Tabstractpointerdef.load(var s:Tstream);
  577. begin
  578. inherited load(s);
  579. (* {The real address in memory is calculated later (deref).}
  580. definition:=readdefref; *)
  581. savesize:=target_os.size_of_pointer;
  582. end;
  583. procedure Tabstractpointerdef.deref;
  584. begin
  585. { resolvedef(definition);}
  586. end;
  587. procedure Tabstractpointerdef.store(var s:Tstream);
  588. begin
  589. inherited store(s);
  590. { writedefref(definition);
  591. current_ppu^.writeentry(ibpointerdef);}
  592. end;
  593. {****************************************************************************
  594. Tpointerdef
  595. ****************************************************************************}
  596. constructor Tpointerdef.initfar(Aowner:Pcontainingsymtable;def:Pdef);
  597. begin
  598. inherited init(Aowner,def);
  599. is_far:=true;
  600. end;
  601. constructor Tpointerdef.load(var s:Tstream);
  602. begin
  603. inherited load(s);
  604. { is_far:=(readbyte<>0);}
  605. end;
  606. function Tpointerdef.gettypename : string;
  607. begin
  608. gettypename:='^'+definition^.typename;
  609. end;
  610. procedure Tpointerdef.store(var s:Tstream);
  611. begin
  612. inherited store(s);
  613. { writebyte(byte(is_far));}
  614. end;
  615. {****************************************************************************
  616. Tclassrefdef
  617. ****************************************************************************}
  618. function Tclassrefdef.gettypename:string;
  619. begin
  620. gettypename:='Class of '+definition^.typename;
  621. end;
  622. {***************************************************************************
  623. TOBJECTDEF
  624. ***************************************************************************}
  625. constructor Tobjectdef.init(const n:string;Aowner:Pcontainingsymtable;
  626. parent:Pobjectdef);
  627. begin
  628. inherited init(Aowner);
  629. new(publicsyms,init);
  630. publicsyms^.name:=stringdup(n);
  631. publicsyms^.defowner:=@self;
  632. set_parent(parent);
  633. objname:=stringdup(n);
  634. end;
  635. procedure tobjectdef.set_parent(parent:Pobjectdef);
  636. const inherited_options=[oo_has_virtual,oo_has_private,oo_has_protected,
  637. oo_has_constructor,oo_has_destructor];
  638. begin
  639. {Nothing to do if the parent was not forward !}
  640. if childof=nil then
  641. begin
  642. childof:=parent;
  643. {Some options are inherited...}
  644. if parent<>nil then
  645. begin
  646. options:=options+parent^.options*inherited_options;
  647. {Add the data of the anchestor class.}
  648. inc(publicsyms^.datasize,parent^.publicsyms^.datasize);
  649. if parent^.privatesyms<>nil then
  650. begin
  651. if privatesyms=nil then
  652. new(privatesyms,init);
  653. inc(privatesyms^.datasize,
  654. parent^.privatesyms^.datasize);
  655. end;
  656. if parent^.protectedsyms<>nil then
  657. begin
  658. if protectedsyms<>nil then
  659. new(protectedsyms,init);
  660. inc(protectedsyms^.datasize,
  661. parent^.protectedsyms^.datasize);
  662. end;
  663. if oo_has_vmt in (options*parent^.options) then
  664. publicsyms^.datasize:=publicsyms^.datasize-
  665. target_os.size_of_pointer;
  666. {If parent has a vmt field then
  667. the offset is the same for the child PM }
  668. if [oo_has_vmt,oo_is_class]*parent^.options<>[] then
  669. begin
  670. vmt_offset:=parent^.vmt_offset;
  671. include(options,oo_has_vmt);
  672. end;
  673. end;
  674. savesize:=publicsyms^.datasize;
  675. end;
  676. end;
  677. constructor Tobjectdef.load(var s:Tstream);
  678. var oldread_member:boolean;
  679. begin
  680. inherited load(s);
  681. (* savesize:=readlong;
  682. vmt_offset:=readlong;
  683. objname:=stringdup(readstring);
  684. childof:=pobjectdef(readdefref);
  685. options:=readlong;
  686. oldread_member:=read_member;
  687. read_member:=true;
  688. publicsyms:=new(psymtable,loadas(objectsymtable));
  689. read_member:=oldread_member;
  690. publicsyms^.defowner:=@self;
  691. { publicsyms^.datasize:=savesize; }
  692. publicsyms^.name := stringdup(objname^);
  693. { handles the predefined class tobject }
  694. { the last TOBJECT which is loaded gets }
  695. { it ! }
  696. if (objname^='TOBJECT') and
  697. isclass and (childof=nil) then
  698. class_tobject:=@self;
  699. has_rtti:=true;*)
  700. end;
  701. procedure Tobjectdef.insertvmt;
  702. begin
  703. if oo_has_vmt in options then
  704. internalerror($990803)
  705. else
  706. begin
  707. {First round up to aktpakrecords.}
  708. publicsyms^.datasize:=align(publicsyms^.datasize,
  709. aktpackrecords);
  710. vmt_offset:=publicsyms^.datasize;
  711. publicsyms^.datasize:=publicsyms^.datasize+
  712. target_os.size_of_pointer;
  713. include(options,oo_has_vmt);
  714. end;
  715. end;
  716. procedure Tobjectdef.check_forwards;
  717. begin
  718. publicsyms^.check_forwards;
  719. if oo_isforward in options then
  720. begin
  721. { ok, in future, the forward can be resolved }
  722. message1(sym_e_class_forward_not_resolved,objname^);
  723. exclude(options,oo_isforward);
  724. end;
  725. end;
  726. { true, if self inherits from d (or if they are equal) }
  727. function Tobjectdef.isrelated(d:Pobjectdef):boolean;
  728. var hp:Pobjectdef;
  729. begin
  730. hp:=@self;
  731. isrelated:=false;
  732. while assigned(hp) do
  733. begin
  734. if hp=d then
  735. begin
  736. isrelated:=true;
  737. break;
  738. end;
  739. hp:=hp^.childof;
  740. end;
  741. end;
  742. function Tobjectdef.search(const s:string):Psym;
  743. begin
  744. search:=speedsearch(s,getspeedvalue(s));
  745. end;
  746. function Tobjectdef.speedsearch(const s:string;speedvalue:longint):Psym;
  747. var r:Psym;
  748. begin
  749. r:=publicsyms^.speedsearch(s,speedvalue);
  750. if (r=nil) and (privatesyms<>nil) then
  751. r:=privatesyms^.speedsearch(s,speedvalue);
  752. if (r=nil) and (protectedsyms<>nil) then
  753. r:=protectedsyms^.speedsearch(s,speedvalue);
  754. end;
  755. function Tobjectdef.size:longint;
  756. begin
  757. if oo_is_class in options then
  758. size:=target_os.size_of_pointer
  759. else
  760. size:=publicsyms^.datasize;
  761. end;
  762. procedure tobjectdef.deref;
  763. var oldrecsyms:Psymtable;
  764. begin
  765. { resolvedef(pdef(childof));
  766. oldrecsyms:=aktrecordsymtable;
  767. aktrecordsymtable:=publicsyms;
  768. publicsyms^.deref;
  769. aktrecordsymtable:=oldrecsyms;}
  770. end;
  771. function Tobjectdef.vmt_mangledname:string;
  772. begin
  773. if oo_has_vmt in options then
  774. message1(parser_object_has_no_vmt,objname^);
  775. vmt_mangledname:='VMT_'+owner^.name^+'$_'+objname^;
  776. end;
  777. function Tobjectdef.rtti_name:string;
  778. begin
  779. rtti_name:='RTTI_'+owner^.name^+'$_'+objname^;
  780. end;
  781. procedure Tobjectdef.store(var s:Tstream);
  782. var oldread_member:boolean;
  783. begin
  784. inherited store(s);
  785. (* writelong(size);
  786. writelong(vmt_offset);
  787. writestring(objname^);
  788. writedefref(childof);
  789. writelong(options);
  790. current_ppu^.writeentry(ibobjectdef);
  791. oldread_member:=read_member;
  792. read_member:=true;
  793. publicsyms^.writeas;
  794. read_member:=oldread_member;*)
  795. end;
  796. procedure tobjectdef.write_child_init_data;
  797. begin
  798. end;
  799. procedure Tobjectdef.write_init_data;
  800. var b:byte;
  801. begin
  802. if oo_is_class in options then
  803. b:=tkclass
  804. else
  805. b:=tkobject;
  806. rttilist^.concat(new(Pai_const,init_8bit(b)));
  807. { generate the name }
  808. rttilist^.concat(new(Pai_const,init_8bit(length(objname^))));
  809. rttilist^.concat(new(Pai_string,init(objname^)));
  810. (* rttilist^.concat(new(Pai_const,init_32bit(size)));
  811. publicsyms^.foreach({$ifndef TP}@{$endif}count_inittable_fields);
  812. rttilist^.concat(new(Pai_const,init_32bit(count)));
  813. publicsyms^.foreach({$ifndef TP}@{$endif}write_field_inittable);*)
  814. end;
  815. function Tobjectdef.needs_inittable:boolean;
  816. var oldb:boolean;
  817. begin
  818. { there are recursive calls to needs_inittable possible, }
  819. { so we have to change to old value how else should }
  820. { we do that ? check_rec_rtti can't be a nested }
  821. { procedure of needs_rtti ! }
  822. (* oldb:=binittable;
  823. binittable:=false;
  824. publicsyms^.foreach({$ifndef TP}@{$endif}check_rec_inittable);
  825. needs_inittable:=binittable;
  826. binittable:=oldb;*)
  827. end;
  828. destructor Tobjectdef.done;
  829. begin
  830. if publicsyms<>nil then
  831. dispose(publicsyms,done);
  832. if privatesyms<>nil then
  833. dispose(privatesyms,done);
  834. if protectedsyms<>nil then
  835. dispose(protectedsyms,done);
  836. if oo_isforward in options then
  837. message1(sym_e_class_forward_not_resolved,objname^);
  838. stringdispose(objname);
  839. inherited done;
  840. end;
  841. var count:longint;
  842. procedure count_published_properties(sym:Pnamedindexobject);
  843. {$ifndef fpc}far;{$endif}
  844. begin
  845. if (typeof(sym^)=typeof(Tpropertysym)) and
  846. (ppo_published in Ppropertysym(sym)^.properties) then
  847. inc(count);
  848. end;
  849. procedure write_property_info(sym:Pnamedindexobject);{$ifndef fpc}far;{$endif}
  850. var proctypesinfo : byte;
  851. procedure writeproc(sym:Psym;def:Pdef;shiftvalue:byte);
  852. var typvalue:byte;
  853. begin
  854. if not(assigned(sym)) then
  855. begin
  856. rttilist^.concat(new(pai_const,init_32bit(1)));
  857. typvalue:=3;
  858. end
  859. else if typeof(sym^)=typeof(Tvarsym) then
  860. begin
  861. rttilist^.concat(new(pai_const,init_32bit(
  862. Pvarsym(sym)^.address)));
  863. typvalue:=0;
  864. end
  865. else
  866. begin
  867. (* if (pprocdef(def)^.options and povirtualmethod)=0 then
  868. begin
  869. rttilist^.concat(new(pai_const_symbol,initname(pprocdef(def)^.mangledname)));
  870. typvalue:=1;
  871. end
  872. else
  873. begin
  874. {Virtual method, write vmt offset.}
  875. rttilist^.concat(new(pai_const,
  876. init_32bit(Pprocdef(def)^.extnumber*4+12)));
  877. typvalue:=2;
  878. end;*)
  879. end;
  880. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  881. end;
  882. begin
  883. if (typeof(sym^)=typeof(Tpropertysym)) and
  884. (ppo_indexed in Ppropertysym(sym)^.properties) then
  885. proctypesinfo:=$40
  886. else
  887. proctypesinfo:=0;
  888. if (typeof(sym^)=typeof(Tpropertysym)) and
  889. (ppo_published in Ppropertysym(sym)^.properties) then
  890. begin
  891. rttilist^.concat(new(pai_const_symbol,initname(
  892. Ppropertysym(sym)^.definition^.get_rtti_label)));
  893. writeproc(Ppropertysym(sym)^.readaccesssym,ppropertysym(sym)^.readaccessdef,0);
  894. writeproc(Ppropertysym(sym)^.writeaccesssym,ppropertysym(sym)^.writeaccessdef,2);
  895. { isn't it stored ? }
  896. if (ppo_stored in Ppropertysym(sym)^.properties) then
  897. begin
  898. rttilist^.concat(new(pai_const,init_32bit(1)));
  899. proctypesinfo:=proctypesinfo or (3 shl 4);
  900. end
  901. else
  902. writeproc(ppropertysym(sym)^.storedsym,ppropertysym(sym)^.storeddef,4);
  903. rttilist^.concat(new(pai_const,
  904. init_32bit(ppropertysym(sym)^.index)));
  905. rttilist^.concat(new(pai_const,
  906. init_32bit(ppropertysym(sym)^.default)));
  907. rttilist^.concat(new(pai_const,
  908. init_16bit(count)));
  909. inc(count);
  910. rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
  911. rttilist^.concat(new(pai_const,
  912. init_8bit(length(ppropertysym(sym)^.name))));
  913. rttilist^.concat(new(pai_string,init(ppropertysym(sym)^.name)));
  914. end;
  915. end;
  916. procedure generate_published_child_rtti(sym:Pnamedindexobject);
  917. {$ifndef fpc}far;{$endif}
  918. begin
  919. if (typeof(sym^)=typeof(Tpropertysym)) and
  920. (ppo_published in Ppropertysym(sym)^.properties) then
  921. Ppropertysym(sym)^.definition^.get_rtti_label;
  922. end;
  923. procedure tobjectdef.write_child_rtti_data;
  924. begin
  925. publicsyms^.foreach({$ifndef TP}@{$endif}generate_published_child_rtti);
  926. end;
  927. procedure Tobjectdef.generate_rtti;
  928. begin
  929. { getdatalabel(rtti_label);
  930. write_child_rtti_data;
  931. rttilist^.concat(new(pai_symbol,initname_global(rtti_name)));
  932. rttilist^.concat(new(pai_label,init(rtti_label)));
  933. write_rtti_data;}
  934. end;
  935. function Tobjectdef.next_free_name_index : longint;
  936. var i:longint;
  937. begin
  938. if (childof<>nil) and (oo_can_have_published in childof^.options) then
  939. i:=childof^.next_free_name_index
  940. else
  941. i:=0;
  942. count:=0;
  943. publicsyms^.foreach({$ifndef TP}@{$endif}count_published_properties);
  944. next_free_name_index:=i+count;
  945. end;
  946. procedure tobjectdef.write_rtti_data;
  947. begin
  948. if oo_is_class in options then
  949. rttilist^.concat(new(pai_const,init_8bit(tkclass)))
  950. else
  951. rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  952. {Generate the name }
  953. rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
  954. rttilist^.concat(new(pai_string,init(objname^)));
  955. {Write class type }
  956. rttilist^.concat(new(pai_const_symbol,initname(vmt_mangledname)));
  957. { write owner typeinfo }
  958. if (childof<>nil) and (oo_can_have_published in childof^.options) then
  959. rttilist^.concat(new(pai_const_symbol,
  960. initname(childof^.get_rtti_label)))
  961. else
  962. rttilist^.concat(new(pai_const,init_32bit(0)));
  963. {Count total number of properties }
  964. if (childof<>nil) and (oo_can_have_published in childof^.options) then
  965. count:=childof^.next_free_name_index
  966. else
  967. count:=0;
  968. {Write it>}
  969. publicsyms^.foreach({$ifndef TP}@{$endif}count_published_properties);
  970. rttilist^.concat(new(Pai_const,init_16bit(count)));
  971. { write unit name }
  972. if owner^.name<>nil then
  973. begin
  974. rttilist^.concat(new(Pai_const,init_8bit(length(owner^.name^))));
  975. rttilist^.concat(new(Pai_string,init(owner^.name^)));
  976. end
  977. else
  978. rttilist^.concat(new(Pai_const,init_8bit(0)));
  979. { write published properties count }
  980. count:=0;
  981. publicsyms^.foreach({$ifndef TP}@{$endif}count_published_properties);
  982. rttilist^.concat(new(pai_const,init_16bit(count)));
  983. { count is used to write nameindex }
  984. { but we need an offset of the owner }
  985. { to give each property an own slot }
  986. if (childof<>nil) and (oo_can_have_published in childof^.options) then
  987. count:=childof^.next_free_name_index
  988. else
  989. count:=0;
  990. publicsyms^.foreach({$ifndef TP}@{$endif}write_property_info);
  991. end;
  992. function Tobjectdef.is_publishable:boolean;
  993. begin
  994. is_publishable:=oo_is_class in options;
  995. end;
  996. function Tobjectdef.get_rtti_label:string;
  997. begin
  998. get_rtti_label:=rtti_name;
  999. end;
  1000. {***************************************************************************
  1001. TARRAYDEF
  1002. ***************************************************************************}
  1003. constructor Tarraydef.init(const l,h:Tconstant;rd:Pdef;
  1004. Aowner:Pcontainingsymtable);
  1005. begin
  1006. inherited init(Aowner);
  1007. lowrange:=l;
  1008. highrange:=h;
  1009. rangedef:=rd;
  1010. end;
  1011. constructor Tarraydef.load(var s:Tstream);
  1012. begin
  1013. inherited load(s);
  1014. (* deftype:=arraydef;
  1015. { the addresses are calculated later }
  1016. definition:=readdefref;
  1017. rangedef:=readdefref;
  1018. lowrange:=readlong;
  1019. highrange:=readlong;
  1020. IsArrayOfConst:=boolean(readbyte);*)
  1021. end;
  1022. function Tarraydef.getrangecheckstring:string;
  1023. begin
  1024. if (cs_smartlink in aktmoduleswitches) then
  1025. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  1026. else
  1027. getrangecheckstring:='R_'+tostr(rangenr);
  1028. end;
  1029. procedure Tarraydef.genrangecheck;
  1030. begin
  1031. if rangenr=0 then
  1032. begin
  1033. {Generates the data for range checking }
  1034. getlabelnr(rangenr);
  1035. if (cs_smartlink in aktmoduleswitches) then
  1036. datasegment^.concat(new(pai_symbol,
  1037. initname_global(getrangecheckstring)))
  1038. else
  1039. datasegment^.concat(new(pai_symbol,
  1040. initname(getrangecheckstring)));
  1041. datasegment^.concat(new(Pai_const,
  1042. init_8bit(byte(lowrange.signed))));
  1043. datasegment^.concat(new(Pai_const,
  1044. init_32bit(lowrange.values)));
  1045. datasegment^.concat(new(Pai_const,
  1046. init_8bit(byte(highrange.signed))));
  1047. datasegment^.concat(new(Pai_const,
  1048. init_32bit(highrange.values)));
  1049. end;
  1050. end;
  1051. procedure Tarraydef.deref;
  1052. begin
  1053. { resolvedef(definition);
  1054. resolvedef(rangedef);}
  1055. end;
  1056. procedure Tarraydef.store(var s:Tstream);
  1057. begin
  1058. inherited store(s);
  1059. (* writedefref(definition);
  1060. writedefref(rangedef);
  1061. writelong(lowrange);
  1062. writelong(highrange);
  1063. writebyte(byte(IsArrayOfConst));
  1064. current_ppu^.writeentry(ibarraydef);*)
  1065. end;
  1066. function Tarraydef.elesize:longint;
  1067. begin
  1068. elesize:=definition^.size;
  1069. end;
  1070. function Tarraydef.size:longint;
  1071. begin
  1072. if (lowrange.signed) and (lowrange.values=-1) then
  1073. internalerror($990804);
  1074. if highrange.signed then
  1075. begin
  1076. {Check for overflow.}
  1077. if (highrange.values-lowrange.values=$7fffffff) or
  1078. (($7fffffff div elesize+elesize-1)>
  1079. (highrange.values-lowrange.values)) then
  1080. begin
  1081. { message(sym_segment_too_large);}
  1082. size:=1;
  1083. end
  1084. else
  1085. size:=(highrange.values-lowrange.values+1)*elesize;
  1086. end
  1087. else
  1088. begin
  1089. {Check for overflow.}
  1090. if (highrange.valueu-lowrange.valueu=$7fffffff) or
  1091. (($7fffffff div elesize+elesize-1)>
  1092. (highrange.valueu-lowrange.valueu)) then
  1093. begin
  1094. { message(sym_segment_too_small);}
  1095. size:=1;
  1096. end
  1097. else
  1098. size:=(highrange.valueu-lowrange.valueu+1)*elesize;
  1099. end;
  1100. end;
  1101. function Tarraydef.needs_inittable:boolean;
  1102. begin
  1103. needs_inittable:=definition^.needs_inittable;
  1104. end;
  1105. procedure Tarraydef.write_child_rtti_data;
  1106. begin
  1107. definition^.get_rtti_label;
  1108. end;
  1109. procedure tarraydef.write_rtti_data;
  1110. begin
  1111. rttilist^.concat(new(Pai_const,init_8bit(13)));
  1112. write_rtti_name;
  1113. { size of elements }
  1114. rttilist^.concat(new(Pai_const,init_32bit(definition^.size)));
  1115. { count of elements }
  1116. rttilist^.concat(new(Pai_const,
  1117. init_32bit(highrange.values-lowrange.values+1)));
  1118. { element type }
  1119. rttilist^.concat(new(Pai_const_symbol,
  1120. initname(definition^.get_rtti_label)));
  1121. end;
  1122. function Tarraydef.gettypename:string;
  1123. var r:string;
  1124. begin
  1125. if [ap_arrayofconst,ap_constructor]*options<>[] then
  1126. gettypename:='array of const'
  1127. else if (lowrange.signed) and (lowrange.values=-1) then
  1128. gettypename:='Array Of '+definition^.typename
  1129. else
  1130. begin
  1131. r:='array[$1..$2 Of $3]';
  1132. if typeof(rangedef^)=typeof(Tenumdef) then
  1133. with Penumdef(rangedef)^.symbols^ do
  1134. begin
  1135. replace(r,'$1',Penumsym(at(0))^.name);
  1136. replace(r,'$2',Penumsym(at(count-1))^.name);
  1137. end
  1138. else
  1139. begin
  1140. if lowrange.signed then
  1141. replace(r,'$1',tostr(lowrange.values))
  1142. else
  1143. replace(r,'$1',tostru(lowrange.valueu));
  1144. if highrange.signed then
  1145. replace(r,'$2',tostr(highrange.values))
  1146. else
  1147. replace(r,'$2',tostr(highrange.valueu));
  1148. replace(r,'$3',definition^.typename);
  1149. end;
  1150. gettypename:=r;
  1151. end;
  1152. end;
  1153. {****************************************************************************
  1154. Tenumdef
  1155. ****************************************************************************}
  1156. constructor Tenumdef.init(Aowner:Pcontainingsymtable);
  1157. begin
  1158. inherited init(Aowner);
  1159. new(symbols,init(8,8));
  1160. calcsavesize;
  1161. end;
  1162. constructor Tenumdef.init_subrange(Abasedef:Penumdef;Amin,Amax:longint;
  1163. Aowner:Pcontainingsymtable);
  1164. begin
  1165. inherited init(Aowner);
  1166. minval:=Amin;
  1167. maxval:=Amax;
  1168. basedef:=Abasedef;
  1169. symbols:=Abasedef^.symbols;
  1170. calcsavesize;
  1171. end;
  1172. constructor Tenumdef.load(var s:Tstream);
  1173. begin
  1174. inherited load(s);
  1175. (* basedef:=penumdef(readdefref);
  1176. minval:=readlong;
  1177. maxval:=readlong;
  1178. savesize:=readlong;*)
  1179. end;
  1180. procedure Tenumdef.calcsavesize;
  1181. begin
  1182. if (aktpackenum=4) or (minval<0) or (maxval>65535) then
  1183. savesize:=4
  1184. else if (aktpackenum=2) or (minval<0) or (maxval>255) then
  1185. savesize:=2
  1186. else
  1187. savesize:=1;
  1188. end;
  1189. procedure Tenumdef.setmax(Amax:longint);
  1190. begin
  1191. maxval:=Amax;
  1192. calcsavesize;
  1193. end;
  1194. procedure Tenumdef.setmin(Amin:longint);
  1195. begin
  1196. minval:=Amin;
  1197. calcsavesize;
  1198. end;
  1199. procedure tenumdef.deref;
  1200. begin
  1201. { resolvedef(pdef(basedef));}
  1202. end;
  1203. procedure Tenumdef.store(var s:Tstream);
  1204. begin
  1205. inherited store(s);
  1206. (* writedefref(basedef);
  1207. writelong(min);
  1208. writelong(max);
  1209. writelong(savesize);
  1210. current_ppu^.writeentry(ibenumdef);*)
  1211. end;
  1212. function tenumdef.getrangecheckstring : string;
  1213. begin
  1214. if (cs_smartlink in aktmoduleswitches) then
  1215. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  1216. else
  1217. getrangecheckstring:='R_'+tostr(rangenr);
  1218. end;
  1219. procedure tenumdef.genrangecheck;
  1220. begin
  1221. if rangenr=0 then
  1222. begin
  1223. { generate two constant for bounds }
  1224. getlabelnr(rangenr);
  1225. if (cs_smartlink in aktmoduleswitches) then
  1226. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring)))
  1227. else
  1228. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring)));
  1229. datasegment^.concat(new(pai_const,init_32bit(minval)));
  1230. datasegment^.concat(new(pai_const,init_32bit(maxval)));
  1231. end;
  1232. end;
  1233. procedure Tenumdef.write_child_rtti_data;
  1234. begin
  1235. if assigned(basedef) then
  1236. basedef^.get_rtti_label;
  1237. end;
  1238. procedure Tenumdef.write_rtti_data;
  1239. var i:word;
  1240. begin
  1241. rttilist^.concat(new(pai_const,init_8bit(tkEnumeration)));
  1242. write_rtti_name;
  1243. case savesize of
  1244. 1:
  1245. rttilist^.concat(new(Pai_const,init_8bit(otUByte)));
  1246. 2:
  1247. rttilist^.concat(new(Pai_const,init_8bit(otUWord)));
  1248. 4:
  1249. rttilist^.concat(new(Pai_const,init_8bit(otULong)));
  1250. end;
  1251. rttilist^.concat(new(pai_const,init_32bit(minval)));
  1252. rttilist^.concat(new(pai_const,init_32bit(maxval)));
  1253. if assigned(basedef) then
  1254. rttilist^.concat(new(pai_const_symbol,initname(basedef^.get_rtti_label)))
  1255. else
  1256. rttilist^.concat(new(pai_const,init_32bit(0)));
  1257. for i:=0 to symbols^.count-1 do
  1258. begin
  1259. rttilist^.concat(new(Pai_const,
  1260. init_8bit(length(Penumsym(symbols^.at(i))^.name))));
  1261. rttilist^.concat(new(Pai_string,
  1262. init(globals.lower(Penumsym(symbols^.at(i))^.name))));
  1263. end;
  1264. rttilist^.concat(new(pai_const,init_8bit(0)));
  1265. end;
  1266. function Tenumdef.is_publishable:boolean;
  1267. begin
  1268. is_publishable:=true;
  1269. end;
  1270. function Tenumdef.gettypename:string;
  1271. var i:word;
  1272. v:longint;
  1273. r:string;
  1274. begin
  1275. r:='(';
  1276. for i:=0 to symbols^.count-1 do
  1277. begin
  1278. v:=Penumsym(symbols^.at(i))^.value;
  1279. if (v>=minval) and (v<=maxval) then
  1280. r:=r+Penumsym(symbols^.at(i))^.name+',';
  1281. end;
  1282. {Turn ',' into ')'.}
  1283. r[length(r)]:=')';
  1284. end;
  1285. {****************************************************************************
  1286. Torddef
  1287. ****************************************************************************}
  1288. constructor Torddef.init(t:Tbasetype;l,h:Tconstant;
  1289. Aowner:Pcontainingsymtable);
  1290. begin
  1291. inherited init(Aowner);
  1292. low:=l;
  1293. high:=h;
  1294. typ:=t;
  1295. setsize;
  1296. end;
  1297. constructor Torddef.load(var s:Tstream);
  1298. begin
  1299. inherited load(s);
  1300. (* typ:=tbasetype(readbyte);
  1301. low:=readlong;
  1302. high:=readlong;*)
  1303. setsize;
  1304. end;
  1305. procedure Torddef.setsize;
  1306. begin
  1307. if typ=uauto then
  1308. begin
  1309. {Generate a unsigned range if high<0 and low>=0 }
  1310. if (low.values>=0) and (high.values<=255) then
  1311. typ:=u8bit
  1312. else if (low.signed) and (low.values>=-128) and (high.values<=127) then
  1313. typ:=s8bit
  1314. else if (low.values>=0) and (high.values<=65536) then
  1315. typ:=u16bit
  1316. else if (low.signed) and (low.values>=-32768) and (high.values<=32767) then
  1317. typ:=s16bit
  1318. else if low.signed then
  1319. typ:=s32bit
  1320. else
  1321. typ:=u32bit
  1322. end;
  1323. case typ of
  1324. u8bit,s8bit,uchar,bool8bit:
  1325. savesize:=1;
  1326. u16bit,s16bit,bool16bit:
  1327. savesize:=2;
  1328. s32bit,u32bit,bool32bit:
  1329. savesize:=4;
  1330. u64bit,s64bitint:
  1331. savesize:=8;
  1332. else
  1333. savesize:=0;
  1334. end;
  1335. rangenr:=0;
  1336. end;
  1337. function Torddef.getrangecheckstring:string;
  1338. begin
  1339. if (cs_smartlink in aktmoduleswitches) then
  1340. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  1341. else
  1342. getrangecheckstring:='R_'+tostr(rangenr);
  1343. end;
  1344. procedure Torddef.genrangecheck;
  1345. begin
  1346. if rangenr=0 then
  1347. begin
  1348. {Generate two constant for bounds.}
  1349. getlabelnr(rangenr);
  1350. if (cs_smartlink in aktmoduleswitches) then
  1351. datasegment^.concat(new(Pai_symbol,
  1352. initname_global(getrangecheckstring)))
  1353. else
  1354. datasegment^.concat(new(Pai_symbol,
  1355. initname(getrangecheckstring)));
  1356. datasegment^.concat(new(Pai_const,init_8bit(byte(low.signed))));
  1357. datasegment^.concat(new(Pai_const,init_32bit(low.values)));
  1358. datasegment^.concat(new(Pai_const,init_8bit(byte(high.signed))));
  1359. datasegment^.concat(new(Pai_const,init_32bit(high.values)));
  1360. end;
  1361. end;
  1362. procedure Torddef.store(var s:Tstream);
  1363. begin
  1364. inherited store(s);
  1365. (* writebyte(byte(typ));
  1366. writelong(low);
  1367. writelong(high);
  1368. current_ppu^.writeentry(iborddef);*)
  1369. end;
  1370. procedure Torddef.write_rtti_data;
  1371. const trans:array[uchar..bool8bit] of byte=
  1372. (otubyte,otubyte,otuword,otulong,
  1373. otsbyte,otsword,otslong,otubyte);
  1374. begin
  1375. case typ of
  1376. bool8bit:
  1377. rttilist^.concat(new(Pai_const,init_8bit(tkbool)));
  1378. uchar:
  1379. rttilist^.concat(new(Pai_const,init_8bit(tkchar)));
  1380. else
  1381. rttilist^.concat(new(Pai_const,init_8bit(tkinteger)));
  1382. end;
  1383. write_rtti_name;
  1384. rttilist^.concat(new(Pai_const,init_8bit(byte(trans[typ]))));
  1385. rttilist^.concat(new(Pai_const,init_32bit(low.values)));
  1386. rttilist^.concat(new(Pai_const,init_32bit(high.values)));
  1387. end;
  1388. function Torddef.is_publishable:boolean;
  1389. begin
  1390. is_publishable:=typ in [uchar..bool8bit];
  1391. end;
  1392. function Torddef.gettypename:string;
  1393. const names:array[Tbasetype] of string[20]=('<unknown type>',
  1394. 'untyped','char','byte','word','dword','shortInt',
  1395. 'smallint','longInt','boolean','wordbool',
  1396. 'longbool','qword','int64');
  1397. begin
  1398. gettypename:=names[typ];
  1399. end;
  1400. {****************************************************************************
  1401. Tfloatdef
  1402. ****************************************************************************}
  1403. constructor Tfloatdef.init(t:Tfloattype;Aowner:Pcontainingsymtable);
  1404. begin
  1405. inherited init(Aowner);
  1406. typ:=t;
  1407. setsize;
  1408. end;
  1409. constructor Tfloatdef.load(var s:Tstream);
  1410. begin
  1411. inherited load(s);
  1412. (* typ:=Tfloattype(readbyte);*)
  1413. setsize;
  1414. end;
  1415. procedure tfloatdef.setsize;
  1416. begin
  1417. case typ of
  1418. f16bit:
  1419. savesize:=2;
  1420. f32bit,
  1421. s32real:
  1422. savesize:=4;
  1423. s64real:
  1424. savesize:=8;
  1425. s80real:
  1426. savesize:=extended_size;
  1427. s64comp:
  1428. savesize:=8;
  1429. else
  1430. savesize:=0;
  1431. end;
  1432. end;
  1433. procedure Tfloatdef.store(var s:Tstream);
  1434. begin
  1435. inherited store(s);
  1436. (* writebyte(byte(typ));
  1437. current_ppu^.writeentry(ibfloatdef);*)
  1438. end;
  1439. procedure Tfloatdef.write_rtti_data;
  1440. const translate:array[Tfloattype] of byte=
  1441. (ftsingle,ftdouble,ftextended,ftcomp,ftfixed16,ftfixed32);
  1442. begin
  1443. rttilist^.concat(new(Pai_const,init_8bit(tkfloat)));
  1444. write_rtti_name;
  1445. rttilist^.concat(new(Pai_const,init_8bit(translate[typ])));
  1446. end;
  1447. function Tfloatdef.is_publishable:boolean;
  1448. begin
  1449. is_publishable:=true;
  1450. end;
  1451. function Tfloatdef.gettypename:string;
  1452. const names:array[Tfloattype] of string[20]=(
  1453. 'single','double','extended','comp','fixed','shortfixed');
  1454. begin
  1455. gettypename:=names[typ];
  1456. end;
  1457. {***************************************************************************
  1458. Tsetdef
  1459. ***************************************************************************}
  1460. { For i386 smallsets work,
  1461. for m68k there are problems
  1462. can be test by compiling with -dusesmallset PM }
  1463. {$ifdef i386}
  1464. {$define usesmallset}
  1465. {$endif i386}
  1466. constructor Tsetdef.init(s:Pdef;high:longint;Aowner:Pcontainingsymtable);
  1467. begin
  1468. inherited init(Aowner);
  1469. setof:=s;
  1470. if high<32 then
  1471. begin
  1472. settype:=smallset;
  1473. savesize:=4;
  1474. end
  1475. else if high<256 then
  1476. begin
  1477. settype:=normset;
  1478. savesize:=32;
  1479. end
  1480. {$ifdef testvarsets}
  1481. else if high<$10000 then
  1482. begin
  1483. settype:=varset;
  1484. savesize:=4*((high+31) div 32);
  1485. end
  1486. {$endif testvarsets}
  1487. else
  1488. message(sym_e_ill_type_decl_set);
  1489. end;
  1490. constructor Tsetdef.load(var s:Tstream);
  1491. begin
  1492. inherited load(s);
  1493. (* setof:=readdefref;
  1494. settype:=tsettype(readbyte);
  1495. case settype of
  1496. normset:
  1497. savesize:=32;
  1498. varset:
  1499. savesize:=readlong;
  1500. smallset:
  1501. savesize:=sizeof(longint);
  1502. end;*)
  1503. end;
  1504. procedure Tsetdef.store(var s:Tstream);
  1505. begin
  1506. inherited store(s);
  1507. (* writedefref(setof);
  1508. writebyte(byte(settype));
  1509. if settype=varset then
  1510. writelong(savesize);
  1511. current_ppu^.writeentry(ibsetdef);*)
  1512. end;
  1513. procedure Tsetdef.deref;
  1514. begin
  1515. { resolvedef(setof);}
  1516. end;
  1517. procedure Tsetdef.write_rtti_data;
  1518. begin
  1519. rttilist^.concat(new(pai_const,init_8bit(tkset)));
  1520. write_rtti_name;
  1521. rttilist^.concat(new(pai_const,init_8bit(otuLong)));
  1522. rttilist^.concat(new(pai_const_symbol,initname(setof^.get_rtti_label)));
  1523. end;
  1524. procedure Tsetdef.write_child_rtti_data;
  1525. begin
  1526. setof^.get_rtti_label;
  1527. end;
  1528. function Tsetdef.is_publishable:boolean;
  1529. begin
  1530. is_publishable:=settype=smallset;
  1531. end;
  1532. function Tsetdef.gettypename:string;
  1533. begin
  1534. gettypename:='set of '+setof^.typename;
  1535. end;
  1536. {***************************************************************************
  1537. Trecorddef
  1538. ***************************************************************************}
  1539. constructor Trecorddef.init(s:Precordsymtable;Aowner:Pcontainingsymtable);
  1540. begin
  1541. inherited init(Aowner);
  1542. symtable:=s;
  1543. savesize:=symtable^.datasize;
  1544. end;
  1545. constructor Trecorddef.load(var s:Tstream);
  1546. var oldread_member:boolean;
  1547. begin
  1548. (* inherited load(s);
  1549. savesize:=readlong;
  1550. oldread_member:=read_member;
  1551. read_member:=true;
  1552. symtable:=new(psymtable,loadas(recordsymtable));
  1553. read_member:=oldread_member;
  1554. symtable^.defowner := @self;*)
  1555. end;
  1556. destructor Trecorddef.done;
  1557. begin
  1558. if symtable<>nil then
  1559. dispose(symtable,done);
  1560. inherited done;
  1561. end;
  1562. var
  1563. binittable : boolean;
  1564. procedure check_rec_inittable(s:Pnamedindexobject);
  1565. begin
  1566. if (typeof(s^)=typeof(Tvarsym)) and
  1567. ((typeof((Pvarsym(s)^.definition^))<>typeof(Tobjectdef)) or
  1568. not (oo_is_class in Pobjectdef(Pvarsym(s)^.definition)^.options)) then
  1569. binittable:=pvarsym(s)^.definition^.needs_inittable;
  1570. end;
  1571. function Trecorddef.needs_inittable:boolean;
  1572. var oldb:boolean;
  1573. begin
  1574. { there are recursive calls to needs_rtti possible, }
  1575. { so we have to change to old value how else should }
  1576. { we do that ? check_rec_rtti can't be a nested }
  1577. { procedure of needs_rtti ! }
  1578. oldb:=binittable;
  1579. binittable:=false;
  1580. symtable^.foreach({$ifndef TP}@{$endif}check_rec_inittable);
  1581. needs_inittable:=binittable;
  1582. binittable:=oldb;
  1583. end;
  1584. procedure Trecorddef.deref;
  1585. var oldrecsyms:Psymtable;
  1586. begin
  1587. (* oldrecsyms:=aktrecordsymtable;
  1588. aktrecordsymtable:=symtable;
  1589. { now dereference the definitions }
  1590. symtable^.deref;
  1591. aktrecordsymtable:=oldrecsyms;*)
  1592. end;
  1593. procedure Trecorddef.store(var s:Tstream);
  1594. var oldread_member:boolean;
  1595. begin
  1596. (* oldread_member:=read_member;
  1597. read_member:=true;
  1598. inherited store(s);
  1599. writelong(savesize);
  1600. current_ppu^.writeentry(ibrecorddef);
  1601. self.symtable^.writeas;
  1602. read_member:=oldread_member;*)
  1603. end;
  1604. procedure count_inittable_fields(sym:Pnamedindexobject);
  1605. {$ifndef fpc}far;{$endif}
  1606. begin
  1607. if (typeof(sym^)=typeof(Tvarsym)) and
  1608. (Pvarsym(sym)^.definition^.needs_inittable) then
  1609. inc(count);
  1610. end;
  1611. procedure count_fields(sym:Pnamedindexobject);{$ifndef fpc}far;{$endif}
  1612. begin
  1613. inc(count);
  1614. end;
  1615. procedure write_field_inittable(sym:Pnamedindexobject);
  1616. {$ifndef fpc}far;{$endif}
  1617. begin
  1618. if (typeof(sym^)=typeof(Tvarsym)) and
  1619. Pvarsym(sym)^.definition^.needs_inittable then
  1620. begin
  1621. rttilist^.concat(new(Pai_const_symbol,
  1622. init(pvarsym(sym)^.definition^.get_inittable_label)));
  1623. rttilist^.concat(new(Pai_const,
  1624. init_32bit(pvarsym(sym)^.address)));
  1625. end;
  1626. end;
  1627. procedure write_field_rtti(sym:Pnamedindexobject);{$ifndef fpc}far;{$endif}
  1628. begin
  1629. rttilist^.concat(new(Pai_const_symbol,
  1630. initname(Pvarsym(sym)^.definition^.get_rtti_label)));
  1631. rttilist^.concat(new(Pai_const,
  1632. init_32bit(Pvarsym(sym)^.address)));
  1633. end;
  1634. procedure generate_child_inittable(sym:Pnamedindexobject);
  1635. {$ifndef fpc}far;{$endif}
  1636. begin
  1637. if (typeof(sym^)=typeof(Tvarsym)) and
  1638. Pvarsym(sym)^.definition^.needs_inittable then
  1639. {Force inittable generation }
  1640. Pvarsym(sym)^.definition^.get_inittable_label;
  1641. end;
  1642. procedure generate_child_rtti(sym:Pnamedindexobject);
  1643. {$ifndef fpc}far;{$endif}
  1644. begin
  1645. Pvarsym(sym)^.definition^.get_rtti_label;
  1646. end;
  1647. procedure Trecorddef.write_child_rtti_data;
  1648. begin
  1649. symtable^.foreach({$ifndef TP}@{$endif}generate_child_rtti);
  1650. end;
  1651. procedure Trecorddef.write_child_init_data;
  1652. begin
  1653. symtable^.foreach({$ifndef TP}@{$endif}generate_child_inittable);
  1654. end;
  1655. procedure Trecorddef.write_rtti_data;
  1656. begin
  1657. rttilist^.concat(new(pai_const,init_8bit(tkrecord)));
  1658. write_rtti_name;
  1659. rttilist^.concat(new(pai_const,init_32bit(size)));
  1660. count:=0;
  1661. symtable^.foreach({$ifndef TP}@{$endif}count_fields);
  1662. rttilist^.concat(new(pai_const,init_32bit(count)));
  1663. symtable^.foreach({$ifndef TP}@{$endif}write_field_rtti);
  1664. end;
  1665. procedure Trecorddef.write_init_data;
  1666. begin
  1667. rttilist^.concat(new(pai_const,init_8bit(14)));
  1668. write_rtti_name;
  1669. rttilist^.concat(new(pai_const,init_32bit(size)));
  1670. count:=0;
  1671. symtable^.foreach({$ifndef TP}@{$endif}count_inittable_fields);
  1672. rttilist^.concat(new(pai_const,init_32bit(count)));
  1673. symtable^.foreach({$ifndef TP}@{$endif}write_field_inittable);
  1674. end;
  1675. function Trecorddef.gettypename:string;
  1676. begin
  1677. gettypename:='<record type>'
  1678. end;
  1679. {***************************************************************************
  1680. Tabstractprocdef
  1681. ***************************************************************************}
  1682. constructor Tabstractprocdef.init(Aowner:Pcontainingsymtable);
  1683. begin
  1684. inherited init(Aowner);
  1685. retdef:=voiddef;
  1686. savesize:=target_os.size_of_pointer;
  1687. end;
  1688. constructor Tabstractprocdef.load(var s:Tstream);
  1689. var count,i:word;
  1690. begin
  1691. inherited load(s);
  1692. (* retdef:=readdefref;
  1693. fpu_used:=readbyte;
  1694. options:=readlong;
  1695. count:=readword;
  1696. new(parameters);
  1697. savesize:=target_os.size_of_pointer;
  1698. for i:=1 to count do
  1699. parameters^.readsymref;*)
  1700. end;
  1701. { all functions returning in FPU are
  1702. assume to use 2 FPU registers
  1703. until the function implementation
  1704. is processed PM }
  1705. procedure Tabstractprocdef.test_if_fpu_result;
  1706. begin
  1707. if (retdef<>nil) and (typeof(retdef^)=typeof(Tfloatdef)) and
  1708. (Pfloatdef(retdef)^.typ in [f32bit,f16bit]) then
  1709. fpu_used:=2;
  1710. end;
  1711. procedure Tabstractprocdef.deref;
  1712. var i:longint;
  1713. begin
  1714. inherited deref;
  1715. { resolvedef(retdef);}
  1716. for i:=0 to parameters^.count-1 do
  1717. Psym(parameters^.at(i))^.deref;
  1718. end;
  1719. function Tabstractprocdef.para_size:longint;
  1720. var i,l:longint;
  1721. begin
  1722. l:=0;
  1723. for i:=0 to parameters^.count-1 do
  1724. inc(l,Pparamsym(parameters^.at(i))^.getpushsize);
  1725. para_size:=l;
  1726. end;
  1727. procedure Tabstractprocdef.store(var s:Tstream);
  1728. var count,i:word;
  1729. begin
  1730. inherited store(s);
  1731. { writedefref(retdef);
  1732. current_ppu^.do_interface_crc:=false;
  1733. writebyte(fpu_used);
  1734. writelong(options);
  1735. writeword(parameters^.count);
  1736. for i:=0 to parameters^.count-1 do
  1737. begin
  1738. writebyte(byte(hp^.paratyp));
  1739. writesymfref(hp^.data);
  1740. end;}
  1741. end;
  1742. function Tabstractprocdef.demangled_paras:string;
  1743. var i:longint;
  1744. s:string;
  1745. procedure doconcat(p:Pparameter);
  1746. begin
  1747. s:=s+p^.data^.name;
  1748. if p^.paratyp=vs_var then
  1749. s:=s+'var'
  1750. else if p^.paratyp=vs_const then
  1751. s:=s+'const';
  1752. end;
  1753. begin
  1754. s:='(';
  1755. for i:=0 to parameters^.count-1 do
  1756. doconcat(parameters^.at(i));
  1757. s[length(s)]:=')';
  1758. demangled_paras:=s;
  1759. end;
  1760. destructor Tabstractprocdef.done;
  1761. begin
  1762. dispose(parameters,done);
  1763. inherited done;
  1764. end;
  1765. {***************************************************************************
  1766. TPROCDEF
  1767. ***************************************************************************}
  1768. constructor Tprocdef.init(Aowner:Pcontainingsymtable);
  1769. begin
  1770. inherited init(Aowner);
  1771. fileinfo:=aktfilepos;
  1772. extnumber:=-1;
  1773. new(localst,init);
  1774. if (cs_browser in aktmoduleswitches) and make_ref then
  1775. begin
  1776. new(references,init(2*owner^.index_growsize,
  1777. owner^.index_growsize));
  1778. references^.insert(new(Pref,init(tokenpos)));
  1779. end;
  1780. {First, we assume that all registers are used }
  1781. usedregisters:=[low(Tregister)..high(Tregister)];
  1782. forwarddef:=true;
  1783. end;
  1784. constructor Tprocdef.load(var s:Tstream);
  1785. var a:string;
  1786. begin
  1787. inherited load(s);
  1788. (* usedregisters:=readlong;
  1789. a:=readstring;
  1790. setstring(_mangledname,s);
  1791. extnumber:=readlong;
  1792. nextoerloaded:=pprocdef(readdefref);
  1793. _class := pobjectdef(readdefref);
  1794. readposinfo(fileinfo);
  1795. if (cs_link_deffile in aktglobalswitches)
  1796. and (poexports in options) then
  1797. deffile.ddexport(mangledname);
  1798. count:=true;*)
  1799. end;
  1800. const local_symtable_index : longint = $8001;
  1801. procedure tprocdef.load_references;
  1802. var pos:Tfileposinfo;
  1803. pdo:Pobjectdef;
  1804. move_last:boolean;
  1805. begin
  1806. (* move_last:=lastwritten=lastref;
  1807. while (not current_ppu^.endofentry) do
  1808. begin
  1809. readposinfo(pos);
  1810. inc(refcount);
  1811. lastref:=new(pref,init(lastref,@pos));
  1812. lastref^.is_written:=true;
  1813. if refcount=1 then
  1814. defref:=lastref;
  1815. end;
  1816. if move_last then
  1817. lastwritten:=lastref;
  1818. if ((current_module^.flags and uf_local_browser)<>0)
  1819. and is_in_current then
  1820. begin
  1821. {$ifndef NOLOCALBROWSER}
  1822. pdo:=_class;
  1823. new(parast,loadas(parasymtable));
  1824. parast^.next:=owner;
  1825. parast^.load_browser;
  1826. new(localst,loadas(localsymtable));
  1827. localst^.next:=parast;
  1828. localst^.load_browser;
  1829. {$endif NOLOCALBROWSER}
  1830. end;*)
  1831. end;
  1832. function Tprocdef.write_references:boolean;
  1833. var ref:Pref;
  1834. pdo:Pobjectdef;
  1835. move_last:boolean;
  1836. begin
  1837. (* move_last:=lastwritten=lastref;
  1838. if move_last and (((current_module^.flags and uf_local_browser)=0)
  1839. or not is_in_current) then
  1840. exit;
  1841. {Write address of this symbol }
  1842. writedefref(@self);
  1843. {Write refs }
  1844. if assigned(lastwritten) then
  1845. ref:=lastwritten
  1846. else
  1847. ref:=defref;
  1848. while assigned(ref) do
  1849. begin
  1850. if ref^.moduleindex=current_module^.unit_index then
  1851. begin
  1852. writeposinfo(ref^.posinfo);
  1853. ref^.is_written:=true;
  1854. if move_last then
  1855. lastwritten:=ref;
  1856. end
  1857. else if not ref^.is_written then
  1858. move_last:=false
  1859. else if move_last then
  1860. lastwritten:=ref;
  1861. ref:=ref^.nextref;
  1862. end;
  1863. current_ppu^.writeentry(ibdefref);
  1864. write_references:=true;
  1865. if ((current_module^.flags and uf_local_browser)<>0)
  1866. and is_in_current then
  1867. begin
  1868. pdo:=_class;
  1869. if (owner^.symtabletype<>localsymtable) then
  1870. while assigned(pdo) do
  1871. begin
  1872. if pdo^.publicsyms<>aktrecordsymtable then
  1873. begin
  1874. pdo^.publicsyms^.unitid:=local_symtable_index;
  1875. inc(local_symtable_index);
  1876. end;
  1877. pdo:=pdo^.childof;
  1878. end;
  1879. {We need TESTLOCALBROWSER para and local symtables
  1880. PPU files are then easier to read PM.}
  1881. inc(local_symtable_index);
  1882. parast^.write_browser;
  1883. if not assigned(localst) then
  1884. localst:=new(psymtable,init);
  1885. localst^.writeas;
  1886. localst^.unitid:=local_symtable_index;
  1887. inc(local_symtable_index);
  1888. localst^.write_browser;
  1889. {Decrement for.}
  1890. local_symtable_index:=local_symtable_index-2;
  1891. pdo:=_class;
  1892. if (owner^.symtabletype<>localsymtable) then
  1893. while assigned(pdo) do
  1894. begin
  1895. if pdo^.publicsyms<>aktrecordsymtable then
  1896. dec(local_symtable_index);
  1897. pdo:=pdo^.childof;
  1898. end;
  1899. end;*)
  1900. end;
  1901. destructor Tprocdef.done;
  1902. begin
  1903. if references<>nil then
  1904. dispose(references,done);
  1905. if (localst<>nil) and (typeof(localst^)<>typeof(Timplsymtable)) then
  1906. dispose(localst,done);
  1907. { if (poinline in options) and (code,nil) then
  1908. disposetree(ptree(code));}
  1909. if _mangledname<>nil then
  1910. disposestr(_mangledname);
  1911. inherited done;
  1912. end;
  1913. procedure Tprocdef.store(var s:Tstream);
  1914. begin
  1915. (* inherited store(s);
  1916. current_ppu^.do_interface_crc:=false;
  1917. writelong(usedregisters);
  1918. writestring(mangledname);
  1919. current_ppu^.do_interface_crc:=true;
  1920. writelong(extnumber);
  1921. if (options and pooperator) = 0 then
  1922. writedefref(nextoverloaded)
  1923. else
  1924. begin
  1925. {Only write the overloads from the same unit }
  1926. if assigned(nextoverloaded) and
  1927. (nextoverloaded^.owner=owner) then
  1928. writedefref(nextoverloaded)
  1929. else
  1930. writedefref(nil);
  1931. end;
  1932. writedefref(_class);
  1933. writeposinfo(fileinfo);
  1934. if (poinline and options) then
  1935. begin
  1936. {We need to save
  1937. - the para and the local symtable
  1938. - the code ptree !! PM
  1939. writesymtable(parast);
  1940. writesymtable(localst);
  1941. writeptree(ptree(code));
  1942. }
  1943. end;
  1944. current_ppu^.writeentry(ibprocdef);*)
  1945. end;
  1946. procedure Tprocdef.deref;
  1947. begin
  1948. { inherited deref;
  1949. resolvedef(pdef(nextoverloaded));
  1950. resolvedef(pdef(_class));}
  1951. end;
  1952. function Tprocdef.mangledname:string;
  1953. var i:word;
  1954. a:byte;
  1955. s:Pprocsym;
  1956. r:string;
  1957. begin
  1958. if _mangledname<>nil then
  1959. mangledname:=_mangledname^
  1960. else
  1961. begin
  1962. {If the procedure is in a unit, we start with the unitname.}
  1963. if current_module^.is_unit then
  1964. r:='_'+current_module^.modulename^
  1965. else
  1966. r:='';
  1967. a:=length(r);
  1968. {If we are a method we add the name of the object we are
  1969. belonging to.}
  1970. if (Pprocsym(sym)^._class<>nil) then
  1971. r:=r+'_M'+Pprocsym(sym)^._class^.sym^.name+'_M';
  1972. {Then we add the names of the procedures we are defined in
  1973. (for the case we are a nested procedure).}
  1974. s:=Pprocsym(sym)^.sub_of;
  1975. while typeof(s^.owner^)=typeof(Tprocsymtable) do
  1976. begin
  1977. insert('_$'+s^.name,r,a);
  1978. s:=s^.sub_of;
  1979. end;
  1980. r:=r+'_'+sym^.name;
  1981. {Add the types of all parameters.}
  1982. for i:=0 to parameters^.count-1 do
  1983. begin
  1984. r:=r+'$'+Pparameter(parameters^.at(i))^.data^.name;
  1985. end;
  1986. end;
  1987. end;
  1988. procedure Tprocdef.setmangledname(const s:string);
  1989. begin
  1990. if _mangledname<>nil then
  1991. disposestr(_mangledname);
  1992. _mangledname:=stringdup(s);
  1993. if localst<>nil then
  1994. begin
  1995. stringdispose(localst^.name);
  1996. localst^.name:=stringdup('locals of '+s);
  1997. end;
  1998. end;
  1999. {***************************************************************************
  2000. Tprocvardef
  2001. ***************************************************************************}
  2002. function Tprocvardef.size:longint;
  2003. begin
  2004. if pomethodpointer in options then
  2005. size:=2*target_os.size_of_pointer
  2006. else
  2007. size:=target_os.size_of_pointer;
  2008. end;
  2009. {$ifdef GDB}
  2010. function tprocvardef.stabstring : pchar;
  2011. var
  2012. nss : pchar;
  2013. i : word;
  2014. param : pdefcoll;
  2015. begin
  2016. i := 0;
  2017. param := para1;
  2018. while assigned(param) do
  2019. begin
  2020. inc(i);
  2021. param := param^.next;
  2022. end;
  2023. getmem(nss,1024);
  2024. { it is not a function but a function pointer !! (PM) }
  2025. strpcopy(nss,'*f'+retdef^.numberstring{+','+tostr(i)}+';');
  2026. param := para1;
  2027. i := 0;
  2028. { this confuses gdb !!
  2029. we should use 'F' instead of 'f' but
  2030. as we use c++ language mode
  2031. it does not like that either
  2032. Please do not remove this part
  2033. might be used once
  2034. gdb for pascal is ready PM }
  2035. (* while assigned(param) do
  2036. begin
  2037. inc(i);
  2038. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  2039. {Here we have lost the parameter names !!}
  2040. pst := strpnew('p'+tostr(i)+':'+param^.data^.numberstring+','+vartyp+';');
  2041. strcat(nss,pst);
  2042. strdispose(pst);
  2043. param := param^.next;
  2044. end; *)
  2045. {strpcopy(strend(nss),';');}
  2046. stabstring := strnew(nss);
  2047. freemem(nss,1024);
  2048. end;
  2049. procedure tprocvardef.concatstabto(asmlist : paasmoutput);
  2050. begin
  2051. if ( not assigned(sym) or sym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2052. and not is_def_stab_written then
  2053. inherited concatstabto(asmlist);
  2054. is_def_stab_written:=true;
  2055. end;
  2056. {$endif GDB}
  2057. procedure Tprocvardef.write_rtti_data;
  2058. begin
  2059. {!!!!!!!}
  2060. end;
  2061. procedure Tprocvardef.write_child_rtti_data;
  2062. begin
  2063. {!!!!!!!!}
  2064. end;
  2065. function Tprocvardef.is_publishable:boolean;
  2066. begin
  2067. is_publishable:=pomethodpointer in options;
  2068. end;
  2069. function Tprocvardef.gettypename:string;
  2070. begin
  2071. gettypename:='<procedure variable type>'
  2072. end;
  2073. end.