symdef.pas 166 KB

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