symdef.pas 197 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353
  1. {
  2. $Id$
  3. Copyright (c) 1998-2002 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 fpcdefs.inc}
  20. interface
  21. uses
  22. { common }
  23. cutils,cclasses,
  24. { global }
  25. globtype,globals,tokens,
  26. { symtable }
  27. symconst,symbase,symtype,
  28. { ppu }
  29. symppu,ppu,
  30. { node }
  31. node,
  32. { aasm }
  33. aasmbase,aasmtai,
  34. cpubase,cpuinfo,
  35. cgbase
  36. {$ifdef Delphi}
  37. ,dmisc
  38. {$endif}
  39. ;
  40. type
  41. {************************************************
  42. TDef
  43. ************************************************}
  44. tstoreddef = class(tdef)
  45. typesymderef : tderef;
  46. { persistent (available across units) rtti and init tables }
  47. rttitablesym,
  48. inittablesym : tsym; {trttisym}
  49. rttitablesymderef,
  50. inittablesymderef : tderef;
  51. { local (per module) rtti and init tables }
  52. localrttilab : array[trttitype] of tasmlabel;
  53. { linked list of global definitions }
  54. nextglobal,
  55. previousglobal : tstoreddef;
  56. {$ifdef EXTDEBUG}
  57. fileinfo : tfileposinfo;
  58. {$endif}
  59. {$ifdef GDB}
  60. globalnb : word;
  61. is_def_stab_written : tdefstabstatus;
  62. {$endif GDB}
  63. constructor create;
  64. constructor ppuloaddef(ppufile:tcompilerppufile);
  65. destructor destroy;override;
  66. function getcopy : tstoreddef;virtual;
  67. procedure ppuwritedef(ppufile:tcompilerppufile);
  68. procedure ppuwrite(ppufile:tcompilerppufile);virtual;abstract;
  69. procedure deref;override;
  70. procedure derefimpl;override;
  71. function size:longint;override;
  72. function alignment:longint;override;
  73. function is_publishable : boolean;override;
  74. function needs_inittable : boolean;override;
  75. { debug }
  76. {$ifdef GDB}
  77. function stabstring : pchar;virtual;
  78. procedure concatstabto(asmlist : taasmoutput);virtual;
  79. function NumberString:string;
  80. procedure set_globalnb;virtual;
  81. function allstabstring : pchar;virtual;
  82. {$endif GDB}
  83. { rtti generation }
  84. procedure write_rtti_name;
  85. procedure write_rtti_data(rt:trttitype);virtual;
  86. procedure write_child_rtti_data(rt:trttitype);virtual;
  87. function get_rtti_label(rt:trttitype):tasmsymbol;
  88. { regvars }
  89. function is_intregable : boolean;
  90. function is_fpuregable : boolean;
  91. private
  92. savesize : longint;
  93. end;
  94. tparaitem = class(TLinkedListItem)
  95. paratype : ttype; { required for procvar }
  96. parasym : tsym;
  97. parasymderef : tderef;
  98. defaultvalue : tsym; { tconstsym }
  99. defaultvaluederef : tderef;
  100. paratyp : tvarspez; { required for procvar }
  101. paraloc : array[tcallercallee] of tparalocation;
  102. is_hidden : boolean; { is this a hidden (implicit) parameter }
  103. {$ifdef EXTDEBUG}
  104. eqval : tequaltype;
  105. {$endif EXTDEBUG}
  106. end;
  107. tfiletyp = (ft_text,ft_typed,ft_untyped);
  108. tfiledef = class(tstoreddef)
  109. filetyp : tfiletyp;
  110. typedfiletype : ttype;
  111. constructor createtext;
  112. constructor createuntyped;
  113. constructor createtyped(const tt : ttype);
  114. constructor ppuload(ppufile:tcompilerppufile);
  115. procedure ppuwrite(ppufile:tcompilerppufile);override;
  116. procedure deref;override;
  117. function gettypename:string;override;
  118. function getmangledparaname:string;override;
  119. procedure setsize;
  120. { debug }
  121. {$ifdef GDB}
  122. function stabstring : pchar;override;
  123. procedure concatstabto(asmlist : taasmoutput);override;
  124. {$endif GDB}
  125. end;
  126. tvariantdef = class(tstoreddef)
  127. constructor create;
  128. constructor ppuload(ppufile:tcompilerppufile);
  129. function gettypename:string;override;
  130. procedure ppuwrite(ppufile:tcompilerppufile);override;
  131. procedure setsize;
  132. function needs_inittable : boolean;override;
  133. procedure write_rtti_data(rt:trttitype);override;
  134. {$ifdef GDB}
  135. procedure concatstabto(asmlist : taasmoutput);override;
  136. {$endif GDB}
  137. end;
  138. tformaldef = class(tstoreddef)
  139. constructor create;
  140. constructor ppuload(ppufile:tcompilerppufile);
  141. procedure ppuwrite(ppufile:tcompilerppufile);override;
  142. function gettypename:string;override;
  143. {$ifdef GDB}
  144. function stabstring : pchar;override;
  145. procedure concatstabto(asmlist : taasmoutput);override;
  146. {$endif GDB}
  147. end;
  148. tforwarddef = class(tstoreddef)
  149. tosymname : pstring;
  150. forwardpos : tfileposinfo;
  151. constructor create(const s:string;const pos : tfileposinfo);
  152. destructor destroy;override;
  153. function gettypename:string;override;
  154. end;
  155. terrordef = class(tstoreddef)
  156. constructor create;
  157. function gettypename:string;override;
  158. function getmangledparaname : string;override;
  159. { debug }
  160. {$ifdef GDB}
  161. function stabstring : pchar;override;
  162. procedure concatstabto(asmlist : taasmoutput);override;
  163. {$endif GDB}
  164. end;
  165. { tpointerdef and tclassrefdef should get a common
  166. base class, but I derived tclassrefdef from tpointerdef
  167. to avoid problems with bugs (FK)
  168. }
  169. tpointerdef = class(tstoreddef)
  170. pointertype : ttype;
  171. is_far : boolean;
  172. constructor create(const tt : ttype);
  173. constructor createfar(const tt : ttype);
  174. constructor ppuload(ppufile:tcompilerppufile);
  175. procedure ppuwrite(ppufile:tcompilerppufile);override;
  176. procedure deref;override;
  177. function gettypename:string;override;
  178. { debug }
  179. {$ifdef GDB}
  180. function stabstring : pchar;override;
  181. procedure concatstabto(asmlist : taasmoutput);override;
  182. {$endif GDB}
  183. end;
  184. tabstractrecorddef = class(tstoreddef)
  185. private
  186. Count : integer;
  187. FRTTIType : trttitype;
  188. {$ifdef GDB}
  189. StabRecString : pchar;
  190. StabRecSize : Integer;
  191. RecOffset : Integer;
  192. procedure addname(p : tnamedindexitem;arg:pointer);
  193. {$endif}
  194. procedure count_field_rtti(sym : tnamedindexitem;arg:pointer);
  195. procedure write_field_rtti(sym : tnamedindexitem;arg:pointer);
  196. procedure generate_field_rtti(sym : tnamedindexitem;arg:pointer);
  197. public
  198. symtable : tsymtable;
  199. function getsymtable(t:tgetsymtable):tsymtable;override;
  200. end;
  201. trecorddef = class(tabstractrecorddef)
  202. public
  203. isunion : boolean;
  204. constructor create(p : tsymtable);
  205. constructor ppuload(ppufile:tcompilerppufile);
  206. destructor destroy;override;
  207. procedure ppuwrite(ppufile:tcompilerppufile);override;
  208. procedure deref;override;
  209. function size:longint;override;
  210. function alignment : longint;override;
  211. function gettypename:string;override;
  212. { debug }
  213. {$ifdef GDB}
  214. function stabstring : pchar;override;
  215. procedure concatstabto(asmlist : taasmoutput);override;
  216. {$endif GDB}
  217. function needs_inittable : boolean;override;
  218. { rtti }
  219. procedure write_child_rtti_data(rt:trttitype);override;
  220. procedure write_rtti_data(rt:trttitype);override;
  221. end;
  222. tprocdef = class;
  223. timplementedinterfaces = class;
  224. tobjectdef = class(tabstractrecorddef)
  225. private
  226. {$ifdef GDB}
  227. procedure addprocname(p :tnamedindexitem;arg:pointer);
  228. {$endif GDB}
  229. procedure count_published_properties(sym:tnamedindexitem;arg:pointer);
  230. procedure write_property_info(sym : tnamedindexitem;arg:pointer);
  231. procedure generate_published_child_rtti(sym : tnamedindexitem;arg:pointer);
  232. procedure count_published_fields(sym:tnamedindexitem;arg:pointer);
  233. procedure writefields(sym:tnamedindexitem;arg:pointer);
  234. public
  235. childof : tobjectdef;
  236. childofderef : tderef;
  237. objname,
  238. objrealname : pstring;
  239. objectoptions : tobjectoptions;
  240. { to be able to have a variable vmt position }
  241. { and no vmt field for objects without virtuals }
  242. vmt_offset : longint;
  243. {$ifdef GDB}
  244. writing_class_record_stab : boolean;
  245. {$endif GDB}
  246. objecttype : tobjectdeftype;
  247. iidguid: pguid;
  248. iidstr: pstring;
  249. lastvtableindex: longint;
  250. { store implemented interfaces defs and name mappings }
  251. implementedinterfaces: timplementedinterfaces;
  252. constructor create(ot : tobjectdeftype;const n : string;c : tobjectdef);
  253. constructor ppuload(ppufile:tcompilerppufile);
  254. destructor destroy;override;
  255. procedure ppuwrite(ppufile:tcompilerppufile);override;
  256. function gettypename:string;override;
  257. procedure deref;override;
  258. function getparentdef:tdef;override;
  259. function size : longint;override;
  260. function alignment:longint;override;
  261. function vmtmethodoffset(index:longint):longint;
  262. function members_need_inittable : boolean;
  263. { this should be called when this class implements an interface }
  264. procedure prepareguid;
  265. function is_publishable : boolean;override;
  266. function needs_inittable : boolean;override;
  267. function vmt_mangledname : string;
  268. function rtti_name : string;
  269. procedure check_forwards;
  270. function is_related(d : tobjectdef) : boolean;
  271. function next_free_name_index : longint;
  272. procedure insertvmt;
  273. procedure set_parent(c : tobjectdef);
  274. function searchdestructor : tprocdef;
  275. { debug }
  276. {$ifdef GDB}
  277. function stabstring : pchar;override;
  278. procedure set_globalnb;override;
  279. function classnumberstring : string;
  280. procedure concatstabto(asmlist : taasmoutput);override;
  281. function allstabstring : pchar;override;
  282. {$endif GDB}
  283. { rtti }
  284. procedure write_child_rtti_data(rt:trttitype);override;
  285. procedure write_rtti_data(rt:trttitype);override;
  286. function generate_field_table : tasmlabel;
  287. end;
  288. timplementedinterfaces = class
  289. constructor create;
  290. destructor destroy; override;
  291. function count: longint;
  292. function interfaces(intfindex: longint): tobjectdef;
  293. function interfacesderef(intfindex: longint): tderef;
  294. function ioffsets(intfindex: longint): plongint;
  295. function searchintf(def: tdef): longint;
  296. procedure addintf(def: tdef);
  297. procedure deref;
  298. { add interface reference loaded from ppu }
  299. procedure addintf_deref(const d:tderef);
  300. procedure clearmappings;
  301. procedure addmappings(intfindex: longint; const name, newname: string);
  302. function getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
  303. procedure clearimplprocs;
  304. procedure addimplproc(intfindex: longint; procdef: tprocdef);
  305. function implproccount(intfindex: longint): longint;
  306. function implprocs(intfindex: longint; procindex: longint): tprocdef;
  307. function isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
  308. private
  309. finterfaces: tindexarray;
  310. procedure checkindex(intfindex: longint);
  311. end;
  312. tclassrefdef = class(tpointerdef)
  313. constructor create(const t:ttype);
  314. constructor ppuload(ppufile:tcompilerppufile);
  315. procedure ppuwrite(ppufile:tcompilerppufile);override;
  316. function gettypename:string;override;
  317. { debug }
  318. {$ifdef GDB}
  319. function stabstring : pchar;override;
  320. procedure concatstabto(asmlist : taasmoutput);override;
  321. {$endif GDB}
  322. end;
  323. tarraydef = class(tstoreddef)
  324. lowrange,
  325. highrange : longint;
  326. rangetype : ttype;
  327. IsDynamicArray,
  328. IsVariant,
  329. IsConstructor,
  330. IsArrayOfConst : boolean;
  331. protected
  332. _elementtype : ttype;
  333. public
  334. function elesize : longint;
  335. constructor create(l,h : longint;const t : ttype);
  336. constructor ppuload(ppufile:tcompilerppufile);
  337. procedure ppuwrite(ppufile:tcompilerppufile);override;
  338. function gettypename:string;override;
  339. function getmangledparaname : string;override;
  340. procedure setelementtype(t: ttype);
  341. {$ifdef GDB}
  342. function stabstring : pchar;override;
  343. procedure concatstabto(asmlist : taasmoutput);override;
  344. {$endif GDB}
  345. procedure deref;override;
  346. function size : longint;override;
  347. function alignment : longint;override;
  348. { returns the label of the range check string }
  349. function needs_inittable : boolean;override;
  350. procedure write_child_rtti_data(rt:trttitype);override;
  351. procedure write_rtti_data(rt:trttitype);override;
  352. property elementtype : ttype Read _ElementType;
  353. end;
  354. torddef = class(tstoreddef)
  355. low,high : TConstExprInt;
  356. typ : tbasetype;
  357. constructor create(t : tbasetype;v,b : TConstExprInt);
  358. constructor ppuload(ppufile:tcompilerppufile);
  359. function getcopy : tstoreddef;override;
  360. procedure ppuwrite(ppufile:tcompilerppufile);override;
  361. function is_publishable : boolean;override;
  362. function gettypename:string;override;
  363. procedure setsize;
  364. { debug }
  365. {$ifdef GDB}
  366. function stabstring : pchar;override;
  367. {$endif GDB}
  368. { rtti }
  369. procedure write_rtti_data(rt:trttitype);override;
  370. end;
  371. tfloatdef = class(tstoreddef)
  372. typ : tfloattype;
  373. constructor create(t : tfloattype);
  374. constructor ppuload(ppufile:tcompilerppufile);
  375. function getcopy : tstoreddef;override;
  376. procedure ppuwrite(ppufile:tcompilerppufile);override;
  377. function gettypename:string;override;
  378. function is_publishable : boolean;override;
  379. procedure setsize;
  380. { debug }
  381. {$ifdef GDB}
  382. function stabstring : pchar;override;
  383. {$endif GDB}
  384. { rtti }
  385. procedure write_rtti_data(rt:trttitype);override;
  386. end;
  387. tabstractprocdef = class(tstoreddef)
  388. { saves a definition to the return type }
  389. rettype : ttype;
  390. paraalign : byte;
  391. parast : tsymtable;
  392. para : tlinkedlist;
  393. proctypeoption : tproctypeoption;
  394. proccalloption : tproccalloption;
  395. procoptions : tprocoptions;
  396. maxparacount,
  397. minparacount : byte;
  398. fpu_used : byte; { how many stack fpu must be empty }
  399. funcret_paraloc : array[tcallercallee] of tparalocation;
  400. has_paraloc_info : boolean; { paraloc info is available }
  401. constructor create(level:byte);
  402. constructor ppuload(ppufile:tcompilerppufile);
  403. destructor destroy;override;
  404. procedure ppuwrite(ppufile:tcompilerppufile);override;
  405. procedure deref;override;
  406. procedure releasemem;
  407. procedure set_calloption(calloption:tproccalloption);
  408. function concatpara(afterpara:tparaitem;const tt:ttype;sym : tsym;defval:tsym;vhidden:boolean):tparaitem;
  409. function insertpara(const tt:ttype;sym : tsym;defval:tsym;vhidden:boolean):tparaitem;
  410. procedure removepara(currpara:tparaitem);
  411. function typename_paras(showhidden:boolean): string;
  412. procedure test_if_fpu_result;
  413. function is_methodpointer:boolean;virtual;
  414. function is_addressonly:boolean;virtual;
  415. { debug }
  416. {$ifdef GDB}
  417. function stabstring : pchar;override;
  418. procedure concatstabto(asmlist : taasmoutput);override;
  419. {$endif GDB}
  420. end;
  421. tprocvardef = class(tabstractprocdef)
  422. constructor create(level:byte);
  423. constructor ppuload(ppufile:tcompilerppufile);
  424. procedure ppuwrite(ppufile:tcompilerppufile);override;
  425. procedure deref;override;
  426. function getsymtable(t:tgetsymtable):tsymtable;override;
  427. function size : longint;override;
  428. function gettypename:string;override;
  429. function is_publishable : boolean;override;
  430. function is_methodpointer:boolean;override;
  431. function is_addressonly:boolean;override;
  432. { debug }
  433. {$ifdef GDB}
  434. function stabstring : pchar;override;
  435. procedure concatstabto(asmlist : taasmoutput); override;
  436. {$endif GDB}
  437. { rtti }
  438. procedure write_rtti_data(rt:trttitype);override;
  439. end;
  440. tmessageinf = record
  441. case integer of
  442. 0 : (str : pchar);
  443. 1 : (i : longint);
  444. end;
  445. tprocdef = class(tabstractprocdef)
  446. private
  447. _mangledname : pstring;
  448. {$ifdef GDB}
  449. isstabwritten : boolean;
  450. {$endif GDB}
  451. public
  452. extnumber : word;
  453. overloadnumber : word;
  454. messageinf : tmessageinf;
  455. {$ifndef EXTDEBUG}
  456. { where is this function defined and what were the symbol
  457. flags, needed here because there
  458. is only one symbol for all overloaded functions
  459. EXTDEBUG has fileinfo in tdef (PFV) }
  460. fileinfo : tfileposinfo;
  461. {$endif}
  462. symoptions : tsymoptions;
  463. { symbol owning this definition }
  464. procsym : tsym;
  465. procsymderef : tderef;
  466. { alias names }
  467. aliasnames : tstringlist;
  468. { symtables }
  469. localst : tsymtable;
  470. funcretsym : tsym;
  471. funcretsymderef : tderef;
  472. { browser info }
  473. lastref,
  474. defref,
  475. lastwritten : tref;
  476. refcount : longint;
  477. _class : tobjectdef;
  478. _classderef : tderef;
  479. { it's a tree, but this not easy to handle }
  480. { used for inlined procs }
  481. code : tnode;
  482. { info about register variables (JM) }
  483. regvarinfo: pointer;
  484. { name of the result variable to insert in the localsymtable }
  485. resultname : stringid;
  486. { true, if the procedure is only declared }
  487. { (forward procedure) }
  488. forwarddef,
  489. { true if the procedure is declared in the interface }
  490. interfacedef : boolean;
  491. { true if the procedure has a forward declaration }
  492. hasforward : boolean;
  493. { check the problems of manglednames }
  494. has_mangledname : boolean;
  495. { small set which contains the modified registers }
  496. usedintregisters:Tsuperregisterset;
  497. usedotherregisters:Totherregisterset;
  498. constructor create(level:byte);
  499. constructor ppuload(ppufile:tcompilerppufile);
  500. destructor destroy;override;
  501. procedure ppuwrite(ppufile:tcompilerppufile);override;
  502. procedure deref;override;
  503. procedure derefimpl;override;
  504. function getsymtable(t:tgetsymtable):tsymtable;override;
  505. function gettypename : string;override;
  506. function mangledname : string;
  507. procedure setmangledname(const s : string);
  508. procedure load_references(ppufile:tcompilerppufile;locals:boolean);
  509. function write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  510. { inserts the local symbol table, if this is not
  511. no local symbol table is built. Should be called only
  512. when we are sure that a local symbol table will be required.
  513. }
  514. procedure insert_localst;
  515. function fullprocname(showhidden:boolean):string;
  516. function cplusplusmangledname : string;
  517. function is_methodpointer:boolean;override;
  518. function is_addressonly:boolean;override;
  519. // function is_visible_for_proc(currprocdef:tprocdef):boolean;
  520. function is_visible_for_object(currobjdef:tobjectdef):boolean;
  521. { debug }
  522. {$ifdef GDB}
  523. function stabstring : pchar;override;
  524. procedure concatstabto(asmlist : taasmoutput);override;
  525. {$endif GDB}
  526. end;
  527. { single linked list of overloaded procs }
  528. pprocdeflist = ^tprocdeflist;
  529. tprocdeflist = record
  530. def : tprocdef;
  531. defderef : tderef;
  532. next : pprocdeflist;
  533. end;
  534. tstringdef = class(tstoreddef)
  535. string_typ : tstringtype;
  536. len : longint;
  537. constructor createshort(l : byte);
  538. constructor loadshort(ppufile:tcompilerppufile);
  539. constructor createlong(l : longint);
  540. constructor loadlong(ppufile:tcompilerppufile);
  541. constructor createansi(l : longint);
  542. constructor loadansi(ppufile:tcompilerppufile);
  543. constructor createwide(l : longint);
  544. constructor loadwide(ppufile:tcompilerppufile);
  545. function getcopy : tstoreddef;override;
  546. function stringtypname:string;
  547. function size : longint;override;
  548. procedure ppuwrite(ppufile:tcompilerppufile);override;
  549. function gettypename:string;override;
  550. function getmangledparaname:string;override;
  551. function is_publishable : boolean;override;
  552. { debug }
  553. {$ifdef GDB}
  554. function stabstring : pchar;override;
  555. procedure concatstabto(asmlist : taasmoutput);override;
  556. {$endif GDB}
  557. { init/final }
  558. function needs_inittable : boolean;override;
  559. { rtti }
  560. procedure write_rtti_data(rt:trttitype);override;
  561. end;
  562. tenumdef = class(tstoreddef)
  563. minval,
  564. maxval : longint;
  565. has_jumps : boolean;
  566. firstenum : tsym; {tenumsym}
  567. basedef : tenumdef;
  568. basedefderef : tderef;
  569. constructor create;
  570. constructor create_subrange(_basedef:tenumdef;_min,_max:longint);
  571. constructor ppuload(ppufile:tcompilerppufile);
  572. destructor destroy;override;
  573. procedure ppuwrite(ppufile:tcompilerppufile);override;
  574. procedure deref;override;
  575. function gettypename:string;override;
  576. function is_publishable : boolean;override;
  577. procedure calcsavesize;
  578. procedure setmax(_max:longint);
  579. procedure setmin(_min:longint);
  580. function min:longint;
  581. function max:longint;
  582. { debug }
  583. {$ifdef GDB}
  584. function stabstring : pchar;override;
  585. {$endif GDB}
  586. { rtti }
  587. procedure write_rtti_data(rt:trttitype);override;
  588. procedure write_child_rtti_data(rt:trttitype);override;
  589. private
  590. procedure correct_owner_symtable;
  591. end;
  592. tsetdef = class(tstoreddef)
  593. elementtype : ttype;
  594. settype : tsettype;
  595. constructor create(const t:ttype;high : longint);
  596. constructor ppuload(ppufile:tcompilerppufile);
  597. destructor destroy;override;
  598. procedure ppuwrite(ppufile:tcompilerppufile);override;
  599. procedure deref;override;
  600. function gettypename:string;override;
  601. function is_publishable : boolean;override;
  602. { debug }
  603. {$ifdef GDB}
  604. function stabstring : pchar;override;
  605. procedure concatstabto(asmlist : taasmoutput);override;
  606. {$endif GDB}
  607. { rtti }
  608. procedure write_rtti_data(rt:trttitype);override;
  609. procedure write_child_rtti_data(rt:trttitype);override;
  610. end;
  611. Tdefmatch=(dm_exact,dm_equal,dm_convertl1);
  612. var
  613. aktobjectdef : tobjectdef; { used for private functions check !! }
  614. firstglobaldef, { linked list of all globals defs }
  615. lastglobaldef : tstoreddef; { used to reset stabs/ranges }
  616. {$ifdef GDB}
  617. { for STAB debugging }
  618. globaltypecount : word;
  619. pglobaltypecount : pword;
  620. {$endif GDB}
  621. { default types }
  622. generrortype, { error in definition }
  623. voidpointertype, { pointer for Void-Pointerdef }
  624. charpointertype, { pointer for Char-Pointerdef }
  625. voidfarpointertype,
  626. cformaltype, { unique formal definition }
  627. voidtype, { Pointer to Void (procedure) }
  628. cchartype, { Pointer to Char }
  629. cwidechartype, { Pointer to WideChar }
  630. booltype, { pointer to boolean type }
  631. u8bittype, { Pointer to 8-Bit unsigned }
  632. u16bittype, { Pointer to 16-Bit unsigned }
  633. u32bittype, { Pointer to 32-Bit unsigned }
  634. s32bittype, { Pointer to 32-Bit signed }
  635. cu64bittype, { pointer to 64 bit unsigned def }
  636. cs64bittype, { pointer to 64 bit signed def, }
  637. s32floattype, { pointer for realconstn }
  638. s64floattype, { pointer for realconstn }
  639. s80floattype, { pointer to type of temp. floats }
  640. s64currencytype, { pointer to a currency type }
  641. s32fixedtype, { pointer to type of temp. fixed }
  642. cshortstringtype, { pointer to type of short string const }
  643. clongstringtype, { pointer to type of long string const }
  644. cansistringtype, { pointer to type of ansi string const }
  645. cwidestringtype, { pointer to type of wide string const }
  646. openshortstringtype, { pointer to type of an open shortstring,
  647. needed for readln() }
  648. openchararraytype, { pointer to type of an open array of char,
  649. needed for readln() }
  650. cfiletype, { get the same definition for all file }
  651. { used for stabs }
  652. methodpointertype, { typecasting of methodpointers to extract self }
  653. { we use only one variant def }
  654. cvarianttype,
  655. { unsigned ord type with the same size as a pointer }
  656. ordpointertype,
  657. defaultordconsttype, { pointer to type of ordinal constants }
  658. pvmttype : ttype; { type of classrefs, used for stabs }
  659. { pointer to the anchestor of all classes }
  660. class_tobject : tobjectdef;
  661. { pointer to the ancestor of all COM interfaces }
  662. interface_iunknown : tobjectdef;
  663. { pointer to the TGUID type
  664. of all interfaces }
  665. rec_tguid : trecorddef;
  666. { Pointer to a procdef with no parameters and no return value.
  667. This is used for procedures which are generated automatically
  668. by the compiler.
  669. }
  670. voidprocdef : tprocdef;
  671. const
  672. {$ifdef i386}
  673. pbestrealtype : ^ttype = @s80floattype;
  674. {$endif}
  675. {$ifdef x86_64}
  676. pbestrealtype : ^ttype = @s80floattype;
  677. {$endif}
  678. {$ifdef m68k}
  679. pbestrealtype : ^ttype = @s64floattype;
  680. {$endif}
  681. {$ifdef alpha}
  682. pbestrealtype : ^ttype = @s64floattype;
  683. {$endif}
  684. {$ifdef powerpc}
  685. pbestrealtype : ^ttype = @s64floattype;
  686. {$endif}
  687. {$ifdef ia64}
  688. pbestrealtype : ^ttype = @s64floattype;
  689. {$endif}
  690. {$ifdef SPARC}
  691. pbestrealtype : ^ttype = @s64floattype;
  692. {$endif SPARC}
  693. {$ifdef vis}
  694. pbestrealtype : ^ttype = @s64floattype;
  695. {$endif vis}
  696. {$ifdef ARM}
  697. pbestrealtype : ^ttype = @s64floattype;
  698. {$endif ARM}
  699. function reverseparaitems(p: tparaitem): tparaitem;
  700. function mangledname_prefix(typeprefix:string;st:tsymtable):string;
  701. {$ifdef GDB}
  702. { GDB Helpers }
  703. function typeglobalnumber(const s : string) : string;
  704. {$endif GDB}
  705. { should be in the types unit, but the types unit uses the node stuff :( }
  706. function is_interfacecom(def: tdef): boolean;
  707. function is_interfacecorba(def: tdef): boolean;
  708. function is_interface(def: tdef): boolean;
  709. function is_object(def: tdef): boolean;
  710. function is_class(def: tdef): boolean;
  711. function is_cppclass(def: tdef): boolean;
  712. function is_class_or_interface(def: tdef): boolean;
  713. procedure reset_global_defs;
  714. implementation
  715. uses
  716. {$ifdef Delphi}
  717. sysutils,
  718. {$else Delphi}
  719. strings,
  720. {$endif Delphi}
  721. { global }
  722. verbose,
  723. { target }
  724. systems,aasmcpu,paramgr,
  725. { symtable }
  726. symsym,symtable,symutil,defutil,
  727. { module }
  728. {$ifdef GDB}
  729. gdb,
  730. {$endif GDB}
  731. fmodule,
  732. { other }
  733. gendef,
  734. rgobj
  735. ;
  736. {****************************************************************************
  737. Helpers
  738. ****************************************************************************}
  739. function reverseparaitems(p: tparaitem): tparaitem;
  740. var
  741. hp1, hp2: tparaitem;
  742. begin
  743. hp1:=nil;
  744. while assigned(p) do
  745. begin
  746. { pull out }
  747. hp2:=p;
  748. p:=tparaitem(p.next);
  749. { pull in }
  750. tparaitem(hp2.next):=hp1;
  751. hp1:=hp2;
  752. end;
  753. reverseparaitems:=hp1;
  754. end;
  755. function mangledname_prefix(typeprefix:string;st:tsymtable):string;
  756. var
  757. s,
  758. prefix : string;
  759. begin
  760. prefix:='';
  761. if not assigned(st) then
  762. internalerror(200204212);
  763. { sub procedures }
  764. while (st.symtabletype=localsymtable) do
  765. begin
  766. if st.defowner.deftype<>procdef then
  767. internalerror(200204173);
  768. s:=tprocdef(st.defowner).procsym.name;
  769. if tprocdef(st.defowner).overloadnumber>0 then
  770. s:=s+'$'+tostr(tprocdef(st.defowner).overloadnumber);
  771. prefix:=s+'$'+prefix;
  772. st:=st.defowner.owner;
  773. end;
  774. { object/classes symtable }
  775. if (st.symtabletype=objectsymtable) then
  776. begin
  777. if st.defowner.deftype<>objectdef then
  778. internalerror(200204174);
  779. prefix:=tobjectdef(st.defowner).objname^+'_$_'+prefix;
  780. st:=st.defowner.owner;
  781. end;
  782. { symtable must now be static or global }
  783. if not(st.symtabletype in [staticsymtable,globalsymtable]) then
  784. internalerror(200204175);
  785. mangledname_prefix:=typeprefix+'_'+st.name^+'_'+prefix;
  786. end;
  787. {$ifdef GDB}
  788. procedure forcestabto(asmlist : taasmoutput; pd : tdef);
  789. begin
  790. if tstoreddef(pd).is_def_stab_written = not_written then
  791. begin
  792. if assigned(pd.typesym) then
  793. ttypesym(pd.typesym).isusedinstab := true;
  794. tstoreddef(pd).concatstabto(asmlist);
  795. end;
  796. end;
  797. {$endif GDB}
  798. {****************************************************************************
  799. TDEF (base class for definitions)
  800. ****************************************************************************}
  801. constructor tstoreddef.create;
  802. begin
  803. inherited create;
  804. savesize := 0;
  805. {$ifdef EXTDEBUG}
  806. fileinfo := aktfilepos;
  807. {$endif}
  808. if registerdef then
  809. symtablestack.registerdef(self);
  810. {$ifdef GDB}
  811. is_def_stab_written := not_written;
  812. globalnb := 0;
  813. {$endif GDB}
  814. if assigned(lastglobaldef) then
  815. begin
  816. lastglobaldef.nextglobal := self;
  817. previousglobal:=lastglobaldef;
  818. end
  819. else
  820. begin
  821. firstglobaldef := self;
  822. previousglobal := nil;
  823. end;
  824. lastglobaldef := self;
  825. nextglobal := nil;
  826. fillchar(localrttilab,sizeof(localrttilab),0);
  827. end;
  828. constructor tstoreddef.ppuloaddef(ppufile:tcompilerppufile);
  829. begin
  830. inherited create;
  831. {$ifdef EXTDEBUG}
  832. fillchar(fileinfo,sizeof(fileinfo),0);
  833. {$endif}
  834. {$ifdef GDB}
  835. is_def_stab_written := not_written;
  836. globalnb := 0;
  837. {$endif GDB}
  838. if assigned(lastglobaldef) then
  839. begin
  840. lastglobaldef.nextglobal := self;
  841. previousglobal:=lastglobaldef;
  842. end
  843. else
  844. begin
  845. firstglobaldef := self;
  846. previousglobal:=nil;
  847. end;
  848. lastglobaldef := self;
  849. nextglobal := nil;
  850. fillchar(localrttilab,sizeof(localrttilab),0);
  851. { load }
  852. indexnr:=ppufile.getword;
  853. ppufile.getderef(typesymderef);
  854. ppufile.getsmallset(defoptions);
  855. if df_has_rttitable in defoptions then
  856. ppufile.getderef(rttitablesymderef);
  857. if df_has_inittable in defoptions then
  858. ppufile.getderef(inittablesymderef);
  859. end;
  860. destructor tstoreddef.destroy;
  861. begin
  862. { first element ? }
  863. if not(assigned(previousglobal)) then
  864. begin
  865. firstglobaldef := nextglobal;
  866. if assigned(firstglobaldef) then
  867. firstglobaldef.previousglobal:=nil;
  868. end
  869. else
  870. begin
  871. { remove reference in the element before }
  872. previousglobal.nextglobal:=nextglobal;
  873. end;
  874. { last element ? }
  875. if not(assigned(nextglobal)) then
  876. begin
  877. lastglobaldef := previousglobal;
  878. if assigned(lastglobaldef) then
  879. lastglobaldef.nextglobal:=nil;
  880. end
  881. else
  882. nextglobal.previousglobal:=previousglobal;
  883. previousglobal:=nil;
  884. nextglobal:=nil;
  885. end;
  886. function tstoreddef.getcopy : tstoreddef;
  887. begin
  888. Message(sym_e_cant_create_unique_type);
  889. getcopy:=nil;
  890. end;
  891. procedure tstoreddef.ppuwritedef(ppufile:tcompilerppufile);
  892. begin
  893. ppufile.putword(indexnr);
  894. ppufile.putderef(typesym,typesymderef);
  895. ppufile.putsmallset(defoptions);
  896. if df_has_rttitable in defoptions then
  897. ppufile.putderef(rttitablesym,rttitablesymderef);
  898. if df_has_inittable in defoptions then
  899. ppufile.putderef(inittablesym,inittablesymderef);
  900. {$ifdef GDB}
  901. if globalnb = 0 then
  902. begin
  903. if assigned(owner) then
  904. globalnb := owner.getnewtypecount
  905. else
  906. begin
  907. globalnb := PGlobalTypeCount^;
  908. Inc(PGlobalTypeCount^);
  909. end;
  910. end;
  911. {$endif GDB}
  912. end;
  913. procedure tstoreddef.deref;
  914. begin
  915. typesym:=ttypesym(typesymderef.resolve);
  916. if df_has_rttitable in defoptions then
  917. rttitablesym:=trttisym(rttitablesymderef.resolve);
  918. if df_has_inittable in defoptions then
  919. inittablesym:=trttisym(inittablesymderef.resolve);
  920. end;
  921. procedure tstoreddef.derefimpl;
  922. begin
  923. end;
  924. function tstoreddef.size : longint;
  925. begin
  926. size:=savesize;
  927. end;
  928. function tstoreddef.alignment : longint;
  929. begin
  930. { normal alignment by default }
  931. alignment:=0;
  932. end;
  933. {$ifdef GDB}
  934. procedure tstoreddef.set_globalnb;
  935. begin
  936. globalnb :=PGlobalTypeCount^;
  937. inc(PglobalTypeCount^);
  938. end;
  939. function tstoreddef.stabstring : pchar;
  940. begin
  941. stabstring := strpnew('t'+numberstring+';');
  942. end;
  943. function tstoreddef.numberstring : string;
  944. var table : tsymtable;
  945. begin
  946. {formal def have no type !}
  947. if deftype = formaldef then
  948. begin
  949. numberstring := tstoreddef(voidtype.def).numberstring;
  950. exit;
  951. end;
  952. if (not assigned(typesym)) or (not ttypesym(typesym).isusedinstab) then
  953. begin
  954. {set even if debuglist is not defined}
  955. if assigned(typesym) then
  956. ttypesym(typesym).isusedinstab := true;
  957. if assigned(debuglist) and (is_def_stab_written = not_written) then
  958. concatstabto(debuglist);
  959. end;
  960. if not (cs_gdb_dbx in aktglobalswitches) then
  961. begin
  962. if globalnb = 0 then
  963. set_globalnb;
  964. numberstring := tostr(globalnb);
  965. end
  966. else
  967. begin
  968. if globalnb = 0 then
  969. begin
  970. if assigned(owner) then
  971. globalnb := owner.getnewtypecount
  972. else
  973. begin
  974. globalnb := PGlobalTypeCount^;
  975. Inc(PGlobalTypeCount^);
  976. end;
  977. end;
  978. if assigned(typesym) then
  979. begin
  980. table := ttypesym(typesym).owner;
  981. if table.unitid > 0 then
  982. numberstring := '('+tostr(table.unitid)+','+tostr(tstoreddef(ttypesym(typesym).restype.def).globalnb)+')'
  983. else
  984. numberstring := tostr(globalnb);
  985. exit;
  986. end;
  987. numberstring := tostr(globalnb);
  988. end;
  989. end;
  990. function tstoreddef.allstabstring : pchar;
  991. var stabchar : string[2];
  992. ss,st : pchar;
  993. sname : string;
  994. sym_line_no : longint;
  995. begin
  996. ss := stabstring;
  997. getmem(st,strlen(ss)+512);
  998. stabchar := 't';
  999. if deftype in tagtypes then
  1000. stabchar := 'Tt';
  1001. if assigned(typesym) then
  1002. begin
  1003. sname := ttypesym(typesym).name;
  1004. sym_line_no:=ttypesym(typesym).fileinfo.line;
  1005. end
  1006. else
  1007. begin
  1008. sname := ' ';
  1009. sym_line_no:=0;
  1010. end;
  1011. strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
  1012. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  1013. allstabstring := strnew(st);
  1014. freemem(st,strlen(ss)+512);
  1015. strdispose(ss);
  1016. end;
  1017. procedure tstoreddef.concatstabto(asmlist : taasmoutput);
  1018. var stab_str : pchar;
  1019. begin
  1020. if ((typesym = nil) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  1021. and (is_def_stab_written = not_written) then
  1022. begin
  1023. If cs_gdb_dbx in aktglobalswitches then
  1024. begin
  1025. { otherwise you get two of each def }
  1026. If assigned(typesym) then
  1027. begin
  1028. if ttypesym(typesym).typ=symconst.typesym then
  1029. ttypesym(typesym).isusedinstab:=true;
  1030. if (ttypesym(typesym).owner = nil) or
  1031. ((ttypesym(typesym).owner.symtabletype = globalsymtable) and
  1032. tglobalsymtable(ttypesym(typesym).owner).dbx_count_ok) then
  1033. begin
  1034. {with DBX we get the definition from the other objects }
  1035. is_def_stab_written := written;
  1036. exit;
  1037. end;
  1038. end;
  1039. end;
  1040. { to avoid infinite loops }
  1041. is_def_stab_written := being_written;
  1042. stab_str := allstabstring;
  1043. asmList.concat(Tai_stabs.Create(stab_str));
  1044. is_def_stab_written := written;
  1045. end;
  1046. end;
  1047. {$endif GDB}
  1048. procedure tstoreddef.write_rtti_name;
  1049. var
  1050. str : string;
  1051. begin
  1052. { name }
  1053. if assigned(typesym) then
  1054. begin
  1055. str:=ttypesym(typesym).realname;
  1056. rttiList.concat(Tai_string.Create(chr(length(str))+str));
  1057. end
  1058. else
  1059. rttiList.concat(Tai_string.Create(#0))
  1060. end;
  1061. procedure tstoreddef.write_rtti_data(rt:trttitype);
  1062. begin
  1063. rttilist.concat(tai_const.create_8bit(tkUnknown));
  1064. write_rtti_name;
  1065. end;
  1066. procedure tstoreddef.write_child_rtti_data(rt:trttitype);
  1067. begin
  1068. end;
  1069. function tstoreddef.get_rtti_label(rt:trttitype) : tasmsymbol;
  1070. begin
  1071. { try to reuse persistent rtti data }
  1072. if (rt=fullrtti) and (df_has_rttitable in defoptions) then
  1073. get_rtti_label:=trttisym(rttitablesym).get_label
  1074. else
  1075. if (rt=initrtti) and (df_has_inittable in defoptions) then
  1076. get_rtti_label:=trttisym(inittablesym).get_label
  1077. else
  1078. begin
  1079. if not assigned(localrttilab[rt]) then
  1080. begin
  1081. objectlibrary.getdatalabel(localrttilab[rt]);
  1082. write_child_rtti_data(rt);
  1083. if (cs_create_smart in aktmoduleswitches) then
  1084. rttiList.concat(Tai_cut.Create);
  1085. rttiList.concat(Tai_align.create(const_align(pointer_size)));
  1086. if (cs_create_smart in aktmoduleswitches) then
  1087. rttiList.concat(Tai_symbol.Create_global(localrttilab[rt],0))
  1088. else
  1089. rttiList.concat(Tai_symbol.Create(localrttilab[rt],0));
  1090. write_rtti_data(rt);
  1091. rttiList.concat(Tai_symbol_end.Create(localrttilab[rt]));
  1092. end;
  1093. get_rtti_label:=localrttilab[rt];
  1094. end;
  1095. end;
  1096. { returns true, if the definition can be published }
  1097. function tstoreddef.is_publishable : boolean;
  1098. begin
  1099. is_publishable:=false;
  1100. end;
  1101. { needs an init table }
  1102. function tstoreddef.needs_inittable : boolean;
  1103. begin
  1104. needs_inittable:=false;
  1105. end;
  1106. function tstoreddef.is_intregable : boolean;
  1107. begin
  1108. is_intregable:=false;
  1109. case deftype of
  1110. pointerdef,
  1111. enumdef:
  1112. is_intregable:=true;
  1113. procvardef :
  1114. is_intregable:=not(po_methodpointer in tprocvardef(self).procoptions);
  1115. orddef :
  1116. case torddef(self).typ of
  1117. bool8bit,bool16bit,bool32bit,
  1118. u8bit,u16bit,u32bit,
  1119. s8bit,s16bit,s32bit:
  1120. is_intregable:=true;
  1121. end;
  1122. objectdef:
  1123. is_intregable:=is_class(self) or is_interface(self);
  1124. setdef:
  1125. is_intregable:=(tsetdef(self).settype=smallset);
  1126. end;
  1127. end;
  1128. function tstoreddef.is_fpuregable : boolean;
  1129. begin
  1130. is_fpuregable:=(deftype=floatdef);
  1131. end;
  1132. {****************************************************************************
  1133. Tstringdef
  1134. ****************************************************************************}
  1135. constructor tstringdef.createshort(l : byte);
  1136. begin
  1137. inherited create;
  1138. string_typ:=st_shortstring;
  1139. deftype:=stringdef;
  1140. len:=l;
  1141. savesize:=len+1;
  1142. end;
  1143. constructor tstringdef.loadshort(ppufile:tcompilerppufile);
  1144. begin
  1145. inherited ppuloaddef(ppufile);
  1146. string_typ:=st_shortstring;
  1147. deftype:=stringdef;
  1148. len:=ppufile.getbyte;
  1149. savesize:=len+1;
  1150. end;
  1151. constructor tstringdef.createlong(l : longint);
  1152. begin
  1153. inherited create;
  1154. string_typ:=st_longstring;
  1155. deftype:=stringdef;
  1156. len:=l;
  1157. savesize:=POINTER_SIZE;
  1158. end;
  1159. constructor tstringdef.loadlong(ppufile:tcompilerppufile);
  1160. begin
  1161. inherited ppuloaddef(ppufile);
  1162. deftype:=stringdef;
  1163. string_typ:=st_longstring;
  1164. len:=ppufile.getlongint;
  1165. savesize:=POINTER_SIZE;
  1166. end;
  1167. constructor tstringdef.createansi(l : longint);
  1168. begin
  1169. inherited create;
  1170. string_typ:=st_ansistring;
  1171. deftype:=stringdef;
  1172. len:=l;
  1173. savesize:=POINTER_SIZE;
  1174. end;
  1175. constructor tstringdef.loadansi(ppufile:tcompilerppufile);
  1176. begin
  1177. inherited ppuloaddef(ppufile);
  1178. deftype:=stringdef;
  1179. string_typ:=st_ansistring;
  1180. len:=ppufile.getlongint;
  1181. savesize:=POINTER_SIZE;
  1182. end;
  1183. constructor tstringdef.createwide(l : longint);
  1184. begin
  1185. inherited create;
  1186. string_typ:=st_widestring;
  1187. deftype:=stringdef;
  1188. len:=l;
  1189. savesize:=POINTER_SIZE;
  1190. end;
  1191. constructor tstringdef.loadwide(ppufile:tcompilerppufile);
  1192. begin
  1193. inherited ppuloaddef(ppufile);
  1194. deftype:=stringdef;
  1195. string_typ:=st_widestring;
  1196. len:=ppufile.getlongint;
  1197. savesize:=POINTER_SIZE;
  1198. end;
  1199. function tstringdef.getcopy : tstoreddef;
  1200. begin
  1201. result:=tstringdef.create;
  1202. result.deftype:=stringdef;
  1203. tstringdef(result).string_typ:=string_typ;
  1204. tstringdef(result).len:=len;
  1205. tstringdef(result).savesize:=savesize;
  1206. end;
  1207. function tstringdef.stringtypname:string;
  1208. const
  1209. typname:array[tstringtype] of string[8]=('',
  1210. 'shortstr','longstr','ansistr','widestr'
  1211. );
  1212. begin
  1213. stringtypname:=typname[string_typ];
  1214. end;
  1215. function tstringdef.size : longint;
  1216. begin
  1217. size:=savesize;
  1218. end;
  1219. procedure tstringdef.ppuwrite(ppufile:tcompilerppufile);
  1220. begin
  1221. inherited ppuwritedef(ppufile);
  1222. if string_typ=st_shortstring then
  1223. begin
  1224. {$ifdef extdebug}
  1225. if len > 255 then internalerror(12122002);
  1226. {$endif}
  1227. ppufile.putbyte(byte(len))
  1228. end
  1229. else
  1230. ppufile.putlongint(len);
  1231. case string_typ of
  1232. st_shortstring : ppufile.writeentry(ibshortstringdef);
  1233. st_longstring : ppufile.writeentry(iblongstringdef);
  1234. st_ansistring : ppufile.writeentry(ibansistringdef);
  1235. st_widestring : ppufile.writeentry(ibwidestringdef);
  1236. end;
  1237. end;
  1238. {$ifdef GDB}
  1239. function tstringdef.stabstring : pchar;
  1240. var
  1241. bytest,charst,longst : string;
  1242. begin
  1243. case string_typ of
  1244. st_shortstring:
  1245. begin
  1246. charst := typeglobalnumber('char');
  1247. { this is what I found in stabs.texinfo but
  1248. gdb 4.12 for go32 doesn't understand that !! }
  1249. {$IfDef GDBknowsstrings}
  1250. stabstring := strpnew('n'+charst+';'+tostr(len));
  1251. {$else}
  1252. bytest := typeglobalnumber('byte');
  1253. stabstring := strpnew('s'+tostr(len+1)+'length:'+bytest
  1254. +',0,8;st:ar'+bytest
  1255. +';1;'+tostr(len)+';'+charst+',8,'+tostr(len*8)+';;');
  1256. {$EndIf}
  1257. end;
  1258. st_longstring:
  1259. begin
  1260. charst := typeglobalnumber('char');
  1261. { this is what I found in stabs.texinfo but
  1262. gdb 4.12 for go32 doesn't understand that !! }
  1263. {$IfDef GDBknowsstrings}
  1264. stabstring := strpnew('n'+charst+';'+tostr(len));
  1265. {$else}
  1266. bytest := typeglobalnumber('byte');
  1267. longst := typeglobalnumber('longint');
  1268. stabstring := strpnew('s'+tostr(len+5)+'length:'+longst
  1269. +',0,32;dummy:'+bytest+',32,8;st:ar'+bytest
  1270. +';1;'+tostr(len)+';'+charst+',40,'+tostr(len*8)+';;');
  1271. {$EndIf}
  1272. end;
  1273. st_ansistring:
  1274. begin
  1275. { an ansi string looks like a pchar easy !! }
  1276. stabstring:=strpnew('*'+typeglobalnumber('char'));
  1277. end;
  1278. st_widestring:
  1279. begin
  1280. { an ansi string looks like a pwidechar easy !! }
  1281. stabstring:=strpnew('*'+typeglobalnumber('widechar'));
  1282. end;
  1283. end;
  1284. end;
  1285. procedure tstringdef.concatstabto(asmlist : taasmoutput);
  1286. begin
  1287. inherited concatstabto(asmlist);
  1288. end;
  1289. {$endif GDB}
  1290. function tstringdef.needs_inittable : boolean;
  1291. begin
  1292. needs_inittable:=string_typ in [st_ansistring,st_widestring];
  1293. end;
  1294. function tstringdef.gettypename : string;
  1295. const
  1296. names : array[tstringtype] of string[20] = ('',
  1297. 'ShortString','LongString','AnsiString','WideString');
  1298. begin
  1299. gettypename:=names[string_typ];
  1300. end;
  1301. procedure tstringdef.write_rtti_data(rt:trttitype);
  1302. begin
  1303. case string_typ of
  1304. st_ansistring:
  1305. begin
  1306. rttiList.concat(Tai_const.Create_8bit(tkAString));
  1307. write_rtti_name;
  1308. end;
  1309. st_widestring:
  1310. begin
  1311. rttiList.concat(Tai_const.Create_8bit(tkWString));
  1312. write_rtti_name;
  1313. end;
  1314. st_longstring:
  1315. begin
  1316. rttiList.concat(Tai_const.Create_8bit(tkLString));
  1317. write_rtti_name;
  1318. end;
  1319. st_shortstring:
  1320. begin
  1321. rttiList.concat(Tai_const.Create_8bit(tkSString));
  1322. write_rtti_name;
  1323. rttiList.concat(Tai_const.Create_8bit(len));
  1324. end;
  1325. end;
  1326. end;
  1327. function tstringdef.getmangledparaname : string;
  1328. begin
  1329. getmangledparaname:='STRING';
  1330. end;
  1331. function tstringdef.is_publishable : boolean;
  1332. begin
  1333. is_publishable:=true;
  1334. end;
  1335. {****************************************************************************
  1336. TENUMDEF
  1337. ****************************************************************************}
  1338. constructor tenumdef.create;
  1339. begin
  1340. inherited create;
  1341. deftype:=enumdef;
  1342. minval:=0;
  1343. maxval:=0;
  1344. calcsavesize;
  1345. has_jumps:=false;
  1346. basedef:=nil;
  1347. firstenum:=nil;
  1348. correct_owner_symtable;
  1349. end;
  1350. constructor tenumdef.create_subrange(_basedef:tenumdef;_min,_max:longint);
  1351. begin
  1352. inherited create;
  1353. deftype:=enumdef;
  1354. minval:=_min;
  1355. maxval:=_max;
  1356. basedef:=_basedef;
  1357. calcsavesize;
  1358. has_jumps:=false;
  1359. firstenum:=basedef.firstenum;
  1360. while assigned(firstenum) and (tenumsym(firstenum).value<>minval) do
  1361. firstenum:=tenumsym(firstenum).nextenum;
  1362. correct_owner_symtable;
  1363. end;
  1364. constructor tenumdef.ppuload(ppufile:tcompilerppufile);
  1365. begin
  1366. inherited ppuloaddef(ppufile);
  1367. deftype:=enumdef;
  1368. ppufile.getderef(basedefderef);
  1369. minval:=ppufile.getlongint;
  1370. maxval:=ppufile.getlongint;
  1371. savesize:=ppufile.getlongint;
  1372. has_jumps:=false;
  1373. firstenum:=Nil;
  1374. end;
  1375. procedure tenumdef.calcsavesize;
  1376. begin
  1377. if (aktpackenum=4) or (min<0) or (max>65535) then
  1378. savesize:=4
  1379. else
  1380. if (aktpackenum=2) or (min<0) or (max>255) then
  1381. savesize:=2
  1382. else
  1383. savesize:=1;
  1384. end;
  1385. procedure tenumdef.setmax(_max:longint);
  1386. begin
  1387. maxval:=_max;
  1388. calcsavesize;
  1389. end;
  1390. procedure tenumdef.setmin(_min:longint);
  1391. begin
  1392. minval:=_min;
  1393. calcsavesize;
  1394. end;
  1395. function tenumdef.min:longint;
  1396. begin
  1397. min:=minval;
  1398. end;
  1399. function tenumdef.max:longint;
  1400. begin
  1401. max:=maxval;
  1402. end;
  1403. procedure tenumdef.deref;
  1404. begin
  1405. inherited deref;
  1406. basedef:=tenumdef(basedefderef.resolve);
  1407. end;
  1408. destructor tenumdef.destroy;
  1409. begin
  1410. inherited destroy;
  1411. end;
  1412. procedure tenumdef.ppuwrite(ppufile:tcompilerppufile);
  1413. begin
  1414. inherited ppuwritedef(ppufile);
  1415. ppufile.putderef(basedef,basedefderef);
  1416. ppufile.putlongint(min);
  1417. ppufile.putlongint(max);
  1418. ppufile.putlongint(savesize);
  1419. ppufile.writeentry(ibenumdef);
  1420. end;
  1421. { used for enumdef because the symbols are
  1422. inserted in the owner symtable }
  1423. procedure tenumdef.correct_owner_symtable;
  1424. var
  1425. st : tsymtable;
  1426. begin
  1427. if assigned(owner) and
  1428. (owner.symtabletype in [recordsymtable,objectsymtable]) then
  1429. begin
  1430. owner.defindex.deleteindex(self);
  1431. st:=owner;
  1432. while (st.symtabletype in [recordsymtable,objectsymtable]) do
  1433. st:=st.next;
  1434. st.registerdef(self);
  1435. end;
  1436. end;
  1437. {$ifdef GDB}
  1438. function tenumdef.stabstring : pchar;
  1439. var st,st2 : pchar;
  1440. p : tenumsym;
  1441. s : string;
  1442. memsize : word;
  1443. begin
  1444. memsize := memsizeinc;
  1445. getmem(st,memsize);
  1446. { we can specify the size with @s<size>; prefix PM }
  1447. if savesize <> std_param_align then
  1448. strpcopy(st,'@s'+tostr(savesize*8)+';e')
  1449. else
  1450. strpcopy(st,'e');
  1451. p := tenumsym(firstenum);
  1452. while assigned(p) do
  1453. begin
  1454. s :=p.name+':'+tostr(p.value)+',';
  1455. { place for the ending ';' also }
  1456. if (strlen(st)+length(s)+1<memsize) then
  1457. strpcopy(strend(st),s)
  1458. else
  1459. begin
  1460. getmem(st2,memsize+memsizeinc);
  1461. strcopy(st2,st);
  1462. freemem(st,memsize);
  1463. st := st2;
  1464. memsize := memsize+memsizeinc;
  1465. strpcopy(strend(st),s);
  1466. end;
  1467. p := p.nextenum;
  1468. end;
  1469. strpcopy(strend(st),';');
  1470. stabstring := strnew(st);
  1471. freemem(st,memsize);
  1472. end;
  1473. {$endif GDB}
  1474. procedure tenumdef.write_child_rtti_data(rt:trttitype);
  1475. begin
  1476. if assigned(basedef) then
  1477. basedef.get_rtti_label(rt);
  1478. end;
  1479. procedure tenumdef.write_rtti_data(rt:trttitype);
  1480. var
  1481. hp : tenumsym;
  1482. begin
  1483. rttiList.concat(Tai_const.Create_8bit(tkEnumeration));
  1484. write_rtti_name;
  1485. case savesize of
  1486. 1:
  1487. rttiList.concat(Tai_const.Create_8bit(otUByte));
  1488. 2:
  1489. rttiList.concat(Tai_const.Create_8bit(otUWord));
  1490. 4:
  1491. rttiList.concat(Tai_const.Create_8bit(otULong));
  1492. end;
  1493. rttiList.concat(Tai_const.Create_32bit(min));
  1494. rttiList.concat(Tai_const.Create_32bit(max));
  1495. if assigned(basedef) then
  1496. rttiList.concat(Tai_const_symbol.Create(basedef.get_rtti_label(rt)))
  1497. else
  1498. rttiList.concat(Tai_const.Create_32bit(0));
  1499. hp:=tenumsym(firstenum);
  1500. while assigned(hp) do
  1501. begin
  1502. rttiList.concat(Tai_const.Create_8bit(length(hp.name)));
  1503. rttiList.concat(Tai_string.Create(lower(hp.name)));
  1504. hp:=hp.nextenum;
  1505. end;
  1506. rttiList.concat(Tai_const.Create_8bit(0));
  1507. end;
  1508. function tenumdef.is_publishable : boolean;
  1509. begin
  1510. is_publishable:=true;
  1511. end;
  1512. function tenumdef.gettypename : string;
  1513. begin
  1514. gettypename:='<enumeration type>';
  1515. end;
  1516. {****************************************************************************
  1517. TORDDEF
  1518. ****************************************************************************}
  1519. constructor torddef.create(t : tbasetype;v,b : TConstExprInt);
  1520. begin
  1521. inherited create;
  1522. deftype:=orddef;
  1523. low:=v;
  1524. high:=b;
  1525. typ:=t;
  1526. setsize;
  1527. end;
  1528. constructor torddef.ppuload(ppufile:tcompilerppufile);
  1529. var
  1530. l1,l2 : longint;
  1531. begin
  1532. inherited ppuloaddef(ppufile);
  1533. deftype:=orddef;
  1534. typ:=tbasetype(ppufile.getbyte);
  1535. if sizeof(TConstExprInt)=8 then
  1536. begin
  1537. l1:=ppufile.getlongint;
  1538. l2:=ppufile.getlongint;
  1539. {$ifopt R+}
  1540. {$define Range_check_on}
  1541. {$endif opt R+}
  1542. {$R- needed here }
  1543. low:=qword(l1)+(int64(l2) shl 32);
  1544. {$ifdef Range_check_on}
  1545. {$R+}
  1546. {$undef Range_check_on}
  1547. {$endif Range_check_on}
  1548. end
  1549. else
  1550. low:=ppufile.getlongint;
  1551. if sizeof(TConstExprInt)=8 then
  1552. begin
  1553. l1:=ppufile.getlongint;
  1554. l2:=ppufile.getlongint;
  1555. {$ifopt R+}
  1556. {$define Range_check_on}
  1557. {$endif opt R+}
  1558. {$R- needed here }
  1559. high:=qword(l1)+(int64(l2) shl 32);
  1560. {$ifdef Range_check_on}
  1561. {$R+}
  1562. {$undef Range_check_on}
  1563. {$endif Range_check_on}
  1564. end
  1565. else
  1566. high:=ppufile.getlongint;
  1567. setsize;
  1568. end;
  1569. function torddef.getcopy : tstoreddef;
  1570. begin
  1571. result:=torddef.create(typ,low,high);
  1572. result.deftype:=orddef;
  1573. torddef(result).low:=low;
  1574. torddef(result).high:=high;
  1575. torddef(result).typ:=typ;
  1576. torddef(result).savesize:=savesize;
  1577. end;
  1578. procedure torddef.setsize;
  1579. const
  1580. sizetbl : array[tbasetype] of longint = (
  1581. 0,
  1582. 1,2,4,8,
  1583. 1,2,4,8,
  1584. 1,2,4,
  1585. 1,2,8
  1586. );
  1587. begin
  1588. savesize:=sizetbl[typ];
  1589. end;
  1590. procedure torddef.ppuwrite(ppufile:tcompilerppufile);
  1591. begin
  1592. inherited ppuwritedef(ppufile);
  1593. ppufile.putbyte(byte(typ));
  1594. if sizeof(TConstExprInt)=8 then
  1595. begin
  1596. ppufile.putlongint(longint(lo(low)));
  1597. ppufile.putlongint(longint(hi(low)));
  1598. end
  1599. else
  1600. ppufile.putlongint(low);
  1601. if sizeof(TConstExprInt)=8 then
  1602. begin
  1603. ppufile.putlongint(longint(lo(high)));
  1604. ppufile.putlongint(longint(hi(high)));
  1605. end
  1606. else
  1607. ppufile.putlongint(high);
  1608. ppufile.writeentry(iborddef);
  1609. end;
  1610. {$ifdef GDB}
  1611. function torddef.stabstring : pchar;
  1612. begin
  1613. case typ of
  1614. uvoid : stabstring := strpnew(numberstring+';');
  1615. {GDB 4.12 for go32 doesn't like boolean as range for 0 to 1 !!!}
  1616. {$ifdef Use_integer_types_for_boolean}
  1617. bool8bit,
  1618. bool16bit,
  1619. bool32bit : stabstring := strpnew('r'+numberstring+';0;255;');
  1620. {$else : not Use_integer_types_for_boolean}
  1621. uchar : stabstring := strpnew('-20;');
  1622. uwidechar : stabstring := strpnew('-30;');
  1623. bool8bit : stabstring := strpnew('-21;');
  1624. bool16bit : stabstring := strpnew('-22;');
  1625. bool32bit : stabstring := strpnew('-23;');
  1626. u64bit : stabstring := strpnew('-32;');
  1627. s64bit : stabstring := strpnew('-31;');
  1628. {$endif not Use_integer_types_for_boolean}
  1629. {u32bit : stabstring := tstoreddef(s32bittype.def).numberstring+';0;-1;'); }
  1630. else
  1631. stabstring := strpnew('r'+tstoreddef(s32bittype.def).numberstring+';'+tostr(longint(low))+';'+tostr(longint(high))+';');
  1632. end;
  1633. end;
  1634. {$endif GDB}
  1635. procedure torddef.write_rtti_data(rt:trttitype);
  1636. procedure dointeger;
  1637. const
  1638. trans : array[tbasetype] of byte =
  1639. (otUByte{otNone},
  1640. otUByte,otUWord,otULong,otUByte{otNone},
  1641. otSByte,otSWord,otSLong,otUByte{otNone},
  1642. otUByte,otUWord,otULong,
  1643. otUByte,otUWord,otUByte);
  1644. begin
  1645. write_rtti_name;
  1646. rttiList.concat(Tai_const.Create_8bit(byte(trans[typ])));
  1647. rttiList.concat(Tai_const.Create_32bit(longint(low)));
  1648. rttiList.concat(Tai_const.Create_32bit(longint(high)));
  1649. end;
  1650. begin
  1651. case typ of
  1652. s64bit :
  1653. begin
  1654. rttiList.concat(Tai_const.Create_8bit(tkInt64));
  1655. write_rtti_name;
  1656. if target_info.endian=endian_little then
  1657. begin
  1658. { low }
  1659. rttiList.concat(Tai_const.Create_32bit($0));
  1660. rttiList.concat(Tai_const.Create_32bit(longint($80000000)));
  1661. { high }
  1662. rttiList.concat(Tai_const.Create_32bit(longint($ffffffff)));
  1663. rttiList.concat(Tai_const.Create_32bit($7fffffff));
  1664. end
  1665. else
  1666. begin
  1667. { low }
  1668. rttiList.concat(Tai_const.Create_32bit(longint($80000000)));
  1669. rttiList.concat(Tai_const.Create_32bit($0));
  1670. { high }
  1671. rttiList.concat(Tai_const.Create_32bit($7fffffff));
  1672. rttiList.concat(Tai_const.Create_32bit(longint($ffffffff)));
  1673. end;
  1674. end;
  1675. u64bit :
  1676. begin
  1677. rttiList.concat(Tai_const.Create_8bit(tkQWord));
  1678. write_rtti_name;
  1679. { low }
  1680. rttiList.concat(Tai_const.Create_32bit($0));
  1681. rttiList.concat(Tai_const.Create_32bit($0));
  1682. { high }
  1683. rttiList.concat(Tai_const.Create_32bit(longint($ffffffff)));
  1684. rttiList.concat(Tai_const.Create_32bit(longint($ffffffff)));
  1685. end;
  1686. bool8bit:
  1687. begin
  1688. rttiList.concat(Tai_const.Create_8bit(tkBool));
  1689. dointeger;
  1690. end;
  1691. uchar:
  1692. begin
  1693. rttiList.concat(Tai_const.Create_8bit(tkChar));
  1694. dointeger;
  1695. end;
  1696. uwidechar:
  1697. begin
  1698. rttiList.concat(Tai_const.Create_8bit(tkWChar));
  1699. dointeger;
  1700. end;
  1701. else
  1702. begin
  1703. rttiList.concat(Tai_const.Create_8bit(tkInteger));
  1704. dointeger;
  1705. end;
  1706. end;
  1707. end;
  1708. function torddef.is_publishable : boolean;
  1709. begin
  1710. is_publishable:=(typ<>uvoid);
  1711. end;
  1712. function torddef.gettypename : string;
  1713. const
  1714. names : array[tbasetype] of string[20] = (
  1715. 'untyped',
  1716. 'Byte','Word','DWord','QWord',
  1717. 'ShortInt','SmallInt','LongInt','Int64',
  1718. 'Boolean','WordBool','LongBool',
  1719. 'Char','WideChar','Currency');
  1720. begin
  1721. gettypename:=names[typ];
  1722. end;
  1723. {****************************************************************************
  1724. TFLOATDEF
  1725. ****************************************************************************}
  1726. constructor tfloatdef.create(t : tfloattype);
  1727. begin
  1728. inherited create;
  1729. deftype:=floatdef;
  1730. typ:=t;
  1731. setsize;
  1732. end;
  1733. constructor tfloatdef.ppuload(ppufile:tcompilerppufile);
  1734. begin
  1735. inherited ppuloaddef(ppufile);
  1736. deftype:=floatdef;
  1737. typ:=tfloattype(ppufile.getbyte);
  1738. setsize;
  1739. end;
  1740. function tfloatdef.getcopy : tstoreddef;
  1741. begin
  1742. result:=tfloatdef.create(typ);
  1743. result.deftype:=floatdef;
  1744. tfloatdef(result).savesize:=savesize;
  1745. end;
  1746. procedure tfloatdef.setsize;
  1747. begin
  1748. case typ of
  1749. s32real : savesize:=4;
  1750. s80real : savesize:=extended_size;
  1751. s64real,
  1752. s64currency,
  1753. s64comp : savesize:=8;
  1754. else
  1755. savesize:=0;
  1756. end;
  1757. end;
  1758. procedure tfloatdef.ppuwrite(ppufile:tcompilerppufile);
  1759. begin
  1760. inherited ppuwritedef(ppufile);
  1761. ppufile.putbyte(byte(typ));
  1762. ppufile.writeentry(ibfloatdef);
  1763. end;
  1764. {$ifdef GDB}
  1765. function tfloatdef.stabstring : pchar;
  1766. begin
  1767. case typ of
  1768. s32real,
  1769. s64real : stabstring := strpnew('r'+
  1770. tstoreddef(s32bittype.def).numberstring+';'+tostr(savesize)+';0;');
  1771. { found this solution in stabsread.c from GDB v4.16 }
  1772. s64currency,
  1773. s64comp : stabstring := strpnew('r'+
  1774. tstoreddef(s32bittype.def).numberstring+';-'+tostr(savesize)+';0;');
  1775. { under dos at least you must give a size of twelve instead of 10 !! }
  1776. { this is probably do to the fact that in gcc all is pushed in 4 bytes size }
  1777. s80real : stabstring := strpnew('r'+tstoreddef(s32bittype.def).numberstring+';12;0;');
  1778. else
  1779. internalerror(10005);
  1780. end;
  1781. end;
  1782. {$endif GDB}
  1783. procedure tfloatdef.write_rtti_data(rt:trttitype);
  1784. const
  1785. {tfloattype = (s32real,s64real,s80real,s64bit,s128bit);}
  1786. translate : array[tfloattype] of byte =
  1787. (ftSingle,ftDouble,ftExtended,ftComp,ftCurr,ftFloat128);
  1788. begin
  1789. rttiList.concat(Tai_const.Create_8bit(tkFloat));
  1790. write_rtti_name;
  1791. rttiList.concat(Tai_const.Create_8bit(translate[typ]));
  1792. end;
  1793. function tfloatdef.is_publishable : boolean;
  1794. begin
  1795. is_publishable:=true;
  1796. end;
  1797. function tfloatdef.gettypename : string;
  1798. const
  1799. names : array[tfloattype] of string[20] = (
  1800. 'Single','Double','Extended','Comp','Currency','Float128');
  1801. begin
  1802. gettypename:=names[typ];
  1803. end;
  1804. {****************************************************************************
  1805. TFILEDEF
  1806. ****************************************************************************}
  1807. constructor tfiledef.createtext;
  1808. begin
  1809. inherited create;
  1810. deftype:=filedef;
  1811. filetyp:=ft_text;
  1812. typedfiletype.reset;
  1813. setsize;
  1814. end;
  1815. constructor tfiledef.createuntyped;
  1816. begin
  1817. inherited create;
  1818. deftype:=filedef;
  1819. filetyp:=ft_untyped;
  1820. typedfiletype.reset;
  1821. setsize;
  1822. end;
  1823. constructor tfiledef.createtyped(const tt : ttype);
  1824. begin
  1825. inherited create;
  1826. deftype:=filedef;
  1827. filetyp:=ft_typed;
  1828. typedfiletype:=tt;
  1829. setsize;
  1830. end;
  1831. constructor tfiledef.ppuload(ppufile:tcompilerppufile);
  1832. begin
  1833. inherited ppuloaddef(ppufile);
  1834. deftype:=filedef;
  1835. filetyp:=tfiletyp(ppufile.getbyte);
  1836. if filetyp=ft_typed then
  1837. ppufile.gettype(typedfiletype)
  1838. else
  1839. typedfiletype.reset;
  1840. setsize;
  1841. end;
  1842. procedure tfiledef.deref;
  1843. begin
  1844. inherited deref;
  1845. if filetyp=ft_typed then
  1846. typedfiletype.resolve;
  1847. end;
  1848. procedure tfiledef.setsize;
  1849. begin
  1850. {$ifdef cpu64bit}
  1851. case filetyp of
  1852. ft_text :
  1853. savesize:=592;
  1854. ft_typed,
  1855. ft_untyped :
  1856. savesize:=316;
  1857. end;
  1858. {$else cpu64bit}
  1859. case filetyp of
  1860. ft_text :
  1861. savesize:=572;
  1862. ft_typed,
  1863. ft_untyped :
  1864. savesize:=316;
  1865. end;
  1866. {$endif cpu64bit}
  1867. end;
  1868. procedure tfiledef.ppuwrite(ppufile:tcompilerppufile);
  1869. begin
  1870. inherited ppuwritedef(ppufile);
  1871. ppufile.putbyte(byte(filetyp));
  1872. if filetyp=ft_typed then
  1873. ppufile.puttype(typedfiletype);
  1874. ppufile.writeentry(ibfiledef);
  1875. end;
  1876. {$ifdef GDB}
  1877. function tfiledef.stabstring : pchar;
  1878. begin
  1879. {$IfDef GDBknowsfiles}
  1880. case filetyp of
  1881. ft_typed :
  1882. stabstring := strpnew('d'+typedfiletype.def.numberstring{+';'});
  1883. ft_untyped :
  1884. stabstring := strpnew('d'+voiddef.numberstring{+';'});
  1885. ft_text :
  1886. stabstring := strpnew('d'+cchartype^.numberstring{+';'});
  1887. end;
  1888. {$Else}
  1889. {based on
  1890. FileRec = Packed Record
  1891. Handle,
  1892. Mode,
  1893. RecSize : longint;
  1894. _private : array[1..32] of byte;
  1895. UserData : array[1..16] of byte;
  1896. name : array[0..255] of char;
  1897. End; }
  1898. { the buffer part is still missing !! (PM) }
  1899. { but the string could become too long !! }
  1900. stabstring := strpnew('s'+tostr(savesize)+
  1901. 'HANDLE:'+typeglobalnumber('longint')+',0,32;'+
  1902. 'MODE:'+typeglobalnumber('longint')+',32,32;'+
  1903. 'RECSIZE:'+typeglobalnumber('longint')+',64,32;'+
  1904. '_PRIVATE:ar'+typeglobalnumber('word')+';1;32;'+typeglobalnumber('byte')
  1905. +',96,256;'+
  1906. 'USERDATA:ar'+typeglobalnumber('word')+';1;16;'+typeglobalnumber('byte')
  1907. +',352,128;'+
  1908. 'NAME:ar'+typeglobalnumber('word')+';0;255;'+typeglobalnumber('char')
  1909. +',480,2048;;');
  1910. {$EndIf}
  1911. end;
  1912. procedure tfiledef.concatstabto(asmlist : taasmoutput);
  1913. begin
  1914. { most file defs are unnamed !!! }
  1915. if ((typesym = nil) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  1916. (is_def_stab_written = not_written) then
  1917. begin
  1918. if assigned(typedfiletype.def) then
  1919. forcestabto(asmlist,typedfiletype.def);
  1920. inherited concatstabto(asmlist);
  1921. end;
  1922. end;
  1923. {$endif GDB}
  1924. function tfiledef.gettypename : string;
  1925. begin
  1926. case filetyp of
  1927. ft_untyped:
  1928. gettypename:='File';
  1929. ft_typed:
  1930. gettypename:='File Of '+typedfiletype.def.typename;
  1931. ft_text:
  1932. gettypename:='Text'
  1933. end;
  1934. end;
  1935. function tfiledef.getmangledparaname : string;
  1936. begin
  1937. case filetyp of
  1938. ft_untyped:
  1939. getmangledparaname:='FILE';
  1940. ft_typed:
  1941. getmangledparaname:='FILE$OF$'+typedfiletype.def.mangledparaname;
  1942. ft_text:
  1943. getmangledparaname:='TEXT'
  1944. end;
  1945. end;
  1946. {****************************************************************************
  1947. TVARIANTDEF
  1948. ****************************************************************************}
  1949. constructor tvariantdef.create;
  1950. begin
  1951. inherited create;
  1952. deftype:=variantdef;
  1953. setsize;
  1954. end;
  1955. constructor tvariantdef.ppuload(ppufile:tcompilerppufile);
  1956. begin
  1957. inherited ppuloaddef(ppufile);
  1958. deftype:=variantdef;
  1959. setsize;
  1960. end;
  1961. procedure tvariantdef.ppuwrite(ppufile:tcompilerppufile);
  1962. begin
  1963. inherited ppuwritedef(ppufile);
  1964. ppufile.writeentry(ibvariantdef);
  1965. end;
  1966. procedure tvariantdef.setsize;
  1967. begin
  1968. savesize:=16;
  1969. end;
  1970. function tvariantdef.gettypename : string;
  1971. begin
  1972. gettypename:='Variant';
  1973. end;
  1974. procedure tvariantdef.write_rtti_data(rt:trttitype);
  1975. begin
  1976. rttiList.concat(Tai_const.Create_8bit(tkVariant));
  1977. end;
  1978. function tvariantdef.needs_inittable : boolean;
  1979. begin
  1980. needs_inittable:=true;
  1981. end;
  1982. {$ifdef GDB}
  1983. procedure tvariantdef.concatstabto(asmlist : taasmoutput);
  1984. begin
  1985. { don't know how to handle this }
  1986. end;
  1987. {$endif GDB}
  1988. {****************************************************************************
  1989. TPOINTERDEF
  1990. ****************************************************************************}
  1991. constructor tpointerdef.create(const tt : ttype);
  1992. begin
  1993. inherited create;
  1994. deftype:=pointerdef;
  1995. pointertype:=tt;
  1996. is_far:=false;
  1997. savesize:=POINTER_SIZE;
  1998. end;
  1999. constructor tpointerdef.createfar(const tt : ttype);
  2000. begin
  2001. inherited create;
  2002. deftype:=pointerdef;
  2003. pointertype:=tt;
  2004. is_far:=true;
  2005. savesize:=POINTER_SIZE;
  2006. end;
  2007. constructor tpointerdef.ppuload(ppufile:tcompilerppufile);
  2008. begin
  2009. inherited ppuloaddef(ppufile);
  2010. deftype:=pointerdef;
  2011. ppufile.gettype(pointertype);
  2012. is_far:=(ppufile.getbyte<>0);
  2013. savesize:=POINTER_SIZE;
  2014. end;
  2015. procedure tpointerdef.deref;
  2016. begin
  2017. inherited deref;
  2018. pointertype.resolve;
  2019. end;
  2020. procedure tpointerdef.ppuwrite(ppufile:tcompilerppufile);
  2021. begin
  2022. inherited ppuwritedef(ppufile);
  2023. ppufile.puttype(pointertype);
  2024. ppufile.putbyte(byte(is_far));
  2025. ppufile.writeentry(ibpointerdef);
  2026. end;
  2027. {$ifdef GDB}
  2028. function tpointerdef.stabstring : pchar;
  2029. begin
  2030. stabstring := strpnew('*'+tstoreddef(pointertype.def).numberstring);
  2031. end;
  2032. procedure tpointerdef.concatstabto(asmlist : taasmoutput);
  2033. var st,nb : string;
  2034. sym_line_no : longint;
  2035. begin
  2036. if assigned(pointertype.def) and
  2037. (pointertype.def.deftype=forwarddef) then
  2038. exit;
  2039. if ( (typesym=nil) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  2040. (is_def_stab_written = not_written) then
  2041. begin
  2042. is_def_stab_written := being_written;
  2043. if assigned(pointertype.def) and
  2044. (pointertype.def.deftype in [recorddef,objectdef]) then
  2045. begin
  2046. if pointertype.def.deftype=objectdef then
  2047. nb:=tobjectdef(pointertype.def).classnumberstring
  2048. else
  2049. nb:=tstoreddef(pointertype.def).numberstring;
  2050. {to avoid infinite recursion in record with next-like fields }
  2051. if tstoreddef(pointertype.def).is_def_stab_written = being_written then
  2052. begin
  2053. if assigned(pointertype.def.typesym) then
  2054. begin
  2055. if assigned(typesym) then
  2056. begin
  2057. st := ttypesym(typesym).name;
  2058. sym_line_no:=ttypesym(typesym).fileinfo.line;
  2059. end
  2060. else
  2061. begin
  2062. st := ' ';
  2063. sym_line_no:=0;
  2064. end;
  2065. st := '"'+st+':t'+numberstring+'=*'+nb
  2066. +'=xs'+pointertype.def.typesym.name+':",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0';
  2067. asmList.concat(Tai_stabs.Create(strpnew(st)));
  2068. end;
  2069. end
  2070. else
  2071. begin
  2072. is_def_stab_written := not_written;
  2073. inherited concatstabto(asmlist);
  2074. end;
  2075. is_def_stab_written := written;
  2076. end
  2077. else
  2078. begin
  2079. if assigned(pointertype.def) then
  2080. forcestabto(asmlist,pointertype.def);
  2081. is_def_stab_written := not_written;
  2082. inherited concatstabto(asmlist);
  2083. end;
  2084. end;
  2085. end;
  2086. {$endif GDB}
  2087. function tpointerdef.gettypename : string;
  2088. begin
  2089. if is_far then
  2090. gettypename:='^'+pointertype.def.typename+';far'
  2091. else
  2092. gettypename:='^'+pointertype.def.typename;
  2093. end;
  2094. {****************************************************************************
  2095. TCLASSREFDEF
  2096. ****************************************************************************}
  2097. constructor tclassrefdef.create(const t:ttype);
  2098. begin
  2099. inherited create(t);
  2100. deftype:=classrefdef;
  2101. end;
  2102. constructor tclassrefdef.ppuload(ppufile:tcompilerppufile);
  2103. begin
  2104. { be careful, tclassdefref inherits from tpointerdef }
  2105. inherited ppuloaddef(ppufile);
  2106. deftype:=classrefdef;
  2107. ppufile.gettype(pointertype);
  2108. is_far:=false;
  2109. savesize:=POINTER_SIZE;
  2110. end;
  2111. procedure tclassrefdef.ppuwrite(ppufile:tcompilerppufile);
  2112. begin
  2113. { be careful, tclassdefref inherits from tpointerdef }
  2114. inherited ppuwritedef(ppufile);
  2115. ppufile.puttype(pointertype);
  2116. ppufile.writeentry(ibclassrefdef);
  2117. end;
  2118. {$ifdef GDB}
  2119. function tclassrefdef.stabstring : pchar;
  2120. begin
  2121. stabstring:=strpnew(tstoreddef(pvmttype.def).numberstring+';');
  2122. end;
  2123. procedure tclassrefdef.concatstabto(asmlist : taasmoutput);
  2124. begin
  2125. inherited concatstabto(asmlist);
  2126. end;
  2127. {$endif GDB}
  2128. function tclassrefdef.gettypename : string;
  2129. begin
  2130. gettypename:='Class Of '+pointertype.def.typename;
  2131. end;
  2132. {***************************************************************************
  2133. TSETDEF
  2134. ***************************************************************************}
  2135. constructor tsetdef.create(const t:ttype;high : longint);
  2136. begin
  2137. inherited create;
  2138. deftype:=setdef;
  2139. elementtype:=t;
  2140. if high<32 then
  2141. begin
  2142. settype:=smallset;
  2143. {$ifdef testvarsets}
  2144. if aktsetalloc=0 THEN { $PACKSET Fixed?}
  2145. {$endif}
  2146. savesize:=Sizeof(longint)
  2147. {$ifdef testvarsets}
  2148. else {No, use $PACKSET VALUE for rounding}
  2149. savesize:=aktsetalloc*((high+aktsetalloc*8-1) DIV (aktsetalloc*8))
  2150. {$endif}
  2151. ;
  2152. end
  2153. else
  2154. if high<256 then
  2155. begin
  2156. settype:=normset;
  2157. savesize:=32;
  2158. end
  2159. else
  2160. {$ifdef testvarsets}
  2161. if high<$10000 then
  2162. begin
  2163. settype:=varset;
  2164. savesize:=4*((high+31) div 32);
  2165. end
  2166. else
  2167. {$endif testvarsets}
  2168. Message(sym_e_ill_type_decl_set);
  2169. end;
  2170. constructor tsetdef.ppuload(ppufile:tcompilerppufile);
  2171. begin
  2172. inherited ppuloaddef(ppufile);
  2173. deftype:=setdef;
  2174. ppufile.gettype(elementtype);
  2175. settype:=tsettype(ppufile.getbyte);
  2176. case settype of
  2177. normset : savesize:=32;
  2178. varset : savesize:=ppufile.getlongint;
  2179. smallset : savesize:=Sizeof(longint);
  2180. end;
  2181. end;
  2182. destructor tsetdef.destroy;
  2183. begin
  2184. inherited destroy;
  2185. end;
  2186. procedure tsetdef.ppuwrite(ppufile:tcompilerppufile);
  2187. begin
  2188. inherited ppuwritedef(ppufile);
  2189. ppufile.puttype(elementtype);
  2190. ppufile.putbyte(byte(settype));
  2191. if settype=varset then
  2192. ppufile.putlongint(savesize);
  2193. ppufile.writeentry(ibsetdef);
  2194. end;
  2195. {$ifdef GDB}
  2196. function tsetdef.stabstring : pchar;
  2197. begin
  2198. { For small sets write a longint, which can at least be seen
  2199. in the current GDB's (PFV)
  2200. this is obsolete with GDBPAS !!
  2201. and anyhow creates problems with version 4.18!! PM
  2202. if settype=smallset then
  2203. stabstring := strpnew('r'+s32bittype^.numberstring+';0;0xffffffff;')
  2204. else }
  2205. stabstring := strpnew('@s'+tostr(savesize*8)+';S'+tstoreddef(elementtype.def).numberstring);
  2206. end;
  2207. procedure tsetdef.concatstabto(asmlist : taasmoutput);
  2208. begin
  2209. if ( not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  2210. (is_def_stab_written = not_written) then
  2211. begin
  2212. if assigned(elementtype.def) then
  2213. forcestabto(asmlist,elementtype.def);
  2214. inherited concatstabto(asmlist);
  2215. end;
  2216. end;
  2217. {$endif GDB}
  2218. procedure tsetdef.deref;
  2219. begin
  2220. inherited deref;
  2221. elementtype.resolve;
  2222. end;
  2223. procedure tsetdef.write_child_rtti_data(rt:trttitype);
  2224. begin
  2225. tstoreddef(elementtype.def).get_rtti_label(rt);
  2226. end;
  2227. procedure tsetdef.write_rtti_data(rt:trttitype);
  2228. begin
  2229. rttiList.concat(Tai_const.Create_8bit(tkSet));
  2230. write_rtti_name;
  2231. rttiList.concat(Tai_const.Create_8bit(otULong));
  2232. rttiList.concat(Tai_const_symbol.Create(tstoreddef(elementtype.def).get_rtti_label(rt)));
  2233. end;
  2234. function tsetdef.is_publishable : boolean;
  2235. begin
  2236. is_publishable:=(settype=smallset);
  2237. end;
  2238. function tsetdef.gettypename : string;
  2239. begin
  2240. if assigned(elementtype.def) then
  2241. gettypename:='Set Of '+elementtype.def.typename
  2242. else
  2243. gettypename:='Empty Set';
  2244. end;
  2245. {***************************************************************************
  2246. TFORMALDEF
  2247. ***************************************************************************}
  2248. constructor tformaldef.create;
  2249. var
  2250. stregdef : boolean;
  2251. begin
  2252. stregdef:=registerdef;
  2253. registerdef:=false;
  2254. inherited create;
  2255. deftype:=formaldef;
  2256. registerdef:=stregdef;
  2257. { formaldef must be registered at unit level !! }
  2258. if registerdef and assigned(current_module) then
  2259. if assigned(current_module.localsymtable) then
  2260. tsymtable(current_module.localsymtable).registerdef(self)
  2261. else if assigned(current_module.globalsymtable) then
  2262. tsymtable(current_module.globalsymtable).registerdef(self);
  2263. savesize:=0;
  2264. end;
  2265. constructor tformaldef.ppuload(ppufile:tcompilerppufile);
  2266. begin
  2267. inherited ppuloaddef(ppufile);
  2268. deftype:=formaldef;
  2269. savesize:=0;
  2270. end;
  2271. procedure tformaldef.ppuwrite(ppufile:tcompilerppufile);
  2272. begin
  2273. inherited ppuwritedef(ppufile);
  2274. ppufile.writeentry(ibformaldef);
  2275. end;
  2276. {$ifdef GDB}
  2277. function tformaldef.stabstring : pchar;
  2278. begin
  2279. stabstring := strpnew('formal'+numberstring+';');
  2280. end;
  2281. procedure tformaldef.concatstabto(asmlist : taasmoutput);
  2282. begin
  2283. { formaldef can't be stab'ed !}
  2284. end;
  2285. {$endif GDB}
  2286. function tformaldef.gettypename : string;
  2287. begin
  2288. gettypename:='<Formal type>';
  2289. end;
  2290. {***************************************************************************
  2291. TARRAYDEF
  2292. ***************************************************************************}
  2293. constructor tarraydef.create(l,h : longint;const t : ttype);
  2294. begin
  2295. inherited create;
  2296. deftype:=arraydef;
  2297. lowrange:=l;
  2298. highrange:=h;
  2299. rangetype:=t;
  2300. elementtype.reset;
  2301. IsVariant:=false;
  2302. IsConstructor:=false;
  2303. IsArrayOfConst:=false;
  2304. IsDynamicArray:=false;
  2305. end;
  2306. constructor tarraydef.ppuload(ppufile:tcompilerppufile);
  2307. begin
  2308. inherited ppuloaddef(ppufile);
  2309. deftype:=arraydef;
  2310. { the addresses are calculated later }
  2311. ppufile.gettype(_elementtype);
  2312. ppufile.gettype(rangetype);
  2313. lowrange:=ppufile.getlongint;
  2314. highrange:=ppufile.getlongint;
  2315. IsArrayOfConst:=boolean(ppufile.getbyte);
  2316. IsDynamicArray:=boolean(ppufile.getbyte);
  2317. IsVariant:=false;
  2318. IsConstructor:=false;
  2319. end;
  2320. procedure tarraydef.deref;
  2321. begin
  2322. inherited deref;
  2323. _elementtype.resolve;
  2324. rangetype.resolve;
  2325. end;
  2326. procedure tarraydef.ppuwrite(ppufile:tcompilerppufile);
  2327. begin
  2328. inherited ppuwritedef(ppufile);
  2329. ppufile.puttype(_elementtype);
  2330. ppufile.puttype(rangetype);
  2331. ppufile.putlongint(lowrange);
  2332. ppufile.putlongint(highrange);
  2333. ppufile.putbyte(byte(IsArrayOfConst));
  2334. ppufile.putbyte(byte(IsDynamicArray));
  2335. ppufile.writeentry(ibarraydef);
  2336. end;
  2337. {$ifdef GDB}
  2338. function tarraydef.stabstring : pchar;
  2339. begin
  2340. stabstring := strpnew('ar'+tstoreddef(rangetype.def).numberstring+';'
  2341. +tostr(lowrange)+';'+tostr(highrange)+';'+tstoreddef(_elementtype.def).numberstring);
  2342. end;
  2343. procedure tarraydef.concatstabto(asmlist : taasmoutput);
  2344. begin
  2345. if (not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2346. and (is_def_stab_written = not_written) then
  2347. begin
  2348. {when array are inserted they have no definition yet !!}
  2349. if assigned(_elementtype.def) then
  2350. inherited concatstabto(asmlist);
  2351. end;
  2352. end;
  2353. {$endif GDB}
  2354. function tarraydef.elesize : longint;
  2355. begin
  2356. elesize:=_elementtype.def.size;
  2357. end;
  2358. function tarraydef.size : longint;
  2359. var
  2360. _resultsize,
  2361. newsize,
  2362. cachedsize: TConstExprInt;
  2363. begin
  2364. if IsDynamicArray then
  2365. begin
  2366. size:=POINTER_SIZE;
  2367. exit;
  2368. end;
  2369. cachedsize := elesize;
  2370. {Tarraydef.size may never be called for an open array!}
  2371. if highrange<lowrange then
  2372. internalerror(99080501);
  2373. newsize:=(int64(highrange)-int64(lowrange)+1)*cachedsize;
  2374. if (cachedsize>0) and
  2375. (
  2376. (TConstExprInt(highrange)-TConstExprInt(lowrange) > $7fffffff) or
  2377. { () are needed around elesize-1 to avoid a possible
  2378. integer overflow for elesize=1 !! PM }
  2379. (($7fffffff div cachedsize + (cachedsize -1)) < (int64(highrange) - int64(lowrange)))
  2380. ) Then
  2381. begin
  2382. Message(sym_e_segment_too_large);
  2383. _resultsize := 4
  2384. end
  2385. else
  2386. begin
  2387. { prevent an overflow }
  2388. if newsize>high(longint) then
  2389. _resultsize:=high(longint)
  2390. else
  2391. _resultsize:=newsize;
  2392. end;
  2393. size := _resultsize;
  2394. end;
  2395. procedure tarraydef.setelementtype(t: ttype);
  2396. begin
  2397. _elementtype:=t;
  2398. If IsDynamicArray then
  2399. exit;
  2400. if (TConstExprInt(highrange)-TConstExprInt(lowrange) > $7fffffff) then
  2401. Message(sym_e_segment_too_large);
  2402. end;
  2403. function tarraydef.alignment : longint;
  2404. begin
  2405. { alignment is the size of the elements }
  2406. if elementtype.def.deftype=recorddef then
  2407. alignment:=elementtype.def.alignment
  2408. else
  2409. alignment:=elesize;
  2410. end;
  2411. function tarraydef.needs_inittable : boolean;
  2412. begin
  2413. needs_inittable:=IsDynamicArray or elementtype.def.needs_inittable;
  2414. end;
  2415. procedure tarraydef.write_child_rtti_data(rt:trttitype);
  2416. begin
  2417. tstoreddef(elementtype.def).get_rtti_label(rt);
  2418. end;
  2419. procedure tarraydef.write_rtti_data(rt:trttitype);
  2420. begin
  2421. if IsDynamicArray then
  2422. rttiList.concat(Tai_const.Create_8bit(tkdynarray))
  2423. else
  2424. rttiList.concat(Tai_const.Create_8bit(tkarray));
  2425. write_rtti_name;
  2426. { size of elements }
  2427. rttiList.concat(Tai_const.Create_32bit(elesize));
  2428. { count of elements }
  2429. if not(IsDynamicArray) then
  2430. rttiList.concat(Tai_const.Create_32bit(highrange-lowrange+1));
  2431. { element type }
  2432. rttiList.concat(Tai_const_symbol.Create(tstoreddef(elementtype.def).get_rtti_label(rt)));
  2433. { variant type }
  2434. // !!!!!!!!!!!!!!!!
  2435. end;
  2436. function tarraydef.gettypename : string;
  2437. begin
  2438. if isarrayofconst or isConstructor then
  2439. begin
  2440. if isvariant or ((highrange=-1) and (lowrange=0)) then
  2441. gettypename:='Array Of Const'
  2442. else
  2443. gettypename:='Array Of '+elementtype.def.typename;
  2444. end
  2445. else if ((highrange=-1) and (lowrange=0)) or IsDynamicArray then
  2446. gettypename:='Array Of '+elementtype.def.typename
  2447. else
  2448. begin
  2449. if rangetype.def.deftype=enumdef then
  2450. gettypename:='Array['+rangetype.def.typename+'] Of '+elementtype.def.typename
  2451. else
  2452. gettypename:='Array['+tostr(lowrange)+'..'+
  2453. tostr(highrange)+'] Of '+elementtype.def.typename
  2454. end;
  2455. end;
  2456. function tarraydef.getmangledparaname : string;
  2457. begin
  2458. if isarrayofconst then
  2459. getmangledparaname:='array_of_const'
  2460. else
  2461. if ((highrange=-1) and (lowrange=0)) then
  2462. getmangledparaname:='array_of_'+elementtype.def.mangledparaname
  2463. else
  2464. internalerror(200204176);
  2465. end;
  2466. {***************************************************************************
  2467. tabstractrecorddef
  2468. ***************************************************************************}
  2469. function tabstractrecorddef.getsymtable(t:tgetsymtable):tsymtable;
  2470. begin
  2471. if t=gs_record then
  2472. getsymtable:=symtable
  2473. else
  2474. getsymtable:=nil;
  2475. end;
  2476. {$ifdef GDB}
  2477. procedure tabstractrecorddef.addname(p : tnamedindexitem;arg:pointer);
  2478. var
  2479. news, newrec : pchar;
  2480. spec : string[3];
  2481. varsize : longint;
  2482. begin
  2483. { static variables from objects are like global objects }
  2484. if (sp_static in tsym(p).symoptions) then
  2485. exit;
  2486. If tsym(p).typ = varsym then
  2487. begin
  2488. if (sp_protected in tsym(p).symoptions) then
  2489. spec:='/1'
  2490. else if (sp_private in tsym(p).symoptions) then
  2491. spec:='/0'
  2492. else
  2493. spec:='';
  2494. if not assigned(tvarsym(p).vartype.def) then
  2495. writeln(tvarsym(p).name);
  2496. { class fields are pointers PM, obsolete now PM }
  2497. {if (tvarsym(p).vartype.def.deftype=objectdef) and
  2498. tobjectdef(tvarsym(p).vartype.def).is_class then
  2499. spec:=spec+'*'; }
  2500. varsize:=tvarsym(p).vartype.def.size;
  2501. { open arrays made overflows !! }
  2502. if varsize>$fffffff then
  2503. varsize:=$fffffff;
  2504. newrec := strpnew(p.name+':'+spec+tstoreddef(tvarsym(p).vartype.def).numberstring
  2505. +','+tostr(tvarsym(p).fieldoffset*8)+','
  2506. +tostr(varsize*8)+';');
  2507. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  2508. begin
  2509. getmem(news,stabrecsize+memsizeinc);
  2510. strcopy(news,stabrecstring);
  2511. freemem(stabrecstring,stabrecsize);
  2512. stabrecsize:=stabrecsize+memsizeinc;
  2513. stabrecstring:=news;
  2514. end;
  2515. strcat(StabRecstring,newrec);
  2516. strdispose(newrec);
  2517. {This should be used for case !!}
  2518. inc(RecOffset,tvarsym(p).vartype.def.size);
  2519. end;
  2520. end;
  2521. {$endif GDB}
  2522. procedure tabstractrecorddef.count_field_rtti(sym : tnamedindexitem;arg:pointer);
  2523. begin
  2524. if (FRTTIType=fullrtti) or
  2525. ((tsym(sym).typ=varsym) and
  2526. tvarsym(sym).vartype.def.needs_inittable) then
  2527. inc(Count);
  2528. end;
  2529. procedure tabstractrecorddef.generate_field_rtti(sym:tnamedindexitem;arg:pointer);
  2530. begin
  2531. if (FRTTIType=fullrtti) or
  2532. ((tsym(sym).typ=varsym) and
  2533. tvarsym(sym).vartype.def.needs_inittable) then
  2534. tstoreddef(tvarsym(sym).vartype.def).get_rtti_label(FRTTIType);
  2535. end;
  2536. procedure tabstractrecorddef.write_field_rtti(sym : tnamedindexitem;arg:pointer);
  2537. begin
  2538. if (FRTTIType=fullrtti) or
  2539. ((tsym(sym).typ=varsym) and
  2540. tvarsym(sym).vartype.def.needs_inittable) then
  2541. begin
  2542. rttiList.concat(Tai_const_symbol.Create(tstoreddef(tvarsym(sym).vartype.def).get_rtti_label(FRTTIType)));
  2543. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym).fieldoffset));
  2544. end;
  2545. end;
  2546. {***************************************************************************
  2547. trecorddef
  2548. ***************************************************************************}
  2549. constructor trecorddef.create(p : tsymtable);
  2550. begin
  2551. inherited create;
  2552. deftype:=recorddef;
  2553. symtable:=p;
  2554. symtable.defowner:=self;
  2555. { recordalign -1 means C record packing, that starts
  2556. with an alignment of 1 }
  2557. if aktalignment.recordalignmax=-1 then
  2558. trecordsymtable(symtable).dataalignment:=1
  2559. else
  2560. trecordsymtable(symtable).dataalignment:=aktalignment.recordalignmax;
  2561. isunion:=false;
  2562. end;
  2563. constructor trecorddef.ppuload(ppufile:tcompilerppufile);
  2564. begin
  2565. inherited ppuloaddef(ppufile);
  2566. deftype:=recorddef;
  2567. savesize:=ppufile.getlongint;
  2568. symtable:=trecordsymtable.create;
  2569. trecordsymtable(symtable).datasize:=ppufile.getlongint;
  2570. trecordsymtable(symtable).dataalignment:=ppufile.getbyte;
  2571. trecordsymtable(symtable).ppuload(ppufile);
  2572. symtable.defowner:=self;
  2573. isunion:=false;
  2574. end;
  2575. destructor trecorddef.destroy;
  2576. begin
  2577. if assigned(symtable) then
  2578. symtable.free;
  2579. inherited destroy;
  2580. end;
  2581. function trecorddef.needs_inittable : boolean;
  2582. begin
  2583. needs_inittable:=trecordsymtable(symtable).needs_init_final
  2584. end;
  2585. procedure trecorddef.deref;
  2586. var
  2587. oldrecsyms : tsymtable;
  2588. begin
  2589. inherited deref;
  2590. oldrecsyms:=aktrecordsymtable;
  2591. aktrecordsymtable:=symtable;
  2592. { now dereference the definitions }
  2593. tstoredsymtable(symtable).deref;
  2594. aktrecordsymtable:=oldrecsyms;
  2595. { assign TGUID? load only from system unit (unitid=1) }
  2596. if not(assigned(rec_tguid)) and
  2597. (upper(typename)='TGUID') and
  2598. assigned(owner) and
  2599. assigned(owner.name) and
  2600. (owner.name^='SYSTEM') then
  2601. rec_tguid:=self;
  2602. end;
  2603. procedure trecorddef.ppuwrite(ppufile:tcompilerppufile);
  2604. begin
  2605. inherited ppuwritedef(ppufile);
  2606. ppufile.putlongint(savesize);
  2607. ppufile.putlongint(trecordsymtable(symtable).datasize);
  2608. ppufile.putbyte(trecordsymtable(symtable).dataalignment);
  2609. ppufile.writeentry(ibrecorddef);
  2610. trecordsymtable(symtable).ppuwrite(ppufile);
  2611. end;
  2612. function trecorddef.size:longint;
  2613. begin
  2614. result:=trecordsymtable(symtable).datasize;
  2615. end;
  2616. function trecorddef.alignment:longint;
  2617. var
  2618. l : longint;
  2619. hp : tvarsym;
  2620. begin
  2621. { also check the first symbol for it's size, because a
  2622. packed record has dataalignment of 1, but the first
  2623. sym could be a longint which should be aligned on 4 bytes,
  2624. this is compatible with C record packing (PFV) }
  2625. hp:=tvarsym(symtable.symindex.first);
  2626. if assigned(hp) then
  2627. begin
  2628. if hp.vartype.def.deftype in [recorddef,arraydef] then
  2629. l:=hp.vartype.def.alignment
  2630. else
  2631. l:=hp.vartype.def.size;
  2632. if l>trecordsymtable(symtable).dataalignment then
  2633. begin
  2634. if l>=4 then
  2635. alignment:=4
  2636. else
  2637. if l>=2 then
  2638. alignment:=2
  2639. else
  2640. alignment:=1;
  2641. end
  2642. else
  2643. alignment:=trecordsymtable(symtable).dataalignment;
  2644. end
  2645. else
  2646. alignment:=trecordsymtable(symtable).dataalignment;
  2647. end;
  2648. {$ifdef GDB}
  2649. function trecorddef.stabstring : pchar;
  2650. begin
  2651. GetMem(stabrecstring,memsizeinc);
  2652. stabrecsize:=memsizeinc;
  2653. strpcopy(stabRecString,'s'+tostr(size));
  2654. RecOffset := 0;
  2655. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addname,nil);
  2656. strpcopy(strend(StabRecString),';');
  2657. stabstring := strnew(StabRecString);
  2658. Freemem(stabrecstring,stabrecsize);
  2659. end;
  2660. procedure trecorddef.concatstabto(asmlist : taasmoutput);
  2661. begin
  2662. if (not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  2663. (is_def_stab_written = not_written) then
  2664. inherited concatstabto(asmlist);
  2665. end;
  2666. {$endif GDB}
  2667. procedure trecorddef.write_child_rtti_data(rt:trttitype);
  2668. begin
  2669. FRTTIType:=rt;
  2670. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_field_rtti,nil);
  2671. end;
  2672. procedure trecorddef.write_rtti_data(rt:trttitype);
  2673. begin
  2674. rttiList.concat(Tai_const.Create_8bit(tkrecord));
  2675. write_rtti_name;
  2676. rttiList.concat(Tai_const.Create_32bit(size));
  2677. Count:=0;
  2678. FRTTIType:=rt;
  2679. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_field_rtti,nil);
  2680. rttiList.concat(Tai_const.Create_32bit(Count));
  2681. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti,nil);
  2682. end;
  2683. function trecorddef.gettypename : string;
  2684. begin
  2685. gettypename:='<record type>'
  2686. end;
  2687. {***************************************************************************
  2688. TABSTRACTPROCDEF
  2689. ***************************************************************************}
  2690. constructor tabstractprocdef.create(level:byte);
  2691. begin
  2692. inherited create;
  2693. parast:=tparasymtable.create(level);
  2694. parast.defowner:=self;
  2695. parast.next:=owner;
  2696. para:=TLinkedList.Create;
  2697. paraalign:=std_param_align;
  2698. minparacount:=0;
  2699. maxparacount:=0;
  2700. proctypeoption:=potype_none;
  2701. proccalloption:=pocall_none;
  2702. procoptions:=[];
  2703. rettype:=voidtype;
  2704. fpu_used:=0;
  2705. savesize:=POINTER_SIZE;
  2706. has_paraloc_info:=false;
  2707. end;
  2708. destructor tabstractprocdef.destroy;
  2709. begin
  2710. if assigned(para) then
  2711. para.free;
  2712. if assigned(parast) then
  2713. begin
  2714. {$ifdef MEMDEBUG}
  2715. memprocparast.start;
  2716. {$endif MEMDEBUG}
  2717. parast.free;
  2718. {$ifdef MEMDEBUG}
  2719. memprocparast.stop;
  2720. {$endif MEMDEBUG}
  2721. end;
  2722. inherited destroy;
  2723. end;
  2724. procedure tabstractprocdef.releasemem;
  2725. begin
  2726. para.free;
  2727. para:=nil;
  2728. parast.free;
  2729. parast:=nil;
  2730. end;
  2731. procedure tabstractprocdef.set_calloption(calloption:tproccalloption);
  2732. begin
  2733. proccalloption:=calloption;
  2734. { Update parameter alignment }
  2735. paraalign:=paramanager.get_para_align(proccalloption);
  2736. end;
  2737. function tabstractprocdef.concatpara(afterpara:tparaitem;const tt:ttype;sym : tsym;defval:tsym;vhidden:boolean):tparaitem;
  2738. var
  2739. hp : TParaItem;
  2740. begin
  2741. hp:=TParaItem.Create;
  2742. hp.paratyp:=tvarsym(sym).varspez;
  2743. hp.parasym:=sym;
  2744. hp.paratype:=tt;
  2745. hp.is_hidden:=vhidden;
  2746. hp.defaultvalue:=defval;
  2747. { Parameters are stored from left to right }
  2748. if assigned(afterpara) then
  2749. Para.insertafter(hp,afterpara)
  2750. else
  2751. Para.concat(hp);
  2752. { Don't count hidden parameters }
  2753. if not vhidden then
  2754. begin
  2755. if not assigned(defval) then
  2756. inc(minparacount);
  2757. inc(maxparacount);
  2758. end;
  2759. concatpara:=hp;
  2760. end;
  2761. function tabstractprocdef.insertpara(const tt:ttype;sym : tsym;defval:tsym;vhidden:boolean):tparaitem;
  2762. var
  2763. hp : TParaItem;
  2764. begin
  2765. hp:=TParaItem.Create;
  2766. hp.paratyp:=tvarsym(sym).varspez;
  2767. hp.parasym:=sym;
  2768. hp.paratype:=tt;
  2769. hp.is_hidden:=vhidden;
  2770. hp.defaultvalue:=defval;
  2771. { Parameters are stored from left to right }
  2772. Para.insert(hp);
  2773. { Don't count hidden parameters }
  2774. if (not vhidden) then
  2775. begin
  2776. if not assigned(defval) then
  2777. inc(minparacount);
  2778. inc(maxparacount);
  2779. end;
  2780. insertpara:=hp;
  2781. end;
  2782. procedure tabstractprocdef.removepara(currpara:tparaitem);
  2783. begin
  2784. { Don't count hidden parameters }
  2785. if (not currpara.is_hidden) then
  2786. begin
  2787. if not assigned(currpara.defaultvalue) then
  2788. dec(minparacount);
  2789. dec(maxparacount);
  2790. end;
  2791. Para.Remove(currpara);
  2792. currpara.free;
  2793. end;
  2794. { all functions returning in FPU are
  2795. assume to use 2 FPU registers
  2796. until the function implementation
  2797. is processed PM }
  2798. procedure tabstractprocdef.test_if_fpu_result;
  2799. begin
  2800. if assigned(rettype.def) and
  2801. (rettype.def.deftype=floatdef) then
  2802. fpu_used:=maxfpuregs;
  2803. end;
  2804. procedure tabstractprocdef.deref;
  2805. var
  2806. hp : TParaItem;
  2807. begin
  2808. inherited deref;
  2809. rettype.resolve;
  2810. { parast }
  2811. tparasymtable(parast).deref;
  2812. { paraitems }
  2813. hp:=TParaItem(Para.first);
  2814. while assigned(hp) do
  2815. begin
  2816. hp.paratype.resolve;
  2817. hp.defaultvalue:=tsym(hp.defaultvaluederef.resolve);
  2818. hp.parasym:=tvarsym(hp.parasymderef.resolve);
  2819. { connect parasym to paraitem }
  2820. tvarsym(hp.parasym).paraitem:=hp;
  2821. hp:=TParaItem(hp.next);
  2822. end;
  2823. end;
  2824. constructor tabstractprocdef.ppuload(ppufile:tcompilerppufile);
  2825. var
  2826. hp : TParaItem;
  2827. count,i : word;
  2828. begin
  2829. inherited ppuloaddef(ppufile);
  2830. parast:=nil;
  2831. Para:=TLinkedList.Create;
  2832. minparacount:=0;
  2833. maxparacount:=0;
  2834. ppufile.gettype(rettype);
  2835. fpu_used:=ppufile.getbyte;
  2836. paraalign:=ppufile.getbyte;
  2837. proctypeoption:=tproctypeoption(ppufile.getbyte);
  2838. proccalloption:=tproccalloption(ppufile.getbyte);
  2839. ppufile.getsmallset(procoptions);
  2840. { get the number of parameters }
  2841. count:=ppufile.getbyte;
  2842. savesize:=POINTER_SIZE;
  2843. has_paraloc_info:=false;
  2844. for i:=1 to count do
  2845. begin
  2846. hp:=TParaItem.Create;
  2847. hp.paratyp:=tvarspez(ppufile.getbyte);
  2848. ppufile.gettype(hp.paratype);
  2849. ppufile.getderef(hp.defaultvaluederef);
  2850. hp.defaultvalue:=nil;
  2851. ppufile.getderef(hp.parasymderef);
  2852. hp.parasym:=nil;
  2853. hp.is_hidden:=boolean(ppufile.getbyte);
  2854. { Don't count hidden parameters }
  2855. if (not hp.is_hidden) then
  2856. begin
  2857. if not assigned(hp.defaultvalue) then
  2858. inc(minparacount);
  2859. inc(maxparacount);
  2860. end;
  2861. { Parameters are stored left to right in both ppu and memory }
  2862. Para.concat(hp);
  2863. end;
  2864. end;
  2865. procedure tabstractprocdef.ppuwrite(ppufile:tcompilerppufile);
  2866. var
  2867. hp : TParaItem;
  2868. oldintfcrc : boolean;
  2869. begin
  2870. inherited ppuwritedef(ppufile);
  2871. ppufile.puttype(rettype);
  2872. oldintfcrc:=ppufile.do_interface_crc;
  2873. ppufile.do_interface_crc:=false;
  2874. if simplify_ppu then
  2875. fpu_used:=0;
  2876. ppufile.putbyte(fpu_used);
  2877. ppufile.putbyte(paraalign);
  2878. ppufile.putbyte(ord(proctypeoption));
  2879. ppufile.putbyte(ord(proccalloption));
  2880. ppufile.putsmallset(procoptions);
  2881. ppufile.do_interface_crc:=oldintfcrc;
  2882. { we need to store the count including vs_hidden }
  2883. ppufile.putbyte(para.count);
  2884. hp:=TParaItem(Para.first);
  2885. while assigned(hp) do
  2886. begin
  2887. ppufile.putbyte(byte(hp.paratyp));
  2888. ppufile.puttype(hp.paratype);
  2889. ppufile.putderef(hp.defaultvalue,hp.defaultvaluederef);
  2890. ppufile.putderef(hp.parasym,hp.parasymderef);
  2891. ppufile.putbyte(byte(hp.is_hidden));
  2892. hp:=TParaItem(hp.next);
  2893. end;
  2894. end;
  2895. function tabstractprocdef.typename_paras(showhidden:boolean) : string;
  2896. var
  2897. hs,s : string;
  2898. hp : TParaItem;
  2899. hpc : tconstsym;
  2900. first : boolean;
  2901. begin
  2902. hp:=TParaItem(Para.first);
  2903. s:='';
  2904. first:=true;
  2905. while assigned(hp) do
  2906. begin
  2907. if (not hp.is_hidden) or
  2908. (showhidden) then
  2909. begin
  2910. if first then
  2911. begin
  2912. s:=s+'(';
  2913. first:=false;
  2914. end
  2915. else
  2916. s:=s+',';
  2917. case hp.paratyp of
  2918. vs_var :
  2919. s:=s+'var';
  2920. vs_const :
  2921. s:=s+'const';
  2922. vs_out :
  2923. s:=s+'out';
  2924. end;
  2925. if assigned(hp.paratype.def.typesym) then
  2926. begin
  2927. if s<>'(' then
  2928. s:=s+' ';
  2929. hs:=hp.paratype.def.typesym.realname;
  2930. if hs[1]<>'$' then
  2931. s:=s+hp.paratype.def.typesym.realname
  2932. else
  2933. s:=s+hp.paratype.def.gettypename;
  2934. end
  2935. else
  2936. s:=s+hp.paratype.def.gettypename;
  2937. { default value }
  2938. if assigned(hp.defaultvalue) then
  2939. begin
  2940. hpc:=tconstsym(hp.defaultvalue);
  2941. hs:='';
  2942. case hpc.consttyp of
  2943. conststring,
  2944. constresourcestring :
  2945. hs:=strpas(pchar(hpc.value.valueptr));
  2946. constreal :
  2947. str(pbestreal(hpc.value.valueptr)^,hs);
  2948. constord :
  2949. hs:=tostr(hpc.value.valueord);
  2950. constpointer :
  2951. hs:=tostr(hpc.value.valueordptr);
  2952. constbool :
  2953. begin
  2954. if hpc.value.valueord<>0 then
  2955. hs:='TRUE'
  2956. else
  2957. hs:='FALSE';
  2958. end;
  2959. constnil :
  2960. hs:='nil';
  2961. constchar :
  2962. hs:=chr(hpc.value.valueord);
  2963. constset :
  2964. hs:='<set>';
  2965. end;
  2966. if hs<>'' then
  2967. s:=s+'="'+hs+'"';
  2968. end;
  2969. end;
  2970. hp:=TParaItem(hp.next);
  2971. end;
  2972. if not first then
  2973. s:=s+')';
  2974. if (po_varargs in procoptions) then
  2975. s:=s+';VarArgs';
  2976. typename_paras:=s;
  2977. end;
  2978. function tabstractprocdef.is_methodpointer:boolean;
  2979. begin
  2980. result:=false;
  2981. end;
  2982. function tabstractprocdef.is_addressonly:boolean;
  2983. begin
  2984. result:=true;
  2985. end;
  2986. {$ifdef GDB}
  2987. function tabstractprocdef.stabstring : pchar;
  2988. begin
  2989. stabstring := strpnew('abstractproc'+numberstring+';');
  2990. end;
  2991. procedure tabstractprocdef.concatstabto(asmlist : taasmoutput);
  2992. begin
  2993. if (not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2994. and (is_def_stab_written = not_written) then
  2995. begin
  2996. if assigned(rettype.def) then forcestabto(asmlist,rettype.def);
  2997. inherited concatstabto(asmlist);
  2998. end;
  2999. end;
  3000. {$endif GDB}
  3001. {***************************************************************************
  3002. TPROCDEF
  3003. ***************************************************************************}
  3004. constructor tprocdef.create(level:byte);
  3005. begin
  3006. inherited create(level);
  3007. deftype:=procdef;
  3008. has_mangledname:=false;
  3009. _mangledname:=nil;
  3010. fileinfo:=aktfilepos;
  3011. extnumber:=$ffff;
  3012. aliasnames:=tstringlist.create;
  3013. funcretsym:=nil;
  3014. localst := nil;
  3015. defref:=nil;
  3016. lastwritten:=nil;
  3017. refcount:=0;
  3018. if (cs_browser in aktmoduleswitches) and make_ref then
  3019. begin
  3020. defref:=tref.create(defref,@akttokenpos);
  3021. inc(refcount);
  3022. end;
  3023. lastref:=defref;
  3024. { first, we assume that all registers are used }
  3025. usedintregisters:=paramanager.get_volatile_registers_int(pocall_default);
  3026. usedotherregisters:=ALL_OTHERREGISTERS;
  3027. forwarddef:=true;
  3028. interfacedef:=false;
  3029. hasforward:=false;
  3030. _class := nil;
  3031. code:=nil;
  3032. regvarinfo := nil;
  3033. overloadnumber:=0;
  3034. {$ifdef GDB}
  3035. isstabwritten := false;
  3036. {$endif GDB}
  3037. end;
  3038. constructor tprocdef.ppuload(ppufile:tcompilerppufile);
  3039. begin
  3040. inherited ppuload(ppufile);
  3041. deftype:=procdef;
  3042. ppufile.getnormalset(usedintregisters);
  3043. ppufile.getnormalset(usedotherregisters);
  3044. has_mangledname:=boolean(ppufile.getbyte);
  3045. if has_mangledname then
  3046. _mangledname:=stringdup(ppufile.getstring)
  3047. else
  3048. _mangledname:=nil;
  3049. overloadnumber:=ppufile.getword;
  3050. extnumber:=ppufile.getword;
  3051. ppufile.getderef(_classderef);
  3052. ppufile.getderef(procsymderef);
  3053. ppufile.getposinfo(fileinfo);
  3054. ppufile.getsmallset(symoptions);
  3055. { inline stuff }
  3056. if proccalloption=pocall_inline then
  3057. begin
  3058. ppufile.getderef(funcretsymderef);
  3059. code:=ppuloadnode(ppufile);
  3060. end
  3061. else
  3062. begin
  3063. code := nil;
  3064. funcretsym:=nil;
  3065. end;
  3066. { load para symtable }
  3067. parast:=tparasymtable.create(unknown_level);
  3068. tparasymtable(parast).ppuload(ppufile);
  3069. parast.defowner:=self;
  3070. { load local symtable }
  3071. if (proccalloption=pocall_inline) or
  3072. ((current_module.flags and uf_local_browser)<>0) then
  3073. begin
  3074. localst:=tlocalsymtable.create(unknown_level);
  3075. tlocalsymtable(localst).ppuload(ppufile);
  3076. localst.defowner:=self;
  3077. end
  3078. else
  3079. localst:=nil;
  3080. { default values for no persistent data }
  3081. if (cs_link_deffile in aktglobalswitches) and
  3082. (tf_need_export in target_info.flags) and
  3083. (po_exports in procoptions) then
  3084. deffile.AddExport(mangledname);
  3085. aliasnames:=tstringlist.create;
  3086. forwarddef:=false;
  3087. interfacedef:=false;
  3088. hasforward:=false;
  3089. regvarinfo := nil;
  3090. lastref:=nil;
  3091. lastwritten:=nil;
  3092. defref:=nil;
  3093. refcount:=0;
  3094. {$ifdef GDB}
  3095. isstabwritten := false;
  3096. {$endif GDB}
  3097. end;
  3098. destructor tprocdef.destroy;
  3099. begin
  3100. if assigned(defref) then
  3101. begin
  3102. defref.freechain;
  3103. defref.free;
  3104. end;
  3105. aliasnames.free;
  3106. if assigned(localst) and (localst.symtabletype<>staticsymtable) then
  3107. begin
  3108. {$ifdef MEMDEBUG}
  3109. memproclocalst.start;
  3110. {$endif MEMDEBUG}
  3111. localst.free;
  3112. {$ifdef MEMDEBUG}
  3113. memproclocalst.start;
  3114. {$endif MEMDEBUG}
  3115. end;
  3116. if (proccalloption=pocall_inline) and assigned(code) then
  3117. begin
  3118. {$ifdef MEMDEBUG}
  3119. memprocnodetree.start;
  3120. {$endif MEMDEBUG}
  3121. tnode(code).free;
  3122. {$ifdef MEMDEBUG}
  3123. memprocnodetree.start;
  3124. {$endif MEMDEBUG}
  3125. end;
  3126. if assigned(regvarinfo) then
  3127. dispose(pregvarinfo(regvarinfo));
  3128. if (po_msgstr in procoptions) then
  3129. strdispose(messageinf.str);
  3130. if assigned(_mangledname) then
  3131. begin
  3132. {$ifdef MEMDEBUG}
  3133. memmanglednames.start;
  3134. {$endif MEMDEBUG}
  3135. stringdispose(_mangledname);
  3136. {$ifdef MEMDEBUG}
  3137. memmanglednames.stop;
  3138. {$endif MEMDEBUG}
  3139. end;
  3140. inherited destroy;
  3141. end;
  3142. procedure tprocdef.ppuwrite(ppufile:tcompilerppufile);
  3143. var
  3144. oldintfcrc : boolean;
  3145. oldparasymtable,
  3146. oldlocalsymtable : tsymtable;
  3147. begin
  3148. oldparasymtable:=aktparasymtable;
  3149. oldlocalsymtable:=aktlocalsymtable;
  3150. aktparasymtable:=parast;
  3151. aktlocalsymtable:=localst;
  3152. inherited ppuwrite(ppufile);
  3153. oldintfcrc:=ppufile.do_interface_crc;
  3154. ppufile.do_interface_crc:=false;
  3155. { set all registers to used for simplified compilation PM }
  3156. if simplify_ppu then
  3157. begin
  3158. usedintregisters:=paramanager.get_volatile_registers_int(pocall_default);
  3159. usedotherregisters:=ALL_OTHERREGISTERS;
  3160. end;
  3161. ppufile.putnormalset(usedintregisters);
  3162. ppufile.putnormalset(usedotherregisters);
  3163. ppufile.do_interface_crc:=oldintfcrc;
  3164. ppufile.putbyte(byte(has_mangledname));
  3165. if has_mangledname then
  3166. ppufile.putstring(mangledname);
  3167. ppufile.putword(overloadnumber);
  3168. ppufile.putword(extnumber);
  3169. ppufile.putderef(_class,_classderef);
  3170. ppufile.putderef(procsym,procsymderef);
  3171. ppufile.putposinfo(fileinfo);
  3172. ppufile.putsmallset(symoptions);
  3173. { inline stuff references to localsymtable, no influence
  3174. on the crc }
  3175. oldintfcrc:=ppufile.do_crc;
  3176. ppufile.do_crc:=false;
  3177. { inline stuff }
  3178. if proccalloption=pocall_inline then
  3179. begin
  3180. ppufile.putderef(funcretsym,funcretsymderef);
  3181. ppuwritenode(ppufile,code);
  3182. end;
  3183. ppufile.do_crc:=oldintfcrc;
  3184. { write this entry }
  3185. ppufile.writeentry(ibprocdef);
  3186. { Save the para symtable, this is taken from the interface }
  3187. tparasymtable(parast).ppuwrite(ppufile);
  3188. { save localsymtable for inline procedures or when local
  3189. browser info is requested, this has no influence on the crc }
  3190. if (proccalloption=pocall_inline) or
  3191. ((current_module.flags and uf_local_browser)<>0) then
  3192. begin
  3193. oldintfcrc:=ppufile.do_crc;
  3194. ppufile.do_crc:=false;
  3195. if not assigned(localst) then
  3196. begin
  3197. localst:=tlocalsymtable.create(unknown_level);
  3198. localst.defowner:=self;
  3199. end;
  3200. tlocalsymtable(localst).ppuwrite(ppufile);
  3201. ppufile.do_crc:=oldintfcrc;
  3202. end;
  3203. aktparasymtable:=oldparasymtable;
  3204. aktlocalsymtable:=oldlocalsymtable;
  3205. end;
  3206. procedure tprocdef.insert_localst;
  3207. begin
  3208. localst:=tlocalsymtable.create(parast.symtablelevel);
  3209. localst.defowner:=self;
  3210. { this is used by insert
  3211. to check same names in parast and localst }
  3212. localst.next:=parast;
  3213. end;
  3214. function tprocdef.fullprocname(showhidden:boolean):string;
  3215. var
  3216. s : string;
  3217. t : ttoken;
  3218. begin
  3219. {$ifdef EXTDEBUG}
  3220. showhidden:=true;
  3221. {$endif EXTDEBUG}
  3222. s:='';
  3223. if assigned(_class) then
  3224. begin
  3225. if po_classmethod in procoptions then
  3226. s:=s+'class ';
  3227. s:=s+_class.objrealname^+'.';
  3228. end;
  3229. if proctypeoption=potype_operator then
  3230. begin
  3231. for t:=NOTOKEN to last_overloaded do
  3232. if procsym.realname='$'+overloaded_names[t] then
  3233. begin
  3234. s:='operator '+arraytokeninfo[t].str+typename_paras(showhidden);
  3235. break;
  3236. end;
  3237. end
  3238. else
  3239. s:=s+procsym.realname+typename_paras(showhidden);
  3240. case proctypeoption of
  3241. potype_constructor:
  3242. s:='constructor '+s;
  3243. potype_destructor:
  3244. s:='destructor '+s;
  3245. else
  3246. if assigned(rettype.def) and
  3247. not(is_void(rettype.def)) then
  3248. s:=s+':'+rettype.def.gettypename;
  3249. end;
  3250. fullprocname:=s;
  3251. end;
  3252. function tprocdef.is_methodpointer:boolean;
  3253. begin
  3254. result:=assigned(_class);
  3255. end;
  3256. function tprocdef.is_addressonly:boolean;
  3257. begin
  3258. result:=assigned(owner) and
  3259. (owner.symtabletype<>objectsymtable);
  3260. end;
  3261. (*
  3262. function tprocdef.is_visible_for_proc(currprocdef:tprocdef):boolean;
  3263. begin
  3264. is_visible_for_proc:=false;
  3265. { private symbols are allowed when we are in the same
  3266. module as they are defined }
  3267. if (sp_private in symoptions) and
  3268. assigned(owner.defowner) and
  3269. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  3270. (owner.defowner.owner.unitid<>0) then
  3271. exit;
  3272. { protected symbols are vissible in the module that defines them and
  3273. also visible to related objects }
  3274. if (sp_protected in symoptions) and
  3275. (
  3276. (
  3277. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  3278. (owner.defowner.owner.unitid<>0)
  3279. ) and
  3280. not(
  3281. assigned(currprocdef) and
  3282. assigned(currprocdef._class) and
  3283. currprocdef._class.is_related(tobjectdef(owner.defowner))
  3284. )
  3285. ) then
  3286. exit;
  3287. is_visible_for_proc:=true;
  3288. end;
  3289. *)
  3290. function tprocdef.is_visible_for_object(currobjdef:tobjectdef):boolean;
  3291. begin
  3292. is_visible_for_object:=false;
  3293. { private symbols are allowed when we are in the same
  3294. module as they are defined }
  3295. if (sp_private in symoptions) and
  3296. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  3297. (owner.defowner.owner.unitid<>0) then
  3298. exit;
  3299. { protected symbols are vissible in the module that defines them and
  3300. also visible to related objects. The related object must be defined
  3301. in the current module }
  3302. if (sp_protected in symoptions) and
  3303. (
  3304. (
  3305. (owner.defowner.owner.symtabletype in [globalsymtable,staticsymtable]) and
  3306. (owner.defowner.owner.unitid<>0)
  3307. ) and
  3308. not(
  3309. assigned(currobjdef) and
  3310. (currobjdef.owner.unitid=0) and
  3311. currobjdef.is_related(tobjectdef(owner.defowner))
  3312. )
  3313. ) then
  3314. exit;
  3315. is_visible_for_object:=true;
  3316. end;
  3317. function tprocdef.getsymtable(t:tgetsymtable):tsymtable;
  3318. begin
  3319. case t of
  3320. gs_local :
  3321. getsymtable:=localst;
  3322. gs_para :
  3323. getsymtable:=parast;
  3324. else
  3325. getsymtable:=nil;
  3326. end;
  3327. end;
  3328. procedure tprocdef.load_references(ppufile:tcompilerppufile;locals:boolean);
  3329. var
  3330. pos : tfileposinfo;
  3331. move_last : boolean;
  3332. oldparasymtable,
  3333. oldlocalsymtable : tsymtable;
  3334. begin
  3335. oldparasymtable:=aktparasymtable;
  3336. oldlocalsymtable:=aktlocalsymtable;
  3337. aktparasymtable:=parast;
  3338. aktlocalsymtable:=localst;
  3339. move_last:=lastwritten=lastref;
  3340. while (not ppufile.endofentry) do
  3341. begin
  3342. ppufile.getposinfo(pos);
  3343. inc(refcount);
  3344. lastref:=tref.create(lastref,@pos);
  3345. lastref.is_written:=true;
  3346. if refcount=1 then
  3347. defref:=lastref;
  3348. end;
  3349. if move_last then
  3350. lastwritten:=lastref;
  3351. if ((current_module.flags and uf_local_browser)<>0) and
  3352. locals then
  3353. begin
  3354. tparasymtable(parast).load_references(ppufile,locals);
  3355. tlocalsymtable(localst).load_references(ppufile,locals);
  3356. end;
  3357. aktparasymtable:=oldparasymtable;
  3358. aktlocalsymtable:=oldlocalsymtable;
  3359. end;
  3360. Const
  3361. local_symtable_index : word = $8001;
  3362. function tprocdef.write_references(ppufile:tcompilerppufile;locals:boolean):boolean;
  3363. var
  3364. ref : tref;
  3365. pdo : tobjectdef;
  3366. move_last : boolean;
  3367. d : tderef;
  3368. oldparasymtable,
  3369. oldlocalsymtable : tsymtable;
  3370. begin
  3371. d.reset;
  3372. move_last:=lastwritten=lastref;
  3373. if move_last and
  3374. (((current_module.flags and uf_local_browser)=0) or
  3375. not locals) then
  3376. exit;
  3377. oldparasymtable:=aktparasymtable;
  3378. oldlocalsymtable:=aktlocalsymtable;
  3379. aktparasymtable:=parast;
  3380. aktlocalsymtable:=localst;
  3381. { write address of this symbol }
  3382. ppufile.putderef(self,d);
  3383. { write refs }
  3384. if assigned(lastwritten) then
  3385. ref:=lastwritten
  3386. else
  3387. ref:=defref;
  3388. while assigned(ref) do
  3389. begin
  3390. if ref.moduleindex=current_module.unit_index then
  3391. begin
  3392. ppufile.putposinfo(ref.posinfo);
  3393. ref.is_written:=true;
  3394. if move_last then
  3395. lastwritten:=ref;
  3396. end
  3397. else if not ref.is_written then
  3398. move_last:=false
  3399. else if move_last then
  3400. lastwritten:=ref;
  3401. ref:=ref.nextref;
  3402. end;
  3403. ppufile.writeentry(ibdefref);
  3404. write_references:=true;
  3405. if ((current_module.flags and uf_local_browser)<>0) and
  3406. locals then
  3407. begin
  3408. pdo:=_class;
  3409. if (owner.symtabletype<>localsymtable) then
  3410. while assigned(pdo) do
  3411. begin
  3412. if pdo.symtable<>aktrecordsymtable then
  3413. begin
  3414. pdo.symtable.unitid:=local_symtable_index;
  3415. inc(local_symtable_index);
  3416. end;
  3417. pdo:=pdo.childof;
  3418. end;
  3419. parast.unitid:=local_symtable_index;
  3420. inc(local_symtable_index);
  3421. localst.unitid:=local_symtable_index;
  3422. inc(local_symtable_index);
  3423. tstoredsymtable(parast).write_references(ppufile,locals);
  3424. tstoredsymtable(localst).write_references(ppufile,locals);
  3425. { decrement for }
  3426. local_symtable_index:=local_symtable_index-2;
  3427. pdo:=_class;
  3428. if (owner.symtabletype<>localsymtable) then
  3429. while assigned(pdo) do
  3430. begin
  3431. if pdo.symtable<>aktrecordsymtable then
  3432. dec(local_symtable_index);
  3433. pdo:=pdo.childof;
  3434. end;
  3435. end;
  3436. aktparasymtable:=oldparasymtable;
  3437. aktlocalsymtable:=oldlocalsymtable;
  3438. end;
  3439. {$ifdef GDB}
  3440. {$ifdef unused}
  3441. { procedure addparaname(p : tsym);
  3442. var vs : char;
  3443. begin
  3444. if tvarsym(p).varspez = vs_value then vs := '1'
  3445. else vs := '0';
  3446. strpcopy(strend(StabRecString),p^.name+':'+tstoreddef(tvarsym(p).vartype.def).numberstring+','+vs+';');
  3447. end; }
  3448. function tprocdef.stabstring : pchar;
  3449. var
  3450. i : longint;
  3451. stabrecstring : pchar;
  3452. begin
  3453. getmem(StabRecString,1024);
  3454. strpcopy(StabRecString,'f'+tstoreddef(rettype.def).numberstring);
  3455. i:=maxparacount;
  3456. if i>0 then
  3457. begin
  3458. strpcopy(strend(StabRecString),','+tostr(i)+';');
  3459. (* confuse gdb !! PM
  3460. if assigned(parast) then
  3461. parast.foreach({$ifdef FPCPROCVAR}@{$endif}addparaname)
  3462. else
  3463. begin
  3464. param := para1;
  3465. i := 0;
  3466. while assigned(param) do
  3467. begin
  3468. inc(i);
  3469. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  3470. {Here we have lost the parameter names !!}
  3471. {using lower case parameters }
  3472. strpcopy(strend(stabrecstring),'p'+tostr(i)
  3473. +':'+param^.paratype.def.numberstring+','+vartyp+';');
  3474. param := param^.next;
  3475. end;
  3476. end; *)
  3477. {strpcopy(strend(StabRecString),';');}
  3478. end;
  3479. stabstring := strnew(stabrecstring);
  3480. freemem(stabrecstring,1024);
  3481. end;
  3482. {$endif unused}
  3483. function tprocdef.stabstring: pchar;
  3484. Var RType : Char;
  3485. Obj,Info : String;
  3486. stabsstr : string;
  3487. p : pchar;
  3488. begin
  3489. obj := procsym.name;
  3490. info := '';
  3491. if tprocsym(procsym).is_global then
  3492. RType := 'F'
  3493. else
  3494. RType := 'f';
  3495. if assigned(owner) then
  3496. begin
  3497. if (owner.symtabletype = objectsymtable) then
  3498. obj := owner.name^+'__'+procsym.name;
  3499. { this code was correct only as long as the local symboltable
  3500. of the parent had the same name as the function
  3501. but this is no true anymore !! PM
  3502. if (owner.symtabletype=localsymtable) and assigned(owner.name) then
  3503. info := ','+name+','+owner.name^; }
  3504. if (owner.symtabletype=localsymtable) and
  3505. assigned(owner.defowner) and
  3506. assigned(tprocdef(owner.defowner).procsym) then
  3507. info := ','+procsym.name+','+tprocdef(owner.defowner).procsym.name;
  3508. end;
  3509. stabsstr:=mangledname;
  3510. getmem(p,length(stabsstr)+255);
  3511. strpcopy(p,'"'+obj+':'+RType
  3512. +tstoreddef(rettype.def).numberstring+info+'",'+tostr(n_function)
  3513. +',0,'+
  3514. tostr(fileinfo.line)
  3515. +',');
  3516. strpcopy(strend(p),stabsstr);
  3517. stabstring:=strnew(p);
  3518. freemem(p,length(stabsstr)+255);
  3519. end;
  3520. procedure tprocdef.concatstabto(asmlist : taasmoutput);
  3521. begin
  3522. if (proccalloption=pocall_internproc) then
  3523. exit;
  3524. if not isstabwritten then
  3525. asmList.concat(Tai_stabs.Create(stabstring));
  3526. isstabwritten := true;
  3527. if not(po_external in procoptions) then
  3528. begin
  3529. tstoredsymtable(parast).concatstabto(asmlist);
  3530. { local type defs and vars should not be written
  3531. inside the main proc stab }
  3532. if assigned(localst) and
  3533. (localst.symtablelevel>main_program_level) then
  3534. tstoredsymtable(localst).concatstabto(asmlist);
  3535. end;
  3536. is_def_stab_written := written;
  3537. end;
  3538. {$endif GDB}
  3539. procedure tprocdef.deref;
  3540. var
  3541. oldparasymtable,
  3542. oldlocalsymtable : tsymtable;
  3543. begin
  3544. oldparasymtable:=aktparasymtable;
  3545. oldlocalsymtable:=aktlocalsymtable;
  3546. aktparasymtable:=parast;
  3547. aktlocalsymtable:=localst;
  3548. inherited deref;
  3549. _class:=tobjectdef(_classderef.resolve);
  3550. { procsym that originaly defined this definition, should be in the
  3551. same symtable }
  3552. procsym:=tprocsym(procsymderef.resolve);
  3553. aktparasymtable:=oldparasymtable;
  3554. aktlocalsymtable:=oldlocalsymtable;
  3555. end;
  3556. procedure tprocdef.derefimpl;
  3557. var
  3558. oldparasymtable,
  3559. oldlocalsymtable : tsymtable;
  3560. begin
  3561. oldparasymtable:=aktparasymtable;
  3562. oldlocalsymtable:=aktlocalsymtable;
  3563. aktparasymtable:=parast;
  3564. aktlocalsymtable:=localst;
  3565. { locals }
  3566. if assigned(localst) then
  3567. begin
  3568. { localst }
  3569. { we can deref both interface and implementation parts }
  3570. tlocalsymtable(localst).deref;
  3571. tlocalsymtable(localst).derefimpl;
  3572. { funcretsym, this is always located in the localst }
  3573. funcretsym:=tsym(funcretsymderef.resolve);
  3574. end
  3575. else
  3576. begin
  3577. { safety }
  3578. funcretsym:=nil;
  3579. end;
  3580. { inline tree }
  3581. if (proccalloption=pocall_inline) then
  3582. code.derefimpl;
  3583. aktparasymtable:=oldparasymtable;
  3584. aktlocalsymtable:=oldlocalsymtable;
  3585. end;
  3586. function tprocdef.gettypename : string;
  3587. begin
  3588. gettypename := FullProcName(false)+';'+ProcCallOptionStr[proccalloption];
  3589. end;
  3590. function tprocdef.mangledname : string;
  3591. var
  3592. s : string;
  3593. hp : TParaItem;
  3594. begin
  3595. if assigned(_mangledname) then
  3596. begin
  3597. mangledname:=_mangledname^;
  3598. exit;
  3599. end;
  3600. { we need to use the symtable where the procsym is inserted,
  3601. because that is visible to the world }
  3602. s:=mangledname_prefix('',procsym.owner)+procsym.name;
  3603. if overloadnumber>0 then
  3604. s:=s+'$'+tostr(overloadnumber);
  3605. { add parameter types }
  3606. hp:=TParaItem(Para.first);
  3607. while assigned(hp) do
  3608. begin
  3609. if not hp.is_hidden then
  3610. s:=s+'$'+hp.paratype.def.mangledparaname;
  3611. hp:=TParaItem(hp.next);
  3612. end;
  3613. _mangledname:=stringdup(s);
  3614. mangledname:=_mangledname^;
  3615. end;
  3616. function tprocdef.cplusplusmangledname : string;
  3617. function getcppparaname(p : tdef) : string;
  3618. const
  3619. ordtype2str : array[tbasetype] of string[2] = (
  3620. '',
  3621. 'Uc','Us','Ui','Us',
  3622. 'Sc','s','i','x',
  3623. 'b','b','b',
  3624. 'c','w','x');
  3625. var
  3626. s : string;
  3627. begin
  3628. case p.deftype of
  3629. orddef:
  3630. s:=ordtype2str[torddef(p).typ];
  3631. pointerdef:
  3632. s:='P'+getcppparaname(tpointerdef(p).pointertype.def);
  3633. else
  3634. internalerror(2103001);
  3635. end;
  3636. getcppparaname:=s;
  3637. end;
  3638. var
  3639. s,s2 : string;
  3640. param : TParaItem;
  3641. begin
  3642. s := procsym.realname;
  3643. if procsym.owner.symtabletype=objectsymtable then
  3644. begin
  3645. s2:=upper(tobjectdef(procsym.owner.defowner).typesym.realname);
  3646. case proctypeoption of
  3647. potype_destructor:
  3648. s:='_$_'+tostr(length(s2))+s2;
  3649. potype_constructor:
  3650. s:='___'+tostr(length(s2))+s2;
  3651. else
  3652. s:='_'+s+'__'+tostr(length(s2))+s2;
  3653. end;
  3654. end
  3655. else s:=s+'__';
  3656. s:=s+'F';
  3657. { concat modifiers }
  3658. { !!!!! }
  3659. { now we handle the parameters }
  3660. param := TParaItem(Para.first);
  3661. if assigned(param) then
  3662. while assigned(param) do
  3663. begin
  3664. s2:=getcppparaname(param.paratype.def);
  3665. if param.paratyp in [vs_var,vs_out] then
  3666. s2:='R'+s2;
  3667. s:=s+s2;
  3668. param:=TParaItem(param.next);
  3669. end
  3670. else
  3671. s:=s+'v';
  3672. cplusplusmangledname:=s;
  3673. end;
  3674. procedure tprocdef.setmangledname(const s : string);
  3675. begin
  3676. stringdispose(_mangledname);
  3677. _mangledname:=stringdup(s);
  3678. has_mangledname:=true;
  3679. end;
  3680. {***************************************************************************
  3681. TPROCVARDEF
  3682. ***************************************************************************}
  3683. constructor tprocvardef.create(level:byte);
  3684. begin
  3685. inherited create(level);
  3686. deftype:=procvardef;
  3687. end;
  3688. constructor tprocvardef.ppuload(ppufile:tcompilerppufile);
  3689. begin
  3690. inherited ppuload(ppufile);
  3691. deftype:=procvardef;
  3692. { load para symtable }
  3693. parast:=tparasymtable.create(unknown_level);
  3694. tparasymtable(parast).ppuload(ppufile);
  3695. parast.defowner:=self;
  3696. end;
  3697. procedure tprocvardef.ppuwrite(ppufile:tcompilerppufile);
  3698. var
  3699. oldparasymtable,
  3700. oldlocalsymtable : tsymtable;
  3701. begin
  3702. oldparasymtable:=aktparasymtable;
  3703. oldlocalsymtable:=aktlocalsymtable;
  3704. aktparasymtable:=parast;
  3705. aktlocalsymtable:=nil;
  3706. { here we cannot get a real good value so just give something }
  3707. { plausible (PM) }
  3708. { a more secure way would be
  3709. to allways store in a temp }
  3710. if is_fpu(rettype.def) then
  3711. fpu_used:={2}maxfpuregs
  3712. else
  3713. fpu_used:=0;
  3714. inherited ppuwrite(ppufile);
  3715. { Write this entry }
  3716. ppufile.writeentry(ibprocvardef);
  3717. { Save the para symtable, this is taken from the interface }
  3718. tparasymtable(parast).ppuwrite(ppufile);
  3719. aktparasymtable:=oldparasymtable;
  3720. aktlocalsymtable:=oldlocalsymtable;
  3721. end;
  3722. procedure tprocvardef.deref;
  3723. var
  3724. oldparasymtable,
  3725. oldlocalsymtable : tsymtable;
  3726. begin
  3727. oldparasymtable:=aktparasymtable;
  3728. oldlocalsymtable:=aktlocalsymtable;
  3729. aktparasymtable:=parast;
  3730. aktlocalsymtable:=nil;
  3731. inherited deref;
  3732. aktparasymtable:=oldparasymtable;
  3733. aktlocalsymtable:=oldlocalsymtable;
  3734. end;
  3735. function tprocvardef.getsymtable(t:tgetsymtable):tsymtable;
  3736. begin
  3737. case t of
  3738. gs_para :
  3739. getsymtable:=parast;
  3740. else
  3741. getsymtable:=nil;
  3742. end;
  3743. end;
  3744. function tprocvardef.size : longint;
  3745. begin
  3746. if (po_methodpointer in procoptions) and
  3747. not(po_addressonly in procoptions) then
  3748. size:=2*POINTER_SIZE
  3749. else
  3750. size:=POINTER_SIZE;
  3751. end;
  3752. function tprocvardef.is_methodpointer:boolean;
  3753. begin
  3754. result:=(po_methodpointer in procoptions);
  3755. end;
  3756. function tprocvardef.is_addressonly:boolean;
  3757. begin
  3758. result:=not(po_methodpointer in procoptions) or
  3759. (po_addressonly in procoptions);
  3760. end;
  3761. {$ifdef GDB}
  3762. function tprocvardef.stabstring : pchar;
  3763. var
  3764. nss : pchar;
  3765. { i : longint; }
  3766. begin
  3767. { i := maxparacount; }
  3768. getmem(nss,1024);
  3769. { it is not a function but a function pointer !! (PM) }
  3770. strpcopy(nss,'*f'+tstoreddef(rettype.def).numberstring{+','+tostr(i)}+';');
  3771. { this confuses gdb !!
  3772. we should use 'F' instead of 'f' but
  3773. as we use c++ language mode
  3774. it does not like that either
  3775. Please do not remove this part
  3776. might be used once
  3777. gdb for pascal is ready PM }
  3778. (*
  3779. param := para1;
  3780. i := 0;
  3781. while assigned(param) do
  3782. begin
  3783. inc(i);
  3784. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  3785. {Here we have lost the parameter names !!}
  3786. pst := strpnew('p'+tostr(i)+':'+param^.paratype.def.numberstring+','+vartyp+';');
  3787. strcat(nss,pst);
  3788. strdispose(pst);
  3789. param := param^.next;
  3790. end; *)
  3791. {strpcopy(strend(nss),';');}
  3792. stabstring := strnew(nss);
  3793. freemem(nss,1024);
  3794. end;
  3795. procedure tprocvardef.concatstabto(asmlist : taasmoutput);
  3796. begin
  3797. if ( not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  3798. and (is_def_stab_written = not_written) then
  3799. inherited concatstabto(asmlist);
  3800. is_def_stab_written:=written;
  3801. end;
  3802. {$endif GDB}
  3803. procedure tprocvardef.write_rtti_data(rt:trttitype);
  3804. var
  3805. pdc : TParaItem;
  3806. methodkind, paraspec : byte;
  3807. begin
  3808. if po_methodpointer in procoptions then
  3809. begin
  3810. { write method id and name }
  3811. rttiList.concat(Tai_const.Create_8bit(tkmethod));
  3812. write_rtti_name;
  3813. { write kind of method (can only be function or procedure)}
  3814. if rettype.def = voidtype.def then
  3815. methodkind := mkProcedure
  3816. else
  3817. methodkind := mkFunction;
  3818. rttiList.concat(Tai_const.Create_8bit(methodkind));
  3819. { get # of parameters }
  3820. rttiList.concat(Tai_const.Create_8bit(maxparacount));
  3821. { write parameter info. The parameters must be written in reverse order
  3822. if this method uses right to left parameter pushing! }
  3823. if proccalloption in pushleftright_pocalls then
  3824. pdc:=TParaItem(Para.first)
  3825. else
  3826. pdc:=TParaItem(Para.last);
  3827. while assigned(pdc) do
  3828. begin
  3829. case pdc.paratyp of
  3830. vs_value: paraspec := 0;
  3831. vs_const: paraspec := pfConst;
  3832. vs_var : paraspec := pfVar;
  3833. vs_out : paraspec := pfOut;
  3834. end;
  3835. { write flags for current parameter }
  3836. rttiList.concat(Tai_const.Create_8bit(paraspec));
  3837. { write name of current parameter ### how can I get this??? (sg)}
  3838. rttiList.concat(Tai_const.Create_8bit(0));
  3839. { write name of type of current parameter }
  3840. tstoreddef(pdc.paratype.def).write_rtti_name;
  3841. if proccalloption in pushleftright_pocalls then
  3842. pdc:=TParaItem(pdc.next)
  3843. else
  3844. pdc:=TParaItem(pdc.previous);
  3845. end;
  3846. { write name of result type }
  3847. tstoreddef(rettype.def).write_rtti_name;
  3848. end;
  3849. end;
  3850. function tprocvardef.is_publishable : boolean;
  3851. begin
  3852. is_publishable:=(po_methodpointer in procoptions);
  3853. end;
  3854. function tprocvardef.gettypename : string;
  3855. var
  3856. s: string;
  3857. showhidden : boolean;
  3858. begin
  3859. {$ifdef EXTDEBUG}
  3860. showhidden:=true;
  3861. {$else EXTDEBUG}
  3862. showhidden:=false;
  3863. {$endif EXTDEBUG}
  3864. s:='<';
  3865. if po_classmethod in procoptions then
  3866. s := s+'class method type of'
  3867. else
  3868. if po_addressonly in procoptions then
  3869. s := s+'address of'
  3870. else
  3871. s := s+'procedure variable type of';
  3872. if assigned(rettype.def) and
  3873. (rettype.def<>voidtype.def) then
  3874. s:=s+' function'+typename_paras(showhidden)+':'+rettype.def.gettypename
  3875. else
  3876. s:=s+' procedure'+typename_paras(showhidden);
  3877. if po_methodpointer in procoptions then
  3878. s := s+' of object';
  3879. gettypename := s+';'+ProcCallOptionStr[proccalloption]+'>';
  3880. end;
  3881. {***************************************************************************
  3882. TOBJECTDEF
  3883. ***************************************************************************}
  3884. constructor tobjectdef.create(ot : tobjectdeftype;const n : string;c : tobjectdef);
  3885. begin
  3886. inherited create;
  3887. objecttype:=ot;
  3888. deftype:=objectdef;
  3889. objectoptions:=[];
  3890. childof:=nil;
  3891. symtable:=tobjectsymtable.create(n);
  3892. { create space for vmt !! }
  3893. vmt_offset:=0;
  3894. symtable.defowner:=self;
  3895. { recordalign -1 means C record packing, that starts
  3896. with an alignment of 1 }
  3897. if aktalignment.recordalignmax=-1 then
  3898. tobjectsymtable(symtable).dataalignment:=1
  3899. else
  3900. tobjectsymtable(symtable).dataalignment:=aktalignment.recordalignmax;
  3901. lastvtableindex:=0;
  3902. set_parent(c);
  3903. objname:=stringdup(upper(n));
  3904. objrealname:=stringdup(n);
  3905. if objecttype in [odt_interfacecorba,odt_interfacecom] then
  3906. prepareguid;
  3907. { setup implemented interfaces }
  3908. if objecttype in [odt_class,odt_interfacecorba] then
  3909. implementedinterfaces:=timplementedinterfaces.create
  3910. else
  3911. implementedinterfaces:=nil;
  3912. {$ifdef GDB}
  3913. writing_class_record_stab:=false;
  3914. {$endif GDB}
  3915. end;
  3916. constructor tobjectdef.ppuload(ppufile:tcompilerppufile);
  3917. var
  3918. i,implintfcount: longint;
  3919. d : tderef;
  3920. begin
  3921. inherited ppuloaddef(ppufile);
  3922. deftype:=objectdef;
  3923. objecttype:=tobjectdeftype(ppufile.getbyte);
  3924. savesize:=ppufile.getlongint;
  3925. vmt_offset:=ppufile.getlongint;
  3926. objrealname:=stringdup(ppufile.getstring);
  3927. objname:=stringdup(upper(objrealname^));
  3928. ppufile.getderef(childofderef);
  3929. ppufile.getsmallset(objectoptions);
  3930. { load guid }
  3931. iidstr:=nil;
  3932. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3933. begin
  3934. new(iidguid);
  3935. ppufile.getguid(iidguid^);
  3936. iidstr:=stringdup(ppufile.getstring);
  3937. lastvtableindex:=ppufile.getlongint;
  3938. end;
  3939. { load implemented interfaces }
  3940. if objecttype in [odt_class,odt_interfacecorba] then
  3941. begin
  3942. implementedinterfaces:=timplementedinterfaces.create;
  3943. implintfcount:=ppufile.getlongint;
  3944. for i:=1 to implintfcount do
  3945. begin
  3946. ppufile.getderef(d);
  3947. implementedinterfaces.addintf_deref(d);
  3948. implementedinterfaces.ioffsets(i)^:=ppufile.getlongint;
  3949. end;
  3950. end
  3951. else
  3952. implementedinterfaces:=nil;
  3953. symtable:=tobjectsymtable.create(objrealname^);
  3954. tobjectsymtable(symtable).datasize:=ppufile.getlongint;
  3955. tobjectsymtable(symtable).dataalignment:=ppufile.getbyte;
  3956. tobjectsymtable(symtable).ppuload(ppufile);
  3957. symtable.defowner:=self;
  3958. { handles the predefined class tobject }
  3959. { the last TOBJECT which is loaded gets }
  3960. { it ! }
  3961. if (childof=nil) and
  3962. (objecttype=odt_class) and
  3963. (objname^='TOBJECT') then
  3964. class_tobject:=self;
  3965. if (childof=nil) and
  3966. (objecttype=odt_interfacecom) and
  3967. (objname^='IUNKNOWN') then
  3968. interface_iunknown:=self;
  3969. {$ifdef GDB}
  3970. writing_class_record_stab:=false;
  3971. {$endif GDB}
  3972. end;
  3973. destructor tobjectdef.destroy;
  3974. begin
  3975. if assigned(symtable) then
  3976. symtable.free;
  3977. stringdispose(objname);
  3978. stringdispose(objrealname);
  3979. if assigned(iidstr) then
  3980. stringdispose(iidstr);
  3981. if assigned(implementedinterfaces) then
  3982. implementedinterfaces.free;
  3983. if assigned(iidguid) then
  3984. dispose(iidguid);
  3985. inherited destroy;
  3986. end;
  3987. procedure tobjectdef.ppuwrite(ppufile:tcompilerppufile);
  3988. var
  3989. implintfcount : longint;
  3990. i : longint;
  3991. begin
  3992. inherited ppuwritedef(ppufile);
  3993. ppufile.putbyte(byte(objecttype));
  3994. ppufile.putlongint(size);
  3995. ppufile.putlongint(vmt_offset);
  3996. ppufile.putstring(objrealname^);
  3997. ppufile.putderef(childof,childofderef);
  3998. ppufile.putsmallset(objectoptions);
  3999. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  4000. begin
  4001. ppufile.putguid(iidguid^);
  4002. ppufile.putstring(iidstr^);
  4003. ppufile.putlongint(lastvtableindex);
  4004. end;
  4005. if objecttype in [odt_class,odt_interfacecorba] then
  4006. begin
  4007. implintfcount:=implementedinterfaces.count;
  4008. ppufile.putlongint(implintfcount);
  4009. for i:=1 to implintfcount do
  4010. begin
  4011. ppufile.putderef(implementedinterfaces.interfaces(i),implementedinterfaces.interfacesderef(i));
  4012. ppufile.putlongint(implementedinterfaces.ioffsets(i)^);
  4013. end;
  4014. end;
  4015. ppufile.putlongint(tobjectsymtable(symtable).datasize);
  4016. ppufile.putbyte(tobjectsymtable(symtable).dataalignment);
  4017. ppufile.writeentry(ibobjectdef);
  4018. tobjectsymtable(symtable).ppuwrite(ppufile);
  4019. end;
  4020. function tobjectdef.gettypename:string;
  4021. begin
  4022. gettypename:=typename;
  4023. end;
  4024. procedure tobjectdef.deref;
  4025. var
  4026. oldrecsyms : tsymtable;
  4027. begin
  4028. inherited deref;
  4029. childof:=tobjectdef(childofderef.resolve);
  4030. oldrecsyms:=aktrecordsymtable;
  4031. aktrecordsymtable:=symtable;
  4032. tstoredsymtable(symtable).deref;
  4033. aktrecordsymtable:=oldrecsyms;
  4034. if objecttype in [odt_class,odt_interfacecorba] then
  4035. implementedinterfaces.deref;
  4036. end;
  4037. function tobjectdef.getparentdef:tdef;
  4038. begin
  4039. result:=childof;
  4040. end;
  4041. procedure tobjectdef.prepareguid;
  4042. begin
  4043. { set up guid }
  4044. if not assigned(iidguid) then
  4045. begin
  4046. new(iidguid);
  4047. fillchar(iidguid^,sizeof(iidguid^),0); { default null guid }
  4048. end;
  4049. { setup iidstring }
  4050. if not assigned(iidstr) then
  4051. iidstr:=stringdup(''); { default is empty string }
  4052. end;
  4053. procedure tobjectdef.set_parent( c : tobjectdef);
  4054. begin
  4055. { nothing to do if the parent was not forward !}
  4056. if assigned(childof) then
  4057. exit;
  4058. childof:=c;
  4059. { some options are inherited !! }
  4060. if assigned(c) then
  4061. begin
  4062. { only important for classes }
  4063. lastvtableindex:=c.lastvtableindex;
  4064. objectoptions:=objectoptions+(c.objectoptions*
  4065. [oo_has_virtual,oo_has_private,oo_has_protected,
  4066. oo_has_constructor,oo_has_destructor]);
  4067. if not (objecttype in [odt_interfacecom,odt_interfacecorba]) then
  4068. begin
  4069. { add the data of the anchestor class }
  4070. inc(tobjectsymtable(symtable).datasize,tobjectsymtable(c.symtable).datasize);
  4071. if (oo_has_vmt in objectoptions) and
  4072. (oo_has_vmt in c.objectoptions) then
  4073. dec(tobjectsymtable(symtable).datasize,POINTER_SIZE);
  4074. { if parent has a vmt field then
  4075. the offset is the same for the child PM }
  4076. if (oo_has_vmt in c.objectoptions) or is_class(self) then
  4077. begin
  4078. vmt_offset:=c.vmt_offset;
  4079. include(objectoptions,oo_has_vmt);
  4080. end;
  4081. end;
  4082. end;
  4083. savesize := tobjectsymtable(symtable).datasize;
  4084. end;
  4085. procedure tobjectdef.insertvmt;
  4086. begin
  4087. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  4088. exit;
  4089. if (oo_has_vmt in objectoptions) then
  4090. internalerror(12345)
  4091. else
  4092. begin
  4093. tobjectsymtable(symtable).datasize:=align(tobjectsymtable(symtable).datasize,
  4094. tobjectsymtable(symtable).dataalignment);
  4095. vmt_offset:=tobjectsymtable(symtable).datasize;
  4096. inc(tobjectsymtable(symtable).datasize,POINTER_SIZE);
  4097. include(objectoptions,oo_has_vmt);
  4098. end;
  4099. end;
  4100. procedure tobjectdef.check_forwards;
  4101. begin
  4102. if not(objecttype in [odt_interfacecom,odt_interfacecorba]) then
  4103. tstoredsymtable(symtable).check_forwards;
  4104. if (oo_is_forward in objectoptions) then
  4105. begin
  4106. { ok, in future, the forward can be resolved }
  4107. Message1(sym_e_class_forward_not_resolved,objrealname^);
  4108. exclude(objectoptions,oo_is_forward);
  4109. end;
  4110. end;
  4111. { true, if self inherits from d (or if they are equal) }
  4112. function tobjectdef.is_related(d : tobjectdef) : boolean;
  4113. var
  4114. hp : tobjectdef;
  4115. begin
  4116. hp:=self;
  4117. while assigned(hp) do
  4118. begin
  4119. if hp=d then
  4120. begin
  4121. is_related:=true;
  4122. exit;
  4123. end;
  4124. hp:=hp.childof;
  4125. end;
  4126. is_related:=false;
  4127. end;
  4128. (* procedure tobjectdef._searchdestructor(sym : tnamedindexitem;arg:pointer);
  4129. var
  4130. p : pprocdeflist;
  4131. begin
  4132. { if we found already a destructor, then we exit }
  4133. if assigned(sd) then
  4134. exit;
  4135. if tsym(sym).typ=procsym then
  4136. begin
  4137. p:=tprocsym(sym).defs;
  4138. while assigned(p) do
  4139. begin
  4140. if p^.def.proctypeoption=potype_destructor then
  4141. begin
  4142. sd:=p^.def;
  4143. exit;
  4144. end;
  4145. p:=p^.next;
  4146. end;
  4147. end;
  4148. end;*)
  4149. procedure _searchdestructor(sym:Tnamedindexitem;sd:pointer);
  4150. begin
  4151. { if we found already a destructor, then we exit }
  4152. if (ppointer(sd)^=nil) and
  4153. (Tsym(sym).typ=procsym) then
  4154. ppointer(sd)^:=Tprocsym(sym).search_procdef_bytype(potype_destructor);
  4155. end;
  4156. function tobjectdef.searchdestructor : tprocdef;
  4157. var
  4158. o : tobjectdef;
  4159. sd : tprocdef;
  4160. begin
  4161. searchdestructor:=nil;
  4162. o:=self;
  4163. sd:=nil;
  4164. while assigned(o) do
  4165. begin
  4166. o.symtable.foreach_static({$ifdef FPCPROCVAR}@{$endif}_searchdestructor,@sd);
  4167. if assigned(sd) then
  4168. begin
  4169. searchdestructor:=sd;
  4170. exit;
  4171. end;
  4172. o:=o.childof;
  4173. end;
  4174. end;
  4175. function tobjectdef.size : longint;
  4176. begin
  4177. if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba] then
  4178. result:=POINTER_SIZE
  4179. else
  4180. result:=tobjectsymtable(symtable).datasize;
  4181. end;
  4182. function tobjectdef.alignment:longint;
  4183. begin
  4184. alignment:=tobjectsymtable(symtable).dataalignment;
  4185. end;
  4186. function tobjectdef.vmtmethodoffset(index:longint):longint;
  4187. begin
  4188. { for offset of methods for classes, see rtl/inc/objpash.inc }
  4189. case objecttype of
  4190. odt_class:
  4191. vmtmethodoffset:=(index+12)*POINTER_SIZE;
  4192. odt_interfacecom,odt_interfacecorba:
  4193. vmtmethodoffset:=index*POINTER_SIZE;
  4194. else
  4195. {$ifdef WITHDMT}
  4196. vmtmethodoffset:=(index+4)*POINTER_SIZE;
  4197. {$else WITHDMT}
  4198. vmtmethodoffset:=(index+3)*POINTER_SIZE;
  4199. {$endif WITHDMT}
  4200. end;
  4201. end;
  4202. function tobjectdef.vmt_mangledname : string;
  4203. begin
  4204. if not(oo_has_vmt in objectoptions) then
  4205. Message1(parser_n_object_has_no_vmt,objrealname^);
  4206. vmt_mangledname:=mangledname_prefix('VMT',owner)+objname^;
  4207. end;
  4208. function tobjectdef.rtti_name : string;
  4209. begin
  4210. rtti_name:=mangledname_prefix('RTTI',owner)+objname^;
  4211. end;
  4212. {$ifdef GDB}
  4213. procedure tobjectdef.addprocname(p :tnamedindexitem;arg:pointer);
  4214. var virtualind,argnames : string;
  4215. news, newrec : pchar;
  4216. pd,ipd : tprocdef;
  4217. lindex : longint;
  4218. para : TParaItem;
  4219. arglength : byte;
  4220. sp : char;
  4221. begin
  4222. If tsym(p).typ = procsym then
  4223. begin
  4224. pd := tprocsym(p).first_procdef;
  4225. { this will be used for full implementation of object stabs
  4226. not yet done }
  4227. ipd := Tprocsym(p).last_procdef;
  4228. if (po_virtualmethod in pd.procoptions) then
  4229. begin
  4230. lindex := pd.extnumber;
  4231. {doesnt seem to be necessary
  4232. lindex := lindex or $80000000;}
  4233. virtualind := '*'+tostr(lindex)+';'+ipd._class.classnumberstring+';'
  4234. end
  4235. else
  4236. virtualind := '.';
  4237. { used by gdbpas to recognize constructor and destructors }
  4238. if (pd.proctypeoption=potype_constructor) then
  4239. argnames:='__ct__'
  4240. else if (pd.proctypeoption=potype_destructor) then
  4241. argnames:='__dt__'
  4242. else
  4243. argnames := '';
  4244. { arguments are not listed here }
  4245. {we don't need another definition}
  4246. para := TParaItem(pd.Para.first);
  4247. while assigned(para) do
  4248. begin
  4249. if Para.paratype.def.deftype = formaldef then
  4250. begin
  4251. if Para.paratyp=vs_var then
  4252. argnames := argnames+'3var'
  4253. else if Para.paratyp=vs_const then
  4254. argnames:=argnames+'5const'
  4255. else if Para.paratyp=vs_out then
  4256. argnames:=argnames+'3out';
  4257. end
  4258. else
  4259. begin
  4260. { if the arg definition is like (v: ^byte;..
  4261. there is no sym attached to data !!! }
  4262. if assigned(Para.paratype.def.typesym) then
  4263. begin
  4264. arglength := length(Para.paratype.def.typesym.name);
  4265. argnames := argnames + tostr(arglength)+Para.paratype.def.typesym.name;
  4266. end
  4267. else
  4268. begin
  4269. argnames:=argnames+'11unnamedtype';
  4270. end;
  4271. end;
  4272. para := TParaItem(Para.next);
  4273. end;
  4274. ipd.is_def_stab_written := written;
  4275. { here 2A must be changed for private and protected }
  4276. { 0 is private 1 protected and 2 public }
  4277. if (sp_private in tsym(p).symoptions) then sp:='0'
  4278. else if (sp_protected in tsym(p).symoptions) then sp:='1'
  4279. else sp:='2';
  4280. newrec := strpnew(p.name+'::'+ipd.numberstring
  4281. +'=##'+tstoreddef(pd.rettype.def).numberstring+';:'+argnames+';'+sp+'A'
  4282. +virtualind+';');
  4283. { get spare place for a string at the end }
  4284. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  4285. begin
  4286. getmem(news,stabrecsize+memsizeinc);
  4287. strcopy(news,stabrecstring);
  4288. freemem(stabrecstring,stabrecsize);
  4289. stabrecsize:=stabrecsize+memsizeinc;
  4290. stabrecstring:=news;
  4291. end;
  4292. strcat(StabRecstring,newrec);
  4293. {freemem(newrec,memsizeinc); }
  4294. strdispose(newrec);
  4295. {This should be used for case !!
  4296. RecOffset := RecOffset + pd.size;}
  4297. end;
  4298. end;
  4299. function tobjectdef.stabstring : pchar;
  4300. var anc : tobjectdef;
  4301. oldrec : pchar;
  4302. oldrecsize,oldrecoffset : longint;
  4303. str_end : string;
  4304. begin
  4305. if not (objecttype=odt_class) or writing_class_record_stab then
  4306. begin
  4307. oldrec := stabrecstring;
  4308. oldrecsize:=stabrecsize;
  4309. stabrecsize:=memsizeinc;
  4310. GetMem(stabrecstring,stabrecsize);
  4311. strpcopy(stabRecString,'s'+tostr(tobjectsymtable(symtable).datasize));
  4312. if assigned(childof) then
  4313. begin
  4314. {only one ancestor not virtual, public, at base offset 0 }
  4315. { !1 , 0 2 0 , }
  4316. strpcopy(strend(stabrecstring),'!1,020,'+childof.classnumberstring+';');
  4317. end;
  4318. {virtual table to implement yet}
  4319. OldRecOffset:=RecOffset;
  4320. RecOffset := 0;
  4321. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addname,nil);
  4322. RecOffset:=OldRecOffset;
  4323. if (oo_has_vmt in objectoptions) then
  4324. if not assigned(childof) or not(oo_has_vmt in childof.objectoptions) then
  4325. begin
  4326. strpcopy(strend(stabrecstring),'$vf'+classnumberstring+':'+typeglobalnumber('vtblarray')
  4327. +','+tostr(vmt_offset*8)+';');
  4328. end;
  4329. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addprocname,nil);
  4330. if (oo_has_vmt in objectoptions) then
  4331. begin
  4332. anc := self;
  4333. while assigned(anc.childof) and (oo_has_vmt in anc.childof.objectoptions) do
  4334. anc := anc.childof;
  4335. { just in case anc = self }
  4336. str_end:=';~%'+anc.classnumberstring+';';
  4337. end
  4338. else
  4339. str_end:=';';
  4340. strpcopy(strend(stabrecstring),str_end);
  4341. stabstring := strnew(StabRecString);
  4342. freemem(stabrecstring,stabrecsize);
  4343. stabrecstring := oldrec;
  4344. stabrecsize:=oldrecsize;
  4345. end
  4346. else
  4347. begin
  4348. stabstring:=strpnew('*'+classnumberstring);
  4349. end;
  4350. end;
  4351. procedure tobjectdef.set_globalnb;
  4352. begin
  4353. globalnb:=PglobalTypeCount^;
  4354. inc(PglobalTypeCount^);
  4355. { classes need two type numbers, the globalnb is set to the ptr }
  4356. if objecttype=odt_class then
  4357. begin
  4358. globalnb:=PGlobalTypeCount^;
  4359. inc(PglobalTypeCount^);
  4360. end;
  4361. end;
  4362. function tobjectdef.classnumberstring : string;
  4363. begin
  4364. { write stabs again if needed }
  4365. numberstring;
  4366. if objecttype=odt_class then
  4367. begin
  4368. dec(globalnb);
  4369. classnumberstring:=numberstring;
  4370. inc(globalnb);
  4371. end
  4372. else
  4373. classnumberstring:=numberstring;
  4374. end;
  4375. function tobjectdef.allstabstring : pchar;
  4376. var stabchar : string[2];
  4377. ss,st : pchar;
  4378. sname : string;
  4379. sym_line_no : longint;
  4380. begin
  4381. ss := stabstring;
  4382. getmem(st,strlen(ss)+512);
  4383. stabchar := 't';
  4384. if deftype in tagtypes then
  4385. stabchar := 'Tt';
  4386. if assigned(typesym) then
  4387. begin
  4388. sname := typesym.name;
  4389. sym_line_no:=typesym.fileinfo.line;
  4390. end
  4391. else
  4392. begin
  4393. sname := ' ';
  4394. sym_line_no:=0;
  4395. end;
  4396. if writing_class_record_stab then
  4397. strpcopy(st,'"'+sname+':'+stabchar+classnumberstring+'=')
  4398. else
  4399. strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
  4400. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  4401. allstabstring := strnew(st);
  4402. freemem(st,strlen(ss)+512);
  4403. strdispose(ss);
  4404. end;
  4405. procedure tobjectdef.concatstabto(asmlist : taasmoutput);
  4406. var st : pstring;
  4407. begin
  4408. if objecttype<>odt_class then
  4409. begin
  4410. inherited concatstabto(asmlist);
  4411. exit;
  4412. end;
  4413. if ((typesym=nil) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  4414. (is_def_stab_written = not_written) then
  4415. begin
  4416. if globalnb=0 then
  4417. set_globalnb;
  4418. { Write the record class itself }
  4419. writing_class_record_stab:=true;
  4420. inherited concatstabto(asmlist);
  4421. writing_class_record_stab:=false;
  4422. { Write the invisible pointer class }
  4423. is_def_stab_written:=not_written;
  4424. if assigned(typesym) then
  4425. begin
  4426. st:=typesym.FName;
  4427. typesym.FName:=stringdup(' ');
  4428. end;
  4429. inherited concatstabto(asmlist);
  4430. if assigned(typesym) then
  4431. begin
  4432. stringdispose(typesym.FName);
  4433. typesym.FName:=st;
  4434. end;
  4435. end;
  4436. end;
  4437. {$endif GDB}
  4438. function tobjectdef.needs_inittable : boolean;
  4439. begin
  4440. case objecttype of
  4441. odt_class :
  4442. needs_inittable:=false;
  4443. odt_interfacecom:
  4444. needs_inittable:=true;
  4445. odt_interfacecorba:
  4446. needs_inittable:=is_related(interface_iunknown);
  4447. odt_object:
  4448. needs_inittable:=tobjectsymtable(symtable).needs_init_final;
  4449. else
  4450. internalerror(200108267);
  4451. end;
  4452. end;
  4453. function tobjectdef.members_need_inittable : boolean;
  4454. begin
  4455. members_need_inittable:=tobjectsymtable(symtable).needs_init_final;
  4456. end;
  4457. procedure tobjectdef.count_published_properties(sym:tnamedindexitem;arg:pointer);
  4458. begin
  4459. if needs_prop_entry(tsym(sym)) and
  4460. (tsym(sym).typ<>varsym) then
  4461. inc(count);
  4462. end;
  4463. procedure tobjectdef.write_property_info(sym : tnamedindexitem;arg:pointer);
  4464. var
  4465. proctypesinfo : byte;
  4466. procedure writeproc(proc : tsymlist; shiftvalue : byte);
  4467. var
  4468. typvalue : byte;
  4469. hp : psymlistitem;
  4470. address : longint;
  4471. begin
  4472. if not(assigned(proc) and assigned(proc.firstsym)) then
  4473. begin
  4474. rttiList.concat(Tai_const.Create_32bit(1));
  4475. typvalue:=3;
  4476. end
  4477. else if proc.firstsym^.sym.typ=varsym then
  4478. begin
  4479. address:=0;
  4480. hp:=proc.firstsym;
  4481. while assigned(hp) do
  4482. begin
  4483. inc(address,tvarsym(hp^.sym).fieldoffset);
  4484. hp:=hp^.next;
  4485. end;
  4486. rttiList.concat(Tai_const.Create_32bit(address));
  4487. typvalue:=0;
  4488. end
  4489. else
  4490. begin
  4491. if not(po_virtualmethod in tprocdef(proc.def).procoptions) then
  4492. begin
  4493. rttiList.concat(Tai_const_symbol.Createname(tprocdef(proc.def).mangledname));
  4494. typvalue:=1;
  4495. end
  4496. else
  4497. begin
  4498. { virtual method, write vmt offset }
  4499. rttiList.concat(Tai_const.Create_32bit(
  4500. tprocdef(proc.def)._class.vmtmethodoffset(tprocdef(proc.def).extnumber)));
  4501. typvalue:=2;
  4502. end;
  4503. end;
  4504. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  4505. end;
  4506. begin
  4507. if needs_prop_entry(tsym(sym)) then
  4508. case tsym(sym).typ of
  4509. varsym:
  4510. begin
  4511. {$ifdef dummy}
  4512. if not(tvarsym(sym).vartype.def.deftype=objectdef) or
  4513. not(tobjectdef(tvarsym(sym).vartype.def).is_class) then
  4514. internalerror(1509992);
  4515. { access to implicit class property as field }
  4516. proctypesinfo:=(0 shl 0) or (0 shl 2) or (0 shl 4);
  4517. rttiList.concat(Tai_const_symbol.Createname(tvarsym(sym.vartype.def.get_rtti_label)));
  4518. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym.address)));
  4519. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym.address)));
  4520. { per default stored }
  4521. rttiList.concat(Tai_const.Create_32bit(1));
  4522. { index as well as ... }
  4523. rttiList.concat(Tai_const.Create_32bit(0));
  4524. { default value are zero }
  4525. rttiList.concat(Tai_const.Create_32bit(0));
  4526. rttiList.concat(Tai_const.Create_16bit(count));
  4527. inc(count);
  4528. rttiList.concat(Tai_const.Create_8bit(proctypesinfo));
  4529. rttiList.concat(Tai_const.Create_8bit(length(tvarsym(sym.realname))));
  4530. rttiList.concat(Tai_string.Create(tvarsym(sym.realname)));
  4531. {$endif dummy}
  4532. end;
  4533. propertysym:
  4534. begin
  4535. if ppo_indexed in tpropertysym(sym).propoptions then
  4536. proctypesinfo:=$40
  4537. else
  4538. proctypesinfo:=0;
  4539. rttiList.concat(Tai_const_symbol.Create(tstoreddef(tpropertysym(sym).proptype.def).get_rtti_label(fullrtti)));
  4540. writeproc(tpropertysym(sym).readaccess,0);
  4541. writeproc(tpropertysym(sym).writeaccess,2);
  4542. { isn't it stored ? }
  4543. if not(ppo_stored in tpropertysym(sym).propoptions) then
  4544. begin
  4545. rttiList.concat(Tai_const.Create_32bit(0));
  4546. proctypesinfo:=proctypesinfo or (3 shl 4);
  4547. end
  4548. else
  4549. writeproc(tpropertysym(sym).storedaccess,4);
  4550. rttiList.concat(Tai_const.Create_32bit(tpropertysym(sym).index));
  4551. rttiList.concat(Tai_const.Create_32bit(tpropertysym(sym).default));
  4552. rttiList.concat(Tai_const.Create_16bit(count));
  4553. inc(count);
  4554. rttiList.concat(Tai_const.Create_8bit(proctypesinfo));
  4555. rttiList.concat(Tai_const.Create_8bit(length(tpropertysym(sym).realname)));
  4556. rttiList.concat(Tai_string.Create(tpropertysym(sym).realname));
  4557. end;
  4558. else internalerror(1509992);
  4559. end;
  4560. end;
  4561. procedure tobjectdef.generate_published_child_rtti(sym : tnamedindexitem;arg:pointer);
  4562. begin
  4563. if needs_prop_entry(tsym(sym)) then
  4564. begin
  4565. case tsym(sym).typ of
  4566. propertysym:
  4567. tstoreddef(tpropertysym(sym).proptype.def).get_rtti_label(fullrtti);
  4568. varsym:
  4569. tstoreddef(tvarsym(sym).vartype.def).get_rtti_label(fullrtti);
  4570. else
  4571. internalerror(1509991);
  4572. end;
  4573. end;
  4574. end;
  4575. procedure tobjectdef.write_child_rtti_data(rt:trttitype);
  4576. begin
  4577. FRTTIType:=rt;
  4578. case rt of
  4579. initrtti :
  4580. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_field_rtti,nil);
  4581. fullrtti :
  4582. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_published_child_rtti,nil);
  4583. else
  4584. internalerror(200108301);
  4585. end;
  4586. end;
  4587. type
  4588. tclasslistitem = class(TLinkedListItem)
  4589. index : longint;
  4590. p : tobjectdef;
  4591. end;
  4592. var
  4593. classtablelist : tlinkedlist;
  4594. tablecount : longint;
  4595. function searchclasstablelist(p : tobjectdef) : tclasslistitem;
  4596. var
  4597. hp : tclasslistitem;
  4598. begin
  4599. hp:=tclasslistitem(classtablelist.first);
  4600. while assigned(hp) do
  4601. if hp.p=p then
  4602. begin
  4603. searchclasstablelist:=hp;
  4604. exit;
  4605. end
  4606. else
  4607. hp:=tclasslistitem(hp.next);
  4608. searchclasstablelist:=nil;
  4609. end;
  4610. procedure tobjectdef.count_published_fields(sym:tnamedindexitem;arg:pointer);
  4611. var
  4612. hp : tclasslistitem;
  4613. begin
  4614. if needs_prop_entry(tsym(sym)) and
  4615. (tsym(sym).typ=varsym) then
  4616. begin
  4617. if tvarsym(sym).vartype.def.deftype<>objectdef then
  4618. internalerror(0206001);
  4619. hp:=searchclasstablelist(tobjectdef(tvarsym(sym).vartype.def));
  4620. if not(assigned(hp)) then
  4621. begin
  4622. hp:=tclasslistitem.create;
  4623. hp.p:=tobjectdef(tvarsym(sym).vartype.def);
  4624. hp.index:=tablecount;
  4625. classtablelist.concat(hp);
  4626. inc(tablecount);
  4627. end;
  4628. inc(count);
  4629. end;
  4630. end;
  4631. procedure tobjectdef.writefields(sym:tnamedindexitem;arg:pointer);
  4632. var
  4633. hp : tclasslistitem;
  4634. begin
  4635. if needs_prop_entry(tsym(sym)) and
  4636. (tsym(sym).typ=varsym) then
  4637. begin
  4638. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym).fieldoffset));
  4639. hp:=searchclasstablelist(tobjectdef(tvarsym(sym).vartype.def));
  4640. if not(assigned(hp)) then
  4641. internalerror(0206002);
  4642. rttiList.concat(Tai_const.Create_16bit(hp.index));
  4643. rttiList.concat(Tai_const.Create_8bit(length(tvarsym(sym).realname)));
  4644. rttiList.concat(Tai_string.Create(tvarsym(sym).realname));
  4645. end;
  4646. end;
  4647. function tobjectdef.generate_field_table : tasmlabel;
  4648. var
  4649. fieldtable,
  4650. classtable : tasmlabel;
  4651. hp : tclasslistitem;
  4652. begin
  4653. classtablelist:=TLinkedList.Create;
  4654. objectlibrary.getdatalabel(fieldtable);
  4655. objectlibrary.getdatalabel(classtable);
  4656. count:=0;
  4657. tablecount:=0;
  4658. symtable.foreach({$ifdef FPC}@{$endif}count_published_fields,nil);
  4659. if (cs_create_smart in aktmoduleswitches) then
  4660. rttiList.concat(Tai_cut.Create);
  4661. rttilist.concat(tai_align.create(const_align(pointer_size)));
  4662. rttiList.concat(Tai_label.Create(fieldtable));
  4663. rttiList.concat(Tai_const.Create_16bit(count));
  4664. rttiList.concat(Tai_const_symbol.Create(classtable));
  4665. symtable.foreach({$ifdef FPC}@{$endif}writefields,nil);
  4666. { generate the class table }
  4667. rttilist.concat(tai_align.create(const_align(pointer_size)));
  4668. rttiList.concat(Tai_label.Create(classtable));
  4669. rttiList.concat(Tai_const.Create_16bit(tablecount));
  4670. hp:=tclasslistitem(classtablelist.first);
  4671. while assigned(hp) do
  4672. begin
  4673. rttiList.concat(Tai_const_symbol.Createname(tobjectdef(hp.p).vmt_mangledname));
  4674. hp:=tclasslistitem(hp.next);
  4675. end;
  4676. generate_field_table:=fieldtable;
  4677. classtablelist.free;
  4678. end;
  4679. function tobjectdef.next_free_name_index : longint;
  4680. var
  4681. i : longint;
  4682. begin
  4683. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4684. i:=childof.next_free_name_index
  4685. else
  4686. i:=0;
  4687. count:=0;
  4688. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties,nil);
  4689. next_free_name_index:=i+count;
  4690. end;
  4691. procedure tobjectdef.write_rtti_data(rt:trttitype);
  4692. begin
  4693. case objecttype of
  4694. odt_class:
  4695. rttiList.concat(Tai_const.Create_8bit(tkclass));
  4696. odt_object:
  4697. rttiList.concat(Tai_const.Create_8bit(tkobject));
  4698. odt_interfacecom:
  4699. rttiList.concat(Tai_const.Create_8bit(tkinterface));
  4700. odt_interfacecorba:
  4701. rttiList.concat(Tai_const.Create_8bit(tkinterfaceCorba));
  4702. else
  4703. exit;
  4704. end;
  4705. { generate the name }
  4706. rttiList.concat(Tai_const.Create_8bit(length(objrealname^)));
  4707. rttiList.concat(Tai_string.Create(objrealname^));
  4708. case rt of
  4709. initrtti :
  4710. begin
  4711. rttiList.concat(Tai_const.Create_32bit(size));
  4712. if objecttype in [odt_class,odt_object] then
  4713. begin
  4714. count:=0;
  4715. FRTTIType:=rt;
  4716. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_field_rtti,nil);
  4717. rttiList.concat(Tai_const.Create_32bit(count));
  4718. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti,nil);
  4719. end;
  4720. end;
  4721. fullrtti :
  4722. begin
  4723. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  4724. rttiList.concat(Tai_const.Create_32bit(0))
  4725. else
  4726. rttiList.concat(Tai_const_symbol.Createname(vmt_mangledname));
  4727. { write owner typeinfo }
  4728. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4729. rttiList.concat(Tai_const_symbol.Create(childof.get_rtti_label(fullrtti)))
  4730. else
  4731. rttiList.concat(Tai_const.Create_32bit(0));
  4732. { count total number of properties }
  4733. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4734. count:=childof.next_free_name_index
  4735. else
  4736. count:=0;
  4737. { write it }
  4738. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties,nil);
  4739. rttiList.concat(Tai_const.Create_16bit(count));
  4740. { write unit name }
  4741. rttiList.concat(Tai_const.Create_8bit(length(current_module.realmodulename^)));
  4742. rttiList.concat(Tai_string.Create(current_module.realmodulename^));
  4743. { write published properties count }
  4744. count:=0;
  4745. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties,nil);
  4746. rttiList.concat(Tai_const.Create_16bit(count));
  4747. { count is used to write nameindex }
  4748. { but we need an offset of the owner }
  4749. { to give each property an own slot }
  4750. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4751. count:=childof.next_free_name_index
  4752. else
  4753. count:=0;
  4754. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_property_info,nil);
  4755. end;
  4756. end;
  4757. end;
  4758. function tobjectdef.is_publishable : boolean;
  4759. begin
  4760. is_publishable:=objecttype in [odt_class,odt_interfacecom,odt_interfacecorba];
  4761. end;
  4762. {****************************************************************************
  4763. TIMPLEMENTEDINTERFACES
  4764. ****************************************************************************}
  4765. type
  4766. tnamemap = class(TNamedIndexItem)
  4767. newname: pstring;
  4768. constructor create(const aname, anewname: string);
  4769. destructor destroy; override;
  4770. end;
  4771. constructor tnamemap.create(const aname, anewname: string);
  4772. begin
  4773. inherited createname(name);
  4774. newname:=stringdup(anewname);
  4775. end;
  4776. destructor tnamemap.destroy;
  4777. begin
  4778. stringdispose(newname);
  4779. inherited destroy;
  4780. end;
  4781. type
  4782. tprocdefstore = class(TNamedIndexItem)
  4783. procdef: tprocdef;
  4784. constructor create(aprocdef: tprocdef);
  4785. end;
  4786. constructor tprocdefstore.create(aprocdef: tprocdef);
  4787. begin
  4788. inherited create;
  4789. procdef:=aprocdef;
  4790. end;
  4791. type
  4792. timplintfentry = class(TNamedIndexItem)
  4793. intf: tobjectdef;
  4794. intfderef : tderef;
  4795. ioffs: longint;
  4796. namemappings: tdictionary;
  4797. procdefs: TIndexArray;
  4798. constructor create(aintf: tobjectdef);
  4799. constructor create_deref(const d:tderef);
  4800. destructor destroy; override;
  4801. end;
  4802. constructor timplintfentry.create(aintf: tobjectdef);
  4803. begin
  4804. inherited create;
  4805. intf:=aintf;
  4806. ioffs:=-1;
  4807. namemappings:=nil;
  4808. procdefs:=nil;
  4809. end;
  4810. constructor timplintfentry.create_deref(const d:tderef);
  4811. begin
  4812. inherited create;
  4813. intf:=nil;
  4814. intfderef:=d;
  4815. ioffs:=-1;
  4816. namemappings:=nil;
  4817. procdefs:=nil;
  4818. end;
  4819. destructor timplintfentry.destroy;
  4820. begin
  4821. if assigned(namemappings) then
  4822. namemappings.free;
  4823. if assigned(procdefs) then
  4824. procdefs.free;
  4825. inherited destroy;
  4826. end;
  4827. constructor timplementedinterfaces.create;
  4828. begin
  4829. finterfaces:=tindexarray.create(1);
  4830. end;
  4831. destructor timplementedinterfaces.destroy;
  4832. begin
  4833. finterfaces.destroy;
  4834. end;
  4835. function timplementedinterfaces.count: longint;
  4836. begin
  4837. count:=finterfaces.count;
  4838. end;
  4839. procedure timplementedinterfaces.checkindex(intfindex: longint);
  4840. begin
  4841. if (intfindex<1) or (intfindex>count) then
  4842. InternalError(200006123);
  4843. end;
  4844. function timplementedinterfaces.interfaces(intfindex: longint): tobjectdef;
  4845. begin
  4846. checkindex(intfindex);
  4847. interfaces:=timplintfentry(finterfaces.search(intfindex)).intf;
  4848. end;
  4849. function timplementedinterfaces.interfacesderef(intfindex: longint): tderef;
  4850. begin
  4851. checkindex(intfindex);
  4852. interfacesderef:=timplintfentry(finterfaces.search(intfindex)).intfderef;
  4853. end;
  4854. function timplementedinterfaces.ioffsets(intfindex: longint): plongint;
  4855. begin
  4856. checkindex(intfindex);
  4857. ioffsets:=@timplintfentry(finterfaces.search(intfindex)).ioffs;
  4858. end;
  4859. function timplementedinterfaces.searchintf(def: tdef): longint;
  4860. var
  4861. i: longint;
  4862. begin
  4863. i:=1;
  4864. while (i<=count) and (tdef(interfaces(i))<>def) do inc(i);
  4865. if i<=count then
  4866. searchintf:=i
  4867. else
  4868. searchintf:=-1;
  4869. end;
  4870. procedure timplementedinterfaces.deref;
  4871. var
  4872. i: longint;
  4873. begin
  4874. for i:=1 to count do
  4875. with timplintfentry(finterfaces.search(i)) do
  4876. intf:=tobjectdef(intfderef.resolve);
  4877. end;
  4878. procedure timplementedinterfaces.addintf_deref(const d:tderef);
  4879. begin
  4880. finterfaces.insert(timplintfentry.create_deref(d));
  4881. end;
  4882. procedure timplementedinterfaces.addintf(def: tdef);
  4883. begin
  4884. if not assigned(def) or (searchintf(def)<>-1) or (def.deftype<>objectdef) or
  4885. not (tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba]) then
  4886. internalerror(200006124);
  4887. finterfaces.insert(timplintfentry.create(tobjectdef(def)));
  4888. end;
  4889. procedure timplementedinterfaces.clearmappings;
  4890. var
  4891. i: longint;
  4892. begin
  4893. for i:=1 to count do
  4894. with timplintfentry(finterfaces.search(i)) do
  4895. begin
  4896. if assigned(namemappings) then
  4897. namemappings.free;
  4898. namemappings:=nil;
  4899. end;
  4900. end;
  4901. procedure timplementedinterfaces.addmappings(intfindex: longint; const name, newname: string);
  4902. begin
  4903. checkindex(intfindex);
  4904. with timplintfentry(finterfaces.search(intfindex)) do
  4905. begin
  4906. if not assigned(namemappings) then
  4907. namemappings:=tdictionary.create;
  4908. namemappings.insert(tnamemap.create(name,newname));
  4909. end;
  4910. end;
  4911. function timplementedinterfaces.getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
  4912. begin
  4913. checkindex(intfindex);
  4914. if not assigned(nextexist) then
  4915. with timplintfentry(finterfaces.search(intfindex)) do
  4916. begin
  4917. if assigned(namemappings) then
  4918. nextexist:=namemappings.search(name)
  4919. else
  4920. nextexist:=nil;
  4921. end;
  4922. if assigned(nextexist) then
  4923. begin
  4924. getmappings:=tnamemap(nextexist).newname^;
  4925. nextexist:=tnamemap(nextexist).listnext;
  4926. end
  4927. else
  4928. getmappings:='';
  4929. end;
  4930. procedure timplementedinterfaces.clearimplprocs;
  4931. var
  4932. i: longint;
  4933. begin
  4934. for i:=1 to count do
  4935. with timplintfentry(finterfaces.search(i)) do
  4936. begin
  4937. if assigned(procdefs) then
  4938. procdefs.free;
  4939. procdefs:=nil;
  4940. end;
  4941. end;
  4942. procedure timplementedinterfaces.addimplproc(intfindex: longint; procdef: tprocdef);
  4943. begin
  4944. checkindex(intfindex);
  4945. with timplintfentry(finterfaces.search(intfindex)) do
  4946. begin
  4947. if not assigned(procdefs) then
  4948. procdefs:=tindexarray.create(4);
  4949. procdefs.insert(tprocdefstore.create(procdef));
  4950. end;
  4951. end;
  4952. function timplementedinterfaces.implproccount(intfindex: longint): longint;
  4953. begin
  4954. checkindex(intfindex);
  4955. with timplintfentry(finterfaces.search(intfindex)) do
  4956. if assigned(procdefs) then
  4957. implproccount:=procdefs.count
  4958. else
  4959. implproccount:=0;
  4960. end;
  4961. function timplementedinterfaces.implprocs(intfindex: longint; procindex: longint): tprocdef;
  4962. begin
  4963. checkindex(intfindex);
  4964. with timplintfentry(finterfaces.search(intfindex)) do
  4965. if assigned(procdefs) then
  4966. implprocs:=tprocdefstore(procdefs.search(procindex)).procdef
  4967. else
  4968. internalerror(200006131);
  4969. end;
  4970. function timplementedinterfaces.isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
  4971. var
  4972. possible: boolean;
  4973. i: longint;
  4974. iiep1: TIndexArray;
  4975. iiep2: TIndexArray;
  4976. begin
  4977. checkindex(intfindex);
  4978. checkindex(remainindex);
  4979. iiep1:=timplintfentry(finterfaces.search(intfindex)).procdefs;
  4980. iiep2:=timplintfentry(finterfaces.search(remainindex)).procdefs;
  4981. if not assigned(iiep1) then { empty interface is mergeable :-) }
  4982. begin
  4983. possible:=true;
  4984. weight:=0;
  4985. end
  4986. else
  4987. begin
  4988. possible:=assigned(iiep2) and (iiep1.count<=iiep2.count);
  4989. i:=1;
  4990. while (possible) and (i<=iiep1.count) do
  4991. begin
  4992. possible:=
  4993. (tprocdefstore(iiep1.search(i)).procdef=tprocdefstore(iiep2.search(i)).procdef);
  4994. inc(i);
  4995. end;
  4996. if possible then
  4997. weight:=iiep1.count;
  4998. end;
  4999. isimplmergepossible:=possible;
  5000. end;
  5001. {****************************************************************************
  5002. TFORWARDDEF
  5003. ****************************************************************************}
  5004. constructor tforwarddef.create(const s:string;const pos : tfileposinfo);
  5005. var
  5006. oldregisterdef : boolean;
  5007. begin
  5008. { never register the forwarddefs, they are disposed at the
  5009. end of the type declaration block }
  5010. oldregisterdef:=registerdef;
  5011. registerdef:=false;
  5012. inherited create;
  5013. registerdef:=oldregisterdef;
  5014. deftype:=forwarddef;
  5015. tosymname:=stringdup(s);
  5016. forwardpos:=pos;
  5017. end;
  5018. function tforwarddef.gettypename:string;
  5019. begin
  5020. gettypename:='unresolved forward to '+tosymname^;
  5021. end;
  5022. destructor tforwarddef.destroy;
  5023. begin
  5024. if assigned(tosymname) then
  5025. stringdispose(tosymname);
  5026. inherited destroy;
  5027. end;
  5028. {****************************************************************************
  5029. TERRORDEF
  5030. ****************************************************************************}
  5031. constructor terrordef.create;
  5032. begin
  5033. inherited create;
  5034. deftype:=errordef;
  5035. end;
  5036. {$ifdef GDB}
  5037. function terrordef.stabstring : pchar;
  5038. begin
  5039. stabstring:=strpnew('error'+numberstring);
  5040. end;
  5041. procedure terrordef.concatstabto(asmlist : taasmoutput);
  5042. begin
  5043. { No internal error needed, an normal error is already
  5044. thrown }
  5045. end;
  5046. {$endif GDB}
  5047. function terrordef.gettypename:string;
  5048. begin
  5049. gettypename:='<erroneous type>';
  5050. end;
  5051. function terrordef.getmangledparaname:string;
  5052. begin
  5053. getmangledparaname:='error';
  5054. end;
  5055. {****************************************************************************
  5056. GDB Helpers
  5057. ****************************************************************************}
  5058. {$ifdef GDB}
  5059. function typeglobalnumber(const s : string) : string;
  5060. var st : string;
  5061. symt : tsymtable;
  5062. srsym : tsym;
  5063. srsymtable : tsymtable;
  5064. old_make_ref : boolean;
  5065. begin
  5066. old_make_ref:=make_ref;
  5067. make_ref:=false;
  5068. typeglobalnumber := '0';
  5069. srsym := nil;
  5070. if pos('.',s) > 0 then
  5071. begin
  5072. st := copy(s,1,pos('.',s)-1);
  5073. searchsym(st,srsym,srsymtable);
  5074. st := copy(s,pos('.',s)+1,255);
  5075. if assigned(srsym) then
  5076. begin
  5077. if srsym.typ = unitsym then
  5078. begin
  5079. symt := tunitsym(srsym).unitsymtable;
  5080. srsym := tsym(symt.search(st));
  5081. end else srsym := nil;
  5082. end;
  5083. end else st := s;
  5084. if srsym = nil then
  5085. searchsym(st,srsym,srsymtable);
  5086. if (srsym=nil) or
  5087. (srsym.typ<>typesym) then
  5088. begin
  5089. Message(type_e_type_id_expected);
  5090. exit;
  5091. end;
  5092. typeglobalnumber := tstoreddef(ttypesym(srsym).restype.def).numberstring;
  5093. make_ref:=old_make_ref;
  5094. end;
  5095. {$endif GDB}
  5096. {****************************************************************************
  5097. Definition Helpers
  5098. ****************************************************************************}
  5099. procedure reset_global_defs;
  5100. var
  5101. def : tstoreddef;
  5102. {$ifdef debug}
  5103. prevdef : tstoreddef;
  5104. {$endif debug}
  5105. begin
  5106. {$ifdef debug}
  5107. prevdef:=nil;
  5108. {$endif debug}
  5109. {$ifdef GDB}
  5110. pglobaltypecount:=@globaltypecount;
  5111. {$endif GDB}
  5112. def:=firstglobaldef;
  5113. while assigned(def) do
  5114. begin
  5115. {$ifdef GDB}
  5116. if assigned(def.typesym) then
  5117. ttypesym(def.typesym).isusedinstab:=false;
  5118. def.is_def_stab_written:=not_written;
  5119. {$endif GDB}
  5120. if assigned(def.rttitablesym) then
  5121. trttisym(def.rttitablesym).lab := nil;
  5122. if assigned(def.inittablesym) then
  5123. trttisym(def.inittablesym).lab := nil;
  5124. def.localrttilab[initrtti]:=nil;
  5125. def.localrttilab[fullrtti]:=nil;
  5126. {$ifdef debug}
  5127. prevdef:=def;
  5128. {$endif debug}
  5129. def:=def.nextglobal;
  5130. end;
  5131. end;
  5132. function is_interfacecom(def: tdef): boolean;
  5133. begin
  5134. is_interfacecom:=
  5135. assigned(def) and
  5136. (def.deftype=objectdef) and
  5137. (tobjectdef(def).objecttype=odt_interfacecom);
  5138. end;
  5139. function is_interfacecorba(def: tdef): boolean;
  5140. begin
  5141. is_interfacecorba:=
  5142. assigned(def) and
  5143. (def.deftype=objectdef) and
  5144. (tobjectdef(def).objecttype=odt_interfacecorba);
  5145. end;
  5146. function is_interface(def: tdef): boolean;
  5147. begin
  5148. is_interface:=
  5149. assigned(def) and
  5150. (def.deftype=objectdef) and
  5151. (tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba]);
  5152. end;
  5153. function is_class(def: tdef): boolean;
  5154. begin
  5155. is_class:=
  5156. assigned(def) and
  5157. (def.deftype=objectdef) and
  5158. (tobjectdef(def).objecttype=odt_class);
  5159. end;
  5160. function is_object(def: tdef): boolean;
  5161. begin
  5162. is_object:=
  5163. assigned(def) and
  5164. (def.deftype=objectdef) and
  5165. (tobjectdef(def).objecttype=odt_object);
  5166. end;
  5167. function is_cppclass(def: tdef): boolean;
  5168. begin
  5169. is_cppclass:=
  5170. assigned(def) and
  5171. (def.deftype=objectdef) and
  5172. (tobjectdef(def).objecttype=odt_cppclass);
  5173. end;
  5174. function is_class_or_interface(def: tdef): boolean;
  5175. begin
  5176. is_class_or_interface:=
  5177. assigned(def) and
  5178. (def.deftype=objectdef) and
  5179. (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba]);
  5180. end;
  5181. end.
  5182. {
  5183. $Log$
  5184. Revision 1.170 2003-10-03 22:00:33 peter
  5185. * parameter alignment fixes
  5186. Revision 1.169 2003/10/02 21:19:42 peter
  5187. * protected visibility fixes
  5188. Revision 1.168 2003/10/01 20:34:49 peter
  5189. * procinfo unit contains tprocinfo
  5190. * cginfo renamed to cgbase
  5191. * moved cgmessage to verbose
  5192. * fixed ppc and sparc compiles
  5193. Revision 1.167 2003/10/01 16:49:05 florian
  5194. * para items are now reversed for pascal calling conventions
  5195. Revision 1.166 2003/10/01 15:32:58 florian
  5196. * fixed FullProcName to handle constructors, destructors and operators correctly
  5197. Revision 1.165 2003/10/01 15:00:02 peter
  5198. * don't write parast,localst debug info for externals
  5199. Revision 1.164 2003/09/23 21:03:35 peter
  5200. * connect parasym to paraitem
  5201. Revision 1.163 2003/09/23 17:56:06 peter
  5202. * locals and paras are allocated in the code generation
  5203. * tvarsym.localloc contains the location of para/local when
  5204. generating code for the current procedure
  5205. Revision 1.162 2003/09/07 22:09:35 peter
  5206. * preparations for different default calling conventions
  5207. * various RA fixes
  5208. Revision 1.161 2003/09/06 22:27:09 florian
  5209. * fixed web bug 2669
  5210. * cosmetic fix in printnode
  5211. * tobjectdef.gettypename implemented
  5212. Revision 1.160 2003/09/03 15:55:01 peter
  5213. * NEWRA branch merged
  5214. Revision 1.159 2003/09/03 11:18:37 florian
  5215. * fixed arm concatcopy
  5216. + arm support in the common compiler sources added
  5217. * moved some generic cg code around
  5218. + tfputype added
  5219. * ...
  5220. Revision 1.158.2.2 2003/08/29 17:28:59 peter
  5221. * next batch of updates
  5222. Revision 1.158.2.1 2003/08/27 19:55:54 peter
  5223. * first tregister patch
  5224. Revision 1.158 2003/08/11 21:18:20 peter
  5225. * start of sparc support for newra
  5226. Revision 1.157 2003/07/08 15:20:56 peter
  5227. * don't allow add/assignments for formaldef
  5228. * formaldef size changed to 0
  5229. Revision 1.156 2003/07/06 21:50:33 jonas
  5230. * fixed ppc compilation problems and changed VOLATILE_REGISTERS for x86
  5231. so that it doesn't include ebp and esp anymore
  5232. Revision 1.155 2003/07/06 15:31:21 daniel
  5233. * Fixed register allocator. *Lots* of fixes.
  5234. Revision 1.154 2003/07/02 22:18:04 peter
  5235. * paraloc splitted in callerparaloc,calleeparaloc
  5236. * sparc calling convention updates
  5237. Revision 1.153 2003/06/25 18:31:23 peter
  5238. * sym,def resolving partly rewritten to support also parent objects
  5239. not directly available through the uses clause
  5240. Revision 1.152 2003/06/17 16:34:44 jonas
  5241. * lots of newra fixes (need getfuncretparaloc implementation for i386)!
  5242. * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it
  5243. processor dependent
  5244. Revision 1.151 2003/06/08 11:41:21 peter
  5245. * set parast.next to the owner of the procdef
  5246. Revision 1.150 2003/06/07 20:26:32 peter
  5247. * re-resolving added instead of reloading from ppu
  5248. * tderef object added to store deref info for resolving
  5249. Revision 1.149 2003/06/05 20:05:55 peter
  5250. * removed changesettype because that will change the definition
  5251. of the setdef forever and can result in a different between
  5252. original interface and current implementation definition
  5253. Revision 1.148 2003/06/03 13:01:59 daniel
  5254. * Register allocator finished
  5255. Revision 1.147 2003/06/02 22:55:28 florian
  5256. * classes and interfaces can be stored in integer registers
  5257. Revision 1.146 2003/05/26 21:17:18 peter
  5258. * procinlinenode removed
  5259. * aktexit2label removed, fast exit removed
  5260. + tcallnode.inlined_pass_2 added
  5261. Revision 1.145 2003/05/25 11:34:17 peter
  5262. * methodpointer self pushing fixed
  5263. Revision 1.144 2003/05/15 18:58:53 peter
  5264. * removed selfpointer_offset, vmtpointer_offset
  5265. * tvarsym.adjusted_address
  5266. * address in localsymtable is now in the real direction
  5267. * removed some obsolete globals
  5268. Revision 1.143 2003/05/13 08:13:16 jonas
  5269. * patch from Peter for rtti symbols
  5270. Revision 1.142 2003/05/11 21:37:03 peter
  5271. * moved implicit exception frame from ncgutil to psub
  5272. * constructor/destructor helpers moved from cobj/ncgutil to psub
  5273. Revision 1.141 2003/05/09 17:47:03 peter
  5274. * self moved to hidden parameter
  5275. * removed hdisposen,hnewn,selfn
  5276. Revision 1.140 2003/05/05 14:53:16 peter
  5277. * vs_hidden replaced by is_hidden boolean
  5278. Revision 1.139 2003/05/01 07:59:43 florian
  5279. * introduced defaultordconsttype to decribe the default size of ordinal constants
  5280. on 64 bit CPUs it's equal to cs64bitdef while on 32 bit CPUs it's equal to s32bitdef
  5281. + added defines CPU32 and CPU64 for 32 bit and 64 bit CPUs
  5282. * int64s/qwords are allowed as for loop counter on 64 bit CPUs
  5283. Revision 1.138 2003/04/27 11:21:34 peter
  5284. * aktprocdef renamed to current_procdef
  5285. * procinfo renamed to current_procinfo
  5286. * procinfo will now be stored in current_module so it can be
  5287. cleaned up properly
  5288. * gen_main_procsym changed to create_main_proc and release_main_proc
  5289. to also generate a tprocinfo structure
  5290. * fixed unit implicit initfinal
  5291. Revision 1.137 2003/04/27 07:29:51 peter
  5292. * current_procdef cleanup, current_procdef is now always nil when parsing
  5293. a new procdef declaration
  5294. * aktprocsym removed
  5295. * lexlevel removed, use symtable.symtablelevel instead
  5296. * implicit init/final code uses the normal genentry/genexit
  5297. * funcret state checking updated for new funcret handling
  5298. Revision 1.136 2003/04/25 20:59:35 peter
  5299. * removed funcretn,funcretsym, function result is now in varsym
  5300. and aliases for result and function name are added using absolutesym
  5301. * vs_hidden parameter for funcret passed in parameter
  5302. * vs_hidden fixes
  5303. * writenode changed to printnode and released from extdebug
  5304. * -vp option added to generate a tree.log with the nodetree
  5305. * nicer printnode for statements, callnode
  5306. Revision 1.135 2003/04/23 20:16:04 peter
  5307. + added currency support based on int64
  5308. + is_64bit for use in cg units instead of is_64bitint
  5309. * removed cgmessage from n386add, replace with internalerrors
  5310. Revision 1.134 2003/04/23 12:35:34 florian
  5311. * fixed several issues with powerpc
  5312. + applied a patch from Jonas for nested function calls (PowerPC only)
  5313. * ...
  5314. Revision 1.133 2003/04/10 17:57:53 peter
  5315. * vs_hidden released
  5316. Revision 1.132 2003/03/18 16:25:50 peter
  5317. * no itnernalerror for errordef.concatstabto()
  5318. Revision 1.131 2003/03/17 16:54:41 peter
  5319. * support DefaultHandler and anonymous inheritance fixed
  5320. for message methods
  5321. Revision 1.130 2003/03/17 15:54:22 peter
  5322. * store symoptions also for procdef
  5323. * check symoptions (private,public) when calculating possible
  5324. overload candidates
  5325. Revision 1.129 2003/02/19 22:00:14 daniel
  5326. * Code generator converted to new register notation
  5327. - Horribily outdated todo.txt removed
  5328. Revision 1.128 2003/02/02 19:25:54 carl
  5329. * Several bugfixes for m68k target (register alloc., opcode emission)
  5330. + VIS target
  5331. + Generic add more complete (still not verified)
  5332. Revision 1.127 2003/01/21 14:36:44 pierre
  5333. * set sizes needs to be passes in bits not bytes to stabs info
  5334. Revision 1.126 2003/01/16 22:11:33 peter
  5335. * fixed tprocdef.is_addressonly
  5336. Revision 1.125 2003/01/15 01:44:33 peter
  5337. * merged methodpointer fixes from 1.0.x
  5338. Revision 1.124 2003/01/09 21:52:37 peter
  5339. * merged some verbosity options.
  5340. * V_LineInfo is a verbosity flag to include line info
  5341. Revision 1.123 2003/01/06 21:16:52 peter
  5342. * po_addressonly added to retrieve the address of a methodpointer
  5343. only, this is used for @tclass.method which has no self pointer
  5344. Revision 1.122 2003/01/05 15:54:15 florian
  5345. + added proper support of type = type <type>; for simple types
  5346. Revision 1.121 2003/01/05 13:36:53 florian
  5347. * x86-64 compiles
  5348. + very basic support for float128 type (x86-64 only)
  5349. Revision 1.120 2003/01/02 19:49:00 peter
  5350. * update self parameter only for methodpointer and methods
  5351. Revision 1.119 2002/12/29 18:25:59 peter
  5352. * tprocdef.gettypename implemented
  5353. Revision 1.118 2002/12/27 15:23:09 peter
  5354. * write class methods in fullname
  5355. Revision 1.117 2002/12/15 19:34:31 florian
  5356. + some front end stuff for vs_hidden added
  5357. Revision 1.116 2002/12/15 11:26:02 peter
  5358. * ignore vs_hidden parameters when choosing overloaded proc
  5359. Revision 1.115 2002/12/07 14:27:09 carl
  5360. * 3% memory optimization
  5361. * changed some types
  5362. + added type checking with different size for call node and for
  5363. parameters
  5364. Revision 1.114 2002/12/01 22:05:27 carl
  5365. * no more warnings for structures over 32K since this is
  5366. handled correctly in this version of the compiler.
  5367. Revision 1.113 2002/11/27 20:04:09 peter
  5368. * tvarsym.get_push_size replaced by paramanager.push_size
  5369. Revision 1.112 2002/11/25 21:05:53 carl
  5370. * several mistakes fixed in message files
  5371. Revision 1.111 2002/11/25 18:43:33 carl
  5372. - removed the invalid if <> checking (Delphi is strange on this)
  5373. + implemented abstract warning on instance creation of class with
  5374. abstract methods.
  5375. * some error message cleanups
  5376. Revision 1.110 2002/11/25 17:43:24 peter
  5377. * splitted defbase in defutil,symutil,defcmp
  5378. * merged isconvertable and is_equal into compare_defs(_ext)
  5379. * made operator search faster by walking the list only once
  5380. Revision 1.109 2002/11/23 22:50:06 carl
  5381. * some small speed optimizations
  5382. + added several new warnings/hints
  5383. Revision 1.108 2002/11/22 22:48:10 carl
  5384. * memory optimization with tconstsym (1.5%)
  5385. Revision 1.107 2002/11/19 16:21:29 pierre
  5386. * correct several stabs generation problems
  5387. Revision 1.106 2002/11/18 17:31:59 peter
  5388. * pass proccalloption to ret_in_xxx and push_xxx functions
  5389. Revision 1.105 2002/11/17 16:31:57 carl
  5390. * memory optimization (3-4%) : cleanup of tai fields,
  5391. cleanup of tdef and tsym fields.
  5392. * make it work for m68k
  5393. Revision 1.104 2002/11/16 19:53:18 carl
  5394. * avoid Range check errors
  5395. Revision 1.103 2002/11/15 16:29:09 peter
  5396. * fixed rtti for int64 (merged)
  5397. Revision 1.102 2002/11/15 01:58:54 peter
  5398. * merged changes from 1.0.7 up to 04-11
  5399. - -V option for generating bug report tracing
  5400. - more tracing for option parsing
  5401. - errors for cdecl and high()
  5402. - win32 import stabs
  5403. - win32 records<=8 are returned in eax:edx (turned off by default)
  5404. - heaptrc update
  5405. - more info for temp management in .s file with EXTDEBUG
  5406. Revision 1.101 2002/11/09 15:31:02 carl
  5407. + align RTTI tables
  5408. Revision 1.100 2002/10/19 15:09:25 peter
  5409. + tobjectdef.members_need_inittable that is used to generate only the
  5410. inittable when it is really used. This saves a lot of useless calls
  5411. to fpc_finalize when destroying classes
  5412. Revision 1.99 2002/10/07 21:30:27 peter
  5413. * removed obsolete rangecheck stuff
  5414. Revision 1.98 2002/10/05 15:14:26 peter
  5415. * getparamangeldname for errordef
  5416. Revision 1.97 2002/10/05 12:43:28 carl
  5417. * fixes for Delphi 6 compilation
  5418. (warning : Some features do not work under Delphi)
  5419. Revision 1.96 2002/09/27 21:13:29 carl
  5420. * low-highval always checked if limit ober 2GB is reached (to avoid overflow)
  5421. Revision 1.95 2002/09/16 09:31:10 florian
  5422. * fixed currency size
  5423. Revision 1.94 2002/09/09 17:34:15 peter
  5424. * tdicationary.replace added to replace and item in a dictionary. This
  5425. is only allowed for the same name
  5426. * varsyms are inserted in symtable before the types are parsed. This
  5427. fixes the long standing "var longint : longint" bug
  5428. - consume_idlist and idstringlist removed. The loops are inserted
  5429. at the callers place and uses the symtable for duplicate id checking
  5430. Revision 1.93 2002/09/07 15:25:07 peter
  5431. * old logs removed and tabs fixed
  5432. Revision 1.92 2002/09/05 19:29:42 peter
  5433. * memdebug enhancements
  5434. Revision 1.91 2002/08/25 19:25:20 peter
  5435. * sym.insert_in_data removed
  5436. * symtable.insertvardata/insertconstdata added
  5437. * removed insert_in_data call from symtable.insert, it needs to be
  5438. called separatly. This allows to deref the address calculation
  5439. * procedures now calculate the parast addresses after the procedure
  5440. directives are parsed. This fixes the cdecl parast problem
  5441. * push_addr_param has an extra argument that specifies if cdecl is used
  5442. or not
  5443. Revision 1.90 2002/08/18 20:06:25 peter
  5444. * inlining is now also allowed in interface
  5445. * renamed write/load to ppuwrite/ppuload
  5446. * tnode storing in ppu
  5447. * nld,ncon,nbas are already updated for storing in ppu
  5448. Revision 1.89 2002/08/11 15:28:00 florian
  5449. + support of explicit type case <any ordinal type>->pointer
  5450. (delphi mode only)
  5451. Revision 1.88 2002/08/11 14:32:28 peter
  5452. * renamed current_library to objectlibrary
  5453. Revision 1.87 2002/08/11 13:24:13 peter
  5454. * saving of asmsymbols in ppu supported
  5455. * asmsymbollist global is removed and moved into a new class
  5456. tasmlibrarydata that will hold the info of a .a file which
  5457. corresponds with a single module. Added librarydata to tmodule
  5458. to keep the library info stored for the module. In the future the
  5459. objectfiles will also be stored to the tasmlibrarydata class
  5460. * all getlabel/newasmsymbol and friends are moved to the new class
  5461. Revision 1.86 2002/08/09 07:33:03 florian
  5462. * a couple of interface related fixes
  5463. Revision 1.85 2002/07/23 09:51:24 daniel
  5464. * Tried to make Tprocsym.defs protected. I didn't succeed but the cleanups
  5465. are worth comitting.
  5466. Revision 1.84 2002/07/20 11:57:57 florian
  5467. * types.pas renamed to defbase.pas because D6 contains a types
  5468. unit so this would conflicts if D6 programms are compiled
  5469. + Willamette/SSE2 instructions to assembler added
  5470. Revision 1.83 2002/07/11 14:41:30 florian
  5471. * start of the new generic parameter handling
  5472. Revision 1.82 2002/07/07 09:52:32 florian
  5473. * powerpc target fixed, very simple units can be compiled
  5474. * some basic stuff for better callparanode handling, far from being finished
  5475. Revision 1.81 2002/07/01 18:46:26 peter
  5476. * internal linker
  5477. * reorganized aasm layer
  5478. Revision 1.80 2002/07/01 16:23:54 peter
  5479. * cg64 patch
  5480. * basics for currency
  5481. * asnode updates for class and interface (not finished)
  5482. Revision 1.79 2002/05/18 13:34:18 peter
  5483. * readded missing revisions
  5484. Revision 1.78 2002/05/16 19:46:44 carl
  5485. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  5486. + try to fix temp allocation (still in ifdef)
  5487. + generic constructor calls
  5488. + start of tassembler / tmodulebase class cleanup
  5489. Revision 1.76 2002/05/12 16:53:10 peter
  5490. * moved entry and exitcode to ncgutil and cgobj
  5491. * foreach gets extra argument for passing local data to the
  5492. iterator function
  5493. * -CR checks also class typecasts at runtime by changing them
  5494. into as
  5495. * fixed compiler to cycle with the -CR option
  5496. * fixed stabs with elf writer, finally the global variables can
  5497. be watched
  5498. * removed a lot of routines from cga unit and replaced them by
  5499. calls to cgobj
  5500. * u32bit-s32bit updates for and,or,xor nodes. When one element is
  5501. u32bit then the other is typecasted also to u32bit without giving
  5502. a rangecheck warning/error.
  5503. * fixed pascal calling method with reversing also the high tree in
  5504. the parast, detected by tcalcst3 test
  5505. Revision 1.75 2002/04/25 20:16:39 peter
  5506. * moved more routines from cga/n386util
  5507. Revision 1.74 2002/04/23 19:16:35 peter
  5508. * add pinline unit that inserts compiler supported functions using
  5509. one or more statements
  5510. * moved finalize and setlength from ninl to pinline
  5511. Revision 1.73 2002/04/21 19:02:05 peter
  5512. * removed newn and disposen nodes, the code is now directly
  5513. inlined from pexpr
  5514. * -an option that will write the secondpass nodes to the .s file, this
  5515. requires EXTDEBUG define to actually write the info
  5516. * fixed various internal errors and crashes due recent code changes
  5517. Revision 1.72 2002/04/20 21:32:25 carl
  5518. + generic FPC_CHECKPOINTER
  5519. + first parameter offset in stack now portable
  5520. * rename some constants
  5521. + move some cpu stuff to other units
  5522. - remove unused constents
  5523. * fix stacksize for some targets
  5524. * fix generic size problems which depend now on EXTEND_SIZE constant
  5525. }