symdef.pas 165 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552
  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. unit symdef;
  19. {$i defines.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,cobjects,
  24. { global }
  25. globtype,globals,tokens,
  26. { symtable }
  27. symconst,symbase,symtype,
  28. { node }
  29. node,
  30. { aasm }
  31. aasm,cpubase
  32. ;
  33. type
  34. {************************************************
  35. TDef
  36. ************************************************}
  37. pstoreddef = ^tstoreddef;
  38. tstoreddef = object(tdef)
  39. has_inittable : boolean;
  40. { adress of init informations }
  41. inittable_label : pasmlabel;
  42. has_rtti : boolean;
  43. { address of rtti }
  44. rtti_label : pasmlabel;
  45. nextglobal,
  46. previousglobal : pstoreddef;
  47. {$ifdef GDB}
  48. globalnb : word;
  49. is_def_stab_written : tdefstabstatus;
  50. {$endif GDB}
  51. constructor init;
  52. constructor load;
  53. destructor done;virtual;
  54. procedure write;virtual;
  55. function size:longint;virtual;
  56. function alignment:longint;virtual;
  57. function is_publishable : boolean;virtual;
  58. function is_in_current : boolean;
  59. { debug }
  60. {$ifdef GDB}
  61. function stabstring : pchar;virtual;
  62. procedure concatstabto(asmlist : paasmoutput);virtual;
  63. function NumberString:string;
  64. procedure set_globalnb;virtual;
  65. function allstabstring : pchar;
  66. {$endif GDB}
  67. { init. tables }
  68. function needs_inittable : boolean;virtual;
  69. procedure generate_inittable;
  70. function get_inittable_label : pasmlabel;
  71. { the default implemenation calls write_rtti_data }
  72. { if init and rtti data is different these procedures }
  73. { must be overloaded }
  74. procedure write_init_data;virtual;
  75. procedure write_child_init_data;virtual;
  76. { rtti }
  77. procedure write_rtti_name;
  78. function get_rtti_label : string;virtual;
  79. procedure generate_rtti;virtual;
  80. procedure write_rtti_data;virtual;
  81. procedure write_child_rtti_data;virtual;
  82. function is_intregable : boolean;
  83. function is_fpuregable : boolean;
  84. private
  85. savesize : longint;
  86. end;
  87. targconvtyp = (act_convertable,act_equal,act_exact);
  88. tvarspez = (vs_value,vs_const,vs_var,vs_out);
  89. pparaitem = ^tparaitem;
  90. tparaitem = object(tlinkedlist_item)
  91. paratype : ttype;
  92. paratyp : tvarspez;
  93. argconvtyp : targconvtyp;
  94. convertlevel : byte;
  95. register : tregister;
  96. defaultvalue : psym; { pconstsym }
  97. end;
  98. { this is only here to override the count method,
  99. which can't be used }
  100. pparalinkedlist = ^tparalinkedlist;
  101. tparalinkedlist = object(tlinkedlist)
  102. function count:longint;
  103. end;
  104. tfiletyp = (ft_text,ft_typed,ft_untyped);
  105. pfiledef = ^tfiledef;
  106. tfiledef = object(tstoreddef)
  107. filetyp : tfiletyp;
  108. typedfiletype : ttype;
  109. constructor inittext;
  110. constructor inituntyped;
  111. constructor inittyped(const tt : ttype);
  112. constructor inittypeddef(p : pdef);
  113. constructor load;
  114. procedure write;virtual;
  115. procedure deref;virtual;
  116. function gettypename:string;virtual;
  117. procedure setsize;
  118. { debug }
  119. {$ifdef GDB}
  120. function stabstring : pchar;virtual;
  121. procedure concatstabto(asmlist : paasmoutput);virtual;
  122. {$endif GDB}
  123. end;
  124. pformaldef = ^tformaldef;
  125. tformaldef = object(tstoreddef)
  126. constructor init;
  127. constructor load;
  128. procedure write;virtual;
  129. function gettypename:string;virtual;
  130. {$ifdef GDB}
  131. function stabstring : pchar;virtual;
  132. procedure concatstabto(asmlist : paasmoutput);virtual;
  133. {$endif GDB}
  134. end;
  135. pforwarddef = ^tforwarddef;
  136. tforwarddef = object(tstoreddef)
  137. tosymname : string;
  138. forwardpos : tfileposinfo;
  139. constructor init(const s:string;const pos : tfileposinfo);
  140. function gettypename:string;virtual;
  141. end;
  142. perrordef = ^terrordef;
  143. terrordef = object(tstoreddef)
  144. constructor init;
  145. function gettypename:string;virtual;
  146. { debug }
  147. {$ifdef GDB}
  148. function stabstring : pchar;virtual;
  149. {$endif GDB}
  150. end;
  151. { tpointerdef and tclassrefdef should get a common
  152. base class, but I derived tclassrefdef from tpointerdef
  153. to avoid problems with bugs (FK)
  154. }
  155. ppointerdef = ^tpointerdef;
  156. tpointerdef = object(tstoreddef)
  157. pointertype : ttype;
  158. is_far : boolean;
  159. constructor init(const tt : ttype);
  160. constructor initfar(const tt : ttype);
  161. constructor initdef(p : pdef);
  162. constructor initfardef(p : pdef);
  163. constructor load;
  164. destructor done;virtual;
  165. procedure write;virtual;
  166. procedure deref;virtual;
  167. function gettypename:string;virtual;
  168. { debug }
  169. {$ifdef GDB}
  170. function stabstring : pchar;virtual;
  171. procedure concatstabto(asmlist : paasmoutput);virtual;
  172. {$endif GDB}
  173. end;
  174. pprocdef = ^tprocdef;
  175. pimplementedinterfaces = ^timplementedinterfaces;
  176. pobjectdef = ^tobjectdef;
  177. tobjectdef = object(tstoreddef)
  178. childof : pobjectdef;
  179. objname : pstring;
  180. symtable : psymtable;
  181. objectoptions : tobjectoptions;
  182. { to be able to have a variable vmt position }
  183. { and no vmt field for objects without virtuals }
  184. vmt_offset : longint;
  185. {$ifdef GDB}
  186. classglobalnb,
  187. classptrglobalnb : word;
  188. writing_stabs : boolean;
  189. {$endif GDB}
  190. objecttype : tobjectdeftype;
  191. isiidguidvalid: boolean;
  192. iidguid: TGUID;
  193. iidstr: pstring;
  194. lastvtableindex: longint;
  195. { store implemented interfaces defs and name mappings }
  196. implementedinterfaces: pimplementedinterfaces;
  197. constructor init(ot : tobjectdeftype;const n : string;c : pobjectdef);
  198. constructor load;
  199. destructor done;virtual;
  200. procedure write;virtual;
  201. procedure deref;virtual;
  202. function size : longint;virtual;
  203. function alignment:longint;virtual;
  204. function getsymtable(t:tgetsymtable):psymtable;virtual;
  205. function vmtmethodoffset(index:longint):longint;
  206. function is_publishable : boolean;virtual;
  207. function vmt_mangledname : string;
  208. function rtti_name : string;
  209. procedure check_forwards;
  210. function is_related(d : pobjectdef) : boolean;
  211. function next_free_name_index : longint;
  212. procedure insertvmt;
  213. procedure set_parent(c : pobjectdef);
  214. function searchdestructor : pprocdef;
  215. { debug }
  216. {$ifdef GDB}
  217. function stabstring : pchar;virtual;
  218. procedure set_globalnb;virtual;
  219. function classnumberstring : string;
  220. function classptrnumberstring : string;
  221. procedure concatstabto(asmlist : paasmoutput);virtual;
  222. {$endif GDB}
  223. { init/final }
  224. function needs_inittable : boolean;virtual;
  225. procedure write_init_data;virtual;
  226. procedure write_child_init_data;virtual;
  227. { rtti }
  228. function get_rtti_label : string;virtual;
  229. procedure generate_rtti;virtual;
  230. procedure write_rtti_data;virtual;
  231. procedure write_child_rtti_data;virtual;
  232. function generate_field_table : pasmlabel;
  233. end;
  234. timplementedinterfaces = object
  235. constructor init;
  236. destructor done; virtual;
  237. function count: longint;
  238. function interfaces(intfindex: longint): pobjectdef;
  239. function ioffsets(intfindex: longint): plongint;
  240. function searchintf(def: pdef): longint;
  241. procedure addintf(def: pdef);
  242. procedure deref;
  243. procedure addintfref(def: pdef);
  244. procedure clearmappings;
  245. procedure addmappings(intfindex: longint; const name, newname: string);
  246. function getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
  247. procedure clearimplprocs;
  248. procedure addimplproc(intfindex: longint; procdef: pprocdef);
  249. function implproccount(intfindex: longint): longint;
  250. function implprocs(intfindex: longint; procindex: longint): pprocdef;
  251. function isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
  252. private
  253. finterfaces: tindexarray;
  254. procedure checkindex(intfindex: longint);
  255. end;
  256. pclassrefdef = ^tclassrefdef;
  257. tclassrefdef = object(tpointerdef)
  258. constructor init(def : pdef);
  259. constructor load;
  260. procedure write;virtual;
  261. function gettypename:string;virtual;
  262. { debug }
  263. {$ifdef GDB}
  264. function stabstring : pchar;virtual;
  265. procedure concatstabto(asmlist : paasmoutput);virtual;
  266. {$endif GDB}
  267. end;
  268. parraydef = ^tarraydef;
  269. tarraydef = object(tstoreddef)
  270. rangenr : longint;
  271. lowrange,
  272. highrange : longint;
  273. elementtype,
  274. rangetype : ttype;
  275. IsDynamicArray,
  276. IsVariant,
  277. IsConstructor,
  278. IsArrayOfConst : boolean;
  279. function gettypename:string;virtual;
  280. function elesize : longint;
  281. constructor init(l,h : longint;rd : pdef);
  282. constructor load;
  283. procedure write;virtual;
  284. {$ifdef GDB}
  285. function stabstring : pchar;virtual;
  286. procedure concatstabto(asmlist : paasmoutput);virtual;
  287. {$endif GDB}
  288. procedure deref;virtual;
  289. function size : longint;virtual;
  290. function alignment : longint;virtual;
  291. { generates the ranges needed by the asm instruction BOUND (i386)
  292. or CMP2 (Motorola) }
  293. procedure genrangecheck;
  294. { returns the label of the range check string }
  295. function getrangecheckstring : string;
  296. function needs_inittable : boolean;virtual;
  297. procedure write_rtti_data;virtual;
  298. procedure write_child_rtti_data;virtual;
  299. end;
  300. precorddef = ^trecorddef;
  301. trecorddef = object(tstoreddef)
  302. symtable : psymtable;
  303. constructor init(p : psymtable);
  304. constructor load;
  305. destructor done;virtual;
  306. procedure write;virtual;
  307. procedure deref;virtual;
  308. function size:longint;virtual;
  309. function alignment : longint;virtual;
  310. function gettypename:string;virtual;
  311. function getsymtable(t:tgetsymtable):psymtable;virtual;
  312. { debug }
  313. {$ifdef GDB}
  314. function stabstring : pchar;virtual;
  315. procedure concatstabto(asmlist : paasmoutput);virtual;
  316. {$endif GDB}
  317. { init/final }
  318. procedure write_init_data;virtual;
  319. procedure write_child_init_data;virtual;
  320. function needs_inittable : boolean;virtual;
  321. { rtti }
  322. procedure write_rtti_data;virtual;
  323. procedure write_child_rtti_data;virtual;
  324. end;
  325. porddef = ^torddef;
  326. torddef = object(tstoreddef)
  327. rangenr : longint;
  328. low,high : longint;
  329. typ : tbasetype;
  330. constructor init(t : tbasetype;v,b : longint);
  331. constructor load;
  332. procedure write;virtual;
  333. function is_publishable : boolean;virtual;
  334. function gettypename:string;virtual;
  335. procedure setsize;
  336. { generates the ranges needed by the asm instruction BOUND }
  337. { or CMP2 (Motorola) }
  338. procedure genrangecheck;
  339. function getrangecheckstring : string;
  340. { debug }
  341. {$ifdef GDB}
  342. function stabstring : pchar;virtual;
  343. {$endif GDB}
  344. { rtti }
  345. procedure write_rtti_data;virtual;
  346. end;
  347. pfloatdef = ^tfloatdef;
  348. tfloatdef = object(tstoreddef)
  349. typ : tfloattype;
  350. constructor init(t : tfloattype);
  351. constructor load;
  352. procedure write;virtual;
  353. function gettypename:string;virtual;
  354. function is_publishable : boolean;virtual;
  355. procedure setsize;
  356. { debug }
  357. {$ifdef GDB}
  358. function stabstring : pchar;virtual;
  359. {$endif GDB}
  360. { rtti }
  361. procedure write_rtti_data;virtual;
  362. end;
  363. pabstractprocdef = ^tabstractprocdef;
  364. tabstractprocdef = object(tstoreddef)
  365. { saves a definition to the return type }
  366. rettype : ttype;
  367. proctypeoption : tproctypeoption;
  368. proccalloptions : tproccalloptions;
  369. procoptions : tprocoptions;
  370. para : pparalinkedlist;
  371. maxparacount,
  372. minparacount : longint;
  373. symtablelevel : byte;
  374. fpu_used : byte; { how many stack fpu must be empty }
  375. constructor init;
  376. constructor load;
  377. destructor done;virtual;
  378. procedure write;virtual;
  379. procedure deref;virtual;
  380. procedure concatpara(tt:ttype;vsp : tvarspez;defval:psym);
  381. function para_size(alignsize:longint) : longint;
  382. function demangled_paras : string;
  383. function proccalloption2str : string;
  384. procedure test_if_fpu_result;
  385. { debug }
  386. {$ifdef GDB}
  387. function stabstring : pchar;virtual;
  388. procedure concatstabto(asmlist : paasmoutput);virtual;
  389. {$endif GDB}
  390. end;
  391. pprocvardef = ^tprocvardef;
  392. tprocvardef = object(tabstractprocdef)
  393. constructor init;
  394. constructor load;
  395. procedure write;virtual;
  396. function size : longint;virtual;
  397. function gettypename:string;virtual;
  398. function is_publishable : boolean;virtual;
  399. { debug }
  400. {$ifdef GDB}
  401. function stabstring : pchar;virtual;
  402. procedure concatstabto(asmlist : paasmoutput); virtual;
  403. {$endif GDB}
  404. { rtti }
  405. procedure write_child_rtti_data;virtual;
  406. procedure write_rtti_data;virtual;
  407. end;
  408. tmessageinf = record
  409. case integer of
  410. 0 : (str : pchar);
  411. 1 : (i : longint);
  412. end;
  413. tprocdef = object(tabstractprocdef)
  414. private
  415. _mangledname : pstring;
  416. public
  417. extnumber : longint;
  418. messageinf : tmessageinf;
  419. nextoverloaded : pprocdef;
  420. { where is this function defined, needed here because there
  421. is only one symbol for all overloaded functions }
  422. fileinfo : tfileposinfo;
  423. { symbol owning this definition }
  424. procsym : psym;
  425. { symtables }
  426. parast,
  427. localst : psymtable;
  428. { browser info }
  429. lastref,
  430. defref,
  431. crossref,
  432. lastwritten : pref;
  433. refcount : longint;
  434. _class : pobjectdef;
  435. { it's a tree, but this not easy to handle }
  436. { used for inlined procs }
  437. code : tnode;
  438. { info about register variables (JM) }
  439. regvarinfo: pointer;
  440. { true, if the procedure is only declared }
  441. { (forward procedure) }
  442. forwarddef,
  443. { true if the procedure is declared in the interface }
  444. interfacedef : boolean;
  445. { true if the procedure has a forward declaration }
  446. hasforward : boolean;
  447. { check the problems of manglednames }
  448. count : boolean;
  449. is_used : boolean;
  450. { small set which contains the modified registers }
  451. {$ifdef newcg}
  452. usedregisters : tregisterset;
  453. {$else newcg}
  454. usedregisters : longint;
  455. {$endif newcg}
  456. constructor init;
  457. constructor load;
  458. destructor done;virtual;
  459. procedure write;virtual;
  460. procedure deref;virtual;
  461. function getsymtable(t:tgetsymtable):psymtable;virtual;
  462. function haspara:boolean;
  463. function mangledname : string;
  464. procedure setmangledname(const s : string);
  465. procedure load_references;
  466. function write_references : boolean;
  467. function fullprocname:string;
  468. function cplusplusmangledname : string;
  469. { debug }
  470. {$ifdef GDB}
  471. function stabstring : pchar;virtual;
  472. procedure concatstabto(asmlist : paasmoutput);virtual;
  473. {$endif GDB}
  474. end;
  475. pstringdef = ^tstringdef;
  476. tstringdef = object(tstoreddef)
  477. string_typ : tstringtype;
  478. len : longint;
  479. constructor shortinit(l : byte);
  480. constructor shortload;
  481. constructor longinit(l : longint);
  482. constructor longload;
  483. constructor ansiinit(l : longint);
  484. constructor ansiload;
  485. constructor wideinit(l : longint);
  486. constructor wideload;
  487. function stringtypname:string;
  488. function size : longint;virtual;
  489. procedure write;virtual;
  490. function gettypename:string;virtual;
  491. function is_publishable : boolean;virtual;
  492. { debug }
  493. {$ifdef GDB}
  494. function stabstring : pchar;virtual;
  495. procedure concatstabto(asmlist : paasmoutput);virtual;
  496. {$endif GDB}
  497. { init/final }
  498. function needs_inittable : boolean;virtual;
  499. { rtti }
  500. procedure write_rtti_data;virtual;
  501. end;
  502. penumdef = ^tenumdef;
  503. tenumdef = object(tstoreddef)
  504. rangenr,
  505. minval,
  506. maxval : longint;
  507. has_jumps : boolean;
  508. firstenum : psym; {penumsym}
  509. basedef : penumdef;
  510. constructor init;
  511. constructor init_subrange(_basedef:penumdef;_min,_max:longint);
  512. constructor load;
  513. destructor done;virtual;
  514. procedure write;virtual;
  515. procedure deref;virtual;
  516. function gettypename:string;virtual;
  517. function is_publishable : boolean;virtual;
  518. procedure calcsavesize;
  519. procedure setmax(_max:longint);
  520. procedure setmin(_min:longint);
  521. function min:longint;
  522. function max:longint;
  523. function getrangecheckstring:string;
  524. procedure genrangecheck;
  525. { debug }
  526. {$ifdef GDB}
  527. function stabstring : pchar;virtual;
  528. {$endif GDB}
  529. { rtti }
  530. procedure write_child_rtti_data;virtual;
  531. procedure write_rtti_data;virtual;
  532. private
  533. procedure correct_owner_symtable;
  534. end;
  535. psetdef = ^tsetdef;
  536. tsetdef = object(tstoreddef)
  537. elementtype : ttype;
  538. settype : tsettype;
  539. constructor init(s : pdef;high : longint);
  540. constructor load;
  541. destructor done;virtual;
  542. procedure write;virtual;
  543. procedure deref;virtual;
  544. function gettypename:string;virtual;
  545. function is_publishable : boolean;virtual;
  546. { debug }
  547. {$ifdef GDB}
  548. function stabstring : pchar;virtual;
  549. procedure concatstabto(asmlist : paasmoutput);virtual;
  550. {$endif GDB}
  551. { rtti }
  552. procedure write_rtti_data;virtual;
  553. procedure write_child_rtti_data;virtual;
  554. end;
  555. var
  556. aktobjectdef : pobjectdef; { used for private functions check !! }
  557. firstglobaldef, { linked list of all globals defs }
  558. lastglobaldef : pstoreddef; { used to reset stabs/ranges }
  559. {$ifdef GDB}
  560. { for STAB debugging }
  561. globaltypecount : word;
  562. pglobaltypecount : pword;
  563. {$endif GDB}
  564. { default types }
  565. generrordef : pdef; { error in definition }
  566. voidpointerdef : ppointerdef; { pointer for Void-Pointerdef }
  567. charpointerdef : ppointerdef; { pointer for Char-Pointerdef }
  568. voidfarpointerdef : ppointerdef;
  569. cformaldef : pformaldef; { unique formal definition }
  570. voiddef : porddef; { Pointer to Void (procedure) }
  571. cchardef : porddef; { Pointer to Char }
  572. cwidechardef : porddef; { Pointer to WideChar }
  573. booldef : porddef; { pointer to boolean type }
  574. u8bitdef : porddef; { Pointer to 8-Bit unsigned }
  575. u16bitdef : porddef; { Pointer to 16-Bit unsigned }
  576. u32bitdef : porddef; { Pointer to 32-Bit unsigned }
  577. s32bitdef : porddef; { Pointer to 32-Bit signed }
  578. cu64bitdef : porddef; { pointer to 64 bit unsigned def }
  579. cs64bitdef : porddef; { pointer to 64 bit signed def, }
  580. { calculated by the int unit on i386 }
  581. s32floatdef : pfloatdef; { pointer for realconstn }
  582. s64floatdef : pfloatdef; { pointer for realconstn }
  583. s80floatdef : pfloatdef; { pointer to type of temp. floats }
  584. s32fixeddef : pfloatdef; { pointer to type of temp. fixed }
  585. cshortstringdef : pstringdef; { pointer to type of short string const }
  586. clongstringdef : pstringdef; { pointer to type of long string const }
  587. cansistringdef : pstringdef; { pointer to type of ansi string const }
  588. cwidestringdef : pstringdef; { pointer to type of wide string const }
  589. openshortstringdef : pstringdef; { pointer to type of an open shortstring,
  590. needed for readln() }
  591. openchararraydef : parraydef; { pointer to type of an open array of char,
  592. needed for readln() }
  593. cfiledef : pfiledef; { get the same definition for all file }
  594. { used for stabs }
  595. class_tobject : pobjectdef; { pointer to the anchestor of all classes }
  596. interface_iunknown : pobjectdef; { KAZ: pointer to the ancestor }
  597. rec_tguid : precorddef; { KAZ: pointer to the TGUID type }
  598. { of all interfaces }
  599. pvmtdef : ppointerdef; { type of classrefs }
  600. const
  601. {$ifdef i386}
  602. bestrealdef : ^pfloatdef = @s80floatdef;
  603. {$endif}
  604. {$ifdef m68k}
  605. bestrealdef : ^pfloatdef = @s64floatdef;
  606. {$endif}
  607. {$ifdef alpha}
  608. bestrealdef : ^pfloatdef = @s64floatdef;
  609. {$endif}
  610. {$ifdef powerpc}
  611. bestrealdef : ^pfloatdef = @s64floatdef;
  612. {$endif}
  613. {$ifdef GDB}
  614. { GDB Helpers }
  615. function typeglobalnumber(const s : string) : string;
  616. {$endif GDB}
  617. { should be in the types unit, but the types unit uses the node stuff :( }
  618. function is_interfacecom(def: pdef): boolean;
  619. function is_interfacecorba(def: pdef): boolean;
  620. function is_interface(def: pdef): boolean;
  621. function is_class(def: pdef): boolean;
  622. function is_object(def: pdef): boolean;
  623. function is_cppclass(def: pdef): boolean;
  624. function is_class_or_interface(def: pdef): boolean;
  625. procedure reset_global_defs;
  626. implementation
  627. uses
  628. {$ifdef Delphi}
  629. sysutils,
  630. {$else Delphi}
  631. strings,
  632. {$endif Delphi}
  633. { global }
  634. verbose,
  635. { target }
  636. systems,cpuinfo,
  637. { symtable }
  638. symsym,symtable,
  639. types,
  640. { ppu }
  641. ppu,symppu,
  642. { module }
  643. {$ifdef GDB}
  644. gdb,
  645. {$endif GDB}
  646. fmodule,
  647. { other }
  648. gendef
  649. ;
  650. const
  651. memsizeinc = 2048; { for long stabstrings }
  652. {****************************************************************************
  653. Helpers
  654. ****************************************************************************}
  655. {$ifdef GDB}
  656. procedure forcestabto(asmlist : paasmoutput; pd : pdef);
  657. begin
  658. if pstoreddef(pd)^.is_def_stab_written = not_written then
  659. begin
  660. if assigned(pd^.typesym) then
  661. ptypesym(pd^.typesym)^.isusedinstab := true;
  662. pstoreddef(pd)^.concatstabto(asmlist);
  663. end;
  664. end;
  665. {$endif GDB}
  666. {****************************************************************************
  667. TDEF (base class for definitions)
  668. ****************************************************************************}
  669. constructor tstoreddef.init;
  670. begin
  671. inherited init;
  672. savesize := 0;
  673. has_rtti:=false;
  674. has_inittable:=false;
  675. if registerdef then
  676. symtablestack^.registerdef(@self);
  677. {$ifdef GDB}
  678. is_def_stab_written := not_written;
  679. globalnb := 0;
  680. {$endif GDB}
  681. if assigned(lastglobaldef) then
  682. begin
  683. lastglobaldef^.nextglobal := @self;
  684. previousglobal:=lastglobaldef;
  685. end
  686. else
  687. begin
  688. firstglobaldef := @self;
  689. previousglobal := nil;
  690. end;
  691. lastglobaldef := @self;
  692. nextglobal := nil;
  693. end;
  694. {$ifdef MEMDEBUG}
  695. var
  696. manglenamesize : longint;
  697. {$endif}
  698. constructor tstoreddef.load;
  699. begin
  700. inherited init;
  701. has_rtti:=false;
  702. has_inittable:=false;
  703. {$ifdef GDB}
  704. is_def_stab_written := not_written;
  705. globalnb := 0;
  706. {$endif GDB}
  707. if assigned(lastglobaldef) then
  708. begin
  709. lastglobaldef^.nextglobal := @self;
  710. previousglobal:=lastglobaldef;
  711. end
  712. else
  713. begin
  714. firstglobaldef := @self;
  715. previousglobal:=nil;
  716. end;
  717. lastglobaldef := @self;
  718. nextglobal := nil;
  719. { load }
  720. indexnr:=readword;
  721. typesym:=ptypesym(readderef);
  722. end;
  723. destructor tstoreddef.done;
  724. begin
  725. { first element ? }
  726. if not(assigned(previousglobal)) then
  727. begin
  728. firstglobaldef := nextglobal;
  729. if assigned(firstglobaldef) then
  730. firstglobaldef^.previousglobal:=nil;
  731. end
  732. else
  733. begin
  734. { remove reference in the element before }
  735. previousglobal^.nextglobal:=nextglobal;
  736. end;
  737. { last element ? }
  738. if not(assigned(nextglobal)) then
  739. begin
  740. lastglobaldef := previousglobal;
  741. if assigned(lastglobaldef) then
  742. lastglobaldef^.nextglobal:=nil;
  743. end
  744. else
  745. nextglobal^.previousglobal:=previousglobal;
  746. previousglobal:=nil;
  747. nextglobal:=nil;
  748. {$ifdef SYNONYM}
  749. while assigned(typesym) do
  750. begin
  751. ptypesym(typesym)^.restype.setdef(nil);
  752. typesym:=ptypesym(typesym)^.synonym;
  753. end;
  754. {$endif}
  755. end;
  756. function tstoreddef.is_in_current : boolean;
  757. var
  758. p : psymtable;
  759. begin
  760. p:=owner;
  761. is_in_current:=false;
  762. while assigned(p) do
  763. begin
  764. if (p=current_module^.globalsymtable) or (p=current_module^.localsymtable)
  765. or (p^.symtabletype in [globalsymtable,staticsymtable]) then
  766. begin
  767. is_in_current:=true;
  768. exit;
  769. end
  770. else if p^.symtabletype in [localsymtable,parasymtable,objectsymtable] then
  771. begin
  772. if assigned(p^.defowner) then
  773. p:=pobjectdef(p^.defowner)^.owner
  774. else
  775. exit;
  776. end
  777. else
  778. exit;
  779. end;
  780. end;
  781. procedure tstoreddef.write;
  782. begin
  783. writeword(indexnr);
  784. writederef(typesym);
  785. {$ifdef GDB}
  786. if globalnb = 0 then
  787. begin
  788. if assigned(owner) then
  789. globalnb := owner^.getnewtypecount
  790. else
  791. begin
  792. globalnb := PGlobalTypeCount^;
  793. Inc(PGlobalTypeCount^);
  794. end;
  795. end;
  796. {$endif GDB}
  797. end;
  798. function tstoreddef.size : longint;
  799. begin
  800. size:=savesize;
  801. end;
  802. function tstoreddef.alignment : longint;
  803. begin
  804. { normal alignment by default }
  805. alignment:=0;
  806. end;
  807. {$ifdef GDB}
  808. procedure tstoreddef.set_globalnb;
  809. begin
  810. globalnb :=PGlobalTypeCount^;
  811. inc(PglobalTypeCount^);
  812. end;
  813. function tstoreddef.stabstring : pchar;
  814. begin
  815. stabstring := strpnew('t'+numberstring+';');
  816. end;
  817. function tstoreddef.numberstring : string;
  818. var table : psymtable;
  819. begin
  820. {formal def have no type !}
  821. if deftype = formaldef then
  822. begin
  823. numberstring := voiddef^.numberstring;
  824. exit;
  825. end;
  826. if (not assigned(typesym)) or (not ptypesym(typesym)^.isusedinstab) then
  827. begin
  828. {set even if debuglist is not defined}
  829. if assigned(typesym) then
  830. ptypesym(typesym)^.isusedinstab := true;
  831. if assigned(debuglist) and (is_def_stab_written = not_written) then
  832. concatstabto(debuglist);
  833. end;
  834. if not (cs_gdb_dbx in aktglobalswitches) then
  835. begin
  836. if globalnb = 0 then
  837. set_globalnb;
  838. numberstring := tostr(globalnb);
  839. end
  840. else
  841. begin
  842. if globalnb = 0 then
  843. begin
  844. if assigned(owner) then
  845. globalnb := owner^.getnewtypecount
  846. else
  847. begin
  848. globalnb := PGlobalTypeCount^;
  849. Inc(PGlobalTypeCount^);
  850. end;
  851. end;
  852. if assigned(typesym) then
  853. begin
  854. table := ptypesym(typesym)^.owner;
  855. if table^.unitid > 0 then
  856. numberstring := '('+tostr(table^.unitid)+','+tostr(pstoreddef(ptypesym(typesym)^.restype.def)^.globalnb)+')'
  857. else
  858. numberstring := tostr(globalnb);
  859. exit;
  860. end;
  861. numberstring := tostr(globalnb);
  862. end;
  863. end;
  864. function tstoreddef.allstabstring : pchar;
  865. var stabchar : string[2];
  866. ss,st : pchar;
  867. sname : string;
  868. sym_line_no : longint;
  869. begin
  870. ss := stabstring;
  871. getmem(st,strlen(ss)+512);
  872. stabchar := 't';
  873. if deftype in tagtypes then
  874. stabchar := 'Tt';
  875. if assigned(typesym) then
  876. begin
  877. sname := ptypesym(typesym)^.name;
  878. sym_line_no:=ptypesym(typesym)^.fileinfo.line;
  879. end
  880. else
  881. begin
  882. sname := ' ';
  883. sym_line_no:=0;
  884. end;
  885. strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
  886. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  887. allstabstring := strnew(st);
  888. freemem(st,strlen(ss)+512);
  889. strdispose(ss);
  890. end;
  891. procedure tstoreddef.concatstabto(asmlist : paasmoutput);
  892. var stab_str : pchar;
  893. begin
  894. if ((typesym = nil) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  895. and (is_def_stab_written = not_written) then
  896. begin
  897. If cs_gdb_dbx in aktglobalswitches then
  898. begin
  899. { otherwise you get two of each def }
  900. If assigned(typesym) then
  901. begin
  902. if ptypesym(typesym)^.typ=symconst.typesym then
  903. ptypesym(typesym)^.isusedinstab:=true;
  904. if (ptypesym(typesym)^.owner = nil) or
  905. ((ptypesym(typesym)^.owner^.symtabletype = unitsymtable) and
  906. punitsymtable(ptypesym(typesym)^.owner)^.dbx_count_ok) then
  907. begin
  908. {with DBX we get the definition from the other objects }
  909. is_def_stab_written := written;
  910. exit;
  911. end;
  912. end;
  913. end;
  914. { to avoid infinite loops }
  915. is_def_stab_written := being_written;
  916. stab_str := allstabstring;
  917. asmlist^.concat(new(pai_stabs,init(stab_str)));
  918. is_def_stab_written := written;
  919. end;
  920. end;
  921. {$endif GDB}
  922. { rtti generation }
  923. procedure tstoreddef.generate_rtti;
  924. begin
  925. if not has_rtti then
  926. begin
  927. has_rtti:=true;
  928. getdatalabel(rtti_label);
  929. write_child_rtti_data;
  930. rttilist^.concat(new(pai_symbol,init(rtti_label,0)));
  931. write_rtti_data;
  932. rttilist^.concat(new(pai_symbol_end,init(rtti_label)));
  933. end;
  934. end;
  935. function tstoreddef.get_rtti_label : string;
  936. begin
  937. generate_rtti;
  938. get_rtti_label:=rtti_label^.name;
  939. end;
  940. { init table handling }
  941. function tstoreddef.needs_inittable : boolean;
  942. begin
  943. needs_inittable:=false;
  944. end;
  945. procedure tstoreddef.generate_inittable;
  946. begin
  947. has_inittable:=true;
  948. getdatalabel(inittable_label);
  949. write_child_init_data;
  950. rttilist^.concat(new(pai_label,init(inittable_label)));
  951. write_init_data;
  952. end;
  953. procedure tstoreddef.write_init_data;
  954. begin
  955. write_rtti_data;
  956. end;
  957. procedure tstoreddef.write_child_init_data;
  958. begin
  959. write_child_rtti_data;
  960. end;
  961. function tstoreddef.get_inittable_label : pasmlabel;
  962. begin
  963. if not(has_inittable) then
  964. generate_inittable;
  965. get_inittable_label:=inittable_label;
  966. end;
  967. procedure tstoreddef.write_rtti_name;
  968. var
  969. str : string;
  970. begin
  971. { name }
  972. if assigned(typesym) then
  973. begin
  974. str:=ptypesym(typesym)^.realname;
  975. rttilist^.concat(new(pai_string,init(chr(length(str))+str)));
  976. end
  977. else
  978. rttilist^.concat(new(pai_string,init(#0)))
  979. end;
  980. { returns true, if the definition can be published }
  981. function tstoreddef.is_publishable : boolean;
  982. begin
  983. is_publishable:=false;
  984. end;
  985. procedure tstoreddef.write_rtti_data;
  986. begin
  987. end;
  988. procedure tstoreddef.write_child_rtti_data;
  989. begin
  990. end;
  991. function tstoreddef.is_intregable : boolean;
  992. begin
  993. is_intregable:=false;
  994. case deftype of
  995. pointerdef,
  996. enumdef,
  997. procvardef :
  998. is_intregable:=true;
  999. orddef :
  1000. case porddef(@self)^.typ of
  1001. bool8bit,bool16bit,bool32bit,
  1002. u8bit,u16bit,u32bit,
  1003. s8bit,s16bit,s32bit:
  1004. is_intregable:=true;
  1005. end;
  1006. setdef:
  1007. is_intregable:=(psetdef(@self)^.settype=smallset);
  1008. end;
  1009. end;
  1010. function tstoreddef.is_fpuregable : boolean;
  1011. begin
  1012. is_fpuregable:=(deftype=floatdef) and not(pfloatdef(@self)^.typ in [f32bit,f16bit]);
  1013. end;
  1014. {****************************************************************************
  1015. TPARALINKEDLIST
  1016. ****************************************************************************}
  1017. function tparalinkedlist.count:longint;
  1018. begin
  1019. { You must use tabstractprocdef.minparacount and .maxparacount instead }
  1020. internalerror(432432978);
  1021. count:=0;
  1022. end;
  1023. {****************************************************************************
  1024. TSTRINGDEF
  1025. ****************************************************************************}
  1026. constructor tstringdef.shortinit(l : byte);
  1027. begin
  1028. inherited init;
  1029. string_typ:=st_shortstring;
  1030. deftype:=stringdef;
  1031. len:=l;
  1032. savesize:=len+1;
  1033. end;
  1034. constructor tstringdef.shortload;
  1035. begin
  1036. inherited load;
  1037. string_typ:=st_shortstring;
  1038. deftype:=stringdef;
  1039. len:=readbyte;
  1040. savesize:=len+1;
  1041. end;
  1042. constructor tstringdef.longinit(l : longint);
  1043. begin
  1044. inherited init;
  1045. string_typ:=st_longstring;
  1046. deftype:=stringdef;
  1047. len:=l;
  1048. savesize:=target_os.size_of_pointer;
  1049. end;
  1050. constructor tstringdef.longload;
  1051. begin
  1052. inherited load;
  1053. deftype:=stringdef;
  1054. string_typ:=st_longstring;
  1055. len:=readlong;
  1056. savesize:=target_os.size_of_pointer;
  1057. end;
  1058. constructor tstringdef.ansiinit(l : longint);
  1059. begin
  1060. inherited init;
  1061. string_typ:=st_ansistring;
  1062. deftype:=stringdef;
  1063. len:=l;
  1064. savesize:=target_os.size_of_pointer;
  1065. end;
  1066. constructor tstringdef.ansiload;
  1067. begin
  1068. inherited load;
  1069. deftype:=stringdef;
  1070. string_typ:=st_ansistring;
  1071. len:=readlong;
  1072. savesize:=target_os.size_of_pointer;
  1073. end;
  1074. constructor tstringdef.wideinit(l : longint);
  1075. begin
  1076. inherited init;
  1077. string_typ:=st_widestring;
  1078. deftype:=stringdef;
  1079. len:=l;
  1080. savesize:=target_os.size_of_pointer;
  1081. end;
  1082. constructor tstringdef.wideload;
  1083. begin
  1084. inherited load;
  1085. deftype:=stringdef;
  1086. string_typ:=st_widestring;
  1087. len:=readlong;
  1088. savesize:=target_os.size_of_pointer;
  1089. end;
  1090. function tstringdef.stringtypname:string;
  1091. const
  1092. typname:array[tstringtype] of string[8]=('',
  1093. 'SHORTSTR','LONGSTR','ANSISTR','WIDESTR'
  1094. );
  1095. begin
  1096. stringtypname:=typname[string_typ];
  1097. end;
  1098. function tstringdef.size : longint;
  1099. begin
  1100. size:=savesize;
  1101. end;
  1102. procedure tstringdef.write;
  1103. begin
  1104. inherited write;
  1105. if string_typ=st_shortstring then
  1106. writebyte(len)
  1107. else
  1108. writelong(len);
  1109. case string_typ of
  1110. st_shortstring : current_ppu^.writeentry(ibshortstringdef);
  1111. st_longstring : current_ppu^.writeentry(iblongstringdef);
  1112. st_ansistring : current_ppu^.writeentry(ibansistringdef);
  1113. st_widestring : current_ppu^.writeentry(ibwidestringdef);
  1114. end;
  1115. end;
  1116. {$ifdef GDB}
  1117. function tstringdef.stabstring : pchar;
  1118. var
  1119. bytest,charst,longst : string;
  1120. begin
  1121. case string_typ of
  1122. st_shortstring:
  1123. begin
  1124. charst := typeglobalnumber('char');
  1125. { this is what I found in stabs.texinfo but
  1126. gdb 4.12 for go32 doesn't understand that !! }
  1127. {$IfDef GDBknowsstrings}
  1128. stabstring := strpnew('n'+charst+';'+tostr(len));
  1129. {$else}
  1130. bytest := typeglobalnumber('byte');
  1131. stabstring := strpnew('s'+tostr(len+1)+'length:'+bytest
  1132. +',0,8;st:ar'+bytest
  1133. +';1;'+tostr(len)+';'+charst+',8,'+tostr(len*8)+';;');
  1134. {$EndIf}
  1135. end;
  1136. st_longstring:
  1137. begin
  1138. charst := typeglobalnumber('char');
  1139. { this is what I found in stabs.texinfo but
  1140. gdb 4.12 for go32 doesn't understand that !! }
  1141. {$IfDef GDBknowsstrings}
  1142. stabstring := strpnew('n'+charst+';'+tostr(len));
  1143. {$else}
  1144. bytest := typeglobalnumber('byte');
  1145. longst := typeglobalnumber('longint');
  1146. stabstring := strpnew('s'+tostr(len+5)+'length:'+longst
  1147. +',0,32;dummy:'+bytest+',32,8;st:ar'+bytest
  1148. +';1;'+tostr(len)+';'+charst+',40,'+tostr(len*8)+';;');
  1149. {$EndIf}
  1150. end;
  1151. st_ansistring:
  1152. begin
  1153. { an ansi string looks like a pchar easy !! }
  1154. stabstring:=strpnew('*'+typeglobalnumber('char'));
  1155. end;
  1156. st_widestring:
  1157. begin
  1158. { an ansi string looks like a pchar easy !! }
  1159. stabstring:=strpnew('*'+typeglobalnumber('char'));
  1160. end;
  1161. end;
  1162. end;
  1163. procedure tstringdef.concatstabto(asmlist : paasmoutput);
  1164. begin
  1165. inherited concatstabto(asmlist);
  1166. end;
  1167. {$endif GDB}
  1168. function tstringdef.needs_inittable : boolean;
  1169. begin
  1170. needs_inittable:=string_typ in [st_ansistring,st_widestring];
  1171. end;
  1172. function tstringdef.gettypename : string;
  1173. const
  1174. names : array[tstringtype] of string[20] = ('',
  1175. 'ShortString','LongString','AnsiString','WideString');
  1176. begin
  1177. gettypename:=names[string_typ];
  1178. end;
  1179. procedure tstringdef.write_rtti_data;
  1180. begin
  1181. case string_typ of
  1182. st_ansistring:
  1183. begin
  1184. rttilist^.concat(new(pai_const,init_8bit(tkAString)));
  1185. write_rtti_name;
  1186. end;
  1187. st_widestring:
  1188. begin
  1189. rttilist^.concat(new(pai_const,init_8bit(tkWString)));
  1190. write_rtti_name;
  1191. end;
  1192. st_longstring:
  1193. begin
  1194. rttilist^.concat(new(pai_const,init_8bit(tkLString)));
  1195. write_rtti_name;
  1196. end;
  1197. st_shortstring:
  1198. begin
  1199. rttilist^.concat(new(pai_const,init_8bit(tkSString)));
  1200. write_rtti_name;
  1201. rttilist^.concat(new(pai_const,init_8bit(len)));
  1202. end;
  1203. end;
  1204. end;
  1205. function tstringdef.is_publishable : boolean;
  1206. begin
  1207. is_publishable:=true;
  1208. end;
  1209. {****************************************************************************
  1210. TENUMDEF
  1211. ****************************************************************************}
  1212. constructor tenumdef.init;
  1213. begin
  1214. inherited init;
  1215. deftype:=enumdef;
  1216. minval:=0;
  1217. maxval:=0;
  1218. calcsavesize;
  1219. has_jumps:=false;
  1220. basedef:=nil;
  1221. rangenr:=0;
  1222. firstenum:=nil;
  1223. correct_owner_symtable;
  1224. end;
  1225. constructor tenumdef.init_subrange(_basedef:penumdef;_min,_max:longint);
  1226. begin
  1227. inherited init;
  1228. deftype:=enumdef;
  1229. minval:=_min;
  1230. maxval:=_max;
  1231. basedef:=_basedef;
  1232. calcsavesize;
  1233. has_jumps:=false;
  1234. rangenr:=0;
  1235. firstenum:=basedef^.firstenum;
  1236. while assigned(firstenum) and (penumsym(firstenum)^.value<>minval) do
  1237. firstenum:=penumsym(firstenum)^.nextenum;
  1238. correct_owner_symtable;
  1239. end;
  1240. constructor tenumdef.load;
  1241. begin
  1242. inherited load;
  1243. deftype:=enumdef;
  1244. basedef:=penumdef(readderef);
  1245. minval:=readlong;
  1246. maxval:=readlong;
  1247. savesize:=readlong;
  1248. has_jumps:=false;
  1249. firstenum:=Nil;
  1250. end;
  1251. procedure tenumdef.calcsavesize;
  1252. begin
  1253. if (aktpackenum=4) or (min<0) or (max>65535) then
  1254. savesize:=4
  1255. else
  1256. if (aktpackenum=2) or (min<0) or (max>255) then
  1257. savesize:=2
  1258. else
  1259. savesize:=1;
  1260. end;
  1261. procedure tenumdef.setmax(_max:longint);
  1262. begin
  1263. maxval:=_max;
  1264. calcsavesize;
  1265. end;
  1266. procedure tenumdef.setmin(_min:longint);
  1267. begin
  1268. minval:=_min;
  1269. calcsavesize;
  1270. end;
  1271. function tenumdef.min:longint;
  1272. begin
  1273. min:=minval;
  1274. end;
  1275. function tenumdef.max:longint;
  1276. begin
  1277. max:=maxval;
  1278. end;
  1279. procedure tenumdef.deref;
  1280. begin
  1281. inherited deref;
  1282. resolvedef(pdef(basedef));
  1283. end;
  1284. destructor tenumdef.done;
  1285. begin
  1286. inherited done;
  1287. end;
  1288. procedure tenumdef.write;
  1289. begin
  1290. inherited write;
  1291. writederef(basedef);
  1292. writelong(min);
  1293. writelong(max);
  1294. writelong(savesize);
  1295. current_ppu^.writeentry(ibenumdef);
  1296. end;
  1297. function tenumdef.getrangecheckstring : string;
  1298. begin
  1299. if (cs_create_smart in aktmoduleswitches) then
  1300. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  1301. else
  1302. getrangecheckstring:='R_'+tostr(rangenr);
  1303. end;
  1304. procedure tenumdef.genrangecheck;
  1305. begin
  1306. if rangenr=0 then
  1307. begin
  1308. { generate two constant for bounds }
  1309. getlabelnr(rangenr);
  1310. if (cs_create_smart in aktmoduleswitches) then
  1311. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,8)))
  1312. else
  1313. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,8)));
  1314. datasegment^.concat(new(pai_const,init_32bit(min)));
  1315. datasegment^.concat(new(pai_const,init_32bit(max)));
  1316. end;
  1317. end;
  1318. { used for enumdef because the symbols are
  1319. inserted in the owner symtable }
  1320. procedure tenumdef.correct_owner_symtable;
  1321. var
  1322. st : psymtable;
  1323. begin
  1324. if assigned(owner) and
  1325. (owner^.symtabletype in [recordsymtable,objectsymtable]) then
  1326. begin
  1327. owner^.defindex^.deleteindex(@self);
  1328. st:=owner;
  1329. while (st^.symtabletype in [recordsymtable,objectsymtable]) do
  1330. st:=st^.next;
  1331. st^.registerdef(@self);
  1332. end;
  1333. end;
  1334. {$ifdef GDB}
  1335. function tenumdef.stabstring : pchar;
  1336. var st,st2 : pchar;
  1337. p : penumsym;
  1338. s : string;
  1339. memsize : word;
  1340. begin
  1341. memsize := memsizeinc;
  1342. getmem(st,memsize);
  1343. strpcopy(st,'e');
  1344. p := penumsym(firstenum);
  1345. while assigned(p) do
  1346. begin
  1347. s :=p^.name+':'+tostr(p^.value)+',';
  1348. { place for the ending ';' also }
  1349. if (strlen(st)+length(s)+1<memsize) then
  1350. strpcopy(strend(st),s)
  1351. else
  1352. begin
  1353. getmem(st2,memsize+memsizeinc);
  1354. strcopy(st2,st);
  1355. freemem(st,memsize);
  1356. st := st2;
  1357. memsize := memsize+memsizeinc;
  1358. strpcopy(strend(st),s);
  1359. end;
  1360. p := p^.nextenum;
  1361. end;
  1362. strpcopy(strend(st),';');
  1363. stabstring := strnew(st);
  1364. freemem(st,memsize);
  1365. end;
  1366. {$endif GDB}
  1367. procedure tenumdef.write_child_rtti_data;
  1368. begin
  1369. if assigned(basedef) then
  1370. basedef^.get_rtti_label;
  1371. end;
  1372. procedure tenumdef.write_rtti_data;
  1373. var
  1374. hp : penumsym;
  1375. begin
  1376. rttilist^.concat(new(pai_const,init_8bit(tkEnumeration)));
  1377. write_rtti_name;
  1378. case savesize of
  1379. 1:
  1380. rttilist^.concat(new(pai_const,init_8bit(otUByte)));
  1381. 2:
  1382. rttilist^.concat(new(pai_const,init_8bit(otUWord)));
  1383. 4:
  1384. rttilist^.concat(new(pai_const,init_8bit(otULong)));
  1385. end;
  1386. rttilist^.concat(new(pai_const,init_32bit(min)));
  1387. rttilist^.concat(new(pai_const,init_32bit(max)));
  1388. if assigned(basedef) then
  1389. rttilist^.concat(new(pai_const_symbol,initname(basedef^.get_rtti_label)))
  1390. else
  1391. rttilist^.concat(new(pai_const,init_32bit(0)));
  1392. hp:=penumsym(firstenum);
  1393. while assigned(hp) do
  1394. begin
  1395. rttilist^.concat(new(pai_const,init_8bit(length(hp^.name))));
  1396. rttilist^.concat(new(pai_string,init(lower(hp^.name))));
  1397. hp:=hp^.nextenum;
  1398. end;
  1399. rttilist^.concat(new(pai_const,init_8bit(0)));
  1400. end;
  1401. function tenumdef.is_publishable : boolean;
  1402. begin
  1403. is_publishable:=true;
  1404. end;
  1405. function tenumdef.gettypename : string;
  1406. begin
  1407. gettypename:='<enumeration type>';
  1408. end;
  1409. {****************************************************************************
  1410. TORDDEF
  1411. ****************************************************************************}
  1412. constructor torddef.init(t : tbasetype;v,b : longint);
  1413. begin
  1414. inherited init;
  1415. deftype:=orddef;
  1416. low:=v;
  1417. high:=b;
  1418. typ:=t;
  1419. rangenr:=0;
  1420. setsize;
  1421. end;
  1422. constructor torddef.load;
  1423. begin
  1424. inherited load;
  1425. deftype:=orddef;
  1426. typ:=tbasetype(readbyte);
  1427. low:=readlong;
  1428. high:=readlong;
  1429. rangenr:=0;
  1430. setsize;
  1431. end;
  1432. procedure torddef.setsize;
  1433. begin
  1434. if typ=uauto then
  1435. begin
  1436. { generate a unsigned range if high<0 and low>=0 }
  1437. if (low>=0) and (high<0) then
  1438. begin
  1439. savesize:=4;
  1440. typ:=u32bit;
  1441. end
  1442. else if (low>=0) and (high<=255) then
  1443. begin
  1444. savesize:=1;
  1445. typ:=u8bit;
  1446. end
  1447. else if (low>=-128) and (high<=127) then
  1448. begin
  1449. savesize:=1;
  1450. typ:=s8bit;
  1451. end
  1452. else if (low>=0) and (high<=65536) then
  1453. begin
  1454. savesize:=2;
  1455. typ:=u16bit;
  1456. end
  1457. else if (low>=-32768) and (high<=32767) then
  1458. begin
  1459. savesize:=2;
  1460. typ:=s16bit;
  1461. end
  1462. else
  1463. begin
  1464. savesize:=4;
  1465. typ:=s32bit;
  1466. end;
  1467. end
  1468. else
  1469. begin
  1470. case typ of
  1471. u8bit,s8bit,
  1472. uchar,bool8bit:
  1473. savesize:=1;
  1474. u16bit,s16bit,
  1475. bool16bit,uwidechar:
  1476. savesize:=2;
  1477. s32bit,u32bit,
  1478. bool32bit:
  1479. savesize:=4;
  1480. u64bit,s64bit:
  1481. savesize:=8;
  1482. else
  1483. savesize:=0;
  1484. end;
  1485. end;
  1486. { there are no entrys for range checking }
  1487. rangenr:=0;
  1488. end;
  1489. function torddef.getrangecheckstring : string;
  1490. begin
  1491. if (cs_create_smart in aktmoduleswitches) then
  1492. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  1493. else
  1494. getrangecheckstring:='R_'+tostr(rangenr);
  1495. end;
  1496. procedure torddef.genrangecheck;
  1497. var
  1498. rangechecksize : longint;
  1499. begin
  1500. if rangenr=0 then
  1501. begin
  1502. if low<=high then
  1503. rangechecksize:=8
  1504. else
  1505. rangechecksize:=16;
  1506. { generate two constant for bounds }
  1507. getlabelnr(rangenr);
  1508. if (cs_create_smart in aktmoduleswitches) then
  1509. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,rangechecksize)))
  1510. else
  1511. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,rangechecksize)));
  1512. if low<=high then
  1513. begin
  1514. datasegment^.concat(new(pai_const,init_32bit(low)));
  1515. datasegment^.concat(new(pai_const,init_32bit(high)));
  1516. end
  1517. { for u32bit we need two bounds }
  1518. else
  1519. begin
  1520. datasegment^.concat(new(pai_const,init_32bit(low)));
  1521. datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
  1522. datasegment^.concat(new(pai_const,init_32bit($80000000)));
  1523. datasegment^.concat(new(pai_const,init_32bit(high)));
  1524. end;
  1525. end;
  1526. end;
  1527. procedure torddef.write;
  1528. begin
  1529. inherited write;
  1530. writebyte(byte(typ));
  1531. writelong(low);
  1532. writelong(high);
  1533. current_ppu^.writeentry(iborddef);
  1534. end;
  1535. {$ifdef GDB}
  1536. function torddef.stabstring : pchar;
  1537. begin
  1538. case typ of
  1539. uvoid : stabstring := strpnew(numberstring+';');
  1540. {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
  1541. {$ifdef Use_integer_types_for_boolean}
  1542. bool8bit,
  1543. bool16bit,
  1544. bool32bit : stabstring := strpnew('r'+numberstring+';0;255;');
  1545. {$else : not Use_integer_types_for_boolean}
  1546. bool8bit : stabstring := strpnew('-21;');
  1547. bool16bit : stabstring := strpnew('-22;');
  1548. bool32bit : stabstring := strpnew('-23;');
  1549. u64bit : stabstring := strpnew('-32;');
  1550. s64bit : stabstring := strpnew('-31;');
  1551. {$endif not Use_integer_types_for_boolean}
  1552. { u32bit : stabstring := strpnew('r'+
  1553. s32bitdef^.numberstring+';0;-1;'); }
  1554. else
  1555. stabstring := strpnew('r'+s32bitdef^.numberstring+';'+tostr(low)+';'+tostr(high)+';');
  1556. end;
  1557. end;
  1558. {$endif GDB}
  1559. procedure torddef.write_rtti_data;
  1560. procedure dointeger;
  1561. const
  1562. trans : array[uchar..bool8bit] of byte =
  1563. (otUByte,otUByte,otUWord,otULong,otSByte,otSWord,otSLong,otUByte);
  1564. begin
  1565. write_rtti_name;
  1566. rttilist^.concat(new(pai_const,init_8bit(byte(trans[typ]))));
  1567. rttilist^.concat(new(pai_const,init_32bit(low)));
  1568. rttilist^.concat(new(pai_const,init_32bit(high)));
  1569. end;
  1570. begin
  1571. case typ of
  1572. s64bit :
  1573. begin
  1574. rttilist^.concat(new(pai_const,init_8bit(tkInt64)));
  1575. write_rtti_name;
  1576. { low }
  1577. rttilist^.concat(new(pai_const,init_32bit($0)));
  1578. rttilist^.concat(new(pai_const,init_32bit($8000)));
  1579. { high }
  1580. rttilist^.concat(new(pai_const,init_32bit($ffff)));
  1581. rttilist^.concat(new(pai_const,init_32bit($7fff)));
  1582. end;
  1583. u64bit :
  1584. begin
  1585. rttilist^.concat(new(pai_const,init_8bit(tkQWord)));
  1586. write_rtti_name;
  1587. { low }
  1588. rttilist^.concat(new(pai_const,init_32bit($0)));
  1589. rttilist^.concat(new(pai_const,init_32bit($0)));
  1590. { high }
  1591. rttilist^.concat(new(pai_const,init_32bit($0)));
  1592. rttilist^.concat(new(pai_const,init_32bit($8000)));
  1593. end;
  1594. bool8bit:
  1595. begin
  1596. rttilist^.concat(new(pai_const,init_8bit(tkBool)));
  1597. dointeger;
  1598. end;
  1599. uchar:
  1600. begin
  1601. rttilist^.concat(new(pai_const,init_8bit(tkWChar)));
  1602. dointeger;
  1603. end;
  1604. uwidechar:
  1605. begin
  1606. rttilist^.concat(new(pai_const,init_8bit(tkChar)));
  1607. dointeger;
  1608. end;
  1609. else
  1610. begin
  1611. rttilist^.concat(new(pai_const,init_8bit(tkInteger)));
  1612. dointeger;
  1613. end;
  1614. end;
  1615. end;
  1616. function torddef.is_publishable : boolean;
  1617. begin
  1618. is_publishable:=typ in [uchar..bool8bit];
  1619. end;
  1620. function torddef.gettypename : string;
  1621. const
  1622. names : array[tbasetype] of string[20] = ('<unknown type>',
  1623. 'untyped','Char','Byte','Word','DWord','ShortInt',
  1624. 'SmallInt','LongInt','Boolean','WordBool',
  1625. 'LongBool','QWord','Int64','WideChar');
  1626. begin
  1627. gettypename:=names[typ];
  1628. end;
  1629. {****************************************************************************
  1630. TFLOATDEF
  1631. ****************************************************************************}
  1632. constructor tfloatdef.init(t : tfloattype);
  1633. begin
  1634. inherited init;
  1635. deftype:=floatdef;
  1636. typ:=t;
  1637. setsize;
  1638. end;
  1639. constructor tfloatdef.load;
  1640. begin
  1641. inherited load;
  1642. deftype:=floatdef;
  1643. typ:=tfloattype(readbyte);
  1644. setsize;
  1645. end;
  1646. procedure tfloatdef.setsize;
  1647. begin
  1648. case typ of
  1649. f16bit : savesize:=2;
  1650. f32bit,
  1651. s32real : savesize:=4;
  1652. s64real : savesize:=8;
  1653. s80real : savesize:=extended_size;
  1654. s64comp : savesize:=8;
  1655. else
  1656. savesize:=0;
  1657. end;
  1658. end;
  1659. procedure tfloatdef.write;
  1660. begin
  1661. inherited write;
  1662. writebyte(byte(typ));
  1663. current_ppu^.writeentry(ibfloatdef);
  1664. end;
  1665. {$ifdef GDB}
  1666. function tfloatdef.stabstring : pchar;
  1667. begin
  1668. case typ of
  1669. s32real,
  1670. s64real : stabstring := strpnew('r'+
  1671. s32bitdef^.numberstring+';'+tostr(savesize)+';0;');
  1672. { for fixed real use longint instead to be able to }
  1673. { debug something at least }
  1674. f32bit:
  1675. stabstring := s32bitdef^.stabstring;
  1676. f16bit:
  1677. stabstring := strpnew('r'+s32bitdef^.numberstring+';0;'+
  1678. tostr($ffff)+';');
  1679. { found this solution in stabsread.c from GDB v4.16 }
  1680. s64comp : stabstring := strpnew('r'+
  1681. s32bitdef^.numberstring+';-'+tostr(savesize)+';0;');
  1682. {$ifdef i386}
  1683. { under dos at least you must give a size of twelve instead of 10 !! }
  1684. { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
  1685. s80real : stabstring := strpnew('r'+s32bitdef^.numberstring+';12;0;');
  1686. {$endif i386}
  1687. else
  1688. internalerror(10005);
  1689. end;
  1690. end;
  1691. {$endif GDB}
  1692. procedure tfloatdef.write_rtti_data;
  1693. const
  1694. {tfloattype = (s32real,s64real,s80real,s64bit,f16bit,f32bit);}
  1695. translate : array[tfloattype] of byte =
  1696. (ftSingle,ftDouble,ftExtended,ftComp,ftFixed16,ftFixed32);
  1697. begin
  1698. rttilist^.concat(new(pai_const,init_8bit(tkFloat)));
  1699. write_rtti_name;
  1700. rttilist^.concat(new(pai_const,init_8bit(translate[typ])));
  1701. end;
  1702. function tfloatdef.is_publishable : boolean;
  1703. begin
  1704. is_publishable:=true;
  1705. end;
  1706. function tfloatdef.gettypename : string;
  1707. const
  1708. names : array[tfloattype] of string[20] = (
  1709. 'Single','Double','Extended','Comp','Fixed','Fixed16');
  1710. begin
  1711. gettypename:=names[typ];
  1712. end;
  1713. {****************************************************************************
  1714. TFILEDEF
  1715. ****************************************************************************}
  1716. constructor tfiledef.inittext;
  1717. begin
  1718. inherited init;
  1719. deftype:=filedef;
  1720. filetyp:=ft_text;
  1721. typedfiletype.reset;
  1722. setsize;
  1723. end;
  1724. constructor tfiledef.inituntyped;
  1725. begin
  1726. inherited init;
  1727. deftype:=filedef;
  1728. filetyp:=ft_untyped;
  1729. typedfiletype.reset;
  1730. setsize;
  1731. end;
  1732. constructor tfiledef.inittyped(const tt : ttype);
  1733. begin
  1734. inherited init;
  1735. deftype:=filedef;
  1736. filetyp:=ft_typed;
  1737. typedfiletype:=tt;
  1738. setsize;
  1739. end;
  1740. constructor tfiledef.inittypeddef(p : pdef);
  1741. begin
  1742. inherited init;
  1743. deftype:=filedef;
  1744. filetyp:=ft_typed;
  1745. typedfiletype.setdef(p);
  1746. setsize;
  1747. end;
  1748. constructor tfiledef.load;
  1749. begin
  1750. inherited load;
  1751. deftype:=filedef;
  1752. filetyp:=tfiletyp(readbyte);
  1753. if filetyp=ft_typed then
  1754. typedfiletype.load
  1755. else
  1756. typedfiletype.reset;
  1757. setsize;
  1758. end;
  1759. procedure tfiledef.deref;
  1760. begin
  1761. inherited deref;
  1762. if filetyp=ft_typed then
  1763. typedfiletype.resolve;
  1764. end;
  1765. procedure tfiledef.setsize;
  1766. begin
  1767. case filetyp of
  1768. ft_text :
  1769. savesize:=572;
  1770. ft_typed,
  1771. ft_untyped :
  1772. savesize:=316;
  1773. end;
  1774. end;
  1775. procedure tfiledef.write;
  1776. begin
  1777. inherited write;
  1778. writebyte(byte(filetyp));
  1779. if filetyp=ft_typed then
  1780. typedfiletype.write;
  1781. current_ppu^.writeentry(ibfiledef);
  1782. end;
  1783. {$ifdef GDB}
  1784. function tfiledef.stabstring : pchar;
  1785. begin
  1786. {$IfDef GDBknowsfiles}
  1787. case filetyp of
  1788. ft_typed :
  1789. stabstring := strpnew('d'+typedfiletype.def^.numberstring{+';'});
  1790. ft_untyped :
  1791. stabstring := strpnew('d'+voiddef^.numberstring{+';'});
  1792. ft_text :
  1793. stabstring := strpnew('d'+cchardef^.numberstring{+';'});
  1794. end;
  1795. {$Else}
  1796. {based on
  1797. FileRec = Packed Record
  1798. Handle,
  1799. Mode,
  1800. RecSize : longint;
  1801. _private : array[1..32] of byte;
  1802. UserData : array[1..16] of byte;
  1803. name : array[0..255] of char;
  1804. End; }
  1805. { the buffer part is still missing !! (PM) }
  1806. { but the string could become too long !! }
  1807. stabstring := strpnew('s'+tostr(savesize)+
  1808. 'HANDLE:'+typeglobalnumber('longint')+',0,32;'+
  1809. 'MODE:'+typeglobalnumber('longint')+',32,32;'+
  1810. 'RECSIZE:'+typeglobalnumber('longint')+',64,32;'+
  1811. '_PRIVATE:ar'+typeglobalnumber('word')+';1;32;'+typeglobalnumber('byte')
  1812. +',96,256;'+
  1813. 'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')
  1814. +',352,128;'+
  1815. 'NAME:ar'+typeglobalnumber('word')+';0;255;'+typeglobalnumber('char')
  1816. +',480,2048;;');
  1817. {$EndIf}
  1818. end;
  1819. procedure tfiledef.concatstabto(asmlist : paasmoutput);
  1820. begin
  1821. { most file defs are unnamed !!! }
  1822. if ((typesym = nil) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1823. (is_def_stab_written = not_written) then
  1824. begin
  1825. if assigned(typedfiletype.def) then
  1826. forcestabto(asmlist,typedfiletype.def);
  1827. inherited concatstabto(asmlist);
  1828. end;
  1829. end;
  1830. {$endif GDB}
  1831. function tfiledef.gettypename : string;
  1832. begin
  1833. case filetyp of
  1834. ft_untyped:
  1835. gettypename:='File';
  1836. ft_typed:
  1837. gettypename:='File Of '+typedfiletype.def^.typename;
  1838. ft_text:
  1839. gettypename:='Text'
  1840. end;
  1841. end;
  1842. {****************************************************************************
  1843. TPOINTERDEF
  1844. ****************************************************************************}
  1845. constructor tpointerdef.init(const tt : ttype);
  1846. begin
  1847. inherited init;
  1848. deftype:=pointerdef;
  1849. pointertype:=tt;
  1850. is_far:=false;
  1851. savesize:=target_os.size_of_pointer;
  1852. end;
  1853. constructor tpointerdef.initfar(const tt : ttype);
  1854. begin
  1855. inherited init;
  1856. deftype:=pointerdef;
  1857. pointertype:=tt;
  1858. is_far:=true;
  1859. savesize:=target_os.size_of_pointer;
  1860. end;
  1861. constructor tpointerdef.initdef(p : pdef);
  1862. var
  1863. t : ttype;
  1864. begin
  1865. t.setdef(p);
  1866. tpointerdef.init(t);
  1867. end;
  1868. constructor tpointerdef.initfardef(p : pdef);
  1869. var
  1870. t : ttype;
  1871. begin
  1872. t.setdef(p);
  1873. tpointerdef.initfar(t);
  1874. end;
  1875. constructor tpointerdef.load;
  1876. begin
  1877. inherited load;
  1878. deftype:=pointerdef;
  1879. pointertype.load;
  1880. is_far:=(readbyte<>0);
  1881. savesize:=target_os.size_of_pointer;
  1882. end;
  1883. destructor tpointerdef.done;
  1884. begin
  1885. if assigned(pointertype.def) and
  1886. (pointertype.def^.deftype=forwarddef) then
  1887. begin
  1888. dispose(pointertype.def,done);
  1889. pointertype.reset;
  1890. end;
  1891. inherited done;
  1892. end;
  1893. procedure tpointerdef.deref;
  1894. begin
  1895. inherited deref;
  1896. pointertype.resolve;
  1897. end;
  1898. procedure tpointerdef.write;
  1899. begin
  1900. inherited write;
  1901. pointertype.write;
  1902. writebyte(byte(is_far));
  1903. current_ppu^.writeentry(ibpointerdef);
  1904. end;
  1905. {$ifdef GDB}
  1906. function tpointerdef.stabstring : pchar;
  1907. begin
  1908. stabstring := strpnew('*'+pstoreddef(pointertype.def)^.numberstring);
  1909. end;
  1910. procedure tpointerdef.concatstabto(asmlist : paasmoutput);
  1911. var st,nb : string;
  1912. sym_line_no : longint;
  1913. begin
  1914. if assigned(pointertype.def) and
  1915. (pointertype.def^.deftype=forwarddef) then
  1916. exit;
  1917. if ( (typesym=nil) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1918. (is_def_stab_written = not_written) then
  1919. begin
  1920. is_def_stab_written := being_written;
  1921. if assigned(pointertype.def) and
  1922. (pointertype.def^.deftype in [recorddef,objectdef]) then
  1923. begin
  1924. nb:=pstoreddef(pointertype.def)^.numberstring;
  1925. {to avoid infinite recursion in record with next-like fields }
  1926. if pstoreddef(pointertype.def)^.is_def_stab_written = being_written then
  1927. begin
  1928. if assigned(pointertype.def^.typesym) then
  1929. begin
  1930. if assigned(typesym) then
  1931. begin
  1932. st := ptypesym(typesym)^.name;
  1933. sym_line_no:=ptypesym(typesym)^.fileinfo.line;
  1934. end
  1935. else
  1936. begin
  1937. st := ' ';
  1938. sym_line_no:=0;
  1939. end;
  1940. st := '"'+st+':t'+numberstring+'=*'+nb
  1941. +'=xs'+pointertype.def^.typesym^.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
  1942. asmlist^.concat(new(pai_stabs,init(strpnew(st))));
  1943. end;
  1944. end
  1945. else
  1946. begin
  1947. is_def_stab_written := not_written;
  1948. inherited concatstabto(asmlist);
  1949. end;
  1950. is_def_stab_written := written;
  1951. end
  1952. else
  1953. begin
  1954. if assigned(pointertype.def) then
  1955. forcestabto(asmlist,pointertype.def);
  1956. is_def_stab_written := not_written;
  1957. inherited concatstabto(asmlist);
  1958. end;
  1959. end;
  1960. end;
  1961. {$endif GDB}
  1962. function tpointerdef.gettypename : string;
  1963. begin
  1964. gettypename:='^'+pointertype.def^.typename;
  1965. end;
  1966. {****************************************************************************
  1967. TCLASSREFDEF
  1968. ****************************************************************************}
  1969. constructor tclassrefdef.init(def : pdef);
  1970. begin
  1971. inherited initdef(def);
  1972. deftype:=classrefdef;
  1973. end;
  1974. constructor tclassrefdef.load;
  1975. begin
  1976. { be careful, tclassdefref inherits from tpointerdef }
  1977. tstoreddef.load;
  1978. deftype:=classrefdef;
  1979. pointertype.load;
  1980. is_far:=false;
  1981. savesize:=target_os.size_of_pointer;
  1982. end;
  1983. procedure tclassrefdef.write;
  1984. begin
  1985. { be careful, tclassdefref inherits from tpointerdef }
  1986. tstoreddef.write;
  1987. pointertype.write;
  1988. current_ppu^.writeentry(ibclassrefdef);
  1989. end;
  1990. {$ifdef GDB}
  1991. function tclassrefdef.stabstring : pchar;
  1992. begin
  1993. stabstring:=strpnew(pvmtdef^.numberstring+';');
  1994. end;
  1995. procedure tclassrefdef.concatstabto(asmlist : paasmoutput);
  1996. begin
  1997. inherited concatstabto(asmlist);
  1998. end;
  1999. {$endif GDB}
  2000. function tclassrefdef.gettypename : string;
  2001. begin
  2002. gettypename:='Class Of '+pointertype.def^.typename;
  2003. end;
  2004. {***************************************************************************
  2005. TSETDEF
  2006. ***************************************************************************}
  2007. { For i386 smallsets work,
  2008. for m68k there are problems
  2009. can be test by compiling with -dusesmallset PM }
  2010. {$ifdef i386}
  2011. {$define usesmallset}
  2012. {$endif i386}
  2013. constructor tsetdef.init(s : pdef;high : longint);
  2014. begin
  2015. inherited init;
  2016. deftype:=setdef;
  2017. elementtype.setdef(s);
  2018. {$ifdef usesmallset}
  2019. { small sets only working for i386 PM }
  2020. if high<32 then
  2021. begin
  2022. settype:=smallset;
  2023. {$ifdef testvarsets}
  2024. if aktsetalloc=0 THEN { $PACKSET Fixed?}
  2025. {$endif}
  2026. savesize:=Sizeof(longint)
  2027. {$ifdef testvarsets}
  2028. else {No, use $PACKSET VALUE for rounding}
  2029. savesize:=aktsetalloc*((high+aktsetalloc*8-1) DIV (aktsetalloc*8))
  2030. {$endif}
  2031. ;
  2032. end
  2033. else
  2034. {$endif usesmallset}
  2035. if high<256 then
  2036. begin
  2037. settype:=normset;
  2038. savesize:=32;
  2039. end
  2040. else
  2041. {$ifdef testvarsets}
  2042. if high<$10000 then
  2043. begin
  2044. settype:=varset;
  2045. savesize:=4*((high+31) div 32);
  2046. end
  2047. else
  2048. {$endif testvarsets}
  2049. Message(sym_e_ill_type_decl_set);
  2050. end;
  2051. constructor tsetdef.load;
  2052. begin
  2053. inherited load;
  2054. deftype:=setdef;
  2055. elementtype.load;
  2056. settype:=tsettype(readbyte);
  2057. case settype of
  2058. normset : savesize:=32;
  2059. varset : savesize:=readlong;
  2060. smallset : savesize:=Sizeof(longint);
  2061. end;
  2062. end;
  2063. destructor tsetdef.done;
  2064. begin
  2065. inherited done;
  2066. end;
  2067. procedure tsetdef.write;
  2068. begin
  2069. inherited write;
  2070. elementtype.write;
  2071. writebyte(byte(settype));
  2072. if settype=varset then
  2073. writelong(savesize);
  2074. current_ppu^.writeentry(ibsetdef);
  2075. end;
  2076. {$ifdef GDB}
  2077. function tsetdef.stabstring : pchar;
  2078. begin
  2079. { For small sets write a longint, which can at least be seen
  2080. in the current GDB's (PFV)
  2081. this is obsolete with GDBPAS !!
  2082. and anyhow creates problems with version 4.18!! PM
  2083. if settype=smallset then
  2084. stabstring := strpnew('r'+s32bitdef^.numberstring+';0;0xffffffff;')
  2085. else }
  2086. stabstring := strpnew('S'+pstoreddef(elementtype.def)^.numberstring);
  2087. end;
  2088. procedure tsetdef.concatstabto(asmlist : paasmoutput);
  2089. begin
  2090. if ( not assigned(typesym) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  2091. (is_def_stab_written = not_written) then
  2092. begin
  2093. if assigned(elementtype.def) then
  2094. forcestabto(asmlist,elementtype.def);
  2095. inherited concatstabto(asmlist);
  2096. end;
  2097. end;
  2098. {$endif GDB}
  2099. procedure tsetdef.deref;
  2100. begin
  2101. inherited deref;
  2102. elementtype.resolve;
  2103. end;
  2104. procedure tsetdef.write_rtti_data;
  2105. begin
  2106. rttilist^.concat(new(pai_const,init_8bit(tkSet)));
  2107. write_rtti_name;
  2108. rttilist^.concat(new(pai_const,init_8bit(otULong)));
  2109. rttilist^.concat(new(pai_const_symbol,initname(elementtype.def^.get_rtti_label)));
  2110. end;
  2111. procedure tsetdef.write_child_rtti_data;
  2112. begin
  2113. elementtype.def^.get_rtti_label;
  2114. end;
  2115. function tsetdef.is_publishable : boolean;
  2116. begin
  2117. is_publishable:=settype=smallset;
  2118. end;
  2119. function tsetdef.gettypename : string;
  2120. begin
  2121. if assigned(elementtype.def) then
  2122. gettypename:='Set Of '+elementtype.def^.typename
  2123. else
  2124. gettypename:='Empty Set';
  2125. end;
  2126. {***************************************************************************
  2127. TFORMALDEF
  2128. ***************************************************************************}
  2129. constructor tformaldef.init;
  2130. var
  2131. stregdef : boolean;
  2132. begin
  2133. stregdef:=registerdef;
  2134. registerdef:=false;
  2135. inherited init;
  2136. deftype:=formaldef;
  2137. registerdef:=stregdef;
  2138. { formaldef must be registered at unit level !! }
  2139. if registerdef and assigned(current_module) then
  2140. if assigned(current_module^.localsymtable) then
  2141. psymtable(current_module^.localsymtable)^.registerdef(@self)
  2142. else if assigned(current_module^.globalsymtable) then
  2143. psymtable(current_module^.globalsymtable)^.registerdef(@self);
  2144. savesize:=target_os.size_of_pointer;
  2145. end;
  2146. constructor tformaldef.load;
  2147. begin
  2148. inherited load;
  2149. deftype:=formaldef;
  2150. savesize:=target_os.size_of_pointer;
  2151. end;
  2152. procedure tformaldef.write;
  2153. begin
  2154. inherited write;
  2155. current_ppu^.writeentry(ibformaldef);
  2156. end;
  2157. {$ifdef GDB}
  2158. function tformaldef.stabstring : pchar;
  2159. begin
  2160. stabstring := strpnew('formal'+numberstring+';');
  2161. end;
  2162. procedure tformaldef.concatstabto(asmlist : paasmoutput);
  2163. begin
  2164. { formaldef can't be stab'ed !}
  2165. end;
  2166. {$endif GDB}
  2167. function tformaldef.gettypename : string;
  2168. begin
  2169. gettypename:='Var';
  2170. end;
  2171. {***************************************************************************
  2172. TARRAYDEF
  2173. ***************************************************************************}
  2174. constructor tarraydef.init(l,h : longint;rd : pdef);
  2175. begin
  2176. inherited init;
  2177. deftype:=arraydef;
  2178. lowrange:=l;
  2179. highrange:=h;
  2180. rangetype.setdef(rd);
  2181. elementtype.reset;
  2182. IsVariant:=false;
  2183. IsConstructor:=false;
  2184. IsArrayOfConst:=false;
  2185. IsDynamicArray:=false;
  2186. rangenr:=0;
  2187. end;
  2188. constructor tarraydef.load;
  2189. begin
  2190. inherited load;
  2191. deftype:=arraydef;
  2192. { the addresses are calculated later }
  2193. elementtype.load;
  2194. rangetype.load;
  2195. lowrange:=readlong;
  2196. highrange:=readlong;
  2197. IsArrayOfConst:=boolean(readbyte);
  2198. IsVariant:=false;
  2199. IsConstructor:=false;
  2200. IsDynamicArray:=false;
  2201. rangenr:=0;
  2202. end;
  2203. function tarraydef.getrangecheckstring : string;
  2204. begin
  2205. if (cs_create_smart in aktmoduleswitches) then
  2206. getrangecheckstring:='R_'+current_module^.modulename^+tostr(rangenr)
  2207. else
  2208. getrangecheckstring:='R_'+tostr(rangenr);
  2209. end;
  2210. procedure tarraydef.genrangecheck;
  2211. begin
  2212. if rangenr=0 then
  2213. begin
  2214. { generates the data for range checking }
  2215. getlabelnr(rangenr);
  2216. if (cs_create_smart in aktmoduleswitches) then
  2217. datasegment^.concat(new(pai_symbol,initname_global(getrangecheckstring,8)))
  2218. else
  2219. datasegment^.concat(new(pai_symbol,initname(getrangecheckstring,8)));
  2220. if lowrange<=highrange then
  2221. begin
  2222. datasegment^.concat(new(pai_const,init_32bit(lowrange)));
  2223. datasegment^.concat(new(pai_const,init_32bit(highrange)));
  2224. end
  2225. { for big arrays we need two bounds }
  2226. else
  2227. begin
  2228. datasegment^.concat(new(pai_const,init_32bit(lowrange)));
  2229. datasegment^.concat(new(pai_const,init_32bit($7fffffff)));
  2230. datasegment^.concat(new(pai_const,init_32bit($80000000)));
  2231. datasegment^.concat(new(pai_const,init_32bit(highrange)));
  2232. end;
  2233. end;
  2234. end;
  2235. procedure tarraydef.deref;
  2236. begin
  2237. inherited deref;
  2238. elementtype.resolve;
  2239. rangetype.resolve;
  2240. end;
  2241. procedure tarraydef.write;
  2242. begin
  2243. inherited write;
  2244. elementtype.write;
  2245. rangetype.write;
  2246. writelong(lowrange);
  2247. writelong(highrange);
  2248. writebyte(byte(IsArrayOfConst));
  2249. current_ppu^.writeentry(ibarraydef);
  2250. end;
  2251. {$ifdef GDB}
  2252. function tarraydef.stabstring : pchar;
  2253. begin
  2254. stabstring := strpnew('ar'+pstoreddef(rangetype.def)^.numberstring+';'
  2255. +tostr(lowrange)+';'+tostr(highrange)+';'+pstoreddef(elementtype.def)^.numberstring);
  2256. end;
  2257. procedure tarraydef.concatstabto(asmlist : paasmoutput);
  2258. begin
  2259. if (not assigned(typesym) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2260. and (is_def_stab_written = not_written) then
  2261. begin
  2262. {when array are inserted they have no definition yet !!}
  2263. if assigned(elementtype.def) then
  2264. inherited concatstabto(asmlist);
  2265. end;
  2266. end;
  2267. {$endif GDB}
  2268. function tarraydef.elesize : longint;
  2269. begin
  2270. if ((lowrange=0) and
  2271. (highrange=-1) and
  2272. (not IsArrayOfConst) and
  2273. (not IsVariant) and
  2274. (not IsDynamicArray)) or
  2275. IsConstructor then
  2276. begin
  2277. { strings are stored by address only }
  2278. case elementtype.def^.deftype of
  2279. stringdef :
  2280. elesize:=4;
  2281. else
  2282. elesize:=elementtype.def^.size;
  2283. end;
  2284. end
  2285. else
  2286. elesize:=elementtype.def^.size;
  2287. end;
  2288. function tarraydef.size : longint;
  2289. begin
  2290. if IsDynamicArray then
  2291. begin
  2292. size:=4;
  2293. exit;
  2294. end;
  2295. {Tarraydef.size may never be called for an open array!}
  2296. if highrange<lowrange then
  2297. internalerror(99080501);
  2298. If (elesize>0) and
  2299. (
  2300. (highrange-lowrange = $7fffffff) or
  2301. { () are needed around elesize-1 to avoid a possible
  2302. integer overflow for elesize=1 !! PM }
  2303. (($7fffffff div elesize + (elesize -1)) < (highrange - lowrange))
  2304. ) Then
  2305. Begin
  2306. Message(sym_e_segment_too_large);
  2307. size := 4
  2308. End
  2309. Else size:=(highrange-lowrange+1)*elesize;
  2310. end;
  2311. function tarraydef.alignment : longint;
  2312. begin
  2313. { alignment is the size of the elements }
  2314. if elementtype.def^.deftype=recorddef then
  2315. alignment:=elementtype.def^.alignment
  2316. else
  2317. alignment:=elesize;
  2318. end;
  2319. function tarraydef.needs_inittable : boolean;
  2320. begin
  2321. needs_inittable:=IsDynamicArray or elementtype.def^.needs_inittable;
  2322. end;
  2323. procedure tarraydef.write_child_rtti_data;
  2324. begin
  2325. elementtype.def^.get_rtti_label;
  2326. end;
  2327. procedure tarraydef.write_rtti_data;
  2328. begin
  2329. if IsDynamicArray then
  2330. rttilist^.concat(new(pai_const,init_8bit(tkdynarray)))
  2331. else
  2332. rttilist^.concat(new(pai_const,init_8bit(tkarray)));
  2333. write_rtti_name;
  2334. { size of elements }
  2335. rttilist^.concat(new(pai_const,init_32bit(elesize)));
  2336. { count of elements }
  2337. if not(IsDynamicArray) then
  2338. rttilist^.concat(new(pai_const,init_32bit(highrange-lowrange+1)));
  2339. { element type }
  2340. rttilist^.concat(new(pai_const_symbol,initname(elementtype.def^.get_rtti_label)));
  2341. { variant type }
  2342. // !!!!!!!!!!!!!!!!
  2343. end;
  2344. function tarraydef.gettypename : string;
  2345. begin
  2346. if isarrayofconst or isConstructor then
  2347. begin
  2348. if isvariant or ((highrange=-1) and (lowrange=0)) then
  2349. gettypename:='Array Of Const'
  2350. else
  2351. gettypename:='Array Of '+elementtype.def^.typename;
  2352. end
  2353. else if ((highrange=-1) and (lowrange=0)) or IsDynamicArray then
  2354. gettypename:='Array Of '+elementtype.def^.typename
  2355. else
  2356. begin
  2357. if rangetype.def^.deftype=enumdef then
  2358. gettypename:='Array['+rangetype.def^.typename+'] Of '+elementtype.def^.typename
  2359. else
  2360. gettypename:='Array['+tostr(lowrange)+'..'+
  2361. tostr(highrange)+'] Of '+elementtype.def^.typename
  2362. end;
  2363. end;
  2364. {***************************************************************************
  2365. trecorddef
  2366. ***************************************************************************}
  2367. constructor trecorddef.init(p : psymtable);
  2368. begin
  2369. inherited init;
  2370. deftype:=recorddef;
  2371. symtable:=p;
  2372. symtable^.defowner := @self;
  2373. symtable^.dataalignment:=packrecordalignment[aktpackrecords];
  2374. end;
  2375. constructor trecorddef.load;
  2376. var
  2377. oldread_member : boolean;
  2378. begin
  2379. inherited load;
  2380. deftype:=recorddef;
  2381. savesize:=readlong;
  2382. oldread_member:=read_member;
  2383. read_member:=true;
  2384. symtable:=new(pstoredsymtable,loadas(recordsymtable));
  2385. read_member:=oldread_member;
  2386. symtable^.defowner := @self;
  2387. end;
  2388. destructor trecorddef.done;
  2389. begin
  2390. if assigned(symtable) then
  2391. dispose(symtable,done);
  2392. inherited done;
  2393. end;
  2394. function trecorddef.getsymtable(t:tgetsymtable):psymtable;
  2395. begin
  2396. if t=gs_record then
  2397. getsymtable:=symtable
  2398. else
  2399. getsymtable:=nil;
  2400. end;
  2401. var
  2402. binittable : boolean;
  2403. procedure check_rec_inittable(s : pnamedindexobject);
  2404. begin
  2405. if (not binittable) and
  2406. (psym(s)^.typ=varsym) and
  2407. assigned(pvarsym(s)^.vartype.def) then
  2408. begin
  2409. if (pvarsym(s)^.vartype.def^.deftype<>objectdef) or
  2410. not(is_class(pdef(pvarsym(s)^.vartype.def))) then
  2411. binittable:=pvarsym(s)^.vartype.def^.needs_inittable;
  2412. end;
  2413. end;
  2414. function trecorddef.needs_inittable : boolean;
  2415. var
  2416. oldb : boolean;
  2417. begin
  2418. { there are recursive calls to needs_rtti possible, }
  2419. { so we have to change to old value how else should }
  2420. { we do that ? check_rec_rtti can't be a nested }
  2421. { procedure of needs_rtti ! }
  2422. oldb:=binittable;
  2423. binittable:=false;
  2424. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}check_rec_inittable);
  2425. needs_inittable:=binittable;
  2426. binittable:=oldb;
  2427. end;
  2428. procedure trecorddef.deref;
  2429. var
  2430. oldrecsyms : psymtable;
  2431. begin
  2432. inherited deref;
  2433. oldrecsyms:=aktrecordsymtable;
  2434. aktrecordsymtable:=symtable;
  2435. { now dereference the definitions }
  2436. pstoredsymtable(symtable)^.deref;
  2437. aktrecordsymtable:=oldrecsyms;
  2438. end;
  2439. procedure trecorddef.write;
  2440. var
  2441. oldread_member : boolean;
  2442. begin
  2443. oldread_member:=read_member;
  2444. read_member:=true;
  2445. inherited write;
  2446. writelong(savesize);
  2447. current_ppu^.writeentry(ibrecorddef);
  2448. pstoredsymtable(symtable)^.writeas;
  2449. read_member:=oldread_member;
  2450. end;
  2451. function trecorddef.size:longint;
  2452. begin
  2453. size:=symtable^.datasize;
  2454. end;
  2455. function trecorddef.alignment:longint;
  2456. var
  2457. l : longint;
  2458. hp : pvarsym;
  2459. begin
  2460. { also check the first symbol for it's size, because a
  2461. packed record has dataalignment of 1, but the first
  2462. sym could be a longint which should be aligned on 4 bytes,
  2463. this is compatible with C record packing (PFV) }
  2464. hp:=pvarsym(symtable^.symindex^.first);
  2465. if assigned(hp) then
  2466. begin
  2467. l:=hp^.vartype.def^.size;
  2468. if l>symtable^.dataalignment then
  2469. begin
  2470. if l>=4 then
  2471. alignment:=4
  2472. else
  2473. if l>=2 then
  2474. alignment:=2
  2475. else
  2476. alignment:=1;
  2477. end
  2478. else
  2479. alignment:=symtable^.dataalignment;
  2480. end
  2481. else
  2482. alignment:=symtable^.dataalignment;
  2483. end;
  2484. {$ifdef GDB}
  2485. Const StabRecString : pchar = Nil;
  2486. StabRecSize : longint = 0;
  2487. {RecOffset : Longint = 0;}
  2488. procedure addname(p : pnamedindexobject);
  2489. var
  2490. news, newrec : pchar;
  2491. spec : string[3];
  2492. size : longint;
  2493. begin
  2494. { static variables from objects are like global objects }
  2495. if (sp_static in psym(p)^.symoptions) then
  2496. exit;
  2497. If psym(p)^.typ = varsym then
  2498. begin
  2499. if (sp_protected in psym(p)^.symoptions) then
  2500. spec:='/1'
  2501. else if (sp_private in psym(p)^.symoptions) then
  2502. spec:='/0'
  2503. else
  2504. spec:='';
  2505. if not assigned(pvarsym(p)^.vartype.def) then
  2506. writeln(pvarsym(p)^.name);
  2507. { class fields are pointers PM, obsolete now PM }
  2508. {if (pvarsym(p)^.vartype.def^.deftype=objectdef) and
  2509. pobjectdef(pvarsym(p)^.vartype.def)^.is_class then
  2510. spec:=spec+'*'; }
  2511. size:=pvarsym(p)^.vartype.def^.size;
  2512. { open arrays made overflows !! }
  2513. if size>$fffffff then
  2514. size:=$fffffff;
  2515. newrec := strpnew(p^.name+':'+spec+pstoreddef(pvarsym(p)^.vartype.def)^.numberstring
  2516. +','+tostr(pvarsym(p)^.address*8)+','
  2517. +tostr(size*8)+';');
  2518. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  2519. begin
  2520. getmem(news,stabrecsize+memsizeinc);
  2521. strcopy(news,stabrecstring);
  2522. freemem(stabrecstring,stabrecsize);
  2523. stabrecsize:=stabrecsize+memsizeinc;
  2524. stabrecstring:=news;
  2525. end;
  2526. strcat(StabRecstring,newrec);
  2527. strdispose(newrec);
  2528. {This should be used for case !!
  2529. RecOffset := RecOffset + pvarsym(p)^.vartype.def^.size;}
  2530. end;
  2531. end;
  2532. function trecorddef.stabstring : pchar;
  2533. Var oldrec : pchar;
  2534. oldsize : longint;
  2535. begin
  2536. oldrec := stabrecstring;
  2537. oldsize:=stabrecsize;
  2538. GetMem(stabrecstring,memsizeinc);
  2539. stabrecsize:=memsizeinc;
  2540. strpcopy(stabRecString,'s'+tostr(size));
  2541. {RecOffset := 0;}
  2542. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}addname);
  2543. { FPC doesn't want to convert a char to a pchar}
  2544. { is this a bug ? }
  2545. strpcopy(strend(StabRecString),';');
  2546. stabstring := strnew(StabRecString);
  2547. Freemem(stabrecstring,stabrecsize);
  2548. stabrecstring := oldrec;
  2549. stabrecsize:=oldsize;
  2550. end;
  2551. procedure trecorddef.concatstabto(asmlist : paasmoutput);
  2552. begin
  2553. if (not assigned(typesym) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  2554. (is_def_stab_written = not_written) then
  2555. inherited concatstabto(asmlist);
  2556. end;
  2557. {$endif GDB}
  2558. var
  2559. count : longint;
  2560. procedure count_inittable_fields(sym : pnamedindexobject);
  2561. begin
  2562. if ((psym(sym)^.typ=varsym) and
  2563. pvarsym(sym)^.vartype.def^.needs_inittable) {and
  2564. (pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
  2565. not(is_class(pdef(pvarsym(sym)^.vartype.def)))} then
  2566. inc(count);
  2567. end;
  2568. procedure count_fields(sym : pnamedindexobject);
  2569. begin
  2570. inc(count);
  2571. end;
  2572. procedure write_field_inittable(sym : pnamedindexobject);
  2573. begin
  2574. if ((psym(sym)^.typ=varsym) and
  2575. pvarsym(sym)^.vartype.def^.needs_inittable) and
  2576. ((pvarsym(sym)^.vartype.def^.deftype<>objectdef) or
  2577. not(is_class(pvarsym(sym)^.vartype.def))) then
  2578. begin
  2579. rttilist^.concat(new(pai_const_symbol,init(pstoreddef(pvarsym(sym)^.vartype.def)^.get_inittable_label)));
  2580. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  2581. end;
  2582. end;
  2583. procedure write_field_rtti(sym : pnamedindexobject);
  2584. begin
  2585. rttilist^.concat(new(pai_const_symbol,initname(pvarsym(sym)^.vartype.def^.get_rtti_label)));
  2586. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  2587. end;
  2588. procedure generate_child_inittable(sym:pnamedindexobject);
  2589. begin
  2590. if (psym(sym)^.typ=varsym) and
  2591. pvarsym(sym)^.vartype.def^.needs_inittable then
  2592. { force inittable generation }
  2593. pstoreddef(pvarsym(sym)^.vartype.def)^.get_inittable_label;
  2594. end;
  2595. procedure generate_child_rtti(sym : pnamedindexobject);
  2596. begin
  2597. pvarsym(sym)^.vartype.def^.get_rtti_label;
  2598. end;
  2599. procedure trecorddef.write_child_rtti_data;
  2600. begin
  2601. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}generate_child_rtti);
  2602. end;
  2603. procedure trecorddef.write_child_init_data;
  2604. begin
  2605. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}generate_child_inittable);
  2606. end;
  2607. procedure trecorddef.write_rtti_data;
  2608. begin
  2609. rttilist^.concat(new(pai_const,init_8bit(tkrecord)));
  2610. write_rtti_name;
  2611. rttilist^.concat(new(pai_const,init_32bit(size)));
  2612. count:=0;
  2613. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_fields);
  2614. rttilist^.concat(new(pai_const,init_32bit(count)));
  2615. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti);
  2616. end;
  2617. procedure trecorddef.write_init_data;
  2618. begin
  2619. rttilist^.concat(new(pai_const,init_8bit(tkrecord)));
  2620. write_rtti_name;
  2621. rttilist^.concat(new(pai_const,init_32bit(size)));
  2622. count:=0;
  2623. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_inittable_fields);
  2624. rttilist^.concat(new(pai_const,init_32bit(count)));
  2625. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_inittable);
  2626. end;
  2627. function trecorddef.gettypename : string;
  2628. begin
  2629. gettypename:='<record type>'
  2630. end;
  2631. {***************************************************************************
  2632. TABSTRACTPROCDEF
  2633. ***************************************************************************}
  2634. constructor tabstractprocdef.init;
  2635. begin
  2636. inherited init;
  2637. new(para,init);
  2638. minparacount:=0;
  2639. maxparacount:=0;
  2640. fpu_used:=0;
  2641. proctypeoption:=potype_none;
  2642. proccalloptions:=[];
  2643. procoptions:=[];
  2644. rettype.setdef(voiddef);
  2645. symtablelevel:=0;
  2646. savesize:=target_os.size_of_pointer;
  2647. end;
  2648. destructor tabstractprocdef.done;
  2649. begin
  2650. dispose(para,done);
  2651. inherited done;
  2652. end;
  2653. procedure tabstractprocdef.concatpara(tt:ttype;vsp : tvarspez;defval:psym);
  2654. var
  2655. hp : pparaitem;
  2656. begin
  2657. new(hp,init);
  2658. hp^.paratyp:=vsp;
  2659. hp^.paratype:=tt;
  2660. hp^.register:=R_NO;
  2661. hp^.defaultvalue:=defval;
  2662. para^.insert(hp);
  2663. if not assigned(defval) then
  2664. inc(minparacount);
  2665. inc(maxparacount);
  2666. end;
  2667. { all functions returning in FPU are
  2668. assume to use 2 FPU registers
  2669. until the function implementation
  2670. is processed PM }
  2671. procedure tabstractprocdef.test_if_fpu_result;
  2672. begin
  2673. if assigned(rettype.def) and
  2674. (rettype.def^.deftype=floatdef) and
  2675. (pfloatdef(rettype.def)^.typ<>f32bit) then
  2676. fpu_used:=2;
  2677. end;
  2678. procedure tabstractprocdef.deref;
  2679. var
  2680. hp : pparaitem;
  2681. begin
  2682. inherited deref;
  2683. rettype.resolve;
  2684. hp:=pparaitem(para^.first);
  2685. while assigned(hp) do
  2686. begin
  2687. hp^.paratype.resolve;
  2688. resolvesym(psym(hp^.defaultvalue));
  2689. hp:=pparaitem(hp^.next);
  2690. end;
  2691. end;
  2692. constructor tabstractprocdef.load;
  2693. var
  2694. hp : pparaitem;
  2695. count,i : word;
  2696. begin
  2697. inherited load;
  2698. new(para,init);
  2699. minparacount:=0;
  2700. maxparacount:=0;
  2701. rettype.load;
  2702. fpu_used:=readbyte;
  2703. proctypeoption:=tproctypeoption(readlong);
  2704. readsmallset(proccalloptions);
  2705. readsmallset(procoptions);
  2706. count:=readword;
  2707. savesize:=target_os.size_of_pointer;
  2708. for i:=1 to count do
  2709. begin
  2710. new(hp,init);
  2711. hp^.paratyp:=tvarspez(readbyte);
  2712. { hp^.register:=tregister(readbyte); }
  2713. hp^.register:=R_NO;
  2714. hp^.paratype.load;
  2715. hp^.defaultvalue:=psym(readderef);
  2716. if not assigned(hp^.defaultvalue) then
  2717. inc(minparacount);
  2718. inc(maxparacount);
  2719. para^.concat(hp);
  2720. end;
  2721. end;
  2722. procedure tabstractprocdef.write;
  2723. var
  2724. hp : pparaitem;
  2725. oldintfcrc : boolean;
  2726. begin
  2727. inherited write;
  2728. rettype.write;
  2729. oldintfcrc:=current_ppu^.do_interface_crc;
  2730. current_ppu^.do_interface_crc:=false;
  2731. writebyte(fpu_used);
  2732. writelong(ord(proctypeoption));
  2733. writesmallset(proccalloptions);
  2734. writesmallset(procoptions);
  2735. current_ppu^.do_interface_crc:=oldintfcrc;
  2736. writeword(maxparacount);
  2737. hp:=pparaitem(para^.first);
  2738. while assigned(hp) do
  2739. begin
  2740. writebyte(byte(hp^.paratyp));
  2741. { writebyte(byte(hp^.register)); }
  2742. hp^.paratype.write;
  2743. writederef(hp^.defaultvalue);
  2744. hp:=pparaitem(hp^.next);
  2745. end;
  2746. end;
  2747. function tabstractprocdef.para_size(alignsize:longint) : longint;
  2748. var
  2749. pdc : pparaitem;
  2750. l : longint;
  2751. begin
  2752. l:=0;
  2753. pdc:=pparaitem(para^.first);
  2754. while assigned(pdc) do
  2755. begin
  2756. case pdc^.paratyp of
  2757. vs_out,
  2758. vs_var : inc(l,target_os.size_of_pointer);
  2759. vs_value,
  2760. vs_const : if push_addr_param(pdc^.paratype.def) then
  2761. inc(l,target_os.size_of_pointer)
  2762. else
  2763. inc(l,pdc^.paratype.def^.size);
  2764. end;
  2765. l:=align(l,alignsize);
  2766. pdc:=pparaitem(pdc^.next);
  2767. end;
  2768. para_size:=l;
  2769. end;
  2770. function tabstractprocdef.demangled_paras : string;
  2771. var
  2772. hs,s : string;
  2773. hp : pparaitem;
  2774. hpc : pconstsym;
  2775. begin
  2776. s:='(';
  2777. hp:=pparaitem(para^.last);
  2778. while assigned(hp) do
  2779. begin
  2780. if assigned(hp^.paratype.def^.typesym) then
  2781. s:=s+hp^.paratype.def^.typesym^.realname
  2782. else if hp^.paratyp=vs_var then
  2783. s:=s+'var'
  2784. else if hp^.paratyp=vs_const then
  2785. s:=s+'const'
  2786. else if hp^.paratyp=vs_out then
  2787. s:=s+'out';
  2788. { default value }
  2789. if assigned(hp^.defaultvalue) then
  2790. begin
  2791. hpc:=pconstsym(hp^.defaultvalue);
  2792. hs:='';
  2793. case hpc^.consttyp of
  2794. conststring,
  2795. constresourcestring :
  2796. hs:=strpas(pchar(tpointerord(hpc^.value)));
  2797. constreal :
  2798. str(pbestreal(tpointerord(hpc^.value))^,hs);
  2799. constord,
  2800. constpointer :
  2801. hs:=tostr(hpc^.value);
  2802. constbool :
  2803. begin
  2804. if hpc^.value<>0 then
  2805. hs:='TRUE'
  2806. else
  2807. hs:='FALSE';
  2808. end;
  2809. constnil :
  2810. hs:='nil';
  2811. constchar :
  2812. hs:=chr(hpc^.value);
  2813. constset :
  2814. hs:='<set>';
  2815. end;
  2816. if hs<>'' then
  2817. s:=s+'="'+hs+'"';
  2818. end;
  2819. hp:=pparaitem(hp^.previous);
  2820. if assigned(hp) then
  2821. s:=s+',';
  2822. end;
  2823. s:=s+')';
  2824. demangled_paras:=s;
  2825. end;
  2826. function tabstractprocdef.proccalloption2str : string;
  2827. type
  2828. tproccallopt=record
  2829. mask : tproccalloption;
  2830. str : string[30];
  2831. end;
  2832. const
  2833. proccallopts=13;
  2834. proccallopt : array[1..proccallopts] of tproccallopt=(
  2835. (mask:pocall_none; str:''),
  2836. (mask:pocall_clearstack; str:'ClearStack'),
  2837. (mask:pocall_leftright; str:'LeftRight'),
  2838. (mask:pocall_cdecl; str:'CDecl'),
  2839. (mask:pocall_register; str:'Register'),
  2840. (mask:pocall_stdcall; str:'StdCall'),
  2841. (mask:pocall_safecall; str:'SafeCall'),
  2842. (mask:pocall_palmossyscall;str:'PalmOSSysCall'),
  2843. (mask:pocall_system; str:'System'),
  2844. (mask:pocall_inline; str:'Inline'),
  2845. (mask:pocall_internproc; str:'InternProc'),
  2846. (mask:pocall_internconst; str:'InternConst'),
  2847. (mask:pocall_cdecl; str:'CPPDecl')
  2848. );
  2849. var
  2850. s : string;
  2851. i : longint;
  2852. first : boolean;
  2853. begin
  2854. s:='';
  2855. first:=true;
  2856. for i:=1to proccallopts do
  2857. if (proccallopt[i].mask in proccalloptions) then
  2858. begin
  2859. if first then
  2860. first:=false
  2861. else
  2862. s:=s+';';
  2863. s:=s+proccallopt[i].str;
  2864. end;
  2865. proccalloption2str:=s;
  2866. end;
  2867. {$ifdef GDB}
  2868. function tabstractprocdef.stabstring : pchar;
  2869. begin
  2870. stabstring := strpnew('abstractproc'+numberstring+';');
  2871. end;
  2872. procedure tabstractprocdef.concatstabto(asmlist : paasmoutput);
  2873. begin
  2874. if (not assigned(typesym) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2875. and (is_def_stab_written = not_written) then
  2876. begin
  2877. if assigned(rettype.def) then forcestabto(asmlist,rettype.def);
  2878. inherited concatstabto(asmlist);
  2879. end;
  2880. end;
  2881. {$endif GDB}
  2882. {***************************************************************************
  2883. TPROCDEF
  2884. ***************************************************************************}
  2885. constructor tprocdef.init;
  2886. begin
  2887. inherited init;
  2888. deftype:=procdef;
  2889. _mangledname:=nil;
  2890. nextoverloaded:=nil;
  2891. fileinfo:=aktfilepos;
  2892. extnumber:=-1;
  2893. localst:=new(pstoredsymtable,init(localsymtable));
  2894. parast:=new(pstoredsymtable,init(parasymtable));
  2895. localst^.defowner:=@self;
  2896. parast^.defowner:=@self;
  2897. { this is used by insert
  2898. to check same names in parast and localst }
  2899. localst^.next:=parast;
  2900. defref:=nil;
  2901. crossref:=nil;
  2902. lastwritten:=nil;
  2903. refcount:=0;
  2904. if (cs_browser in aktmoduleswitches) and make_ref then
  2905. begin
  2906. defref:=new(pref,init(defref,@akttokenpos));
  2907. inc(refcount);
  2908. end;
  2909. lastref:=defref;
  2910. { first, we assume that all registers are used }
  2911. {$ifdef newcg}
  2912. usedregisters:=[firstreg..lastreg];
  2913. {$else newcg}
  2914. {$ifdef i386}
  2915. usedregisters:=$ff;
  2916. {$endif i386}
  2917. {$ifdef m68k}
  2918. usedregisters:=$FFFF;
  2919. {$endif}
  2920. {$endif newcg}
  2921. forwarddef:=true;
  2922. interfacedef:=false;
  2923. hasforward:=false;
  2924. _class := nil;
  2925. code:=nil;
  2926. regvarinfo := nil;
  2927. count:=false;
  2928. is_used:=false;
  2929. end;
  2930. constructor tprocdef.load;
  2931. begin
  2932. inherited load;
  2933. deftype:=procdef;
  2934. {$ifdef newcg}
  2935. readnormalset(usedregisters);
  2936. {$else newcg}
  2937. {$ifdef i386}
  2938. usedregisters:=readbyte;
  2939. {$endif i386}
  2940. {$ifdef m68k}
  2941. usedregisters:=readword;
  2942. {$endif}
  2943. {$endif newcg}
  2944. _mangledname:=stringdup(readstring);
  2945. extnumber:=readlong;
  2946. nextoverloaded:=pprocdef(readderef);
  2947. _class := pobjectdef(readderef);
  2948. readposinfo(fileinfo);
  2949. if (cs_link_deffile in aktglobalswitches) and
  2950. (tf_need_export in target_info.flags) and
  2951. (po_exports in procoptions) then
  2952. deffile.AddExport(mangledname);
  2953. parast:=new(pstoredsymtable,loadas(parasymtable));
  2954. parast^.defowner:=@self;
  2955. {new(localst,loadas(localsymtable));
  2956. localst^.defowner:=@self;
  2957. parast^.next:=localst;
  2958. localst^.next:=owner;}
  2959. forwarddef:=false;
  2960. interfacedef:=false;
  2961. hasforward:=false;
  2962. code := nil;
  2963. regvarinfo := nil;
  2964. lastref:=nil;
  2965. lastwritten:=nil;
  2966. defref:=nil;
  2967. refcount:=0;
  2968. count:=true;
  2969. is_used:=false;
  2970. end;
  2971. function tprocdef.fullprocname:string;
  2972. var
  2973. s : string;
  2974. begin
  2975. s:='';
  2976. if assigned(_class) then
  2977. s:=_class^.objname^+'.';
  2978. s:=s+procsym^.realname+demangled_paras;
  2979. fullprocname:=s;
  2980. end;
  2981. function tprocdef.getsymtable(t:tgetsymtable):psymtable;
  2982. begin
  2983. case t of
  2984. gs_local :
  2985. getsymtable:=localst;
  2986. gs_para :
  2987. getsymtable:=parast;
  2988. else
  2989. getsymtable:=nil;
  2990. end;
  2991. end;
  2992. Const local_symtable_index : longint = $8001;
  2993. procedure tprocdef.load_references;
  2994. var
  2995. pos : tfileposinfo;
  2996. {$ifndef NOLOCALBROWSER}
  2997. oldsymtablestack,
  2998. st : psymtable;
  2999. {$endif ndef NOLOCALBROWSER}
  3000. move_last : boolean;
  3001. begin
  3002. move_last:=lastwritten=lastref;
  3003. while (not current_ppu^.endofentry) do
  3004. begin
  3005. readposinfo(pos);
  3006. inc(refcount);
  3007. lastref:=new(pref,init(lastref,@pos));
  3008. lastref^.is_written:=true;
  3009. if refcount=1 then
  3010. defref:=lastref;
  3011. end;
  3012. if move_last then
  3013. lastwritten:=lastref;
  3014. if ((current_module^.flags and uf_local_browser)<>0)
  3015. and is_in_current then
  3016. begin
  3017. {$ifndef NOLOCALBROWSER}
  3018. oldsymtablestack:=symtablestack;
  3019. st:=aktlocalsymtable;
  3020. parast:=new(pstoredsymtable,loadas(parasymtable));
  3021. parast^.defowner:=@self;
  3022. aktlocalsymtable:=parast;
  3023. pstoredsymtable(parast)^.deref;
  3024. parast^.next:=owner;
  3025. pstoredsymtable(parast)^.load_browser;
  3026. aktlocalsymtable:=st;
  3027. localst:=new(pstoredsymtable,loadas(localsymtable));
  3028. localst^.defowner:=@self;
  3029. aktlocalsymtable:=localst;
  3030. symtablestack:=parast;
  3031. pstoredsymtable(localst)^.deref;
  3032. localst^.next:=parast;
  3033. pstoredsymtable(localst)^.load_browser;
  3034. aktlocalsymtable:=st;
  3035. symtablestack:=oldsymtablestack;
  3036. {$endif ndef NOLOCALBROWSER}
  3037. end;
  3038. end;
  3039. function tprocdef.write_references : boolean;
  3040. var
  3041. ref : pref;
  3042. {$ifndef NOLOCALBROWSER}
  3043. st : psymtable;
  3044. pdo : pobjectdef;
  3045. {$endif ndef NOLOCALBROWSER}
  3046. move_last : boolean;
  3047. begin
  3048. move_last:=lastwritten=lastref;
  3049. if move_last and (((current_module^.flags and uf_local_browser)=0)
  3050. or not is_in_current) then
  3051. exit;
  3052. { write address of this symbol }
  3053. writederef(@self);
  3054. { write refs }
  3055. if assigned(lastwritten) then
  3056. ref:=lastwritten
  3057. else
  3058. ref:=defref;
  3059. while assigned(ref) do
  3060. begin
  3061. if ref^.moduleindex=current_module^.unit_index then
  3062. begin
  3063. writeposinfo(ref^.posinfo);
  3064. ref^.is_written:=true;
  3065. if move_last then
  3066. lastwritten:=ref;
  3067. end
  3068. else if not ref^.is_written then
  3069. move_last:=false
  3070. else if move_last then
  3071. lastwritten:=ref;
  3072. ref:=ref^.nextref;
  3073. end;
  3074. current_ppu^.writeentry(ibdefref);
  3075. write_references:=true;
  3076. if ((current_module^.flags and uf_local_browser)<>0)
  3077. and is_in_current then
  3078. begin
  3079. {$ifndef NOLOCALBROWSER}
  3080. pdo:=_class;
  3081. if (owner^.symtabletype<>localsymtable) then
  3082. while assigned(pdo) do
  3083. begin
  3084. if pdo^.symtable<>aktrecordsymtable then
  3085. begin
  3086. pdo^.symtable^.unitid:=local_symtable_index;
  3087. inc(local_symtable_index);
  3088. end;
  3089. pdo:=pdo^.childof;
  3090. end;
  3091. { we need TESTLOCALBROWSER para and local symtables
  3092. PPU files are then easier to read PM }
  3093. if not assigned(parast) then
  3094. parast:=new(pstoredsymtable,init(parasymtable));
  3095. parast^.defowner:=@self;
  3096. st:=aktlocalsymtable;
  3097. aktlocalsymtable:=parast;
  3098. pstoredsymtable(parast)^.writeas;
  3099. parast^.unitid:=local_symtable_index;
  3100. inc(local_symtable_index);
  3101. pstoredsymtable(parast)^.write_browser;
  3102. if not assigned(localst) then
  3103. localst:=new(pstoredsymtable,init(localsymtable));
  3104. localst^.defowner:=@self;
  3105. aktlocalsymtable:=localst;
  3106. pstoredsymtable(localst)^.writeas;
  3107. localst^.unitid:=local_symtable_index;
  3108. inc(local_symtable_index);
  3109. pstoredsymtable(localst)^.write_browser;
  3110. aktlocalsymtable:=st;
  3111. { decrement for }
  3112. local_symtable_index:=local_symtable_index-2;
  3113. pdo:=_class;
  3114. if (owner^.symtabletype<>localsymtable) then
  3115. while assigned(pdo) do
  3116. begin
  3117. if pdo^.symtable<>aktrecordsymtable then
  3118. dec(local_symtable_index);
  3119. pdo:=pdo^.childof;
  3120. end;
  3121. {$endif ndef NOLOCALBROWSER}
  3122. end;
  3123. end;
  3124. destructor tprocdef.done;
  3125. begin
  3126. if assigned(defref) then
  3127. begin
  3128. defref^.freechain;
  3129. dispose(defref,done);
  3130. end;
  3131. if assigned(parast) then
  3132. dispose(parast,done);
  3133. if assigned(localst) and (localst^.symtabletype<>staticsymtable) then
  3134. dispose(localst,done);
  3135. if (pocall_inline in proccalloptions) and assigned(code) then
  3136. tnode(code).free;
  3137. if assigned(regvarinfo) then
  3138. dispose(pregvarinfo(regvarinfo));
  3139. if (po_msgstr in procoptions) then
  3140. strdispose(messageinf.str);
  3141. if assigned(_mangledname) then
  3142. stringdispose(_mangledname);
  3143. inherited done;
  3144. end;
  3145. procedure tprocdef.write;
  3146. var
  3147. oldintfcrc : boolean;
  3148. begin
  3149. inherited write;
  3150. oldintfcrc:=current_ppu^.do_interface_crc;
  3151. current_ppu^.do_interface_crc:=false;
  3152. { set all registers to used for simplified compilation PM }
  3153. if simplify_ppu then
  3154. begin
  3155. {$ifdef newcg}
  3156. usedregisters:=[firstreg..lastreg];
  3157. {$else newcg}
  3158. {$ifdef i386}
  3159. usedregisters:=$ff;
  3160. {$endif i386}
  3161. {$ifdef m68k}
  3162. usedregisters:=$ffff;
  3163. {$endif}
  3164. {$endif newcg}
  3165. end;
  3166. {$ifdef newcg}
  3167. writenormalset(usedregisters);
  3168. {$else newcg}
  3169. {$ifdef i386}
  3170. writebyte(usedregisters);
  3171. {$endif i386}
  3172. {$ifdef m68k}
  3173. writeword(usedregisters);
  3174. {$endif}
  3175. {$endif newcg}
  3176. current_ppu^.do_interface_crc:=oldintfcrc;
  3177. writestring(mangledname);
  3178. writelong(extnumber);
  3179. if (proctypeoption<>potype_operator) then
  3180. writederef(nextoverloaded)
  3181. else
  3182. begin
  3183. { only write the overloads from the same unit }
  3184. if assigned(nextoverloaded) and
  3185. (nextoverloaded^.owner=owner) then
  3186. writederef(nextoverloaded)
  3187. else
  3188. writederef(nil);
  3189. end;
  3190. writederef(_class);
  3191. writeposinfo(fileinfo);
  3192. if (pocall_inline in proccalloptions) then
  3193. begin
  3194. { we need to save
  3195. - the para and the local symtable
  3196. - the code ptree !! PM
  3197. writesymtable(parast);
  3198. writesymtable(localst);
  3199. writeptree(ptree(code));
  3200. }
  3201. end;
  3202. current_ppu^.writeentry(ibprocdef);
  3203. { Save the para and local symtable, for easier reading
  3204. save both always, they don't influence the interface crc }
  3205. oldintfcrc:=current_ppu^.do_interface_crc;
  3206. current_ppu^.do_interface_crc:=false;
  3207. if not assigned(parast) then
  3208. begin
  3209. parast:=new(pstoredsymtable,init(parasymtable));
  3210. parast^.defowner:=@self;
  3211. end;
  3212. pstoredsymtable(parast)^.writeas;
  3213. {if not assigned(localst) then
  3214. begin
  3215. localst:=new(pstoredsymtable,init(localsymtable));
  3216. localst^.defowner:=@self;
  3217. end;
  3218. localst^.writeas;}
  3219. current_ppu^.do_interface_crc:=oldintfcrc;
  3220. end;
  3221. function tprocdef.haspara:boolean;
  3222. begin
  3223. haspara:=assigned(parast^.symindex^.first);
  3224. end;
  3225. {$ifdef GDB}
  3226. procedure addparaname(p : psym);
  3227. var vs : char;
  3228. begin
  3229. if pvarsym(p)^.varspez = vs_value then vs := '1'
  3230. else vs := '0';
  3231. strpcopy(strend(StabRecString),p^.name+':'+pstoreddef(pvarsym(p)^.vartype.def)^.numberstring+','+vs+';');
  3232. end;
  3233. function tprocdef.stabstring : pchar;
  3234. var
  3235. i : longint;
  3236. oldrec : pchar;
  3237. begin
  3238. oldrec := stabrecstring;
  3239. getmem(StabRecString,1024);
  3240. strpcopy(StabRecString,'f'+pstoreddef(rettype.def)^.numberstring);
  3241. i:=maxparacount;
  3242. if i>0 then
  3243. begin
  3244. strpcopy(strend(StabRecString),','+tostr(i)+';');
  3245. (* confuse gdb !! PM
  3246. if assigned(parast) then
  3247. parast^.foreach({$ifdef FPCPROCVAR}@{$endif}addparaname)
  3248. else
  3249. begin
  3250. param := para1;
  3251. i := 0;
  3252. while assigned(param) do
  3253. begin
  3254. inc(i);
  3255. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  3256. {Here we have lost the parameter names !!}
  3257. {using lower case parameters }
  3258. strpcopy(strend(stabrecstring),'p'+tostr(i)
  3259. +':'+param^.paratype.def^.numberstring+','+vartyp+';');
  3260. param := param^.next;
  3261. end;
  3262. end; *)
  3263. {strpcopy(strend(StabRecString),';');}
  3264. end;
  3265. stabstring := strnew(stabrecstring);
  3266. freemem(stabrecstring,1024);
  3267. stabrecstring := oldrec;
  3268. end;
  3269. procedure tprocdef.concatstabto(asmlist : paasmoutput);
  3270. begin
  3271. end;
  3272. {$endif GDB}
  3273. procedure tprocdef.deref;
  3274. var
  3275. oldsymtablestack,
  3276. oldlocalsymtable : psymtable;
  3277. begin
  3278. inherited deref;
  3279. resolvedef(pdef(nextoverloaded));
  3280. resolvedef(pdef(_class));
  3281. { parast }
  3282. oldsymtablestack:=symtablestack;
  3283. oldlocalsymtable:=aktlocalsymtable;
  3284. aktlocalsymtable:=parast;
  3285. pstoredsymtable(parast)^.deref;
  3286. {symtablestack:=parast;
  3287. aktlocalsymtable:=localst;
  3288. localst^.deref;}
  3289. aktlocalsymtable:=oldlocalsymtable;
  3290. symtablestack:=oldsymtablestack;
  3291. end;
  3292. function tprocdef.mangledname : string;
  3293. begin
  3294. if assigned(_mangledname) then
  3295. mangledname:=_mangledname^
  3296. else
  3297. mangledname:='';
  3298. if count then
  3299. is_used:=true;
  3300. end;
  3301. function tprocdef.cplusplusmangledname : string;
  3302. function getcppparaname(p : pdef) : string;
  3303. const
  3304. ordtype2str : array[tbasetype] of string[2] = (
  3305. '','','c',
  3306. 'Uc','Us','Ui',
  3307. 'Sc','s','i',
  3308. 'b','b','b',
  3309. 'Us','x','w');
  3310. var
  3311. s : string;
  3312. begin
  3313. case p^.deftype of
  3314. orddef:
  3315. s:=ordtype2str[porddef(p)^.typ];
  3316. pointerdef:
  3317. s:='P'+getcppparaname(ppointerdef(p)^.pointertype.def);
  3318. else
  3319. internalerror(2103001);
  3320. end;
  3321. getcppparaname:=s;
  3322. end;
  3323. var
  3324. s,s2 : string;
  3325. param : pparaitem;
  3326. begin
  3327. s := procsym^.realname;
  3328. if procsym^.owner^.symtabletype=objectsymtable then
  3329. begin
  3330. s2:=upper(pobjectdef(procsym^.owner^.defowner)^.typesym^.realname);
  3331. case proctypeoption of
  3332. potype_destructor:
  3333. s:='_$_'+tostr(length(s2))+s2;
  3334. potype_constructor:
  3335. s:='___'+tostr(length(s2))+s2;
  3336. else
  3337. s:='_'+s+'__'+tostr(length(s2))+s2;
  3338. end;
  3339. end
  3340. else s:=s+'__';
  3341. s:=s+'F';
  3342. { concat modifiers }
  3343. { !!!!! }
  3344. { now we handle the parameters }
  3345. param := pparaitem(para^.first);
  3346. if assigned(param) then
  3347. while assigned(param) do
  3348. begin
  3349. s2:=getcppparaname(param^.paratype.def);
  3350. if param^.paratyp in [vs_var,vs_out] then
  3351. s2:='R'+s2;
  3352. s:=s+s2;
  3353. param:=pparaitem(param^.next);
  3354. end
  3355. else
  3356. s:=s+'v';
  3357. cplusplusmangledname:=s;
  3358. end;
  3359. procedure tprocdef.setmangledname(const s : string);
  3360. begin
  3361. if assigned(_mangledname) then
  3362. begin
  3363. {$ifdef MEMDEBUG}
  3364. dec(manglenamesize,length(_mangledname^));
  3365. {$endif}
  3366. stringdispose(_mangledname);
  3367. end;
  3368. _mangledname:=stringdup(s);
  3369. {$ifdef MEMDEBUG}
  3370. inc(manglenamesize,length(s));
  3371. {$endif}
  3372. {$ifdef EXTDEBUG}
  3373. if assigned(parast) then
  3374. begin
  3375. stringdispose(parast^.name);
  3376. parast^.name:=stringdup('args of '+s);
  3377. end;
  3378. if assigned(localst) then
  3379. begin
  3380. stringdispose(localst^.name);
  3381. localst^.name:=stringdup('locals of '+s);
  3382. end;
  3383. {$endif}
  3384. end;
  3385. {***************************************************************************
  3386. TPROCVARDEF
  3387. ***************************************************************************}
  3388. constructor tprocvardef.init;
  3389. begin
  3390. inherited init;
  3391. deftype:=procvardef;
  3392. end;
  3393. constructor tprocvardef.load;
  3394. begin
  3395. inherited load;
  3396. deftype:=procvardef;
  3397. end;
  3398. procedure tprocvardef.write;
  3399. begin
  3400. { here we cannot get a real good value so just give something }
  3401. { plausible (PM) }
  3402. { a more secure way would be
  3403. to allways store in a temp }
  3404. if is_fpu(rettype.def) then
  3405. fpu_used:=2
  3406. else
  3407. fpu_used:=0;
  3408. inherited write;
  3409. current_ppu^.writeentry(ibprocvardef);
  3410. end;
  3411. function tprocvardef.size : longint;
  3412. begin
  3413. if (po_methodpointer in procoptions) then
  3414. size:=2*target_os.size_of_pointer
  3415. else
  3416. size:=target_os.size_of_pointer;
  3417. end;
  3418. {$ifdef GDB}
  3419. function tprocvardef.stabstring : pchar;
  3420. var
  3421. nss : pchar;
  3422. { i : longint; }
  3423. begin
  3424. { i := maxparacount; }
  3425. getmem(nss,1024);
  3426. { it is not a function but a function pointer !! (PM) }
  3427. strpcopy(nss,'*f'+pstoreddef(rettype.def)^.numberstring{+','+tostr(i)}+';');
  3428. { this confuses gdb !!
  3429. we should use 'F' instead of 'f' but
  3430. as we use c++ language mode
  3431. it does not like that either
  3432. Please do not remove this part
  3433. might be used once
  3434. gdb for pascal is ready PM }
  3435. (*
  3436. param := para1;
  3437. i := 0;
  3438. while assigned(param) do
  3439. begin
  3440. inc(i);
  3441. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  3442. {Here we have lost the parameter names !!}
  3443. pst := strpnew('p'+tostr(i)+':'+param^.paratype.def^.numberstring+','+vartyp+';');
  3444. strcat(nss,pst);
  3445. strdispose(pst);
  3446. param := param^.next;
  3447. end; *)
  3448. {strpcopy(strend(nss),';');}
  3449. stabstring := strnew(nss);
  3450. freemem(nss,1024);
  3451. end;
  3452. procedure tprocvardef.concatstabto(asmlist : paasmoutput);
  3453. begin
  3454. if ( not assigned(typesym) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  3455. and (is_def_stab_written = not_written) then
  3456. inherited concatstabto(asmlist);
  3457. is_def_stab_written:=written;
  3458. end;
  3459. {$endif GDB}
  3460. procedure tprocvardef.write_rtti_data;
  3461. var
  3462. pdc : pparaitem;
  3463. methodkind, paraspec : byte;
  3464. begin
  3465. if po_methodpointer in procoptions then
  3466. begin
  3467. { write method id and name }
  3468. rttilist^.concat(new(pai_const,init_8bit(tkmethod)));
  3469. write_rtti_name;
  3470. { write kind of method (can only be function or procedure)}
  3471. if rettype.def = pdef(voiddef) then { ### typecast shoudln't be necessary! (sg) }
  3472. methodkind := mkProcedure
  3473. else
  3474. methodkind := mkFunction;
  3475. rttilist^.concat(new(pai_const,init_8bit(methodkind)));
  3476. { get # of parameters }
  3477. rttilist^.concat(new(pai_const,init_8bit(maxparacount)));
  3478. { write parameter info. The parameters must be written in reverse order
  3479. if this method uses right to left parameter pushing! }
  3480. if (pocall_leftright in proccalloptions) then
  3481. pdc:=pparaitem(para^.last)
  3482. else
  3483. pdc:=pparaitem(para^.first);
  3484. while assigned(pdc) do
  3485. begin
  3486. case pdc^.paratyp of
  3487. vs_value: paraspec := 0;
  3488. vs_const: paraspec := pfConst;
  3489. vs_var : paraspec := pfVar;
  3490. vs_out : paraspec := pfOut;
  3491. end;
  3492. { write flags for current parameter }
  3493. rttilist^.concat(new(pai_const,init_8bit(paraspec)));
  3494. { write name of current parameter ### how can I get this??? (sg)}
  3495. rttilist^.concat(new(pai_const,init_8bit(0)));
  3496. { write name of type of current parameter }
  3497. pstoreddef(pdc^.paratype.def)^.write_rtti_name;
  3498. if (pocall_leftright in proccalloptions) then
  3499. pdc:=pparaitem(pdc^.previous)
  3500. else
  3501. pdc:=pparaitem(pdc^.next);
  3502. end;
  3503. { write name of result type }
  3504. pstoreddef(rettype.def)^.write_rtti_name;
  3505. end;
  3506. end;
  3507. procedure tprocvardef.write_child_rtti_data;
  3508. begin
  3509. {!!!!!!!!}
  3510. end;
  3511. function tprocvardef.is_publishable : boolean;
  3512. begin
  3513. is_publishable:=(po_methodpointer in procoptions);
  3514. end;
  3515. function tprocvardef.gettypename : string;
  3516. begin
  3517. if assigned(rettype.def) and
  3518. (rettype.def<>pdef(voiddef)) then
  3519. gettypename:='<procedure variable type of function'+demangled_paras+
  3520. ':'+rettype.def^.gettypename+';'+proccalloption2str+'>'
  3521. else
  3522. gettypename:='<procedure variable type of procedure'+demangled_paras+
  3523. ';'+proccalloption2str+'>';
  3524. end;
  3525. {***************************************************************************
  3526. TOBJECTDEF
  3527. ***************************************************************************}
  3528. {$ifdef GDB}
  3529. const
  3530. vtabletype : word = 0;
  3531. vtableassigned : boolean = false;
  3532. {$endif GDB}
  3533. constructor tobjectdef.init(ot : tobjectdeftype;const n : string;c : pobjectdef);
  3534. begin
  3535. inherited init;
  3536. objecttype:=ot;
  3537. deftype:=objectdef;
  3538. objectoptions:=[];
  3539. childof:=nil;
  3540. symtable:=new(pstoredsymtable,init(objectsymtable));
  3541. symtable^.name := stringdup(n);
  3542. { create space for vmt !! }
  3543. vmt_offset:=0;
  3544. symtable^.datasize:=0;
  3545. symtable^.defowner:=@self;
  3546. symtable^.dataalignment:=packrecordalignment[aktpackrecords];
  3547. set_parent(c);
  3548. objname:=stringdup(n);
  3549. lastvtableindex:=0;
  3550. { set up guid }
  3551. isiidguidvalid:=true; { default null guid }
  3552. fillchar(iidguid,sizeof(iidguid),0); { default null guid }
  3553. iidstr:=stringdup(''); { default is empty string }
  3554. { set£p implemented interfaces }
  3555. if objecttype in [odt_class,odt_interfacecorba] then
  3556. new(implementedinterfaces,init)
  3557. else
  3558. implementedinterfaces:=nil;
  3559. {$ifdef GDB}
  3560. writing_stabs:=false;
  3561. classglobalnb:=0;
  3562. classptrglobalnb:=0;
  3563. {$endif GDB}
  3564. end;
  3565. constructor tobjectdef.load;
  3566. var
  3567. oldread_member : boolean;
  3568. i,implintfcount: longint;
  3569. begin
  3570. inherited load;
  3571. deftype:=objectdef;
  3572. objecttype:=tobjectdeftype(readbyte);
  3573. savesize:=readlong;
  3574. vmt_offset:=readlong;
  3575. objname:=stringdup(readstring);
  3576. childof:=pobjectdef(readderef);
  3577. readsmallset(objectoptions);
  3578. has_rtti:=boolean(readbyte);
  3579. { load guid }
  3580. iidstr:=nil;
  3581. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3582. begin
  3583. isiidguidvalid:=boolean(readbyte);
  3584. readguid(iidguid);
  3585. iidstr:=stringdup(readstring);
  3586. lastvtableindex:=readlong;
  3587. end;
  3588. { load implemented interfaces }
  3589. if objecttype in [odt_class,odt_interfacecorba] then
  3590. begin
  3591. new(implementedinterfaces,init);
  3592. implintfcount:=readlong;
  3593. for i:=1 to implintfcount do
  3594. begin
  3595. implementedinterfaces^.addintfref(pdef(readderef));
  3596. implementedinterfaces^.ioffsets(i)^:=readlong;
  3597. end;
  3598. end
  3599. else
  3600. implementedinterfaces:=nil;
  3601. oldread_member:=read_member;
  3602. read_member:=true;
  3603. symtable:=new(pstoredsymtable,loadas(objectsymtable));
  3604. read_member:=oldread_member;
  3605. symtable^.defowner:=@self;
  3606. symtable^.name := stringdup(objname^);
  3607. { handles the predefined class tobject }
  3608. { the last TOBJECT which is loaded gets }
  3609. { it ! }
  3610. if (childof=nil) and
  3611. (objecttype=odt_class) and
  3612. (upper(objname^)='TOBJECT') then
  3613. class_tobject:=@self;
  3614. if (childof=nil) and
  3615. (objecttype=odt_interfacecom) and
  3616. (upper(objname^)='IUNKNOWN') then
  3617. interface_iunknown:=@self;
  3618. {$ifdef GDB}
  3619. writing_stabs:=false;
  3620. classglobalnb:=0;
  3621. classptrglobalnb:=0;
  3622. {$endif GDB}
  3623. end;
  3624. destructor tobjectdef.done;
  3625. begin
  3626. if assigned(symtable) then
  3627. dispose(symtable,done);
  3628. if (oo_is_forward in objectoptions) then
  3629. Message1(sym_e_class_forward_not_resolved,objname^);
  3630. stringdispose(objname);
  3631. stringdispose(iidstr);
  3632. if assigned(implementedinterfaces) then
  3633. dispose(implementedinterfaces,done);
  3634. inherited done;
  3635. end;
  3636. procedure tobjectdef.write;
  3637. var
  3638. oldread_member : boolean;
  3639. implintfcount : longint;
  3640. i : longint;
  3641. begin
  3642. inherited write;
  3643. writebyte(byte(objecttype));
  3644. writelong(size);
  3645. writelong(vmt_offset);
  3646. writestring(objname^);
  3647. writederef(childof);
  3648. writesmallset(objectoptions);
  3649. writebyte(byte(has_rtti));
  3650. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3651. begin
  3652. writebyte(byte(isiidguidvalid));
  3653. writeguid(iidguid);
  3654. writestring(iidstr^);
  3655. writelong(lastvtableindex);
  3656. end;
  3657. if objecttype in [odt_class,odt_interfacecorba] then
  3658. begin
  3659. implintfcount:=implementedinterfaces^.count;
  3660. writelong(implintfcount);
  3661. for i:=1 to implintfcount do
  3662. begin
  3663. writederef(implementedinterfaces^.interfaces(i));
  3664. writelong(implementedinterfaces^.ioffsets(i)^);
  3665. end;
  3666. end;
  3667. current_ppu^.writeentry(ibobjectdef);
  3668. oldread_member:=read_member;
  3669. read_member:=true;
  3670. pstoredsymtable(symtable)^.writeas;
  3671. read_member:=oldread_member;
  3672. end;
  3673. function tobjectdef.getsymtable(t:tgetsymtable):psymtable;
  3674. begin
  3675. if t=gs_record then
  3676. getsymtable:=symtable
  3677. else
  3678. getsymtable:=nil;
  3679. end;
  3680. procedure tobjectdef.deref;
  3681. var
  3682. oldrecsyms : psymtable;
  3683. begin
  3684. inherited deref;
  3685. resolvedef(pdef(childof));
  3686. oldrecsyms:=aktrecordsymtable;
  3687. aktrecordsymtable:=symtable;
  3688. pstoredsymtable(symtable)^.deref;
  3689. aktrecordsymtable:=oldrecsyms;
  3690. if objecttype in [odt_class,odt_interfacecorba] then
  3691. implementedinterfaces^.deref;
  3692. end;
  3693. procedure tobjectdef.set_parent( c : pobjectdef);
  3694. begin
  3695. { nothing to do if the parent was not forward !}
  3696. if assigned(childof) then
  3697. exit;
  3698. childof:=c;
  3699. { some options are inherited !! }
  3700. if assigned(c) then
  3701. begin
  3702. { only important for classes }
  3703. lastvtableindex:=c^.lastvtableindex;
  3704. objectoptions:=objectoptions+(c^.objectoptions*
  3705. [oo_has_virtual,oo_has_private,oo_has_protected,oo_has_constructor,oo_has_destructor]);
  3706. if not (objecttype in [odt_interfacecom,odt_interfacecorba]) then
  3707. begin
  3708. { add the data of the anchestor class }
  3709. inc(symtable^.datasize,c^.symtable^.datasize);
  3710. if (oo_has_vmt in objectoptions) and
  3711. (oo_has_vmt in c^.objectoptions) then
  3712. dec(symtable^.datasize,target_os.size_of_pointer);
  3713. { if parent has a vmt field then
  3714. the offset is the same for the child PM }
  3715. if (oo_has_vmt in c^.objectoptions) or is_class(@self) then
  3716. begin
  3717. vmt_offset:=c^.vmt_offset;
  3718. include(objectoptions,oo_has_vmt);
  3719. end;
  3720. end;
  3721. end;
  3722. savesize := symtable^.datasize;
  3723. end;
  3724. procedure tobjectdef.insertvmt;
  3725. begin
  3726. if objecttype in [odt_interfacecom,odt_interfacecorba] then exit;
  3727. if (oo_has_vmt in objectoptions) then
  3728. internalerror(12345)
  3729. else
  3730. begin
  3731. { first round up to multiple of 4 }
  3732. if (symtable^.dataalignment=2) then
  3733. begin
  3734. if (symtable^.datasize and 1)<>0 then
  3735. inc(symtable^.datasize);
  3736. end
  3737. else
  3738. if (symtable^.dataalignment>=4) then
  3739. begin
  3740. if (symtable^.datasize mod 4) <> 0 then
  3741. inc(symtable^.datasize,4-(symtable^.datasize mod 4));
  3742. end;
  3743. vmt_offset:=symtable^.datasize;
  3744. inc(symtable^.datasize,target_os.size_of_pointer);
  3745. include(objectoptions,oo_has_vmt);
  3746. end;
  3747. end;
  3748. procedure tobjectdef.check_forwards;
  3749. begin
  3750. if objecttype in [odt_interfacecom,odt_interfacecorba] then exit; { Kaz: ??? }
  3751. pstoredsymtable(symtable)^.check_forwards;
  3752. if (oo_is_forward in objectoptions) then
  3753. begin
  3754. { ok, in future, the forward can be resolved }
  3755. Message1(sym_e_class_forward_not_resolved,objname^);
  3756. exclude(objectoptions,oo_is_forward);
  3757. end;
  3758. end;
  3759. { true, if self inherits from d (or if they are equal) }
  3760. function tobjectdef.is_related(d : pobjectdef) : boolean;
  3761. var
  3762. hp : pobjectdef;
  3763. begin
  3764. hp:=@self;
  3765. while assigned(hp) do
  3766. begin
  3767. if hp=d then
  3768. begin
  3769. is_related:=true;
  3770. exit;
  3771. end;
  3772. hp:=hp^.childof;
  3773. end;
  3774. is_related:=false;
  3775. end;
  3776. var
  3777. sd : pprocdef;
  3778. procedure _searchdestructor(sym : pnamedindexobject);
  3779. var
  3780. p : pprocdef;
  3781. begin
  3782. { if we found already a destructor, then we exit }
  3783. if assigned(sd) then
  3784. exit;
  3785. if psym(sym)^.typ=procsym then
  3786. begin
  3787. p:=pprocsym(sym)^.definition;
  3788. while assigned(p) do
  3789. begin
  3790. if p^.proctypeoption=potype_destructor then
  3791. begin
  3792. sd:=p;
  3793. exit;
  3794. end;
  3795. p:=p^.nextoverloaded;
  3796. end;
  3797. end;
  3798. end;
  3799. function tobjectdef.searchdestructor : pprocdef;
  3800. var
  3801. o : pobjectdef;
  3802. begin
  3803. searchdestructor:=nil;
  3804. o:=@self;
  3805. sd:=nil;
  3806. while assigned(o) do
  3807. begin
  3808. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}_searchdestructor);
  3809. if assigned(sd) then
  3810. begin
  3811. searchdestructor:=sd;
  3812. exit;
  3813. end;
  3814. o:=o^.childof;
  3815. end;
  3816. end;
  3817. function tobjectdef.size : longint;
  3818. begin
  3819. if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba] then
  3820. size:=target_os.size_of_pointer
  3821. else
  3822. size:=symtable^.datasize;
  3823. end;
  3824. function tobjectdef.alignment:longint;
  3825. begin
  3826. alignment:=symtable^.dataalignment;
  3827. end;
  3828. function tobjectdef.vmtmethodoffset(index:longint):longint;
  3829. begin
  3830. { for offset of methods for classes, see rtl/inc/objpash.inc }
  3831. if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba] then
  3832. vmtmethodoffset:=(index+12)*target_os.size_of_pointer
  3833. else
  3834. {$ifdef WITHDMT}
  3835. vmtmethodoffset:=(index+4)*target_os.size_of_pointer;
  3836. {$else WITHDMT}
  3837. vmtmethodoffset:=(index+3)*target_os.size_of_pointer;
  3838. {$endif WITHDMT}
  3839. end;
  3840. function tobjectdef.vmt_mangledname : string;
  3841. {DM: I get a nil pointer on the owner name. I don't know if this
  3842. may happen, and I have therefore fixed the problem by doing nil pointer
  3843. checks.}
  3844. var
  3845. s1,s2:string;
  3846. begin
  3847. if not(oo_has_vmt in objectoptions) then
  3848. Message1(parser_object_has_no_vmt,objname^);
  3849. if owner^.name=nil then
  3850. s1:=''
  3851. else
  3852. s1:=upper(owner^.name^);
  3853. if objname=nil then
  3854. s2:=''
  3855. else
  3856. s2:=Upper(objname^);
  3857. vmt_mangledname:='VMT_'+s1+'$_'+s2;
  3858. end;
  3859. function tobjectdef.rtti_name : string;
  3860. var
  3861. s1,s2:string;
  3862. begin
  3863. if owner^.name=nil then
  3864. s1:=''
  3865. else
  3866. s1:=upper(owner^.name^);
  3867. if objname=nil then
  3868. s2:=''
  3869. else
  3870. s2:=Upper(objname^);
  3871. rtti_name:='RTTI_'+s1+'$_'+s2;
  3872. end;
  3873. {$ifdef GDB}
  3874. procedure addprocname(p :pnamedindexobject);
  3875. var virtualind,argnames : string;
  3876. news, newrec : pchar;
  3877. pd,ipd : pprocdef;
  3878. lindex : longint;
  3879. para : pparaitem;
  3880. arglength : byte;
  3881. sp : char;
  3882. begin
  3883. If psym(p)^.typ = procsym then
  3884. begin
  3885. pd := pprocsym(p)^.definition;
  3886. { this will be used for full implementation of object stabs
  3887. not yet done }
  3888. ipd := pd;
  3889. while assigned(ipd^.nextoverloaded) do ipd := ipd^.nextoverloaded;
  3890. if (po_virtualmethod in pd^.procoptions) then
  3891. begin
  3892. lindex := pd^.extnumber;
  3893. {doesnt seem to be necessary
  3894. lindex := lindex or $80000000;}
  3895. virtualind := '*'+tostr(lindex)+';'+ipd^._class^.classnumberstring+';'
  3896. end
  3897. else
  3898. virtualind := '.';
  3899. { used by gdbpas to recognize constructor and destructors }
  3900. if (pd^.proctypeoption=potype_constructor) then
  3901. argnames:='__ct__'
  3902. else if (pd^.proctypeoption=potype_destructor) then
  3903. argnames:='__dt__'
  3904. else
  3905. argnames := '';
  3906. { arguments are not listed here }
  3907. {we don't need another definition}
  3908. para := pparaitem(pd^.para^.first);
  3909. while assigned(para) do
  3910. begin
  3911. if para^.paratype.def^.deftype = formaldef then
  3912. begin
  3913. if para^.paratyp=vs_var then
  3914. argnames := argnames+'3var'
  3915. else if para^.paratyp=vs_const then
  3916. argnames:=argnames+'5const'
  3917. else if para^.paratyp=vs_out then
  3918. argnames:=argnames+'3out';
  3919. end
  3920. else
  3921. begin
  3922. { if the arg definition is like (v: ^byte;..
  3923. there is no sym attached to data !!! }
  3924. if assigned(para^.paratype.def^.typesym) then
  3925. begin
  3926. arglength := length(para^.paratype.def^.typesym^.name);
  3927. argnames := argnames + tostr(arglength)+para^.paratype.def^.typesym^.name;
  3928. end
  3929. else
  3930. begin
  3931. argnames:=argnames+'11unnamedtype';
  3932. end;
  3933. end;
  3934. para := pparaitem(para^.next);
  3935. end;
  3936. ipd^.is_def_stab_written := written;
  3937. { here 2A must be changed for private and protected }
  3938. { 0 is private 1 protected and 2 public }
  3939. if (sp_private in psym(p)^.symoptions) then sp:='0'
  3940. else if (sp_protected in psym(p)^.symoptions) then sp:='1'
  3941. else sp:='2';
  3942. newrec := strpnew(p^.name+'::'+ipd^.numberstring
  3943. +'=##'+pstoreddef(pd^.rettype.def)^.numberstring+';:'+argnames+';'+sp+'A'
  3944. +virtualind+';');
  3945. { get spare place for a string at the end }
  3946. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  3947. begin
  3948. getmem(news,stabrecsize+memsizeinc);
  3949. strcopy(news,stabrecstring);
  3950. freemem(stabrecstring,stabrecsize);
  3951. stabrecsize:=stabrecsize+memsizeinc;
  3952. stabrecstring:=news;
  3953. end;
  3954. strcat(StabRecstring,newrec);
  3955. {freemem(newrec,memsizeinc); }
  3956. strdispose(newrec);
  3957. {This should be used for case !!
  3958. RecOffset := RecOffset + pd^.size;}
  3959. end;
  3960. end;
  3961. function tobjectdef.stabstring : pchar;
  3962. var anc : pobjectdef;
  3963. oldrec : pchar;
  3964. storenb, oldrecsize : longint;
  3965. str_end : string;
  3966. begin
  3967. if not (objecttype=odt_class) or writing_stabs then
  3968. begin
  3969. storenb:=globalnb;
  3970. globalnb:=classptrglobalnb;
  3971. oldrec := stabrecstring;
  3972. oldrecsize:=stabrecsize;
  3973. stabrecsize:=memsizeinc;
  3974. GetMem(stabrecstring,stabrecsize);
  3975. strpcopy(stabRecString,'s'+tostr(symtable^.datasize));
  3976. if assigned(childof) then
  3977. begin
  3978. {only one ancestor not virtual, public, at base offset 0 }
  3979. { !1 , 0 2 0 , }
  3980. strpcopy(strend(stabrecstring),'!1,020,'+childof^.classnumberstring+';');
  3981. end;
  3982. {virtual table to implement yet}
  3983. {RecOffset := 0;}
  3984. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}addname);
  3985. if (oo_has_vmt in objectoptions) then
  3986. if not assigned(childof) or not(oo_has_vmt in childof^.objectoptions) then
  3987. begin
  3988. strpcopy(strend(stabrecstring),'$vf'+classnumberstring+':'+typeglobalnumber('vtblarray')
  3989. +','+tostr(vmt_offset*8)+';');
  3990. end;
  3991. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}addprocname);
  3992. if (oo_has_vmt in objectoptions) then
  3993. begin
  3994. anc := @self;
  3995. while assigned(anc^.childof) and (oo_has_vmt in anc^.childof^.objectoptions) do
  3996. anc := anc^.childof;
  3997. { just in case anc = self }
  3998. str_end:=';~%'+anc^.classnumberstring+';';
  3999. end
  4000. else
  4001. str_end:=';';
  4002. strpcopy(strend(stabrecstring),str_end);
  4003. stabstring := strnew(StabRecString);
  4004. freemem(stabrecstring,stabrecsize);
  4005. stabrecstring := oldrec;
  4006. stabrecsize:=oldrecsize;
  4007. globalnb:=storenb;
  4008. end
  4009. else
  4010. begin
  4011. stabstring:=strpnew('*'+classnumberstring);
  4012. end;
  4013. end;
  4014. procedure tobjectdef.set_globalnb;
  4015. begin
  4016. classglobalnb:=PGlobalTypeCount^;
  4017. globalnb:=classglobalnb;
  4018. inc(PglobalTypeCount^);
  4019. { classes need two type numbers, the globalnb is set to the ptr }
  4020. if objecttype=odt_class then
  4021. begin
  4022. classptrglobalnb:=PGlobalTypeCount^;
  4023. globalnb:=classptrglobalnb;
  4024. inc(PglobalTypeCount^);
  4025. end;
  4026. end;
  4027. function tobjectdef.classnumberstring : string;
  4028. var
  4029. onb : word;
  4030. begin
  4031. if globalnb=0 then
  4032. numberstring;
  4033. if objecttype=odt_class then
  4034. begin
  4035. onb:=globalnb;
  4036. globalnb:=classglobalnb;
  4037. classnumberstring:=numberstring;
  4038. globalnb:=onb;
  4039. end
  4040. else
  4041. classnumberstring:=numberstring;
  4042. end;
  4043. function tobjectdef.classptrnumberstring : string;
  4044. var
  4045. onb : word;
  4046. begin
  4047. if globalnb=0 then
  4048. numberstring;
  4049. if objecttype=odt_class then
  4050. begin
  4051. onb:=globalnb;
  4052. globalnb:=classptrglobalnb;
  4053. classptrnumberstring:=numberstring;
  4054. globalnb:=onb;
  4055. end
  4056. else
  4057. classptrnumberstring:=numberstring;
  4058. end;
  4059. procedure tobjectdef.concatstabto(asmlist : paasmoutput);
  4060. var st : pstring;
  4061. begin
  4062. if objecttype<>odt_class then
  4063. begin
  4064. inherited concatstabto(asmlist);
  4065. exit;
  4066. end;
  4067. if ((typesym=nil) or ptypesym(typesym)^.isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  4068. (is_def_stab_written = not_written) then
  4069. begin
  4070. if globalnb=0 then
  4071. set_globalnb;
  4072. { Write the record class itself }
  4073. writing_stabs:=true;
  4074. if assigned(typesym) then
  4075. begin
  4076. st:=ptypesym(typesym)^._name;
  4077. ptypesym(typesym)^._name:=stringdup(' ');
  4078. end;
  4079. globalnb:=classglobalnb;
  4080. inherited concatstabto(asmlist);
  4081. if assigned(typesym) then
  4082. begin
  4083. stringdispose(ptypesym(typesym)^._name);
  4084. ptypesym(typesym)^._name:=st;
  4085. end;
  4086. globalnb:=classptrglobalnb;
  4087. writing_stabs:=false;
  4088. { Write the invisible pointer class }
  4089. is_def_stab_written:=not_written;
  4090. inherited concatstabto(asmlist);
  4091. end;
  4092. end;
  4093. {$endif GDB}
  4094. procedure tobjectdef.write_child_init_data;
  4095. begin
  4096. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}generate_child_inittable);
  4097. end;
  4098. procedure tobjectdef.write_init_data;
  4099. begin
  4100. case objecttype of
  4101. odt_class:
  4102. rttilist^.concat(new(pai_const,init_8bit(tkclass)));
  4103. odt_object:
  4104. rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  4105. odt_interfacecom:
  4106. rttilist^.concat(new(pai_const,init_8bit(tkinterface)));
  4107. odt_interfacecorba:
  4108. rttilist^.concat(new(pai_const,init_8bit(tkinterfaceCorba)));
  4109. else
  4110. exit;
  4111. end;
  4112. { generate the name }
  4113. rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
  4114. rttilist^.concat(new(pai_string,init(objname^)));
  4115. rttilist^.concat(new(pai_const,init_32bit(size)));
  4116. count:=0;
  4117. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  4118. begin
  4119. end
  4120. else
  4121. begin
  4122. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_inittable_fields);
  4123. rttilist^.concat(new(pai_const,init_32bit(count)));
  4124. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_inittable);
  4125. end;
  4126. end;
  4127. function tobjectdef.needs_inittable : boolean;
  4128. var
  4129. oldb : boolean;
  4130. begin
  4131. case objecttype of
  4132. odt_interfacecom: needs_inittable:=true;
  4133. odt_object:
  4134. begin
  4135. { there are recursive calls to needs_inittable possible, }
  4136. { so we have to change to old value how else should }
  4137. { we do that ? check_rec_rtti can't be a nested }
  4138. { procedure of needs_rtti ! }
  4139. oldb:=binittable;
  4140. binittable:=false;
  4141. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}check_rec_inittable);
  4142. needs_inittable:=binittable;
  4143. binittable:=oldb;
  4144. end;
  4145. else needs_inittable:=false;
  4146. end;
  4147. end;
  4148. procedure count_published_properties(sym:pnamedindexobject);
  4149. begin
  4150. if needs_prop_entry(psym(sym)) and
  4151. (psym(sym)^.typ<>varsym) then
  4152. inc(count);
  4153. end;
  4154. procedure write_property_info(sym : pnamedindexobject);
  4155. var
  4156. proctypesinfo : byte;
  4157. procedure writeproc(proc : psymlist; shiftvalue : byte);
  4158. var
  4159. typvalue : byte;
  4160. hp : psymlistitem;
  4161. address : longint;
  4162. begin
  4163. if not(assigned(proc) and assigned(proc^.firstsym)) then
  4164. begin
  4165. rttilist^.concat(new(pai_const,init_32bit(1)));
  4166. typvalue:=3;
  4167. end
  4168. else if proc^.firstsym^.sym^.typ=varsym then
  4169. begin
  4170. address:=0;
  4171. hp:=proc^.firstsym;
  4172. while assigned(hp) do
  4173. begin
  4174. inc(address,pvarsym(hp^.sym)^.address);
  4175. hp:=hp^.next;
  4176. end;
  4177. rttilist^.concat(new(pai_const,init_32bit(address)));
  4178. typvalue:=0;
  4179. end
  4180. else
  4181. begin
  4182. if not(po_virtualmethod in pprocdef(proc^.def)^.procoptions) then
  4183. begin
  4184. rttilist^.concat(new(pai_const_symbol,initname(pprocdef(proc^.def)^.mangledname)));
  4185. typvalue:=1;
  4186. end
  4187. else
  4188. begin
  4189. { virtual method, write vmt offset }
  4190. rttilist^.concat(new(pai_const,init_32bit(
  4191. pprocdef(proc^.def)^._class^.vmtmethodoffset(pprocdef(proc^.def)^.extnumber))));
  4192. typvalue:=2;
  4193. end;
  4194. end;
  4195. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  4196. end;
  4197. begin
  4198. if needs_prop_entry(psym(sym)) then
  4199. case psym(sym)^.typ of
  4200. varsym:
  4201. begin
  4202. {$ifdef dummy}
  4203. if not(pvarsym(sym)^.vartype.def^.deftype=objectdef) or
  4204. not(pobjectdef(pvarsym(sym)^.vartype.def)^.is_class) then
  4205. internalerror(1509992);
  4206. { access to implicit class property as field }
  4207. proctypesinfo:=(0 shl 0) or (0 shl 2) or (0 shl 4);
  4208. rttilist^.concat(new(pai_const_symbol,initname(pvarsym(sym)^.vartype.def^.get_rtti_label)));
  4209. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  4210. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  4211. { per default stored }
  4212. rttilist^.concat(new(pai_const,init_32bit(1)));
  4213. { index as well as ... }
  4214. rttilist^.concat(new(pai_const,init_32bit(0)));
  4215. { default value are zero }
  4216. rttilist^.concat(new(pai_const,init_32bit(0)));
  4217. rttilist^.concat(new(pai_const,init_16bit(count)));
  4218. inc(count);
  4219. rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
  4220. rttilist^.concat(new(pai_const,init_8bit(length(pvarsym(sym)^.realname))));
  4221. rttilist^.concat(new(pai_string,init(pvarsym(sym)^.realname)));
  4222. {$endif dummy}
  4223. end;
  4224. propertysym:
  4225. begin
  4226. if ppo_indexed in ppropertysym(sym)^.propoptions then
  4227. proctypesinfo:=$40
  4228. else
  4229. proctypesinfo:=0;
  4230. rttilist^.concat(new(pai_const_symbol,initname(ppropertysym(sym)^.proptype.def^.get_rtti_label)));
  4231. writeproc(ppropertysym(sym)^.readaccess,0);
  4232. writeproc(ppropertysym(sym)^.writeaccess,2);
  4233. { isn't it stored ? }
  4234. if not(ppo_stored in ppropertysym(sym)^.propoptions) then
  4235. begin
  4236. rttilist^.concat(new(pai_const,init_32bit(0)));
  4237. proctypesinfo:=proctypesinfo or (3 shl 4);
  4238. end
  4239. else
  4240. writeproc(ppropertysym(sym)^.storedaccess,4);
  4241. rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.index)));
  4242. rttilist^.concat(new(pai_const,init_32bit(ppropertysym(sym)^.default)));
  4243. rttilist^.concat(new(pai_const,init_16bit(count)));
  4244. inc(count);
  4245. rttilist^.concat(new(pai_const,init_8bit(proctypesinfo)));
  4246. rttilist^.concat(new(pai_const,init_8bit(length(ppropertysym(sym)^.realname))));
  4247. rttilist^.concat(new(pai_string,init(ppropertysym(sym)^.realname)));
  4248. end;
  4249. else internalerror(1509992);
  4250. end;
  4251. end;
  4252. procedure generate_published_child_rtti(sym : pnamedindexobject);
  4253. begin
  4254. if needs_prop_entry(psym(sym)) then
  4255. case psym(sym)^.typ of
  4256. varsym:
  4257. ;
  4258. { now ignored:
  4259. pvarsym(sym)^.vartype.def^.get_rtti_label;
  4260. }
  4261. propertysym:
  4262. ppropertysym(sym)^.proptype.def^.get_rtti_label;
  4263. else
  4264. internalerror(1509991);
  4265. end;
  4266. end;
  4267. procedure tobjectdef.write_child_rtti_data;
  4268. begin
  4269. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}generate_published_child_rtti);
  4270. end;
  4271. procedure tobjectdef.generate_rtti;
  4272. begin
  4273. if not has_rtti then
  4274. begin
  4275. has_rtti:=true;
  4276. getdatalabel(rtti_label);
  4277. write_child_rtti_data;
  4278. rttilist^.concat(new(pai_symbol,initname_global(rtti_name,0)));
  4279. rttilist^.concat(new(pai_label,init(rtti_label)));
  4280. write_rtti_data;
  4281. rttilist^.concat(new(pai_symbol_end,initname(rtti_name)));
  4282. end;
  4283. end;
  4284. type
  4285. tclasslistitem = object(tlinkedlist_item)
  4286. index : longint;
  4287. p : pobjectdef;
  4288. end;
  4289. pclasslistitem = ^tclasslistitem;
  4290. var
  4291. classtablelist : tlinkedlist;
  4292. tablecount : longint;
  4293. function searchclasstablelist(p : pobjectdef) : pclasslistitem;
  4294. var
  4295. hp : pclasslistitem;
  4296. begin
  4297. hp:=pclasslistitem(classtablelist.first);
  4298. while assigned(hp) do
  4299. if hp^.p=p then
  4300. begin
  4301. searchclasstablelist:=hp;
  4302. exit;
  4303. end
  4304. else
  4305. hp:=pclasslistitem(hp^.next);
  4306. searchclasstablelist:=nil;
  4307. end;
  4308. procedure count_published_fields(sym:pnamedindexobject);
  4309. var
  4310. hp : pclasslistitem;
  4311. begin
  4312. if needs_prop_entry(psym(sym)) and
  4313. (psym(sym)^.typ=varsym) then
  4314. begin
  4315. if pvarsym(sym)^.vartype.def^.deftype<>objectdef then
  4316. internalerror(0206001);
  4317. hp:=searchclasstablelist(pobjectdef(pvarsym(sym)^.vartype.def));
  4318. if not(assigned(hp)) then
  4319. begin
  4320. hp:=new(pclasslistitem,init);
  4321. hp^.p:=pobjectdef(pvarsym(sym)^.vartype.def);
  4322. hp^.index:=tablecount;
  4323. classtablelist.concat(hp);
  4324. inc(tablecount);
  4325. end;
  4326. inc(count);
  4327. end;
  4328. end;
  4329. procedure writefields(sym:pnamedindexobject);
  4330. var
  4331. hp : pclasslistitem;
  4332. begin
  4333. if needs_prop_entry(psym(sym)) and
  4334. (psym(sym)^.typ=varsym) then
  4335. begin
  4336. rttilist^.concat(new(pai_const,init_32bit(pvarsym(sym)^.address)));
  4337. hp:=searchclasstablelist(pobjectdef(pvarsym(sym)^.vartype.def));
  4338. if not(assigned(hp)) then
  4339. internalerror(0206002);
  4340. rttilist^.concat(new(pai_const,init_16bit(hp^.index)));
  4341. rttilist^.concat(new(pai_const,init_8bit(length(pvarsym(sym)^.realname))));
  4342. rttilist^.concat(new(pai_string,init(pvarsym(sym)^.realname)));
  4343. end;
  4344. end;
  4345. function tobjectdef.generate_field_table : pasmlabel;
  4346. var
  4347. fieldtable,
  4348. classtable : pasmlabel;
  4349. hp : pclasslistitem;
  4350. begin
  4351. classtablelist.init;
  4352. getdatalabel(fieldtable);
  4353. getdatalabel(classtable);
  4354. count:=0;
  4355. tablecount:=0;
  4356. symtable^.foreach({$ifdef FPC}@{$endif}count_published_fields);
  4357. rttilist^.concat(new(pai_label,init(fieldtable)));
  4358. rttilist^.concat(new(pai_const,init_16bit(count)));
  4359. rttilist^.concat(new(pai_const_symbol,init(classtable)));
  4360. symtable^.foreach({$ifdef FPC}@{$endif}writefields);
  4361. { generate the class table }
  4362. rttilist^.concat(new(pai_label,init(classtable)));
  4363. rttilist^.concat(new(pai_const,init_16bit(tablecount)));
  4364. hp:=pclasslistitem(classtablelist.first);
  4365. while assigned(hp) do
  4366. begin
  4367. rttilist^.concat(new(pai_const_symbol,initname(pobjectdef(hp^.p)^.vmt_mangledname)));
  4368. hp:=pclasslistitem(hp^.next);
  4369. end;
  4370. generate_field_table:=fieldtable;
  4371. classtablelist.done;
  4372. end;
  4373. function tobjectdef.next_free_name_index : longint;
  4374. var
  4375. i : longint;
  4376. begin
  4377. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  4378. i:=childof^.next_free_name_index
  4379. else
  4380. i:=0;
  4381. count:=0;
  4382. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
  4383. next_free_name_index:=i+count;
  4384. end;
  4385. procedure tobjectdef.write_rtti_data;
  4386. begin
  4387. case objecttype of
  4388. odt_class: rttilist^.concat(new(pai_const,init_8bit(tkclass)));
  4389. odt_object: rttilist^.concat(new(pai_const,init_8bit(tkobject)));
  4390. odt_interfacecom: rttilist^.concat(new(pai_const,init_8bit(tkinterface)));
  4391. odt_interfacecorba: rttilist^.concat(new(pai_const,init_8bit(tkinterfaceCorba)));
  4392. else
  4393. exit;
  4394. end;
  4395. { generate the name }
  4396. rttilist^.concat(new(pai_const,init_8bit(length(objname^))));
  4397. rttilist^.concat(new(pai_string,init(objname^)));
  4398. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  4399. rttilist^.concat(new(pai_const,init_32bit(0)))
  4400. else
  4401. rttilist^.concat(new(pai_const_symbol,initname(vmt_mangledname)));
  4402. { write owner typeinfo }
  4403. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  4404. rttilist^.concat(new(pai_const_symbol,initname(childof^.get_rtti_label)))
  4405. else
  4406. rttilist^.concat(new(pai_const,init_32bit(0)));
  4407. { count total number of properties }
  4408. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  4409. count:=childof^.next_free_name_index
  4410. else
  4411. count:=0;
  4412. { write it }
  4413. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
  4414. rttilist^.concat(new(pai_const,init_16bit(count)));
  4415. { write unit name }
  4416. rttilist^.concat(new(pai_const,init_8bit(length(current_module^.realmodulename^))));
  4417. rttilist^.concat(new(pai_string,init(current_module^.realmodulename^)));
  4418. { write published properties count }
  4419. count:=0;
  4420. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
  4421. rttilist^.concat(new(pai_const,init_16bit(count)));
  4422. { count is used to write nameindex }
  4423. { but we need an offset of the owner }
  4424. { to give each property an own slot }
  4425. if assigned(childof) and (oo_can_have_published in childof^.objectoptions) then
  4426. count:=childof^.next_free_name_index
  4427. else
  4428. count:=0;
  4429. symtable^.foreach({$ifdef FPCPROCVAR}@{$endif}write_property_info);
  4430. end;
  4431. function tobjectdef.is_publishable : boolean;
  4432. begin
  4433. is_publishable:=objecttype in [odt_class,odt_interfacecom,odt_interfacecorba];
  4434. end;
  4435. function tobjectdef.get_rtti_label : string;
  4436. begin
  4437. generate_rtti;
  4438. get_rtti_label:=rtti_name;
  4439. end;
  4440. {****************************************************************************
  4441. TIMPLEMENTEDINTERFACES
  4442. ****************************************************************************}
  4443. type
  4444. pnamemap = ^tnamemap;
  4445. tnamemap = object(tnamedindexobject)
  4446. newname: pstring;
  4447. constructor init(const aname, anewname: string);
  4448. destructor done; virtual;
  4449. end;
  4450. constructor tnamemap.init(const aname, anewname: string);
  4451. begin
  4452. inherited initname(name);
  4453. newname:=stringdup(anewname);
  4454. end;
  4455. destructor tnamemap.done;
  4456. begin
  4457. stringdispose(newname);
  4458. inherited done;
  4459. end;
  4460. type
  4461. pprocdefstore = ^tprocdefstore;
  4462. tprocdefstore = object(tnamedindexobject)
  4463. procdef: pprocdef;
  4464. constructor init(aprocdef: pprocdef);
  4465. end;
  4466. constructor tprocdefstore.init(aprocdef: pprocdef);
  4467. begin
  4468. inherited init;
  4469. procdef:=aprocdef;
  4470. end;
  4471. type
  4472. pimplintfentry = ^timplintfentry;
  4473. timplintfentry = object(tnamedindexobject)
  4474. intf: pobjectdef;
  4475. ioffs: longint;
  4476. namemappings: pdictionary;
  4477. procdefs: pindexarray;
  4478. constructor init(aintf: pobjectdef);
  4479. destructor done; virtual;
  4480. end;
  4481. constructor timplintfentry.init(aintf: pobjectdef);
  4482. begin
  4483. inherited init;
  4484. intf:=aintf;
  4485. ioffs:=-1;
  4486. namemappings:=nil;
  4487. procdefs:=nil;
  4488. end;
  4489. destructor timplintfentry.done;
  4490. begin
  4491. if assigned(namemappings) then
  4492. dispose(namemappings,done);
  4493. if assigned(procdefs) then
  4494. dispose(procdefs,done);
  4495. inherited done;
  4496. end;
  4497. constructor timplementedinterfaces.init;
  4498. begin
  4499. finterfaces.init(1);
  4500. end;
  4501. destructor timplementedinterfaces.done;
  4502. begin
  4503. finterfaces.done;
  4504. end;
  4505. function timplementedinterfaces.count: longint;
  4506. begin
  4507. count:=finterfaces.count;
  4508. end;
  4509. procedure timplementedinterfaces.checkindex(intfindex: longint);
  4510. begin
  4511. if (intfindex<1) or (intfindex>count) then
  4512. InternalError(200006123);
  4513. end;
  4514. function timplementedinterfaces.interfaces(intfindex: longint): pobjectdef;
  4515. begin
  4516. checkindex(intfindex);
  4517. interfaces:=pimplintfentry(finterfaces.search(intfindex))^.intf;
  4518. end;
  4519. function timplementedinterfaces.ioffsets(intfindex: longint): plongint;
  4520. begin
  4521. checkindex(intfindex);
  4522. ioffsets:=@pimplintfentry(finterfaces.search(intfindex))^.ioffs;
  4523. end;
  4524. function timplementedinterfaces.searchintf(def: pdef): longint;
  4525. var
  4526. i: longint;
  4527. begin
  4528. i:=1;
  4529. while (i<=count) and (pdef(interfaces(i))<>def) do inc(i);
  4530. if i<=count then
  4531. searchintf:=i
  4532. else
  4533. searchintf:=-1;
  4534. end;
  4535. procedure timplementedinterfaces.deref;
  4536. var
  4537. i: longint;
  4538. begin
  4539. for i:=1 to count do
  4540. with pimplintfentry(finterfaces.search(i))^ do
  4541. resolvedef(pdef(intf));
  4542. end;
  4543. procedure timplementedinterfaces.addintfref(def: pdef);
  4544. begin
  4545. finterfaces.insert(new(pimplintfentry,init(pobjectdef(def))));
  4546. end;
  4547. procedure timplementedinterfaces.addintf(def: pdef);
  4548. begin
  4549. if not assigned(def) or (searchintf(def)<>-1) or (def^.deftype<>objectdef) or
  4550. not (pobjectdef(def)^.objecttype in [odt_interfacecom,odt_interfacecorba]) then
  4551. internalerror(200006124);
  4552. finterfaces.insert(new(pimplintfentry,init(pobjectdef(def))));
  4553. end;
  4554. procedure timplementedinterfaces.clearmappings;
  4555. var
  4556. i: longint;
  4557. begin
  4558. for i:=1 to count do
  4559. with pimplintfentry(finterfaces.search(i))^ do
  4560. begin
  4561. if assigned(namemappings) then
  4562. dispose(namemappings,done);
  4563. namemappings:=nil;
  4564. end;
  4565. end;
  4566. procedure timplementedinterfaces.addmappings(intfindex: longint; const name, newname: string);
  4567. begin
  4568. checkindex(intfindex);
  4569. with pimplintfentry(finterfaces.search(intfindex))^ do
  4570. begin
  4571. if not assigned(namemappings) then
  4572. new(namemappings,init);
  4573. namemappings^.insert(new(pnamemap,init(name,newname)));
  4574. end;
  4575. end;
  4576. function timplementedinterfaces.getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
  4577. begin
  4578. checkindex(intfindex);
  4579. if not assigned(nextexist) then
  4580. with pimplintfentry(finterfaces.search(intfindex))^ do
  4581. begin
  4582. if assigned(namemappings) then
  4583. nextexist:=namemappings^.search(name)
  4584. else
  4585. nextexist:=nil;
  4586. end;
  4587. if assigned(nextexist) then
  4588. begin
  4589. getmappings:=pnamemap(nextexist)^.newname^;
  4590. nextexist:=pnamemap(nextexist)^.listnext;
  4591. end
  4592. else
  4593. getmappings:='';
  4594. end;
  4595. procedure timplementedinterfaces.clearimplprocs;
  4596. var
  4597. i: longint;
  4598. begin
  4599. for i:=1 to count do
  4600. with pimplintfentry(finterfaces.search(i))^ do
  4601. begin
  4602. if assigned(procdefs) then
  4603. dispose(procdefs,done);
  4604. procdefs:=nil;
  4605. end;
  4606. end;
  4607. procedure timplementedinterfaces.addimplproc(intfindex: longint; procdef: pprocdef);
  4608. begin
  4609. checkindex(intfindex);
  4610. with pimplintfentry(finterfaces.search(intfindex))^ do
  4611. begin
  4612. if not assigned(procdefs) then
  4613. new(procdefs,init(4));
  4614. procdefs^.insert(new(pprocdefstore,init(procdef)));
  4615. end;
  4616. end;
  4617. function timplementedinterfaces.implproccount(intfindex: longint): longint;
  4618. begin
  4619. checkindex(intfindex);
  4620. with pimplintfentry(finterfaces.search(intfindex))^ do
  4621. if assigned(procdefs) then
  4622. implproccount:=procdefs^.count
  4623. else
  4624. implproccount:=0;
  4625. end;
  4626. function timplementedinterfaces.implprocs(intfindex: longint; procindex: longint): pprocdef;
  4627. begin
  4628. checkindex(intfindex);
  4629. with pimplintfentry(finterfaces.search(intfindex))^ do
  4630. if assigned(procdefs) then
  4631. implprocs:=pprocdefstore(procdefs^.search(procindex))^.procdef
  4632. else
  4633. internalerror(200006131);
  4634. end;
  4635. function timplementedinterfaces.isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
  4636. var
  4637. possible: boolean;
  4638. i: longint;
  4639. iiep1: pindexarray;
  4640. iiep2: pindexarray;
  4641. begin
  4642. checkindex(intfindex);
  4643. checkindex(remainindex);
  4644. iiep1:=pimplintfentry(finterfaces.search(intfindex))^.procdefs;
  4645. iiep2:=pimplintfentry(finterfaces.search(remainindex))^.procdefs;
  4646. if not assigned(iiep1) then { empty interface is mergeable :-) }
  4647. begin
  4648. possible:=true;
  4649. weight:=0;
  4650. end
  4651. else
  4652. begin
  4653. possible:=assigned(iiep2) and (iiep1^.count<=iiep2^.count);
  4654. i:=1;
  4655. while (possible) and (i<=iiep1^.count) do
  4656. begin
  4657. possible:=
  4658. pprocdefstore(iiep1^.search(i))^.procdef=
  4659. pprocdefstore(iiep2^.search(i))^.procdef;
  4660. inc(i);
  4661. end;
  4662. if possible then
  4663. weight:=iiep1^.count;
  4664. end;
  4665. isimplmergepossible:=possible;
  4666. end;
  4667. {****************************************************************************
  4668. TFORWARDDEF
  4669. ****************************************************************************}
  4670. constructor tforwarddef.init(const s:string;const pos : tfileposinfo);
  4671. var
  4672. oldregisterdef : boolean;
  4673. begin
  4674. { never register the forwarddefs, they are disposed at the
  4675. end of the type declaration block }
  4676. oldregisterdef:=registerdef;
  4677. registerdef:=false;
  4678. inherited init;
  4679. registerdef:=oldregisterdef;
  4680. deftype:=forwarddef;
  4681. tosymname:=s;
  4682. forwardpos:=pos;
  4683. end;
  4684. function tforwarddef.gettypename:string;
  4685. begin
  4686. gettypename:='unresolved forward to '+tosymname;
  4687. end;
  4688. {****************************************************************************
  4689. TERRORDEF
  4690. ****************************************************************************}
  4691. constructor terrordef.init;
  4692. begin
  4693. inherited init;
  4694. deftype:=errordef;
  4695. end;
  4696. {$ifdef GDB}
  4697. function terrordef.stabstring : pchar;
  4698. begin
  4699. stabstring:=strpnew('error'+numberstring);
  4700. end;
  4701. {$endif GDB}
  4702. function terrordef.gettypename:string;
  4703. begin
  4704. gettypename:='<erroneous type>';
  4705. end;
  4706. {****************************************************************************
  4707. GDB Helpers
  4708. ****************************************************************************}
  4709. {$ifdef GDB}
  4710. function typeglobalnumber(const s : string) : string;
  4711. var st : string;
  4712. symt : psymtable;
  4713. old_make_ref : boolean;
  4714. begin
  4715. old_make_ref:=make_ref;
  4716. make_ref:=false;
  4717. typeglobalnumber := '0';
  4718. srsym := nil;
  4719. if pos('.',s) > 0 then
  4720. begin
  4721. st := copy(s,1,pos('.',s)-1);
  4722. getsym(st,false);
  4723. st := copy(s,pos('.',s)+1,255);
  4724. if assigned(srsym) then
  4725. begin
  4726. if srsym^.typ = unitsym then
  4727. begin
  4728. symt := punitsym(srsym)^.unitsymtable;
  4729. srsym := psym(symt^.search(st));
  4730. end else srsym := nil;
  4731. end;
  4732. end else st := s;
  4733. if srsym = nil then getsym(st,true);
  4734. if srsym^.typ<>typesym then
  4735. begin
  4736. Message(type_e_type_id_expected);
  4737. exit;
  4738. end;
  4739. typeglobalnumber := pstoreddef(ptypesym(srsym)^.restype.def)^.numberstring;
  4740. make_ref:=old_make_ref;
  4741. end;
  4742. {$endif GDB}
  4743. {****************************************************************************
  4744. Definition Helpers
  4745. ****************************************************************************}
  4746. procedure reset_global_defs;
  4747. var
  4748. def : pstoreddef;
  4749. {$ifdef debug}
  4750. prevdef : pstoreddef;
  4751. {$endif debug}
  4752. begin
  4753. {$ifdef debug}
  4754. prevdef:=nil;
  4755. {$endif debug}
  4756. {$ifdef GDB}
  4757. pglobaltypecount:=@globaltypecount;
  4758. {$endif GDB}
  4759. def:=firstglobaldef;
  4760. while assigned(def) do
  4761. begin
  4762. {$ifdef GDB}
  4763. if assigned(def^.typesym) then
  4764. ptypesym(def^.typesym)^.isusedinstab:=false;
  4765. def^.is_def_stab_written:=not_written;
  4766. {$endif GDB}
  4767. {if not current_module^.in_implementation then}
  4768. begin
  4769. { reset rangenr's }
  4770. case def^.deftype of
  4771. orddef : porddef(def)^.rangenr:=0;
  4772. enumdef : penumdef(def)^.rangenr:=0;
  4773. arraydef : parraydef(def)^.rangenr:=0;
  4774. end;
  4775. if def^.deftype<>objectdef then
  4776. def^.has_rtti:=false;
  4777. def^.has_inittable:=false;
  4778. end;
  4779. {$ifdef debug}
  4780. prevdef:=def;
  4781. {$endif debug}
  4782. def:=def^.nextglobal;
  4783. end;
  4784. end;
  4785. function is_interfacecom(def: pdef): boolean;
  4786. begin
  4787. is_interfacecom:=
  4788. assigned(def) and
  4789. (def^.deftype=objectdef) and
  4790. (pobjectdef(def)^.objecttype=odt_interfacecom);
  4791. end;
  4792. function is_interfacecorba(def: pdef): boolean;
  4793. begin
  4794. is_interfacecorba:=
  4795. assigned(def) and
  4796. (def^.deftype=objectdef) and
  4797. (pobjectdef(def)^.objecttype=odt_interfacecorba);
  4798. end;
  4799. function is_interface(def: pdef): boolean;
  4800. begin
  4801. is_interface:=
  4802. assigned(def) and
  4803. (def^.deftype=objectdef) and
  4804. (pobjectdef(def)^.objecttype in [odt_interfacecom,odt_interfacecorba]);
  4805. end;
  4806. function is_class(def: pdef): boolean;
  4807. begin
  4808. is_class:=
  4809. assigned(def) and
  4810. (def^.deftype=objectdef) and
  4811. (pobjectdef(def)^.objecttype=odt_class);
  4812. end;
  4813. function is_object(def: pdef): boolean;
  4814. begin
  4815. is_object:=
  4816. assigned(def) and
  4817. (def^.deftype=objectdef) and
  4818. (pobjectdef(def)^.objecttype=odt_object);
  4819. end;
  4820. function is_cppclass(def: pdef): boolean;
  4821. begin
  4822. is_cppclass:=
  4823. assigned(def) and
  4824. (def^.deftype=objectdef) and
  4825. (pobjectdef(def)^.objecttype=odt_cppclass);
  4826. end;
  4827. function is_class_or_interface(def: pdef): boolean;
  4828. begin
  4829. is_class_or_interface:=
  4830. assigned(def) and
  4831. (def^.deftype=objectdef) and
  4832. (pobjectdef(def)^.objecttype in [odt_class,odt_interfacecom,odt_interfacecorba]);
  4833. end;
  4834. end.
  4835. {
  4836. $Log$
  4837. Revision 1.9 2000-11-07 20:01:57 peter
  4838. * fix vmt index for classes
  4839. Revision 1.8 2000/11/06 23:13:53 peter
  4840. * uppercase manglednames
  4841. Revision 1.7 2000/11/06 23:11:38 florian
  4842. * writeln debugger uninstalled ;)
  4843. Revision 1.6 2000/11/06 23:05:52 florian
  4844. * more fixes
  4845. Revision 1.5 2000/11/06 20:30:55 peter
  4846. * more fixes to get make cycle working
  4847. Revision 1.4 2000/11/04 14:25:22 florian
  4848. + merged Attila's changes for interfaces, not tested yet
  4849. Revision 1.3 2000/11/02 12:04:10 pierre
  4850. * remove RecOffset code, that created problems
  4851. Revision 1.2 2000/11/01 23:04:38 peter
  4852. * tprocdef.fullprocname added for better casesensitve writing of
  4853. procedures
  4854. Revision 1.1 2000/10/31 22:02:52 peter
  4855. * symtable splitted, no real code changes
  4856. }