symdef.pas 171 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657
  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,
  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. constructor tsetdef.create(const t:ttype;high : longint);
  2036. begin
  2037. inherited create;
  2038. deftype:=setdef;
  2039. elementtype:=t;
  2040. if high<32 then
  2041. begin
  2042. settype:=smallset;
  2043. {$ifdef testvarsets}
  2044. if aktsetalloc=0 THEN { $PACKSET Fixed?}
  2045. {$endif}
  2046. savesize:=Sizeof(longint)
  2047. {$ifdef testvarsets}
  2048. else {No, use $PACKSET VALUE for rounding}
  2049. savesize:=aktsetalloc*((high+aktsetalloc*8-1) DIV (aktsetalloc*8))
  2050. {$endif}
  2051. ;
  2052. end
  2053. else
  2054. if high<256 then
  2055. begin
  2056. settype:=normset;
  2057. savesize:=32;
  2058. end
  2059. else
  2060. {$ifdef testvarsets}
  2061. if high<$10000 then
  2062. begin
  2063. settype:=varset;
  2064. savesize:=4*((high+31) div 32);
  2065. end
  2066. else
  2067. {$endif testvarsets}
  2068. Message(sym_e_ill_type_decl_set);
  2069. end;
  2070. constructor tsetdef.load(ppufile:tcompilerppufile);
  2071. begin
  2072. inherited loaddef(ppufile);
  2073. deftype:=setdef;
  2074. ppufile.gettype(elementtype);
  2075. settype:=tsettype(ppufile.getbyte);
  2076. case settype of
  2077. normset : savesize:=32;
  2078. varset : savesize:=ppufile.getlongint;
  2079. smallset : savesize:=Sizeof(longint);
  2080. end;
  2081. end;
  2082. destructor tsetdef.destroy;
  2083. begin
  2084. inherited destroy;
  2085. end;
  2086. procedure tsetdef.write(ppufile:tcompilerppufile);
  2087. begin
  2088. inherited writedef(ppufile);
  2089. ppufile.puttype(elementtype);
  2090. ppufile.putbyte(byte(settype));
  2091. if settype=varset then
  2092. ppufile.putlongint(savesize);
  2093. ppufile.writeentry(ibsetdef);
  2094. end;
  2095. {$ifdef GDB}
  2096. function tsetdef.stabstring : pchar;
  2097. begin
  2098. { For small sets write a longint, which can at least be seen
  2099. in the current GDB's (PFV)
  2100. this is obsolete with GDBPAS !!
  2101. and anyhow creates problems with version 4.18!! PM
  2102. if settype=smallset then
  2103. stabstring := strpnew('r'+s32bittype^.numberstring+';0;0xffffffff;')
  2104. else }
  2105. stabstring := strpnew('S'+tstoreddef(elementtype.def).numberstring);
  2106. end;
  2107. procedure tsetdef.concatstabto(asmlist : taasmoutput);
  2108. begin
  2109. if ( not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  2110. (is_def_stab_written = not_written) then
  2111. begin
  2112. if assigned(elementtype.def) then
  2113. forcestabto(asmlist,elementtype.def);
  2114. inherited concatstabto(asmlist);
  2115. end;
  2116. end;
  2117. {$endif GDB}
  2118. procedure tsetdef.deref;
  2119. begin
  2120. inherited deref;
  2121. elementtype.resolve;
  2122. end;
  2123. procedure tsetdef.write_rtti_data;
  2124. begin
  2125. rttiList.concat(Tai_const.Create_8bit(tkSet));
  2126. write_rtti_name;
  2127. rttiList.concat(Tai_const.Create_8bit(otULong));
  2128. rttiList.concat(Tai_const_symbol.Createname(elementtype.def.get_rtti_label));
  2129. end;
  2130. procedure tsetdef.write_child_rtti_data;
  2131. begin
  2132. elementtype.def.get_rtti_label;
  2133. end;
  2134. function tsetdef.is_publishable : boolean;
  2135. begin
  2136. is_publishable:=settype=smallset;
  2137. end;
  2138. function tsetdef.gettypename : string;
  2139. begin
  2140. if assigned(elementtype.def) then
  2141. gettypename:='Set Of '+elementtype.def.typename
  2142. else
  2143. gettypename:='Empty Set';
  2144. end;
  2145. {***************************************************************************
  2146. TFORMALDEF
  2147. ***************************************************************************}
  2148. constructor tformaldef.create;
  2149. var
  2150. stregdef : boolean;
  2151. begin
  2152. stregdef:=registerdef;
  2153. registerdef:=false;
  2154. inherited create;
  2155. deftype:=formaldef;
  2156. registerdef:=stregdef;
  2157. { formaldef must be registered at unit level !! }
  2158. if registerdef and assigned(current_module) then
  2159. if assigned(current_module.localsymtable) then
  2160. tsymtable(current_module.localsymtable).registerdef(self)
  2161. else if assigned(current_module.globalsymtable) then
  2162. tsymtable(current_module.globalsymtable).registerdef(self);
  2163. savesize:=target_info.size_of_pointer;
  2164. end;
  2165. constructor tformaldef.load(ppufile:tcompilerppufile);
  2166. begin
  2167. inherited loaddef(ppufile);
  2168. deftype:=formaldef;
  2169. savesize:=target_info.size_of_pointer;
  2170. end;
  2171. procedure tformaldef.write(ppufile:tcompilerppufile);
  2172. begin
  2173. inherited writedef(ppufile);
  2174. ppufile.writeentry(ibformaldef);
  2175. end;
  2176. {$ifdef GDB}
  2177. function tformaldef.stabstring : pchar;
  2178. begin
  2179. stabstring := strpnew('formal'+numberstring+';');
  2180. end;
  2181. procedure tformaldef.concatstabto(asmlist : taasmoutput);
  2182. begin
  2183. { formaldef can't be stab'ed !}
  2184. end;
  2185. {$endif GDB}
  2186. function tformaldef.gettypename : string;
  2187. begin
  2188. gettypename:='Var';
  2189. end;
  2190. {***************************************************************************
  2191. TARRAYDEF
  2192. ***************************************************************************}
  2193. constructor tarraydef.create(l,h : longint;const t : ttype);
  2194. begin
  2195. inherited create;
  2196. deftype:=arraydef;
  2197. lowrange:=l;
  2198. highrange:=h;
  2199. rangetype:=t;
  2200. elementtype.reset;
  2201. IsVariant:=false;
  2202. IsConstructor:=false;
  2203. IsArrayOfConst:=false;
  2204. IsDynamicArray:=false;
  2205. rangenr:=0;
  2206. end;
  2207. constructor tarraydef.load(ppufile:tcompilerppufile);
  2208. begin
  2209. inherited loaddef(ppufile);
  2210. deftype:=arraydef;
  2211. { the addresses are calculated later }
  2212. ppufile.gettype(elementtype);
  2213. ppufile.gettype(rangetype);
  2214. lowrange:=ppufile.getlongint;
  2215. highrange:=ppufile.getlongint;
  2216. IsArrayOfConst:=boolean(ppufile.getbyte);
  2217. IsVariant:=false;
  2218. IsConstructor:=false;
  2219. IsDynamicArray:=false;
  2220. rangenr:=0;
  2221. end;
  2222. function tarraydef.getrangecheckstring : string;
  2223. begin
  2224. if (cs_create_smart in aktmoduleswitches) then
  2225. getrangecheckstring:='R_'+current_module.modulename^+tostr(rangenr)
  2226. else
  2227. getrangecheckstring:='R_'+tostr(rangenr);
  2228. end;
  2229. procedure tarraydef.genrangecheck;
  2230. begin
  2231. if rangenr=0 then
  2232. begin
  2233. { generates the data for range checking }
  2234. getlabelnr(rangenr);
  2235. if (cs_create_smart in aktmoduleswitches) then
  2236. dataSegment.concat(Tai_symbol.Createname_global(getrangecheckstring,8))
  2237. else
  2238. dataSegment.concat(Tai_symbol.Createname(getrangecheckstring,8));
  2239. if lowrange<=highrange then
  2240. begin
  2241. dataSegment.concat(Tai_const.Create_32bit(lowrange));
  2242. dataSegment.concat(Tai_const.Create_32bit(highrange));
  2243. end
  2244. { for big arrays we need two bounds }
  2245. else
  2246. begin
  2247. dataSegment.concat(Tai_const.Create_32bit(lowrange));
  2248. dataSegment.concat(Tai_const.Create_32bit($7fffffff));
  2249. dataSegment.concat(Tai_const.Create_32bit(longint($80000000)));
  2250. dataSegment.concat(Tai_const.Create_32bit(highrange));
  2251. end;
  2252. end;
  2253. end;
  2254. procedure tarraydef.deref;
  2255. begin
  2256. inherited deref;
  2257. elementtype.resolve;
  2258. rangetype.resolve;
  2259. end;
  2260. procedure tarraydef.write(ppufile:tcompilerppufile);
  2261. begin
  2262. inherited writedef(ppufile);
  2263. ppufile.puttype(elementtype);
  2264. ppufile.puttype(rangetype);
  2265. ppufile.putlongint(lowrange);
  2266. ppufile.putlongint(highrange);
  2267. ppufile.putbyte(byte(IsArrayOfConst));
  2268. ppufile.writeentry(ibarraydef);
  2269. end;
  2270. {$ifdef GDB}
  2271. function tarraydef.stabstring : pchar;
  2272. begin
  2273. stabstring := strpnew('ar'+tstoreddef(rangetype.def).numberstring+';'
  2274. +tostr(lowrange)+';'+tostr(highrange)+';'+tstoreddef(elementtype.def).numberstring);
  2275. end;
  2276. procedure tarraydef.concatstabto(asmlist : taasmoutput);
  2277. begin
  2278. if (not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2279. and (is_def_stab_written = not_written) then
  2280. begin
  2281. {when array are inserted they have no definition yet !!}
  2282. if assigned(elementtype.def) then
  2283. inherited concatstabto(asmlist);
  2284. end;
  2285. end;
  2286. {$endif GDB}
  2287. function tarraydef.elesize : longint;
  2288. begin
  2289. if ((lowrange=0) and
  2290. (highrange=-1) and
  2291. (not IsArrayOfConst) and
  2292. (not IsVariant) and
  2293. (not IsDynamicArray)) or
  2294. IsConstructor then
  2295. begin
  2296. { strings are stored by address only }
  2297. case elementtype.def.deftype of
  2298. stringdef :
  2299. elesize:=4;
  2300. else
  2301. elesize:=elementtype.def.size;
  2302. end;
  2303. end
  2304. else
  2305. elesize:=elementtype.def.size;
  2306. end;
  2307. function tarraydef.size : longint;
  2308. begin
  2309. if IsDynamicArray then
  2310. begin
  2311. size:=4;
  2312. exit;
  2313. end;
  2314. {Tarraydef.size may never be called for an open array!}
  2315. if highrange<lowrange then
  2316. internalerror(99080501);
  2317. If (elesize>0) and
  2318. (
  2319. (highrange-lowrange = $7fffffff) or
  2320. { () are needed around elesize-1 to avoid a possible
  2321. integer overflow for elesize=1 !! PM }
  2322. (($7fffffff div elesize + (elesize -1)) < (highrange - lowrange))
  2323. ) Then
  2324. Begin
  2325. Message(sym_e_segment_too_large);
  2326. size := 4
  2327. End
  2328. Else size:=(highrange-lowrange+1)*elesize;
  2329. end;
  2330. function tarraydef.alignment : longint;
  2331. begin
  2332. { alignment is the size of the elements }
  2333. if elementtype.def.deftype=recorddef then
  2334. alignment:=elementtype.def.alignment
  2335. else
  2336. alignment:=elesize;
  2337. end;
  2338. function tarraydef.needs_inittable : boolean;
  2339. begin
  2340. needs_inittable:=IsDynamicArray or elementtype.def.needs_inittable;
  2341. end;
  2342. procedure tarraydef.write_child_rtti_data;
  2343. begin
  2344. elementtype.def.get_rtti_label;
  2345. end;
  2346. procedure tarraydef.write_rtti_data;
  2347. begin
  2348. if IsDynamicArray then
  2349. rttiList.concat(Tai_const.Create_8bit(tkdynarray))
  2350. else
  2351. rttiList.concat(Tai_const.Create_8bit(tkarray));
  2352. write_rtti_name;
  2353. { size of elements }
  2354. rttiList.concat(Tai_const.Create_32bit(elesize));
  2355. { count of elements }
  2356. if not(IsDynamicArray) then
  2357. rttiList.concat(Tai_const.Create_32bit(highrange-lowrange+1));
  2358. { element type }
  2359. rttiList.concat(Tai_const_symbol.Createname(elementtype.def.get_rtti_label));
  2360. { variant type }
  2361. // !!!!!!!!!!!!!!!!
  2362. end;
  2363. function tarraydef.gettypename : string;
  2364. begin
  2365. if isarrayofconst or isConstructor then
  2366. begin
  2367. if isvariant or ((highrange=-1) and (lowrange=0)) then
  2368. gettypename:='Array Of Const'
  2369. else
  2370. gettypename:='Array Of '+elementtype.def.typename;
  2371. end
  2372. else if ((highrange=-1) and (lowrange=0)) or IsDynamicArray then
  2373. gettypename:='Array Of '+elementtype.def.typename
  2374. else
  2375. begin
  2376. if rangetype.def.deftype=enumdef then
  2377. gettypename:='Array['+rangetype.def.typename+'] Of '+elementtype.def.typename
  2378. else
  2379. gettypename:='Array['+tostr(lowrange)+'..'+
  2380. tostr(highrange)+'] Of '+elementtype.def.typename
  2381. end;
  2382. end;
  2383. {***************************************************************************
  2384. tabstractrecorddef
  2385. ***************************************************************************}
  2386. function tabstractrecorddef.getsymtable(t:tgetsymtable):tsymtable;
  2387. begin
  2388. if t=gs_record then
  2389. getsymtable:=symtable
  2390. else
  2391. getsymtable:=nil;
  2392. end;
  2393. {$ifdef GDB}
  2394. procedure tabstractrecorddef.addname(p : tnamedindexitem);
  2395. var
  2396. news, newrec : pchar;
  2397. spec : string[3];
  2398. varsize : longint;
  2399. begin
  2400. { static variables from objects are like global objects }
  2401. if (sp_static in tsym(p).symoptions) then
  2402. exit;
  2403. If tsym(p).typ = varsym then
  2404. begin
  2405. if (sp_protected in tsym(p).symoptions) then
  2406. spec:='/1'
  2407. else if (sp_private in tsym(p).symoptions) then
  2408. spec:='/0'
  2409. else
  2410. spec:='';
  2411. if not assigned(tvarsym(p).vartype.def) then
  2412. writeln(tvarsym(p).name);
  2413. { class fields are pointers PM, obsolete now PM }
  2414. {if (tvarsym(p).vartype.def.deftype=objectdef) and
  2415. tobjectdef(tvarsym(p).vartype.def).is_class then
  2416. spec:=spec+'*'; }
  2417. varsize:=tvarsym(p).vartype.def.size;
  2418. { open arrays made overflows !! }
  2419. if varsize>$fffffff then
  2420. varsize:=$fffffff;
  2421. newrec := strpnew(p.name+':'+spec+tstoreddef(tvarsym(p).vartype.def).numberstring
  2422. +','+tostr(tvarsym(p).address*8)+','
  2423. +tostr(varsize*8)+';');
  2424. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  2425. begin
  2426. getmem(news,stabrecsize+memsizeinc);
  2427. strcopy(news,stabrecstring);
  2428. freemem(stabrecstring,stabrecsize);
  2429. stabrecsize:=stabrecsize+memsizeinc;
  2430. stabrecstring:=news;
  2431. end;
  2432. strcat(StabRecstring,newrec);
  2433. strdispose(newrec);
  2434. {This should be used for case !!}
  2435. inc(RecOffset,tvarsym(p).vartype.def.size);
  2436. end;
  2437. end;
  2438. {$endif GDB}
  2439. procedure tabstractrecorddef.count_inittable_fields(sym : tnamedindexitem);
  2440. begin
  2441. if ((tsym(sym).typ=varsym) and
  2442. tvarsym(sym).vartype.def.needs_inittable) then
  2443. inc(count);
  2444. end;
  2445. procedure tabstractrecorddef.count_fields(sym : tnamedindexitem);
  2446. begin
  2447. inc(count);
  2448. end;
  2449. procedure tabstractrecorddef.write_field_inittable(sym : tnamedindexitem);
  2450. begin
  2451. if ((tsym(sym).typ=varsym) and
  2452. tvarsym(sym).vartype.def.needs_inittable) then
  2453. begin
  2454. rttiList.concat(Tai_const_symbol.Create(tstoreddef(tvarsym(sym).vartype.def).get_inittable_label));
  2455. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym).address));
  2456. end;
  2457. end;
  2458. procedure tabstractrecorddef.write_field_rtti(sym : tnamedindexitem);
  2459. begin
  2460. rttiList.concat(Tai_const_symbol.Createname(tvarsym(sym).vartype.def.get_rtti_label));
  2461. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym).address));
  2462. end;
  2463. procedure tabstractrecorddef.generate_child_inittable(sym:tnamedindexitem);
  2464. begin
  2465. if (tsym(sym).typ=varsym) and
  2466. tvarsym(sym).vartype.def.needs_inittable then
  2467. { force inittable generation }
  2468. tstoreddef(tvarsym(sym).vartype.def).get_inittable_label;
  2469. end;
  2470. procedure tabstractrecorddef.generate_child_rtti(sym : tnamedindexitem);
  2471. begin
  2472. tvarsym(sym).vartype.def.get_rtti_label;
  2473. end;
  2474. {***************************************************************************
  2475. trecorddef
  2476. ***************************************************************************}
  2477. constructor trecorddef.create(p : tsymtable);
  2478. begin
  2479. inherited create;
  2480. deftype:=recorddef;
  2481. symtable:=p;
  2482. symtable.defowner:=self;
  2483. { recordalign -1 means C record packing, that starts
  2484. with an alignment of 1 }
  2485. if aktalignment.recordalignmax=-1 then
  2486. symtable.dataalignment:=1
  2487. else
  2488. symtable.dataalignment:=aktalignment.recordalignmax;
  2489. end;
  2490. constructor trecorddef.load(ppufile:tcompilerppufile);
  2491. var
  2492. oldread_member : boolean;
  2493. begin
  2494. inherited loaddef(ppufile);
  2495. deftype:=recorddef;
  2496. savesize:=ppufile.getlongint;
  2497. oldread_member:=read_member;
  2498. read_member:=true;
  2499. symtable:=trecordsymtable.create;
  2500. trecordsymtable(symtable).load(ppufile);
  2501. read_member:=oldread_member;
  2502. symtable.defowner:=self;
  2503. end;
  2504. destructor trecorddef.destroy;
  2505. begin
  2506. if assigned(symtable) then
  2507. symtable.free;
  2508. inherited destroy;
  2509. end;
  2510. function trecorddef.needs_inittable : boolean;
  2511. begin
  2512. needs_inittable:=trecordsymtable(symtable).needs_init_final
  2513. end;
  2514. procedure trecorddef.deref;
  2515. var
  2516. oldrecsyms : tsymtable;
  2517. begin
  2518. inherited deref;
  2519. oldrecsyms:=aktrecordsymtable;
  2520. aktrecordsymtable:=symtable;
  2521. { now dereference the definitions }
  2522. tstoredsymtable(symtable).deref;
  2523. aktrecordsymtable:=oldrecsyms;
  2524. { assign TGUID? load only from system unit (unitid=1) }
  2525. if not(assigned(rec_tguid)) and
  2526. (upper(typename)='TGUID') and
  2527. assigned(owner) and
  2528. assigned(owner.name) and
  2529. (owner.name^='SYSTEM') then
  2530. rec_tguid:=self;
  2531. end;
  2532. procedure trecorddef.write(ppufile:tcompilerppufile);
  2533. var
  2534. oldread_member : boolean;
  2535. begin
  2536. oldread_member:=read_member;
  2537. read_member:=true;
  2538. inherited writedef(ppufile);
  2539. ppufile.putlongint(savesize);
  2540. ppufile.writeentry(ibrecorddef);
  2541. trecordsymtable(symtable).write(ppufile);
  2542. read_member:=oldread_member;
  2543. end;
  2544. function trecorddef.size:longint;
  2545. begin
  2546. size:=symtable.datasize;
  2547. end;
  2548. function trecorddef.alignment:longint;
  2549. var
  2550. l : longint;
  2551. hp : tvarsym;
  2552. begin
  2553. { also check the first symbol for it's size, because a
  2554. packed record has dataalignment of 1, but the first
  2555. sym could be a longint which should be aligned on 4 bytes,
  2556. this is compatible with C record packing (PFV) }
  2557. hp:=tvarsym(symtable.symindex.first);
  2558. if assigned(hp) then
  2559. begin
  2560. if hp.vartype.def.deftype in [recorddef,arraydef] then
  2561. l:=hp.vartype.def.alignment
  2562. else
  2563. l:=hp.vartype.def.size;
  2564. if l>symtable.dataalignment then
  2565. begin
  2566. if l>=4 then
  2567. alignment:=4
  2568. else
  2569. if l>=2 then
  2570. alignment:=2
  2571. else
  2572. alignment:=1;
  2573. end
  2574. else
  2575. alignment:=symtable.dataalignment;
  2576. end
  2577. else
  2578. alignment:=symtable.dataalignment;
  2579. end;
  2580. {$ifdef GDB}
  2581. function trecorddef.stabstring : pchar;
  2582. begin
  2583. GetMem(stabrecstring,memsizeinc);
  2584. stabrecsize:=memsizeinc;
  2585. strpcopy(stabRecString,'s'+tostr(size));
  2586. RecOffset := 0;
  2587. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addname);
  2588. strpcopy(strend(StabRecString),';');
  2589. stabstring := strnew(StabRecString);
  2590. Freemem(stabrecstring,stabrecsize);
  2591. end;
  2592. procedure trecorddef.concatstabto(asmlist : taasmoutput);
  2593. begin
  2594. if (not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  2595. (is_def_stab_written = not_written) then
  2596. inherited concatstabto(asmlist);
  2597. end;
  2598. {$endif GDB}
  2599. procedure trecorddef.write_child_rtti_data;
  2600. begin
  2601. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_child_rtti);
  2602. end;
  2603. procedure trecorddef.write_child_init_data;
  2604. begin
  2605. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_child_inittable);
  2606. end;
  2607. procedure trecorddef.write_rtti_data;
  2608. begin
  2609. rttiList.concat(Tai_const.Create_8bit(tkrecord));
  2610. write_rtti_name;
  2611. rttiList.concat(Tai_const.Create_32bit(size));
  2612. count:=0;
  2613. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_fields);
  2614. rttiList.concat(Tai_const.Create_32bit(count));
  2615. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_rtti);
  2616. end;
  2617. procedure trecorddef.write_init_data;
  2618. begin
  2619. rttiList.concat(Tai_const.Create_8bit(tkrecord));
  2620. write_rtti_name;
  2621. rttiList.concat(Tai_const.Create_32bit(size));
  2622. count:=0;
  2623. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_inittable_fields);
  2624. rttiList.concat(Tai_const.Create_32bit(count));
  2625. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_inittable);
  2626. end;
  2627. function trecorddef.gettypename : string;
  2628. begin
  2629. gettypename:='<record type>'
  2630. end;
  2631. {***************************************************************************
  2632. TABSTRACTPROCDEF
  2633. ***************************************************************************}
  2634. constructor tabstractprocdef.create;
  2635. begin
  2636. inherited create;
  2637. para:=TParaLinkedList.Create;
  2638. minparacount:=0;
  2639. maxparacount:=0;
  2640. fpu_used:=0;
  2641. proctypeoption:=potype_none;
  2642. proccalloptions:=[];
  2643. procoptions:=[];
  2644. rettype:=voidtype;
  2645. symtablelevel:=0;
  2646. savesize:=target_info.size_of_pointer;
  2647. end;
  2648. destructor tabstractprocdef.destroy;
  2649. begin
  2650. Para.Free;
  2651. inherited destroy;
  2652. end;
  2653. procedure tabstractprocdef.concatpara(const tt:ttype;vsp : tvarspez;defval:tsym);
  2654. var
  2655. hp : TParaItem;
  2656. begin
  2657. hp:=TParaItem.Create;
  2658. hp.paratyp:=vsp;
  2659. hp.paratype:=tt;
  2660. hp.register:=R_NO;
  2661. hp.defaultvalue:=defval;
  2662. Para.insert(hp);
  2663. if not assigned(defval) then
  2664. inc(minparacount);
  2665. inc(maxparacount);
  2666. end;
  2667. { all functions returning in FPU are
  2668. assume to use 2 FPU registers
  2669. until the function implementation
  2670. is processed PM }
  2671. procedure tabstractprocdef.test_if_fpu_result;
  2672. begin
  2673. if assigned(rettype.def) and
  2674. (rettype.def.deftype=floatdef) then
  2675. fpu_used:=2;
  2676. end;
  2677. procedure tabstractprocdef.deref;
  2678. var
  2679. hp : TParaItem;
  2680. begin
  2681. inherited deref;
  2682. rettype.resolve;
  2683. hp:=TParaItem(Para.first);
  2684. while assigned(hp) do
  2685. begin
  2686. hp.paratype.resolve;
  2687. resolvesym(tsym(hp.defaultvalue));
  2688. hp:=TParaItem(hp.next);
  2689. end;
  2690. end;
  2691. constructor tabstractprocdef.load(ppufile:tcompilerppufile);
  2692. var
  2693. hp : TParaItem;
  2694. count,i : word;
  2695. begin
  2696. inherited loaddef(ppufile);
  2697. Para:=TParaLinkedList.Create;
  2698. minparacount:=0;
  2699. maxparacount:=0;
  2700. ppufile.gettype(rettype);
  2701. fpu_used:=ppufile.getbyte;
  2702. proctypeoption:=tproctypeoption(ppufile.getlongint);
  2703. ppufile.getsmallset(proccalloptions);
  2704. ppufile.getsmallset(procoptions);
  2705. count:=ppufile.getword;
  2706. savesize:=target_info.size_of_pointer;
  2707. for i:=1 to count do
  2708. begin
  2709. hp:=TParaItem.Create;
  2710. hp.paratyp:=tvarspez(ppufile.getbyte);
  2711. { hp.register:=tregister(ppufile.getbyte); }
  2712. hp.register:=R_NO;
  2713. ppufile.gettype(hp.paratype);
  2714. hp.defaultvalue:=tsym(ppufile.getderef);
  2715. if not assigned(hp.defaultvalue) then
  2716. inc(minparacount);
  2717. inc(maxparacount);
  2718. Para.concat(hp);
  2719. end;
  2720. end;
  2721. procedure tabstractprocdef.write(ppufile:tcompilerppufile);
  2722. var
  2723. hp : TParaItem;
  2724. oldintfcrc : boolean;
  2725. begin
  2726. inherited writedef(ppufile);
  2727. ppufile.puttype(rettype);
  2728. oldintfcrc:=ppufile.do_interface_crc;
  2729. ppufile.do_interface_crc:=false;
  2730. ppufile.putbyte(fpu_used);
  2731. ppufile.putlongint(ord(proctypeoption));
  2732. ppufile.putsmallset(proccalloptions);
  2733. ppufile.putsmallset(procoptions);
  2734. ppufile.do_interface_crc:=oldintfcrc;
  2735. ppufile.putword(maxparacount);
  2736. hp:=TParaItem(Para.first);
  2737. while assigned(hp) do
  2738. begin
  2739. ppufile.putbyte(byte(hp.paratyp));
  2740. { ppufile.putbyte(byte(hp.register)); }
  2741. ppufile.puttype(hp.paratype);
  2742. ppufile.putderef(hp.defaultvalue);
  2743. hp:=TParaItem(hp.next);
  2744. end;
  2745. end;
  2746. function tabstractprocdef.para_size(alignsize:longint) : longint;
  2747. var
  2748. pdc : TParaItem;
  2749. l : longint;
  2750. begin
  2751. l:=0;
  2752. pdc:=TParaItem(Para.first);
  2753. while assigned(pdc) do
  2754. begin
  2755. case pdc.paratyp of
  2756. vs_out,
  2757. vs_var : inc(l,target_info.size_of_pointer);
  2758. vs_value,
  2759. vs_const : if push_addr_param(pdc.paratype.def) then
  2760. inc(l,target_info.size_of_pointer)
  2761. else
  2762. inc(l,pdc.paratype.def.size);
  2763. end;
  2764. l:=align(l,alignsize);
  2765. pdc:=TParaItem(pdc.next);
  2766. end;
  2767. para_size:=l;
  2768. end;
  2769. function tabstractprocdef.demangled_paras : string;
  2770. var
  2771. hs,s : string;
  2772. hp : TParaItem;
  2773. hpc : tconstsym;
  2774. begin
  2775. hp:=TParaItem(Para.last);
  2776. if not(assigned(hp)) then
  2777. begin
  2778. demangled_paras:='';
  2779. exit;
  2780. end;
  2781. s:='(';
  2782. while assigned(hp) do
  2783. begin
  2784. if assigned(hp.paratype.def.typesym) then
  2785. s:=s+hp.paratype.def.typesym.realname
  2786. else if hp.paratyp=vs_var then
  2787. s:=s+'var'
  2788. else if hp.paratyp=vs_const then
  2789. s:=s+'const'
  2790. else if hp.paratyp=vs_out then
  2791. s:=s+'out';
  2792. { default value }
  2793. if assigned(hp.defaultvalue) then
  2794. begin
  2795. hpc:=tconstsym(hp.defaultvalue);
  2796. hs:='';
  2797. case hpc.consttyp of
  2798. conststring,
  2799. constresourcestring :
  2800. hs:=strpas(pchar(tpointerord(hpc.value)));
  2801. constreal :
  2802. str(pbestreal(tpointerord(hpc.value))^,hs);
  2803. constord,
  2804. constpointer :
  2805. hs:=tostr(hpc.value);
  2806. constbool :
  2807. begin
  2808. if hpc.value<>0 then
  2809. hs:='TRUE'
  2810. else
  2811. hs:='FALSE';
  2812. end;
  2813. constnil :
  2814. hs:='nil';
  2815. constchar :
  2816. hs:=chr(hpc.value);
  2817. constset :
  2818. hs:='<set>';
  2819. end;
  2820. if hs<>'' then
  2821. s:=s+'="'+hs+'"';
  2822. end;
  2823. hp:=TParaItem(hp.previous);
  2824. if assigned(hp) then
  2825. s:=s+',';
  2826. end;
  2827. s:=s+')';
  2828. if (po_varargs in procoptions) then
  2829. s:=s+';VarArgs';
  2830. demangled_paras:=s;
  2831. end;
  2832. function tabstractprocdef.proccalloption2str : string;
  2833. type
  2834. tproccallopt=record
  2835. mask : tproccalloption;
  2836. str : string[30];
  2837. end;
  2838. const
  2839. proccallopts=13;
  2840. proccallopt : array[1..proccallopts] of tproccallopt=(
  2841. (mask:pocall_none; str:''),
  2842. (mask:pocall_clearstack; str:'ClearStack'),
  2843. (mask:pocall_leftright; str:'LeftRight'),
  2844. (mask:pocall_cdecl; str:'CDecl'),
  2845. (mask:pocall_register; str:'Register'),
  2846. (mask:pocall_stdcall; str:'StdCall'),
  2847. (mask:pocall_safecall; str:'SafeCall'),
  2848. (mask:pocall_palmossyscall;str:'PalmOSSysCall'),
  2849. (mask:pocall_system; str:'System'),
  2850. (mask:pocall_inline; str:'Inline'),
  2851. (mask:pocall_internproc; str:'InternProc'),
  2852. (mask:pocall_internconst; str:'InternConst'),
  2853. (mask:pocall_cppdecl; str:'CPPDecl')
  2854. );
  2855. var
  2856. s : string;
  2857. i : longint;
  2858. first : boolean;
  2859. begin
  2860. s:='';
  2861. first:=true;
  2862. for i:=1to proccallopts do
  2863. if (proccallopt[i].mask in proccalloptions) then
  2864. begin
  2865. if first then
  2866. first:=false
  2867. else
  2868. s:=s+';';
  2869. s:=s+proccallopt[i].str;
  2870. end;
  2871. proccalloption2str:=s;
  2872. end;
  2873. {$ifdef GDB}
  2874. function tabstractprocdef.stabstring : pchar;
  2875. begin
  2876. stabstring := strpnew('abstractproc'+numberstring+';');
  2877. end;
  2878. procedure tabstractprocdef.concatstabto(asmlist : taasmoutput);
  2879. begin
  2880. if (not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  2881. and (is_def_stab_written = not_written) then
  2882. begin
  2883. if assigned(rettype.def) then forcestabto(asmlist,rettype.def);
  2884. inherited concatstabto(asmlist);
  2885. end;
  2886. end;
  2887. {$endif GDB}
  2888. {***************************************************************************
  2889. TPROCDEF
  2890. ***************************************************************************}
  2891. constructor tprocdef.create;
  2892. begin
  2893. inherited create;
  2894. deftype:=procdef;
  2895. _mangledname:=nil;
  2896. nextoverloaded:=nil;
  2897. fileinfo:=aktfilepos;
  2898. extnumber:=-1;
  2899. aliasnames:=tstringlist.create;
  2900. localst:=tlocalsymtable.create;
  2901. parast:=tparasymtable.create;
  2902. localst.defowner:=self;
  2903. parast.defowner:=self;
  2904. { this is used by insert
  2905. to check same names in parast and localst }
  2906. localst.next:=parast;
  2907. defref:=nil;
  2908. crossref:=nil;
  2909. lastwritten:=nil;
  2910. refcount:=0;
  2911. if (cs_browser in aktmoduleswitches) and make_ref then
  2912. begin
  2913. defref:=tref.create(defref,@akttokenpos);
  2914. inc(refcount);
  2915. end;
  2916. lastref:=defref;
  2917. { first, we assume that all registers are used }
  2918. {$ifdef newcg}
  2919. usedregisters:=[firstreg..lastreg];
  2920. {$else newcg}
  2921. {$ifdef i386}
  2922. usedregisters:=$ff;
  2923. {$else}
  2924. usedregisters:=ALL_REGISTERS;
  2925. {$endif i386}
  2926. {$endif newcg}
  2927. forwarddef:=true;
  2928. interfacedef:=false;
  2929. hasforward:=false;
  2930. _class := nil;
  2931. code:=nil;
  2932. regvarinfo := nil;
  2933. count:=false;
  2934. is_used:=false;
  2935. end;
  2936. constructor tprocdef.load(ppufile:tcompilerppufile);
  2937. begin
  2938. inherited load(ppufile);
  2939. deftype:=procdef;
  2940. {$ifdef newcg}
  2941. readnormalset(usedregisters);
  2942. {$else newcg}
  2943. {$ifdef i386}
  2944. usedregisters:=ppufile.getbyte;
  2945. {$else}
  2946. readnormalset(usedregisters);
  2947. {$endif}
  2948. {$endif newcg}
  2949. _mangledname:=stringdup(ppufile.getstring);
  2950. extnumber:=ppufile.getlongint;
  2951. nextoverloaded:=tprocdef(ppufile.getderef);
  2952. _class := tobjectdef(ppufile.getderef);
  2953. ppufile.getposinfo(fileinfo);
  2954. if (cs_link_deffile in aktglobalswitches) and
  2955. (tf_need_export in target_info.flags) and
  2956. (po_exports in procoptions) then
  2957. deffile.AddExport(mangledname);
  2958. aliasnames:=tstringlist.create;
  2959. parast:=tparasymtable.create;
  2960. tparasymtable(parast).load(ppufile);
  2961. parast.defowner:=self;
  2962. localst:=nil;
  2963. {new(localst,loadas(localsymtable));
  2964. localst.defowner:=self;
  2965. parast.next:=localst;
  2966. localst.next:=owner;}
  2967. forwarddef:=false;
  2968. interfacedef:=false;
  2969. hasforward:=false;
  2970. code := nil;
  2971. regvarinfo := nil;
  2972. lastref:=nil;
  2973. lastwritten:=nil;
  2974. defref:=nil;
  2975. refcount:=0;
  2976. count:=true;
  2977. is_used:=false;
  2978. end;
  2979. destructor tprocdef.destroy;
  2980. begin
  2981. if assigned(defref) then
  2982. begin
  2983. defref.freechain;
  2984. defref.free;
  2985. end;
  2986. aliasnames.free;
  2987. if assigned(parast) then
  2988. parast.free;
  2989. if assigned(localst) and (localst.symtabletype<>staticsymtable) then
  2990. localst.free;
  2991. if (pocall_inline in proccalloptions) and assigned(code) then
  2992. tnode(code).free;
  2993. if assigned(regvarinfo) then
  2994. dispose(pregvarinfo(regvarinfo));
  2995. if (po_msgstr in procoptions) then
  2996. strdispose(messageinf.str);
  2997. if assigned(_mangledname) then
  2998. stringdispose(_mangledname);
  2999. inherited destroy;
  3000. end;
  3001. procedure tprocdef.write(ppufile:tcompilerppufile);
  3002. var
  3003. oldintfcrc : boolean;
  3004. begin
  3005. inherited write(ppufile);
  3006. oldintfcrc:=ppufile.do_interface_crc;
  3007. ppufile.do_interface_crc:=false;
  3008. { set all registers to used for simplified compilation PM }
  3009. if simplify_ppu then
  3010. begin
  3011. {$ifdef newcg}
  3012. usedregisters:=[firstreg..lastreg];
  3013. {$else newcg}
  3014. {$ifdef i386}
  3015. usedregisters:=$ff;
  3016. {$else}
  3017. usedregisters:=[firstreg..lastreg];
  3018. {$endif i386}
  3019. {$endif newcg}
  3020. end;
  3021. {$ifdef newcg}
  3022. writenormalset(usedregisters);
  3023. {$else newcg}
  3024. {$ifdef i386}
  3025. ppufile.putbyte(usedregisters);
  3026. {$else}
  3027. writenormalset(usedregisters);
  3028. {$endif i386}
  3029. {$endif newcg}
  3030. ppufile.do_interface_crc:=oldintfcrc;
  3031. ppufile.putstring(mangledname);
  3032. ppufile.putlongint(extnumber);
  3033. if (proctypeoption<>potype_operator) then
  3034. ppufile.putderef(nextoverloaded)
  3035. else
  3036. begin
  3037. { only write the overloads from the same unit }
  3038. if assigned(nextoverloaded) and
  3039. (nextoverloaded.owner=owner) then
  3040. ppufile.putderef(nextoverloaded)
  3041. else
  3042. ppufile.putderef(nil);
  3043. end;
  3044. ppufile.putderef(_class);
  3045. ppufile.putposinfo(fileinfo);
  3046. if (pocall_inline in proccalloptions) then
  3047. begin
  3048. { we need to save
  3049. - the para and the local symtable
  3050. - the code ptree !! PM
  3051. writesymtable(parast);
  3052. writesymtable(localst);
  3053. writeptree(ptree(code));
  3054. }
  3055. end;
  3056. ppufile.writeentry(ibprocdef);
  3057. { Save the para and local symtable, for easier reading
  3058. save both always, they don't influence the interface crc }
  3059. oldintfcrc:=ppufile.do_interface_crc;
  3060. ppufile.do_interface_crc:=false;
  3061. if not assigned(parast) then
  3062. begin
  3063. parast:=tparasymtable.create;
  3064. parast.defowner:=self;
  3065. end;
  3066. tparasymtable(parast).write(ppufile);
  3067. {if not assigned(localst) then
  3068. begin
  3069. localst:=new(tstoredsymtable.create(localsymtable));
  3070. localst.defowner:=self;
  3071. end;
  3072. localst.writeas;}
  3073. ppufile.do_interface_crc:=oldintfcrc;
  3074. end;
  3075. function tprocdef.fullprocname:string;
  3076. var
  3077. s : string;
  3078. begin
  3079. s:='';
  3080. if assigned(_class) then
  3081. s:=_class.objname^+'.';
  3082. s:=s+procsym.realname+demangled_paras;
  3083. fullprocname:=s;
  3084. end;
  3085. function tprocdef.fullprocnamewithret:string;
  3086. var
  3087. s : string;
  3088. begin
  3089. s:=fullprocname;
  3090. if assigned(rettype.def) and
  3091. not(is_equal(rettype.def,voidtype.def)) then
  3092. s:=s+' : '+rettype.def.gettypename;
  3093. fullprocnamewithret:=s;
  3094. end;
  3095. function tprocdef.getsymtable(t:tgetsymtable):tsymtable;
  3096. begin
  3097. case t of
  3098. gs_local :
  3099. getsymtable:=localst;
  3100. gs_para :
  3101. getsymtable:=parast;
  3102. else
  3103. getsymtable:=nil;
  3104. end;
  3105. end;
  3106. Const local_symtable_index : longint = $8001;
  3107. procedure tprocdef.load_references(ppufile:tcompilerppufile);
  3108. var
  3109. pos : tfileposinfo;
  3110. oldsymtablestack,
  3111. st : tsymtable;
  3112. move_last : boolean;
  3113. begin
  3114. move_last:=lastwritten=lastref;
  3115. while (not ppufile.endofentry) do
  3116. begin
  3117. ppufile.getposinfo(pos);
  3118. inc(refcount);
  3119. lastref:=tref.create(lastref,@pos);
  3120. lastref.is_written:=true;
  3121. if refcount=1 then
  3122. defref:=lastref;
  3123. end;
  3124. if move_last then
  3125. lastwritten:=lastref;
  3126. if ((current_module.flags and uf_local_browser)<>0)
  3127. and is_in_current then
  3128. begin
  3129. oldsymtablestack:=symtablestack;
  3130. st:=aktlocalsymtable;
  3131. parast:=tparasymtable.create;
  3132. tparasymtable(parast).load(ppufile);
  3133. parast.defowner:=self;
  3134. aktlocalsymtable:=parast;
  3135. tparasymtable(parast).deref;
  3136. parast.next:=owner;
  3137. tparasymtable(parast).load_browser(ppufile);
  3138. aktlocalsymtable:=st;
  3139. localst:=tlocalsymtable.create;
  3140. tlocalsymtable(localst).load(ppufile);
  3141. localst.defowner:=self;
  3142. aktlocalsymtable:=localst;
  3143. symtablestack:=parast;
  3144. tlocalsymtable(localst).deref;
  3145. localst.next:=parast;
  3146. tlocalsymtable(localst).load_browser(ppufile);
  3147. aktlocalsymtable:=st;
  3148. symtablestack:=oldsymtablestack;
  3149. end;
  3150. end;
  3151. function tprocdef.write_references(ppufile:tcompilerppufile) : boolean;
  3152. var
  3153. ref : tref;
  3154. st : tsymtable;
  3155. pdo : tobjectdef;
  3156. move_last : boolean;
  3157. begin
  3158. move_last:=lastwritten=lastref;
  3159. if move_last and (((current_module.flags and uf_local_browser)=0)
  3160. or not is_in_current) then
  3161. exit;
  3162. { write address of this symbol }
  3163. ppufile.putderef(self);
  3164. { write refs }
  3165. if assigned(lastwritten) then
  3166. ref:=lastwritten
  3167. else
  3168. ref:=defref;
  3169. while assigned(ref) do
  3170. begin
  3171. if ref.moduleindex=current_module.unit_index then
  3172. begin
  3173. ppufile.putposinfo(ref.posinfo);
  3174. ref.is_written:=true;
  3175. if move_last then
  3176. lastwritten:=ref;
  3177. end
  3178. else if not ref.is_written then
  3179. move_last:=false
  3180. else if move_last then
  3181. lastwritten:=ref;
  3182. ref:=ref.nextref;
  3183. end;
  3184. ppufile.writeentry(ibdefref);
  3185. write_references:=true;
  3186. if ((current_module.flags and uf_local_browser)<>0)
  3187. and is_in_current then
  3188. begin
  3189. pdo:=_class;
  3190. if (owner.symtabletype<>localsymtable) then
  3191. while assigned(pdo) do
  3192. begin
  3193. if pdo.symtable<>aktrecordsymtable then
  3194. begin
  3195. pdo.symtable.unitid:=local_symtable_index;
  3196. inc(local_symtable_index);
  3197. end;
  3198. pdo:=pdo.childof;
  3199. end;
  3200. { we need TESTLOCALBROWSER para and local symtables
  3201. PPU files are then easier to read PM }
  3202. if not assigned(parast) then
  3203. parast:=tparasymtable.create;
  3204. parast.defowner:=self;
  3205. st:=aktlocalsymtable;
  3206. aktlocalsymtable:=parast;
  3207. tstoredsymtable(parast).write(ppufile);
  3208. parast.unitid:=local_symtable_index;
  3209. inc(local_symtable_index);
  3210. tstoredsymtable(parast).write_browser(ppufile);
  3211. if not assigned(localst) then
  3212. localst:=tlocalsymtable.create;
  3213. localst.defowner:=self;
  3214. aktlocalsymtable:=localst;
  3215. tstoredsymtable(localst).write(ppufile);
  3216. localst.unitid:=local_symtable_index;
  3217. inc(local_symtable_index);
  3218. tstoredsymtable(localst).write_browser(ppufile);
  3219. aktlocalsymtable:=st;
  3220. { decrement for }
  3221. local_symtable_index:=local_symtable_index-2;
  3222. pdo:=_class;
  3223. if (owner.symtabletype<>localsymtable) then
  3224. while assigned(pdo) do
  3225. begin
  3226. if pdo.symtable<>aktrecordsymtable then
  3227. dec(local_symtable_index);
  3228. pdo:=pdo.childof;
  3229. end;
  3230. end;
  3231. end;
  3232. function tprocdef.haspara:boolean;
  3233. begin
  3234. haspara:=assigned(parast.symindex.first);
  3235. end;
  3236. {$ifdef GDB}
  3237. { procedure addparaname(p : tsym);
  3238. var vs : char;
  3239. begin
  3240. if tvarsym(p).varspez = vs_value then vs := '1'
  3241. else vs := '0';
  3242. strpcopy(strend(StabRecString),p^.name+':'+tstoreddef(tvarsym(p).vartype.def).numberstring+','+vs+';');
  3243. end; }
  3244. function tprocdef.stabstring : pchar;
  3245. var
  3246. i : longint;
  3247. stabrecstring : pchar;
  3248. begin
  3249. getmem(StabRecString,1024);
  3250. strpcopy(StabRecString,'f'+tstoreddef(rettype.def).numberstring);
  3251. i:=maxparacount;
  3252. if i>0 then
  3253. begin
  3254. strpcopy(strend(StabRecString),','+tostr(i)+';');
  3255. (* confuse gdb !! PM
  3256. if assigned(parast) then
  3257. parast.foreach({$ifdef FPCPROCVAR}@{$endif}addparaname)
  3258. else
  3259. begin
  3260. param := para1;
  3261. i := 0;
  3262. while assigned(param) do
  3263. begin
  3264. inc(i);
  3265. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  3266. {Here we have lost the parameter names !!}
  3267. {using lower case parameters }
  3268. strpcopy(strend(stabrecstring),'p'+tostr(i)
  3269. +':'+param^.paratype.def.numberstring+','+vartyp+';');
  3270. param := param^.next;
  3271. end;
  3272. end; *)
  3273. {strpcopy(strend(StabRecString),';');}
  3274. end;
  3275. stabstring := strnew(stabrecstring);
  3276. freemem(stabrecstring,1024);
  3277. end;
  3278. procedure tprocdef.concatstabto(asmlist : taasmoutput);
  3279. begin
  3280. end;
  3281. {$endif GDB}
  3282. procedure tprocdef.deref;
  3283. var
  3284. oldsymtablestack,
  3285. oldlocalsymtable : tsymtable;
  3286. begin
  3287. inherited deref;
  3288. resolvedef(tdef(nextoverloaded));
  3289. resolvedef(tdef(_class));
  3290. { parast }
  3291. oldsymtablestack:=symtablestack;
  3292. oldlocalsymtable:=aktlocalsymtable;
  3293. aktlocalsymtable:=parast;
  3294. tparasymtable(parast).deref;
  3295. {symtablestack:=parast;
  3296. aktlocalsymtable:=localst;
  3297. localst.deref;}
  3298. aktlocalsymtable:=oldlocalsymtable;
  3299. symtablestack:=oldsymtablestack;
  3300. end;
  3301. function tprocdef.mangledname : string;
  3302. begin
  3303. if assigned(_mangledname) then
  3304. mangledname:=_mangledname^
  3305. else
  3306. mangledname:='';
  3307. if count then
  3308. is_used:=true;
  3309. end;
  3310. function tprocdef.cplusplusmangledname : string;
  3311. function getcppparaname(p : tdef) : string;
  3312. const
  3313. ordtype2str : array[tbasetype] of string[2] = (
  3314. '','','c',
  3315. 'Uc','Us','Ui',
  3316. 'Sc','s','i',
  3317. 'b','b','b',
  3318. 'Us','x','w');
  3319. var
  3320. s : string;
  3321. begin
  3322. case p.deftype of
  3323. orddef:
  3324. s:=ordtype2str[torddef(p).typ];
  3325. pointerdef:
  3326. s:='P'+getcppparaname(tpointerdef(p).pointertype.def);
  3327. else
  3328. internalerror(2103001);
  3329. end;
  3330. getcppparaname:=s;
  3331. end;
  3332. var
  3333. s,s2 : string;
  3334. param : TParaItem;
  3335. begin
  3336. s := procsym.realname;
  3337. if procsym.owner.symtabletype=objectsymtable then
  3338. begin
  3339. s2:=upper(tobjectdef(procsym.owner.defowner).typesym.realname);
  3340. case proctypeoption of
  3341. potype_destructor:
  3342. s:='_$_'+tostr(length(s2))+s2;
  3343. potype_constructor:
  3344. s:='___'+tostr(length(s2))+s2;
  3345. else
  3346. s:='_'+s+'__'+tostr(length(s2))+s2;
  3347. end;
  3348. end
  3349. else s:=s+'__';
  3350. s:=s+'F';
  3351. { concat modifiers }
  3352. { !!!!! }
  3353. { now we handle the parameters }
  3354. param := TParaItem(Para.first);
  3355. if assigned(param) then
  3356. while assigned(param) do
  3357. begin
  3358. s2:=getcppparaname(param.paratype.def);
  3359. if param.paratyp in [vs_var,vs_out] then
  3360. s2:='R'+s2;
  3361. s:=s+s2;
  3362. param:=TParaItem(param.next);
  3363. end
  3364. else
  3365. s:=s+'v';
  3366. cplusplusmangledname:=s;
  3367. end;
  3368. procedure tprocdef.setmangledname(const s : string);
  3369. begin
  3370. if assigned(_mangledname) then
  3371. begin
  3372. {$ifdef MEMDEBUG}
  3373. dec(manglenamesize,length(_mangledname^));
  3374. {$endif}
  3375. stringdispose(_mangledname);
  3376. end;
  3377. _mangledname:=stringdup(s);
  3378. {$ifdef MEMDEBUG}
  3379. inc(manglenamesize,length(s));
  3380. {$endif}
  3381. {$ifdef EXTDEBUG}
  3382. if assigned(parast) then
  3383. begin
  3384. stringdispose(parast.name);
  3385. parast.name:=stringdup('args of '+s);
  3386. end;
  3387. if assigned(localst) then
  3388. begin
  3389. stringdispose(localst.name);
  3390. localst.name:=stringdup('locals of '+s);
  3391. end;
  3392. {$endif}
  3393. end;
  3394. {***************************************************************************
  3395. TPROCVARDEF
  3396. ***************************************************************************}
  3397. constructor tprocvardef.create;
  3398. begin
  3399. inherited create;
  3400. deftype:=procvardef;
  3401. end;
  3402. constructor tprocvardef.load(ppufile:tcompilerppufile);
  3403. begin
  3404. inherited load(ppufile);
  3405. deftype:=procvardef;
  3406. end;
  3407. procedure tprocvardef.write(ppufile:tcompilerppufile);
  3408. begin
  3409. { here we cannot get a real good value so just give something }
  3410. { plausible (PM) }
  3411. { a more secure way would be
  3412. to allways store in a temp }
  3413. if is_fpu(rettype.def) then
  3414. fpu_used:=2
  3415. else
  3416. fpu_used:=0;
  3417. inherited write(ppufile);
  3418. ppufile.writeentry(ibprocvardef);
  3419. end;
  3420. function tprocvardef.size : longint;
  3421. begin
  3422. if (po_methodpointer in procoptions) then
  3423. size:=2*target_info.size_of_pointer
  3424. else
  3425. size:=target_info.size_of_pointer;
  3426. end;
  3427. {$ifdef GDB}
  3428. function tprocvardef.stabstring : pchar;
  3429. var
  3430. nss : pchar;
  3431. { i : longint; }
  3432. begin
  3433. { i := maxparacount; }
  3434. getmem(nss,1024);
  3435. { it is not a function but a function pointer !! (PM) }
  3436. strpcopy(nss,'*f'+tstoreddef(rettype.def).numberstring{+','+tostr(i)}+';');
  3437. { this confuses gdb !!
  3438. we should use 'F' instead of 'f' but
  3439. as we use c++ language mode
  3440. it does not like that either
  3441. Please do not remove this part
  3442. might be used once
  3443. gdb for pascal is ready PM }
  3444. (*
  3445. param := para1;
  3446. i := 0;
  3447. while assigned(param) do
  3448. begin
  3449. inc(i);
  3450. if param^.paratyp = vs_value then vartyp := '1' else vartyp := '0';
  3451. {Here we have lost the parameter names !!}
  3452. pst := strpnew('p'+tostr(i)+':'+param^.paratype.def.numberstring+','+vartyp+';');
  3453. strcat(nss,pst);
  3454. strdispose(pst);
  3455. param := param^.next;
  3456. end; *)
  3457. {strpcopy(strend(nss),';');}
  3458. stabstring := strnew(nss);
  3459. freemem(nss,1024);
  3460. end;
  3461. procedure tprocvardef.concatstabto(asmlist : taasmoutput);
  3462. begin
  3463. if ( not assigned(typesym) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches))
  3464. and (is_def_stab_written = not_written) then
  3465. inherited concatstabto(asmlist);
  3466. is_def_stab_written:=written;
  3467. end;
  3468. {$endif GDB}
  3469. procedure tprocvardef.write_rtti_data;
  3470. var
  3471. pdc : TParaItem;
  3472. methodkind, paraspec : byte;
  3473. begin
  3474. if po_methodpointer in procoptions then
  3475. begin
  3476. { write method id and name }
  3477. rttiList.concat(Tai_const.Create_8bit(tkmethod));
  3478. write_rtti_name;
  3479. { write kind of method (can only be function or procedure)}
  3480. if rettype.def = voidtype.def then
  3481. methodkind := mkProcedure
  3482. else
  3483. methodkind := mkFunction;
  3484. rttiList.concat(Tai_const.Create_8bit(methodkind));
  3485. { get # of parameters }
  3486. rttiList.concat(Tai_const.Create_8bit(maxparacount));
  3487. { write parameter info. The parameters must be written in reverse order
  3488. if this method uses right to left parameter pushing! }
  3489. if (pocall_leftright in proccalloptions) then
  3490. pdc:=TParaItem(Para.last)
  3491. else
  3492. pdc:=TParaItem(Para.first);
  3493. while assigned(pdc) do
  3494. begin
  3495. case pdc.paratyp of
  3496. vs_value: paraspec := 0;
  3497. vs_const: paraspec := pfConst;
  3498. vs_var : paraspec := pfVar;
  3499. vs_out : paraspec := pfOut;
  3500. end;
  3501. { write flags for current parameter }
  3502. rttiList.concat(Tai_const.Create_8bit(paraspec));
  3503. { write name of current parameter ### how can I get this??? (sg)}
  3504. rttiList.concat(Tai_const.Create_8bit(0));
  3505. { write name of type of current parameter }
  3506. tstoreddef(pdc.paratype.def).write_rtti_name;
  3507. if (pocall_leftright in proccalloptions) then
  3508. pdc:=TParaItem(pdc.previous)
  3509. else
  3510. pdc:=TParaItem(pdc.next);
  3511. end;
  3512. { write name of result type }
  3513. tstoreddef(rettype.def).write_rtti_name;
  3514. end;
  3515. end;
  3516. procedure tprocvardef.write_child_rtti_data;
  3517. begin
  3518. {!!!!!!!!}
  3519. end;
  3520. function tprocvardef.is_publishable : boolean;
  3521. begin
  3522. is_publishable:=(po_methodpointer in procoptions);
  3523. end;
  3524. function tprocvardef.gettypename : string;
  3525. begin
  3526. if assigned(rettype.def) and
  3527. (rettype.def<>voidtype.def) then
  3528. gettypename:='<procedure variable type of function'+demangled_paras+
  3529. ':'+rettype.def.gettypename+';'+proccalloption2str+'>'
  3530. else
  3531. gettypename:='<procedure variable type of procedure'+demangled_paras+
  3532. ';'+proccalloption2str+'>';
  3533. end;
  3534. {***************************************************************************
  3535. TOBJECTDEF
  3536. ***************************************************************************}
  3537. {$ifdef GDB}
  3538. const
  3539. vtabletype : word = 0;
  3540. vtableassigned : boolean = false;
  3541. {$endif GDB}
  3542. constructor tobjectdef.create(ot : tobjectdeftype;const n : string;c : tobjectdef);
  3543. begin
  3544. inherited create;
  3545. objecttype:=ot;
  3546. deftype:=objectdef;
  3547. objectoptions:=[];
  3548. childof:=nil;
  3549. symtable:=tobjectsymtable.create(n);
  3550. { create space for vmt !! }
  3551. vmt_offset:=0;
  3552. symtable.datasize:=0;
  3553. symtable.defowner:=self;
  3554. { recordalign -1 means C record packing, that starts
  3555. with an alignment of 1 }
  3556. if aktalignment.recordalignmax=-1 then
  3557. symtable.dataalignment:=1
  3558. else
  3559. symtable.dataalignment:=aktalignment.recordalignmax;
  3560. lastvtableindex:=0;
  3561. set_parent(c);
  3562. objname:=stringdup(n);
  3563. { set up guid }
  3564. isiidguidvalid:=true; { default null guid }
  3565. fillchar(iidguid,sizeof(iidguid),0); { default null guid }
  3566. iidstr:=stringdup(''); { default is empty string }
  3567. { set£p implemented interfaces }
  3568. if objecttype in [odt_class,odt_interfacecorba] then
  3569. implementedinterfaces:=timplementedinterfaces.create
  3570. else
  3571. implementedinterfaces:=nil;
  3572. {$ifdef GDB}
  3573. writing_class_record_stab:=false;
  3574. {$endif GDB}
  3575. end;
  3576. constructor tobjectdef.load(ppufile:tcompilerppufile);
  3577. var
  3578. oldread_member : boolean;
  3579. i,implintfcount: longint;
  3580. begin
  3581. inherited loaddef(ppufile);
  3582. deftype:=objectdef;
  3583. objecttype:=tobjectdeftype(ppufile.getbyte);
  3584. savesize:=ppufile.getlongint;
  3585. vmt_offset:=ppufile.getlongint;
  3586. objname:=stringdup(ppufile.getstring);
  3587. childof:=tobjectdef(ppufile.getderef);
  3588. ppufile.getsmallset(objectoptions);
  3589. has_rtti:=boolean(ppufile.getbyte);
  3590. { load guid }
  3591. iidstr:=nil;
  3592. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3593. begin
  3594. isiidguidvalid:=boolean(ppufile.getbyte);
  3595. ppufile.putguid(iidguid);
  3596. iidstr:=stringdup(ppufile.getstring);
  3597. lastvtableindex:=ppufile.getlongint;
  3598. end;
  3599. { load implemented interfaces }
  3600. if objecttype in [odt_class,odt_interfacecorba] then
  3601. begin
  3602. implementedinterfaces:=timplementedinterfaces.create;
  3603. implintfcount:=ppufile.getlongint;
  3604. for i:=1 to implintfcount do
  3605. begin
  3606. implementedinterfaces.addintfref(tdef(ppufile.getderef));
  3607. implementedinterfaces.ioffsets(i)^:=ppufile.getlongint;
  3608. end;
  3609. end
  3610. else
  3611. implementedinterfaces:=nil;
  3612. oldread_member:=read_member;
  3613. read_member:=true;
  3614. symtable:=tobjectsymtable.create(objname^);
  3615. tobjectsymtable(symtable).load(ppufile);
  3616. read_member:=oldread_member;
  3617. symtable.defowner:=self;
  3618. { handles the predefined class tobject }
  3619. { the last TOBJECT which is loaded gets }
  3620. { it ! }
  3621. if (childof=nil) and
  3622. (objecttype=odt_class) and
  3623. (upper(objname^)='TOBJECT') then
  3624. class_tobject:=self;
  3625. if (childof=nil) and
  3626. (objecttype=odt_interfacecom) and
  3627. (upper(objname^)='IUNKNOWN') then
  3628. interface_iunknown:=self;
  3629. {$ifdef GDB}
  3630. writing_class_record_stab:=false;
  3631. {$endif GDB}
  3632. end;
  3633. destructor tobjectdef.destroy;
  3634. begin
  3635. if assigned(symtable) then
  3636. symtable.free;
  3637. if (oo_is_forward in objectoptions) then
  3638. Message1(sym_e_class_forward_not_resolved,objname^);
  3639. stringdispose(objname);
  3640. stringdispose(iidstr);
  3641. if assigned(implementedinterfaces) then
  3642. implementedinterfaces.free;
  3643. inherited destroy;
  3644. end;
  3645. procedure tobjectdef.write(ppufile:tcompilerppufile);
  3646. var
  3647. oldread_member : boolean;
  3648. implintfcount : longint;
  3649. i : longint;
  3650. begin
  3651. inherited writedef(ppufile);
  3652. ppufile.putbyte(byte(objecttype));
  3653. ppufile.putlongint(size);
  3654. ppufile.putlongint(vmt_offset);
  3655. ppufile.putstring(objname^);
  3656. ppufile.putderef(childof);
  3657. ppufile.putsmallset(objectoptions);
  3658. ppufile.putbyte(byte(has_rtti));
  3659. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  3660. begin
  3661. ppufile.putbyte(byte(isiidguidvalid));
  3662. ppufile.putguid(iidguid);
  3663. ppufile.putstring(iidstr^);
  3664. ppufile.putlongint(lastvtableindex);
  3665. end;
  3666. if objecttype in [odt_class,odt_interfacecorba] then
  3667. begin
  3668. implintfcount:=implementedinterfaces.count;
  3669. ppufile.putlongint(implintfcount);
  3670. for i:=1 to implintfcount do
  3671. begin
  3672. ppufile.putderef(implementedinterfaces.interfaces(i));
  3673. ppufile.putlongint(implementedinterfaces.ioffsets(i)^);
  3674. end;
  3675. end;
  3676. ppufile.writeentry(ibobjectdef);
  3677. oldread_member:=read_member;
  3678. read_member:=true;
  3679. tobjectsymtable(symtable).write(ppufile);
  3680. read_member:=oldread_member;
  3681. end;
  3682. procedure tobjectdef.deref;
  3683. var
  3684. oldrecsyms : tsymtable;
  3685. begin
  3686. inherited deref;
  3687. resolvedef(tdef(childof));
  3688. oldrecsyms:=aktrecordsymtable;
  3689. aktrecordsymtable:=symtable;
  3690. tstoredsymtable(symtable).deref;
  3691. aktrecordsymtable:=oldrecsyms;
  3692. if objecttype in [odt_class,odt_interfacecorba] then
  3693. implementedinterfaces.deref;
  3694. end;
  3695. procedure tobjectdef.set_parent( c : tobjectdef);
  3696. begin
  3697. { nothing to do if the parent was not forward !}
  3698. if assigned(childof) then
  3699. exit;
  3700. childof:=c;
  3701. { some options are inherited !! }
  3702. if assigned(c) then
  3703. begin
  3704. { only important for classes }
  3705. lastvtableindex:=c.lastvtableindex;
  3706. objectoptions:=objectoptions+(c.objectoptions*
  3707. [oo_has_virtual,oo_has_private,oo_has_protected,oo_has_constructor,oo_has_destructor]);
  3708. if not (objecttype in [odt_interfacecom,odt_interfacecorba]) then
  3709. begin
  3710. { add the data of the anchestor class }
  3711. inc(symtable.datasize,c.symtable.datasize);
  3712. if (oo_has_vmt in objectoptions) and
  3713. (oo_has_vmt in c.objectoptions) then
  3714. dec(symtable.datasize,target_info.size_of_pointer);
  3715. { if parent has a vmt field then
  3716. the offset is the same for the child PM }
  3717. if (oo_has_vmt in c.objectoptions) or is_class(self) then
  3718. begin
  3719. vmt_offset:=c.vmt_offset;
  3720. include(objectoptions,oo_has_vmt);
  3721. end;
  3722. end;
  3723. end;
  3724. savesize := symtable.datasize;
  3725. end;
  3726. procedure tobjectdef.insertvmt;
  3727. begin
  3728. if objecttype in [odt_interfacecom,odt_interfacecorba] then exit;
  3729. if (oo_has_vmt in objectoptions) then
  3730. internalerror(12345)
  3731. else
  3732. begin
  3733. { first round up to multiple of 4 }
  3734. if (symtable.dataalignment=2) then
  3735. begin
  3736. if (symtable.datasize and 1)<>0 then
  3737. inc(symtable.datasize);
  3738. end
  3739. else
  3740. if (symtable.dataalignment>=4) then
  3741. begin
  3742. if (symtable.datasize mod 4) <> 0 then
  3743. inc(symtable.datasize,4-(symtable.datasize mod 4));
  3744. end;
  3745. vmt_offset:=symtable.datasize;
  3746. inc(symtable.datasize,target_info.size_of_pointer);
  3747. include(objectoptions,oo_has_vmt);
  3748. end;
  3749. end;
  3750. procedure tobjectdef.check_forwards;
  3751. begin
  3752. if not(objecttype in [odt_interfacecom,odt_interfacecorba]) then
  3753. tstoredsymtable(symtable).check_forwards;
  3754. if (oo_is_forward in objectoptions) then
  3755. begin
  3756. { ok, in future, the forward can be resolved }
  3757. Message1(sym_e_class_forward_not_resolved,objname^);
  3758. exclude(objectoptions,oo_is_forward);
  3759. end;
  3760. end;
  3761. { true, if self inherits from d (or if they are equal) }
  3762. function tobjectdef.is_related(d : tobjectdef) : boolean;
  3763. var
  3764. hp : tobjectdef;
  3765. begin
  3766. hp:=self;
  3767. while assigned(hp) do
  3768. begin
  3769. if hp=d then
  3770. begin
  3771. is_related:=true;
  3772. exit;
  3773. end;
  3774. hp:=hp.childof;
  3775. end;
  3776. is_related:=false;
  3777. end;
  3778. procedure tobjectdef._searchdestructor(sym : tnamedindexitem);
  3779. var
  3780. p : tprocdef;
  3781. begin
  3782. { if we found already a destructor, then we exit }
  3783. if assigned(sd) then
  3784. exit;
  3785. if tsym(sym).typ=procsym then
  3786. begin
  3787. p:=tprocsym(sym).definition;
  3788. while assigned(p) do
  3789. begin
  3790. if p.proctypeoption=potype_destructor then
  3791. begin
  3792. sd:=p;
  3793. exit;
  3794. end;
  3795. p:=p.nextoverloaded;
  3796. end;
  3797. end;
  3798. end;
  3799. function tobjectdef.searchdestructor : tprocdef;
  3800. var
  3801. o : tobjectdef;
  3802. begin
  3803. searchdestructor:=nil;
  3804. o:=self;
  3805. sd:=nil;
  3806. while assigned(o) do
  3807. begin
  3808. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}_searchdestructor);
  3809. if assigned(sd) then
  3810. begin
  3811. searchdestructor:=sd;
  3812. exit;
  3813. end;
  3814. o:=o.childof;
  3815. end;
  3816. end;
  3817. function tobjectdef.size : longint;
  3818. begin
  3819. if objecttype in [odt_class,odt_interfacecom,odt_interfacecorba] then
  3820. size:=target_info.size_of_pointer
  3821. else
  3822. size:=symtable.datasize;
  3823. end;
  3824. function tobjectdef.alignment:longint;
  3825. begin
  3826. alignment:=symtable.dataalignment;
  3827. end;
  3828. function tobjectdef.vmtmethodoffset(index:longint):longint;
  3829. begin
  3830. { for offset of methods for classes, see rtl/inc/objpash.inc }
  3831. case objecttype of
  3832. odt_class:
  3833. vmtmethodoffset:=(index+12)*target_info.size_of_pointer;
  3834. odt_interfacecom,odt_interfacecorba:
  3835. vmtmethodoffset:=index*target_info.size_of_pointer;
  3836. else
  3837. {$ifdef WITHDMT}
  3838. vmtmethodoffset:=(index+4)*target_info.size_of_pointer;
  3839. {$else WITHDMT}
  3840. vmtmethodoffset:=(index+3)*target_info.size_of_pointer;
  3841. {$endif WITHDMT}
  3842. end;
  3843. end;
  3844. function tobjectdef.vmt_mangledname : string;
  3845. {DM: I get a nil pointer on the owner name. I don't know if this
  3846. may happen, and I have therefore fixed the problem by doing nil pointer
  3847. checks.}
  3848. var
  3849. s1,s2:string;
  3850. begin
  3851. if not(oo_has_vmt in objectoptions) then
  3852. Message1(parser_object_has_no_vmt,objname^);
  3853. if owner.name=nil then
  3854. s1:=''
  3855. else
  3856. s1:=upper(owner.name^);
  3857. if objname=nil then
  3858. s2:=''
  3859. else
  3860. s2:=Upper(objname^);
  3861. vmt_mangledname:='VMT_'+s1+'$_'+s2;
  3862. end;
  3863. function tobjectdef.rtti_name : string;
  3864. var
  3865. s1,s2:string;
  3866. begin
  3867. if owner.name=nil then
  3868. s1:=''
  3869. else
  3870. s1:=upper(owner.name^);
  3871. if objname=nil then
  3872. s2:=''
  3873. else
  3874. s2:=Upper(objname^);
  3875. rtti_name:='RTTI_'+s1+'$_'+s2;
  3876. end;
  3877. {$ifdef GDB}
  3878. procedure tobjectdef.addprocname(p :tnamedindexitem);
  3879. var virtualind,argnames : string;
  3880. news, newrec : pchar;
  3881. pd,ipd : tprocdef;
  3882. lindex : longint;
  3883. para : TParaItem;
  3884. arglength : byte;
  3885. sp : char;
  3886. begin
  3887. If tsym(p).typ = procsym then
  3888. begin
  3889. pd := tprocsym(p).definition;
  3890. { this will be used for full implementation of object stabs
  3891. not yet done }
  3892. ipd := pd;
  3893. while assigned(ipd.nextoverloaded) do ipd := ipd.nextoverloaded;
  3894. if (po_virtualmethod in pd.procoptions) then
  3895. begin
  3896. lindex := pd.extnumber;
  3897. {doesnt seem to be necessary
  3898. lindex := lindex or $80000000;}
  3899. virtualind := '*'+tostr(lindex)+';'+ipd._class.classnumberstring+';'
  3900. end
  3901. else
  3902. virtualind := '.';
  3903. { used by gdbpas to recognize constructor and destructors }
  3904. if (pd.proctypeoption=potype_constructor) then
  3905. argnames:='__ct__'
  3906. else if (pd.proctypeoption=potype_destructor) then
  3907. argnames:='__dt__'
  3908. else
  3909. argnames := '';
  3910. { arguments are not listed here }
  3911. {we don't need another definition}
  3912. para := TParaItem(pd.Para.first);
  3913. while assigned(para) do
  3914. begin
  3915. if Para.paratype.def.deftype = formaldef then
  3916. begin
  3917. if Para.paratyp=vs_var then
  3918. argnames := argnames+'3var'
  3919. else if Para.paratyp=vs_const then
  3920. argnames:=argnames+'5const'
  3921. else if Para.paratyp=vs_out then
  3922. argnames:=argnames+'3out';
  3923. end
  3924. else
  3925. begin
  3926. { if the arg definition is like (v: ^byte;..
  3927. there is no sym attached to data !!! }
  3928. if assigned(Para.paratype.def.typesym) then
  3929. begin
  3930. arglength := length(Para.paratype.def.typesym.name);
  3931. argnames := argnames + tostr(arglength)+Para.paratype.def.typesym.name;
  3932. end
  3933. else
  3934. begin
  3935. argnames:=argnames+'11unnamedtype';
  3936. end;
  3937. end;
  3938. para := TParaItem(Para.next);
  3939. end;
  3940. ipd.is_def_stab_written := written;
  3941. { here 2A must be changed for private and protected }
  3942. { 0 is private 1 protected and 2 public }
  3943. if (sp_private in tsym(p).symoptions) then sp:='0'
  3944. else if (sp_protected in tsym(p).symoptions) then sp:='1'
  3945. else sp:='2';
  3946. newrec := strpnew(p.name+'::'+ipd.numberstring
  3947. +'=##'+tstoreddef(pd.rettype.def).numberstring+';:'+argnames+';'+sp+'A'
  3948. +virtualind+';');
  3949. { get spare place for a string at the end }
  3950. if strlen(StabRecString) + strlen(newrec) >= StabRecSize-256 then
  3951. begin
  3952. getmem(news,stabrecsize+memsizeinc);
  3953. strcopy(news,stabrecstring);
  3954. freemem(stabrecstring,stabrecsize);
  3955. stabrecsize:=stabrecsize+memsizeinc;
  3956. stabrecstring:=news;
  3957. end;
  3958. strcat(StabRecstring,newrec);
  3959. {freemem(newrec,memsizeinc); }
  3960. strdispose(newrec);
  3961. {This should be used for case !!
  3962. RecOffset := RecOffset + pd.size;}
  3963. end;
  3964. end;
  3965. function tobjectdef.stabstring : pchar;
  3966. var anc : tobjectdef;
  3967. oldrec : pchar;
  3968. oldrecsize,oldrecoffset : longint;
  3969. str_end : string;
  3970. begin
  3971. if not (objecttype=odt_class) or writing_class_record_stab then
  3972. begin
  3973. oldrec := stabrecstring;
  3974. oldrecsize:=stabrecsize;
  3975. stabrecsize:=memsizeinc;
  3976. GetMem(stabrecstring,stabrecsize);
  3977. strpcopy(stabRecString,'s'+tostr(symtable.datasize));
  3978. if assigned(childof) then
  3979. begin
  3980. {only one ancestor not virtual, public, at base offset 0 }
  3981. { !1 , 0 2 0 , }
  3982. strpcopy(strend(stabrecstring),'!1,020,'+childof.classnumberstring+';');
  3983. end;
  3984. {virtual table to implement yet}
  3985. OldRecOffset:=RecOffset;
  3986. RecOffset := 0;
  3987. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addname);
  3988. RecOffset:=OldRecOffset;
  3989. if (oo_has_vmt in objectoptions) then
  3990. if not assigned(childof) or not(oo_has_vmt in childof.objectoptions) then
  3991. begin
  3992. strpcopy(strend(stabrecstring),'$vf'+classnumberstring+':'+typeglobalnumber('vtblarray')
  3993. +','+tostr(vmt_offset*8)+';');
  3994. end;
  3995. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}addprocname);
  3996. if (oo_has_vmt in objectoptions) then
  3997. begin
  3998. anc := self;
  3999. while assigned(anc.childof) and (oo_has_vmt in anc.childof.objectoptions) do
  4000. anc := anc.childof;
  4001. { just in case anc = self }
  4002. str_end:=';~%'+anc.classnumberstring+';';
  4003. end
  4004. else
  4005. str_end:=';';
  4006. strpcopy(strend(stabrecstring),str_end);
  4007. stabstring := strnew(StabRecString);
  4008. freemem(stabrecstring,stabrecsize);
  4009. stabrecstring := oldrec;
  4010. stabrecsize:=oldrecsize;
  4011. end
  4012. else
  4013. begin
  4014. stabstring:=strpnew('*'+classnumberstring);
  4015. end;
  4016. end;
  4017. procedure tobjectdef.set_globalnb;
  4018. begin
  4019. globalnb:=PglobalTypeCount^;
  4020. inc(PglobalTypeCount^);
  4021. { classes need two type numbers, the globalnb is set to the ptr }
  4022. if objecttype=odt_class then
  4023. begin
  4024. globalnb:=PGlobalTypeCount^;
  4025. inc(PglobalTypeCount^);
  4026. end;
  4027. end;
  4028. function tobjectdef.classnumberstring : string;
  4029. begin
  4030. { write stabs again if needed }
  4031. numberstring;
  4032. if objecttype=odt_class then
  4033. begin
  4034. dec(globalnb);
  4035. classnumberstring:=numberstring;
  4036. inc(globalnb);
  4037. end
  4038. else
  4039. classnumberstring:=numberstring;
  4040. end;
  4041. function tobjectdef.allstabstring : pchar;
  4042. var stabchar : string[2];
  4043. ss,st : pchar;
  4044. sname : string;
  4045. sym_line_no : longint;
  4046. begin
  4047. ss := stabstring;
  4048. getmem(st,strlen(ss)+512);
  4049. stabchar := 't';
  4050. if deftype in tagtypes then
  4051. stabchar := 'Tt';
  4052. if assigned(typesym) then
  4053. begin
  4054. sname := typesym.name;
  4055. sym_line_no:=typesym.fileinfo.line;
  4056. end
  4057. else
  4058. begin
  4059. sname := ' ';
  4060. sym_line_no:=0;
  4061. end;
  4062. if writing_class_record_stab then
  4063. strpcopy(st,'"'+sname+':'+stabchar+classnumberstring+'=')
  4064. else
  4065. strpcopy(st,'"'+sname+':'+stabchar+numberstring+'=');
  4066. strpcopy(strecopy(strend(st),ss),'",'+tostr(N_LSYM)+',0,'+tostr(sym_line_no)+',0');
  4067. allstabstring := strnew(st);
  4068. freemem(st,strlen(ss)+512);
  4069. strdispose(ss);
  4070. end;
  4071. procedure tobjectdef.concatstabto(asmlist : taasmoutput);
  4072. var st : pstring;
  4073. begin
  4074. if objecttype<>odt_class then
  4075. begin
  4076. inherited concatstabto(asmlist);
  4077. exit;
  4078. end;
  4079. if ((typesym=nil) or ttypesym(typesym).isusedinstab or (cs_gdb_dbx in aktglobalswitches)) and
  4080. (is_def_stab_written = not_written) then
  4081. begin
  4082. if globalnb=0 then
  4083. set_globalnb;
  4084. { Write the record class itself }
  4085. writing_class_record_stab:=true;
  4086. inherited concatstabto(asmlist);
  4087. writing_class_record_stab:=false;
  4088. { Write the invisible pointer class }
  4089. is_def_stab_written:=not_written;
  4090. if assigned(typesym) then
  4091. begin
  4092. st:=typesym.FName;
  4093. typesym.FName:=stringdup(' ');
  4094. end;
  4095. inherited concatstabto(asmlist);
  4096. if assigned(typesym) then
  4097. begin
  4098. stringdispose(typesym.FName);
  4099. typesym.FName:=st;
  4100. end;
  4101. end;
  4102. end;
  4103. {$endif GDB}
  4104. procedure tobjectdef.write_child_init_data;
  4105. begin
  4106. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_child_inittable);
  4107. end;
  4108. procedure tobjectdef.write_init_data;
  4109. begin
  4110. case objecttype of
  4111. odt_class:
  4112. rttiList.concat(Tai_const.Create_8bit(tkclass));
  4113. odt_object:
  4114. rttiList.concat(Tai_const.Create_8bit(tkobject));
  4115. odt_interfacecom:
  4116. rttiList.concat(Tai_const.Create_8bit(tkinterface));
  4117. odt_interfacecorba:
  4118. rttiList.concat(Tai_const.Create_8bit(tkinterfaceCorba));
  4119. else
  4120. exit;
  4121. end;
  4122. { generate the name }
  4123. rttiList.concat(Tai_const.Create_8bit(length(objname^)));
  4124. rttiList.concat(Tai_string.Create(objname^));
  4125. rttiList.concat(Tai_const.Create_32bit(size));
  4126. count:=0;
  4127. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  4128. begin
  4129. end
  4130. else
  4131. begin
  4132. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_inittable_fields);
  4133. rttiList.concat(Tai_const.Create_32bit(count));
  4134. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_field_inittable);
  4135. end;
  4136. end;
  4137. function tobjectdef.needs_inittable : boolean;
  4138. begin
  4139. case objecttype of
  4140. odt_interfacecom:
  4141. needs_inittable:=true;
  4142. odt_interfacecorba:
  4143. needs_inittable:=is_related(interface_iunknown);
  4144. odt_object:
  4145. needs_inittable:=tobjectsymtable(symtable).needs_init_final;
  4146. else
  4147. needs_inittable:=false;
  4148. end;
  4149. end;
  4150. procedure tobjectdef.count_published_properties(sym:tnamedindexitem);
  4151. begin
  4152. if needs_prop_entry(tsym(sym)) and
  4153. (tsym(sym).typ<>varsym) then
  4154. inc(count);
  4155. end;
  4156. procedure tobjectdef.write_property_info(sym : tnamedindexitem);
  4157. var
  4158. proctypesinfo : byte;
  4159. procedure writeproc(proc : tsymlist; shiftvalue : byte);
  4160. var
  4161. typvalue : byte;
  4162. hp : psymlistitem;
  4163. address : longint;
  4164. begin
  4165. if not(assigned(proc) and assigned(proc.firstsym)) then
  4166. begin
  4167. rttiList.concat(Tai_const.Create_32bit(1));
  4168. typvalue:=3;
  4169. end
  4170. else if proc.firstsym^.sym.typ=varsym then
  4171. begin
  4172. address:=0;
  4173. hp:=proc.firstsym;
  4174. while assigned(hp) do
  4175. begin
  4176. inc(address,tvarsym(hp^.sym).address);
  4177. hp:=hp^.next;
  4178. end;
  4179. rttiList.concat(Tai_const.Create_32bit(address));
  4180. typvalue:=0;
  4181. end
  4182. else
  4183. begin
  4184. if not(po_virtualmethod in tprocdef(proc.def).procoptions) then
  4185. begin
  4186. rttiList.concat(Tai_const_symbol.Createname(tprocdef(proc.def).mangledname));
  4187. typvalue:=1;
  4188. end
  4189. else
  4190. begin
  4191. { virtual method, write vmt offset }
  4192. rttiList.concat(Tai_const.Create_32bit(
  4193. tprocdef(proc.def)._class.vmtmethodoffset(tprocdef(proc.def).extnumber)));
  4194. typvalue:=2;
  4195. end;
  4196. end;
  4197. proctypesinfo:=proctypesinfo or (typvalue shl shiftvalue);
  4198. end;
  4199. begin
  4200. if needs_prop_entry(tsym(sym)) then
  4201. case tsym(sym).typ of
  4202. varsym:
  4203. begin
  4204. {$ifdef dummy}
  4205. if not(tvarsym(sym).vartype.def.deftype=objectdef) or
  4206. not(tobjectdef(tvarsym(sym).vartype.def).is_class) then
  4207. internalerror(1509992);
  4208. { access to implicit class property as field }
  4209. proctypesinfo:=(0 shl 0) or (0 shl 2) or (0 shl 4);
  4210. rttiList.concat(Tai_const_symbol.Createname(tvarsym(sym.vartype.def.get_rtti_label)));
  4211. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym.address)));
  4212. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym.address)));
  4213. { per default stored }
  4214. rttiList.concat(Tai_const.Create_32bit(1));
  4215. { index as well as ... }
  4216. rttiList.concat(Tai_const.Create_32bit(0));
  4217. { default value are zero }
  4218. rttiList.concat(Tai_const.Create_32bit(0));
  4219. rttiList.concat(Tai_const.Create_16bit(count));
  4220. inc(count);
  4221. rttiList.concat(Tai_const.Create_8bit(proctypesinfo));
  4222. rttiList.concat(Tai_const.Create_8bit(length(tvarsym(sym.realname))));
  4223. rttiList.concat(Tai_string.Create(tvarsym(sym.realname)));
  4224. {$endif dummy}
  4225. end;
  4226. propertysym:
  4227. begin
  4228. if ppo_indexed in tpropertysym(sym).propoptions then
  4229. proctypesinfo:=$40
  4230. else
  4231. proctypesinfo:=0;
  4232. rttiList.concat(Tai_const_symbol.Createname(tpropertysym(sym).proptype.def.get_rtti_label));
  4233. writeproc(tpropertysym(sym).readaccess,0);
  4234. writeproc(tpropertysym(sym).writeaccess,2);
  4235. { isn't it stored ? }
  4236. if not(ppo_stored in tpropertysym(sym).propoptions) then
  4237. begin
  4238. rttiList.concat(Tai_const.Create_32bit(0));
  4239. proctypesinfo:=proctypesinfo or (3 shl 4);
  4240. end
  4241. else
  4242. writeproc(tpropertysym(sym).storedaccess,4);
  4243. rttiList.concat(Tai_const.Create_32bit(tpropertysym(sym).index));
  4244. rttiList.concat(Tai_const.Create_32bit(tpropertysym(sym).default));
  4245. rttiList.concat(Tai_const.Create_16bit(count));
  4246. inc(count);
  4247. rttiList.concat(Tai_const.Create_8bit(proctypesinfo));
  4248. rttiList.concat(Tai_const.Create_8bit(length(tpropertysym(sym).realname)));
  4249. rttiList.concat(Tai_string.Create(tpropertysym(sym).realname));
  4250. end;
  4251. else internalerror(1509992);
  4252. end;
  4253. end;
  4254. procedure tobjectdef.generate_published_child_rtti(sym : tnamedindexitem);
  4255. begin
  4256. if needs_prop_entry(tsym(sym)) then
  4257. case tsym(sym).typ of
  4258. varsym:
  4259. ;
  4260. { now ignored:
  4261. tvarsym(sym).vartype.def.get_rtti_label;
  4262. }
  4263. propertysym:
  4264. tpropertysym(sym).proptype.def.get_rtti_label;
  4265. else
  4266. internalerror(1509991);
  4267. end;
  4268. end;
  4269. procedure tobjectdef.write_child_rtti_data;
  4270. begin
  4271. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}generate_published_child_rtti);
  4272. end;
  4273. procedure tobjectdef.generate_rtti;
  4274. begin
  4275. if not has_rtti then
  4276. begin
  4277. has_rtti:=true;
  4278. getdatalabel(rtti_label);
  4279. write_child_rtti_data;
  4280. rttiList.concat(Tai_symbol.Createname_global(rtti_name,0));
  4281. rttiList.concat(Tai_label.Create(rtti_label));
  4282. write_rtti_data;
  4283. rttiList.concat(Tai_symbol_end.Createname(rtti_name));
  4284. end;
  4285. end;
  4286. type
  4287. tclasslistitem = class(tlinkedlistitem)
  4288. index : longint;
  4289. p : tobjectdef;
  4290. end;
  4291. var
  4292. classtablelist : tlinkedlist;
  4293. tablecount : longint;
  4294. function searchclasstablelist(p : tobjectdef) : tclasslistitem;
  4295. var
  4296. hp : tclasslistitem;
  4297. begin
  4298. hp:=tclasslistitem(classtablelist.first);
  4299. while assigned(hp) do
  4300. if hp.p=p then
  4301. begin
  4302. searchclasstablelist:=hp;
  4303. exit;
  4304. end
  4305. else
  4306. hp:=tclasslistitem(hp.next);
  4307. searchclasstablelist:=nil;
  4308. end;
  4309. procedure tobjectdef.count_published_fields(sym:tnamedindexitem);
  4310. var
  4311. hp : tclasslistitem;
  4312. begin
  4313. if needs_prop_entry(tsym(sym)) and
  4314. (tsym(sym).typ=varsym) then
  4315. begin
  4316. if tvarsym(sym).vartype.def.deftype<>objectdef then
  4317. internalerror(0206001);
  4318. hp:=searchclasstablelist(tobjectdef(tvarsym(sym).vartype.def));
  4319. if not(assigned(hp)) then
  4320. begin
  4321. hp:=tclasslistitem.create;
  4322. hp.p:=tobjectdef(tvarsym(sym).vartype.def);
  4323. hp.index:=tablecount;
  4324. classtablelist.concat(hp);
  4325. inc(tablecount);
  4326. end;
  4327. inc(count);
  4328. end;
  4329. end;
  4330. procedure tobjectdef.writefields(sym:tnamedindexitem);
  4331. var
  4332. hp : tclasslistitem;
  4333. begin
  4334. if needs_prop_entry(tsym(sym)) and
  4335. (tsym(sym).typ=varsym) then
  4336. begin
  4337. rttiList.concat(Tai_const.Create_32bit(tvarsym(sym).address));
  4338. hp:=searchclasstablelist(tobjectdef(tvarsym(sym).vartype.def));
  4339. if not(assigned(hp)) then
  4340. internalerror(0206002);
  4341. rttiList.concat(Tai_const.Create_16bit(hp.index));
  4342. rttiList.concat(Tai_const.Create_8bit(length(tvarsym(sym).realname)));
  4343. rttiList.concat(Tai_string.Create(tvarsym(sym).realname));
  4344. end;
  4345. end;
  4346. function tobjectdef.generate_field_table : tasmlabel;
  4347. var
  4348. fieldtable,
  4349. classtable : tasmlabel;
  4350. hp : tclasslistitem;
  4351. begin
  4352. classtablelist:=TLinkedList.Create;
  4353. getdatalabel(fieldtable);
  4354. getdatalabel(classtable);
  4355. count:=0;
  4356. tablecount:=0;
  4357. symtable.foreach({$ifdef FPC}@{$endif}count_published_fields);
  4358. rttiList.concat(Tai_label.Create(fieldtable));
  4359. rttiList.concat(Tai_const.Create_16bit(count));
  4360. rttiList.concat(Tai_const_symbol.Create(classtable));
  4361. symtable.foreach({$ifdef FPC}@{$endif}writefields);
  4362. { generate the class table }
  4363. rttiList.concat(Tai_label.Create(classtable));
  4364. rttiList.concat(Tai_const.Create_16bit(tablecount));
  4365. hp:=tclasslistitem(classtablelist.first);
  4366. while assigned(hp) do
  4367. begin
  4368. rttiList.concat(Tai_const_symbol.Createname(tobjectdef(hp.p).vmt_mangledname));
  4369. hp:=tclasslistitem(hp.next);
  4370. end;
  4371. generate_field_table:=fieldtable;
  4372. classtablelist.free;
  4373. end;
  4374. function tobjectdef.next_free_name_index : longint;
  4375. var
  4376. i : longint;
  4377. begin
  4378. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4379. i:=childof.next_free_name_index
  4380. else
  4381. i:=0;
  4382. count:=0;
  4383. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
  4384. next_free_name_index:=i+count;
  4385. end;
  4386. procedure tobjectdef.write_rtti_data;
  4387. begin
  4388. case objecttype of
  4389. odt_class: rttiList.concat(Tai_const.Create_8bit(tkclass));
  4390. odt_object: rttiList.concat(Tai_const.Create_8bit(tkobject));
  4391. odt_interfacecom: rttiList.concat(Tai_const.Create_8bit(tkinterface));
  4392. odt_interfacecorba: rttiList.concat(Tai_const.Create_8bit(tkinterfaceCorba));
  4393. else
  4394. exit;
  4395. end;
  4396. { generate the name }
  4397. rttiList.concat(Tai_const.Create_8bit(length(objname^)));
  4398. rttiList.concat(Tai_string.Create(objname^));
  4399. if objecttype in [odt_interfacecom,odt_interfacecorba] then
  4400. rttiList.concat(Tai_const.Create_32bit(0))
  4401. else
  4402. rttiList.concat(Tai_const_symbol.Createname(vmt_mangledname));
  4403. { write owner typeinfo }
  4404. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4405. rttiList.concat(Tai_const_symbol.Createname(childof.get_rtti_label))
  4406. else
  4407. rttiList.concat(Tai_const.Create_32bit(0));
  4408. { count total number of properties }
  4409. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4410. count:=childof.next_free_name_index
  4411. else
  4412. count:=0;
  4413. { write it }
  4414. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
  4415. rttiList.concat(Tai_const.Create_16bit(count));
  4416. { write unit name }
  4417. rttiList.concat(Tai_const.Create_8bit(length(current_module.realmodulename^)));
  4418. rttiList.concat(Tai_string.Create(current_module.realmodulename^));
  4419. { write published properties count }
  4420. count:=0;
  4421. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}count_published_properties);
  4422. rttiList.concat(Tai_const.Create_16bit(count));
  4423. { count is used to write nameindex }
  4424. { but we need an offset of the owner }
  4425. { to give each property an own slot }
  4426. if assigned(childof) and (oo_can_have_published in childof.objectoptions) then
  4427. count:=childof.next_free_name_index
  4428. else
  4429. count:=0;
  4430. symtable.foreach({$ifdef FPCPROCVAR}@{$endif}write_property_info);
  4431. end;
  4432. function tobjectdef.is_publishable : boolean;
  4433. begin
  4434. is_publishable:=objecttype in [odt_class,odt_interfacecom,odt_interfacecorba];
  4435. end;
  4436. function tobjectdef.get_rtti_label : string;
  4437. begin
  4438. generate_rtti;
  4439. get_rtti_label:=rtti_name;
  4440. end;
  4441. {****************************************************************************
  4442. TIMPLEMENTEDINTERFACES
  4443. ****************************************************************************}
  4444. type
  4445. tnamemap = class(TNamedIndexItem)
  4446. newname: pstring;
  4447. constructor create(const aname, anewname: string);
  4448. destructor destroy; override;
  4449. end;
  4450. constructor tnamemap.create(const aname, anewname: string);
  4451. begin
  4452. inherited createname(name);
  4453. newname:=stringdup(anewname);
  4454. end;
  4455. destructor tnamemap.destroy;
  4456. begin
  4457. stringdispose(newname);
  4458. inherited destroy;
  4459. end;
  4460. type
  4461. tprocdefstore = class(TNamedIndexItem)
  4462. procdef: tprocdef;
  4463. constructor create(aprocdef: tprocdef);
  4464. end;
  4465. constructor tprocdefstore.create(aprocdef: tprocdef);
  4466. begin
  4467. inherited create;
  4468. procdef:=aprocdef;
  4469. end;
  4470. type
  4471. timplintfentry = class(TNamedIndexItem)
  4472. intf: tobjectdef;
  4473. ioffs: longint;
  4474. namemappings: tdictionary;
  4475. procdefs: TIndexArray;
  4476. constructor create(aintf: tobjectdef);
  4477. destructor destroy; override;
  4478. end;
  4479. constructor timplintfentry.create(aintf: tobjectdef);
  4480. begin
  4481. inherited create;
  4482. intf:=aintf;
  4483. ioffs:=-1;
  4484. namemappings:=nil;
  4485. procdefs:=nil;
  4486. end;
  4487. destructor timplintfentry.destroy;
  4488. begin
  4489. if assigned(namemappings) then
  4490. namemappings.free;
  4491. if assigned(procdefs) then
  4492. procdefs.free;
  4493. inherited destroy;
  4494. end;
  4495. constructor timplementedinterfaces.create;
  4496. begin
  4497. finterfaces:=tindexarray.create(1);
  4498. end;
  4499. destructor timplementedinterfaces.destroy;
  4500. begin
  4501. finterfaces.destroy;
  4502. end;
  4503. function timplementedinterfaces.count: longint;
  4504. begin
  4505. count:=finterfaces.count;
  4506. end;
  4507. procedure timplementedinterfaces.checkindex(intfindex: longint);
  4508. begin
  4509. if (intfindex<1) or (intfindex>count) then
  4510. InternalError(200006123);
  4511. end;
  4512. function timplementedinterfaces.interfaces(intfindex: longint): tobjectdef;
  4513. begin
  4514. checkindex(intfindex);
  4515. interfaces:=timplintfentry(finterfaces.search(intfindex)).intf;
  4516. end;
  4517. function timplementedinterfaces.ioffsets(intfindex: longint): plongint;
  4518. begin
  4519. checkindex(intfindex);
  4520. ioffsets:=@timplintfentry(finterfaces.search(intfindex)).ioffs;
  4521. end;
  4522. function timplementedinterfaces.searchintf(def: tdef): longint;
  4523. var
  4524. i: longint;
  4525. begin
  4526. i:=1;
  4527. while (i<=count) and (tdef(interfaces(i))<>def) do inc(i);
  4528. if i<=count then
  4529. searchintf:=i
  4530. else
  4531. searchintf:=-1;
  4532. end;
  4533. procedure timplementedinterfaces.deref;
  4534. var
  4535. i: longint;
  4536. begin
  4537. for i:=1 to count do
  4538. with timplintfentry(finterfaces.search(i)) do
  4539. resolvedef(tdef(intf));
  4540. end;
  4541. procedure timplementedinterfaces.addintfref(def: tdef);
  4542. begin
  4543. finterfaces.insert(timplintfentry.create(tobjectdef(def)));
  4544. end;
  4545. procedure timplementedinterfaces.addintf(def: tdef);
  4546. begin
  4547. if not assigned(def) or (searchintf(def)<>-1) or (def.deftype<>objectdef) or
  4548. not (tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba]) then
  4549. internalerror(200006124);
  4550. finterfaces.insert(timplintfentry.create(tobjectdef(def)));
  4551. end;
  4552. procedure timplementedinterfaces.clearmappings;
  4553. var
  4554. i: longint;
  4555. begin
  4556. for i:=1 to count do
  4557. with timplintfentry(finterfaces.search(i)) do
  4558. begin
  4559. if assigned(namemappings) then
  4560. namemappings.free;
  4561. namemappings:=nil;
  4562. end;
  4563. end;
  4564. procedure timplementedinterfaces.addmappings(intfindex: longint; const name, newname: string);
  4565. begin
  4566. checkindex(intfindex);
  4567. with timplintfentry(finterfaces.search(intfindex)) do
  4568. begin
  4569. if not assigned(namemappings) then
  4570. namemappings:=tdictionary.create;
  4571. namemappings.insert(tnamemap.create(name,newname));
  4572. end;
  4573. end;
  4574. function timplementedinterfaces.getmappings(intfindex: longint; const name: string; var nextexist: pointer): string;
  4575. begin
  4576. checkindex(intfindex);
  4577. if not assigned(nextexist) then
  4578. with timplintfentry(finterfaces.search(intfindex)) do
  4579. begin
  4580. if assigned(namemappings) then
  4581. nextexist:=namemappings.search(name)
  4582. else
  4583. nextexist:=nil;
  4584. end;
  4585. if assigned(nextexist) then
  4586. begin
  4587. getmappings:=tnamemap(nextexist).newname^;
  4588. nextexist:=tnamemap(nextexist).listnext;
  4589. end
  4590. else
  4591. getmappings:='';
  4592. end;
  4593. procedure timplementedinterfaces.clearimplprocs;
  4594. var
  4595. i: longint;
  4596. begin
  4597. for i:=1 to count do
  4598. with timplintfentry(finterfaces.search(i)) do
  4599. begin
  4600. if assigned(procdefs) then
  4601. procdefs.free;
  4602. procdefs:=nil;
  4603. end;
  4604. end;
  4605. procedure timplementedinterfaces.addimplproc(intfindex: longint; procdef: tprocdef);
  4606. begin
  4607. checkindex(intfindex);
  4608. with timplintfentry(finterfaces.search(intfindex)) do
  4609. begin
  4610. if not assigned(procdefs) then
  4611. procdefs:=tindexarray.create(4);
  4612. procdefs.insert(tprocdefstore.create(procdef));
  4613. end;
  4614. end;
  4615. function timplementedinterfaces.implproccount(intfindex: longint): longint;
  4616. begin
  4617. checkindex(intfindex);
  4618. with timplintfentry(finterfaces.search(intfindex)) do
  4619. if assigned(procdefs) then
  4620. implproccount:=procdefs.count
  4621. else
  4622. implproccount:=0;
  4623. end;
  4624. function timplementedinterfaces.implprocs(intfindex: longint; procindex: longint): tprocdef;
  4625. begin
  4626. checkindex(intfindex);
  4627. with timplintfentry(finterfaces.search(intfindex)) do
  4628. if assigned(procdefs) then
  4629. implprocs:=tprocdefstore(procdefs.search(procindex)).procdef
  4630. else
  4631. internalerror(200006131);
  4632. end;
  4633. function timplementedinterfaces.isimplmergepossible(intfindex, remainindex: longint; var weight: longint): boolean;
  4634. var
  4635. possible: boolean;
  4636. i: longint;
  4637. iiep1: TIndexArray;
  4638. iiep2: TIndexArray;
  4639. begin
  4640. checkindex(intfindex);
  4641. checkindex(remainindex);
  4642. iiep1:=timplintfentry(finterfaces.search(intfindex)).procdefs;
  4643. iiep2:=timplintfentry(finterfaces.search(remainindex)).procdefs;
  4644. if not assigned(iiep1) then { empty interface is mergeable :-) }
  4645. begin
  4646. possible:=true;
  4647. weight:=0;
  4648. end
  4649. else
  4650. begin
  4651. possible:=assigned(iiep2) and (iiep1.count<=iiep2.count);
  4652. i:=1;
  4653. while (possible) and (i<=iiep1.count) do
  4654. begin
  4655. possible:=
  4656. (tprocdefstore(iiep1.search(i)).procdef=tprocdefstore(iiep2.search(i)).procdef);
  4657. inc(i);
  4658. end;
  4659. if possible then
  4660. weight:=iiep1.count;
  4661. end;
  4662. isimplmergepossible:=possible;
  4663. end;
  4664. {****************************************************************************
  4665. TFORWARDDEF
  4666. ****************************************************************************}
  4667. constructor tforwarddef.create(const s:string;const pos : tfileposinfo);
  4668. var
  4669. oldregisterdef : boolean;
  4670. begin
  4671. { never register the forwarddefs, they are disposed at the
  4672. end of the type declaration block }
  4673. oldregisterdef:=registerdef;
  4674. registerdef:=false;
  4675. inherited create;
  4676. registerdef:=oldregisterdef;
  4677. deftype:=forwarddef;
  4678. tosymname:=s;
  4679. forwardpos:=pos;
  4680. end;
  4681. function tforwarddef.gettypename:string;
  4682. begin
  4683. gettypename:='unresolved forward to '+tosymname;
  4684. end;
  4685. {****************************************************************************
  4686. TERRORDEF
  4687. ****************************************************************************}
  4688. constructor terrordef.create;
  4689. begin
  4690. inherited create;
  4691. deftype:=errordef;
  4692. end;
  4693. {$ifdef GDB}
  4694. function terrordef.stabstring : pchar;
  4695. begin
  4696. stabstring:=strpnew('error'+numberstring);
  4697. end;
  4698. {$endif GDB}
  4699. function terrordef.gettypename:string;
  4700. begin
  4701. gettypename:='<erroneous type>';
  4702. end;
  4703. {****************************************************************************
  4704. GDB Helpers
  4705. ****************************************************************************}
  4706. {$ifdef GDB}
  4707. function typeglobalnumber(const s : string) : string;
  4708. var st : string;
  4709. symt : tsymtable;
  4710. srsym : tsym;
  4711. srsymtable : tsymtable;
  4712. old_make_ref : boolean;
  4713. begin
  4714. old_make_ref:=make_ref;
  4715. make_ref:=false;
  4716. typeglobalnumber := '0';
  4717. srsym := nil;
  4718. if pos('.',s) > 0 then
  4719. begin
  4720. st := copy(s,1,pos('.',s)-1);
  4721. searchsym(st,srsym,srsymtable);
  4722. st := copy(s,pos('.',s)+1,255);
  4723. if assigned(srsym) then
  4724. begin
  4725. if srsym.typ = unitsym then
  4726. begin
  4727. symt := tunitsym(srsym).unitsymtable;
  4728. srsym := tsym(symt.search(st));
  4729. end else srsym := nil;
  4730. end;
  4731. end else st := s;
  4732. if srsym = nil then
  4733. searchsym(st,srsym,srsymtable);
  4734. if (srsym=nil) or
  4735. (srsym.typ<>typesym) then
  4736. begin
  4737. Message(type_e_type_id_expected);
  4738. exit;
  4739. end;
  4740. typeglobalnumber := tstoreddef(ttypesym(srsym).restype.def).numberstring;
  4741. make_ref:=old_make_ref;
  4742. end;
  4743. {$endif GDB}
  4744. {****************************************************************************
  4745. Definition Helpers
  4746. ****************************************************************************}
  4747. procedure reset_global_defs;
  4748. var
  4749. def : tstoreddef;
  4750. {$ifdef debug}
  4751. prevdef : tstoreddef;
  4752. {$endif debug}
  4753. begin
  4754. {$ifdef debug}
  4755. prevdef:=nil;
  4756. {$endif debug}
  4757. {$ifdef GDB}
  4758. pglobaltypecount:=@globaltypecount;
  4759. {$endif GDB}
  4760. def:=firstglobaldef;
  4761. while assigned(def) do
  4762. begin
  4763. {$ifdef GDB}
  4764. if assigned(def.typesym) then
  4765. ttypesym(def.typesym).isusedinstab:=false;
  4766. def.is_def_stab_written:=not_written;
  4767. {$endif GDB}
  4768. {if not current_module.in_implementation then}
  4769. begin
  4770. { reset rangenr's }
  4771. case def.deftype of
  4772. orddef : torddef(def).rangenr:=0;
  4773. enumdef : tenumdef(def).rangenr:=0;
  4774. arraydef : tarraydef(def).rangenr:=0;
  4775. end;
  4776. if def.deftype<>objectdef then
  4777. def.has_rtti:=false;
  4778. def.has_inittable:=false;
  4779. end;
  4780. {$ifdef debug}
  4781. prevdef:=def;
  4782. {$endif debug}
  4783. def:=def.nextglobal;
  4784. end;
  4785. end;
  4786. function is_interfacecom(def: tdef): boolean;
  4787. begin
  4788. is_interfacecom:=
  4789. assigned(def) and
  4790. (def.deftype=objectdef) and
  4791. (tobjectdef(def).objecttype=odt_interfacecom);
  4792. end;
  4793. function is_interfacecorba(def: tdef): boolean;
  4794. begin
  4795. is_interfacecorba:=
  4796. assigned(def) and
  4797. (def.deftype=objectdef) and
  4798. (tobjectdef(def).objecttype=odt_interfacecorba);
  4799. end;
  4800. function is_interface(def: tdef): boolean;
  4801. begin
  4802. is_interface:=
  4803. assigned(def) and
  4804. (def.deftype=objectdef) and
  4805. (tobjectdef(def).objecttype in [odt_interfacecom,odt_interfacecorba]);
  4806. end;
  4807. function is_class(def: tdef): boolean;
  4808. begin
  4809. is_class:=
  4810. assigned(def) and
  4811. (def.deftype=objectdef) and
  4812. (tobjectdef(def).objecttype=odt_class);
  4813. end;
  4814. function is_object(def: tdef): boolean;
  4815. begin
  4816. is_object:=
  4817. assigned(def) and
  4818. (def.deftype=objectdef) and
  4819. (tobjectdef(def).objecttype=odt_object);
  4820. end;
  4821. function is_cppclass(def: tdef): boolean;
  4822. begin
  4823. is_cppclass:=
  4824. assigned(def) and
  4825. (def.deftype=objectdef) and
  4826. (tobjectdef(def).objecttype=odt_cppclass);
  4827. end;
  4828. function is_class_or_interface(def: tdef): boolean;
  4829. begin
  4830. is_class_or_interface:=
  4831. assigned(def) and
  4832. (def.deftype=objectdef) and
  4833. (tobjectdef(def).objecttype in [odt_class,odt_interfacecom,odt_interfacecorba]);
  4834. end;
  4835. end.
  4836. {
  4837. $Log$
  4838. Revision 1.36 2001-07-01 20:16:16 peter
  4839. * alignmentinfo record added
  4840. * -Oa argument supports more alignment settings that can be specified
  4841. per type: PROC,LOOP,VARMIN,VARMAX,CONSTMIN,CONSTMAX,RECORDMIN
  4842. RECORDMAX,LOCALMIN,LOCALMAX. It is possible to set the mimimum
  4843. required alignment and the maximum usefull alignment. The final
  4844. alignment will be choosen per variable size dependent on these
  4845. settings
  4846. Revision 1.35 2001/06/27 21:37:36 peter
  4847. * v10 merges
  4848. Revision 1.34 2001/06/04 18:05:39 peter
  4849. * procdef demangling fixed
  4850. Revision 1.33 2001/06/04 11:53:13 peter
  4851. + varargs directive
  4852. Revision 1.32 2001/05/09 19:58:45 peter
  4853. * m68k doesn't support double (merged)
  4854. Revision 1.31 2001/05/06 14:49:17 peter
  4855. * ppu object to class rewrite
  4856. * move ppu read and write stuff to fppu
  4857. Revision 1.30 2001/04/22 22:46:49 florian
  4858. * more variant support
  4859. Revision 1.29 2001/04/21 12:03:12 peter
  4860. * m68k updates merged from fixes branch
  4861. Revision 1.28 2001/04/18 22:01:58 peter
  4862. * registration of targets and assemblers
  4863. Revision 1.27 2001/04/13 01:22:15 peter
  4864. * symtable change to classes
  4865. * range check generation and errors fixed, make cycle DEBUG=1 works
  4866. * memory leaks fixed
  4867. Revision 1.26 2001/04/05 21:32:22 peter
  4868. * enum stabs fix (merged)
  4869. Revision 1.25 2001/04/04 21:30:45 florian
  4870. * applied several fixes to get the DD8 Delphi Unit compiled
  4871. e.g. "forward"-interfaces are working now
  4872. Revision 1.24 2001/04/02 21:20:34 peter
  4873. * resulttype rewrite
  4874. Revision 1.23 2001/03/22 23:28:39 florian
  4875. * correct initialisation of rec_tguid when loading the system unit
  4876. Revision 1.22 2001/03/22 00:10:58 florian
  4877. + basic variant type support in the compiler
  4878. Revision 1.21 2001/03/11 22:58:50 peter
  4879. * getsym redesign, removed the globals srsym,srsymtable
  4880. Revision 1.20 2001/01/06 20:11:29 peter
  4881. * merged c packrecords fix
  4882. Revision 1.19 2000/12/25 00:07:29 peter
  4883. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  4884. tlinkedlist objects)
  4885. Revision 1.18 2000/12/24 12:20:45 peter
  4886. * classes, enum stabs fixes merged from 1.0.x
  4887. Revision 1.17 2000/12/07 17:19:43 jonas
  4888. * new constant handling: from now on, hex constants >$7fffffff are
  4889. parsed as unsigned constants (otherwise, $80000000 got sign extended
  4890. and became $ffffffff80000000), all constants in the longint range
  4891. become longints, all constants >$7fffffff and <=cardinal($ffffffff)
  4892. are cardinals and the rest are int64's.
  4893. * added lots of longint typecast to prevent range check errors in the
  4894. compiler and rtl
  4895. * type casts of symbolic ordinal constants are now preserved
  4896. * fixed bug where the original resulttype.def wasn't restored correctly
  4897. after doing a 64bit rangecheck
  4898. Revision 1.16 2000/11/30 23:12:57 florian
  4899. * if raw interfaces inherit from IUnknown they are ref. counted too
  4900. Revision 1.15 2000/11/29 00:30:40 florian
  4901. * unused units removed from uses clause
  4902. * some changes for widestrings
  4903. Revision 1.14 2000/11/28 00:28:06 pierre
  4904. * stabs fixing
  4905. Revision 1.13 2000/11/26 18:09:40 florian
  4906. * fixed rtti for chars
  4907. Revision 1.12 2000/11/19 16:23:35 florian
  4908. *** empty log message ***
  4909. Revision 1.11 2000/11/12 23:24:12 florian
  4910. * interfaces are basically running
  4911. Revision 1.10 2000/11/11 16:12:38 peter
  4912. * add far; to typename for far pointer
  4913. Revision 1.9 2000/11/07 20:01:57 peter
  4914. * fix vmt index for classes
  4915. Revision 1.8 2000/11/06 23:13:53 peter
  4916. * uppercase manglednames
  4917. Revision 1.7 2000/11/06 23:11:38 florian
  4918. * writeln debugger uninstalled ;)
  4919. Revision 1.6 2000/11/06 23:05:52 florian
  4920. * more fixes
  4921. Revision 1.5 2000/11/06 20:30:55 peter
  4922. * more fixes to get make cycle working
  4923. Revision 1.4 2000/11/04 14:25:22 florian
  4924. + merged Attila's changes for interfaces, not tested yet
  4925. Revision 1.3 2000/11/02 12:04:10 pierre
  4926. * remove RecOffset code, that created problems
  4927. Revision 1.2 2000/11/01 23:04:38 peter
  4928. * tprocdef.fullprocname added for better casesensitve writing of
  4929. procedures
  4930. Revision 1.1 2000/10/31 22:02:52 peter
  4931. * symtable splitted, no real code changes
  4932. }