symdef.inc 124 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl, Pierre Muller
  4. Symbol table implementation for the definitions
  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. {****************************************************************************
  19. TDEF (base class for definitions)
  20. ****************************************************************************}
  21. function tparalinkedlist.count:longint;
  22. begin
  23. { You must use tabstractprocdef.minparacount and .maxparacount instead }
  24. internalerror(432432978);
  25. count:=0;
  26. end;
  27. {****************************************************************************
  28. TDEF (base class for definitions)
  29. ****************************************************************************}
  30. constructor tdef.init;
  31. begin
  32. inherited init;
  33. deftype:=abstractdef;
  34. owner := nil;
  35. typesym := nil;
  36. savesize := 0;
  37. if registerdef then
  38. symtablestack^.registerdef(@self);
  39. has_rtti:=false;
  40. has_inittable:=false;
  41. {$ifdef GDB}
  42. is_def_stab_written := not_written;
  43. globalnb := 0;
  44. {$endif GDB}
  45. if assigned(lastglobaldef) then
  46. begin
  47. lastglobaldef^.nextglobal := @self;
  48. previousglobal:=lastglobaldef;
  49. end
  50. else
  51. begin
  52. firstglobaldef := @self;
  53. previousglobal := nil;
  54. end;
  55. lastglobaldef := @self;
  56. nextglobal := nil;
  57. end;
  58. {$ifdef MEMDEBUG}
  59. var
  60. manglenamesize : longint;
  61. {$endif}
  62. constructor tdef.load;
  63. begin
  64. inherited init;
  65. deftype:=abstractdef;
  66. owner := nil;
  67. has_rtti:=false;
  68. has_inittable:=false;
  69. {$ifdef GDB}
  70. is_def_stab_written := not_written;
  71. globalnb := 0;
  72. {$endif GDB}
  73. if assigned(lastglobaldef) then
  74. begin
  75. lastglobaldef^.nextglobal := @self;
  76. previousglobal:=lastglobaldef;
  77. end
  78. else
  79. begin
  80. firstglobaldef := @self;
  81. previousglobal:=nil;
  82. end;
  83. lastglobaldef := @self;
  84. nextglobal := nil;
  85. { load }
  86. indexnr:=readword;
  87. typesym:=ptypesym(readsymref);
  88. end;
  89. destructor tdef.done;
  90. begin
  91. { first element ? }
  92. if not(assigned(previousglobal)) then
  93. begin
  94. firstglobaldef := nextglobal;
  95. if assigned(firstglobaldef) then
  96. firstglobaldef^.previousglobal:=nil;
  97. end
  98. else
  99. begin
  100. { remove reference in the element before }
  101. previousglobal^.nextglobal:=nextglobal;
  102. end;
  103. { last element ? }
  104. if not(assigned(nextglobal)) then
  105. begin
  106. lastglobaldef := previousglobal;
  107. if assigned(lastglobaldef) then
  108. lastglobaldef^.nextglobal:=nil;
  109. end
  110. else
  111. nextglobal^.previousglobal:=previousglobal;
  112. previousglobal:=nil;
  113. nextglobal:=nil;
  114. {$ifdef SYNONYM}
  115. while assigned(typesym) do
  116. begin
  117. typesym^.restype.setdef(nil);
  118. typesym:=typesym^.synonym;
  119. end;
  120. {$endif}
  121. end;
  122. { used for enumdef because the symbols are
  123. inserted in the owner symtable }
  124. procedure tdef.correct_owner_symtable;
  125. var
  126. st : psymtable;
  127. begin
  128. if assigned(owner) and
  129. (owner^.symtabletype in [recordsymtable,objectsymtable]) then
  130. begin
  131. owner^.defindex^.deleteindex(@self);
  132. st:=owner;
  133. while (st^.symtabletype in [recordsymtable,objectsymtable]) do
  134. st:=st^.next;
  135. st^.registerdef(@self);
  136. end;
  137. end;
  138. function tdef.typename:string;
  139. begin
  140. if assigned(typesym) then
  141. typename:=Upper(typesym^.name)
  142. else
  143. typename:=gettypename;
  144. end;
  145. function tdef.gettypename : string;
  146. begin
  147. gettypename:='<unknown type>'
  148. end;
  149. function tdef.is_in_current : boolean;
  150. var
  151. p : psymtable;
  152. begin
  153. p:=owner;
  154. is_in_current:=false;
  155. while assigned(p) do
  156. begin
  157. if (p=current_module^.globalsymtable) or (p=current_module^.localsymtable)
  158. or (p^.symtabletype in [globalsymtable,staticsymtable]) then
  159. begin
  160. is_in_current:=true;
  161. exit;
  162. end
  163. else if p^.symtabletype in [localsymtable,parasymtable,objectsymtable] then
  164. begin
  165. if assigned(p^.defowner) then
  166. p:=pobjectdef(p^.defowner)^.owner
  167. else
  168. exit;
  169. end
  170. else
  171. exit;
  172. end;
  173. end;
  174. procedure tdef.write;
  175. begin
  176. writeword(indexnr);
  177. writesymref(typesym);
  178. {$ifdef GDB}
  179. if globalnb = 0 then
  180. begin
  181. if assigned(owner) then
  182. globalnb := owner^.getnewtypecount
  183. else
  184. begin
  185. globalnb := PGlobalTypeCount^;
  186. Inc(PGlobalTypeCount^);
  187. end;
  188. end;
  189. {$endif GDB}
  190. end;
  191. function tdef.size : longint;
  192. begin
  193. size:=savesize;
  194. end;
  195. function tdef.alignment : longint;
  196. begin
  197. { normal alignment by default }
  198. alignment:=0;
  199. end;
  200. {$ifdef GDB}
  201. procedure tdef.set_globalnb;
  202. begin
  203. globalnb :=PGlobalTypeCount^;
  204. inc(PglobalTypeCount^);
  205. end;
  206. function tdef.stabstring : pchar;
  207. begin
  208. stabstring := strpnew('t'+numberstring+';');
  209. end;
  210. function tdef.numberstring : string;
  211. var table : psymtable;
  212. begin
  213. {formal def have no type !}
  214. if deftype = formaldef then
  215. begin
  216. numberstring := voiddef^.numberstring;
  217. exit;
  218. end;
  219. if (not assigned(typesym)) or (not typesym^.isusedinstab) then
  220. begin
  221. {set even if debuglist is not defined}
  222. if assigned(typesym) then
  223. typesym^.isusedinstab := true;
  224. if assigned(debuglist) and (is_def_stab_written = not_written) then
  225. concatstabto(debuglist);
  226. end;
  227. if not (cs_gdb_dbx in aktglobalswitches) then
  228. begin
  229. if globalnb = 0 then
  230. set_globalnb;
  231. numberstring := tostr(globalnb);
  232. end
  233. else
  234. begin
  235. if globalnb = 0 then
  236. begin
  237. if assigned(owner) then
  238. globalnb := owner^.getnewtypecount
  239. else
  240. begin
  241. globalnb := PGlobalTypeCount^;
  242. Inc(PGlobalTypeCount^);
  243. end;
  244. end;
  245. if assigned(typesym) then
  246. begin
  247. table := typesym^.owner;
  248. if table^.unitid > 0 then
  249. numberstring := '('+tostr(table^.unitid)+','+tostr(typesym^.restype.def^.globalnb)+')'
  250. else
  251. numberstring := tostr(globalnb);
  252. exit;
  253. end;
  254. numberstring := tostr(globalnb);
  255. end;
  256. end;
  257. function tdef.allstabstring : pchar;
  258. var stabchar : string[2];
  259. ss,st : pchar;
  260. sname : string;
  261. sym_line_no : longint;
  262. begin
  263. ss := stabstring;
  264. getmem(st,strlen(ss)+512);
  265. stabchar := 't';
  266. if deftype in tagtypes then
  267. stabchar := 'Tt';
  268. if assigned(typesym) then
  269. begin
  270. sname := typesym^.name;
  271. sym_line_no:=typesym^.fileinfo.line;
  272. end
  273. else
  274. begin
  275. sname := ' ';
  276. sym_line_no:=0;
  277. end;
  278. strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
  279. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  280. allstabstring := strnew(st);
  281. freemem(st,strlen(ss)+512);
  282. strdispose(ss);
  283. end;
  284. procedure tdef.concatstabto(asmlist : paasmoutput);
  285. var stab_str : pchar;
  286. begin
  287. if ((typesym = nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  288. and (is_def_stab_written = not_written) then
  289. begin
  290. If cs_gdb_dbx in aktglobalswitches then
  291. begin
  292. { otherwise you get two of each def }
  293. If assigned(typesym) then
  294. begin
  295. if typesym^.typ=symconst.typesym then
  296. typesym^.isusedinstab:=true;
  297. if (typesym^.owner = nil) or
  298. ((typesym^.owner^.symtabletype = unitsymtable) and
  299. punitsymtable(typesym^.owner)^.dbx_count_ok) then
  300. begin
  301. {with DBX we get the definition from the other objects }
  302. is_def_stab_written := written;
  303. exit;
  304. end;
  305. end;
  306. end;
  307. { to avoid infinite loops }
  308. is_def_stab_written := being_written;
  309. stab_str := allstabstring;
  310. asmlist^.concat(new(pai_stabs,init(stab_str)));
  311. is_def_stab_written := written;
  312. end;
  313. end;
  314. {$endif GDB}
  315. procedure tdef.deref;
  316. begin
  317. resolvesym(psym(typesym));
  318. end;
  319. { rtti generation }
  320. procedure tdef.generate_rtti;
  321. begin
  322. if not has_rtti then
  323. begin
  324. has_rtti:=true;
  325. getdatalabel(rtti_label);
  326. write_child_rtti_data;
  327. rttilist^.concat(new(pai_symbol,init(rtti_label,0)));
  328. write_rtti_data;
  329. rttilist^.concat(new(pai_symbol_end,init(rtti_label)));
  330. end;
  331. end;
  332. function tdef.get_rtti_label : string;
  333. begin
  334. generate_rtti;
  335. get_rtti_label:=rtti_label^.name;
  336. end;
  337. { init table handling }
  338. function tdef.needs_inittable : boolean;
  339. begin
  340. needs_inittable:=false;
  341. end;
  342. procedure tdef.generate_inittable;
  343. begin
  344. has_inittable:=true;
  345. getdatalabel(inittable_label);
  346. write_child_init_data;
  347. rttilist^.concat(new(pai_label,init(inittable_label)));
  348. write_init_data;
  349. end;
  350. procedure tdef.write_init_data;
  351. begin
  352. write_rtti_data;
  353. end;
  354. procedure tdef.write_child_init_data;
  355. begin
  356. write_child_rtti_data;
  357. end;
  358. function tdef.get_inittable_label : pasmlabel;
  359. begin
  360. if not(has_inittable) then
  361. generate_inittable;
  362. get_inittable_label:=inittable_label;
  363. end;
  364. procedure tdef.write_rtti_name;
  365. var
  366. str : string;
  367. begin
  368. { name }
  369. if assigned(typesym) then
  370. begin
  371. str:=typesym^.name;
  372. rttilist^.concat(new(pai_string,init(chr(length(str))+str)));
  373. end
  374. else
  375. rttilist^.concat(new(pai_string,init(#0)))
  376. end;
  377. { returns true, if the definition can be published }
  378. function tdef.is_publishable : boolean;
  379. begin
  380. is_publishable:=false;
  381. end;
  382. procedure tdef.write_rtti_data;
  383. begin
  384. end;
  385. procedure tdef.write_child_rtti_data;
  386. begin
  387. end;
  388. function tdef.is_intregable : boolean;
  389. begin
  390. is_intregable:=false;
  391. case deftype of
  392. pointerdef,
  393. enumdef,
  394. procvardef :
  395. is_intregable:=true;
  396. orddef :
  397. case porddef(@self)^.typ of
  398. bool8bit,bool16bit,bool32bit,
  399. u8bit,u16bit,u32bit,
  400. s8bit,s16bit,s32bit:
  401. is_intregable:=true;
  402. end;
  403. setdef:
  404. is_intregable:=is_smallset(@self);
  405. end;
  406. end;
  407. function tdef.is_fpuregable : boolean;
  408. begin
  409. is_fpuregable:=(deftype=floatdef) and not(pfloatdef(@self)^.typ in [f32bit,f16bit]);
  410. end;
  411. {****************************************************************************
  412. TSTRINGDEF
  413. ****************************************************************************}
  414. constructor tstringdef.shortinit(l : byte);
  415. begin
  416. tdef.init;
  417. string_typ:=st_shortstring;
  418. deftype:=stringdef;
  419. len:=l;
  420. savesize:=len+1;
  421. end;
  422. constructor tstringdef.shortload;
  423. begin
  424. tdef.load;
  425. string_typ:=st_shortstring;
  426. deftype:=stringdef;
  427. len:=readbyte;
  428. savesize:=len+1;
  429. end;
  430. constructor tstringdef.longinit(l : longint);
  431. begin
  432. tdef.init;
  433. string_typ:=st_longstring;
  434. deftype:=stringdef;
  435. len:=l;
  436. savesize:=target_os.size_of_pointer;
  437. end;
  438. constructor tstringdef.longload;
  439. begin
  440. tdef.load;
  441. deftype:=stringdef;
  442. string_typ:=st_longstring;
  443. len:=readlong;
  444. savesize:=target_os.size_of_pointer;
  445. end;
  446. constructor tstringdef.ansiinit(l : longint);
  447. begin
  448. tdef.init;
  449. string_typ:=st_ansistring;
  450. deftype:=stringdef;
  451. len:=l;
  452. savesize:=target_os.size_of_pointer;
  453. end;
  454. constructor tstringdef.ansiload;
  455. begin
  456. tdef.load;
  457. deftype:=stringdef;
  458. string_typ:=st_ansistring;
  459. len:=readlong;
  460. savesize:=target_os.size_of_pointer;
  461. end;
  462. constructor tstringdef.wideinit(l : longint);
  463. begin
  464. tdef.init;
  465. string_typ:=st_widestring;
  466. deftype:=stringdef;
  467. len:=l;
  468. savesize:=target_os.size_of_pointer;
  469. end;
  470. constructor tstringdef.wideload;
  471. begin
  472. tdef.load;
  473. deftype:=stringdef;
  474. string_typ:=st_widestring;
  475. len:=readlong;
  476. savesize:=target_os.size_of_pointer;
  477. end;
  478. function tstringdef.stringtypname:string;
  479. const
  480. typname:array[tstringtype] of string[8]=('',
  481. 'SHORTSTR','LONGSTR','ANSISTR','WIDESTR'
  482. );
  483. begin
  484. stringtypname:=typname[string_typ];
  485. end;
  486. function tstringdef.size : longint;
  487. begin
  488. size:=savesize;
  489. end;
  490. procedure tstringdef.write;
  491. begin
  492. tdef.write;
  493. if string_typ=st_shortstring then
  494. writebyte(len)
  495. else
  496. writelong(len);
  497. case string_typ of
  498. st_shortstring : current_ppu^.writeentry(ibshortstringdef);
  499. st_longstring : current_ppu^.writeentry(iblongstringdef);
  500. st_ansistring : current_ppu^.writeentry(ibansistringdef);
  501. st_widestring : current_ppu^.writeentry(ibwidestringdef);
  502. end;
  503. end;
  504. {$ifdef GDB}
  505. function tstringdef.stabstring : pchar;
  506. var
  507. bytest,charst,longst : string;
  508. begin
  509. case string_typ of
  510. st_shortstring:
  511. begin
  512. charst := typeglobalnumber('char');
  513. { this is what I found in stabs.texinfo but
  514. gdb 4.12 for go32 doesn't understand that !! }
  515. {$IfDef GDBknowsstrings}
  516. stabstring := strpnew('n'+charst+';'+tostr(len));
  517. {$else}
  518. bytest := typeglobalnumber('byte');
  519. stabstring := strpnew('s'+tostr(len+1)+'length:'+bytest
  520. +',0,8;st:ar'+bytest
  521. +';1;'+tostr(len)+';'+charst+',8,'+tostr(len*8)+';;');
  522. {$EndIf}
  523. end;
  524. st_longstring:
  525. begin
  526. charst := typeglobalnumber('char');
  527. { this is what I found in stabs.texinfo but
  528. gdb 4.12 for go32 doesn't understand that !! }
  529. {$IfDef GDBknowsstrings}
  530. stabstring := strpnew('n'+charst+';'+tostr(len));
  531. {$else}
  532. bytest := typeglobalnumber('byte');
  533. longst := typeglobalnumber('longint');
  534. stabstring := strpnew('s'+tostr(len+5)+'length:'+longst
  535. +',0,32;dummy:'+bytest+',32,8;st:ar'+bytest
  536. +';1;'+tostr(len)+';'+charst+',40,'+tostr(len*8)+';;');
  537. {$EndIf}
  538. end;
  539. st_ansistring:
  540. begin
  541. { an ansi string looks like a pchar easy !! }
  542. stabstring:=strpnew('*'+typeglobalnumber('char'));
  543. end;
  544. st_widestring:
  545. begin
  546. { an ansi string looks like a pchar easy !! }
  547. stabstring:=strpnew('*'+typeglobalnumber('char'));
  548. end;
  549. end;
  550. end;
  551. procedure tstringdef.concatstabto(asmlist : paasmoutput);
  552. begin
  553. inherited concatstabto(asmlist);
  554. end;
  555. {$endif GDB}
  556. function tstringdef.needs_inittable : boolean;
  557. begin
  558. needs_inittable:=string_typ in [st_ansistring,st_widestring];
  559. end;
  560. function tstringdef.gettypename : string;
  561. const
  562. names : array[tstringtype] of string[20] = ('',
  563. 'ShortString','LongString','AnsiString','WideString');
  564. begin
  565. gettypename:=names[string_typ];
  566. end;
  567. procedure tstringdef.write_rtti_data;
  568. begin
  569. case string_typ of
  570. st_ansistring:
  571. begin
  572. rttilist^.concat(new(pai_const,init_8bit(tkAString)));
  573. write_rtti_name;
  574. end;
  575. st_widestring:
  576. begin
  577. rttilist^.concat(new(pai_const,init_8bit(tkWString)));
  578. write_rtti_name;
  579. end;
  580. st_longstring:
  581. begin
  582. rttilist^.concat(new(pai_const,init_8bit(tkLString)));
  583. write_rtti_name;
  584. end;
  585. st_shortstring:
  586. begin
  587. rttilist^.concat(new(pai_const,init_8bit(tkSString)));
  588. write_rtti_name;
  589. rttilist^.concat(new(pai_const,init_8bit(len)));
  590. end;
  591. end;
  592. end;
  593. function tstringdef.is_publishable : boolean;
  594. begin
  595. is_publishable:=true;
  596. end;
  597. {****************************************************************************
  598. TENUMDEF
  599. ****************************************************************************}
  600. constructor tenumdef.init;
  601. begin
  602. tdef.init;
  603. deftype:=enumdef;
  604. minval:=0;
  605. maxval:=0;
  606. calcsavesize;
  607. has_jumps:=false;
  608. basedef:=nil;
  609. rangenr:=0;
  610. firstenum:=nil;
  611. correct_owner_symtable;
  612. end;
  613. constructor tenumdef.init_subrange(_basedef:penumdef;_min,_max:longint);
  614. begin
  615. tdef.init;
  616. deftype:=enumdef;
  617. minval:=_min;
  618. maxval:=_max;
  619. basedef:=_basedef;
  620. calcsavesize;
  621. has_jumps:=false;
  622. rangenr:=0;
  623. firstenum:=basedef^.firstenum;
  624. while assigned(firstenum) and (penumsym(firstenum)^.value<>minval) do
  625. firstenum:=firstenum^.nextenum;
  626. correct_owner_symtable;
  627. end;
  628. constructor tenumdef.load;
  629. begin
  630. tdef.load;
  631. deftype:=enumdef;
  632. basedef:=penumdef(readdefref);
  633. minval:=readlong;
  634. maxval:=readlong;
  635. savesize:=readlong;
  636. has_jumps:=false;
  637. firstenum:=Nil;
  638. end;
  639. procedure tenumdef.calcsavesize;
  640. begin
  641. if (aktpackenum=4) or (min<0) or (max>65535) then
  642. savesize:=4
  643. else
  644. if (aktpackenum=2) or (min<0) or (max>255) then
  645. savesize:=2
  646. else
  647. savesize:=1;
  648. end;
  649. procedure tenumdef.setmax(_max:longint);
  650. begin
  651. maxval:=_max;
  652. calcsavesize;
  653. end;
  654. procedure tenumdef.setmin(_min:longint);
  655. begin
  656. minval:=_min;
  657. calcsavesize;
  658. end;
  659. function tenumdef.min:longint;
  660. begin
  661. min:=minval;
  662. end;
  663. function tenumdef.max:longint;
  664. begin
  665. max:=maxval;
  666. end;
  667. procedure tenumdef.deref;
  668. begin
  669. inherited deref;
  670. resolvedef(pdef(basedef));
  671. end;
  672. destructor tenumdef.done;
  673. begin
  674. inherited done;
  675. end;
  676. procedure tenumdef.write;
  677. begin
  678. tdef.write;
  679. writedefref(basedef);
  680. writelong(min);
  681. writelong(max);
  682. writelong(savesize);
  683. current_ppu^.writeentry(ibenumdef);
  684. end;
  685. function tenumdef.getrangecheckstring : string;
  686. begin
  687. if (cs_create_smart in aktmoduleswitches) then
  688. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  689. else
  690. getrangecheckstring:='R_'+tostr(rangenr);
  691. end;
  692. procedure tenumdef.genrangecheck;
  693. begin
  694. if rangenr=0 then
  695. begin
  696. { generate two constant for bounds }
  697. getlabelnr(rangenr);
  698. if (cs_create_smart in aktmoduleswitches) then
  699. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,8)))
  700. else
  701. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,8)));
  702. datasegment^.concat(new(pai_const,init_32bit(min)));
  703. datasegment^.concat(new(pai_const,init_32bit(max)));
  704. end;
  705. end;
  706. {$ifdef GDB}
  707. function tenumdef.stabstring : pchar;
  708. var st,st2 : pchar;
  709. p : penumsym;
  710. s : string;
  711. memsize : word;
  712. begin
  713. memsize := memsizeinc;
  714. getmem(st,memsize);
  715. strpcopy(st,'e');
  716. p := firstenum;
  717. while assigned(p) do
  718. begin
  719. s :=p^.name+':'+tostr(p^.value)+',';
  720. { place for the ending ';' also }
  721. if (strlen(st)+length(s)+1<memsize) then
  722. strpcopy(strend(st),s)
  723. else
  724. begin
  725. getmem(st2,memsize+memsizeinc);
  726. strcopy(st2,st);
  727. freemem(st,memsize);
  728. st := st2;
  729. memsize := memsize+memsizeinc;
  730. strpcopy(strend(st),s);
  731. end;
  732. p := p^.nextenum;
  733. end;
  734. strpcopy(strend(st),';');
  735. stabstring := strnew(st);
  736. freemem(st,memsize);
  737. end;
  738. {$endif GDB}
  739. procedure tenumdef.write_child_rtti_data;
  740. begin
  741. if assigned(basedef) then
  742. basedef^.get_rtti_label;
  743. end;
  744. procedure tenumdef.write_rtti_data;
  745. var
  746. hp : penumsym;
  747. begin
  748. rttilist^.concat(new(pai_const,init_8bit(tkEnumeration)));
  749. write_rtti_name;
  750. case savesize of
  751. 1:
  752. rttilist^.concat(new(pai_const,init_8bit(otUByte)));
  753. 2:
  754. rttilist^.concat(new(pai_const,init_8bit(otUWord)));
  755. 4:
  756. rttilist^.concat(new(pai_const,init_8bit(otULong)));
  757. end;
  758. rttilist^.concat(new(pai_const,init_32bit(min)));
  759. rttilist^.concat(new(pai_const,init_32bit(max)));
  760. if assigned(basedef) then
  761. rttilist^.concat(new(pai_const_symbol,initname(basedef^.get_rtti_label)))
  762. else
  763. rttilist^.concat(new(pai_const,init_32bit(0)));
  764. hp:=firstenum;
  765. while assigned(hp) do
  766. begin
  767. rttilist^.concat(new(pai_const,init_8bit(length(hp^.name))));
  768. rttilist^.concat(new(pai_string,init(globals.lower(hp^.name))));
  769. hp:=hp^.nextenum;
  770. end;
  771. rttilist^.concat(new(pai_const,init_8bit(0)));
  772. end;
  773. function tenumdef.is_publishable : boolean;
  774. begin
  775. is_publishable:=true;
  776. end;
  777. function tenumdef.gettypename : string;
  778. begin
  779. gettypename:='<enumeration type>';
  780. end;
  781. {****************************************************************************
  782. TORDDEF
  783. ****************************************************************************}
  784. constructor torddef.init(t : tbasetype;v,b : longint);
  785. begin
  786. inherited init;
  787. deftype:=orddef;
  788. low:=v;
  789. high:=b;
  790. typ:=t;
  791. rangenr:=0;
  792. setsize;
  793. end;
  794. constructor torddef.load;
  795. begin
  796. inherited load;
  797. deftype:=orddef;
  798. typ:=tbasetype(readbyte);
  799. low:=readlong;
  800. high:=readlong;
  801. rangenr:=0;
  802. setsize;
  803. end;
  804. procedure torddef.setsize;
  805. begin
  806. if typ=uauto then
  807. begin
  808. { generate a unsigned range if high<0 and low>=0 }
  809. if (low>=0) and (high<0) then
  810. begin
  811. savesize:=4;
  812. typ:=u32bit;
  813. end
  814. else if (low>=0) and (high<=255) then
  815. begin
  816. savesize:=1;
  817. typ:=u8bit;
  818. end
  819. else if (low>=-128) and (high<=127) then
  820. begin
  821. savesize:=1;
  822. typ:=s8bit;
  823. end
  824. else if (low>=0) and (high<=65536) then
  825. begin
  826. savesize:=2;
  827. typ:=u16bit;
  828. end
  829. else if (low>=-32768) and (high<=32767) then
  830. begin
  831. savesize:=2;
  832. typ:=s16bit;
  833. end
  834. else
  835. begin
  836. savesize:=4;
  837. typ:=s32bit;
  838. end;
  839. end
  840. else
  841. begin
  842. case typ of
  843. u8bit,s8bit,
  844. uchar,bool8bit:
  845. savesize:=1;
  846. u16bit,s16bit,
  847. bool16bit,uwidechar:
  848. savesize:=2;
  849. s32bit,u32bit,
  850. bool32bit:
  851. savesize:=4;
  852. u64bit,s64bit:
  853. savesize:=8;
  854. else
  855. savesize:=0;
  856. end;
  857. end;
  858. { there are no entrys for range checking }
  859. rangenr:=0;
  860. end;
  861. function torddef.getrangecheckstring : string;
  862. begin
  863. if (cs_create_smart in aktmoduleswitches) then
  864. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  865. else
  866. getrangecheckstring:='R_'+tostr(rangenr);
  867. end;
  868. procedure torddef.genrangecheck;
  869. var
  870. rangechecksize : longint;
  871. begin
  872. if rangenr=0 then
  873. begin
  874. if low<=high then
  875. rangechecksize:=8
  876. else
  877. rangechecksize:=16;
  878. { generate two constant for bounds }
  879. getlabelnr(rangenr);
  880. if (cs_create_smart in aktmoduleswitches) then
  881. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,rangechecksize)))
  882. else
  883. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,rangechecksize)));
  884. if low<=high then
  885. begin
  886. datasegment^.concat(new(pai_const,init_32bit(low)));
  887. datasegment^.concat(new(pai_const,init_32bit(high)));
  888. end
  889. { for u32bit we need two bounds }
  890. else
  891. begin
  892. datasegment^.concat(new(pai_const,init_32bit(low)));
  893. datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
  894. datasegment^.concat(new(pai_const,init_32bit($80000000)));
  895. datasegment^.concat(new(pai_const,init_32bit(high)));
  896. end;
  897. end;
  898. end;
  899. procedure torddef.write;
  900. begin
  901. tdef.write;
  902. writebyte(byte(typ));
  903. writelong(low);
  904. writelong(high);
  905. current_ppu^.writeentry(iborddef);
  906. end;
  907. {$ifdef GDB}
  908. function torddef.stabstring : pchar;
  909. begin
  910. case typ of
  911. uvoid : stabstring := strpnew(numberstring+';');
  912. {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
  913. {$ifdef Use_integer_types_for_boolean}
  914. bool8bit,
  915. bool16bit,
  916. bool32bit : stabstring := strpnew('r'+numberstring+';0;255;');
  917. {$else : not Use_integer_types_for_boolean}
  918. bool8bit : stabstring := strpnew('-21;');
  919. bool16bit : stabstring := strpnew('-22;');
  920. bool32bit : stabstring := strpnew('-23;');
  921. u64bit : stabstring := strpnew('-32;');
  922. s64bit : stabstring := strpnew('-31;');
  923. {$endif not Use_integer_types_for_boolean}
  924. { u32bit : stabstring := strpnew('r'+
  925. s32bitdef^.numberstring+';0;-1;'); }
  926. else
  927. stabstring := strpnew('r'+s32bitdef^.numberstring+';'+tostr(low)+';'+tostr(high)+';');
  928. end;
  929. end;
  930. {$endif GDB}
  931. procedure torddef.write_rtti_data;
  932. procedure dointeger;
  933. const
  934. trans : array[uchar..bool8bit] of byte =
  935. (otUByte,otUByte,otUWord,otULong,otSByte,otSWord,otSLong,otUByte);
  936. begin
  937. write_rtti_name;
  938. rttilist^.concat(new(pai_const,init_8bit(byte(trans[typ]))));
  939. rttilist^.concat(new(pai_const,init_32bit(low)));
  940. rttilist^.concat(new(pai_const,init_32bit(high)));
  941. end;
  942. begin
  943. case typ of
  944. s64bit :
  945. begin
  946. rttilist^.concat(new(pai_const,init_8bit(tkInt64)));
  947. write_rtti_name;
  948. { low }
  949. rttilist^.concat(new(pai_const,init_32bit($0)));
  950. rttilist^.concat(new(pai_const,init_32bit($8000)));
  951. { high }
  952. rttilist^.concat(new(pai_const,init_32bit($ffff)));
  953. rttilist^.concat(new(pai_const,init_32bit($7fff)));
  954. end;
  955. u64bit :
  956. begin
  957. rttilist^.concat(new(pai_const,init_8bit(tkQWord)));
  958. write_rtti_name;
  959. { low }
  960. rttilist^.concat(new(pai_const,init_32bit($0)));
  961. rttilist^.concat(new(pai_const,init_32bit($0)));
  962. { high }
  963. rttilist^.concat(new(pai_const,init_32bit($0)));
  964. rttilist^.concat(new(pai_const,init_32bit($8000)));
  965. end;
  966. bool8bit:
  967. begin
  968. rttilist^.concat(new(pai_const,init_8bit(tkBool)));
  969. dointeger;
  970. end;
  971. uchar:
  972. begin
  973. rttilist^.concat(new(pai_const,init_8bit(tkWChar)));
  974. dointeger;
  975. end;
  976. uwidechar:
  977. begin
  978. rttilist^.concat(new(pai_const,init_8bit(tkChar)));
  979. dointeger;
  980. end;
  981. else
  982. begin
  983. rttilist^.concat(new(pai_const,init_8bit(tkInteger)));
  984. dointeger;
  985. end;
  986. end;
  987. end;
  988. function torddef.is_publishable : boolean;
  989. begin
  990. is_publishable:=typ in [uchar..bool8bit];
  991. end;
  992. function torddef.gettypename : string;
  993. const
  994. names : array[tbasetype] of string[20] = ('<unknown type>',
  995. 'untyped','Char','Byte','Word','DWord','ShortInt',
  996. 'SmallInt','LongInt','Boolean','WordBool',
  997. 'LongBool','QWord','Int64','WideChar');
  998. begin
  999. gettypename:=names[typ];
  1000. end;
  1001. {****************************************************************************
  1002. TFLOATDEF
  1003. ****************************************************************************}
  1004. constructor tfloatdef.init(t : tfloattype);
  1005. begin
  1006. inherited init;
  1007. deftype:=floatdef;
  1008. typ:=t;
  1009. setsize;
  1010. end;
  1011. constructor tfloatdef.load;
  1012. begin
  1013. inherited load;
  1014. deftype:=floatdef;
  1015. typ:=tfloattype(readbyte);
  1016. setsize;
  1017. end;
  1018. procedure tfloatdef.setsize;
  1019. begin
  1020. case typ of
  1021. f16bit : savesize:=2;
  1022. f32bit,
  1023. s32real : savesize:=4;
  1024. s64real : savesize:=8;
  1025. s80real : savesize:=extended_size;
  1026. s64comp : savesize:=8;
  1027. else
  1028. savesize:=0;
  1029. end;
  1030. end;
  1031. procedure tfloatdef.write;
  1032. begin
  1033. inherited write;
  1034. writebyte(byte(typ));
  1035. current_ppu^.writeentry(ibfloatdef);
  1036. end;
  1037. {$ifdef GDB}
  1038. function tfloatdef.stabstring : pchar;
  1039. begin
  1040. case typ of
  1041. s32real,
  1042. s64real : stabstring := strpnew('r'+
  1043. s32bitdef^.numberstring+';'+tostr(savesize)+';0;');
  1044. { for fixed real use longint instead to be able to }
  1045. { debug something at least }
  1046. f32bit:
  1047. stabstring := s32bitdef^.stabstring;
  1048. f16bit:
  1049. stabstring := strpnew('r'+s32bitdef^.numberstring+';0;'+
  1050. tostr($ffff)+';');
  1051. { found this solution in stabsread.c from GDB v4.16 }
  1052. s64comp : stabstring := strpnew('r'+
  1053. s32bitdef^.numberstring+';-'+tostr(savesize)+';0;');
  1054. {$ifdef i386}
  1055. { under dos at least you must give a size of twelve instead of 10 !! }
  1056. { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
  1057. s80real : stabstring := strpnew('r'+s32bitdef^.numberstring+';12;0;');
  1058. {$endif i386}
  1059. else
  1060. internalerror(10005);
  1061. end;
  1062. end;
  1063. {$endif GDB}
  1064. procedure tfloatdef.write_rtti_data;
  1065. const
  1066. {tfloattype = (s32real,s64real,s80real,s64bit,f16bit,f32bit);}
  1067. translate : array[tfloattype] of byte =
  1068. (ftSingle,ftDouble,ftExtended,ftComp,ftFixed16,ftFixed32);
  1069. begin
  1070. rttilist^.concat(new(pai_const,init_8bit(tkFloat)));
  1071. write_rtti_name;
  1072. rttilist^.concat(new(pai_const,init_8bit(translate[typ])));
  1073. end;
  1074. function tfloatdef.is_publishable : boolean;
  1075. begin
  1076. is_publishable:=true;
  1077. end;
  1078. function tfloatdef.gettypename : string;
  1079. const
  1080. names : array[tfloattype] of string[20] = (
  1081. 'Single','Double','Extended','Comp','Fixed','Fixed16');
  1082. begin
  1083. gettypename:=names[typ];
  1084. end;
  1085. {****************************************************************************
  1086. TFILEDEF
  1087. ****************************************************************************}
  1088. constructor tfiledef.inittext;
  1089. begin
  1090. inherited init;
  1091. deftype:=filedef;
  1092. filetyp:=ft_text;
  1093. typedfiletype.reset;
  1094. setsize;
  1095. end;
  1096. constructor tfiledef.inituntyped;
  1097. begin
  1098. inherited init;
  1099. deftype:=filedef;
  1100. filetyp:=ft_untyped;
  1101. typedfiletype.reset;
  1102. setsize;
  1103. end;
  1104. constructor tfiledef.inittyped(const tt : ttype);
  1105. begin
  1106. inherited init;
  1107. deftype:=filedef;
  1108. filetyp:=ft_typed;
  1109. typedfiletype:=tt;
  1110. setsize;
  1111. end;
  1112. constructor tfiledef.inittypeddef(p : pdef);
  1113. begin
  1114. inherited init;
  1115. deftype:=filedef;
  1116. filetyp:=ft_typed;
  1117. typedfiletype.setdef(p);
  1118. setsize;
  1119. end;
  1120. constructor tfiledef.load;
  1121. begin
  1122. inherited load;
  1123. deftype:=filedef;
  1124. filetyp:=tfiletyp(readbyte);
  1125. if filetyp=ft_typed then
  1126. typedfiletype.load
  1127. else
  1128. typedfiletype.reset;
  1129. setsize;
  1130. end;
  1131. procedure tfiledef.deref;
  1132. begin
  1133. inherited deref;
  1134. if filetyp=ft_typed then
  1135. typedfiletype.resolve;
  1136. end;
  1137. procedure tfiledef.setsize;
  1138. begin
  1139. case filetyp of
  1140. ft_text :
  1141. savesize:=572;
  1142. ft_typed,
  1143. ft_untyped :
  1144. savesize:=316;
  1145. end;
  1146. end;
  1147. procedure tfiledef.write;
  1148. begin
  1149. inherited write;
  1150. writebyte(byte(filetyp));
  1151. if filetyp=ft_typed then
  1152. typedfiletype.write;
  1153. current_ppu^.writeentry(ibfiledef);
  1154. end;
  1155. {$ifdef GDB}
  1156. function tfiledef.stabstring : pchar;
  1157. begin
  1158. {$IfDef GDBknowsfiles}
  1159. case filetyp of
  1160. ft_typed :
  1161. stabstring := strpnew('d'+typedfiletype.def^.numberstring{+';'});
  1162. ft_untyped :
  1163. stabstring := strpnew('d'+voiddef^.numberstring{+';'});
  1164. ft_text :
  1165. stabstring := strpnew('d'+cchardef^.numberstring{+';'});
  1166. end;
  1167. {$Else}
  1168. {based on
  1169. FileRec = Packed Record
  1170. Handle,
  1171. Mode,
  1172. RecSize : longint;
  1173. _private : array[1..32] of byte;
  1174. UserData : array[1..16] of byte;
  1175. name : array[0..255] of char;
  1176. End; }
  1177. { the buffer part is still missing !! (PM) }
  1178. { but the string could become too long !! }
  1179. stabstring := strpnew('s'+tostr(savesize)+
  1180. 'HANDLE:'+typeglobalnumber('longint')+',0,32;'+
  1181. 'MODE:'+typeglobalnumber('longint')+',32,32;'+
  1182. 'RECSIZE:'+typeglobalnumber('longint')+',64,32;'+
  1183. '_PRIVATE:ar'+typeglobalnumber('word')+';1;32;'+typeglobalnumber('byte')
  1184. +',96,256;'+
  1185. 'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')
  1186. +',352,128;'+
  1187. 'NAME:ar'+typeglobalnumber('word')+';0;255;'+typeglobalnumber('char')
  1188. +',480,2048;;');
  1189. {$EndIf}
  1190. end;
  1191. procedure tfiledef.concatstabto(asmlist : paasmoutput);
  1192. begin
  1193. { most file defs are unnamed !!! }
  1194. if ((typesym = nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1195. (is_def_stab_written = not_written) then
  1196. begin
  1197. if assigned(typedfiletype.def) then forcestabto(asmlist,typedfiletype.def);
  1198. inherited concatstabto(asmlist);
  1199. end;
  1200. end;
  1201. {$endif GDB}
  1202. function tfiledef.gettypename : string;
  1203. begin
  1204. case filetyp of
  1205. ft_untyped:
  1206. gettypename:='File';
  1207. ft_typed:
  1208. gettypename:='File Of '+typedfiletype.def^.typename;
  1209. ft_text:
  1210. gettypename:='Text'
  1211. end;
  1212. end;
  1213. {****************************************************************************
  1214. TPOINTERDEF
  1215. ****************************************************************************}
  1216. constructor tpointerdef.init(const tt : ttype);
  1217. begin
  1218. tdef.init;
  1219. deftype:=pointerdef;
  1220. pointertype:=tt;
  1221. is_far:=false;
  1222. savesize:=target_os.size_of_pointer;
  1223. end;
  1224. constructor tpointerdef.initfar(const tt : ttype);
  1225. begin
  1226. tdef.init;
  1227. deftype:=pointerdef;
  1228. pointertype:=tt;
  1229. is_far:=true;
  1230. savesize:=target_os.size_of_pointer;
  1231. end;
  1232. constructor tpointerdef.initdef(p : pdef);
  1233. var
  1234. t : ttype;
  1235. begin
  1236. t.setdef(p);
  1237. tpointerdef.init(t);
  1238. end;
  1239. constructor tpointerdef.initfardef(p : pdef);
  1240. var
  1241. t : ttype;
  1242. begin
  1243. t.setdef(p);
  1244. tpointerdef.initfar(t);
  1245. end;
  1246. constructor tpointerdef.load;
  1247. begin
  1248. tdef.load;
  1249. deftype:=pointerdef;
  1250. pointertype.load;
  1251. is_far:=(readbyte<>0);
  1252. savesize:=target_os.size_of_pointer;
  1253. end;
  1254. destructor tpointerdef.done;
  1255. begin
  1256. if assigned(pointertype.def) and
  1257. (pointertype.def^.deftype=forwarddef) then
  1258. begin
  1259. dispose(pointertype.def,done);
  1260. pointertype.reset;
  1261. end;
  1262. inherited done;
  1263. end;
  1264. procedure tpointerdef.deref;
  1265. begin
  1266. inherited deref;
  1267. pointertype.resolve;
  1268. end;
  1269. procedure tpointerdef.write;
  1270. begin
  1271. inherited write;
  1272. pointertype.write;
  1273. writebyte(byte(is_far));
  1274. current_ppu^.writeentry(ibpointerdef);
  1275. end;
  1276. {$ifdef GDB}
  1277. function tpointerdef.stabstring : pchar;
  1278. begin
  1279. stabstring := strpnew('*'+pointertype.def^.numberstring);
  1280. end;
  1281. procedure tpointerdef.concatstabto(asmlist : paasmoutput);
  1282. var st,nb : string;
  1283. sym_line_no : longint;
  1284. begin
  1285. if assigned(pointertype.def) and
  1286. (pointertype.def^.deftype=forwarddef) then
  1287. exit;
  1288. if ( (typesym=nil) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1289. (is_def_stab_written = not_written) then
  1290. begin
  1291. is_def_stab_written := being_written;
  1292. if assigned(pointertype.def) and
  1293. (pointertype.def^.deftype in [recorddef,objectdef]) then
  1294. begin
  1295. nb:=pointertype.def^.numberstring;
  1296. {to avoid infinite recursion in record with next-like fields }
  1297. if pointertype.def^.is_def_stab_written = being_written then
  1298. begin
  1299. if assigned(pointertype.def^.typesym) then
  1300. begin
  1301. if assigned(typesym) then
  1302. begin
  1303. st := typesym^.name;
  1304. sym_line_no:=typesym^.fileinfo.line;
  1305. end
  1306. else
  1307. begin
  1308. st := ' ';
  1309. sym_line_no:=0;
  1310. end;
  1311. st := '"'+st+':t'+numberstring+'=*'+nb
  1312. +'=xs'+pointertype.def^.typesym^.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
  1313. asmlist^.concat(new(pai_stabs,init(strpnew(st))));
  1314. end;
  1315. end
  1316. else
  1317. begin
  1318. is_def_stab_written := not_written;
  1319. inherited concatstabto(asmlist);
  1320. end;
  1321. is_def_stab_written := written;
  1322. end
  1323. else
  1324. begin
  1325. if assigned(pointertype.def) then
  1326. forcestabto(asmlist,pointertype.def);
  1327. is_def_stab_written := not_written;
  1328. inherited concatstabto(asmlist);
  1329. end;
  1330. end;
  1331. end;
  1332. {$endif GDB}
  1333. function tpointerdef.gettypename : string;
  1334. begin
  1335. gettypename:='^'+pointertype.def^.typename;
  1336. end;
  1337. {****************************************************************************
  1338. TCLASSREFDEF
  1339. ****************************************************************************}
  1340. constructor tclassrefdef.init(def : pdef);
  1341. begin
  1342. inherited initdef(def);
  1343. deftype:=classrefdef;
  1344. end;
  1345. constructor tclassrefdef.load;
  1346. begin
  1347. { be careful, tclassdefref inherits from tpointerdef }
  1348. tdef.load;
  1349. deftype:=classrefdef;
  1350. pointertype.load;
  1351. is_far:=false;
  1352. savesize:=target_os.size_of_pointer;
  1353. end;
  1354. procedure tclassrefdef.write;
  1355. begin
  1356. { be careful, tclassdefref inherits from tpointerdef }
  1357. tdef.write;
  1358. pointertype.write;
  1359. current_ppu^.writeentry(ibclassrefdef);
  1360. end;
  1361. {$ifdef GDB}
  1362. function tclassrefdef.stabstring : pchar;
  1363. begin
  1364. stabstring:=strpnew(pvmtdef^.numberstring+';');
  1365. end;
  1366. procedure tclassrefdef.concatstabto(asmlist : paasmoutput);
  1367. begin
  1368. inherited concatstabto(asmlist);
  1369. end;
  1370. {$endif GDB}
  1371. function tclassrefdef.gettypename : string;
  1372. begin
  1373. gettypename:='Class Of '+pointertype.def^.typename;
  1374. end;
  1375. {***************************************************************************
  1376. TSETDEF
  1377. ***************************************************************************}
  1378. { For i386 smallsets work,
  1379. for m68k there are problems
  1380. can be test by compiling with -dusesmallset PM }
  1381. {$ifdef i386}
  1382. {$define usesmallset}
  1383. {$endif i386}
  1384. constructor tsetdef.init(s : pdef;high : longint);
  1385. begin
  1386. inherited init;
  1387. deftype:=setdef;
  1388. elementtype.setdef(s);
  1389. {$ifdef usesmallset}
  1390. { small sets only working for i386 PM }
  1391. if high<32 then
  1392. begin
  1393. settype:=smallset;
  1394. {$ifdef testvarsets}
  1395. if aktsetalloc=0 THEN { $PACKSET Fixed?}
  1396. {$endif}
  1397. savesize:=Sizeof(longint)
  1398. {$ifdef testvarsets}
  1399. else {No, use $PACKSET VALUE for rounding}
  1400. savesize:=aktsetalloc*((high+aktsetalloc*8-1) DIV (aktsetalloc*8))
  1401. {$endif}
  1402. ;
  1403. end
  1404. else
  1405. {$endif usesmallset}
  1406. if high<256 then
  1407. begin
  1408. settype:=normset;
  1409. savesize:=32;
  1410. end
  1411. else
  1412. {$ifdef testvarsets}
  1413. if high<$10000 then
  1414. begin
  1415. settype:=varset;
  1416. savesize:=4*((high+31) div 32);
  1417. end
  1418. else
  1419. {$endif testvarsets}
  1420. Message(sym_e_ill_type_decl_set);
  1421. end;
  1422. constructor tsetdef.load;
  1423. begin
  1424. inherited load;
  1425. deftype:=setdef;
  1426. elementtype.load;
  1427. settype:=tsettype(readbyte);
  1428. case settype of
  1429. normset : savesize:=32;
  1430. varset : savesize:=readlong;
  1431. smallset : savesize:=Sizeof(longint);
  1432. end;
  1433. end;
  1434. destructor tsetdef.done;
  1435. begin
  1436. inherited done;
  1437. end;
  1438. procedure tsetdef.write;
  1439. begin
  1440. inherited write;
  1441. elementtype.write;
  1442. writebyte(byte(settype));
  1443. if settype=varset then
  1444. writelong(savesize);
  1445. current_ppu^.writeentry(ibsetdef);
  1446. end;
  1447. {$ifdef GDB}
  1448. function tsetdef.stabstring : pchar;
  1449. begin
  1450. { For small sets write a longint, which can at least be seen
  1451. in the current GDB's (PFV)
  1452. this is obsolete with GDBPAS !!
  1453. and anyhow creates problems with version 4.18!! PM
  1454. if settype=smallset then
  1455. stabstring := strpnew('r'+s32bitdef^.numberstring+';0;0xffffffff;')
  1456. else }
  1457. stabstring := strpnew('S'+elementtype.def^.numberstring);
  1458. end;
  1459. procedure tsetdef.concatstabto(asmlist : paasmoutput);
  1460. begin
  1461. if ( not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1462. (is_def_stab_written = not_written) then
  1463. begin
  1464. if assigned(elementtype.def) then
  1465. forcestabto(asmlist,elementtype.def);
  1466. inherited concatstabto(asmlist);
  1467. end;
  1468. end;
  1469. {$endif GDB}
  1470. procedure tsetdef.deref;
  1471. begin
  1472. inherited deref;
  1473. elementtype.resolve;
  1474. end;
  1475. procedure tsetdef.write_rtti_data;
  1476. begin
  1477. rttilist^.concat(new(pai_const,init_8bit(tkSet)));
  1478. write_rtti_name;
  1479. rttilist^.concat(new(pai_const,init_8bit(otULong)));
  1480. rttilist^.concat(new(pai_const_symbol,initname(elementtype.def^.get_rtti_label)));
  1481. end;
  1482. procedure tsetdef.write_child_rtti_data;
  1483. begin
  1484. elementtype.def^.get_rtti_label;
  1485. end;
  1486. function tsetdef.is_publishable : boolean;
  1487. begin
  1488. is_publishable:=settype=smallset;
  1489. end;
  1490. function tsetdef.gettypename : string;
  1491. begin
  1492. if assigned(elementtype.def) then
  1493. gettypename:='Set Of '+elementtype.def^.typename
  1494. else
  1495. gettypename:='Empty Set';
  1496. end;
  1497. {***************************************************************************
  1498. TFORMALDEF
  1499. ***************************************************************************}
  1500. constructor tformaldef.init;
  1501. var
  1502. stregdef : boolean;
  1503. begin
  1504. stregdef:=registerdef;
  1505. registerdef:=false;
  1506. inherited init;
  1507. deftype:=formaldef;
  1508. registerdef:=stregdef;
  1509. { formaldef must be registered at unit level !! }
  1510. if registerdef and assigned(current_module) then
  1511. if assigned(current_module^.localsymtable) then
  1512. psymtable(current_module^.localsymtable)^.registerdef(@self)
  1513. else if assigned(current_module^.globalsymtable) then
  1514. psymtable(current_module^.globalsymtable)^.registerdef(@self);
  1515. savesize:=target_os.size_of_pointer;
  1516. end;
  1517. constructor tformaldef.load;
  1518. begin
  1519. inherited load;
  1520. deftype:=formaldef;
  1521. savesize:=target_os.size_of_pointer;
  1522. end;
  1523. procedure tformaldef.write;
  1524. begin
  1525. inherited write;
  1526. current_ppu^.writeentry(ibformaldef);
  1527. end;
  1528. {$ifdef GDB}
  1529. function tformaldef.stabstring : pchar;
  1530. begin
  1531. stabstring := strpnew('formal'+numberstring+';');
  1532. end;
  1533. procedure tformaldef.concatstabto(asmlist : paasmoutput);
  1534. begin
  1535. { formaldef can't be stab'ed !}
  1536. end;
  1537. {$endif GDB}
  1538. function tformaldef.gettypename : string;
  1539. begin
  1540. gettypename:='Var';
  1541. end;
  1542. {***************************************************************************
  1543. TARRAYDEF
  1544. ***************************************************************************}
  1545. constructor tarraydef.init(l,h : longint;rd : pdef);
  1546. begin
  1547. inherited init;
  1548. deftype:=arraydef;
  1549. lowrange:=l;
  1550. highrange:=h;
  1551. rangetype.setdef(rd);
  1552. elementtype.reset;
  1553. IsVariant:=false;
  1554. IsConstructor:=false;
  1555. IsArrayOfConst:=false;
  1556. rangenr:=0;
  1557. end;
  1558. constructor tarraydef.load;
  1559. begin
  1560. inherited load;
  1561. deftype:=arraydef;
  1562. { the addresses are calculated later }
  1563. elementtype.load;
  1564. rangetype.load;
  1565. lowrange:=readlong;
  1566. highrange:=readlong;
  1567. IsArrayOfConst:=boolean(readbyte);
  1568. IsVariant:=false;
  1569. IsConstructor:=false;
  1570. rangenr:=0;
  1571. end;
  1572. function tarraydef.getrangecheckstring : string;
  1573. begin
  1574. if (cs_create_smart in aktmoduleswitches) then
  1575. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  1576. else
  1577. getrangecheckstring:='R_'+tostr(rangenr);
  1578. end;
  1579. procedure tarraydef.genrangecheck;
  1580. begin
  1581. if rangenr=0 then
  1582. begin
  1583. { generates the data for range checking }
  1584. getlabelnr(rangenr);
  1585. if (cs_create_smart in aktmoduleswitches) then
  1586. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,8)))
  1587. else
  1588. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,8)));
  1589. if lowrange<=highrange then
  1590. begin
  1591. datasegment^.concat(new(pai_const,init_32bit(lowrange)));
  1592. datasegment^.concat(new(pai_const,init_32bit(highrange)));
  1593. end
  1594. { for big arrays we need two bounds }
  1595. else
  1596. begin
  1597. datasegment^.concat(new(pai_const,init_32bit(lowrange)));
  1598. datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
  1599. datasegment^.concat(new(pai_const,init_32bit($80000000)));
  1600. datasegment^.concat(new(pai_const,init_32bit(highrange)));
  1601. end;
  1602. end;
  1603. end;
  1604. procedure tarraydef.deref;
  1605. begin
  1606. inherited deref;
  1607. elementtype.resolve;
  1608. rangetype.resolve;
  1609. end;
  1610. procedure tarraydef.write;
  1611. begin
  1612. inherited write;
  1613. elementtype.write;
  1614. rangetype.write;
  1615. writelong(lowrange);
  1616. writelong(highrange);
  1617. writebyte(byte(IsArrayOfConst));
  1618. current_ppu^.writeentry(ibarraydef);
  1619. end;
  1620. {$ifdef GDB}
  1621. function tarraydef.stabstring : pchar;
  1622. begin
  1623. stabstring := strpnew('ar'+rangetype.def^.numberstring+';'
  1624. +tostr(lowrange)+';'+tostr(highrange)+';'+elementtype.def^.numberstring);
  1625. end;
  1626. procedure tarraydef.concatstabto(asmlist : paasmoutput);
  1627. begin
  1628. if (not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  1629. and (is_def_stab_written = not_written) then
  1630. begin
  1631. {when array are inserted they have no definition yet !!}
  1632. if assigned(elementtype.def) then
  1633. inherited concatstabto(asmlist);
  1634. end;
  1635. end;
  1636. {$endif GDB}
  1637. function tarraydef.elesize : longint;
  1638. begin
  1639. if isconstructor or is_open_array(@self) then
  1640. begin
  1641. { strings are stored by address only }
  1642. case elementtype.def^.deftype of
  1643. stringdef :
  1644. elesize:=4;
  1645. else
  1646. elesize:=elementtype.def^.size;
  1647. end;
  1648. end
  1649. else
  1650. elesize:=elementtype.def^.size;
  1651. end;
  1652. function tarraydef.size : longint;
  1653. begin
  1654. {Tarraydef.size may never be called for an open array!}
  1655. if highrange<lowrange then
  1656. internalerror(99080501);
  1657. If (elesize>0) and
  1658. (
  1659. (highrange-lowrange = $7fffffff) or
  1660. { () are needed around elesize-1 to avoid a possible
  1661. integer overflow for elesize=1 !! PM }
  1662. (($7fffffff div elesize + (elesize -1)) < (highrange - lowrange))
  1663. ) Then
  1664. Begin
  1665. Message(sym_e_segment_too_large);
  1666. size := 4
  1667. End
  1668. Else size:=(highrange-lowrange+1)*elesize;
  1669. end;
  1670. function tarraydef.alignment : longint;
  1671. begin
  1672. { alignment is the size of the elements }
  1673. alignment:=elesize;
  1674. end;
  1675. function tarraydef.needs_inittable : boolean;
  1676. begin
  1677. needs_inittable:=elementtype.def^.needs_inittable;
  1678. end;
  1679. procedure tarraydef.write_child_rtti_data;
  1680. begin
  1681. elementtype.def^.get_rtti_label;
  1682. end;
  1683. procedure tarraydef.write_rtti_data;
  1684. begin
  1685. rttilist^.concat(new(pai_const,init_8bit(tkarray)));
  1686. write_rtti_name;
  1687. { size of elements }
  1688. rttilist^.concat(new(pai_const,init_32bit(elesize)));
  1689. { count of elements }
  1690. rttilist^.concat(new(pai_const,init_32bit(highrange-lowrange+1)));
  1691. { element type }
  1692. rttilist^.concat(new(pai_const_symbol,initname(elementtype.def^.get_rtti_label)));
  1693. end;
  1694. function tarraydef.gettypename : string;
  1695. begin
  1696. if isarrayofconst or isConstructor then
  1697. begin
  1698. if isvariant then
  1699. gettypename:='Array Of Const'
  1700. else
  1701. gettypename:='Array Of '+elementtype.def^.typename;
  1702. end
  1703. else if is_open_array(@self) then
  1704. gettypename:='Array Of '+elementtype.def^.typename
  1705. else
  1706. begin
  1707. if rangetype.def^.deftype=enumdef then
  1708. gettypename:='Array['+rangetype.def^.typename+'] Of '+elementtype.def^.typename
  1709. else
  1710. gettypename:='Array['+tostr(lowrange)+'..'+
  1711. tostr(highrange)+'] Of '+elementtype.def^.typename
  1712. end;
  1713. end;
  1714. {***************************************************************************
  1715. trecorddef
  1716. ***************************************************************************}
  1717. constructor trecorddef.init(p : psymtable);
  1718. begin
  1719. inherited init;
  1720. deftype:=recorddef;
  1721. symtable:=p;
  1722. symtable^.defowner := @self;
  1723. symtable^.dataalignment:=packrecordalignment[aktpackrecords];
  1724. end;
  1725. constructor trecorddef.load;
  1726. var
  1727. oldread_member : boolean;
  1728. begin
  1729. inherited load;
  1730. deftype:=recorddef;
  1731. savesize:=readlong;
  1732. oldread_member:=read_member;
  1733. read_member:=true;
  1734. symtable:=new(psymtable,loadas(recordsymtable));
  1735. read_member:=oldread_member;
  1736. symtable^.defowner := @self;
  1737. end;
  1738. destructor trecorddef.done;
  1739. begin
  1740. if assigned(symtable) then
  1741. dispose(symtable,done);
  1742. inherited done;
  1743. end;
  1744. var
  1745. binittable : boolean;
  1746. procedure check_rec_inittable(s : pnamedindexobject);
  1747. begin
  1748. if (not binittable) and
  1749. (psym(s)^.typ=varsym) and
  1750. assigned(pvarsym(s)^.vartype.def) then
  1751. begin
  1752. if ((pvarsym(s)^.vartype.def^.deftype<>objectdef) or
  1753. not(pobjectdef(pvarsym(s)^.vartype.def)^.is_class)) then
  1754. binittable:=pvarsym(s)^.vartype.def^.needs_inittable;
  1755. end;
  1756. end;
  1757. function trecorddef.needs_inittable : boolean;
  1758. var
  1759. oldb : boolean;
  1760. begin
  1761. { there are recursive calls to needs_rtti possible, }
  1762. { so we have to change to old value how else should }
  1763. { we do that ? check_rec_rtti can't be a nested }
  1764. { procedure of needs_rtti ! }
  1765. oldb:=binittable;
  1766. binittable:=false;
  1767. symtable^.foreach({$ifndef TP}@{$endif}check_rec_inittable);
  1768. needs_inittable:=binittable;
  1769. binittable:=oldb;
  1770. end;
  1771. procedure trecorddef.deref;
  1772. var
  1773. oldrecsyms : psymtable;
  1774. begin
  1775. inherited deref;
  1776. oldrecsyms:=aktrecordsymtable;
  1777. aktrecordsymtable:=symtable;
  1778. { now dereference the definitions }
  1779. symtable^.deref;
  1780. aktrecordsymtable:=oldrecsyms;
  1781. end;
  1782. procedure trecorddef.write;
  1783. var
  1784. oldread_member : boolean;
  1785. begin
  1786. oldread_member:=read_member;
  1787. read_member:=true;
  1788. inherited write;
  1789. writelong(savesize);
  1790. current_ppu^.writeentry(ibrecorddef);
  1791. self.symtable^.writeas;
  1792. read_member:=oldread_member;
  1793. end;
  1794. function trecorddef.size:longint;
  1795. begin
  1796. size:=symtable^.datasize;
  1797. end;
  1798. function trecorddef.alignment:longint;
  1799. var
  1800. l : longint;
  1801. hp : pvarsym;
  1802. begin
  1803. { also check the first symbol for it's size, because a
  1804. packed record has dataalignment of 1, but the first
  1805. sym could be a longint which should be aligned on 4 bytes,
  1806. this is compatible with C record packing (PFV) }
  1807. hp:=pvarsym(symtable^.symindex^.first);
  1808. if assigned(hp) then
  1809. begin
  1810. l:=hp^.vartype.def^.size;
  1811. if l>symtable^.dataalignment then
  1812. begin
  1813. if l>=4 then
  1814. alignment:=4
  1815. else
  1816. if l>=2 then
  1817. alignment:=2
  1818. else
  1819. alignment:=1;
  1820. end
  1821. else
  1822. alignment:=symtable^.dataalignment;
  1823. end
  1824. else
  1825. alignment:=symtable^.dataalignment;
  1826. end;
  1827. {$ifdef GDB}
  1828. Const StabRecString : pchar = Nil;
  1829. StabRecSize : longint = 0;
  1830. RecOffset : Longint = 0;
  1831. procedure addname(p : pnamedindexobject);
  1832. var
  1833. news, newrec : pchar;
  1834. spec : string[3];
  1835. size : longint;
  1836. begin
  1837. { static variables from objects are like global objects }
  1838. if (sp_static in psym(p)^.symoptions) then
  1839. exit;
  1840. If psym(p)^.typ = varsym then
  1841. begin
  1842. if (sp_protected in psym(p)^.symoptions) then
  1843. spec:='/1'
  1844. else if (sp_private in psym(p)^.symoptions) then
  1845. spec:='/0'
  1846. else
  1847. spec:='';
  1848. { class fields are pointers PM }
  1849. if not assigned(pvarsym(p)^.vartype.def) then
  1850. writeln(pvarsym(p)^.name);
  1851. if (pvarsym(p)^.vartype.def^.deftype=objectdef) and
  1852. pobjectdef(pvarsym(p)^.vartype.def)^.is_class then
  1853. spec:=spec+'*';
  1854. size:=pvarsym(p)^.vartype.def^.size;
  1855. { open arrays made overflows !! }
  1856. if size>$fffffff then
  1857. size:=$fffffff;
  1858. newrec := strpnew(p^.name+':'+spec+pvarsym(p)^.vartype.def^.numberstring
  1859. +','+tostr(pvarsym(p)^.address*8)+','
  1860. +tostr(size*8)+';');
  1861. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  1862. begin
  1863. getmem(news,stabrecsize+memsizeinc);
  1864. strcopy(news,stabrecstring);
  1865. freemem(stabrecstring,stabrecsize);
  1866. stabrecsize:=stabrecsize+memsizeinc;
  1867. stabrecstring:=news;
  1868. end;
  1869. strcat(StabRecstring,newrec);
  1870. strdispose(newrec);
  1871. {This should be used for case !!}
  1872. RecOffset := RecOffset + pvarsym(p)^.vartype.def^.size;
  1873. end;
  1874. end;
  1875. function trecorddef.stabstring : pchar;
  1876. Var oldrec : pchar;
  1877. oldsize : longint;
  1878. begin
  1879. oldrec := stabrecstring;
  1880. oldsize:=stabrecsize;
  1881. GetMem(stabrecstring,memsizeinc);
  1882. stabrecsize:=memsizeinc;
  1883. strpcopy(stabRecString,'s'+tostr(size));
  1884. RecOffset := 0;
  1885. symtable^.foreach({$ifndef TP}@{$endif}addname);
  1886. { FPC doesn't want to convert a char to a pchar}
  1887. { is this a bug ? }
  1888. strpcopy(strend(StabRecString),';');
  1889. stabstring := strnew(StabRecString);
  1890. Freemem(stabrecstring,stabrecsize);
  1891. stabrecstring := oldrec;
  1892. stabrecsize:=oldsize;
  1893. end;
  1894. procedure trecorddef.concatstabto(asmlist : paasmoutput);
  1895. begin
  1896. if (not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1897. (is_def_stab_written = not_written) then
  1898. inherited concatstabto(asmlist);
  1899. end;
  1900. {$endif GDB}
  1901. var
  1902. count : longint;
  1903. procedure count_inittable_fields(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1904. begin
  1905. if ((psym(sym)^.typ=varsym) and
  1906. pvarsym(sym)^.vartype.def^.needs_inittable)
  1907. and ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
  1908. (not pobjectdef(pvarsym(sym)^.vartype.def)^.is_class)) then
  1909. inc(count);
  1910. end;
  1911. procedure count_fields(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1912. begin
  1913. inc(count);
  1914. end;
  1915. procedure write_field_inittable(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1916. begin
  1917. if ((psym(sym)^.typ=varsym) and
  1918. pvarsym(sym)^.vartype.def^.needs_inittable) and
  1919. ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
  1920. (not pobjectdef(pvarsym(sym)^.vartype.def)^.is_class)) then
  1921. begin
  1922. rttilist^.concat(new(pai_const_symbol,init(pvarsym(sym)^.vartype.def^.get_inittable_label)));
  1923. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  1924. end;
  1925. end;
  1926. procedure write_field_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1927. begin
  1928. rttilist^.concat(new(pai_const_symbol,initname(pvarsym(sym)^.vartype.def^.get_rtti_label)));
  1929. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  1930. end;
  1931. procedure generate_child_inittable(sym:pnamedindexobject);{$ifndef fpc}far;{$endif}
  1932. begin
  1933. if (psym(sym)^.typ=varsym) and
  1934. pvarsym(sym)^.vartype.def^.needs_inittable then
  1935. { force inittable generation }
  1936. pvarsym(sym)^.vartype.def^.get_inittable_label;
  1937. end;
  1938. procedure generate_child_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  1939. begin
  1940. pvarsym(sym)^.vartype.def^.get_rtti_label;
  1941. end;
  1942. procedure trecorddef.write_child_rtti_data;
  1943. begin
  1944. symtable^.foreach({$ifndef TP}@{$endif}generate_child_rtti);
  1945. end;
  1946. procedure trecorddef.write_child_init_data;
  1947. begin
  1948. symtable^.foreach({$ifndef TP}@{$endif}generate_child_inittable);
  1949. end;
  1950. procedure trecorddef.write_rtti_data;
  1951. begin
  1952. rttilist^.concat(new(pai_const,init_8bit(tkrecord)));
  1953. write_rtti_name;
  1954. rttilist^.concat(new(pai_const,init_32bit(size)));
  1955. count:=0;
  1956. symtable^.foreach({$ifndef TP}@{$endif}count_fields);
  1957. rttilist^.concat(new(pai_const,init_32bit(count)));
  1958. symtable^.foreach({$ifndef TP}@{$endif}write_field_rtti);
  1959. end;
  1960. procedure trecorddef.write_init_data;
  1961. begin
  1962. rttilist^.concat(new(pai_const,init_8bit(tkrecord)));
  1963. write_rtti_name;
  1964. rttilist^.concat(new(pai_const,init_32bit(size)));
  1965. count:=0;
  1966. symtable^.foreach({$ifndef TP}@{$endif}count_inittable_fields);
  1967. rttilist^.concat(new(pai_const,init_32bit(count)));
  1968. symtable^.foreach({$ifndef TP}@{$endif}write_field_inittable);
  1969. end;
  1970. function trecorddef.gettypename : string;
  1971. begin
  1972. gettypename:='<record type>'
  1973. end;
  1974. {***************************************************************************
  1975. TABSTRACTPROCDEF
  1976. ***************************************************************************}
  1977. constructor tabstractprocdef.init;
  1978. begin
  1979. inherited init;
  1980. new(para,init);
  1981. minparacount:=0;
  1982. maxparacount:=0;
  1983. fpu_used:=0;
  1984. proctypeoption:=potype_none;
  1985. proccalloptions:=[];
  1986. procoptions:=[];
  1987. rettype.setdef(voiddef);
  1988. symtablelevel:=0;
  1989. savesize:=target_os.size_of_pointer;
  1990. end;
  1991. destructor tabstractprocdef.done;
  1992. begin
  1993. dispose(para,done);
  1994. inherited done;
  1995. end;
  1996. procedure tabstractprocdef.concatpara(tt:ttype;vsp : tvarspez;defval:psym);
  1997. var
  1998. hp : pparaitem;
  1999. begin
  2000. new(hp,init);
  2001. hp^.paratyp:=vsp;
  2002. hp^.paratype:=tt;
  2003. hp^.register:=R_NO;
  2004. hp^.defaultvalue:=defval;
  2005. para^.insert(hp);
  2006. if not assigned(defval) then
  2007. inc(minparacount);
  2008. inc(maxparacount);
  2009. end;
  2010. { all functions returning in FPU are
  2011. assume to use 2 FPU registers
  2012. until the function implementation
  2013. is processed PM }
  2014. procedure tabstractprocdef.test_if_fpu_result;
  2015. begin
  2016. if assigned(rettype.def) and is_fpu(rettype.def) then
  2017. fpu_used:=2;
  2018. end;
  2019. procedure tabstractprocdef.deref;
  2020. var
  2021. hp : pparaitem;
  2022. begin
  2023. inherited deref;
  2024. rettype.resolve;
  2025. hp:=pparaitem(para^.first);
  2026. while assigned(hp) do
  2027. begin
  2028. hp^.paratype.resolve;
  2029. resolvesym(psym(hp^.defaultvalue));
  2030. hp:=pparaitem(hp^.next);
  2031. end;
  2032. end;
  2033. constructor tabstractprocdef.load;
  2034. var
  2035. hp : pparaitem;
  2036. count,i : word;
  2037. begin
  2038. inherited load;
  2039. new(para,init);
  2040. minparacount:=0;
  2041. maxparacount:=0;
  2042. rettype.load;
  2043. fpu_used:=readbyte;
  2044. proctypeoption:=tproctypeoption(readlong);
  2045. readsmallset(proccalloptions);
  2046. readsmallset(procoptions);
  2047. count:=readword;
  2048. savesize:=target_os.size_of_pointer;
  2049. for i:=1 to count do
  2050. begin
  2051. new(hp,init);
  2052. hp^.paratyp:=tvarspez(readbyte);
  2053. { hp^.register:=tregister(readbyte); }
  2054. hp^.register:=R_NO;
  2055. hp^.paratype.load;
  2056. hp^.defaultvalue:=readsymref;
  2057. if not assigned(hp^.defaultvalue) then
  2058. inc(minparacount);
  2059. inc(maxparacount);
  2060. para^.concat(hp);
  2061. end;
  2062. end;
  2063. procedure tabstractprocdef.write;
  2064. var
  2065. hp : pparaitem;
  2066. oldintfcrc : boolean;
  2067. begin
  2068. inherited write;
  2069. rettype.write;
  2070. oldintfcrc:=current_ppu^.do_interface_crc;
  2071. current_ppu^.do_interface_crc:=false;
  2072. writebyte(fpu_used);
  2073. writelong(ord(proctypeoption));
  2074. writesmallset(proccalloptions);
  2075. writesmallset(procoptions);
  2076. current_ppu^.do_interface_crc:=oldintfcrc;
  2077. writeword(maxparacount);
  2078. hp:=pparaitem(para^.first);
  2079. while assigned(hp) do
  2080. begin
  2081. writebyte(byte(hp^.paratyp));
  2082. { writebyte(byte(hp^.register)); }
  2083. hp^.paratype.write;
  2084. writesymref(hp^.defaultvalue);
  2085. hp:=pparaitem(hp^.next);
  2086. end;
  2087. end;
  2088. function tabstractprocdef.para_size(alignsize:longint) : longint;
  2089. var
  2090. pdc : pparaitem;
  2091. l : longint;
  2092. begin
  2093. l:=0;
  2094. pdc:=pparaitem(para^.first);
  2095. while assigned(pdc) do
  2096. begin
  2097. case pdc^.paratyp of
  2098. vs_out,
  2099. vs_var : inc(l,target_os.size_of_pointer);
  2100. vs_value,
  2101. vs_const : if push_addr_param(pdc^.paratype.def) then
  2102. inc(l,target_os.size_of_pointer)
  2103. else
  2104. inc(l,pdc^.paratype.def^.size);
  2105. end;
  2106. l:=align(l,alignsize);
  2107. pdc:=pparaitem(pdc^.next);
  2108. end;
  2109. para_size:=l;
  2110. end;
  2111. function tabstractprocdef.demangled_paras : string;
  2112. var
  2113. hs,s : string;
  2114. hp : pparaitem;
  2115. hpc : pconstsym;
  2116. begin
  2117. s:='(';
  2118. hp:=pparaitem(para^.last);
  2119. while assigned(hp) do
  2120. begin
  2121. if assigned(hp^.paratype.def^.typesym) then
  2122. s:=s+hp^.paratype.def^.typesym^.name
  2123. else if hp^.paratyp=vs_var then
  2124. s:=s+'var'
  2125. else if hp^.paratyp=vs_const then
  2126. s:=s+'const'
  2127. else if hp^.paratyp=vs_out then
  2128. s:=s+'out';
  2129. { default value }
  2130. if assigned(hp^.defaultvalue) then
  2131. begin
  2132. hpc:=pconstsym(hp^.defaultvalue);
  2133. hs:='';
  2134. case hpc^.consttyp of
  2135. conststring,
  2136. constresourcestring :
  2137. hs:=+strpas(pchar(tpointerord(hpc^.value)));
  2138. constreal :
  2139. str(pbestreal(tpointerord(hpc^.value))^,hs);
  2140. constord,
  2141. constpointer :
  2142. hs:=tostr(hpc^.value);
  2143. constbool :
  2144. begin
  2145. if hpc^.value<>0 then
  2146. hs:='TRUE'
  2147. else
  2148. hs:='FALSE';
  2149. end;
  2150. constnil :
  2151. hs:='nil';
  2152. constchar :
  2153. hs:=chr(hpc^.value);
  2154. constset :
  2155. hs:='<set>';
  2156. end;
  2157. if hs<>'' then
  2158. s:=s+'="'+hs+'"';
  2159. end;
  2160. hp:=pparaitem(hp^.previous);
  2161. if assigned(hp) then
  2162. s:=s+',';
  2163. end;
  2164. s:=s+')';
  2165. demangled_paras:=s;
  2166. end;
  2167. function tabstractprocdef.proccalloption2str : string;
  2168. type
  2169. tproccallopt=record
  2170. mask : tproccalloption;
  2171. str : string[30];
  2172. end;
  2173. const
  2174. proccallopts=12;
  2175. proccallopt : array[1..proccallopts] of tproccallopt=(
  2176. (mask:pocall_none; str:''),
  2177. (mask:pocall_clearstack; str:'ClearStack'),
  2178. (mask:pocall_leftright; str:'LeftRight'),
  2179. (mask:pocall_cdecl; str:'Cdecl'),
  2180. (mask:pocall_register; str:'Register'),
  2181. (mask:pocall_stdcall; str:'StdCall'),
  2182. (mask:pocall_safecall; str:'SafeCall'),
  2183. (mask:pocall_palmossyscall;str:'PalmOSSysCall'),
  2184. (mask:pocall_system; str:'System'),
  2185. (mask:pocall_inline; str:'Inline'),
  2186. (mask:pocall_internproc; str:'InternProc'),
  2187. (mask:pocall_internconst; str:'InternConst')
  2188. );
  2189. var
  2190. s : string;
  2191. i : longint;
  2192. first : boolean;
  2193. begin
  2194. s:='';
  2195. first:=true;
  2196. for i:=1to proccallopts do
  2197. if (proccallopt[i].mask in proccalloptions) then
  2198. begin
  2199. if first then
  2200. first:=false
  2201. else
  2202. s:=s+';';
  2203. s:=s+proccallopt[i].str;
  2204. end;
  2205. proccalloption2str:=s;
  2206. end;
  2207. {$ifdef GDB}
  2208. function tabstractprocdef.stabstring : pchar;
  2209. begin
  2210. stabstring := strpnew('abstractproc'+numberstring+';');
  2211. end;
  2212. procedure tabstractprocdef.concatstabto(asmlist : paasmoutput);
  2213. begin
  2214. if (not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2215. and (is_def_stab_written = not_written) then
  2216. begin
  2217. if assigned(rettype.def) then forcestabto(asmlist,rettype.def);
  2218. inherited concatstabto(asmlist);
  2219. end;
  2220. end;
  2221. {$endif GDB}
  2222. {***************************************************************************
  2223. TPROCDEF
  2224. ***************************************************************************}
  2225. constructor tprocdef.init;
  2226. begin
  2227. inherited init;
  2228. deftype:=procdef;
  2229. _mangledname:=nil;
  2230. nextoverloaded:=nil;
  2231. fileinfo:=aktfilepos;
  2232. extnumber:=-1;
  2233. localst:=new(psymtable,init(localsymtable));
  2234. parast:=new(psymtable,init(parasymtable));
  2235. localst^.defowner:=@self;
  2236. parast^.defowner:=@self;
  2237. { this is used by insert
  2238. to check same names in parast and localst }
  2239. localst^.next:=parast;
  2240. defref:=nil;
  2241. crossref:=nil;
  2242. lastwritten:=nil;
  2243. refcount:=0;
  2244. if (cs_browser in aktmoduleswitches) and make_ref then
  2245. begin
  2246. defref:=new(pref,init(defref,@tokenpos));
  2247. inc(refcount);
  2248. end;
  2249. lastref:=defref;
  2250. { first, we assume that all registers are used }
  2251. {$ifdef newcg}
  2252. usedregisters:=[firstreg..lastreg];
  2253. {$else newcg}
  2254. {$ifdef i386}
  2255. usedregisters:=$ff;
  2256. {$endif i386}
  2257. {$ifdef m68k}
  2258. usedregisters:=$FFFF;
  2259. {$endif}
  2260. {$endif newcg}
  2261. forwarddef:=true;
  2262. interfacedef:=false;
  2263. hasforward:=false;
  2264. _class := nil;
  2265. code:=nil;
  2266. regvarinfo := nil;
  2267. count:=false;
  2268. is_used:=false;
  2269. end;
  2270. constructor tprocdef.load;
  2271. var
  2272. s : string;
  2273. begin
  2274. inherited load;
  2275. deftype:=procdef;
  2276. {$ifdef newcg}
  2277. readnormalset(usedregisters);
  2278. {$else newcg}
  2279. {$ifdef i386}
  2280. usedregisters:=readbyte;
  2281. {$endif i386}
  2282. {$ifdef m68k}
  2283. usedregisters:=readword;
  2284. {$endif}
  2285. {$endif newcg}
  2286. s:=readstring;
  2287. setstring(_mangledname,s);
  2288. extnumber:=readlong;
  2289. nextoverloaded:=pprocdef(readdefref);
  2290. _class := pobjectdef(readdefref);
  2291. readposinfo(fileinfo);
  2292. if (cs_link_deffile in aktglobalswitches) and
  2293. (tf_need_export in target_info.flags) and
  2294. (po_exports in procoptions) then
  2295. deffile.AddExport(mangledname);
  2296. new(parast,loadas(parasymtable));
  2297. parast^.defowner:=@self;
  2298. {new(localst,loadas(localsymtable));
  2299. localst^.defowner:=@self;
  2300. parast^.next:=localst;
  2301. localst^.next:=owner;}
  2302. forwarddef:=false;
  2303. interfacedef:=false;
  2304. hasforward:=false;
  2305. code := nil;
  2306. regvarinfo := nil;
  2307. lastref:=nil;
  2308. lastwritten:=nil;
  2309. defref:=nil;
  2310. refcount:=0;
  2311. count:=true;
  2312. is_used:=false;
  2313. end;
  2314. Const local_symtable_index : longint = $8001;
  2315. procedure tprocdef.load_references;
  2316. var
  2317. pos : tfileposinfo;
  2318. {$ifndef NOLOCALBROWSER}
  2319. oldsymtablestack,
  2320. st : psymtable;
  2321. {$endif ndef NOLOCALBROWSER}
  2322. move_last : boolean;
  2323. begin
  2324. move_last:=lastwritten=lastref;
  2325. while (not current_ppu^.endofentry) do
  2326. begin
  2327. readposinfo(pos);
  2328. inc(refcount);
  2329. lastref:=new(pref,init(lastref,@pos));
  2330. lastref^.is_written:=true;
  2331. if refcount=1 then
  2332. defref:=lastref;
  2333. end;
  2334. if move_last then
  2335. lastwritten:=lastref;
  2336. if ((current_module^.flags and uf_local_browser)<>0)
  2337. and is_in_current then
  2338. begin
  2339. {$ifndef NOLOCALBROWSER}
  2340. oldsymtablestack:=symtablestack;
  2341. st:=aktlocalsymtable;
  2342. new(parast,loadas(parasymtable));
  2343. parast^.defowner:=@self;
  2344. aktlocalsymtable:=parast;
  2345. parast^.deref;
  2346. parast^.next:=owner;
  2347. parast^.load_browser;
  2348. aktlocalsymtable:=st;
  2349. new(localst,loadas(localsymtable));
  2350. localst^.defowner:=@self;
  2351. aktlocalsymtable:=localst;
  2352. symtablestack:=parast;
  2353. localst^.deref;
  2354. localst^.next:=parast;
  2355. localst^.load_browser;
  2356. aktlocalsymtable:=st;
  2357. symtablestack:=oldsymtablestack;
  2358. {$endif ndef NOLOCALBROWSER}
  2359. end;
  2360. end;
  2361. function tprocdef.write_references : boolean;
  2362. var
  2363. ref : pref;
  2364. {$ifndef NOLOCALBROWSER}
  2365. st : psymtable;
  2366. pdo : pobjectdef;
  2367. {$endif ndef NOLOCALBROWSER}
  2368. move_last : boolean;
  2369. begin
  2370. move_last:=lastwritten=lastref;
  2371. if move_last and (((current_module^.flags and uf_local_browser)=0)
  2372. or not is_in_current) then
  2373. exit;
  2374. { write address of this symbol }
  2375. writedefref(@self);
  2376. { write refs }
  2377. if assigned(lastwritten) then
  2378. ref:=lastwritten
  2379. else
  2380. ref:=defref;
  2381. while assigned(ref) do
  2382. begin
  2383. if ref^.moduleindex=current_module^.unit_index then
  2384. begin
  2385. writeposinfo(ref^.posinfo);
  2386. ref^.is_written:=true;
  2387. if move_last then
  2388. lastwritten:=ref;
  2389. end
  2390. else if not ref^.is_written then
  2391. move_last:=false
  2392. else if move_last then
  2393. lastwritten:=ref;
  2394. ref:=ref^.nextref;
  2395. end;
  2396. current_ppu^.writeentry(ibdefref);
  2397. write_references:=true;
  2398. if ((current_module^.flags and uf_local_browser)<>0)
  2399. and is_in_current then
  2400. begin
  2401. {$ifndef NOLOCALBROWSER}
  2402. pdo:=_class;
  2403. if (owner^.symtabletype<>localsymtable) then
  2404. while assigned(pdo) do
  2405. begin
  2406. if pdo^.symtable<>aktrecordsymtable then
  2407. begin
  2408. pdo^.symtable^.unitid:=local_symtable_index;
  2409. inc(local_symtable_index);
  2410. end;
  2411. pdo:=pdo^.childof;
  2412. end;
  2413. { we need TESTLOCALBROWSER para and local symtables
  2414. PPU files are then easier to read PM }
  2415. if not assigned(parast) then
  2416. parast:=new(psymtable,init(parasymtable));
  2417. parast^.defowner:=@self;
  2418. st:=aktlocalsymtable;
  2419. aktlocalsymtable:=parast;
  2420. parast^.writeas;
  2421. parast^.unitid:=local_symtable_index;
  2422. inc(local_symtable_index);
  2423. parast^.write_browser;
  2424. if not assigned(localst) then
  2425. localst:=new(psymtable,init(localsymtable));
  2426. localst^.defowner:=@self;
  2427. aktlocalsymtable:=localst;
  2428. localst^.writeas;
  2429. localst^.unitid:=local_symtable_index;
  2430. inc(local_symtable_index);
  2431. localst^.write_browser;
  2432. aktlocalsymtable:=st;
  2433. { decrement for }
  2434. local_symtable_index:=local_symtable_index-2;
  2435. pdo:=_class;
  2436. if (owner^.symtabletype<>localsymtable) then
  2437. while assigned(pdo) do
  2438. begin
  2439. if pdo^.symtable<>aktrecordsymtable then
  2440. dec(local_symtable_index);
  2441. pdo:=pdo^.childof;
  2442. end;
  2443. {$endif ndef NOLOCALBROWSER}
  2444. end;
  2445. end;
  2446. {$ifdef BrowserLog}
  2447. procedure tprocdef.add_to_browserlog;
  2448. begin
  2449. if assigned(defref) then
  2450. begin
  2451. browserlog.AddLog('***'+mangledname);
  2452. browserlog.AddLogRefs(defref);
  2453. if (current_module^.flags and uf_local_browser)<>0 then
  2454. begin
  2455. if assigned(parast) then
  2456. parast^.writebrowserlog;
  2457. if assigned(localst) then
  2458. localst^.writebrowserlog;
  2459. end;
  2460. end;
  2461. end;
  2462. {$endif BrowserLog}
  2463. destructor tprocdef.done;
  2464. begin
  2465. if assigned(defref) then
  2466. begin
  2467. defref^.freechain;
  2468. dispose(defref,done);
  2469. end;
  2470. if assigned(parast) then
  2471. dispose(parast,done);
  2472. if assigned(localst) and (localst^.symtabletype<>staticsymtable) then
  2473. dispose(localst,done);
  2474. if (pocall_inline in proccalloptions) and assigned(code) then
  2475. disposetree(ptree(code));
  2476. if assigned(regvarinfo) then
  2477. dispose(pregvarinfo(regvarinfo));
  2478. if (po_msgstr in procoptions) then
  2479. strdispose(messageinf.str);
  2480. if
  2481. {$ifdef tp}
  2482. not(use_big) and
  2483. {$endif}
  2484. assigned(_mangledname) then
  2485. strdispose(_mangledname);
  2486. inherited done;
  2487. end;
  2488. procedure tprocdef.write;
  2489. var
  2490. oldintfcrc : boolean;
  2491. begin
  2492. inherited write;
  2493. oldintfcrc:=current_ppu^.do_interface_crc;
  2494. current_ppu^.do_interface_crc:=false;
  2495. { set all registers to used for simplified compilation PM }
  2496. if simplify_ppu then
  2497. begin
  2498. {$ifdef newcg}
  2499. usedregisters:=[firstreg..lastreg];
  2500. {$else newcg}
  2501. {$ifdef i386}
  2502. usedregisters:=$ff;
  2503. {$endif i386}
  2504. {$ifdef m68k}
  2505. usedregisters:=$ffff;
  2506. {$endif}
  2507. {$endif newcg}
  2508. end;
  2509. {$ifdef newcg}
  2510. writenormalset(usedregisters);
  2511. {$else newcg}
  2512. {$ifdef i386}
  2513. writebyte(usedregisters);
  2514. {$endif i386}
  2515. {$ifdef m68k}
  2516. writeword(usedregisters);
  2517. {$endif}
  2518. {$endif newcg}
  2519. current_ppu^.do_interface_crc:=oldintfcrc;
  2520. writestring(mangledname);
  2521. writelong(extnumber);
  2522. if (proctypeoption<>potype_operator) then
  2523. writedefref(nextoverloaded)
  2524. else
  2525. begin
  2526. { only write the overloads from the same unit }
  2527. if assigned(nextoverloaded) and
  2528. (nextoverloaded^.owner=owner) then
  2529. writedefref(nextoverloaded)
  2530. else
  2531. writedefref(nil);
  2532. end;
  2533. writedefref(_class);
  2534. writeposinfo(fileinfo);
  2535. if (pocall_inline in proccalloptions) then
  2536. begin
  2537. { we need to save
  2538. - the para and the local symtable
  2539. - the code ptree !! PM
  2540. writesymtable(parast);
  2541. writesymtable(localst);
  2542. writeptree(ptree(code));
  2543. }
  2544. end;
  2545. current_ppu^.writeentry(ibprocdef);
  2546. { Save the para and local symtable, for easier reading
  2547. save both always, they don't influence the interface crc }
  2548. oldintfcrc:=current_ppu^.do_interface_crc;
  2549. current_ppu^.do_interface_crc:=false;
  2550. if not assigned(parast) then
  2551. begin
  2552. parast:=new(psymtable,init(parasymtable));
  2553. parast^.defowner:=@self;
  2554. end;
  2555. parast^.writeas;
  2556. {if not assigned(localst) then
  2557. begin
  2558. localst:=new(psymtable,init(localsymtable));
  2559. localst^.defowner:=@self;
  2560. end;
  2561. localst^.writeas;}
  2562. current_ppu^.do_interface_crc:=oldintfcrc;
  2563. end;
  2564. function tprocdef.haspara:boolean;
  2565. begin
  2566. haspara:=assigned(aktprocsym^.definition^.parast^.symindex^.first);
  2567. end;
  2568. {$ifdef GDB}
  2569. procedure addparaname(p : psym);
  2570. var vs : char;
  2571. begin
  2572. if pvarsym(p)^.varspez = vs_value then vs := '1'
  2573. else vs := '0';
  2574. strpcopy(strend(StabRecString),p^.name+':'+pvarsym(p)^.vartype.def^.numberstring+','+vs+';');
  2575. end;
  2576. function tprocdef.stabstring : pchar;
  2577. var
  2578. i : longint;
  2579. oldrec : pchar;
  2580. begin
  2581. oldrec := stabrecstring;
  2582. getmem(StabRecString,1024);
  2583. strpcopy(StabRecString,'f'+rettype.def^.numberstring);
  2584. i:=maxparacount;
  2585. if i>0 then
  2586. begin
  2587. strpcopy(strend(StabRecString),','+tostr(i)+';');
  2588. (* confuse gdb !! PM
  2589. if assigned(parast) then
  2590. parast^.foreach({$ifndef TP}@{$endif}addparaname)
  2591. else
  2592. begin
  2593. param := para1;
  2594. i := 0;
  2595. while assigned(param) do
  2596. begin
  2597. inc(i);
  2598. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  2599. {Here we have lost the parameter names !!}
  2600. {using lower case parameters }
  2601. strpcopy(strend(stabrecstring),'p'+tostr(i)
  2602. +':'+param^.paratype.def^.numberstring+','+vartyp+';');
  2603. param := param^.next;
  2604. end;
  2605. end; *)
  2606. {strpcopy(strend(StabRecString),';');}
  2607. end;
  2608. stabstring := strnew(stabrecstring);
  2609. freemem(stabrecstring,1024);
  2610. stabrecstring := oldrec;
  2611. end;
  2612. procedure tprocdef.concatstabto(asmlist : paasmoutput);
  2613. begin
  2614. end;
  2615. {$endif GDB}
  2616. procedure tprocdef.deref;
  2617. var
  2618. oldsymtablestack,
  2619. oldlocalsymtable : psymtable;
  2620. begin
  2621. inherited deref;
  2622. resolvedef(pdef(nextoverloaded));
  2623. resolvedef(pdef(_class));
  2624. { parast }
  2625. oldsymtablestack:=symtablestack;
  2626. oldlocalsymtable:=aktlocalsymtable;
  2627. aktlocalsymtable:=parast;
  2628. parast^.deref;
  2629. {symtablestack:=parast;
  2630. aktlocalsymtable:=localst;
  2631. localst^.deref;}
  2632. aktlocalsymtable:=oldlocalsymtable;
  2633. symtablestack:=oldsymtablestack;
  2634. end;
  2635. function tprocdef.mangledname : string;
  2636. {$ifdef tp}
  2637. var
  2638. oldpos : longint;
  2639. s : string;
  2640. b : byte;
  2641. {$endif tp}
  2642. begin
  2643. {$ifndef Delphi}
  2644. {$ifdef tp}
  2645. if use_big then
  2646. begin
  2647. symbolstream.seek(longint(_mangledname));
  2648. symbolstream.read(b,1);
  2649. symbolstream.read(s[1],b);
  2650. s[0]:=chr(b);
  2651. mangledname:=s;
  2652. end
  2653. else
  2654. {$endif}
  2655. {$endif Delphi}
  2656. mangledname:=strpas(_mangledname);
  2657. if count then
  2658. is_used:=true;
  2659. end;
  2660. function tprocdef.procname: string;
  2661. var
  2662. s : string;
  2663. l : longint;
  2664. begin
  2665. s:=mangledname;
  2666. { delete leading $$'s }
  2667. l:=pos('$$',s);
  2668. while l<>0 do
  2669. begin
  2670. delete(s,1,l+1);
  2671. l:=pos('$$',s);
  2672. end;
  2673. { delete leading _$'s }
  2674. l:=pos('_$',s);
  2675. while l<>0 do
  2676. begin
  2677. delete(s,1,l+1);
  2678. l:=pos('_$',s);
  2679. end;
  2680. l:=pos('$',s);
  2681. if l=0 then
  2682. procname:=s
  2683. else
  2684. procname:=Copy(s,1,l-1);
  2685. end;
  2686. {$IfDef GDB}
  2687. function tprocdef.cplusplusmangledname : string;
  2688. function getcppparaname(p : pdef) : string;
  2689. const
  2690. ordtype2str : array[tbasetype] of string[2] = (
  2691. '','','c',
  2692. 'Uc','Us','Ul',
  2693. 'Sc','s','l',
  2694. 'b','b','b',
  2695. 'Us','x','w');
  2696. var
  2697. s : string;
  2698. begin
  2699. case p^.deftype of
  2700. orddef:
  2701. s:=ordtype2str[porddef(p)^.typ];
  2702. pointerdef:
  2703. s:='P'+getcppparaname(ppointerdef(p)^.pointertype.def);
  2704. else
  2705. internalerror(2103001);
  2706. end;
  2707. getcppparaname:=s;
  2708. end;
  2709. var
  2710. s,s2 : string;
  2711. param : pparaitem;
  2712. begin
  2713. { we need this in lowercase letters! }
  2714. s := procsym^.name;
  2715. if procsym^.owner^.symtabletype=objectsymtable then
  2716. begin
  2717. s2:=pobjectdef(procsym^.owner^.defowner)^.objname^;
  2718. case proctypeoption of
  2719. potype_destructor:
  2720. s:='_$_'+tostr(length(s2))+s2;
  2721. potype_constructor:
  2722. s:='___'+tostr(length(s2))+s2;
  2723. else
  2724. s:='_'+s+'__'+tostr(length(s2))+s2;
  2725. end;
  2726. end
  2727. else s:=s+'_';
  2728. { concat modifiers }
  2729. { !!!!! }
  2730. { now we handle the parameters }
  2731. param := pparaitem(para^.first);
  2732. while assigned(param) do
  2733. begin
  2734. s2:=getcppparaname(param^.paratype.def);
  2735. if param^.paratyp in [vs_var,vs_out] then
  2736. s2:='R'+s2;
  2737. s:=s+s2;
  2738. param:=pparaitem(param^.next);
  2739. end;
  2740. cplusplusmangledname:=s;
  2741. end;
  2742. {$EndIf GDB}
  2743. procedure tprocdef.setmangledname(const s : string);
  2744. begin
  2745. if {$ifdef tp}not(use_big) and{$endif} (assigned(_mangledname)) then
  2746. begin
  2747. {$ifdef MEMDEBUG}
  2748. dec(manglenamesize,length(_mangledname^));
  2749. {$endif}
  2750. strdispose(_mangledname);
  2751. end;
  2752. setstring(_mangledname,s);
  2753. {$ifdef MEMDEBUG}
  2754. inc(manglenamesize,length(s));
  2755. {$endif}
  2756. {$ifdef EXTDEBUG}
  2757. if assigned(parast) then
  2758. begin
  2759. stringdispose(parast^.name);
  2760. parast^.name:=stringdup('args of '+s);
  2761. end;
  2762. if assigned(localst) then
  2763. begin
  2764. stringdispose(localst^.name);
  2765. localst^.name:=stringdup('locals of '+s);
  2766. end;
  2767. {$endif}
  2768. end;
  2769. {***************************************************************************
  2770. TPROCVARDEF
  2771. ***************************************************************************}
  2772. constructor tprocvardef.init;
  2773. begin
  2774. inherited init;
  2775. deftype:=procvardef;
  2776. end;
  2777. constructor tprocvardef.load;
  2778. begin
  2779. inherited load;
  2780. deftype:=procvardef;
  2781. end;
  2782. procedure tprocvardef.write;
  2783. begin
  2784. { here we cannot get a real good value so just give something }
  2785. { plausible (PM) }
  2786. { a more secure way would be
  2787. to allways store in a temp }
  2788. if is_fpu(rettype.def) then
  2789. fpu_used:=2
  2790. else
  2791. fpu_used:=0;
  2792. inherited write;
  2793. current_ppu^.writeentry(ibprocvardef);
  2794. end;
  2795. function tprocvardef.size : longint;
  2796. begin
  2797. if (po_methodpointer in procoptions) then
  2798. size:=2*target_os.size_of_pointer
  2799. else
  2800. size:=target_os.size_of_pointer;
  2801. end;
  2802. {$ifdef GDB}
  2803. function tprocvardef.stabstring : pchar;
  2804. var
  2805. nss : pchar;
  2806. { i : longint; }
  2807. begin
  2808. { i := maxparacount; }
  2809. getmem(nss,1024);
  2810. { it is not a function but a function pointer !! (PM) }
  2811. strpcopy(nss,'*f'+rettype.def^.numberstring{+','+tostr(i)}+';');
  2812. { this confuses gdb !!
  2813. we should use 'F' instead of 'f' but
  2814. as we use c++ language mode
  2815. it does not like that either
  2816. Please do not remove this part
  2817. might be used once
  2818. gdb for pascal is ready PM }
  2819. (*
  2820. param := para1;
  2821. i := 0;
  2822. while assigned(param) do
  2823. begin
  2824. inc(i);
  2825. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  2826. {Here we have lost the parameter names !!}
  2827. pst := strpnew('p'+tostr(i)+':'+param^.paratype.def^.numberstring+','+vartyp+';');
  2828. strcat(nss,pst);
  2829. strdispose(pst);
  2830. param := param^.next;
  2831. end; *)
  2832. {strpcopy(strend(nss),';');}
  2833. stabstring := strnew(nss);
  2834. freemem(nss,1024);
  2835. end;
  2836. procedure tprocvardef.concatstabto(asmlist : paasmoutput);
  2837. begin
  2838. if ( not assigned(typesym) or typesym^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2839. and (is_def_stab_written = not_written) then
  2840. inherited concatstabto(asmlist);
  2841. is_def_stab_written:=written;
  2842. end;
  2843. {$endif GDB}
  2844. procedure tprocvardef.write_rtti_data;
  2845. var
  2846. pdc : pparaitem;
  2847. methodkind, paraspec : byte;
  2848. begin
  2849. if po_methodpointer in procoptions then
  2850. begin
  2851. { write method id and name }
  2852. rttilist^.concat(new(pai_const,init_8bit(tkmethod)));
  2853. write_rtti_name;
  2854. { write kind of method (can only be function or procedure)}
  2855. if rettype.def = pdef(voiddef) then { ### typecast shoudln't be necessary! (sg) }
  2856. methodkind := mkProcedure
  2857. else
  2858. methodkind := mkFunction;
  2859. rttilist^.concat(new(pai_const,init_8bit(methodkind)));
  2860. { get # of parameters }
  2861. rttilist^.concat(new(pai_const,init_8bit(maxparacount)));
  2862. { write parameter info. The parameters must be written in reverse order
  2863. if this method uses right to left parameter pushing! }
  2864. if (pocall_leftright in proccalloptions) then
  2865. pdc:=pparaitem(para^.last)
  2866. else
  2867. pdc:=pparaitem(para^.first);
  2868. while assigned(pdc) do
  2869. begin
  2870. case pdc^.paratyp of
  2871. vs_value: paraspec := 0;
  2872. vs_const: paraspec := pfConst;
  2873. vs_var : paraspec := pfVar;
  2874. vs_out : paraspec := pfOut;
  2875. end;
  2876. { write flags for current parameter }
  2877. rttilist^.concat(new(pai_const,init_8bit(paraspec)));
  2878. { write name of current parameter ### how can I get this??? (sg)}
  2879. rttilist^.concat(new(pai_const,init_8bit(0)));
  2880. { write name of type of current parameter }
  2881. pdc^.paratype.def^.write_rtti_name;
  2882. if (pocall_leftright in proccalloptions) then
  2883. pdc:=pparaitem(pdc^.previous)
  2884. else
  2885. pdc:=pparaitem(pdc^.next);
  2886. end;
  2887. { write name of result type }
  2888. rettype.def^.write_rtti_name;
  2889. end;
  2890. end;
  2891. procedure tprocvardef.write_child_rtti_data;
  2892. begin
  2893. {!!!!!!!!}
  2894. end;
  2895. function tprocvardef.is_publishable : boolean;
  2896. begin
  2897. is_publishable:=(po_methodpointer in procoptions);
  2898. end;
  2899. function tprocvardef.gettypename : string;
  2900. begin
  2901. if assigned(rettype.def) and
  2902. (rettype.def<>pdef(voiddef)) then
  2903. gettypename:='<procedure variable type of function'+demangled_paras+
  2904. ':'+rettype.def^.gettypename+';'+proccalloption2str+'>'
  2905. else
  2906. gettypename:='<procedure variable type of procedure'+demangled_paras+
  2907. ';'+proccalloption2str+'>';
  2908. end;
  2909. {***************************************************************************
  2910. TOBJECTDEF
  2911. ***************************************************************************}
  2912. {$ifdef GDB}
  2913. const
  2914. vtabletype : word = 0;
  2915. vtableassigned : boolean = false;
  2916. {$endif GDB}
  2917. constructor tobjectdef.init(const n : string;c : pobjectdef);
  2918. begin
  2919. tdef.init;
  2920. deftype:=objectdef;
  2921. objectoptions:=[];
  2922. childof:=nil;
  2923. symtable:=new(psymtable,init(objectsymtable));
  2924. symtable^.name := stringdup(n);
  2925. { create space for vmt !! }
  2926. vmt_offset:=0;
  2927. symtable^.datasize:=0;
  2928. symtable^.defowner:=@self;
  2929. symtable^.dataalignment:=packrecordalignment[aktpackrecords];
  2930. set_parent(c);
  2931. objname:=stringdup(n);
  2932. end;
  2933. constructor tobjectdef.load;
  2934. var
  2935. oldread_member : boolean;
  2936. begin
  2937. tdef.load;
  2938. deftype:=objectdef;
  2939. savesize:=readlong;
  2940. vmt_offset:=readlong;
  2941. objname:=stringdup(readstring);
  2942. childof:=pobjectdef(readdefref);
  2943. readsmallset(objectoptions);
  2944. has_rtti:=boolean(readbyte);
  2945. oldread_member:=read_member;
  2946. read_member:=true;
  2947. symtable:=new(psymtable,loadas(objectsymtable));
  2948. read_member:=oldread_member;
  2949. symtable^.defowner:=@self;
  2950. symtable^.name := stringdup(objname^);
  2951. { handles the predefined class tobject }
  2952. { the last TOBJECT which is loaded gets }
  2953. { it ! }
  2954. if (childof=nil) and
  2955. is_class and
  2956. (objname^='TOBJECT') then
  2957. class_tobject:=@self;
  2958. end;
  2959. destructor tobjectdef.done;
  2960. begin
  2961. if assigned(symtable) then
  2962. dispose(symtable,done);
  2963. if (oo_is_forward in objectoptions) then
  2964. Message1(sym_e_class_forward_not_resolved,objname^);
  2965. stringdispose(objname);
  2966. tdef.done;
  2967. end;
  2968. procedure tobjectdef.write;
  2969. var
  2970. oldread_member : boolean;
  2971. begin
  2972. tdef.write;
  2973. writelong(size);
  2974. writelong(vmt_offset);
  2975. writestring(objname^);
  2976. writedefref(childof);
  2977. writesmallset(objectoptions);
  2978. writebyte(byte(has_rtti));
  2979. current_ppu^.writeentry(ibobjectdef);
  2980. oldread_member:=read_member;
  2981. read_member:=true;
  2982. symtable^.writeas;
  2983. read_member:=oldread_member;
  2984. end;
  2985. procedure tobjectdef.deref;
  2986. var
  2987. oldrecsyms : psymtable;
  2988. begin
  2989. inherited deref;
  2990. resolvedef(pdef(childof));
  2991. oldrecsyms:=aktrecordsymtable;
  2992. aktrecordsymtable:=symtable;
  2993. symtable^.deref;
  2994. aktrecordsymtable:=oldrecsyms;
  2995. end;
  2996. procedure tobjectdef.set_parent( c : pobjectdef);
  2997. begin
  2998. { nothing to do if the parent was not forward !}
  2999. if assigned(childof) then
  3000. exit;
  3001. childof:=c;
  3002. { some options are inherited !! }
  3003. if assigned(c) then
  3004. begin
  3005. objectoptions:=objectoptions+(c^.objectoptions*
  3006. [oo_has_virtual,oo_has_private,oo_has_protected,oo_has_constructor,oo_has_destructor]);
  3007. { add the data of the anchestor class }
  3008. inc(symtable^.datasize,c^.symtable^.datasize);
  3009. if (oo_has_vmt in objectoptions) and
  3010. (oo_has_vmt in c^.objectoptions) then
  3011. dec(symtable^.datasize,target_os.size_of_pointer);
  3012. { if parent has a vmt field then
  3013. the offset is the same for the child PM }
  3014. if (oo_has_vmt in c^.objectoptions) or is_class then
  3015. begin
  3016. vmt_offset:=c^.vmt_offset;
  3017. include(objectoptions,oo_has_vmt);
  3018. end;
  3019. end;
  3020. savesize := symtable^.datasize;
  3021. end;
  3022. procedure tobjectdef.insertvmt;
  3023. begin
  3024. if (oo_has_vmt in objectoptions) then
  3025. internalerror(12345)
  3026. else
  3027. begin
  3028. { first round up to multiple of 4 }
  3029. if (symtable^.dataalignment=2) then
  3030. begin
  3031. if (symtable^.datasize and 1)<>0 then
  3032. inc(symtable^.datasize);
  3033. end
  3034. else
  3035. if (symtable^.dataalignment>=4) then
  3036. begin
  3037. if (symtable^.datasize mod 4) <> 0 then
  3038. inc(symtable^.datasize,4-(symtable^.datasize mod 4));
  3039. end;
  3040. vmt_offset:=symtable^.datasize;
  3041. inc(symtable^.datasize,target_os.size_of_pointer);
  3042. include(objectoptions,oo_has_vmt);
  3043. end;
  3044. end;
  3045. procedure tobjectdef.check_forwards;
  3046. begin
  3047. symtable^.check_forwards;
  3048. if (oo_is_forward in objectoptions) then
  3049. begin
  3050. { ok, in future, the forward can be resolved }
  3051. Message1(sym_e_class_forward_not_resolved,objname^);
  3052. exclude(objectoptions,oo_is_forward);
  3053. end;
  3054. end;
  3055. { true, if self inherits from d (or if they are equal) }
  3056. function tobjectdef.is_related(d : pobjectdef) : boolean;
  3057. var
  3058. hp : pobjectdef;
  3059. begin
  3060. hp:=@self;
  3061. while assigned(hp) do
  3062. begin
  3063. if hp=d then
  3064. begin
  3065. is_related:=true;
  3066. exit;
  3067. end;
  3068. hp:=hp^.childof;
  3069. end;
  3070. is_related:=false;
  3071. end;
  3072. var
  3073. sd : pprocdef;
  3074. procedure _searchdestructor(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  3075. var
  3076. p : pprocdef;
  3077. begin
  3078. { if we found already a destructor, then we exit }
  3079. if assigned(sd) then
  3080. exit;
  3081. if psym(sym)^.typ=procsym then
  3082. begin
  3083. p:=pprocsym(sym)^.definition;
  3084. while assigned(p) do
  3085. begin
  3086. if p^.proctypeoption=potype_destructor then
  3087. begin
  3088. sd:=p;
  3089. exit;
  3090. end;
  3091. p:=p^.nextoverloaded;
  3092. end;
  3093. end;
  3094. end;
  3095. function tobjectdef.searchdestructor : pprocdef;
  3096. var
  3097. o : pobjectdef;
  3098. begin
  3099. searchdestructor:=nil;
  3100. o:=@self;
  3101. sd:=nil;
  3102. while assigned(o) do
  3103. begin
  3104. symtable^.foreach({$ifndef TP}@{$endif}_searchdestructor);
  3105. if assigned(sd) then
  3106. begin
  3107. searchdestructor:=sd;
  3108. exit;
  3109. end;
  3110. o:=o^.childof;
  3111. end;
  3112. end;
  3113. function tobjectdef.size : longint;
  3114. begin
  3115. if (oo_is_class in objectoptions) then
  3116. size:=target_os.size_of_pointer
  3117. else
  3118. size:=symtable^.datasize;
  3119. end;
  3120. function tobjectdef.alignment:longint;
  3121. begin
  3122. alignment:=symtable^.dataalignment;
  3123. end;
  3124. function tobjectdef.vmtmethodoffset(index:longint):longint;
  3125. begin
  3126. { for offset of methods for classes, see rtl/inc/objpash.inc }
  3127. if is_class then
  3128. vmtmethodoffset:=(index+12)*target_os.size_of_pointer
  3129. else
  3130. {$ifdef WITHDMT}
  3131. vmtmethodoffset:=(index+4)*target_os.size_of_pointer;
  3132. {$else WITHDMT}
  3133. vmtmethodoffset:=(index+3)*target_os.size_of_pointer;
  3134. {$endif WITHDMT}
  3135. end;
  3136. function tobjectdef.vmt_mangledname : string;
  3137. {DM: I get a nil pointer on the owner name. I don't know if this
  3138. mayhappen, and I have therefore fixed the problem by doing nil pointer
  3139. checks.}
  3140. var
  3141. s1,s2:string;
  3142. begin
  3143. if not(oo_has_vmt in objectoptions) then
  3144. Message1(parser_object_has_no_vmt,objname^);
  3145. if owner^.name=nil then
  3146. s1:=''
  3147. else
  3148. s1:=owner^.name^;
  3149. if objname=nil then
  3150. s2:=''
  3151. else
  3152. s2:=objname^;
  3153. vmt_mangledname:='VMT_'+s1+'$_'+s2;
  3154. end;
  3155. function tobjectdef.rtti_name : string;
  3156. var
  3157. s1,s2:string;
  3158. begin
  3159. if owner^.name=nil then
  3160. s1:=''
  3161. else
  3162. s1:=owner^.name^;
  3163. if objname=nil then
  3164. s2:=''
  3165. else
  3166. s2:=objname^;
  3167. rtti_name:='RTTI_'+s1+'$_'+s2;
  3168. end;
  3169. function tobjectdef.is_class : boolean;
  3170. begin
  3171. is_class:=(oo_is_class in objectoptions);
  3172. end;
  3173. function tobjectdef.is_object : boolean;
  3174. begin
  3175. is_object:=([oo_is_class,oo_is_interface,oo_is_cppclass]*
  3176. objectoptions)=[];
  3177. end;
  3178. function tobjectdef.is_interface : boolean;
  3179. begin
  3180. is_interface:=(oo_is_interface in objectoptions);
  3181. end;
  3182. function tobjectdef.is_cppclass : boolean;
  3183. begin
  3184. is_cppclass:=(oo_is_cppclass in objectoptions);
  3185. end;
  3186. {$ifdef GDB}
  3187. procedure addprocname(p :pnamedindexobject);
  3188. var virtualind,argnames : string;
  3189. news, newrec : pchar;
  3190. pd,ipd : pprocdef;
  3191. lindex : longint;
  3192. para : pparaitem;
  3193. arglength : byte;
  3194. sp : char;
  3195. begin
  3196. If psym(p)^.typ = procsym then
  3197. begin
  3198. pd := pprocsym(p)^.definition;
  3199. { this will be used for full implementation of object stabs
  3200. not yet done }
  3201. ipd := pd;
  3202. while assigned(ipd^.nextoverloaded) do ipd := ipd^.nextoverloaded;
  3203. if (po_virtualmethod in pd^.procoptions) then
  3204. begin
  3205. lindex := pd^.extnumber;
  3206. {doesnt seem to be necessary
  3207. lindex := lindex or $80000000;}
  3208. virtualind := '*'+tostr(lindex)+';'+ipd^._class^.numberstring+';'
  3209. end else virtualind := '.';
  3210. { used by gdbpas to recognize constructor and destructors }
  3211. if (pd^.proctypeoption=potype_constructor) then
  3212. argnames:='__ct__'
  3213. else if (pd^.proctypeoption=potype_destructor) then
  3214. argnames:='__dt__'
  3215. else
  3216. argnames := '';
  3217. { arguments are not listed here }
  3218. {we don't need another definition}
  3219. para := pparaitem(pd^.para^.first);
  3220. while assigned(para) do
  3221. begin
  3222. if para^.paratype.def^.deftype = formaldef then
  3223. begin
  3224. if para^.paratyp=vs_var then
  3225. argnames := argnames+'3var'
  3226. else if para^.paratyp=vs_const then
  3227. argnames:=argnames+'5const'
  3228. else if para^.paratyp=vs_out then
  3229. argnames:=argnames+'3out';
  3230. end
  3231. else
  3232. begin
  3233. { if the arg definition is like (v: ^byte;..
  3234. there is no sym attached to data !!! }
  3235. if assigned(para^.paratype.def^.typesym) then
  3236. begin
  3237. arglength := length(para^.paratype.def^.typesym^.name);
  3238. argnames := argnames + tostr(arglength)+para^.paratype.def^.typesym^.name;
  3239. end
  3240. else
  3241. begin
  3242. argnames:=argnames+'11unnamedtype';
  3243. end;
  3244. end;
  3245. para := pparaitem(para^.next);
  3246. end;
  3247. ipd^.is_def_stab_written := written;
  3248. { here 2A must be changed for private and protected }
  3249. { 0 is private 1 protected and 2 public }
  3250. if (sp_private in psym(p)^.symoptions) then sp:='0'
  3251. else if (sp_protected in psym(p)^.symoptions) then sp:='1'
  3252. else sp:='2';
  3253. newrec := strpnew(p^.name+'::'+ipd^.numberstring
  3254. +'=##'+pd^.rettype.def^.numberstring+';:'+argnames+';'+sp+'A'
  3255. +virtualind+';');
  3256. { get spare place for a string at the end }
  3257. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  3258. begin
  3259. getmem(news,stabrecsize+memsizeinc);
  3260. strcopy(news,stabrecstring);
  3261. freemem(stabrecstring,stabrecsize);
  3262. stabrecsize:=stabrecsize+memsizeinc;
  3263. stabrecstring:=news;
  3264. end;
  3265. strcat(StabRecstring,newrec);
  3266. {freemem(newrec,memsizeinc); }
  3267. strdispose(newrec);
  3268. {This should be used for case !!}
  3269. RecOffset := RecOffset + pd^.size;
  3270. end;
  3271. end;
  3272. function tobjectdef.stabstring : pchar;
  3273. var anc : pobjectdef;
  3274. oldrec : pchar;
  3275. oldrecsize : longint;
  3276. str_end : string;
  3277. begin
  3278. oldrec := stabrecstring;
  3279. oldrecsize:=stabrecsize;
  3280. stabrecsize:=memsizeinc;
  3281. GetMem(stabrecstring,stabrecsize);
  3282. strpcopy(stabRecString,'s'+tostr(symtable^.datasize));
  3283. if assigned(childof) then
  3284. {only one ancestor not virtual, public, at base offset 0 }
  3285. { !1 , 0 2 0 , }
  3286. strpcopy(strend(stabrecstring),'!1,020,'+childof^.numberstring+';');
  3287. {virtual table to implement yet}
  3288. RecOffset := 0;
  3289. symtable^.foreach({$ifndef TP}@{$endif}addname);
  3290. if (oo_has_vmt in objectoptions) then
  3291. if not assigned(childof) or not(oo_has_vmt in childof^.objectoptions) then
  3292. begin
  3293. strpcopy(strend(stabrecstring),'$vf'+numberstring+':'+typeglobalnumber('vtblarray')
  3294. +','+tostr(vmt_offset*8)+';');
  3295. end;
  3296. symtable^.foreach({$ifndef TP}@{$endif}addprocname);
  3297. if (oo_has_vmt in objectoptions) then
  3298. begin
  3299. anc := @self;
  3300. while assigned(anc^.childof) and (oo_has_vmt in anc^.childof^.objectoptions) do
  3301. anc := anc^.childof;
  3302. str_end:=';~%'+anc^.numberstring+';';
  3303. end
  3304. else
  3305. str_end:=';';
  3306. strpcopy(strend(stabrecstring),str_end);
  3307. stabstring := strnew(StabRecString);
  3308. freemem(stabrecstring,stabrecsize);
  3309. stabrecstring := oldrec;
  3310. stabrecsize:=oldrecsize;
  3311. end;
  3312. {$endif GDB}
  3313. procedure tobjectdef.write_child_init_data;
  3314. begin
  3315. symtable^.foreach({$ifndef TP}@{$endif}generate_child_inittable);
  3316. end;
  3317. procedure tobjectdef.write_init_data;
  3318. begin
  3319. if is_class then
  3320. rttilist^.concat(new(pai_const,init_8bit(tkclass)))
  3321. else
  3322. rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  3323. { generate the name }
  3324. rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
  3325. rttilist^.concat(new(pai_string,init(objname^)));
  3326. rttilist^.concat(new(pai_const,init_32bit(size)));
  3327. count:=0;
  3328. symtable^.foreach({$ifndef TP}@{$endif}count_inittable_fields);
  3329. rttilist^.concat(new(pai_const,init_32bit(count)));
  3330. symtable^.foreach({$ifndef TP}@{$endif}write_field_inittable);
  3331. end;
  3332. function tobjectdef.needs_inittable : boolean;
  3333. var
  3334. oldb : boolean;
  3335. begin
  3336. if is_class then
  3337. needs_inittable:=false
  3338. else
  3339. begin
  3340. { there are recursive calls to needs_inittable possible, }
  3341. { so we have to change to old value how else should }
  3342. { we do that ? check_rec_rtti can't be a nested }
  3343. { procedure of needs_rtti ! }
  3344. oldb:=binittable;
  3345. binittable:=false;
  3346. symtable^.foreach({$ifndef TP}@{$endif}check_rec_inittable);
  3347. needs_inittable:=binittable;
  3348. binittable:=oldb;
  3349. end;
  3350. end;
  3351. procedure count_published_properties(sym:pnamedindexobject);
  3352. {$ifndef fpc}far;{$endif}
  3353. begin
  3354. if needs_prop_entry(psym(sym)) and
  3355. (psym(sym)^.typ<>varsym) then
  3356. inc(count);
  3357. end;
  3358. procedure write_property_info(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  3359. var
  3360. proctypesinfo : byte;
  3361. procedure writeproc(proc : psymlist; shiftvalue : byte);
  3362. var
  3363. typvalue : byte;
  3364. hp : psymlistitem;
  3365. address : longint;
  3366. begin
  3367. if not(assigned(proc) and assigned(proc^.firstsym)) then
  3368. begin
  3369. rttilist^.concat(new(pai_const,init_32bit(1)));
  3370. typvalue:=3;
  3371. end
  3372. else if proc^.firstsym^.sym^.typ=varsym then
  3373. begin
  3374. address:=0;
  3375. hp:=proc^.firstsym;
  3376. while assigned(hp) do
  3377. begin
  3378. inc(address,pvarsym(hp^.sym)^.address);
  3379. hp:=hp^.next;
  3380. end;
  3381. rttilist^.concat(new(pai_const,init_32bit(address)));
  3382. typvalue:=0;
  3383. end
  3384. else
  3385. begin
  3386. if not(po_virtualmethod in pprocdef(proc^.def)^.procoptions) then
  3387. begin
  3388. rttilist^.concat(new(pai_const_symbol,initname(pprocdef(proc^.def)^.mangledname)));
  3389. typvalue:=1;
  3390. end
  3391. else
  3392. begin
  3393. { virtual method, write vmt offset }
  3394. rttilist^.concat(new(pai_const,init_32bit(
  3395. pprocdef(proc^.def)^._class^.vmtmethodoffset(pprocdef(proc^.def)^.extnumber))));
  3396. typvalue:=2;
  3397. end;
  3398. end;
  3399. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  3400. end;
  3401. begin
  3402. if needs_prop_entry(psym(sym)) then
  3403. case psym(sym)^.typ of
  3404. varsym:
  3405. begin
  3406. {$ifdef dummy}
  3407. if not(pvarsym(sym)^.vartype.def^.deftype=objectdef) or
  3408. not(pobjectdef(pvarsym(sym)^.vartype.def)^.is_class) then
  3409. internalerror(1509992);
  3410. { access to implicit class property as field }
  3411. proctypesinfo:=(0 shl 0) or (0 shl 2) or (0 shl 4);
  3412. rttilist^.concat(new(pai_const_symbol,initname(pvarsym(sym)^.vartype.def^.get_rtti_label)));
  3413. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  3414. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  3415. { per default stored }
  3416. rttilist^.concat(new(pai_const,init_32bit(1)));
  3417. { index as well as ... }
  3418. rttilist^.concat(new(pai_const,init_32bit(0)));
  3419. { default value are zero }
  3420. rttilist^.concat(new(pai_const,init_32bit(0)));
  3421. rttilist^.concat(new(pai_const,init_16bit(count)));
  3422. inc(count);
  3423. rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
  3424. rttilist^.concat(new(pai_const,init_8bit(length(pvarsym(sym)^.name))));
  3425. rttilist^.concat(new(pai_string,init(pvarsym(sym)^.name)));
  3426. {$endif dummy}
  3427. end;
  3428. propertysym:
  3429. begin
  3430. if ppo_indexed in ppropertysym(sym)^.propoptions then
  3431. proctypesinfo:=$40
  3432. else
  3433. proctypesinfo:=0;
  3434. rttilist^.concat(new(pai_const_symbol,initname(ppropertysym(sym)^.proptype.def^.get_rtti_label)));
  3435. writeproc(ppropertysym(sym)^.readaccess,0);
  3436. writeproc(ppropertysym(sym)^.writeaccess,2);
  3437. { isn't it stored ? }
  3438. if not(ppo_stored in ppropertysym(sym)^.propoptions) then
  3439. begin
  3440. rttilist^.concat(new(pai_const,init_32bit(0)));
  3441. proctypesinfo:=proctypesinfo or (3 shl 4);
  3442. end
  3443. else
  3444. writeproc(ppropertysym(sym)^.storedaccess,4);
  3445. rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.index)));
  3446. rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.default)));
  3447. rttilist^.concat(new(pai_const,init_16bit(count)));
  3448. inc(count);
  3449. rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
  3450. rttilist^.concat(new(pai_const,init_8bit(length(ppropertysym(sym)^.name))));
  3451. rttilist^.concat(new(pai_string,init(ppropertysym(sym)^.name)));
  3452. end;
  3453. else internalerror(1509992);
  3454. end;
  3455. end;
  3456. procedure generate_published_child_rtti(sym : pnamedindexobject);{$ifndef fpc}far;{$endif}
  3457. begin
  3458. if needs_prop_entry(psym(sym)) then
  3459. case psym(sym)^.typ of
  3460. varsym:
  3461. ;
  3462. { now ignored:
  3463. pvarsym(sym)^.vartype.def^.get_rtti_label;
  3464. }
  3465. propertysym:
  3466. ppropertysym(sym)^.proptype.def^.get_rtti_label;
  3467. else
  3468. internalerror(1509991);
  3469. end;
  3470. end;
  3471. procedure tobjectdef.write_child_rtti_data;
  3472. begin
  3473. symtable^.foreach({$ifndef TP}@{$endif}generate_published_child_rtti);
  3474. end;
  3475. procedure tobjectdef.generate_rtti;
  3476. begin
  3477. if not has_rtti then
  3478. begin
  3479. has_rtti:=true;
  3480. getdatalabel(rtti_label);
  3481. write_child_rtti_data;
  3482. rttilist^.concat(new(pai_symbol,initname_global(rtti_name,0)));
  3483. rttilist^.concat(new(pai_label,init(rtti_label)));
  3484. write_rtti_data;
  3485. rttilist^.concat(new(pai_symbol_end,initname(rtti_name)));
  3486. end;
  3487. end;
  3488. type
  3489. tclasslistitem = object(tlinkedlist_item)
  3490. index : longint;
  3491. p : pobjectdef;
  3492. end;
  3493. pclasslistitem = ^tclasslistitem;
  3494. var
  3495. classtablelist : tlinkedlist;
  3496. tablecount : longint;
  3497. function searchclasstablelist(p : pobjectdef) : pclasslistitem;
  3498. var
  3499. hp : pclasslistitem;
  3500. begin
  3501. hp:=pclasslistitem(classtablelist.first);
  3502. while assigned(hp) do
  3503. if hp^.p=p then
  3504. begin
  3505. searchclasstablelist:=hp;
  3506. exit;
  3507. end
  3508. else
  3509. hp:=pclasslistitem(hp^.next);
  3510. searchclasstablelist:=nil;
  3511. end;
  3512. procedure count_published_fields(sym:pnamedindexobject);
  3513. {$ifndef fpc}far;{$endif}
  3514. var
  3515. hp : pclasslistitem;
  3516. begin
  3517. if needs_prop_entry(psym(sym)) and
  3518. (psym(sym)^.typ=varsym) then
  3519. begin
  3520. if pvarsym(sym)^.vartype.def^.deftype<>objectdef then
  3521. internalerror(0206001);
  3522. hp:=searchclasstablelist(pobjectdef(pvarsym(sym)^.vartype.def));
  3523. if not(assigned(hp)) then
  3524. begin
  3525. hp:=new(pclasslistitem,init);
  3526. hp^.p:=pobjectdef(pvarsym(sym)^.vartype.def);
  3527. hp^.index:=tablecount;
  3528. classtablelist.concat(hp);
  3529. inc(tablecount);
  3530. end;
  3531. inc(count);
  3532. end;
  3533. end;
  3534. procedure writefields(sym:pnamedindexobject);
  3535. {$ifndef fpc}far;{$endif}
  3536. var
  3537. hp : pclasslistitem;
  3538. begin
  3539. if needs_prop_entry(psym(sym)) and
  3540. (psym(sym)^.typ=varsym) then
  3541. begin
  3542. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  3543. hp:=searchclasstablelist(pobjectdef(pvarsym(sym)^.vartype.def));
  3544. if not(assigned(hp)) then
  3545. internalerror(0206002);
  3546. rttilist^.concat(new(pai_const,init_16bit(hp^.index)));
  3547. rttilist^.concat(new(pai_const,init_8bit(length(pvarsym(sym)^.name))));
  3548. rttilist^.concat(new(pai_string,init(pvarsym(sym)^.name)));
  3549. end;
  3550. end;
  3551. function tobjectdef.generate_field_table : pasmlabel;
  3552. var
  3553. fieldtable,
  3554. classtable : pasmlabel;
  3555. hp : pclasslistitem;
  3556. begin
  3557. classtablelist.init;
  3558. getdatalabel(fieldtable);
  3559. getdatalabel(classtable);
  3560. count:=0;
  3561. tablecount:=0;
  3562. symtable^.foreach({$ifdef FPC}@{$endif}count_published_fields);
  3563. rttilist^.concat(new(pai_label,init(fieldtable)));
  3564. rttilist^.concat(new(pai_const,init_16bit(count)));
  3565. rttilist^.concat(new(pai_const_symbol,init(classtable)));
  3566. symtable^.foreach({$ifdef FPC}@{$endif}writefields);
  3567. { generate the class table }
  3568. rttilist^.concat(new(pai_label,init(classtable)));
  3569. rttilist^.concat(new(pai_const,init_16bit(tablecount)));
  3570. hp:=pclasslistitem(classtablelist.first);
  3571. while assigned(hp) do
  3572. begin
  3573. rttilist^.concat(new(pai_const_symbol,initname(pobjectdef(hp^.p)^.vmt_mangledname)));
  3574. hp:=pclasslistitem(hp^.next);
  3575. end;
  3576. generate_field_table:=fieldtable;
  3577. classtablelist.done;
  3578. end;
  3579. function tobjectdef.next_free_name_index : longint;
  3580. var
  3581. i : longint;
  3582. begin
  3583. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  3584. i:=childof^.next_free_name_index
  3585. else
  3586. i:=0;
  3587. count:=0;
  3588. symtable^.foreach({$ifndef TP}@{$endif}count_published_properties);
  3589. next_free_name_index:=i+count;
  3590. end;
  3591. procedure tobjectdef.write_rtti_data;
  3592. begin
  3593. if is_class then
  3594. rttilist^.concat(new(pai_const,init_8bit(tkclass)))
  3595. else
  3596. rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  3597. { generate the name }
  3598. rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
  3599. rttilist^.concat(new(pai_string,init(objname^)));
  3600. { write class type }
  3601. rttilist^.concat(new(pai_const_symbol,initname(vmt_mangledname)));
  3602. { write owner typeinfo }
  3603. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  3604. rttilist^.concat(new(pai_const_symbol,initname(childof^.get_rtti_label)))
  3605. else
  3606. rttilist^.concat(new(pai_const,init_32bit(0)));
  3607. { count total number of properties }
  3608. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  3609. count:=childof^.next_free_name_index
  3610. else
  3611. count:=0;
  3612. { write it }
  3613. symtable^.foreach({$ifndef TP}@{$endif}count_published_properties);
  3614. rttilist^.concat(new(pai_const,init_16bit(count)));
  3615. { write unit name }
  3616. if assigned(owner^.name) then
  3617. begin
  3618. rttilist^.concat(new(pai_const,init_8bit(length(owner^.name^))));
  3619. rttilist^.concat(new(pai_string,init(owner^.name^)));
  3620. end
  3621. else
  3622. rttilist^.concat(new(pai_const,init_8bit(0)));
  3623. { write published properties count }
  3624. count:=0;
  3625. symtable^.foreach({$ifndef TP}@{$endif}count_published_properties);
  3626. rttilist^.concat(new(pai_const,init_16bit(count)));
  3627. { count is used to write nameindex }
  3628. { but we need an offset of the owner }
  3629. { to give each property an own slot }
  3630. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  3631. count:=childof^.next_free_name_index
  3632. else
  3633. count:=0;
  3634. symtable^.foreach({$ifndef TP}@{$endif}write_property_info);
  3635. end;
  3636. function tobjectdef.is_publishable : boolean;
  3637. begin
  3638. is_publishable:=is_class;
  3639. end;
  3640. function tobjectdef.get_rtti_label : string;
  3641. begin
  3642. generate_rtti;
  3643. get_rtti_label:=rtti_name;
  3644. end;
  3645. {****************************************************************************
  3646. TFORWARDDEF
  3647. ****************************************************************************}
  3648. constructor tforwarddef.init(const s:string;const pos : tfileposinfo);
  3649. var
  3650. oldregisterdef : boolean;
  3651. begin
  3652. { never register the forwarddefs, they are disposed at the
  3653. end of the type declaration block }
  3654. oldregisterdef:=registerdef;
  3655. registerdef:=false;
  3656. inherited init;
  3657. registerdef:=oldregisterdef;
  3658. deftype:=forwarddef;
  3659. tosymname:=s;
  3660. forwardpos:=pos;
  3661. end;
  3662. function tforwarddef.gettypename:string;
  3663. begin
  3664. gettypename:='unresolved forward to '+tosymname;
  3665. end;
  3666. {****************************************************************************
  3667. TERRORDEF
  3668. ****************************************************************************}
  3669. constructor terrordef.init;
  3670. begin
  3671. inherited init;
  3672. deftype:=errordef;
  3673. end;
  3674. {$ifdef GDB}
  3675. function terrordef.stabstring : pchar;
  3676. begin
  3677. stabstring:=strpnew('error'+numberstring);
  3678. end;
  3679. {$endif GDB}
  3680. function terrordef.gettypename:string;
  3681. begin
  3682. gettypename:='<erroneous type>';
  3683. end;
  3684. {
  3685. $Log$
  3686. Revision 1.12 2000-08-21 11:27:44 pierre
  3687. * fix the stabs problems
  3688. Revision 1.11 2000/08/16 18:33:54 peter
  3689. * splitted namedobjectitem.next into indexnext and listnext so it
  3690. can be used in both lists
  3691. * don't allow "word = word" type definitions (merged)
  3692. Revision 1.10 2000/08/16 13:06:06 florian
  3693. + support of 64 bit integer constants
  3694. Revision 1.9 2000/08/13 13:06:37 peter
  3695. * store parast always for procdef (browser needs still update)
  3696. * add default parameter value to demangledpara
  3697. Revision 1.8 2000/08/08 19:28:57 peter
  3698. * memdebug/memory patches (merged)
  3699. * only once illegal directive (merged)
  3700. Revision 1.7 2000/08/06 19:39:28 peter
  3701. * default parameters working !
  3702. Revision 1.6 2000/08/06 14:17:15 peter
  3703. * overload fixes (merged)
  3704. Revision 1.5 2000/08/03 13:17:26 jonas
  3705. + allow regvars to be used inside inlined procs, which required the
  3706. following changes:
  3707. + load regvars in genentrycode/free them in genexitcode (cgai386)
  3708. * moved all regvar related code to new regvars unit
  3709. + added pregvarinfo type to hcodegen
  3710. + added regvarinfo field to tprocinfo (symdef/symdefh)
  3711. * deallocate the regvars of the caller in secondprocinline before
  3712. inlining the called procedure and reallocate them afterwards
  3713. Revision 1.4 2000/08/02 19:49:59 peter
  3714. * first things for default parameters
  3715. Revision 1.3 2000/07/13 12:08:27 michael
  3716. + patched to 1.1.0 with former 1.09patch from peter
  3717. Revision 1.2 2000/07/13 11:32:49 michael
  3718. + removed logs
  3719. }