symdef.inc 128 KB

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