symdef.pas 177 KB

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