symdef.pas 202 KB

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