symdef.pas 174 KB

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