symdef.pas 175 KB

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