symdef.pas 171 KB

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