pass_1.pas 231 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192
  1. {
  2. $Id$
  3. Copyright (c) 1996-98 by Florian Klaempfl
  4. This unit implements the first pass of the code generator
  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. {$ifdef tp}
  19. {$F+}
  20. {$endif tp}
  21. unit pass_1;
  22. interface
  23. uses tree;
  24. procedure firstpass(var p : ptree);
  25. function do_firstpass(var p : ptree) : boolean;
  26. implementation
  27. uses
  28. cobjects,verbose,comphook,systems,globals,
  29. aasm,symtable,types,strings,hcodegen,files
  30. {$ifdef i386}
  31. ,i386
  32. ,tgeni386
  33. {$endif}
  34. {$ifdef m68k}
  35. ,m68k
  36. ,tgen68k
  37. {$endif}
  38. {$ifdef UseBrowser}
  39. ,browser
  40. {$endif UseBrowser}
  41. ;
  42. { firstcallparan without varspez
  43. we don't count the ref }
  44. const
  45. count_ref : boolean = true;
  46. allow_array_constructor : boolean = false;
  47. { marks an lvalue as "unregable" }
  48. procedure make_not_regable(p : ptree);
  49. begin
  50. case p^.treetype of
  51. typeconvn :
  52. make_not_regable(p^.left);
  53. loadn :
  54. if p^.symtableentry^.typ=varsym then
  55. pvarsym(p^.symtableentry)^.var_options :=
  56. pvarsym(p^.symtableentry)^.var_options and not vo_regable;
  57. end;
  58. end;
  59. procedure left_right_max(p : ptree);
  60. begin
  61. if assigned(p^.left) then
  62. begin
  63. if assigned(p^.right) then
  64. begin
  65. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  66. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  67. {$ifdef SUPPORT_MMX}
  68. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  69. {$endif SUPPORT_MMX}
  70. end
  71. else
  72. begin
  73. p^.registers32:=p^.left^.registers32;
  74. p^.registersfpu:=p^.left^.registersfpu;
  75. {$ifdef SUPPORT_MMX}
  76. p^.registersmmx:=p^.left^.registersmmx;
  77. {$endif SUPPORT_MMX}
  78. end;
  79. end;
  80. end;
  81. { calculates the needed registers for a binary operator }
  82. procedure calcregisters(p : ptree;r32,fpu,mmx : word);
  83. begin
  84. left_right_max(p);
  85. { Only when the difference between the left and right registers < the
  86. wanted registers allocate the amount of registers }
  87. if assigned(p^.left) then
  88. begin
  89. if assigned(p^.right) then
  90. begin
  91. if (abs(p^.left^.registers32-p^.right^.registers32)<r32) then
  92. inc(p^.registers32,r32);
  93. if (abs(p^.left^.registersfpu-p^.right^.registersfpu)<fpu) then
  94. inc(p^.registersfpu,fpu);
  95. {$ifdef SUPPORT_MMX}
  96. if (abs(p^.left^.registersmmx-p^.right^.registersmmx)<mmx) then
  97. inc(p^.registersmmx,mmx);
  98. {$endif SUPPORT_MMX}
  99. end
  100. else
  101. begin
  102. if (p^.left^.registers32<r32) then
  103. inc(p^.registers32,r32);
  104. if (p^.left^.registersfpu<fpu) then
  105. inc(p^.registersfpu,fpu);
  106. {$ifdef SUPPORT_MMX}
  107. if (p^.left^.registersmmx<mmx) then
  108. inc(p^.registersmmx,mmx);
  109. {$endif SUPPORT_MMX}
  110. end;
  111. end;
  112. { error CGMessage, if more than 8 floating point }
  113. { registers are needed }
  114. if p^.registersfpu>8 then
  115. CGMessage(cg_e_too_complex_expr);
  116. end;
  117. function both_rm(p : ptree) : boolean;
  118. begin
  119. both_rm:=(p^.left^.location.loc in [LOC_MEM,LOC_REFERENCE]) and
  120. (p^.right^.location.loc in [LOC_MEM,LOC_REFERENCE]);
  121. end;
  122. function is_assignment_overloaded(from_def,to_def : pdef) : boolean;forward;
  123. procedure arrayconstructor_to_set(var p:ptree);
  124. var
  125. constp,
  126. buildp,
  127. p2,p3,p4 : ptree;
  128. pd : pdef;
  129. constset : pconstset;
  130. constsetlo,
  131. constsethi : longint;
  132. procedure update_constsethi(p:pdef);
  133. begin
  134. if ((p^.deftype=orddef) and
  135. (porddef(p)^.high>constsethi)) then
  136. constsethi:=porddef(p)^.high
  137. else
  138. if ((p^.deftype=enumdef) and
  139. (penumdef(p)^.max>constsethi)) then
  140. constsethi:=penumdef(p)^.max;
  141. end;
  142. procedure do_set(pos : longint);
  143. var
  144. mask,l : longint;
  145. begin
  146. if (pos>255) or (pos<0) then
  147. Message(parser_e_illegal_set_expr);
  148. if pos>constsethi then
  149. constsethi:=pos;
  150. if pos<constsetlo then
  151. constsetlo:=pos;
  152. l:=pos shr 3;
  153. mask:=1 shl (pos mod 8);
  154. { do we allow the same twice }
  155. if (constset^[l] and mask)<>0 then
  156. Message(parser_e_illegal_set_expr);
  157. constset^[l]:=constset^[l] or mask;
  158. end;
  159. var
  160. l : longint;
  161. begin
  162. new(constset);
  163. FillChar(constset^,sizeof(constset^),0);
  164. pd:=nil;
  165. constsetlo:=0;
  166. constsethi:=0;
  167. constp:=gensinglenode(setconstn,nil);
  168. constp^.value_set:=constset;
  169. buildp:=constp;
  170. if assigned(p^.left) then
  171. begin
  172. while assigned(p) do
  173. begin
  174. p4:=nil; { will contain the tree to create the set }
  175. { split a range into p2 and p3 }
  176. if p^.left^.treetype=arrayconstructrangen then
  177. begin
  178. p2:=p^.left^.left;
  179. p3:=p^.left^.right;
  180. { node is not used anymore }
  181. putnode(p^.left);
  182. end
  183. else
  184. begin
  185. p2:=p^.left;
  186. p3:=nil;
  187. end;
  188. firstpass(p2);
  189. if codegenerror then
  190. break;
  191. case p2^.resulttype^.deftype of
  192. enumdef,
  193. orddef : begin
  194. if (p2^.resulttype^.deftype=orddef) and
  195. (porddef(p2^.resulttype)^.typ in [s8bit,s16bit,s32bit,u16bit,u32bit]) then
  196. begin
  197. p2:=gentypeconvnode(p2,u8bitdef);
  198. firstpass(p2);
  199. end;
  200. { set settype result }
  201. if pd=nil then
  202. pd:=p2^.resulttype;
  203. if not(is_equal(pd,p2^.resulttype)) then
  204. begin
  205. Message(type_e_typeconflict_in_set);
  206. disposetree(p2);
  207. end
  208. else
  209. begin
  210. if assigned(p3) then
  211. begin
  212. if (p3^.resulttype^.deftype=orddef) and
  213. (porddef(p3^.resulttype)^.typ in [s8bit,s16bit,s32bit,u16bit,u32bit]) then
  214. begin
  215. p3:=gentypeconvnode(p3,u8bitdef);
  216. firstpass(p3);
  217. end;
  218. if not(is_equal(pd,p3^.resulttype)) then
  219. Message(type_e_typeconflict_in_set)
  220. else
  221. begin
  222. if (p2^.treetype=ordconstn) and (p3^.treetype=ordconstn) then
  223. begin
  224. for l:=p2^.value to p3^.value do
  225. do_set(l);
  226. disposetree(p3);
  227. disposetree(p2);
  228. end
  229. else
  230. begin
  231. update_constsethi(p3^.resulttype);
  232. p4:=gennode(setelementn,p2,p3);
  233. end;
  234. end;
  235. end
  236. else
  237. begin
  238. { Single value }
  239. if p2^.treetype=ordconstn then
  240. begin
  241. do_set(p2^.value);
  242. disposetree(p2);
  243. end
  244. else
  245. begin
  246. update_constsethi(p2^.resulttype);
  247. p4:=gennode(setelementn,p2,nil);
  248. end;
  249. end;
  250. end;
  251. end;
  252. stringdef : begin
  253. if pd=nil then
  254. pd:=cchardef;
  255. if not(is_equal(pd,cchardef)) then
  256. Message(type_e_typeconflict_in_set)
  257. else
  258. for l:=1 to length(pstring(p2^.value_str)^) do
  259. do_set(ord(pstring(p2^.value_str)^[l]));
  260. disposetree(p2);
  261. end;
  262. else
  263. Internalerror(4234);
  264. end;
  265. { insert the set creation tree }
  266. if assigned(p4) then
  267. buildp:=gennode(addn,buildp,p4);
  268. { load next and dispose current node }
  269. p2:=p;
  270. p:=p^.right;
  271. putnode(p2);
  272. end;
  273. end
  274. else
  275. begin
  276. { empty set [], only remove node }
  277. putnode(p);
  278. end;
  279. { set the initial set type }
  280. constp^.resulttype:=new(psetdef,init(pd,constsethi));
  281. { set the new tree }
  282. p:=buildp;
  283. end;
  284. procedure firstarrayconstruct(var p : ptree);
  285. var
  286. pd : pdef;
  287. hp : ptree;
  288. len : longint;
  289. varia : boolean;
  290. begin
  291. { are we allowing array constructor? Then convert it to a set }
  292. if not allow_array_constructor then
  293. begin
  294. arrayconstructor_to_set(p);
  295. firstpass(p);
  296. exit;
  297. end;
  298. { only pass left tree, right tree contains next construct if any }
  299. pd:=nil;
  300. len:=0;
  301. varia:=false;
  302. if assigned(p^.left) then
  303. begin
  304. hp:=p;
  305. while assigned(hp) do
  306. begin
  307. firstpass(hp^.left);
  308. case hp^.left^.resulttype^.deftype of
  309. floatdef : begin
  310. gentypeconvnode(hp^.left,s80floatdef);
  311. firstpass(hp^.left);
  312. end;
  313. end;
  314. if (pd=nil) then
  315. pd:=hp^.left^.resulttype
  316. else
  317. if (not varia) and (not is_equal(pd,hp^.left^.resulttype)) then
  318. begin
  319. varia:=true;
  320. Comment(V_Warning,'Variant type found !!');
  321. end;
  322. inc(len);
  323. hp:=hp^.right;
  324. end;
  325. end;
  326. calcregisters(p,0,0,0);
  327. p^.resulttype:=new(parraydef,init(0,len-1,pd));
  328. parraydef(p^.resulttype)^.IsConstructor:=true;
  329. parraydef(p^.resulttype)^.IsVariant:=varia;
  330. p^.location.loc:=LOC_REFERENCE;
  331. end;
  332. procedure firstarrayconstructrange(var p : ptree);
  333. begin
  334. { This is not allowed, it's only to support sets when parsing the [a..b] }
  335. Internalerror(4236);
  336. Codegenerror:=true;
  337. end;
  338. function isconvertable(def_from,def_to : pdef;
  339. var doconv : tconverttype;fromtreetype : ttreetyp;
  340. explicit : boolean) : boolean;
  341. const
  342. { Tbasetype: uauto,uvoid,uchar,
  343. u8bit,u16bit,u32bit,
  344. s8bit,s16bit,s32,
  345. bool8bit,bool16bit,boot32bit }
  346. basedefconverts : array[tbasetype,tbasetype] of tconverttype =
  347. {uauto}
  348. ((tc_not_possible,tc_not_possible,tc_not_possible,
  349. tc_not_possible,tc_not_possible,tc_not_possible,
  350. tc_not_possible,tc_not_possible,tc_not_possible,
  351. tc_not_possible,tc_not_possible,tc_not_possible),
  352. {uvoid}
  353. (tc_not_possible,tc_not_possible,tc_not_possible,
  354. tc_not_possible,tc_not_possible,tc_not_possible,
  355. tc_not_possible,tc_not_possible,tc_not_possible,
  356. tc_not_possible,tc_not_possible,tc_not_possible),
  357. {uchar}
  358. (tc_not_possible,tc_not_possible,tc_only_rangechecks32bit,
  359. tc_not_possible,tc_not_possible,tc_not_possible,
  360. tc_not_possible,tc_not_possible,tc_not_possible,
  361. tc_not_possible,tc_not_possible,tc_not_possible),
  362. {u8bit}
  363. (tc_not_possible,tc_not_possible,tc_not_possible,
  364. tc_only_rangechecks32bit,tc_u8bit_2_u16bit,tc_u8bit_2_u32bit,
  365. tc_only_rangechecks32bit,tc_u8bit_2_s16bit,tc_u8bit_2_s32bit,
  366. tc_int_2_bool,tc_int_2_bool,tc_int_2_bool),
  367. {u16bit}
  368. (tc_not_possible,tc_not_possible,tc_not_possible,
  369. tc_u16bit_2_u8bit,tc_only_rangechecks32bit,tc_u16bit_2_u32bit,
  370. tc_u16bit_2_s8bit,tc_only_rangechecks32bit,tc_u16bit_2_s32bit,
  371. tc_int_2_bool,tc_int_2_bool,tc_int_2_bool),
  372. {u32bit}
  373. (tc_not_possible,tc_not_possible,tc_not_possible,
  374. tc_u32bit_2_u8bit,tc_u32bit_2_u16bit,tc_only_rangechecks32bit,
  375. tc_u32bit_2_s8bit,tc_u32bit_2_s16bit,tc_only_rangechecks32bit,
  376. tc_int_2_bool,tc_int_2_bool,tc_int_2_bool),
  377. {s8bit}
  378. (tc_not_possible,tc_not_possible,tc_not_possible,
  379. tc_only_rangechecks32bit,tc_s8bit_2_u16bit,tc_s8bit_2_u32bit,
  380. tc_only_rangechecks32bit,tc_s8bit_2_s16bit,tc_s8bit_2_s32bit,
  381. tc_int_2_bool,tc_int_2_bool,tc_int_2_bool),
  382. {s16bit}
  383. (tc_not_possible,tc_not_possible,tc_not_possible,
  384. tc_s16bit_2_u8bit,tc_only_rangechecks32bit,tc_s16bit_2_u32bit,
  385. tc_s16bit_2_s8bit,tc_only_rangechecks32bit,tc_s16bit_2_s32bit,
  386. tc_int_2_bool,tc_int_2_bool,tc_int_2_bool),
  387. {s32bit}
  388. (tc_not_possible,tc_not_possible,tc_not_possible,
  389. tc_s32bit_2_u8bit,tc_s32bit_2_u16bit,tc_only_rangechecks32bit,
  390. tc_s32bit_2_s8bit,tc_s32bit_2_s16bit,tc_only_rangechecks32bit,
  391. tc_int_2_bool,tc_int_2_bool,tc_int_2_bool),
  392. {bool8bit}
  393. (tc_not_possible,tc_not_possible,tc_not_possible,
  394. tc_bool_2_int,tc_bool_2_int,tc_bool_2_int,
  395. tc_bool_2_int,tc_bool_2_int,tc_bool_2_int,
  396. tc_only_rangechecks32bit,tc_bool_2_int,tc_bool_2_int),
  397. {bool16bit}
  398. (tc_not_possible,tc_not_possible,tc_not_possible,
  399. tc_bool_2_int,tc_bool_2_int,tc_bool_2_int,
  400. tc_bool_2_int,tc_bool_2_int,tc_bool_2_int,
  401. tc_bool_2_int,tc_only_rangechecks32bit,tc_bool_2_int),
  402. {bool32bit}
  403. (tc_not_possible,tc_not_possible,tc_not_possible,
  404. tc_bool_2_int,tc_bool_2_int,tc_bool_2_int,
  405. tc_bool_2_int,tc_bool_2_int,tc_bool_2_int,
  406. tc_bool_2_int,tc_bool_2_int,tc_only_rangechecks32bit));
  407. var
  408. b : boolean;
  409. hd1,hd2 : pdef;
  410. begin
  411. { safety check }
  412. if not(assigned(def_from) and assigned(def_to)) then
  413. begin
  414. isconvertable:=false;
  415. exit;
  416. end;
  417. b:=false;
  418. { handle ord to ord first }
  419. if (def_from^.deftype=orddef) and (def_to^.deftype=orddef) then
  420. begin
  421. doconv:=basedefconverts[porddef(def_from)^.typ,porddef(def_to)^.typ];
  422. { Don't allow automatic int->bool.
  423. Very Bad Hack !!!! (PFV) }
  424. if (doconv=tc_int_2_bool) and (not explicit) then
  425. b:=false
  426. else
  427. if doconv<>tc_not_possible then
  428. b:=true;
  429. end
  430. else
  431. if (def_from^.deftype=orddef) and (def_to^.deftype=floatdef) then
  432. begin
  433. if pfloatdef(def_to)^.typ=f32bit then
  434. doconv:=tc_int_2_fix
  435. else
  436. doconv:=tc_int_2_real;
  437. b:=true;
  438. end
  439. else
  440. { 2 float types ? }
  441. if (def_from^.deftype=floatdef) and (def_to^.deftype=floatdef) then
  442. begin
  443. if pfloatdef(def_from)^.typ=pfloatdef(def_to)^.typ then
  444. doconv:=tc_equal
  445. else
  446. begin
  447. if pfloatdef(def_from)^.typ=f32bit then
  448. doconv:=tc_fix_2_real
  449. else if pfloatdef(def_to)^.typ=f32bit then
  450. doconv:=tc_real_2_fix
  451. else
  452. doconv:=tc_real_2_real;
  453. { comp isn't a floating type }
  454. {$ifdef i386}
  455. if (pfloatdef(def_to)^.typ=s64bit) and
  456. (pfloatdef(def_from)^.typ<>s64bit) and
  457. not (explicit) then
  458. CGMessage(type_w_convert_real_2_comp);
  459. {$endif}
  460. end;
  461. b:=true;
  462. end
  463. else
  464. { enum to enum }
  465. if (def_from^.deftype=enumdef) and (def_to^.deftype=enumdef) then
  466. begin
  467. if assigned(penumdef(def_from)^.basedef) then
  468. hd1:=penumdef(def_from)^.basedef
  469. else
  470. hd1:=def_from;
  471. if assigned(penumdef(def_to)^.basedef) then
  472. hd2:=penumdef(def_to)^.basedef
  473. else
  474. hd2:=def_to;
  475. b:=(hd1=hd2);
  476. end
  477. else
  478. { assignment overwritten ?? }
  479. if is_assignment_overloaded(def_from,def_to) then
  480. b:=true
  481. else
  482. if (def_from^.deftype=pointerdef) and (def_to^.deftype=arraydef) and
  483. (parraydef(def_to)^.lowrange=0) and
  484. is_equal(ppointerdef(def_from)^.definition,parraydef(def_to)^.definition) then
  485. begin
  486. doconv:=tc_pointer_to_array;
  487. b:=true;
  488. end
  489. else
  490. if (def_from^.deftype=arraydef) and (def_to^.deftype=pointerdef) and
  491. (parraydef(def_from)^.lowrange=0) and
  492. is_equal(parraydef(def_from)^.definition,ppointerdef(def_to)^.definition) then
  493. begin
  494. doconv:=tc_array_to_pointer;
  495. b:=true;
  496. end
  497. else
  498. if (def_from^.deftype=arraydef) and (def_to^.deftype=setdef) and
  499. (parraydef(def_from)^.IsConstructor) then
  500. begin
  501. doconv:=tc_arrayconstructor_2_set;
  502. b:=true;
  503. end
  504. else
  505. { typed files are all equal to the abstract file type
  506. name TYPEDFILE in system.pp in is_equal in types.pas
  507. the problem is that it sholud be also compatible to FILE
  508. but this would leed to a problem for ASSIGN RESET and REWRITE
  509. when trying to find the good overloaded function !!
  510. so all file function are doubled in system.pp
  511. this is not very beautiful !!}
  512. if (def_from^.deftype=filedef) and (def_to^.deftype=filedef) and
  513. (
  514. (
  515. (pfiledef(def_from)^.filetype = ft_typed) and
  516. (pfiledef(def_to)^.filetype = ft_typed) and
  517. (
  518. (pfiledef(def_from)^.typed_as = pdef(voiddef)) or
  519. (pfiledef(def_to)^.typed_as = pdef(voiddef))
  520. )
  521. ) or
  522. (
  523. (
  524. (pfiledef(def_from)^.filetype = ft_untyped) and
  525. (pfiledef(def_to)^.filetype = ft_typed)
  526. ) or
  527. (
  528. (pfiledef(def_from)^.filetype = ft_typed) and
  529. (pfiledef(def_to)^.filetype = ft_untyped)
  530. )
  531. )
  532. ) then
  533. begin
  534. doconv:=tc_equal;
  535. b:=true;
  536. end
  537. else
  538. { object pascal objects }
  539. if (def_from^.deftype=objectdef) and (def_to^.deftype=objectdef) {and
  540. pobjectdef(def_from)^.isclass and pobjectdef(def_to)^.isclass }then
  541. begin
  542. doconv:=tc_equal;
  543. b:=pobjectdef(def_from)^.isrelated(
  544. pobjectdef(def_to));
  545. end
  546. else
  547. { class types and class reference type
  548. can be assigned to void pointers }
  549. if (((def_from^.deftype=objectdef) and
  550. pobjectdef(def_from)^.isclass) or
  551. (def_from^.deftype=classrefdef)
  552. ) and
  553. (def_to^.deftype=pointerdef) and
  554. (ppointerdef(def_to)^.definition^.deftype=orddef) and
  555. (porddef(ppointerdef(def_to)^.definition)^.typ=uvoid) then
  556. begin
  557. doconv:=tc_equal;
  558. b:=true;
  559. end
  560. else
  561. { class reference types }
  562. if (def_from^.deftype=classrefdef) and (def_from^.deftype=classrefdef) then
  563. begin
  564. doconv:=tc_equal;
  565. b:=pobjectdef(pclassrefdef(def_from)^.definition)^.isrelated(
  566. pobjectdef(pclassrefdef(def_to)^.definition));
  567. end
  568. else
  569. if (def_from^.deftype=pointerdef) and (def_to^.deftype=pointerdef) then
  570. begin
  571. { child class pointer can be assigned to anchestor pointers }
  572. if (
  573. (ppointerdef(def_from)^.definition^.deftype=objectdef) and
  574. (ppointerdef(def_to)^.definition^.deftype=objectdef) and
  575. pobjectdef(ppointerdef(def_from)^.definition)^.isrelated(
  576. pobjectdef(ppointerdef(def_to)^.definition))
  577. ) or
  578. { all pointers can be assigned to void-pointer }
  579. is_equal(ppointerdef(def_to)^.definition,voiddef) or
  580. { in my opnion, is this not clean pascal }
  581. { well, but it's handy to use, it isn't ? (FK) }
  582. is_equal(ppointerdef(def_from)^.definition,voiddef) then
  583. begin
  584. doconv:=tc_equal;
  585. b:=true;
  586. end
  587. end
  588. else
  589. if (def_from^.deftype=stringdef) and (def_to^.deftype=stringdef) then
  590. begin
  591. doconv:=tc_string_to_string;
  592. b:=true;
  593. end
  594. else
  595. { char to string}
  596. if is_equal(def_from,cchardef) and (def_to^.deftype=stringdef) then
  597. begin
  598. doconv:=tc_char_to_string;
  599. b:=true;
  600. end
  601. else
  602. { string constant to zero terminated string constant }
  603. if (fromtreetype=stringconstn) and
  604. is_pchar(def_to) then
  605. begin
  606. doconv:=tc_cstring_charpointer;
  607. b:=true;
  608. end
  609. else
  610. { array of char to string, the length check is done by the firstpass of this node }
  611. if (def_from^.deftype=stringdef) and
  612. ((def_to^.deftype=arraydef) and is_equal(parraydef(def_to)^.definition,cchardef)) then
  613. begin
  614. doconv:=tc_string_chararray;
  615. b:=true;
  616. end
  617. else
  618. { string to array of char, the length check is done by the firstpass of this node }
  619. if ((def_from^.deftype=arraydef) and is_equal(parraydef(def_from)^.definition,cchardef)) and
  620. (def_to^.deftype=stringdef) then
  621. begin
  622. doconv:=tc_chararray_2_string;
  623. b:=true;
  624. end
  625. else
  626. if (fromtreetype=ordconstn) and is_equal(def_from,cchardef) then
  627. begin
  628. if (def_to^.deftype=pointerdef) and
  629. is_equal(ppointerdef(def_to)^.definition,cchardef) then
  630. begin
  631. doconv:=tc_cchar_charpointer;
  632. b:=true;
  633. end;
  634. end
  635. else
  636. if (def_to^.deftype=procvardef) and (def_from^.deftype=procdef) then
  637. begin
  638. def_from^.deftype:=procvardef;
  639. doconv:=tc_proc2procvar;
  640. b:=is_equal(def_from,def_to);
  641. def_from^.deftype:=procdef;
  642. end
  643. else
  644. { nil is compatible with class instances }
  645. if (fromtreetype=niln) and (def_to^.deftype=objectdef)
  646. and (pobjectdef(def_to)^.isclass) then
  647. begin
  648. doconv:=tc_equal;
  649. b:=true;
  650. end
  651. else
  652. { nil is compatible with class references }
  653. if (fromtreetype=niln) and (def_to^.deftype=classrefdef) then
  654. begin
  655. doconv:=tc_equal;
  656. b:=true;
  657. end
  658. else
  659. { nil is compatible with procvars }
  660. if (fromtreetype=niln) and (def_to^.deftype=procvardef) then
  661. begin
  662. doconv:=tc_equal;
  663. b:=true;
  664. end
  665. else
  666. { nil is compatible with ansi- and wide strings }
  667. { no, that isn't true, (FK)
  668. if (fromtreetype=niln) and (def_to^.deftype=stringdef)
  669. and (pstringdef(def_to)^.string_typ in [st_ansistring,st_widestring]) then
  670. begin
  671. doconv:=tc_equal;
  672. b:=true;
  673. end
  674. else
  675. }
  676. { ansi- and wide strings can be assigned to void pointers }
  677. { no, (FK)
  678. if (def_from^.deftype=stringdef) and
  679. (pstringdef(def_from)^.string_typ in [st_ansistring,st_widestring]) and
  680. (def_to^.deftype=pointerdef) and
  681. (ppointerdef(def_to)^.definition^.deftype=orddef) and
  682. (porddef(ppointerdef(def_to)^.definition)^.typ=uvoid) then
  683. begin
  684. doconv:=tc_equal;
  685. b:=true;
  686. end
  687. else
  688. }
  689. { ansistrings can be assigned to pchar
  690. this needs an explicit type cast (FK)
  691. if is_ansistring(def_from) and
  692. (def_to^.deftype=pointerdef) and
  693. (ppointerdef(def_to)^.definition^.deftype=orddef) and
  694. (porddef(ppointerdef(def_to)^.definition)^.typ=uchar) then
  695. begin
  696. doconv:=tc_ansistring_2_pchar;
  697. b:=true;
  698. end
  699. else
  700. }
  701. { pchar can be assigned to short/ansistrings }
  702. if (def_to^.deftype=stringdef) and
  703. ((def_from^.deftype=pointerdef) and
  704. (ppointerdef(def_from)^.definition^.deftype=orddef) and
  705. (porddef(ppointerdef(def_from)^.definition)^.typ=uchar)) then
  706. begin
  707. if (pstringdef(def_to)^.string_typ in [st_shortstring,st_ansistring]) then
  708. begin
  709. doconv:=tc_pchar_2_string;
  710. b:=true;
  711. end;
  712. end
  713. else
  714. { procedure variable can be assigned to an void pointer }
  715. { Not anymore. Use the @ operator now.}
  716. if not (cs_tp_compatible in aktmoduleswitches) then
  717. begin
  718. if (def_from^.deftype=procvardef) and
  719. (def_to^.deftype=pointerdef) and
  720. (ppointerdef(def_to)^.definition^.deftype=orddef) and
  721. (porddef(ppointerdef(def_to)^.definition)^.typ=uvoid) then
  722. begin
  723. doconv:=tc_equal;
  724. b:=true;
  725. end;
  726. end;
  727. isconvertable:=b;
  728. end;
  729. procedure firsterror(var p : ptree);
  730. begin
  731. p^.error:=true;
  732. codegenerror:=true;
  733. p^.resulttype:=generrordef;
  734. end;
  735. procedure firstload(var p : ptree);
  736. begin
  737. p^.location.loc:=LOC_REFERENCE;
  738. p^.registers32:=0;
  739. p^.registersfpu:=0;
  740. {$ifdef SUPPORT_MMX}
  741. p^.registersmmx:=0;
  742. {$endif SUPPORT_MMX}
  743. clear_reference(p^.location.reference);
  744. if p^.symtableentry^.typ=funcretsym then
  745. begin
  746. putnode(p);
  747. p:=genzeronode(funcretn);
  748. p^.funcretprocinfo:=pprocinfo(pfuncretsym(p^.symtableentry)^.funcretprocinfo);
  749. p^.retdef:=pfuncretsym(p^.symtableentry)^.funcretdef;
  750. firstpass(p);
  751. exit;
  752. end;
  753. if p^.symtableentry^.typ=absolutesym then
  754. begin
  755. p^.resulttype:=pabsolutesym(p^.symtableentry)^.definition;
  756. if pabsolutesym(p^.symtableentry)^.abstyp=tovar then
  757. p^.symtableentry:=pabsolutesym(p^.symtableentry)^.ref;
  758. p^.symtable:=p^.symtableentry^.owner;
  759. p^.is_absolute:=true;
  760. end;
  761. case p^.symtableentry^.typ of
  762. absolutesym :;
  763. varsym :
  764. begin
  765. if not(p^.is_absolute) and (p^.resulttype=nil) then
  766. p^.resulttype:=pvarsym(p^.symtableentry)^.definition;
  767. if ((p^.symtable^.symtabletype=parasymtable) or
  768. (p^.symtable^.symtabletype=localsymtable)) and
  769. (lexlevel>p^.symtable^.symtablelevel) then
  770. begin
  771. { sollte sich die Variable in einem anderen Stackframe }
  772. { befinden, so brauchen wir ein Register zum Dereferenceieren }
  773. if (p^.symtable^.symtablelevel)>0 then
  774. begin
  775. p^.registers32:=1;
  776. { further, the variable can't be put into a register }
  777. pvarsym(p^.symtableentry)^.var_options:=
  778. pvarsym(p^.symtableentry)^.var_options and not vo_regable;
  779. end;
  780. end;
  781. if (pvarsym(p^.symtableentry)^.varspez=vs_const) then
  782. p^.location.loc:=LOC_MEM;
  783. { we need a register for call by reference parameters }
  784. if (pvarsym(p^.symtableentry)^.varspez=vs_var) or
  785. ((pvarsym(p^.symtableentry)^.varspez=vs_const) and
  786. dont_copy_const_param(pvarsym(p^.symtableentry)^.definition)
  787. ) or
  788. { call by value open arrays are also indirect addressed }
  789. is_open_array(pvarsym(p^.symtableentry)^.definition) then
  790. p^.registers32:=1;
  791. if p^.symtable^.symtabletype=withsymtable then
  792. inc(p^.registers32);
  793. { a class variable is a pointer !!!
  794. yes, but we have to resolve the reference in an
  795. appropriate tree node (FK)
  796. if (pvarsym(p^.symtableentry)^.definition^.deftype=objectdef) and
  797. ((pobjectdef(pvarsym(p^.symtableentry)^.definition)^.options and oois_class)<>0) then
  798. p^.registers32:=1;
  799. }
  800. { count variable references }
  801. if must_be_valid and p^.is_first then
  802. begin
  803. if pvarsym(p^.symtableentry)^.is_valid=2 then
  804. if (assigned(pvarsym(p^.symtableentry)^.owner) and assigned(aktprocsym)
  805. and (pvarsym(p^.symtableentry)^.owner = aktprocsym^.definition^.localst)) then
  806. CGMessage1(sym_n_uninitialized_local_variable,pvarsym(p^.symtableentry)^.name);
  807. end;
  808. if count_ref then
  809. begin
  810. if (p^.is_first) then
  811. begin
  812. if (pvarsym(p^.symtableentry)^.is_valid=2) then
  813. pvarsym(p^.symtableentry)^.is_valid:=1;
  814. p^.is_first:=false;
  815. end;
  816. end;
  817. { this will create problem with local var set by
  818. under_procedures
  819. if (assigned(pvarsym(p^.symtableentry)^.owner) and assigned(aktprocsym)
  820. and ((pvarsym(p^.symtableentry)^.owner = aktprocsym^.definition^.localst)
  821. or (pvarsym(p^.symtableentry)^.owner = aktprocsym^.definition^.localst))) then }
  822. if t_times<1 then
  823. inc(pvarsym(p^.symtableentry)^.refs)
  824. else
  825. inc(pvarsym(p^.symtableentry)^.refs,t_times);
  826. end;
  827. typedconstsym :
  828. if not p^.is_absolute then
  829. p^.resulttype:=ptypedconstsym(p^.symtableentry)^.definition;
  830. procsym :
  831. begin
  832. if assigned(pprocsym(p^.symtableentry)^.definition^.nextoverloaded) then
  833. CGMessage(parser_e_no_overloaded_procvars);
  834. p^.resulttype:=pprocsym(p^.symtableentry)^.definition;
  835. end;
  836. else internalerror(3);
  837. end;
  838. end;
  839. procedure firstadd(var p : ptree);
  840. procedure make_bool_equal_size(var p:ptree);
  841. begin
  842. if porddef(p^.left^.resulttype)^.typ>porddef(p^.right^.resulttype)^.typ then
  843. begin
  844. p^.right:=gentypeconvnode(p^.right,porddef(p^.left^.resulttype));
  845. p^.right^.convtyp:=tc_bool_2_int;
  846. p^.right^.explizit:=true;
  847. firstpass(p^.right);
  848. end
  849. else
  850. if porddef(p^.left^.resulttype)^.typ<porddef(p^.right^.resulttype)^.typ then
  851. begin
  852. p^.left:=gentypeconvnode(p^.left,porddef(p^.right^.resulttype));
  853. p^.left^.convtyp:=tc_bool_2_int;
  854. p^.left^.explizit:=true;
  855. firstpass(p^.left);
  856. end;
  857. end;
  858. var
  859. t : ptree;
  860. lt,rt : ttreetyp;
  861. rv,lv : longint;
  862. rvd,lvd : bestreal;
  863. rd,ld : pdef;
  864. tempdef : pdef;
  865. concatstrings : boolean;
  866. { to evalute const sets }
  867. resultset : pconstset;
  868. i : longint;
  869. b : boolean;
  870. convdone : boolean;
  871. {$ifndef UseAnsiString}
  872. s1,s2:^string;
  873. {$else UseAnsiString}
  874. s1,s2 : pchar;
  875. l1,l2 : longint;
  876. {$endif UseAnsiString}
  877. { this totally forgets to set the pi_do_call flag !! }
  878. label
  879. no_overload;
  880. begin
  881. { first do the two subtrees }
  882. firstpass(p^.left);
  883. firstpass(p^.right);
  884. lt:=p^.left^.treetype;
  885. rt:=p^.right^.treetype;
  886. rd:=p^.right^.resulttype;
  887. ld:=p^.left^.resulttype;
  888. convdone:=false;
  889. if codegenerror then
  890. exit;
  891. { overloaded operator ? }
  892. if (p^.treetype=starstarn) or
  893. (ld^.deftype=recorddef) or
  894. { <> and = are defined for classes }
  895. ((ld^.deftype=objectdef) and
  896. (not(pobjectdef(ld)^.isclass) or
  897. not(p^.treetype in [equaln,unequaln])
  898. )
  899. ) or
  900. (rd^.deftype=recorddef) or
  901. { <> and = are defined for classes }
  902. ((rd^.deftype=objectdef) and
  903. (not(pobjectdef(rd)^.isclass) or
  904. not(p^.treetype in [equaln,unequaln])
  905. )
  906. ) then
  907. begin
  908. {!!!!!!!!! handle paras }
  909. case p^.treetype of
  910. { the nil as symtable signs firstcalln that this is
  911. an overloaded operator }
  912. addn:
  913. t:=gencallnode(overloaded_operators[plus],nil);
  914. subn:
  915. t:=gencallnode(overloaded_operators[minus],nil);
  916. muln:
  917. t:=gencallnode(overloaded_operators[star],nil);
  918. starstarn:
  919. t:=gencallnode(overloaded_operators[starstar],nil);
  920. slashn:
  921. t:=gencallnode(overloaded_operators[slash],nil);
  922. ltn:
  923. t:=gencallnode(overloaded_operators[globals.lt],nil);
  924. gtn:
  925. t:=gencallnode(overloaded_operators[gt],nil);
  926. lten:
  927. t:=gencallnode(overloaded_operators[lte],nil);
  928. gten:
  929. t:=gencallnode(overloaded_operators[gte],nil);
  930. equaln,unequaln :
  931. t:=gencallnode(overloaded_operators[equal],nil);
  932. else goto no_overload;
  933. end;
  934. { we have to convert p^.left and p^.right into
  935. callparanodes }
  936. t^.left:=gencallparanode(p^.left,nil);
  937. t^.left:=gencallparanode(p^.right,t^.left);
  938. if t^.symtableprocentry=nil then
  939. CGMessage(parser_e_operator_not_overloaded);
  940. if p^.treetype=unequaln then
  941. t:=gensinglenode(notn,t);
  942. firstpass(t);
  943. putnode(p);
  944. p:=t;
  945. exit;
  946. end;
  947. no_overload:
  948. { compact consts }
  949. { convert int consts to real consts, if the }
  950. { other operand is a real const }
  951. if (rt=realconstn) and is_constintnode(p^.left) then
  952. begin
  953. t:=genrealconstnode(p^.left^.value);
  954. disposetree(p^.left);
  955. p^.left:=t;
  956. lt:=realconstn;
  957. end;
  958. if (lt=realconstn) and is_constintnode(p^.right) then
  959. begin
  960. t:=genrealconstnode(p^.right^.value);
  961. disposetree(p^.right);
  962. p^.right:=t;
  963. rt:=realconstn;
  964. end;
  965. { both are int constants ? }
  966. if is_constintnode(p^.left) and is_constintnode(p^.right) then
  967. begin
  968. lv:=p^.left^.value;
  969. rv:=p^.right^.value;
  970. case p^.treetype of
  971. addn : t:=genordinalconstnode(lv+rv,s32bitdef);
  972. subn : t:=genordinalconstnode(lv-rv,s32bitdef);
  973. muln : t:=genordinalconstnode(lv*rv,s32bitdef);
  974. xorn : t:=genordinalconstnode(lv xor rv,s32bitdef);
  975. orn : t:=genordinalconstnode(lv or rv,s32bitdef);
  976. andn : t:=genordinalconstnode(lv and rv,s32bitdef);
  977. ltn : t:=genordinalconstnode(ord(lv<rv),booldef);
  978. lten : t:=genordinalconstnode(ord(lv<=rv),booldef);
  979. gtn : t:=genordinalconstnode(ord(lv>rv),booldef);
  980. gten : t:=genordinalconstnode(ord(lv>=rv),booldef);
  981. equaln : t:=genordinalconstnode(ord(lv=rv),booldef);
  982. unequaln : t:=genordinalconstnode(ord(lv<>rv),booldef);
  983. slashn : begin
  984. { int/int becomes a real }
  985. t:=genrealconstnode(int(lv)/int(rv));
  986. firstpass(t);
  987. end;
  988. else
  989. CGMessage(type_e_mismatch);
  990. end;
  991. disposetree(p);
  992. firstpass(t);
  993. p:=t;
  994. exit;
  995. end;
  996. { both real constants ? }
  997. if (lt=realconstn) and (rt=realconstn) then
  998. begin
  999. lvd:=p^.left^.value_real;
  1000. rvd:=p^.right^.value_real;
  1001. case p^.treetype of
  1002. addn : t:=genrealconstnode(lvd+rvd);
  1003. subn : t:=genrealconstnode(lvd-rvd);
  1004. muln : t:=genrealconstnode(lvd*rvd);
  1005. caretn : t:=genrealconstnode(exp(ln(lvd)*rvd));
  1006. slashn : t:=genrealconstnode(lvd/rvd);
  1007. ltn : t:=genordinalconstnode(ord(lvd<rvd),booldef);
  1008. lten : t:=genordinalconstnode(ord(lvd<=rvd),booldef);
  1009. gtn : t:=genordinalconstnode(ord(lvd>rvd),booldef);
  1010. gten : t:=genordinalconstnode(ord(lvd>=rvd),booldef);
  1011. equaln : t:=genordinalconstnode(ord(lvd=rvd),booldef);
  1012. unequaln : t:=genordinalconstnode(ord(lvd<>rvd),booldef);
  1013. else
  1014. CGMessage(type_e_mismatch);
  1015. end;
  1016. disposetree(p);
  1017. p:=t;
  1018. firstpass(p);
  1019. exit;
  1020. end;
  1021. { concating strings ? }
  1022. concatstrings:=false;
  1023. {$ifdef UseAnsiString}
  1024. s1:=nil;
  1025. s2:=nil;
  1026. {$else UseAnsiString}
  1027. new(s1);
  1028. new(s2);
  1029. {$endif UseAnsiString}
  1030. if (lt=ordconstn) and (rt=ordconstn) and
  1031. (ld^.deftype=orddef) and (porddef(ld)^.typ=uchar) and
  1032. (rd^.deftype=orddef) and (porddef(rd)^.typ=uchar) then
  1033. begin
  1034. {$ifdef UseAnsiString}
  1035. s1:=strpnew(char(byte(p^.left^.value)));
  1036. s2:=strpnew(char(byte(p^.right^.value)));
  1037. l1:=1;l2:=1;
  1038. {$else UseAnsiString}
  1039. s1^:=char(byte(p^.left^.value));
  1040. s2^:=char(byte(p^.right^.value));
  1041. {$endif UseAnsiString}
  1042. concatstrings:=true;
  1043. end
  1044. else
  1045. if (lt=stringconstn) and (rt=ordconstn) and
  1046. (rd^.deftype=orddef) and (porddef(rd)^.typ=uchar) then
  1047. begin
  1048. {$ifdef UseAnsiString}
  1049. { here there is allways the damn #0 problem !! }
  1050. s1:=getpcharcopy(p^.left);
  1051. l1:=p^.left^.length;
  1052. s2:=strpnew(char(byte(p^.right^.value)));
  1053. l2:=1;
  1054. {$else UseAnsiString}
  1055. s1^:=p^.left^.value_str^;
  1056. s2^:=char(byte(p^.right^.value));
  1057. {$endif UseAnsiString}
  1058. concatstrings:=true;
  1059. end
  1060. else if (lt=ordconstn) and (rt=stringconstn) and
  1061. (ld^.deftype=orddef) and
  1062. (porddef(ld)^.typ=uchar) then
  1063. begin
  1064. {$ifdef UseAnsiString}
  1065. { here there is allways the damn #0 problem !! }
  1066. s1:=strpnew(char(byte(p^.left^.value)));
  1067. l1:=1;
  1068. s2:=getpcharcopy(p^.right);
  1069. l2:=p^.right^.length;
  1070. {$else UseAnsiString}
  1071. s1^:=char(byte(p^.left^.value));
  1072. s2^:=p^.right^.value_str^;
  1073. {$endif UseAnsiString}
  1074. concatstrings:=true;
  1075. end
  1076. else if (lt=stringconstn) and (rt=stringconstn) then
  1077. begin
  1078. {$ifdef UseAnsiString}
  1079. s1:=getpcharcopy(p^.left);
  1080. l1:=p^.left^.length;
  1081. s2:=getpcharcopy(p^.right);
  1082. l2:=p^.right^.length;
  1083. {$else UseAnsiString}
  1084. s1^:=p^.left^.value_str^;
  1085. s2^:=p^.right^.value_str^;
  1086. {$endif UseAnsiString}
  1087. concatstrings:=true;
  1088. end;
  1089. { I will need to translate all this to ansistrings !!! }
  1090. if concatstrings then
  1091. begin
  1092. case p^.treetype of
  1093. {$ifndef UseAnsiString}
  1094. addn : t:=genstringconstnode(s1^+s2^);
  1095. ltn : t:=genordinalconstnode(byte(s1^<s2^),booldef);
  1096. lten : t:=genordinalconstnode(byte(s1^<=s2^),booldef);
  1097. gtn : t:=genordinalconstnode(byte(s1^>s2^),booldef);
  1098. gten : t:=genordinalconstnode(byte(s1^>=s2^),booldef);
  1099. equaln : t:=genordinalconstnode(byte(s1^=s2^),booldef);
  1100. unequaln : t:=genordinalconstnode(byte(s1^<>s2^),booldef);
  1101. {$else UseAnsiString}
  1102. addn : t:=genpcharconstnode(
  1103. concatansistrings(s1,s2,l1,l2),l1+l2);
  1104. ltn : t:=genordinalconstnode(
  1105. byte(compareansistrings(s1,s2,l1,l2)<0),booldef);
  1106. lten : t:=genordinalconstnode(
  1107. byte(compareansistrings(s1,s2,l1,l2)<=0),booldef);
  1108. gtn : t:=genordinalconstnode(
  1109. byte(compareansistrings(s1,s2,l1,l2)>0),booldef);
  1110. gten : t:=genordinalconstnode(
  1111. byte(compareansistrings(s1,s2,l1,l2)>=0),booldef);
  1112. equaln : t:=genordinalconstnode(
  1113. byte(compareansistrings(s1,s2,l1,l2)=0),booldef);
  1114. unequaln : t:=genordinalconstnode(
  1115. byte(compareansistrings(s1,s2,l1,l2)<>0),booldef);
  1116. {$endif UseAnsiString}
  1117. end;
  1118. {$ifdef UseAnsiString}
  1119. ansistringdispose(s1,l1);
  1120. ansistringdispose(s2,l2);
  1121. {$else UseAnsiString}
  1122. dispose(s1);
  1123. dispose(s2);
  1124. {$endif UseAnsiString}
  1125. disposetree(p);
  1126. firstpass(t);
  1127. p:=t;
  1128. exit;
  1129. end;
  1130. {$ifdef UseAnsiString}
  1131. ansistringdispose(s1,l1);
  1132. ansistringdispose(s2,l2);
  1133. {$else UseAnsiString}
  1134. dispose(s1);
  1135. dispose(s2);
  1136. {$endif UseAnsiString}
  1137. { if both are orddefs then check sub types }
  1138. if (ld^.deftype=orddef) and (rd^.deftype=orddef) then
  1139. begin
  1140. { 2 booleans ? }
  1141. if (porddef(ld)^.typ in [bool8bit,bool16bit,bool32bit]) and
  1142. (porddef(rd)^.typ in [bool8bit,bool16bit,bool32bit]) then
  1143. begin
  1144. case p^.treetype of
  1145. andn,orn : begin
  1146. calcregisters(p,0,0,0);
  1147. p^.location.loc:=LOC_JUMP;
  1148. end;
  1149. unequaln,
  1150. equaln,xorn : begin
  1151. { this forces a better code generation (TEST }
  1152. { instead of CMP) }
  1153. if p^.treetype<>xorn then
  1154. begin
  1155. if (p^.left^.treetype=ordconstn) and
  1156. (p^.left^.value<>0) then
  1157. begin
  1158. p^.left^.value:=0;
  1159. if p^.treetype=equaln then
  1160. p^.treetype:=unequaln
  1161. else
  1162. p^.treetype:=equaln;
  1163. end;
  1164. if (p^.right^.treetype=ordconstn) and
  1165. (p^.right^.value<>0) then
  1166. begin
  1167. p^.right^.value:=0;
  1168. if p^.treetype=equaln then
  1169. p^.treetype:=unequaln
  1170. else
  1171. p^.treetype:=equaln;
  1172. end;
  1173. end;
  1174. make_bool_equal_size(p);
  1175. calcregisters(p,1,0,0);
  1176. end
  1177. else
  1178. CGMessage(type_e_mismatch);
  1179. end;
  1180. convdone:=true;
  1181. end
  1182. else
  1183. { Both are chars? only convert to strings for addn }
  1184. if (porddef(rd)^.typ=uchar) and (porddef(ld)^.typ=uchar) then
  1185. begin
  1186. if p^.treetype=addn then
  1187. begin
  1188. p^.left:=gentypeconvnode(p^.left,cstringdef);
  1189. firstpass(p^.left);
  1190. p^.right:=gentypeconvnode(p^.right,cstringdef);
  1191. firstpass(p^.right);
  1192. { here we call STRCOPY }
  1193. procinfo.flags:=procinfo.flags or pi_do_call;
  1194. calcregisters(p,0,0,0);
  1195. p^.location.loc:=LOC_MEM;
  1196. end
  1197. else
  1198. calcregisters(p,1,0,0);
  1199. convdone:=true;
  1200. end;
  1201. end
  1202. else
  1203. { is one of the sides a shortstring ? }
  1204. if (rd^.deftype=stringdef) or (ld^.deftype=stringdef) then
  1205. begin
  1206. {
  1207. if is_widestring(rd) or is_widestring(ld) then
  1208. begin
  1209. end
  1210. else if is_ansistring(rd) or is_ansistring(ld) then
  1211. begin
  1212. end
  1213. else if is_longstring(rd) or is_longstring(ld) then
  1214. begin
  1215. end
  1216. }
  1217. if not((rd^.deftype=stringdef) and (ld^.deftype=stringdef)) then
  1218. begin
  1219. if ld^.deftype=stringdef then
  1220. p^.right:=gentypeconvnode(p^.right,cstringdef)
  1221. else
  1222. p^.left:=gentypeconvnode(p^.left,cstringdef);
  1223. firstpass(p^.left);
  1224. firstpass(p^.right);
  1225. end;
  1226. { here we call STRCONCAT or STRCMP or STRCOPY }
  1227. procinfo.flags:=procinfo.flags or pi_do_call;
  1228. calcregisters(p,0,0,0);
  1229. p^.location.loc:=LOC_MEM;
  1230. convdone:=true;
  1231. end
  1232. else
  1233. { left side a setdef ? }
  1234. if (ld^.deftype=setdef) then
  1235. begin
  1236. { right site must also be a setdef, unless addn is used }
  1237. if not(p^.treetype in [subn,symdifn,addn,muln,equaln,unequaln]) or
  1238. ((rd^.deftype<>setdef) and (p^.treetype<>addn)) then
  1239. CGMessage(type_e_mismatch);
  1240. if ((rd^.deftype=setdef) and not(is_equal(rd,ld))) and
  1241. not((rt=setelementn) and is_equal(psetdef(ld)^.setof,rd)) then
  1242. CGMessage(type_e_set_element_are_not_comp);
  1243. { ranges require normsets }
  1244. if (psetdef(ld)^.settype=smallset) and
  1245. (rt=setelementn) and
  1246. assigned(p^.right^.right) then
  1247. begin
  1248. { generate a temporary normset def }
  1249. tempdef:=new(psetdef,init(psetdef(ld)^.setof,255));
  1250. p^.left:=gentypeconvnode(p^.left,tempdef);
  1251. firstpass(p^.left);
  1252. dispose(tempdef,done);
  1253. ld:=p^.left^.resulttype;
  1254. end;
  1255. { if the destination is not a smallset then insert a typeconv
  1256. which loads a smallset into a normal set }
  1257. if (psetdef(ld)^.settype<>smallset) and
  1258. (psetdef(rd)^.settype=smallset) then
  1259. begin
  1260. p^.right:=gentypeconvnode(p^.right,psetdef(p^.left^.resulttype));
  1261. firstpass(p^.right);
  1262. end;
  1263. { do constant evalution }
  1264. if (p^.right^.treetype=setconstn) and
  1265. (p^.left^.treetype=setconstn) then
  1266. begin
  1267. new(resultset);
  1268. case p^.treetype of
  1269. addn : begin
  1270. for i:=0 to 31 do
  1271. resultset^[i]:=
  1272. p^.right^.value_set^[i] or p^.left^.value_set^[i];
  1273. t:=gensetconstnode(resultset,psetdef(ld));
  1274. end;
  1275. muln : begin
  1276. for i:=0 to 31 do
  1277. resultset^[i]:=
  1278. p^.right^.value_set^[i] and p^.left^.value_set^[i];
  1279. t:=gensetconstnode(resultset,psetdef(ld));
  1280. end;
  1281. subn : begin
  1282. for i:=0 to 31 do
  1283. resultset^[i]:=
  1284. p^.left^.value_set^[i] and not(p^.right^.value_set^[i]);
  1285. t:=gensetconstnode(resultset,psetdef(ld));
  1286. end;
  1287. symdifn : begin
  1288. for i:=0 to 31 do
  1289. resultset^[i]:=
  1290. p^.left^.value_set^[i] xor p^.right^.value_set^[i];
  1291. t:=gensetconstnode(resultset,psetdef(ld));
  1292. end;
  1293. unequaln : begin
  1294. b:=true;
  1295. for i:=0 to 31 do
  1296. if p^.right^.value_set^[i]=p^.left^.value_set^[i] then
  1297. begin
  1298. b:=false;
  1299. break;
  1300. end;
  1301. t:=genordinalconstnode(ord(b),booldef);
  1302. end;
  1303. equaln : begin
  1304. b:=true;
  1305. for i:=0 to 31 do
  1306. if p^.right^.value_set^[i]<>p^.left^.value_set^[i] then
  1307. begin
  1308. b:=false;
  1309. break;
  1310. end;
  1311. t:=genordinalconstnode(ord(b),booldef);
  1312. end;
  1313. end;
  1314. dispose(resultset);
  1315. disposetree(p);
  1316. p:=t;
  1317. firstpass(p);
  1318. exit;
  1319. end
  1320. else
  1321. if psetdef(ld)^.settype=smallset then
  1322. begin
  1323. calcregisters(p,1,0,0);
  1324. p^.location.loc:=LOC_REGISTER;
  1325. end
  1326. else
  1327. begin
  1328. calcregisters(p,0,0,0);
  1329. { here we call SET... }
  1330. procinfo.flags:=procinfo.flags or pi_do_call;
  1331. p^.location.loc:=LOC_MEM;
  1332. end;
  1333. convdone:=true;
  1334. end
  1335. else
  1336. { is one a real float ? }
  1337. if (rd^.deftype=floatdef) or (ld^.deftype=floatdef) then
  1338. begin
  1339. { if one is a fixed, then convert to f32bit }
  1340. if ((rd^.deftype=floatdef) and (pfloatdef(rd)^.typ=f32bit)) or
  1341. ((ld^.deftype=floatdef) and (pfloatdef(ld)^.typ=f32bit)) then
  1342. begin
  1343. if not(porddef(rd)^.typ in [u8bit,s8bit,u16bit,s16bit,s32bit,u32bit]) or (p^.treetype<>muln) then
  1344. p^.right:=gentypeconvnode(p^.right,s32fixeddef);
  1345. if not(porddef(rd)^.typ in [u8bit,s8bit,u16bit,s16bit,s32bit,u32bit]) or (p^.treetype<>muln) then
  1346. p^.left:=gentypeconvnode(p^.left,s32fixeddef);
  1347. firstpass(p^.left);
  1348. firstpass(p^.right);
  1349. calcregisters(p,1,0,0);
  1350. p^.location.loc:=LOC_REGISTER;
  1351. end
  1352. else
  1353. { convert both to c64float }
  1354. begin
  1355. p^.right:=gentypeconvnode(p^.right,c64floatdef);
  1356. p^.left:=gentypeconvnode(p^.left,c64floatdef);
  1357. firstpass(p^.left);
  1358. firstpass(p^.right);
  1359. calcregisters(p,1,1,0);
  1360. p^.location.loc:=LOC_FPU;
  1361. end;
  1362. convdone:=true;
  1363. end
  1364. else
  1365. { pointer comperation and subtraction }
  1366. if (rd^.deftype=pointerdef) and (ld^.deftype=pointerdef) then
  1367. begin
  1368. p^.location.loc:=LOC_REGISTER;
  1369. p^.right:=gentypeconvnode(p^.right,ld);
  1370. firstpass(p^.right);
  1371. calcregisters(p,1,0,0);
  1372. case p^.treetype of
  1373. equaln,unequaln : ;
  1374. ltn,lten,gtn,gten:
  1375. begin
  1376. if not(cs_extsyntax in aktmoduleswitches) then
  1377. CGMessage(type_e_mismatch);
  1378. end;
  1379. subn:
  1380. begin
  1381. if not(cs_extsyntax in aktmoduleswitches) then
  1382. CGMessage(type_e_mismatch);
  1383. p^.resulttype:=s32bitdef;
  1384. exit;
  1385. end;
  1386. else CGMessage(type_e_mismatch);
  1387. end;
  1388. convdone:=true;
  1389. end
  1390. else
  1391. if (rd^.deftype=objectdef) and (ld^.deftype=objectdef) and
  1392. pobjectdef(rd)^.isclass and pobjectdef(ld)^.isclass then
  1393. begin
  1394. p^.location.loc:=LOC_REGISTER;
  1395. if pobjectdef(rd)^.isrelated(pobjectdef(ld)) then
  1396. p^.right:=gentypeconvnode(p^.right,ld)
  1397. else
  1398. p^.left:=gentypeconvnode(p^.left,rd);
  1399. firstpass(p^.right);
  1400. firstpass(p^.left);
  1401. calcregisters(p,1,0,0);
  1402. case p^.treetype of
  1403. equaln,unequaln : ;
  1404. else CGMessage(type_e_mismatch);
  1405. end;
  1406. convdone:=true;
  1407. end
  1408. else
  1409. if (rd^.deftype=classrefdef) and (ld^.deftype=classrefdef) then
  1410. begin
  1411. p^.location.loc:=LOC_REGISTER;
  1412. if pobjectdef(pclassrefdef(rd)^.definition)^.isrelated(pobjectdef(
  1413. pclassrefdef(ld)^.definition)) then
  1414. p^.right:=gentypeconvnode(p^.right,ld)
  1415. else
  1416. p^.left:=gentypeconvnode(p^.left,rd);
  1417. firstpass(p^.right);
  1418. firstpass(p^.left);
  1419. calcregisters(p,1,0,0);
  1420. case p^.treetype of
  1421. equaln,unequaln : ;
  1422. else CGMessage(type_e_mismatch);
  1423. end;
  1424. convdone:=true;
  1425. end
  1426. else
  1427. { allows comperasion with nil pointer }
  1428. if (rd^.deftype=objectdef) and
  1429. pobjectdef(rd)^.isclass then
  1430. begin
  1431. p^.location.loc:=LOC_REGISTER;
  1432. p^.left:=gentypeconvnode(p^.left,rd);
  1433. firstpass(p^.left);
  1434. calcregisters(p,1,0,0);
  1435. case p^.treetype of
  1436. equaln,unequaln : ;
  1437. else CGMessage(type_e_mismatch);
  1438. end;
  1439. convdone:=true;
  1440. end
  1441. else
  1442. if (ld^.deftype=objectdef) and
  1443. pobjectdef(ld)^.isclass then
  1444. begin
  1445. p^.location.loc:=LOC_REGISTER;
  1446. p^.right:=gentypeconvnode(p^.right,ld);
  1447. firstpass(p^.right);
  1448. calcregisters(p,1,0,0);
  1449. case p^.treetype of
  1450. equaln,unequaln : ;
  1451. else CGMessage(type_e_mismatch);
  1452. end;
  1453. convdone:=true;
  1454. end
  1455. else
  1456. if (rd^.deftype=classrefdef) then
  1457. begin
  1458. p^.left:=gentypeconvnode(p^.left,rd);
  1459. firstpass(p^.left);
  1460. calcregisters(p,1,0,0);
  1461. case p^.treetype of
  1462. equaln,unequaln : ;
  1463. else CGMessage(type_e_mismatch);
  1464. end;
  1465. convdone:=true;
  1466. end
  1467. else
  1468. if (ld^.deftype=classrefdef) then
  1469. begin
  1470. p^.right:=gentypeconvnode(p^.right,ld);
  1471. firstpass(p^.right);
  1472. calcregisters(p,1,0,0);
  1473. case p^.treetype of
  1474. equaln,unequaln : ;
  1475. else
  1476. CGMessage(type_e_mismatch);
  1477. end;
  1478. convdone:=true;
  1479. end
  1480. else
  1481. if (rd^.deftype=pointerdef) then
  1482. begin
  1483. p^.location.loc:=LOC_REGISTER;
  1484. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  1485. firstpass(p^.left);
  1486. calcregisters(p,1,0,0);
  1487. if p^.treetype=addn then
  1488. begin
  1489. if not(cs_extsyntax in aktmoduleswitches) then
  1490. CGMessage(type_e_mismatch);
  1491. end
  1492. else
  1493. CGMessage(type_e_mismatch);
  1494. convdone:=true;
  1495. end
  1496. else
  1497. if (ld^.deftype=pointerdef) then
  1498. begin
  1499. p^.location.loc:=LOC_REGISTER;
  1500. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  1501. firstpass(p^.right);
  1502. calcregisters(p,1,0,0);
  1503. case p^.treetype of
  1504. addn,subn : if not(cs_extsyntax in aktmoduleswitches) then
  1505. CGMessage(type_e_mismatch);
  1506. else
  1507. CGMessage(type_e_mismatch);
  1508. end;
  1509. convdone:=true;
  1510. end
  1511. else
  1512. if (rd^.deftype=procvardef) and (ld^.deftype=procvardef) and is_equal(rd,ld) then
  1513. begin
  1514. calcregisters(p,1,0,0);
  1515. p^.location.loc:=LOC_REGISTER;
  1516. case p^.treetype of
  1517. equaln,unequaln : ;
  1518. else
  1519. CGMessage(type_e_mismatch);
  1520. end;
  1521. convdone:=true;
  1522. end
  1523. else
  1524. {$ifdef SUPPORT_MMX}
  1525. if (cs_mmx in aktlocalswitches) and is_mmx_able_array(ld) and
  1526. is_mmx_able_array(rd) and is_equal(ld,rd) then
  1527. begin
  1528. firstpass(p^.right);
  1529. firstpass(p^.left);
  1530. case p^.treetype of
  1531. addn,subn,xorn,orn,andn:
  1532. ;
  1533. { mul is a little bit restricted }
  1534. muln:
  1535. if not(mmx_type(p^.left^.resulttype) in
  1536. [mmxu16bit,mmxs16bit,mmxfixed16]) then
  1537. CGMessage(type_e_mismatch);
  1538. else
  1539. CGMessage(type_e_mismatch);
  1540. end;
  1541. p^.location.loc:=LOC_MMXREGISTER;
  1542. calcregisters(p,0,0,1);
  1543. convdone:=true;
  1544. end
  1545. else
  1546. {$endif SUPPORT_MMX}
  1547. if (ld^.deftype=enumdef) and (rd^.deftype=enumdef) and (is_equal(ld,rd)) then
  1548. begin
  1549. calcregisters(p,1,0,0);
  1550. case p^.treetype of
  1551. equaln,unequaln,
  1552. ltn,lten,gtn,gten : ;
  1553. else CGMessage(type_e_mismatch);
  1554. end;
  1555. convdone:=true;
  1556. end;
  1557. { the general solution is to convert to 32 bit int }
  1558. if not convdone then
  1559. begin
  1560. { but an int/int gives real/real! }
  1561. if p^.treetype=slashn then
  1562. begin
  1563. CGMessage(type_w_int_slash_int);
  1564. CGMessage(type_h_use_div_for_int);
  1565. p^.right:=gentypeconvnode(p^.right,c64floatdef);
  1566. p^.left:=gentypeconvnode(p^.left,c64floatdef);
  1567. firstpass(p^.left);
  1568. firstpass(p^.right);
  1569. { maybe we need an integer register to save }
  1570. { a reference }
  1571. if ((p^.left^.location.loc<>LOC_FPU) or
  1572. (p^.right^.location.loc<>LOC_FPU)) and
  1573. (p^.left^.registers32=p^.right^.registers32) then
  1574. calcregisters(p,1,1,0)
  1575. else
  1576. calcregisters(p,0,1,0);
  1577. p^.location.loc:=LOC_FPU;
  1578. end
  1579. else
  1580. begin
  1581. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  1582. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  1583. firstpass(p^.left);
  1584. firstpass(p^.right);
  1585. calcregisters(p,1,0,0);
  1586. p^.location.loc:=LOC_REGISTER;
  1587. end;
  1588. end;
  1589. if codegenerror then
  1590. exit;
  1591. { determines result type for comparions }
  1592. { here the is a problem with multiple passes }
  1593. { example length(s)+1 gets internal 'longint' type first }
  1594. { if it is a arg it is converted to 'LONGINT' }
  1595. { but a second first pass will reset this to 'longint' }
  1596. case p^.treetype of
  1597. ltn,lten,gtn,gten,equaln,unequaln:
  1598. begin
  1599. if not assigned(p^.resulttype) then
  1600. p^.resulttype:=booldef;
  1601. p^.location.loc:=LOC_FLAGS;
  1602. end;
  1603. xorn:
  1604. begin
  1605. if not assigned(p^.resulttype) then
  1606. p^.resulttype:=p^.left^.resulttype;
  1607. p^.location.loc:=LOC_REGISTER;
  1608. end;
  1609. addn:
  1610. begin
  1611. { the result of a string addition is a string of length 255 }
  1612. if (p^.left^.resulttype^.deftype=stringdef) or
  1613. (p^.right^.resulttype^.deftype=stringdef) then
  1614. begin
  1615. {$ifndef UseAnsiString}
  1616. if not assigned(p^.resulttype) then
  1617. p^.resulttype:=cstringdef
  1618. {$else UseAnsiString}
  1619. if is_ansistring(p^.left^.resulttype) or
  1620. is_ansistring(p^.right^.resulttype) then
  1621. p^.resulttype:=cansistringdef
  1622. else
  1623. p^.resulttype:=cstringdef;
  1624. {$endif UseAnsiString}
  1625. end
  1626. else
  1627. if not assigned(p^.resulttype) then
  1628. p^.resulttype:=p^.left^.resulttype;
  1629. end;
  1630. else if not assigned(p^.resulttype) then
  1631. p^.resulttype:=p^.left^.resulttype;
  1632. end;
  1633. end;
  1634. procedure firstmoddiv(var p : ptree);
  1635. var
  1636. t : ptree;
  1637. {power : longint; }
  1638. begin
  1639. firstpass(p^.left);
  1640. firstpass(p^.right);
  1641. if codegenerror then
  1642. exit;
  1643. if is_constintnode(p^.left) and is_constintnode(p^.right) then
  1644. begin
  1645. case p^.treetype of
  1646. modn : t:=genordinalconstnode(p^.left^.value mod p^.right^.value,s32bitdef);
  1647. divn : t:=genordinalconstnode(p^.left^.value div p^.right^.value,s32bitdef);
  1648. end;
  1649. disposetree(p);
  1650. firstpass(t);
  1651. p:=t;
  1652. exit;
  1653. end;
  1654. if not(p^.right^.resulttype^.deftype=orddef) or
  1655. not(porddef(p^.right^.resulttype)^.typ in [s32bit,u32bit]) then
  1656. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  1657. if not(p^.left^.resulttype^.deftype=orddef) or
  1658. not(porddef(p^.left^.resulttype)^.typ in [s32bit,u32bit]) then
  1659. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  1660. firstpass(p^.left);
  1661. firstpass(p^.right);
  1662. { the resulttype depends on the right side, because the left becomes }
  1663. { always 64 bit }
  1664. p^.resulttype:=p^.right^.resulttype;
  1665. if codegenerror then
  1666. exit;
  1667. left_right_max(p);
  1668. if p^.left^.registers32<=p^.right^.registers32 then
  1669. inc(p^.registers32);
  1670. p^.location.loc:=LOC_REGISTER;
  1671. end;
  1672. procedure firstshlshr(var p : ptree);
  1673. var
  1674. t : ptree;
  1675. begin
  1676. firstpass(p^.left);
  1677. firstpass(p^.right);
  1678. if codegenerror then
  1679. exit;
  1680. if is_constintnode(p^.left) and is_constintnode(p^.right) then
  1681. begin
  1682. case p^.treetype of
  1683. shrn : t:=genordinalconstnode(p^.left^.value shr p^.right^.value,s32bitdef);
  1684. shln : t:=genordinalconstnode(p^.left^.value shl p^.right^.value,s32bitdef);
  1685. end;
  1686. disposetree(p);
  1687. firstpass(t);
  1688. p:=t;
  1689. exit;
  1690. end;
  1691. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  1692. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  1693. firstpass(p^.left);
  1694. firstpass(p^.right);
  1695. if codegenerror then
  1696. exit;
  1697. calcregisters(p,2,0,0);
  1698. {
  1699. p^.registers32:=p^.left^.registers32;
  1700. if p^.registers32<p^.right^.registers32 then
  1701. p^.registers32:=p^.right^.registers32;
  1702. if p^.registers32<1 then p^.registers32:=1;
  1703. }
  1704. p^.resulttype:=s32bitdef;
  1705. p^.location.loc:=LOC_REGISTER;
  1706. end;
  1707. procedure firstrealconst(var p : ptree);
  1708. begin
  1709. p^.location.loc:=LOC_MEM;
  1710. end;
  1711. procedure firstfixconst(var p : ptree);
  1712. begin
  1713. p^.location.loc:=LOC_MEM;
  1714. end;
  1715. procedure firstordconst(var p : ptree);
  1716. begin
  1717. p^.location.loc:=LOC_MEM;
  1718. end;
  1719. procedure firstniln(var p : ptree);
  1720. begin
  1721. p^.resulttype:=voidpointerdef;
  1722. p^.location.loc:=LOC_MEM;
  1723. end;
  1724. procedure firststringconst(var p : ptree);
  1725. begin
  1726. {why this !!! lost of dummy type definitions
  1727. one per const string !!!
  1728. p^.resulttype:=new(pstringdef,init(length(p^.value_str^)));}
  1729. if cs_ansistrings in aktlocalswitches then
  1730. p^.resulttype:=cansistringdef
  1731. else
  1732. p^.resulttype:=cstringdef;
  1733. p^.location.loc:=LOC_MEM;
  1734. end;
  1735. procedure firstumminus(var p : ptree);
  1736. var
  1737. t : ptree;
  1738. minusdef : pprocdef;
  1739. begin
  1740. firstpass(p^.left);
  1741. p^.registers32:=p^.left^.registers32;
  1742. p^.registersfpu:=p^.left^.registersfpu;
  1743. {$ifdef SUPPORT_MMX}
  1744. p^.registersmmx:=p^.left^.registersmmx;
  1745. {$endif SUPPORT_MMX}
  1746. p^.resulttype:=p^.left^.resulttype;
  1747. if codegenerror then
  1748. exit;
  1749. if is_constintnode(p^.left) then
  1750. begin
  1751. t:=genordinalconstnode(-p^.left^.value,s32bitdef);
  1752. disposetree(p);
  1753. firstpass(t);
  1754. p:=t;
  1755. exit;
  1756. end;
  1757. { nasm can not cope with negativ reals !! }
  1758. if is_constrealnode(p^.left)
  1759. {$ifdef i386}
  1760. and not(aktoutputformat in [as_nasmcoff,as_nasmelf,as_nasmobj])
  1761. {$endif}
  1762. then
  1763. begin
  1764. t:=genrealconstnode(-p^.left^.value_real);
  1765. disposetree(p);
  1766. firstpass(t);
  1767. p:=t;
  1768. exit;
  1769. end;
  1770. if (p^.left^.resulttype^.deftype=floatdef) then
  1771. begin
  1772. if pfloatdef(p^.left^.resulttype)^.typ=f32bit then
  1773. begin
  1774. if (p^.left^.location.loc<>LOC_REGISTER) and
  1775. (p^.registers32<1) then
  1776. p^.registers32:=1;
  1777. p^.location.loc:=LOC_REGISTER;
  1778. end
  1779. else
  1780. p^.location.loc:=LOC_FPU;
  1781. end
  1782. {$ifdef SUPPORT_MMX}
  1783. else if (cs_mmx in aktlocalswitches) and
  1784. is_mmx_able_array(p^.left^.resulttype) then
  1785. begin
  1786. if (p^.left^.location.loc<>LOC_MMXREGISTER) and
  1787. (p^.registersmmx<1) then
  1788. p^.registersmmx:=1;
  1789. { if saturation is on, p^.left^.resulttype isn't
  1790. "mmx able" (FK)
  1791. if (cs_mmx_saturation in aktlocalswitches^) and
  1792. (porddef(parraydef(p^.resulttype)^.definition)^.typ in
  1793. [s32bit,u32bit]) then
  1794. CGMessage(type_e_mismatch);
  1795. }
  1796. end
  1797. {$endif SUPPORT_MMX}
  1798. else if (p^.left^.resulttype^.deftype=orddef) then
  1799. begin
  1800. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  1801. firstpass(p^.left);
  1802. p^.registersfpu:=p^.left^.registersfpu;
  1803. {$ifdef SUPPORT_MMX}
  1804. p^.registersmmx:=p^.left^.registersmmx;
  1805. {$endif SUPPORT_MMX}
  1806. p^.registers32:=p^.left^.registers32;
  1807. if codegenerror then
  1808. exit;
  1809. if (p^.left^.location.loc<>LOC_REGISTER) and
  1810. (p^.registers32<1) then
  1811. p^.registers32:=1;
  1812. p^.location.loc:=LOC_REGISTER;
  1813. p^.resulttype:=p^.left^.resulttype;
  1814. end
  1815. else
  1816. begin
  1817. if assigned(overloaded_operators[minus]) then
  1818. minusdef:=overloaded_operators[minus]^.definition
  1819. else
  1820. minusdef:=nil;
  1821. while assigned(minusdef) do
  1822. begin
  1823. if (minusdef^.para1^.data=p^.left^.resulttype) and
  1824. (minusdef^.para1^.next=nil) then
  1825. begin
  1826. t:=gencallnode(overloaded_operators[minus],nil);
  1827. t^.left:=gencallparanode(p^.left,nil);
  1828. putnode(p);
  1829. p:=t;
  1830. firstpass(p);
  1831. exit;
  1832. end;
  1833. minusdef:=minusdef^.nextoverloaded;
  1834. end;
  1835. CGMessage(type_e_mismatch);
  1836. end;
  1837. end;
  1838. procedure firstaddr(var p : ptree);
  1839. var
  1840. hp : ptree;
  1841. hp2 : pdefcoll;
  1842. store_valid : boolean;
  1843. hp3 : pabstractprocdef;
  1844. begin
  1845. make_not_regable(p^.left);
  1846. if not(assigned(p^.resulttype)) then
  1847. begin
  1848. if p^.left^.treetype=calln then
  1849. begin
  1850. { it could also be a procvar, not only pprocsym ! }
  1851. if p^.left^.symtableprocentry^.typ=varsym then
  1852. hp:=genloadnode(pvarsym(p^.left^.symtableprocentry),p^.left^.symtableproc)
  1853. else
  1854. hp:=genloadcallnode(pprocsym(p^.left^.symtableprocentry),p^.left^.symtableproc);
  1855. { result is a procedure variable }
  1856. { No, to be TP compatible, you must return a pointer to
  1857. the procedure that is stored in the procvar.}
  1858. if not(cs_tp_compatible in aktmoduleswitches) then
  1859. begin
  1860. p^.resulttype:=new(pprocvardef,init);
  1861. { it could also be a procvar, not only pprocsym ! }
  1862. if p^.left^.symtableprocentry^.typ=varsym then
  1863. hp3:=pabstractprocdef(pvarsym(p^.left^.symtableprocentry)^.definition)
  1864. else
  1865. hp3:=pabstractprocdef(pprocsym(p^.left^.symtableprocentry)^.definition);
  1866. pprocvardef(p^.resulttype)^.options:=hp3^.options;
  1867. pprocvardef(p^.resulttype)^.retdef:=hp3^.retdef;
  1868. hp2:=hp3^.para1;
  1869. while assigned(hp2) do
  1870. begin
  1871. pprocvardef(p^.resulttype)^.concatdef(hp2^.data,hp2^.paratyp);
  1872. hp2:=hp2^.next;
  1873. end;
  1874. end
  1875. else
  1876. p^.resulttype:=voidpointerdef;
  1877. disposetree(p^.left);
  1878. p^.left:=hp;
  1879. end
  1880. else
  1881. begin
  1882. if not(cs_typed_addresses in aktlocalswitches) then
  1883. p^.resulttype:=voidpointerdef
  1884. else p^.resulttype:=new(ppointerdef,init(p^.left^.resulttype));
  1885. end;
  1886. end;
  1887. store_valid:=must_be_valid;
  1888. must_be_valid:=false;
  1889. firstpass(p^.left);
  1890. must_be_valid:=store_valid;
  1891. if codegenerror then
  1892. exit;
  1893. { we should allow loc_mem for @string }
  1894. if (p^.left^.location.loc<>LOC_REFERENCE) and
  1895. (p^.left^.location.loc<>LOC_MEM) then
  1896. CGMessage(cg_e_illegal_expression);
  1897. p^.registers32:=p^.left^.registers32;
  1898. p^.registersfpu:=p^.left^.registersfpu;
  1899. {$ifdef SUPPORT_MMX}
  1900. p^.registersmmx:=p^.left^.registersmmx;
  1901. {$endif SUPPORT_MMX}
  1902. if p^.registers32<1 then
  1903. p^.registers32:=1;
  1904. p^.location.loc:=LOC_REGISTER;
  1905. end;
  1906. procedure firstdoubleaddr(var p : ptree);
  1907. begin
  1908. make_not_regable(p^.left);
  1909. firstpass(p^.left);
  1910. if p^.resulttype=nil then
  1911. p^.resulttype:=voidpointerdef;
  1912. if (p^.left^.resulttype^.deftype)<>procvardef then
  1913. CGMessage(cg_e_illegal_expression);
  1914. if codegenerror then
  1915. exit;
  1916. if (p^.left^.location.loc<>LOC_REFERENCE) then
  1917. CGMessage(cg_e_illegal_expression);
  1918. p^.registers32:=p^.left^.registers32;
  1919. p^.registersfpu:=p^.left^.registersfpu;
  1920. {$ifdef SUPPORT_MMX}
  1921. p^.registersmmx:=p^.left^.registersmmx;
  1922. {$endif SUPPORT_MMX}
  1923. if p^.registers32<1 then
  1924. p^.registers32:=1;
  1925. p^.location.loc:=LOC_REGISTER;
  1926. end;
  1927. procedure firstnot(var p : ptree);
  1928. var
  1929. t : ptree;
  1930. begin
  1931. firstpass(p^.left);
  1932. if codegenerror then
  1933. exit;
  1934. if (p^.left^.treetype=ordconstn) then
  1935. begin
  1936. t:=genordinalconstnode(not(p^.left^.value),p^.left^.resulttype);
  1937. disposetree(p);
  1938. firstpass(t);
  1939. p:=t;
  1940. exit;
  1941. end;
  1942. p^.resulttype:=p^.left^.resulttype;
  1943. p^.location.loc:=p^.left^.location.loc;
  1944. {$ifdef SUPPORT_MMX}
  1945. p^.registersmmx:=p^.left^.registersmmx;
  1946. {$endif SUPPORT_MMX}
  1947. if is_equal(p^.resulttype,booldef) then
  1948. begin
  1949. p^.registers32:=p^.left^.registers32;
  1950. if ((p^.location.loc=LOC_REFERENCE) or
  1951. (p^.location.loc=LOC_CREGISTER)) and
  1952. (p^.registers32<1) then
  1953. p^.registers32:=1;
  1954. end
  1955. else
  1956. {$ifdef SUPPORT_MMX}
  1957. if (cs_mmx in aktlocalswitches) and
  1958. is_mmx_able_array(p^.left^.resulttype) then
  1959. begin
  1960. if (p^.left^.location.loc<>LOC_MMXREGISTER) and
  1961. (p^.registersmmx<1) then
  1962. p^.registersmmx:=1;
  1963. end
  1964. else
  1965. {$endif SUPPORT_MMX}
  1966. begin
  1967. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  1968. firstpass(p^.left);
  1969. if codegenerror then
  1970. exit;
  1971. p^.resulttype:=p^.left^.resulttype;
  1972. p^.registers32:=p^.left^.registers32;
  1973. {$ifdef SUPPORT_MMX}
  1974. p^.registersmmx:=p^.left^.registersmmx;
  1975. {$endif SUPPORT_MMX}
  1976. if (p^.left^.location.loc<>LOC_REGISTER) and
  1977. (p^.registers32<1) then
  1978. p^.registers32:=1;
  1979. p^.location.loc:=LOC_REGISTER;
  1980. end;
  1981. p^.registersfpu:=p^.left^.registersfpu;
  1982. end;
  1983. procedure firstnothing(var p : ptree);
  1984. begin
  1985. p^.resulttype:=voiddef;
  1986. end;
  1987. procedure firstassignment(var p : ptree);
  1988. var
  1989. store_valid : boolean;
  1990. hp : ptree;
  1991. begin
  1992. store_valid:=must_be_valid;
  1993. must_be_valid:=false;
  1994. firstpass(p^.left);
  1995. if codegenerror then
  1996. exit;
  1997. { assignements to open arrays aren't allowed }
  1998. if is_open_array(p^.left^.resulttype) then
  1999. CGMessage(type_e_mismatch);
  2000. { test if we can avoid copying string to temp
  2001. as in s:=s+...; (PM) }
  2002. {$ifdef dummyi386}
  2003. if ((p^.right^.treetype=addn) or (p^.right^.treetype=subn)) and
  2004. equal_trees(p^.left,p^.right^.left) and
  2005. (ret_in_acc(p^.left^.resulttype)) and
  2006. (not cs_rangechecking in aktmoduleswitches^) then
  2007. begin
  2008. disposetree(p^.right^.left);
  2009. hp:=p^.right;
  2010. p^.right:=p^.right^.right;
  2011. if hp^.treetype=addn then
  2012. p^.assigntyp:=at_plus
  2013. else
  2014. p^.assigntyp:=at_minus;
  2015. putnode(hp);
  2016. end;
  2017. if p^.assigntyp<>at_normal then
  2018. begin
  2019. { for fpu type there is no faster way }
  2020. if is_fpu(p^.left^.resulttype) then
  2021. case p^.assigntyp of
  2022. at_plus : p^.right:=gennode(addn,getcopy(p^.left),p^.right);
  2023. at_minus : p^.right:=gennode(subn,getcopy(p^.left),p^.right);
  2024. at_star : p^.right:=gennode(muln,getcopy(p^.left),p^.right);
  2025. at_slash : p^.right:=gennode(slashn,getcopy(p^.left),p^.right);
  2026. end;
  2027. end;
  2028. {$endif i386}
  2029. must_be_valid:=true;
  2030. firstpass(p^.right);
  2031. must_be_valid:=store_valid;
  2032. if codegenerror then
  2033. exit;
  2034. { some string functions don't need conversion, so treat them separatly }
  2035. if is_shortstring(p^.left^.resulttype) and (assigned(p^.right^.resulttype)) then
  2036. begin
  2037. if not (is_shortstring(p^.right^.resulttype) or
  2038. is_ansistring(p^.right^.resulttype) or
  2039. ((p^.right^.resulttype^.deftype=orddef) and (porddef(p^.right^.resulttype)^.typ=uchar))) then
  2040. begin
  2041. p^.right:=gentypeconvnode(p^.right,p^.left^.resulttype);
  2042. firstpass(p^.right);
  2043. if codegenerror then
  2044. exit;
  2045. end;
  2046. { we call STRCOPY }
  2047. procinfo.flags:=procinfo.flags or pi_do_call;
  2048. hp:=p^.right;
  2049. { test for s:=s+anything ... }
  2050. { the problem is for
  2051. s:=s+s+s;
  2052. this is broken here !! }
  2053. { while hp^.treetype=addn do hp:=hp^.left;
  2054. if equal_trees(p^.left,hp) then
  2055. begin
  2056. p^.concat_string:=true;
  2057. hp:=p^.right;
  2058. while hp^.treetype=addn do
  2059. begin
  2060. hp^.use_strconcat:=true;
  2061. hp:=hp^.left;
  2062. end;
  2063. end; }
  2064. end
  2065. else
  2066. begin
  2067. if (p^.right^.treetype=realconstn) then
  2068. begin
  2069. if p^.left^.resulttype^.deftype=floatdef then
  2070. begin
  2071. case pfloatdef(p^.left^.resulttype)^.typ of
  2072. s32real : p^.right^.realtyp:=ait_real_32bit;
  2073. s64real : p^.right^.realtyp:=ait_real_64bit;
  2074. s80real : p^.right^.realtyp:=ait_real_extended;
  2075. { what about f32bit and s64bit }
  2076. else
  2077. begin
  2078. p^.right:=gentypeconvnode(p^.right,p^.left^.resulttype);
  2079. { nochmal firstpass wegen der Typkonvertierung aufrufen }
  2080. firstpass(p^.right);
  2081. if codegenerror then
  2082. exit;
  2083. end;
  2084. end;
  2085. end;
  2086. end
  2087. else
  2088. begin
  2089. p^.right:=gentypeconvnode(p^.right,p^.left^.resulttype);
  2090. firstpass(p^.right);
  2091. if codegenerror then
  2092. exit;
  2093. end;
  2094. end;
  2095. p^.resulttype:=voiddef;
  2096. {
  2097. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  2098. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  2099. }
  2100. p^.registers32:=p^.left^.registers32+p^.right^.registers32;
  2101. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  2102. {$ifdef SUPPORT_MMX}
  2103. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  2104. {$endif SUPPORT_MMX}
  2105. end;
  2106. procedure firstlr(var p : ptree);
  2107. begin
  2108. firstpass(p^.left);
  2109. firstpass(p^.right);
  2110. end;
  2111. procedure firstderef(var p : ptree);
  2112. begin
  2113. firstpass(p^.left);
  2114. if codegenerror then
  2115. begin
  2116. p^.resulttype:=generrordef;
  2117. exit;
  2118. end;
  2119. p^.registers32:=max(p^.left^.registers32,1);
  2120. p^.registersfpu:=p^.left^.registersfpu;
  2121. {$ifdef SUPPORT_MMX}
  2122. p^.registersmmx:=p^.left^.registersmmx;
  2123. {$endif SUPPORT_MMX}
  2124. if p^.left^.resulttype^.deftype<>pointerdef then
  2125. CGMessage(cg_e_invalid_qualifier);
  2126. p^.resulttype:=ppointerdef(p^.left^.resulttype)^.definition;
  2127. p^.location.loc:=LOC_REFERENCE;
  2128. end;
  2129. procedure firstrange(var p : ptree);
  2130. var
  2131. ct : tconverttype;
  2132. begin
  2133. firstpass(p^.left);
  2134. firstpass(p^.right);
  2135. if codegenerror then
  2136. exit;
  2137. { both types must be compatible }
  2138. if not(is_equal(p^.left^.resulttype,p^.right^.resulttype)) and
  2139. not(isconvertable(p^.left^.resulttype,p^.right^.resulttype,ct,ordconstn,false)) then
  2140. CGMessage(type_e_mismatch);
  2141. { Check if only when its a constant set }
  2142. if (p^.left^.treetype=ordconstn) and (p^.right^.treetype=ordconstn) then
  2143. begin
  2144. { upper limit must be greater or equal than lower limit }
  2145. { not if u32bit }
  2146. if (p^.left^.value>p^.right^.value) and
  2147. (( p^.left^.value<0) or (p^.right^.value>=0)) then
  2148. CGMessage(cg_e_upper_lower_than_lower);
  2149. end;
  2150. left_right_max(p);
  2151. p^.resulttype:=p^.left^.resulttype;
  2152. set_location(p^.location,p^.left^.location);
  2153. end;
  2154. procedure firstvecn(var p : ptree);
  2155. var
  2156. harr : pdef;
  2157. ct : tconverttype;
  2158. begin
  2159. firstpass(p^.left);
  2160. firstpass(p^.right);
  2161. if codegenerror then
  2162. exit;
  2163. { range check only for arrays }
  2164. if (p^.left^.resulttype^.deftype=arraydef) then
  2165. begin
  2166. if not(isconvertable(p^.right^.resulttype,
  2167. parraydef(p^.left^.resulttype)^.rangedef,
  2168. ct,ordconstn,false)) and
  2169. not(is_equal(p^.right^.resulttype,
  2170. parraydef(p^.left^.resulttype)^.rangedef)) then
  2171. CGMessage(type_e_mismatch);
  2172. end;
  2173. { Never convert a boolean or a char !}
  2174. { maybe type conversion }
  2175. if (p^.right^.resulttype^.deftype<>enumdef) and
  2176. not ((p^.right^.resulttype^.deftype=orddef) and
  2177. (Porddef(p^.right^.resulttype)^.typ in [bool8bit,bool16bit,bool32bit,uchar])) then
  2178. begin
  2179. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  2180. { once more firstpass }
  2181. {?? It's better to only firstpass when the tree has
  2182. changed, isn't it ?}
  2183. firstpass(p^.right);
  2184. end;
  2185. if codegenerror then
  2186. exit;
  2187. { determine return type }
  2188. if not assigned(p^.resulttype) then
  2189. if p^.left^.resulttype^.deftype=arraydef then
  2190. p^.resulttype:=parraydef(p^.left^.resulttype)^.definition
  2191. else if (p^.left^.resulttype^.deftype=pointerdef) then
  2192. begin
  2193. { convert pointer to array }
  2194. harr:=new(parraydef,init(0,$7fffffff,s32bitdef));
  2195. parraydef(harr)^.definition:=ppointerdef(p^.left^.resulttype)^.definition;
  2196. p^.left:=gentypeconvnode(p^.left,harr);
  2197. firstpass(p^.left);
  2198. if codegenerror then
  2199. exit;
  2200. p^.resulttype:=parraydef(harr)^.definition
  2201. end
  2202. else if p^.left^.resulttype^.deftype=stringdef then
  2203. begin
  2204. { indexed access to strings }
  2205. case pstringdef(p^.left^.resulttype)^.string_typ of
  2206. {
  2207. st_widestring : p^.resulttype:=cwchardef;
  2208. }
  2209. st_ansistring : p^.resulttype:=cchardef;
  2210. st_longstring : p^.resulttype:=cchardef;
  2211. st_shortstring : p^.resulttype:=cchardef;
  2212. end;
  2213. end
  2214. else
  2215. CGMessage(type_e_mismatch);
  2216. { the register calculation is easy if a const index is used }
  2217. if p^.right^.treetype=ordconstn then
  2218. begin
  2219. p^.registers32:=p^.left^.registers32;
  2220. { for ansi/wide strings, we need at least one register }
  2221. if is_ansistring(p^.left^.resulttype) or
  2222. is_widestring(p^.left^.resulttype) then
  2223. p^.registers32:=max(p^.registers32,1);
  2224. end
  2225. else
  2226. begin
  2227. { this rules are suboptimal, but they should give }
  2228. { good results }
  2229. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  2230. { for ansi/wide strings, we need at least one register }
  2231. if is_ansistring(p^.left^.resulttype) or
  2232. is_widestring(p^.left^.resulttype) then
  2233. p^.registers32:=max(p^.registers32,1);
  2234. { need we an extra register when doing the restore ? }
  2235. if (p^.left^.registers32<=p^.right^.registers32) and
  2236. { only if the node needs less than 3 registers }
  2237. { two for the right node and one for the }
  2238. { left address }
  2239. (p^.registers32<3) then
  2240. inc(p^.registers32);
  2241. { need we an extra register for the index ? }
  2242. if (p^.right^.location.loc<>LOC_REGISTER)
  2243. { only if the right node doesn't need a register }
  2244. and (p^.right^.registers32<1) then
  2245. inc(p^.registers32);
  2246. { not correct, but what works better ?
  2247. if p^.left^.registers32>0 then
  2248. p^.registers32:=max(p^.registers32,2)
  2249. else
  2250. min. one register
  2251. p^.registers32:=max(p^.registers32,1);
  2252. }
  2253. end;
  2254. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  2255. {$ifdef SUPPORT_MMX}
  2256. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  2257. {$endif SUPPORT_MMX}
  2258. p^.location.loc:=p^.left^.location.loc;
  2259. end;
  2260. type
  2261. tfirstconvproc = procedure(var p : ptree);
  2262. procedure first_bigger_smaller(var p : ptree);
  2263. begin
  2264. if (p^.left^.location.loc<>LOC_REGISTER) and (p^.registers32=0) then
  2265. p^.registers32:=1;
  2266. p^.location.loc:=LOC_REGISTER;
  2267. end;
  2268. procedure first_cstring_charpointer(var p : ptree);
  2269. begin
  2270. p^.registers32:=1;
  2271. p^.location.loc:=LOC_REGISTER;
  2272. end;
  2273. procedure first_string_chararray(var p : ptree);
  2274. begin
  2275. p^.registers32:=1;
  2276. p^.location.loc:=LOC_REGISTER;
  2277. end;
  2278. procedure first_string_string(var p : ptree);
  2279. begin
  2280. if pstringdef(p^.resulttype)^.string_typ<>
  2281. pstringdef(p^.left^.resulttype)^.string_typ then
  2282. begin
  2283. if p^.left^.treetype=stringconstn then
  2284. begin
  2285. p^.left^.stringtype:=pstringdef(p^.resulttype)^.string_typ;
  2286. { we don't have to do anything, the const }
  2287. { node generates an ansistring }
  2288. p^.convtyp:=tc_equal;
  2289. end
  2290. else
  2291. procinfo.flags:=procinfo.flags or pi_do_call;
  2292. end;
  2293. { for simplicity lets first keep all ansistrings
  2294. as LOC_MEM, could also become LOC_REGISTER }
  2295. p^.location.loc:=LOC_MEM;
  2296. end;
  2297. procedure first_char_to_string(var p : ptree);
  2298. var
  2299. hp : ptree;
  2300. begin
  2301. if p^.left^.treetype=ordconstn then
  2302. begin
  2303. hp:=genstringconstnode(chr(p^.left^.value));
  2304. firstpass(hp);
  2305. disposetree(p);
  2306. p:=hp;
  2307. end
  2308. else
  2309. p^.location.loc:=LOC_MEM;
  2310. end;
  2311. procedure first_nothing(var p : ptree);
  2312. begin
  2313. p^.location.loc:=LOC_MEM;
  2314. end;
  2315. procedure first_array_to_pointer(var p : ptree);
  2316. begin
  2317. if p^.registers32<1 then
  2318. p^.registers32:=1;
  2319. p^.location.loc:=LOC_REGISTER;
  2320. end;
  2321. procedure first_int_real(var p : ptree);
  2322. var t : ptree;
  2323. begin
  2324. if p^.left^.treetype=ordconstn then
  2325. begin
  2326. { convert constants direct }
  2327. { not because of type conversion }
  2328. t:=genrealconstnode(p^.left^.value);
  2329. { do a first pass here
  2330. because firstpass of typeconv does
  2331. not redo it for left field !! }
  2332. firstpass(t);
  2333. { the type can be something else than s64real !!}
  2334. t:=gentypeconvnode(t,p^.resulttype);
  2335. firstpass(t);
  2336. disposetree(p);
  2337. p:=t;
  2338. exit;
  2339. end
  2340. else
  2341. begin
  2342. if p^.registersfpu<1 then
  2343. p^.registersfpu:=1;
  2344. p^.location.loc:=LOC_FPU;
  2345. end;
  2346. end;
  2347. procedure first_int_fix(var p : ptree);
  2348. begin
  2349. if p^.left^.treetype=ordconstn then
  2350. begin
  2351. { convert constants direct }
  2352. p^.treetype:=fixconstn;
  2353. p^.value_fix:=p^.left^.value shl 16;
  2354. p^.disposetyp:=dt_nothing;
  2355. disposetree(p^.left);
  2356. p^.location.loc:=LOC_MEM;
  2357. end
  2358. else
  2359. begin
  2360. if p^.registers32<1 then
  2361. p^.registers32:=1;
  2362. p^.location.loc:=LOC_REGISTER;
  2363. end;
  2364. end;
  2365. procedure first_real_fix(var p : ptree);
  2366. begin
  2367. if p^.left^.treetype=realconstn then
  2368. begin
  2369. { convert constants direct }
  2370. p^.treetype:=fixconstn;
  2371. p^.value_fix:=round(p^.left^.value_real*65536);
  2372. p^.disposetyp:=dt_nothing;
  2373. disposetree(p^.left);
  2374. p^.location.loc:=LOC_MEM;
  2375. end
  2376. else
  2377. begin
  2378. { at least one fpu and int register needed }
  2379. if p^.registers32<1 then
  2380. p^.registers32:=1;
  2381. if p^.registersfpu<1 then
  2382. p^.registersfpu:=1;
  2383. p^.location.loc:=LOC_REGISTER;
  2384. end;
  2385. end;
  2386. procedure first_fix_real(var p : ptree);
  2387. begin
  2388. if p^.left^.treetype=fixconstn then
  2389. begin
  2390. { convert constants direct }
  2391. p^.treetype:=realconstn;
  2392. p^.value_real:=round(p^.left^.value_fix/65536.0);
  2393. p^.disposetyp:=dt_nothing;
  2394. disposetree(p^.left);
  2395. p^.location.loc:=LOC_MEM;
  2396. end
  2397. else
  2398. begin
  2399. if p^.registersfpu<1 then
  2400. p^.registersfpu:=1;
  2401. p^.location.loc:=LOC_FPU;
  2402. end;
  2403. end;
  2404. procedure first_real_real(var p : ptree);
  2405. begin
  2406. if p^.registersfpu<1 then
  2407. p^.registersfpu:=1;
  2408. p^.location.loc:=LOC_FPU;
  2409. end;
  2410. procedure first_pointer_to_array(var p : ptree);
  2411. begin
  2412. if p^.registers32<1 then
  2413. p^.registers32:=1;
  2414. p^.location.loc:=LOC_REFERENCE;
  2415. end;
  2416. procedure first_chararray_string(var p : ptree);
  2417. begin
  2418. { the only important information is the location of the }
  2419. { result }
  2420. { other stuff is done by firsttypeconv }
  2421. p^.location.loc:=LOC_MEM;
  2422. end;
  2423. procedure first_cchar_charpointer(var p : ptree);
  2424. begin
  2425. p^.left:=gentypeconvnode(p^.left,cstringdef);
  2426. { convert constant char to constant string }
  2427. firstpass(p^.left);
  2428. { evalute tree }
  2429. firstpass(p);
  2430. end;
  2431. procedure first_locmem(var p : ptree);
  2432. begin
  2433. p^.location.loc:=LOC_MEM;
  2434. end;
  2435. procedure first_bool_int(var p : ptree);
  2436. begin
  2437. p^.location.loc:=LOC_REGISTER;
  2438. { Florian I think this is overestimated
  2439. but I still do not really understand how to get this right (PM) }
  2440. { Hmmm, I think we need only one reg to return the result of }
  2441. { this node => so }
  2442. if p^.registers32<1 then
  2443. p^.registers32:=1;
  2444. { should work (FK)
  2445. p^.registers32:=p^.left^.registers32+1;}
  2446. end;
  2447. procedure first_int_bool(var p : ptree);
  2448. begin
  2449. p^.location.loc:=LOC_REGISTER;
  2450. { Florian I think this is overestimated
  2451. but I still do not really understand how to get this right (PM) }
  2452. { Hmmm, I think we need only one reg to return the result of }
  2453. { this node => so }
  2454. p^.left:=gentypeconvnode(p^.left,s32bitdef);
  2455. firstpass(p^.left);
  2456. if p^.registers32<1 then
  2457. p^.registers32:=1;
  2458. { p^.resulttype:=booldef; }
  2459. { should work (FK)
  2460. p^.registers32:=p^.left^.registers32+1;}
  2461. end;
  2462. procedure first_proc_to_procvar(var p : ptree);
  2463. begin
  2464. { hmmm, I'am not sure if that is necessary (FK) }
  2465. firstpass(p^.left);
  2466. if codegenerror then
  2467. exit;
  2468. if (p^.left^.location.loc<>LOC_REFERENCE) then
  2469. CGMessage(cg_e_illegal_expression);
  2470. p^.registers32:=p^.left^.registers32;
  2471. if p^.registers32<1 then
  2472. p^.registers32:=1;
  2473. p^.location.loc:=LOC_REGISTER;
  2474. end;
  2475. procedure first_load_smallset(var p : ptree);
  2476. begin
  2477. end;
  2478. procedure first_pchar_to_ansistring(var p : ptree);
  2479. begin
  2480. p^.location.loc:=LOC_REGISTER;
  2481. if p^.registers32<1 then
  2482. p^.registers32:=1;
  2483. end;
  2484. procedure first_ansistring_to_pchar(var p : ptree);
  2485. begin
  2486. p^.location.loc:=LOC_REGISTER;
  2487. if p^.registers32<1 then
  2488. p^.registers32:=1;
  2489. end;
  2490. procedure first_arrayconstructor_to_set(var p:ptree);
  2491. var
  2492. hp : ptree;
  2493. begin
  2494. if p^.left^.treetype<>arrayconstructn then
  2495. internalerror(5546);
  2496. { remove typeconv node }
  2497. hp:=p;
  2498. p:=p^.left;
  2499. putnode(hp);
  2500. { create a set constructor tree }
  2501. arrayconstructor_to_set(p);
  2502. end;
  2503. function is_procsym_load(p:Ptree):boolean;
  2504. begin
  2505. is_procsym_load:=((p^.treetype=loadn) and (p^.symtableentry^.typ=procsym)) or
  2506. ((p^.treetype=addrn) and (p^.left^.treetype=loadn)
  2507. and (p^.left^.symtableentry^.typ=procsym)) ;
  2508. end;
  2509. { change a proc call to a procload for assignment to a procvar }
  2510. { this can only happen for proc/function without arguments }
  2511. function is_procsym_call(p:Ptree):boolean;
  2512. begin
  2513. is_procsym_call:=(p^.treetype=calln) and (p^.left=nil) and
  2514. (((p^.symtableprocentry^.typ=procsym) and (p^.right=nil)) or
  2515. ((p^.right<>nil) and (p^.right^.symtableprocentry^.typ=varsym)));
  2516. end;
  2517. {***}
  2518. function is_assignment_overloaded(from_def,to_def : pdef) : boolean;
  2519. var
  2520. passproc : pprocdef;
  2521. convtyp : tconverttype;
  2522. begin
  2523. is_assignment_overloaded:=false;
  2524. if assigned(overloaded_operators[assignment]) then
  2525. passproc:=overloaded_operators[assignment]^.definition
  2526. else
  2527. exit;
  2528. while passproc<>nil do
  2529. begin
  2530. if is_equal(passproc^.retdef,to_def) and
  2531. isconvertable(from_def,passproc^.para1^.data,convtyp,
  2532. ordconstn { nur Dummy},false ) then
  2533. begin
  2534. is_assignment_overloaded:=true;
  2535. break;
  2536. end;
  2537. passproc:=passproc^.nextoverloaded;
  2538. end;
  2539. end;
  2540. { Attention: do *** no *** recursive call of firstpass }
  2541. { because the child tree is always passed }
  2542. procedure firsttypeconv(var p : ptree);
  2543. var
  2544. hp : ptree;
  2545. aprocdef : pprocdef;
  2546. proctype : tdeftype;
  2547. const
  2548. firstconvert : array[tconverttype] of
  2549. tfirstconvproc = (first_nothing,first_nothing,
  2550. first_bigger_smaller,first_nothing,first_bigger_smaller,
  2551. first_bigger_smaller,first_bigger_smaller,
  2552. first_bigger_smaller,first_bigger_smaller,
  2553. first_bigger_smaller,first_string_string,
  2554. first_cstring_charpointer,first_string_chararray,
  2555. first_array_to_pointer,first_pointer_to_array,
  2556. first_char_to_string,first_bigger_smaller,
  2557. first_bigger_smaller,first_bigger_smaller,
  2558. first_bigger_smaller,first_bigger_smaller,
  2559. first_bigger_smaller,first_bigger_smaller,
  2560. first_bigger_smaller,first_bigger_smaller,
  2561. first_bigger_smaller,first_bigger_smaller,
  2562. first_bigger_smaller,first_bigger_smaller,
  2563. first_bigger_smaller,first_bigger_smaller,
  2564. first_bigger_smaller,first_bigger_smaller,
  2565. first_bigger_smaller,first_bigger_smaller,
  2566. first_bool_int,first_int_bool,
  2567. first_int_real,first_real_fix,
  2568. first_fix_real,first_int_fix,first_real_real,
  2569. first_locmem,first_proc_to_procvar,
  2570. first_cchar_charpointer,
  2571. first_load_smallset,
  2572. first_ansistring_to_pchar,
  2573. first_pchar_to_ansistring,
  2574. first_arrayconstructor_to_set);
  2575. begin
  2576. aprocdef:=nil;
  2577. { if explicite type conversation, then run firstpass }
  2578. if p^.explizit then
  2579. firstpass(p^.left);
  2580. if codegenerror then
  2581. begin
  2582. p^.resulttype:=generrordef;
  2583. exit;
  2584. end;
  2585. if not assigned(p^.left^.resulttype) then
  2586. begin
  2587. codegenerror:=true;
  2588. internalerror(52349);
  2589. exit;
  2590. end;
  2591. { load the value_str from the left part }
  2592. p^.registers32:=p^.left^.registers32;
  2593. p^.registersfpu:=p^.left^.registersfpu;
  2594. {$ifdef SUPPORT_MMX}
  2595. p^.registersmmx:=p^.left^.registersmmx;
  2596. {$endif}
  2597. set_location(p^.location,p^.left^.location);
  2598. { remove obsolete type conversions }
  2599. if is_equal(p^.left^.resulttype,p^.resulttype) then
  2600. begin
  2601. { becuase is_equal only checks the basetype for sets we need to
  2602. check here if we are loading a smallset into a normalset }
  2603. if (p^.resulttype^.deftype=setdef) and
  2604. (p^.left^.resulttype^.deftype=setdef) and
  2605. (psetdef(p^.resulttype)^.settype<>smallset) and
  2606. (psetdef(p^.left^.resulttype)^.settype=smallset) then
  2607. begin
  2608. { try to define the set as a normalset if it's a constant set }
  2609. if p^.left^.treetype=setconstn then
  2610. begin
  2611. p^.resulttype:=p^.left^.resulttype;
  2612. psetdef(p^.resulttype)^.settype:=normset
  2613. end
  2614. else
  2615. p^.convtyp:=tc_load_smallset;
  2616. exit;
  2617. end
  2618. else
  2619. begin
  2620. hp:=p;
  2621. p:=p^.left;
  2622. p^.resulttype:=hp^.resulttype;
  2623. putnode(hp);
  2624. exit;
  2625. end;
  2626. end;
  2627. if is_assignment_overloaded(p^.left^.resulttype,p^.resulttype) then
  2628. begin
  2629. procinfo.flags:=procinfo.flags or pi_do_call;
  2630. hp:=gencallnode(overloaded_operators[assignment],nil);
  2631. hp^.left:=gencallparanode(p^.left,nil);
  2632. putnode(p);
  2633. p:=hp;
  2634. firstpass(p);
  2635. exit;
  2636. end;
  2637. if (not(isconvertable(p^.left^.resulttype,p^.resulttype,
  2638. p^.convtyp,p^.left^.treetype,p^.explizit))) then
  2639. begin
  2640. {Procedures have a resulttype of voiddef and functions of their
  2641. own resulttype. They will therefore always be incompatible with
  2642. a procvar. Because isconvertable cannot check for procedures we
  2643. use an extra check for them.}
  2644. if (cs_tp_compatible in aktmoduleswitches) and
  2645. ((is_procsym_load(p^.left) or is_procsym_call(p^.left)) and
  2646. (p^.resulttype^.deftype=procvardef)) then
  2647. begin
  2648. { just a test: p^.explizit:=false; }
  2649. if is_procsym_call(p^.left) then
  2650. begin
  2651. if p^.left^.right=nil then
  2652. begin
  2653. p^.left^.treetype:=loadn;
  2654. { are at same offset so this could be spared, but
  2655. it more secure to do it anyway }
  2656. p^.left^.symtableentry:=p^.left^.symtableprocentry;
  2657. p^.left^.resulttype:=pprocsym(p^.left^.symtableentry)^.definition;
  2658. aprocdef:=pprocdef(p^.left^.resulttype);
  2659. end
  2660. else
  2661. begin
  2662. p^.left^.right^.treetype:=loadn;
  2663. p^.left^.right^.symtableentry:=p^.left^.right^.symtableentry;
  2664. P^.left^.right^.resulttype:=pvarsym(p^.left^.symtableentry)^.definition;
  2665. hp:=p^.left^.right;
  2666. putnode(p^.left);
  2667. p^.left:=hp;
  2668. { should we do that ? }
  2669. firstpass(p^.left);
  2670. if not is_equal(p^.left^.resulttype,p^.resulttype) then
  2671. begin
  2672. CGMessage(type_e_mismatch);
  2673. exit;
  2674. end
  2675. else
  2676. begin
  2677. hp:=p;
  2678. p:=p^.left;
  2679. p^.resulttype:=hp^.resulttype;
  2680. putnode(hp);
  2681. exit;
  2682. end;
  2683. end;
  2684. end
  2685. else
  2686. begin
  2687. if p^.left^.treetype=addrn then
  2688. begin
  2689. hp:=p^.left;
  2690. p^.left:=p^.left^.left;
  2691. putnode(p^.left);
  2692. end
  2693. else
  2694. aprocdef:=pprocsym(p^.left^.symtableentry)^.definition;
  2695. end;
  2696. p^.convtyp:=tc_proc2procvar;
  2697. { Now check if the procedure we are going to assign to
  2698. the procvar, is compatible with the procvar's type.
  2699. Did the original procvar support do such a check?
  2700. I can't find any.}
  2701. { answer : is_equal works for procvardefs !! }
  2702. { but both must be procvardefs, so we cheet little }
  2703. if assigned(aprocdef) then
  2704. begin
  2705. proctype:=aprocdef^.deftype;
  2706. aprocdef^.deftype:=procvardef;
  2707. if not is_equal(aprocdef,p^.resulttype) then
  2708. begin
  2709. aprocdef^.deftype:=proctype;
  2710. CGMessage(type_e_mismatch);
  2711. end;
  2712. aprocdef^.deftype:=proctype;
  2713. firstconvert[p^.convtyp](p);
  2714. end
  2715. else
  2716. CGMessage(type_e_mismatch);
  2717. exit;
  2718. end
  2719. else
  2720. begin
  2721. if p^.explizit then
  2722. begin
  2723. { boolean to byte are special because the
  2724. location can be different }
  2725. if (p^.resulttype^.deftype=orddef) and
  2726. (porddef(p^.resulttype)^.typ=u8bit) and
  2727. (p^.left^.resulttype^.deftype=orddef) and
  2728. (porddef(p^.left^.resulttype)^.typ=bool8bit) then
  2729. begin
  2730. p^.convtyp:=tc_bool_2_int;
  2731. firstconvert[p^.convtyp](p);
  2732. exit;
  2733. end;
  2734. { normal tc_equal-Konvertierung durchf�hren }
  2735. p^.convtyp:=tc_equal;
  2736. { wenn Aufz„hltyp nach Ordinal konvertiert werden soll }
  2737. { dann Aufz„hltyp=s32bit }
  2738. if (p^.left^.resulttype^.deftype=enumdef) and
  2739. is_ordinal(p^.resulttype) then
  2740. begin
  2741. if p^.left^.treetype=ordconstn then
  2742. begin
  2743. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  2744. disposetree(p);
  2745. firstpass(hp);
  2746. p:=hp;
  2747. exit;
  2748. end
  2749. else
  2750. begin
  2751. if not isconvertable(s32bitdef,p^.resulttype,p^.convtyp,
  2752. ordconstn { nur Dummy},false ) then
  2753. CGMessage(cg_e_illegal_type_conversion);
  2754. end;
  2755. end
  2756. { ordinal to enumeration }
  2757. else
  2758. if (p^.resulttype^.deftype=enumdef) and
  2759. is_ordinal(p^.left^.resulttype) then
  2760. begin
  2761. if p^.left^.treetype=ordconstn then
  2762. begin
  2763. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  2764. disposetree(p);
  2765. firstpass(hp);
  2766. p:=hp;
  2767. exit;
  2768. end
  2769. else
  2770. begin
  2771. if not isconvertable(p^.left^.resulttype,s32bitdef,p^.convtyp,
  2772. ordconstn { nur Dummy},false ) then
  2773. CGMessage(cg_e_illegal_type_conversion);
  2774. end;
  2775. end
  2776. {Are we typecasting an ordconst to a char?}
  2777. else
  2778. if is_equal(p^.resulttype,cchardef) and
  2779. is_ordinal(p^.left^.resulttype) then
  2780. begin
  2781. if p^.left^.treetype=ordconstn then
  2782. begin
  2783. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  2784. firstpass(hp);
  2785. disposetree(p);
  2786. p:=hp;
  2787. exit;
  2788. end
  2789. else
  2790. begin
  2791. { this is wrong because it converts to a 4 byte long var !!
  2792. if not isconvertable(p^.left^.resulttype,s32bitdef,p^.convtyp,ordconstn nur Dummy ) then }
  2793. if not isconvertable(p^.left^.resulttype,u8bitdef,
  2794. p^.convtyp,ordconstn { nur Dummy},false ) then
  2795. CGMessage(cg_e_illegal_type_conversion);
  2796. end;
  2797. end
  2798. { only if the same size or formal def }
  2799. { why do we allow typecasting of voiddef ?? (PM) }
  2800. else
  2801. if not(
  2802. (p^.left^.resulttype^.deftype=formaldef) or
  2803. (p^.left^.resulttype^.size=p^.resulttype^.size) or
  2804. (is_equal(p^.left^.resulttype,voiddef) and
  2805. (p^.left^.treetype=derefn))
  2806. ) then
  2807. CGMessage(cg_e_illegal_type_conversion);
  2808. { the conversion into a strutured type is only }
  2809. { possible, if the source is no register }
  2810. if ((p^.resulttype^.deftype in [recorddef,stringdef,arraydef]) or
  2811. ((p^.resulttype^.deftype=objectdef) and not(pobjectdef(p^.resulttype)^.isclass))
  2812. ) and (p^.left^.location.loc in [LOC_REGISTER,LOC_CREGISTER]) and
  2813. {it also works if the assignment is overloaded }
  2814. not is_assignment_overloaded(p^.left^.resulttype,p^.resulttype) then
  2815. CGMessage(cg_e_illegal_type_conversion);
  2816. end
  2817. else
  2818. CGMessage(type_e_mismatch);
  2819. end
  2820. end
  2821. else
  2822. begin
  2823. { ordinal contants can be directly converted }
  2824. if (p^.left^.treetype=ordconstn) and is_ordinal(p^.resulttype) then
  2825. begin
  2826. { perform range checking }
  2827. if not(p^.explizit and (cs_tp_compatible in aktmoduleswitches)) then
  2828. testrange(p^.resulttype,p^.left^.value);
  2829. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  2830. disposetree(p);
  2831. firstpass(hp);
  2832. p:=hp;
  2833. exit;
  2834. end;
  2835. if p^.convtyp<>tc_equal then
  2836. firstconvert[p^.convtyp](p);
  2837. end;
  2838. end;
  2839. { *************** subroutine handling **************** }
  2840. { protected field handling
  2841. protected field can not appear in
  2842. var parameters of function !!
  2843. this can only be done after we have determined the
  2844. overloaded function
  2845. this is the reason why it is not in the parser
  2846. PM }
  2847. procedure test_protected_sym(sym : psym);
  2848. begin
  2849. if ((sym^.properties and sp_protected)<>0) and
  2850. ((sym^.owner^.symtabletype=unitsymtable) or
  2851. ((sym^.owner^.symtabletype=objectsymtable) and
  2852. (pobjectdef(sym^.owner^.defowner)^.owner^.symtabletype=unitsymtable))) then
  2853. CGMessage(parser_e_cant_access_protected_member);
  2854. end;
  2855. procedure test_protected(p : ptree);
  2856. begin
  2857. if p^.treetype=loadn then
  2858. begin
  2859. test_protected_sym(p^.symtableentry);
  2860. end
  2861. else if p^.treetype=typeconvn then
  2862. begin
  2863. test_protected(p^.left);
  2864. end
  2865. else if p^.treetype=derefn then
  2866. begin
  2867. test_protected(p^.left);
  2868. end
  2869. else if p^.treetype=subscriptn then
  2870. begin
  2871. { test_protected(p^.left);
  2872. Is a field of a protected var
  2873. also protected ??? PM }
  2874. test_protected_sym(p^.vs);
  2875. end;
  2876. end;
  2877. procedure firstcallparan(var p : ptree;defcoll : pdefcoll);
  2878. var store_valid : boolean;
  2879. old_array_constructor : boolean;
  2880. convtyp : tconverttype;
  2881. begin
  2882. inc(parsing_para_level);
  2883. if assigned(p^.right) then
  2884. begin
  2885. if defcoll=nil then
  2886. firstcallparan(p^.right,nil)
  2887. else
  2888. firstcallparan(p^.right,defcoll^.next);
  2889. p^.registers32:=p^.right^.registers32;
  2890. p^.registersfpu:=p^.right^.registersfpu;
  2891. {$ifdef SUPPORT_MMX}
  2892. p^.registersmmx:=p^.right^.registersmmx;
  2893. {$endif}
  2894. end;
  2895. if defcoll=nil then
  2896. begin
  2897. old_array_constructor:=allow_array_constructor;
  2898. allow_array_constructor:=true;
  2899. if not(assigned(p^.resulttype)) or
  2900. (p^.left^.treetype=typeconvn) then
  2901. firstpass(p^.left);
  2902. allow_array_constructor:=old_array_constructor;
  2903. if codegenerror then
  2904. begin
  2905. dec(parsing_para_level);
  2906. exit;
  2907. end;
  2908. p^.resulttype:=p^.left^.resulttype;
  2909. end
  2910. { if we know the routine which is called, then the type }
  2911. { conversions are inserted }
  2912. else
  2913. begin
  2914. if count_ref then
  2915. begin
  2916. store_valid:=must_be_valid;
  2917. if (defcoll^.paratyp=vs_var) then
  2918. test_protected(p^.left);
  2919. if (defcoll^.paratyp<>vs_var) then
  2920. must_be_valid:=true
  2921. else
  2922. must_be_valid:=false;
  2923. { here we must add something for the implicit type }
  2924. { conversion from array of char to pchar }
  2925. if isconvertable(p^.left^.resulttype,defcoll^.data,convtyp,
  2926. p^.left^.treetype,false) then
  2927. if convtyp=tc_array_to_pointer then
  2928. must_be_valid:=false;
  2929. { only process typeconvn, else it will break other trees }
  2930. old_array_constructor:=allow_array_constructor;
  2931. allow_array_constructor:=true;
  2932. if (p^.left^.treetype=typeconvn) then
  2933. firstpass(p^.left);
  2934. allow_array_constructor:=old_array_constructor;
  2935. must_be_valid:=store_valid;
  2936. end;
  2937. if not(is_shortstring(p^.left^.resulttype) and
  2938. is_shortstring(defcoll^.data)) and
  2939. (defcoll^.data^.deftype<>formaldef) then
  2940. begin
  2941. if (defcoll^.paratyp=vs_var) and
  2942. { allows conversion from word to integer and
  2943. byte to shortint }
  2944. (not(
  2945. (p^.left^.resulttype^.deftype=orddef) and
  2946. (defcoll^.data^.deftype=orddef) and
  2947. (p^.left^.resulttype^.size=defcoll^.data^.size)
  2948. ) and
  2949. { an implicit pointer conversion is allowed }
  2950. not(
  2951. (p^.left^.resulttype^.deftype=pointerdef) and
  2952. (defcoll^.data^.deftype=pointerdef)
  2953. ) and
  2954. { child classes can be also passed }
  2955. not(
  2956. (p^.left^.resulttype^.deftype=objectdef) and
  2957. (defcoll^.data^.deftype=objectdef) and
  2958. pobjectdef(p^.left^.resulttype)^.isrelated(pobjectdef(defcoll^.data))
  2959. ) and
  2960. { an implicit file conversion is also allowed }
  2961. { from a typed file to an untyped one }
  2962. not(
  2963. (p^.left^.resulttype^.deftype=filedef) and
  2964. (defcoll^.data^.deftype=filedef) and
  2965. (pfiledef(defcoll^.data)^.filetype = ft_untyped) and
  2966. (pfiledef(p^.left^.resulttype)^.filetype = ft_typed)
  2967. ) and
  2968. not(is_equal(p^.left^.resulttype,defcoll^.data))) then
  2969. CGMessage(parser_e_call_by_ref_without_typeconv);
  2970. { don't generate an type conversion for open arrays }
  2971. { else we loss the ranges }
  2972. if not(is_open_array(defcoll^.data)) then
  2973. begin
  2974. p^.left:=gentypeconvnode(p^.left,defcoll^.data);
  2975. firstpass(p^.left);
  2976. end;
  2977. if codegenerror then
  2978. begin
  2979. dec(parsing_para_level);
  2980. exit;
  2981. end;
  2982. end;
  2983. { check var strings }
  2984. if (cs_strict_var_strings in aktlocalswitches) and
  2985. is_shortstring(p^.left^.resulttype) and
  2986. is_shortstring(defcoll^.data) and
  2987. (defcoll^.paratyp=vs_var) and
  2988. not(is_equal(p^.left^.resulttype,defcoll^.data)) then
  2989. CGMessage(type_e_strict_var_string_violation);
  2990. { Variablen, die call by reference �bergeben werden, }
  2991. { k”nnen nicht in ein Register kopiert werden }
  2992. { is this usefull here ? }
  2993. { this was missing in formal parameter list }
  2994. if defcoll^.paratyp=vs_var then
  2995. make_not_regable(p^.left);
  2996. p^.resulttype:=defcoll^.data;
  2997. end;
  2998. if p^.left^.registers32>p^.registers32 then
  2999. p^.registers32:=p^.left^.registers32;
  3000. if p^.left^.registersfpu>p^.registersfpu then
  3001. p^.registersfpu:=p^.left^.registersfpu;
  3002. {$ifdef SUPPORT_MMX}
  3003. if p^.left^.registersmmx>p^.registersmmx then
  3004. p^.registersmmx:=p^.left^.registersmmx;
  3005. {$endif SUPPORT_MMX}
  3006. dec(parsing_para_level);
  3007. end;
  3008. procedure firstcalln(var p : ptree);
  3009. type
  3010. pprocdefcoll = ^tprocdefcoll;
  3011. tprocdefcoll = record
  3012. data : pprocdef;
  3013. nextpara : pdefcoll;
  3014. firstpara : pdefcoll;
  3015. next : pprocdefcoll;
  3016. end;
  3017. var
  3018. hp,procs,hp2 : pprocdefcoll;
  3019. pd : pprocdef;
  3020. actprocsym : pprocsym;
  3021. def_from,def_to,conv_to : pdef;
  3022. pt,inlinecode : ptree;
  3023. exactmatch,inlined : boolean;
  3024. paralength,l : longint;
  3025. pdc : pdefcoll;
  3026. { only Dummy }
  3027. hcvt : tconverttype;
  3028. regi : tregister;
  3029. store_valid, old_count_ref : boolean;
  3030. { types.is_equal can't handle a formaldef ! }
  3031. function is_equal(def1,def2 : pdef) : boolean;
  3032. begin
  3033. { safety check }
  3034. if not (assigned(def1) or assigned(def2)) then
  3035. begin
  3036. is_equal:=false;
  3037. exit;
  3038. end;
  3039. { all types can be passed to a formaldef }
  3040. is_equal:=(def1^.deftype=formaldef) or
  3041. (types.is_equal(def1,def2))
  3042. { to support ansi/long/wide strings in a proper way }
  3043. { string and string[10] are assumed as equal }
  3044. { when searching the correct overloaded procedure }
  3045. or
  3046. (
  3047. (def1^.deftype=stringdef) and (def2^.deftype=stringdef) and
  3048. (pstringdef(def1)^.string_typ=pstringdef(def2)^.string_typ)
  3049. )
  3050. { set can also be a not yet converted array constructor }
  3051. or
  3052. (
  3053. (def1^.deftype=setdef) and (def2^.deftype=arraydef) and
  3054. (parraydef(def2)^.IsConstructor) and not(parraydef(def2)^.IsVariant)
  3055. )
  3056. ;
  3057. end;
  3058. function is_in_limit(def_from,def_to : pdef) : boolean;
  3059. begin
  3060. is_in_limit:=(def_from^.deftype = orddef) and
  3061. (def_to^.deftype = orddef) and
  3062. (porddef(def_from)^.low>porddef(def_to)^.low) and
  3063. (porddef(def_from)^.high<porddef(def_to)^.high);
  3064. end;
  3065. var
  3066. is_const : boolean;
  3067. begin
  3068. { release registers! }
  3069. { if procdefinition<>nil then we called firstpass already }
  3070. { it seems to be bad because of the registers }
  3071. { at least we can avoid the overloaded search !! }
  3072. procs:=nil;
  3073. { made this global for disposing !! }
  3074. store_valid:=must_be_valid;
  3075. must_be_valid:=false;
  3076. inlined:=false;
  3077. if assigned(p^.procdefinition) and
  3078. ((p^.procdefinition^.options and poinline)<>0) then
  3079. begin
  3080. inlinecode:=p^.right;
  3081. if assigned(inlinecode) then
  3082. begin
  3083. inlined:=true;
  3084. p^.procdefinition^.options:=p^.procdefinition^.options and (not poinline);
  3085. end;
  3086. p^.right:=nil;
  3087. end;
  3088. { procedure variable ? }
  3089. if assigned(p^.right) then
  3090. begin
  3091. { procedure does a call }
  3092. procinfo.flags:=procinfo.flags or pi_do_call;
  3093. { calc the correture value for the register }
  3094. {$ifdef i386}
  3095. for regi:=R_EAX to R_EDI do
  3096. inc(reg_pushes[regi],t_times*2);
  3097. {$endif}
  3098. {$ifdef m68k}
  3099. for regi:=R_D0 to R_A6 do
  3100. inc(reg_pushes[regi],t_times*2);
  3101. {$endif}
  3102. { calculate the type of the parameters }
  3103. if assigned(p^.left) then
  3104. begin
  3105. old_count_ref:=count_ref;
  3106. count_ref:=false;
  3107. firstcallparan(p^.left,nil);
  3108. count_ref:=old_count_ref;
  3109. if codegenerror then
  3110. exit;
  3111. end;
  3112. firstpass(p^.right);
  3113. { check the parameters }
  3114. pdc:=pprocvardef(p^.right^.resulttype)^.para1;
  3115. pt:=p^.left;
  3116. while assigned(pdc) and assigned(pt) do
  3117. begin
  3118. pt:=pt^.right;
  3119. pdc:=pdc^.next;
  3120. end;
  3121. if assigned(pt) or assigned(pdc) then
  3122. CGMessage(parser_e_illegal_parameter_list);
  3123. { insert type conversions }
  3124. if assigned(p^.left) then
  3125. begin
  3126. old_count_ref:=count_ref;
  3127. count_ref:=true;
  3128. firstcallparan(p^.left,pprocvardef(p^.right^.resulttype)^.para1);
  3129. count_ref:=old_count_ref;
  3130. if codegenerror then
  3131. exit;
  3132. end;
  3133. p^.resulttype:=pprocvardef(p^.right^.resulttype)^.retdef;
  3134. { this was missing, leads to a bug below if
  3135. the procvar is a function }
  3136. p^.procdefinition:=pprocdef(p^.right^.resulttype);
  3137. end
  3138. else
  3139. { not a procedure variable }
  3140. begin
  3141. { determine the type of the parameters }
  3142. if assigned(p^.left) then
  3143. begin
  3144. old_count_ref:=count_ref;
  3145. count_ref:=false;
  3146. store_valid:=must_be_valid;
  3147. must_be_valid:=false;
  3148. firstcallparan(p^.left,nil);
  3149. count_ref:=old_count_ref;
  3150. must_be_valid:=store_valid;
  3151. if codegenerror then
  3152. exit;
  3153. end;
  3154. { do we know the procedure to call ? }
  3155. if not(assigned(p^.procdefinition)) then
  3156. begin
  3157. actprocsym:=pprocsym(p^.symtableprocentry);
  3158. { determine length of parameter list }
  3159. pt:=p^.left;
  3160. paralength:=0;
  3161. while assigned(pt) do
  3162. begin
  3163. inc(paralength);
  3164. pt:=pt^.right;
  3165. end;
  3166. { link all procedures which have the same # of parameters }
  3167. pd:=actprocsym^.definition;
  3168. while assigned(pd) do
  3169. begin
  3170. { we should also check that the overloaded function
  3171. has been declared in a unit that is in the uses !! }
  3172. { pd^.owner should be in the symtablestack !! }
  3173. { Laenge der deklarierten Parameterliste feststellen: }
  3174. { not necessary why nextprocsym field }
  3175. {st:=symtablestack;
  3176. if (pd^.owner^.symtabletype<>objectsymtable) then
  3177. while assigned(st) do
  3178. begin
  3179. if (st=pd^.owner) then break;
  3180. st:=st^.next;
  3181. end;
  3182. if assigned(st) then }
  3183. begin
  3184. pdc:=pd^.para1;
  3185. l:=0;
  3186. while assigned(pdc) do
  3187. begin
  3188. inc(l);
  3189. pdc:=pdc^.next;
  3190. end;
  3191. { only when the # of parameter are equal }
  3192. if l=paralength then
  3193. begin
  3194. new(hp);
  3195. hp^.data:=pd;
  3196. hp^.next:=procs;
  3197. hp^.nextpara:=pd^.para1;
  3198. hp^.firstpara:=pd^.para1;
  3199. procs:=hp;
  3200. end;
  3201. end;
  3202. pd:=pd^.nextoverloaded;
  3203. {$ifdef CHAINPROCSYMS}
  3204. if (pd=nil) and not (p^.unit_specific) then
  3205. begin
  3206. actprocsym:=actprocsym^.nextprocsym;
  3207. if assigned(actprocsym) then
  3208. pd:=actprocsym^.definition;
  3209. end;
  3210. {$endif CHAINPROCSYMS}
  3211. end;
  3212. { no procedures found? then there is something wrong
  3213. with the parameter size }
  3214. if not assigned(procs) and
  3215. ((parsing_para_level=0) or assigned(p^.left)) then
  3216. begin
  3217. CGMessage(parser_e_wrong_parameter_size);
  3218. actprocsym^.write_parameter_lists;
  3219. exit;
  3220. end;
  3221. { now we can compare parameter after parameter }
  3222. pt:=p^.left;
  3223. while assigned(pt) do
  3224. begin
  3225. { matches a parameter of one procedure exact ? }
  3226. exactmatch:=false;
  3227. hp:=procs;
  3228. while assigned(hp) do
  3229. begin
  3230. if is_equal(hp^.nextpara^.data,pt^.resulttype) then
  3231. begin
  3232. if hp^.nextpara^.data=pt^.resulttype then
  3233. begin
  3234. pt^.exact_match_found:=true;
  3235. hp^.nextpara^.argconvtyp:=act_exact;
  3236. end
  3237. else
  3238. hp^.nextpara^.argconvtyp:=act_equal;
  3239. exactmatch:=true;
  3240. end
  3241. else
  3242. hp^.nextpara^.argconvtyp:=act_convertable;
  3243. hp:=hp^.next;
  3244. end;
  3245. { .... if yes, del all the other procedures }
  3246. if exactmatch then
  3247. begin
  3248. { the first .... }
  3249. while (assigned(procs)) and not(is_equal(procs^.nextpara^.data,pt^.resulttype)) do
  3250. begin
  3251. hp:=procs^.next;
  3252. dispose(procs);
  3253. procs:=hp;
  3254. end;
  3255. { and the others }
  3256. hp:=procs;
  3257. while (assigned(hp)) and assigned(hp^.next) do
  3258. begin
  3259. if not(is_equal(hp^.next^.nextpara^.data,pt^.resulttype)) then
  3260. begin
  3261. hp2:=hp^.next^.next;
  3262. dispose(hp^.next);
  3263. hp^.next:=hp2;
  3264. end
  3265. else
  3266. hp:=hp^.next;
  3267. end;
  3268. end
  3269. { when a parameter matches exact, remove all procs
  3270. which need typeconvs }
  3271. else
  3272. begin
  3273. { the first... }
  3274. while (assigned(procs)) and
  3275. not(isconvertable(pt^.resulttype,procs^.nextpara^.data,
  3276. hcvt,pt^.left^.treetype,false)) do
  3277. begin
  3278. hp:=procs^.next;
  3279. dispose(procs);
  3280. procs:=hp;
  3281. end;
  3282. { and the others }
  3283. hp:=procs;
  3284. while (assigned(hp)) and assigned(hp^.next) do
  3285. begin
  3286. if not(isconvertable(pt^.resulttype,hp^.next^.nextpara^.data,
  3287. hcvt,pt^.left^.treetype,false)) then
  3288. begin
  3289. hp2:=hp^.next^.next;
  3290. dispose(hp^.next);
  3291. hp^.next:=hp2;
  3292. end
  3293. else
  3294. hp:=hp^.next;
  3295. end;
  3296. end;
  3297. { update nextpara for all procedures }
  3298. hp:=procs;
  3299. while assigned(hp) do
  3300. begin
  3301. hp^.nextpara:=hp^.nextpara^.next;
  3302. hp:=hp^.next;
  3303. end;
  3304. { load next parameter }
  3305. pt:=pt^.right;
  3306. end;
  3307. if not assigned(procs) then
  3308. begin
  3309. { there is an error, must be wrong type, because
  3310. wrong size is already checked (PFV) }
  3311. if (parsing_para_level=0) or (p^.left<>nil) then
  3312. begin
  3313. CGMessage(parser_e_wrong_parameter_type);
  3314. actprocsym^.write_parameter_lists;
  3315. exit;
  3316. end
  3317. else
  3318. begin
  3319. { try to convert to procvar }
  3320. p^.treetype:=loadn;
  3321. p^.resulttype:=pprocsym(p^.symtableprocentry)^.definition;
  3322. p^.symtableentry:=p^.symtableprocentry;
  3323. p^.is_first:=false;
  3324. p^.disposetyp:=dt_nothing;
  3325. firstpass(p);
  3326. exit;
  3327. end;
  3328. end;
  3329. { if there are several choices left then for orddef }
  3330. { if a type is totally included in the other }
  3331. { we don't fear an overflow , }
  3332. { so we can do as if it is an exact match }
  3333. { this will convert integer to longint }
  3334. { rather than to words }
  3335. { conversion of byte to integer or longint }
  3336. {would still not be solved }
  3337. if assigned(procs^.next) then
  3338. begin
  3339. hp:=procs;
  3340. while assigned(hp) do
  3341. begin
  3342. hp^.nextpara:=hp^.firstpara;
  3343. hp:=hp^.next;
  3344. end;
  3345. pt:=p^.left;
  3346. while assigned(pt) do
  3347. begin
  3348. { matches a parameter of one procedure exact ? }
  3349. exactmatch:=false;
  3350. def_from:=pt^.resulttype;
  3351. hp:=procs;
  3352. while assigned(hp) do
  3353. begin
  3354. if not is_equal(hp^.nextpara^.data,pt^.resulttype) then
  3355. begin
  3356. def_to:=hp^.nextpara^.data;
  3357. if ((def_from^.deftype=orddef) and (def_to^.deftype=orddef)) and
  3358. (is_in_limit(def_from,def_to) or
  3359. ((hp^.nextpara^.paratyp=vs_var) and
  3360. (def_from^.size=def_to^.size))) then
  3361. begin
  3362. exactmatch:=true;
  3363. conv_to:=def_to;
  3364. end;
  3365. end;
  3366. hp:=hp^.next;
  3367. end;
  3368. { .... if yes, del all the other procedures }
  3369. if exactmatch then
  3370. begin
  3371. { the first .... }
  3372. while (assigned(procs)) and not(is_in_limit(def_from,procs^.nextpara^.data)) do
  3373. begin
  3374. hp:=procs^.next;
  3375. dispose(procs);
  3376. procs:=hp;
  3377. end;
  3378. { and the others }
  3379. hp:=procs;
  3380. while (assigned(hp)) and assigned(hp^.next) do
  3381. begin
  3382. if not(is_in_limit(def_from,hp^.next^.nextpara^.data)) then
  3383. begin
  3384. hp2:=hp^.next^.next;
  3385. dispose(hp^.next);
  3386. hp^.next:=hp2;
  3387. end
  3388. else
  3389. begin
  3390. def_to:=hp^.next^.nextpara^.data;
  3391. if (conv_to^.size>def_to^.size) or
  3392. ((porddef(conv_to)^.low<porddef(def_to)^.low) and
  3393. (porddef(conv_to)^.high>porddef(def_to)^.high)) then
  3394. begin
  3395. hp2:=procs;
  3396. procs:=hp;
  3397. conv_to:=def_to;
  3398. dispose(hp2);
  3399. end
  3400. else
  3401. hp:=hp^.next;
  3402. end;
  3403. end;
  3404. end;
  3405. { update nextpara for all procedures }
  3406. hp:=procs;
  3407. while assigned(hp) do
  3408. begin
  3409. hp^.nextpara:=hp^.nextpara^.next;
  3410. hp:=hp^.next;
  3411. end;
  3412. pt:=pt^.right;
  3413. end;
  3414. end;
  3415. { let's try to eliminate equal is exact is there }
  3416. {if assigned(procs^.next) then
  3417. begin
  3418. pt:=p^.left;
  3419. while assigned(pt) do
  3420. begin
  3421. if pt^.exact_match_found then
  3422. begin
  3423. hp:=procs;
  3424. while (assigned(procs)) and (procs^.nextpara^.data<>pt^.resulttype) do
  3425. begin
  3426. hp:=procs^.next;
  3427. dispose(procs);
  3428. procs:=hp;
  3429. end;
  3430. end;
  3431. pt:=pt^.right;
  3432. end;
  3433. end; }
  3434. {$ifndef CHAINPROCSYMS}
  3435. if assigned(procs^.next) then
  3436. begin
  3437. CGMessage(cg_e_cant_choose_overload_function);
  3438. actprocsym^.write_parameter_lists;
  3439. end;
  3440. {$else CHAINPROCSYMS}
  3441. if assigned(procs^.next) then
  3442. { if the last retained is the only one }
  3443. { from a unit it is OK PM }
  3444. { the last is the one coming from the first symtable }
  3445. { as the diff defcoll are inserted in front }
  3446. begin
  3447. hp2:=procs;
  3448. while assigned(hp2^.next) and assigned(hp2^.next^.next) do
  3449. hp2:=hp2^.next;
  3450. if (hp2^.data^.owner<>hp2^.next^.data^.owner) then
  3451. begin
  3452. hp:=procs^.next;
  3453. {hp2 is the correct one }
  3454. hp2:=hp2^.next;
  3455. while hp<>hp2 do
  3456. begin
  3457. dispose(procs);
  3458. procs:=hp;
  3459. hp:=procs^.next;
  3460. end;
  3461. procs:=hp2;
  3462. end
  3463. else
  3464. begin
  3465. CGMessage(cg_e_cant_choose_overload_function);
  3466. actprocsym^.write_parameter_lists;
  3467. error(too_much_matches);
  3468. end;
  3469. end;
  3470. {$endif CHAINPROCSYMS}
  3471. {$ifdef UseBrowser}
  3472. if make_ref then
  3473. begin
  3474. procs^.data^.lastref:=new(pref,init(procs^.data^.lastref,@p^.fileinfo));
  3475. end;
  3476. {$endif UseBrowser}
  3477. p^.procdefinition:=procs^.data;
  3478. p^.resulttype:=procs^.data^.retdef;
  3479. { big error for with statements
  3480. p^.symtableproc:=p^.procdefinition^.owner; }
  3481. p^.location.loc:=LOC_MEM;
  3482. {$ifdef CHAINPROCSYMS}
  3483. { object with method read;
  3484. call to read(x) will be a usual procedure call }
  3485. if assigned(p^.methodpointer) and
  3486. (p^.procdefinition^._class=nil) then
  3487. begin
  3488. { not ok for extended }
  3489. case p^.methodpointer^.treetype of
  3490. typen,hnewn : fatalerror(no_para_match);
  3491. end;
  3492. disposetree(p^.methodpointer);
  3493. p^.methodpointer:=nil;
  3494. end;
  3495. {$endif CHAINPROCSYMS}
  3496. end;{ end of procedure to call determination }
  3497. is_const:=((p^.procdefinition^.options and pointernconst)<>0) and
  3498. (p^.left^.left^.treetype in [realconstn,ordconstn]);
  3499. { handle predefined procedures }
  3500. if ((p^.procdefinition^.options and pointernproc)<>0) or is_const then
  3501. begin
  3502. { settextbuf needs two args }
  3503. if assigned(p^.left^.right) then
  3504. pt:=geninlinenode(pprocdef(p^.procdefinition)^.extnumber,is_const,p^.left)
  3505. else
  3506. begin
  3507. pt:=geninlinenode(pprocdef(p^.procdefinition)^.extnumber,is_const,p^.left^.left);
  3508. putnode(p^.left);
  3509. end;
  3510. putnode(p);
  3511. firstpass(pt);
  3512. p:=pt;
  3513. must_be_valid:=store_valid;
  3514. if codegenerror then
  3515. exit;
  3516. dispose(procs);
  3517. exit;
  3518. end
  3519. else
  3520. { no intern procedure => we do a call }
  3521. { calc the correture value for the register }
  3522. { handle predefined procedures }
  3523. if (p^.procdefinition^.options and poinline)<>0 then
  3524. begin
  3525. if assigned(p^.methodpointer) then
  3526. CGMessage(cg_e_unable_inline_object_methods);
  3527. if assigned(p^.right) and (p^.right^.treetype<>procinlinen) then
  3528. CGMessage(cg_e_unable_inline_procvar);
  3529. { p^.treetype:=procinlinen; }
  3530. if not assigned(p^.right) then
  3531. begin
  3532. if assigned(p^.procdefinition^.code) then
  3533. inlinecode:=genprocinlinenode(p,ptree(p^.procdefinition^.code))
  3534. else
  3535. CGMessage(cg_e_no_code_for_inline_stored);
  3536. if assigned(inlinecode) then
  3537. begin
  3538. { consider it has not inlined if called
  3539. again inside the args }
  3540. p^.procdefinition^.options:=p^.procdefinition^.options and (not poinline);
  3541. firstpass(inlinecode);
  3542. inlined:=true;
  3543. end;
  3544. end;
  3545. end
  3546. else
  3547. procinfo.flags:=procinfo.flags or pi_do_call;
  3548. { work trough all parameters to insert the type conversions }
  3549. { !!! done now after internproc !! (PM) }
  3550. if assigned(p^.left) then
  3551. begin
  3552. old_count_ref:=count_ref;
  3553. count_ref:=true;
  3554. firstcallparan(p^.left,p^.procdefinition^.para1);
  3555. count_ref:=old_count_ref;
  3556. end;
  3557. {$ifdef i386}
  3558. for regi:=R_EAX to R_EDI do
  3559. begin
  3560. if (p^.procdefinition^.usedregisters and ($80 shr word(regi)))<>0 then
  3561. inc(reg_pushes[regi],t_times*2);
  3562. end;
  3563. {$endif}
  3564. {$ifdef m68k}
  3565. for regi:=R_D0 to R_A6 do
  3566. begin
  3567. if (p^.procdefinition^.usedregisters and ($800 shr word(regi)))<>0 then
  3568. inc(reg_pushes[regi],t_times*2);
  3569. end;
  3570. {$endif}
  3571. end;
  3572. { ensure that the result type is set }
  3573. p^.resulttype:=p^.procdefinition^.retdef;
  3574. { get a register for the return value }
  3575. if (p^.resulttype<>pdef(voiddef)) then
  3576. begin
  3577. if (p^.procdefinition^.options and poconstructor)<>0 then
  3578. begin
  3579. { extra handling of classes }
  3580. { p^.methodpointer should be assigned! }
  3581. if assigned(p^.methodpointer) and assigned(p^.methodpointer^.resulttype) and
  3582. (p^.methodpointer^.resulttype^.deftype=classrefdef) then
  3583. begin
  3584. p^.location.loc:=LOC_REGISTER;
  3585. p^.registers32:=1;
  3586. { the result type depends on the classref }
  3587. p^.resulttype:=pclassrefdef(p^.methodpointer^.resulttype)^.definition;
  3588. end
  3589. { a object constructor returns the result with the flags }
  3590. else
  3591. p^.location.loc:=LOC_FLAGS;
  3592. end
  3593. else
  3594. begin
  3595. {$ifdef SUPPORT_MMX}
  3596. if (cs_mmx in aktlocalswitches) and
  3597. is_mmx_able_array(p^.resulttype) then
  3598. begin
  3599. p^.location.loc:=LOC_MMXREGISTER;
  3600. p^.registersmmx:=1;
  3601. end
  3602. else
  3603. {$endif SUPPORT_MMX}
  3604. if ret_in_acc(p^.resulttype) then
  3605. begin
  3606. p^.location.loc:=LOC_REGISTER;
  3607. p^.registers32:=1;
  3608. end
  3609. else if (p^.resulttype^.deftype=floatdef) then
  3610. begin
  3611. p^.location.loc:=LOC_FPU;
  3612. p^.registersfpu:=1;
  3613. end
  3614. end;
  3615. end;
  3616. { a fpu can be used in any procedure !! }
  3617. p^.registersfpu:=p^.procdefinition^.fpu_used;
  3618. { if this is a call to a method calc the registers }
  3619. if (p^.methodpointer<>nil) then
  3620. begin
  3621. case p^.methodpointer^.treetype of
  3622. { but only, if this is not a supporting node }
  3623. typen,hnewn : ;
  3624. else
  3625. begin
  3626. { R.Assign is not a constructor !!! }
  3627. { but for R^.Assign, R must be valid !! }
  3628. if ((p^.procdefinition^.options and poconstructor) <> 0) or
  3629. ((p^.methodpointer^.treetype=loadn) and
  3630. ((pobjectdef(p^.methodpointer^.resulttype)^.options and oo_hasvirtual) = 0)) then
  3631. must_be_valid:=false
  3632. else
  3633. must_be_valid:=true;
  3634. firstpass(p^.methodpointer);
  3635. p^.registersfpu:=max(p^.methodpointer^.registersfpu,p^.registersfpu);
  3636. p^.registers32:=max(p^.methodpointer^.registers32,p^.registers32);
  3637. {$ifdef SUPPORT_MMX}
  3638. p^.registersmmx:=max(p^.methodpointer^.registersmmx,p^.registersmmx);
  3639. {$endif SUPPORT_MMX}
  3640. end;
  3641. end;
  3642. end;
  3643. if inlined then
  3644. begin
  3645. p^.right:=inlinecode;
  3646. p^.procdefinition^.options:=p^.procdefinition^.options or poinline;
  3647. end;
  3648. { determine the registers of the procedure variable }
  3649. { is this OK for inlined procs also ?? (PM) }
  3650. if assigned(p^.right) then
  3651. begin
  3652. p^.registersfpu:=max(p^.right^.registersfpu,p^.registersfpu);
  3653. p^.registers32:=max(p^.right^.registers32,p^.registers32);
  3654. {$ifdef SUPPORT_MMX}
  3655. p^.registersmmx:=max(p^.right^.registersmmx,p^.registersmmx);
  3656. {$endif SUPPORT_MMX}
  3657. end;
  3658. { determine the registers of the procedure }
  3659. if assigned(p^.left) then
  3660. begin
  3661. p^.registersfpu:=max(p^.left^.registersfpu,p^.registersfpu);
  3662. p^.registers32:=max(p^.left^.registers32,p^.registers32);
  3663. {$ifdef SUPPORT_MMX}
  3664. p^.registersmmx:=max(p^.left^.registersmmx,p^.registersmmx);
  3665. {$endif SUPPORT_MMX}
  3666. end;
  3667. if assigned(procs) then
  3668. dispose(procs);
  3669. must_be_valid:=store_valid;
  3670. end;
  3671. procedure firstfuncret(var p : ptree);
  3672. begin
  3673. p^.resulttype:=p^.retdef;
  3674. p^.location.loc:=LOC_REFERENCE;
  3675. if ret_in_param(p^.retdef) or
  3676. (@procinfo<>pprocinfo(p^.funcretprocinfo)) then
  3677. p^.registers32:=1;
  3678. { no claim if setting higher return value_str }
  3679. if must_be_valid and
  3680. (@procinfo=pprocinfo(p^.funcretprocinfo)) and
  3681. not procinfo.funcret_is_valid then
  3682. CGMessage(sym_w_function_result_not_set);
  3683. if count_ref then
  3684. pprocinfo(p^.funcretprocinfo)^.funcret_is_valid:=true;
  3685. end;
  3686. { intern inline suborutines }
  3687. procedure firstinline(var p : ptree);
  3688. var
  3689. vl : longint;
  3690. vr : bestreal;
  3691. hp,hpp : ptree;
  3692. store_count_ref,
  3693. isreal,
  3694. dowrite,
  3695. store_valid,
  3696. file_is_typed : boolean;
  3697. procedure do_lowhigh(adef : pdef);
  3698. var
  3699. v : longint;
  3700. enum : penumsym;
  3701. begin
  3702. case Adef^.deftype of
  3703. orddef:
  3704. begin
  3705. if p^.inlinenumber=in_low_x then
  3706. v:=porddef(Adef)^.low
  3707. else
  3708. v:=porddef(Adef)^.high;
  3709. hp:=genordinalconstnode(v,adef);
  3710. firstpass(hp);
  3711. disposetree(p);
  3712. p:=hp;
  3713. end;
  3714. enumdef:
  3715. begin
  3716. enum:=Penumdef(Adef)^.first;
  3717. if p^.inlinenumber=in_high_x then
  3718. while enum^.next<>nil do
  3719. enum:=enum^.next;
  3720. hp:=genenumnode(enum);
  3721. disposetree(p);
  3722. p:=hp;
  3723. end
  3724. end;
  3725. end;
  3726. begin
  3727. store_valid:=must_be_valid;
  3728. store_count_ref:=count_ref;
  3729. count_ref:=false;
  3730. if not (p^.inlinenumber in [in_read_x,in_readln_x,in_sizeof_x,
  3731. in_typeof_x,in_ord_x,in_str_x_string,
  3732. in_reset_typedfile,in_rewrite_typedfile]) then
  3733. must_be_valid:=true
  3734. else
  3735. must_be_valid:=false;
  3736. { if we handle writeln; p^.left contains no valid address }
  3737. if assigned(p^.left) then
  3738. begin
  3739. if p^.left^.treetype=callparan then
  3740. firstcallparan(p^.left,nil)
  3741. else
  3742. firstpass(p^.left);
  3743. left_right_max(p);
  3744. set_location(p^.location,p^.left^.location);
  3745. end;
  3746. { handle intern constant functions in separate case }
  3747. if p^.inlineconst then
  3748. begin
  3749. isreal:=(p^.left^.treetype=realconstn);
  3750. vl:=p^.left^.value;
  3751. vr:=p^.left^.value_real;
  3752. case p^.inlinenumber of
  3753. in_const_trunc : begin
  3754. if isreal then
  3755. hp:=genordinalconstnode(trunc(vr),s32bitdef)
  3756. else
  3757. hp:=genordinalconstnode(trunc(vl),s32bitdef);
  3758. end;
  3759. in_const_round : begin
  3760. if isreal then
  3761. hp:=genordinalconstnode(round(vr),s32bitdef)
  3762. else
  3763. hp:=genordinalconstnode(round(vl),s32bitdef);
  3764. end;
  3765. in_const_frac : begin
  3766. if isreal then
  3767. hp:=genrealconstnode(frac(vr))
  3768. else
  3769. hp:=genrealconstnode(frac(vl));
  3770. end;
  3771. in_const_int : begin
  3772. if isreal then
  3773. hp:=genrealconstnode(int(vr))
  3774. else
  3775. hp:=genrealconstnode(int(vl));
  3776. end;
  3777. in_const_abs : begin
  3778. if isreal then
  3779. hp:=genrealconstnode(abs(vr))
  3780. else
  3781. hp:=genordinalconstnode(abs(vl),p^.left^.resulttype);
  3782. end;
  3783. in_const_sqr : begin
  3784. if isreal then
  3785. hp:=genrealconstnode(sqr(vr))
  3786. else
  3787. hp:=genordinalconstnode(sqr(vl),p^.left^.resulttype);
  3788. end;
  3789. in_const_odd : begin
  3790. if isreal then
  3791. CGMessage(type_e_integer_expr_expected)
  3792. else
  3793. hp:=genordinalconstnode(byte(odd(vl)),booldef);
  3794. end;
  3795. in_const_swap_word : begin
  3796. if isreal then
  3797. CGMessage(type_e_integer_expr_expected)
  3798. else
  3799. hp:=genordinalconstnode((vl and $ff) shl 8+(vl shr 8),p^.left^.resulttype);
  3800. end;
  3801. in_const_swap_long : begin
  3802. if isreal then
  3803. CGMessage(type_e_mismatch)
  3804. else
  3805. hp:=genordinalconstnode((vl and $ffff) shl 16+(vl shr 16),p^.left^.resulttype);
  3806. end;
  3807. in_const_ptr : begin
  3808. if isreal then
  3809. CGMessage(type_e_mismatch)
  3810. else
  3811. hp:=genordinalconstnode(vl,voidpointerdef);
  3812. end;
  3813. else
  3814. internalerror(88);
  3815. end;
  3816. disposetree(p);
  3817. firstpass(hp);
  3818. p:=hp;
  3819. end
  3820. else
  3821. begin
  3822. case p^.inlinenumber of
  3823. in_lo_long,in_hi_long,
  3824. in_lo_word,in_hi_word:
  3825. begin
  3826. if p^.registers32<1 then
  3827. p^.registers32:=1;
  3828. if p^.inlinenumber in [in_lo_word,in_hi_word] then
  3829. p^.resulttype:=u8bitdef
  3830. else
  3831. p^.resulttype:=u16bitdef;
  3832. p^.location.loc:=LOC_REGISTER;
  3833. if not is_integer(p^.left^.resulttype) then
  3834. CGMessage(type_e_mismatch)
  3835. else
  3836. begin
  3837. if p^.left^.treetype=ordconstn then
  3838. begin
  3839. case p^.inlinenumber of
  3840. in_lo_word : hp:=genordinalconstnode(p^.left^.value and $ff,p^.left^.resulttype);
  3841. in_hi_word : hp:=genordinalconstnode(p^.left^.value shr 8,p^.left^.resulttype);
  3842. in_lo_long : hp:=genordinalconstnode(p^.left^.value and $ffff,p^.left^.resulttype);
  3843. in_hi_long : hp:=genordinalconstnode(p^.left^.value shr 16,p^.left^.resulttype);
  3844. end;
  3845. disposetree(p);
  3846. firstpass(hp);
  3847. p:=hp;
  3848. end;
  3849. end;
  3850. end;
  3851. in_sizeof_x:
  3852. begin
  3853. if p^.registers32<1 then
  3854. p^.registers32:=1;
  3855. p^.resulttype:=s32bitdef;
  3856. p^.location.loc:=LOC_REGISTER;
  3857. end;
  3858. in_typeof_x:
  3859. begin
  3860. if p^.registers32<1 then
  3861. p^.registers32:=1;
  3862. p^.location.loc:=LOC_REGISTER;
  3863. p^.resulttype:=voidpointerdef;
  3864. end;
  3865. in_ord_x:
  3866. begin
  3867. if (p^.left^.treetype=ordconstn) then
  3868. begin
  3869. hp:=genordinalconstnode(p^.left^.value,s32bitdef);
  3870. disposetree(p);
  3871. p:=hp;
  3872. firstpass(p);
  3873. end
  3874. else
  3875. begin
  3876. if (p^.left^.resulttype^.deftype=orddef) then
  3877. if (porddef(p^.left^.resulttype)^.typ in [uchar,bool8bit]) then
  3878. begin
  3879. if porddef(p^.left^.resulttype)^.typ=bool8bit then
  3880. begin
  3881. hp:=gentypeconvnode(p^.left,u8bitdef);
  3882. putnode(p);
  3883. p:=hp;
  3884. p^.convtyp:=tc_bool_2_int;
  3885. p^.explizit:=true;
  3886. firstpass(p);
  3887. end
  3888. else
  3889. begin
  3890. hp:=gentypeconvnode(p^.left,u8bitdef);
  3891. putnode(p);
  3892. p:=hp;
  3893. p^.explizit:=true;
  3894. firstpass(p);
  3895. end;
  3896. end
  3897. { can this happen ? }
  3898. else if (porddef(p^.left^.resulttype)^.typ=uvoid) then
  3899. CGMessage(type_e_mismatch)
  3900. else
  3901. { all other orddef need no transformation }
  3902. begin
  3903. hp:=p^.left;
  3904. putnode(p);
  3905. p:=hp;
  3906. end
  3907. else if (p^.left^.resulttype^.deftype=enumdef) then
  3908. begin
  3909. hp:=gentypeconvnode(p^.left,s32bitdef);
  3910. putnode(p);
  3911. p:=hp;
  3912. p^.explizit:=true;
  3913. firstpass(p);
  3914. end
  3915. else
  3916. begin
  3917. { can anything else be ord() ?}
  3918. CGMessage(type_e_mismatch);
  3919. end;
  3920. end;
  3921. end;
  3922. in_chr_byte:
  3923. begin
  3924. hp:=gentypeconvnode(p^.left,cchardef);
  3925. putnode(p);
  3926. p:=hp;
  3927. p^.explizit:=true;
  3928. firstpass(p);
  3929. end;
  3930. in_length_string:
  3931. begin
  3932. {$ifdef UseAnsiString}
  3933. if is_ansistring(p^.left^.resulttype) then
  3934. p^.resulttype:=s32bitdef
  3935. else
  3936. {$endif UseAnsiString}
  3937. p^.resulttype:=u8bitdef;
  3938. { wer don't need string conversations here }
  3939. if (p^.left^.treetype=typeconvn) and
  3940. (p^.left^.left^.resulttype^.deftype=stringdef) then
  3941. begin
  3942. hp:=p^.left^.left;
  3943. putnode(p^.left);
  3944. p^.left:=hp;
  3945. end;
  3946. { evalutes length of constant strings direct }
  3947. if (p^.left^.treetype=stringconstn) then
  3948. begin
  3949. {$ifdef UseAnsiString}
  3950. hp:=genordinalconstnode(p^.left^.length,s32bitdef);
  3951. {$else UseAnsiString}
  3952. hp:=genordinalconstnode(length(p^.left^.value_str^),s32bitdef);
  3953. {$endif UseAnsiString}
  3954. disposetree(p);
  3955. firstpass(hp);
  3956. p:=hp;
  3957. end;
  3958. end;
  3959. in_assigned_x:
  3960. begin
  3961. p^.resulttype:=booldef;
  3962. p^.location.loc:=LOC_FLAGS;
  3963. end;
  3964. in_pred_x,
  3965. in_succ_x:
  3966. begin
  3967. inc(p^.registers32);
  3968. p^.resulttype:=p^.left^.resulttype;
  3969. p^.location.loc:=LOC_REGISTER;
  3970. if not is_ordinal(p^.resulttype) then
  3971. CGMessage(type_e_ordinal_expr_expected)
  3972. else
  3973. begin
  3974. if (p^.resulttype^.deftype=enumdef) and
  3975. (penumdef(p^.resulttype)^.has_jumps) then
  3976. CGMessage(type_e_succ_and_pred_enums_with_assign_not_possible)
  3977. else
  3978. if p^.left^.treetype=ordconstn then
  3979. begin
  3980. if p^.inlinenumber=in_succ_x then
  3981. hp:=genordinalconstnode(p^.left^.value+1,p^.left^.resulttype)
  3982. else
  3983. hp:=genordinalconstnode(p^.left^.value-1,p^.left^.resulttype);
  3984. disposetree(p);
  3985. firstpass(hp);
  3986. p:=hp;
  3987. end;
  3988. end;
  3989. end;
  3990. in_inc_x,
  3991. in_dec_x:
  3992. begin
  3993. p^.resulttype:=voiddef;
  3994. if assigned(p^.left) then
  3995. begin
  3996. firstcallparan(p^.left,nil);
  3997. if codegenerror then
  3998. exit;
  3999. { first param must be var }
  4000. if is_constnode(p^.left^.left) then
  4001. CGMessage(type_e_variable_id_expected);
  4002. { check type }
  4003. if (p^.left^.resulttype^.deftype in [enumdef,pointerdef]) or
  4004. is_ordinal(p^.left^.resulttype) then
  4005. begin
  4006. { two paras ? }
  4007. if assigned(p^.left^.right) then
  4008. begin
  4009. { insert a type conversion }
  4010. { the second param is always longint }
  4011. p^.left^.right^.left:=gentypeconvnode(p^.left^.right^.left,s32bitdef);
  4012. { check the type conversion }
  4013. firstpass(p^.left^.right^.left);
  4014. { need we an additional register ? }
  4015. if not(is_constintnode(p^.left^.right^.left)) and
  4016. (p^.left^.right^.left^.location.loc in [LOC_MEM,LOC_REFERENCE]) and
  4017. (p^.left^.right^.left^.registers32<1) then
  4018. inc(p^.registers32);
  4019. if assigned(p^.left^.right^.right) then
  4020. CGMessage(cg_e_illegal_expression);
  4021. end;
  4022. end
  4023. else
  4024. CGMessage(type_e_ordinal_expr_expected);
  4025. end
  4026. else
  4027. CGMessage(type_e_mismatch);
  4028. end;
  4029. in_read_x,
  4030. in_readln_x,
  4031. in_write_x,
  4032. in_writeln_x :
  4033. begin
  4034. { needs a call }
  4035. procinfo.flags:=procinfo.flags or pi_do_call;
  4036. p^.resulttype:=voiddef;
  4037. { we must know if it is a typed file or not }
  4038. { but we must first do the firstpass for it }
  4039. file_is_typed:=false;
  4040. if assigned(p^.left) then
  4041. begin
  4042. firstcallparan(p^.left,nil);
  4043. { now we can check }
  4044. hp:=p^.left;
  4045. while assigned(hp^.right) do
  4046. hp:=hp^.right;
  4047. { if resulttype is not assigned, then automatically }
  4048. { file is not typed. }
  4049. if assigned(hp) and assigned(hp^.resulttype) then
  4050. Begin
  4051. if (hp^.resulttype^.deftype=filedef) and
  4052. (pfiledef(hp^.resulttype)^.filetype=ft_typed) then
  4053. begin
  4054. file_is_typed:=true;
  4055. { test the type }
  4056. hpp:=p^.left;
  4057. while (hpp<>hp) do
  4058. begin
  4059. if (hpp^.left^.treetype=typen) then
  4060. CGMessage(type_e_cant_read_write_type);
  4061. if not is_equal(hpp^.resulttype,pfiledef(hp^.resulttype)^.typed_as) then
  4062. CGMessage(type_e_mismatch);
  4063. hpp:=hpp^.right;
  4064. end;
  4065. end;
  4066. end; { endif assigned(hp) }
  4067. { insert type conversions for write(ln) }
  4068. if (not file_is_typed) then
  4069. begin
  4070. dowrite:=(p^.inlinenumber in [in_write_x,in_writeln_x]);
  4071. hp:=p^.left;
  4072. while assigned(hp) do
  4073. begin
  4074. if (hp^.left^.treetype=typen) then
  4075. CGMessage(type_e_cant_read_write_type);
  4076. if assigned(hp^.left^.resulttype) then
  4077. begin
  4078. isreal:=false;
  4079. case hp^.left^.resulttype^.deftype of
  4080. filedef : begin
  4081. { only allowed as first parameter }
  4082. if assigned(hp^.right) then
  4083. CGMessage(type_e_cant_read_write_type);
  4084. end;
  4085. stringdef : ;
  4086. pointerdef : begin
  4087. if not is_equal(ppointerdef(hp^.left^.resulttype)^.definition,cchardef) then
  4088. CGMessage(type_e_cant_read_write_type);
  4089. end;
  4090. floatdef : begin
  4091. isreal:=true;
  4092. end;
  4093. orddef : begin
  4094. case porddef(hp^.left^.resulttype)^.typ of
  4095. uchar,
  4096. u32bit,s32bit : ;
  4097. u8bit,s8bit,
  4098. u16bit,s16bit : if dowrite then
  4099. hp^.left:=gentypeconvnode(hp^.left,s32bitdef);
  4100. bool8bit,
  4101. bool16bit,bool32bit : if dowrite then
  4102. hp^.left:=gentypeconvnode(hp^.left,booldef)
  4103. else
  4104. CGMessage(type_e_cant_read_write_type);
  4105. else
  4106. CGMessage(type_e_cant_read_write_type);
  4107. end;
  4108. end;
  4109. arraydef : begin
  4110. if not((parraydef(hp^.left^.resulttype)^.lowrange=0) and
  4111. is_equal(parraydef(hp^.left^.resulttype)^.definition,cchardef)) then
  4112. begin
  4113. { but we convert only if the first index<>0,
  4114. because in this case we have a ASCIIZ string }
  4115. if dowrite and
  4116. (parraydef(hp^.left^.resulttype)^.lowrange<>0) and
  4117. (parraydef(hp^.left^.resulttype)^.definition^.deftype=orddef) and
  4118. (porddef(parraydef(hp^.left^.resulttype)^.definition)^.typ=uchar) then
  4119. hp^.left:=gentypeconvnode(hp^.left,cstringdef)
  4120. else
  4121. CGMessage(type_e_cant_read_write_type);
  4122. end;
  4123. end;
  4124. else
  4125. CGMessage(type_e_cant_read_write_type);
  4126. end;
  4127. { some format options ? }
  4128. (* commented
  4129. because supposes reverse order of parameters
  4130. PM
  4131. hpp:=hp^.right;
  4132. if assigned(hpp) and hpp^.is_colon_para then
  4133. begin
  4134. if (not is_integer(hpp^.resulttype)) then
  4135. CGMessage(type_e_integer_expr_expected)
  4136. else
  4137. hpp^.left:=gentypeconvnode(hpp^.left,s32bitdef);
  4138. hpp:=hpp^.right;
  4139. if assigned(hpp) and hpp^.is_colon_para then
  4140. begin
  4141. if isreal then
  4142. begin
  4143. if (not is_integer(hpp^.resulttype)) then
  4144. CGMessage(type_e_integer_expr_expected)
  4145. else
  4146. hpp^.left:=gentypeconvnode(hpp^.left,s32bitdef);
  4147. end
  4148. else
  4149. CGMessage(parser_e_illegal_colon_qualifier);
  4150. end;
  4151. end; *)
  4152. end;
  4153. hp:=hp^.right;
  4154. end;
  4155. end;
  4156. { pass all parameters again for the typeconversions }
  4157. if codegenerror then
  4158. exit;
  4159. must_be_valid:=true;
  4160. firstcallparan(p^.left,nil);
  4161. { calc registers }
  4162. left_right_max(p);
  4163. end;
  4164. end;
  4165. in_settextbuf_file_x :
  4166. begin
  4167. { warning here p^.left is the callparannode
  4168. not the argument directly }
  4169. { p^.left^.left is text var }
  4170. { p^.left^.right^.left is the buffer var }
  4171. { firstcallparan(p^.left,nil);
  4172. already done in firstcalln }
  4173. { now we know the type of buffer }
  4174. getsymonlyin(systemunit,'SETTEXTBUF');
  4175. hp:=gencallnode(pprocsym(srsym),systemunit);
  4176. hp^.left:=gencallparanode(
  4177. genordinalconstnode(p^.left^.left^.resulttype^.size,s32bitdef),p^.left);
  4178. putnode(p);
  4179. p:=hp;
  4180. firstpass(p);
  4181. end;
  4182. { the firstpass of the arg has been done in firstcalln ? }
  4183. in_reset_typedfile,in_rewrite_typedfile :
  4184. begin
  4185. procinfo.flags:=procinfo.flags or pi_do_call;
  4186. { to be sure the right definition is loaded }
  4187. p^.left^.resulttype:=nil;
  4188. firstload(p^.left);
  4189. p^.resulttype:=voiddef;
  4190. end;
  4191. in_str_x_string :
  4192. begin
  4193. procinfo.flags:=procinfo.flags or pi_do_call;
  4194. p^.resulttype:=voiddef;
  4195. if assigned(p^.left) then
  4196. begin
  4197. hp:=p^.left^.right;
  4198. { first pass just the string for first local use }
  4199. must_be_valid:=false;
  4200. count_ref:=true;
  4201. p^.left^.right:=nil;
  4202. firstcallparan(p^.left,nil);
  4203. must_be_valid:=true;
  4204. p^.left^.right:=hp;
  4205. firstcallparan(p^.left^.right,nil);
  4206. hp:=p^.left;
  4207. { valid string ? }
  4208. if not assigned(hp) or
  4209. (hp^.left^.resulttype^.deftype<>stringdef) or
  4210. (hp^.right=nil) or
  4211. (hp^.left^.location.loc<>LOC_REFERENCE) then
  4212. CGMessage(cg_e_illegal_expression);
  4213. { !!!! check length of string }
  4214. while assigned(hp^.right) do
  4215. hp:=hp^.right;
  4216. { check and convert the first param }
  4217. if hp^.is_colon_para then
  4218. CGMessage(cg_e_illegal_expression);
  4219. isreal:=false;
  4220. case hp^.resulttype^.deftype of
  4221. orddef : begin
  4222. case porddef(hp^.left^.resulttype)^.typ of
  4223. u32bit,s32bit : ;
  4224. u8bit,s8bit,
  4225. u16bit,s16bit : hp^.left:=gentypeconvnode(hp^.left,s32bitdef);
  4226. else
  4227. CGMessage(type_e_integer_or_real_expr_expected);
  4228. end;
  4229. end;
  4230. floatdef : begin
  4231. isreal:=true;
  4232. end;
  4233. else
  4234. CGMessage(type_e_integer_or_real_expr_expected);
  4235. end;
  4236. { some format options ? }
  4237. hpp:=p^.left^.right;
  4238. if assigned(hpp) and hpp^.is_colon_para then
  4239. begin
  4240. if (not is_integer(hpp^.resulttype)) then
  4241. CGMessage(type_e_integer_expr_expected)
  4242. else
  4243. hpp^.left:=gentypeconvnode(hpp^.left,s32bitdef);
  4244. hpp:=hpp^.right;
  4245. if assigned(hpp) and hpp^.is_colon_para then
  4246. begin
  4247. if isreal then
  4248. begin
  4249. if (not is_integer(hpp^.resulttype)) then
  4250. CGMessage(type_e_integer_expr_expected)
  4251. else
  4252. hpp^.left:=gentypeconvnode(hpp^.left,s32bitdef);
  4253. end
  4254. else
  4255. CGMessage(parser_e_illegal_colon_qualifier);
  4256. end;
  4257. end;
  4258. { for first local use }
  4259. must_be_valid:=false;
  4260. count_ref:=true;
  4261. end
  4262. else
  4263. CGMessage(parser_e_illegal_parameter_list);
  4264. { pass all parameters again for the typeconversions }
  4265. if codegenerror then
  4266. exit;
  4267. must_be_valid:=true;
  4268. firstcallparan(p^.left,nil);
  4269. { calc registers }
  4270. left_right_max(p);
  4271. end;
  4272. in_include_x_y,
  4273. in_exclude_x_y:
  4274. begin
  4275. p^.resulttype:=voiddef;
  4276. if assigned(p^.left) then
  4277. begin
  4278. firstcallparan(p^.left,nil);
  4279. p^.registers32:=p^.left^.registers32;
  4280. p^.registersfpu:=p^.left^.registersfpu;
  4281. {$ifdef SUPPORT_MMX}
  4282. p^.registersmmx:=p^.left^.registersmmx;
  4283. {$endif SUPPORT_MMX}
  4284. { first param must be var }
  4285. if (p^.left^.left^.location.loc<>LOC_REFERENCE) and
  4286. (p^.left^.left^.location.loc<>LOC_CREGISTER) then
  4287. CGMessage(cg_e_illegal_expression);
  4288. { check type }
  4289. if (p^.left^.resulttype^.deftype=setdef) then
  4290. begin
  4291. { two paras ? }
  4292. if assigned(p^.left^.right) then
  4293. begin
  4294. { insert a type conversion }
  4295. { to the type of the set elements }
  4296. p^.left^.right^.left:=gentypeconvnode(
  4297. p^.left^.right^.left,
  4298. psetdef(p^.left^.resulttype)^.setof);
  4299. { check the type conversion }
  4300. firstpass(p^.left^.right^.left);
  4301. { only three parameters are allowed }
  4302. if assigned(p^.left^.right^.right) then
  4303. CGMessage(cg_e_illegal_expression);
  4304. end;
  4305. end
  4306. else
  4307. CGMessage(type_e_mismatch);
  4308. end
  4309. else
  4310. CGMessage(type_e_mismatch);
  4311. end;
  4312. in_low_x,in_high_x:
  4313. begin
  4314. if p^.left^.treetype in [typen,loadn] then
  4315. begin
  4316. case p^.left^.resulttype^.deftype of
  4317. orddef,enumdef:
  4318. begin
  4319. do_lowhigh(p^.left^.resulttype);
  4320. firstpass(p);
  4321. end;
  4322. setdef:
  4323. begin
  4324. do_lowhigh(Psetdef(p^.left^.resulttype)^.setof);
  4325. firstpass(p);
  4326. end;
  4327. arraydef:
  4328. begin
  4329. if is_open_array(p^.left^.resulttype) then
  4330. begin
  4331. if p^.inlinenumber=in_low_x then
  4332. begin
  4333. hp:=genordinalconstnode(Parraydef(p^.left^.resulttype)^.lowrange,s32bitdef);
  4334. disposetree(p);
  4335. p:=hp;
  4336. firstpass(p);
  4337. end
  4338. else
  4339. begin
  4340. p^.resulttype:=s32bitdef;
  4341. p^.registers32:=max(1,
  4342. p^.registers32);
  4343. p^.location.loc:=LOC_REGISTER;
  4344. end;
  4345. end
  4346. else
  4347. begin
  4348. if p^.inlinenumber=in_low_x then
  4349. hp:=genordinalconstnode(Parraydef(p^.left^.resulttype)^.lowrange,s32bitdef)
  4350. else
  4351. hp:=genordinalconstnode(Parraydef(p^.left^.resulttype)^.highrange,s32bitdef);
  4352. disposetree(p);
  4353. p:=hp;
  4354. firstpass(p);
  4355. end;
  4356. end;
  4357. stringdef:
  4358. begin
  4359. if p^.inlinenumber=in_low_x then
  4360. hp:=genordinalconstnode(0,u8bitdef)
  4361. else
  4362. hp:=genordinalconstnode(Pstringdef(p^.left^.resulttype)^.len,u8bitdef);
  4363. disposetree(p);
  4364. p:=hp;
  4365. firstpass(p);
  4366. end;
  4367. else
  4368. CGMessage(type_e_mismatch);
  4369. end;
  4370. end
  4371. else
  4372. CGMessage(type_e_varid_or_typeid_expected);
  4373. end
  4374. else internalerror(8);
  4375. end;
  4376. end;
  4377. must_be_valid:=store_valid;
  4378. count_ref:=store_count_ref;
  4379. end;
  4380. procedure firstsubscriptn(var p : ptree);
  4381. begin
  4382. firstpass(p^.left);
  4383. if codegenerror then
  4384. begin
  4385. p^.resulttype:=generrordef;
  4386. exit;
  4387. end;
  4388. p^.resulttype:=p^.vs^.definition;
  4389. { this must be done in the parser
  4390. if count_ref and not must_be_valid then
  4391. if (p^.vs^.properties and sp_protected)<>0 then
  4392. CGMessage(parser_e_cant_write_protected_member);
  4393. }
  4394. p^.registers32:=p^.left^.registers32;
  4395. p^.registersfpu:=p^.left^.registersfpu;
  4396. {$ifdef SUPPORT_MMX}
  4397. p^.registersmmx:=p^.left^.registersmmx;
  4398. {$endif SUPPORT_MMX}
  4399. { classes must be dereferenced implicit }
  4400. if (p^.left^.resulttype^.deftype=objectdef) and
  4401. pobjectdef(p^.left^.resulttype)^.isclass then
  4402. begin
  4403. if p^.registers32=0 then
  4404. p^.registers32:=1;
  4405. p^.location.loc:=LOC_REFERENCE;
  4406. end
  4407. else
  4408. begin
  4409. if (p^.left^.location.loc<>LOC_MEM) and
  4410. (p^.left^.location.loc<>LOC_REFERENCE) then
  4411. CGMessage(cg_e_illegal_expression);
  4412. set_location(p^.location,p^.left^.location);
  4413. end;
  4414. end;
  4415. procedure firstselfn(var p : ptree);
  4416. begin
  4417. if (p^.resulttype^.deftype=classrefdef) or
  4418. ((p^.resulttype^.deftype=objectdef)
  4419. and pobjectdef(p^.resulttype)^.isclass
  4420. ) then
  4421. p^.location.loc:=LOC_REGISTER
  4422. else
  4423. p^.location.loc:=LOC_REFERENCE;
  4424. end;
  4425. procedure firsttypen(var p : ptree);
  4426. begin
  4427. { DM: Why not allowed? For example: low(word) results in a type
  4428. id of word.
  4429. error(typeid_here_not_allowed);}
  4430. end;
  4431. procedure firsthnewn(var p : ptree);
  4432. begin
  4433. end;
  4434. procedure firsthdisposen(var p : ptree);
  4435. begin
  4436. firstpass(p^.left);
  4437. if codegenerror then
  4438. exit;
  4439. p^.registers32:=p^.left^.registers32;
  4440. p^.registersfpu:=p^.left^.registersfpu;
  4441. {$ifdef SUPPORT_MMX}
  4442. p^.registersmmx:=p^.left^.registersmmx;
  4443. {$endif SUPPORT_MMX}
  4444. if p^.registers32<1 then
  4445. p^.registers32:=1;
  4446. {
  4447. if p^.left^.location.loc<>LOC_REFERENCE then
  4448. CGMessage(cg_e_illegal_expression);
  4449. }
  4450. p^.location.loc:=LOC_REFERENCE;
  4451. p^.resulttype:=ppointerdef(p^.left^.resulttype)^.definition;
  4452. end;
  4453. procedure firstnewn(var p : ptree);
  4454. begin
  4455. { Standardeinleitung }
  4456. firstpass(p^.left);
  4457. if codegenerror then
  4458. exit;
  4459. p^.registers32:=p^.left^.registers32;
  4460. p^.registersfpu:=p^.left^.registersfpu;
  4461. {$ifdef SUPPORT_MMX}
  4462. p^.registersmmx:=p^.left^.registersmmx;
  4463. {$endif SUPPORT_MMX}
  4464. { result type is already set }
  4465. procinfo.flags:=procinfo.flags or pi_do_call;
  4466. p^.location.loc:=LOC_REGISTER;
  4467. end;
  4468. procedure firstsimplenewdispose(var p : ptree);
  4469. begin
  4470. { this cannot be in a register !! }
  4471. make_not_regable(p^.left);
  4472. firstpass(p^.left);
  4473. { check the type }
  4474. if (p^.left^.resulttype=nil) or (p^.left^.resulttype^.deftype<>pointerdef) then
  4475. CGMessage(type_e_pointer_type_expected);
  4476. if (p^.left^.location.loc<>LOC_REFERENCE) {and
  4477. (p^.left^.location.loc<>LOC_CREGISTER)} then
  4478. CGMessage(cg_e_illegal_expression);
  4479. p^.registers32:=p^.left^.registers32;
  4480. p^.registersfpu:=p^.left^.registersfpu;
  4481. {$ifdef SUPPORT_MMX}
  4482. p^.registersmmx:=p^.left^.registersmmx;
  4483. {$endif SUPPORT_MMX}
  4484. p^.resulttype:=voiddef;
  4485. procinfo.flags:=procinfo.flags or pi_do_call;
  4486. end;
  4487. procedure firstsetele(var p : ptree);
  4488. begin
  4489. firstpass(p^.left);
  4490. if codegenerror then
  4491. exit;
  4492. if assigned(p^.right) then
  4493. begin
  4494. firstpass(p^.right);
  4495. if codegenerror then
  4496. exit;
  4497. end;
  4498. calcregisters(p,0,0,0);
  4499. p^.resulttype:=p^.left^.resulttype;
  4500. set_location(p^.location,p^.left^.location);
  4501. end;
  4502. procedure firstsetcons(var p : ptree);
  4503. begin
  4504. p^.location.loc:=LOC_MEM;
  4505. end;
  4506. procedure firstin(var p : ptree);
  4507. begin
  4508. p^.location.loc:=LOC_FLAGS;
  4509. p^.resulttype:=booldef;
  4510. firstpass(p^.right);
  4511. if codegenerror then
  4512. exit;
  4513. if p^.right^.resulttype^.deftype<>setdef then
  4514. CGMessage(sym_e_set_expected);
  4515. firstpass(p^.left);
  4516. if codegenerror then
  4517. exit;
  4518. p^.left:=gentypeconvnode(p^.left,psetdef(p^.right^.resulttype)^.setof);
  4519. firstpass(p^.left);
  4520. if codegenerror then
  4521. exit;
  4522. left_right_max(p);
  4523. { this is not allways true due to optimization }
  4524. { but if we don't set this we get problems with optimizing self code }
  4525. if psetdef(p^.right^.resulttype)^.settype<>smallset then
  4526. procinfo.flags:=procinfo.flags or pi_do_call
  4527. else
  4528. begin
  4529. { a smallset needs maybe an misc. register }
  4530. if (p^.left^.treetype<>ordconstn) and
  4531. not(p^.right^.location.loc in [LOC_CREGISTER,LOC_REGISTER]) and
  4532. (p^.right^.registers32<1) then
  4533. inc(p^.registers32);
  4534. end;
  4535. end;
  4536. procedure firststatement(var p : ptree);
  4537. begin
  4538. { left is the next statement in the list }
  4539. p^.resulttype:=voiddef;
  4540. { no temps over several statements }
  4541. cleartempgen;
  4542. { right is the statement itself calln assignn or a complex one }
  4543. firstpass(p^.right);
  4544. if (not (cs_extsyntax in aktmoduleswitches)) and
  4545. assigned(p^.right^.resulttype) and
  4546. (p^.right^.resulttype<>pdef(voiddef)) then
  4547. CGMessage(cg_e_illegal_expression);
  4548. if codegenerror then
  4549. exit;
  4550. p^.registers32:=p^.right^.registers32;
  4551. p^.registersfpu:=p^.right^.registersfpu;
  4552. {$ifdef SUPPORT_MMX}
  4553. p^.registersmmx:=p^.right^.registersmmx;
  4554. {$endif SUPPORT_MMX}
  4555. { left is the next in the list }
  4556. firstpass(p^.left);
  4557. if codegenerror then
  4558. exit;
  4559. if p^.right^.registers32>p^.registers32 then
  4560. p^.registers32:=p^.right^.registers32;
  4561. if p^.right^.registersfpu>p^.registersfpu then
  4562. p^.registersfpu:=p^.right^.registersfpu;
  4563. {$ifdef SUPPORT_MMX}
  4564. if p^.right^.registersmmx>p^.registersmmx then
  4565. p^.registersmmx:=p^.right^.registersmmx;
  4566. {$endif}
  4567. end;
  4568. procedure firstblock(var p : ptree);
  4569. var
  4570. hp : ptree;
  4571. count : longint;
  4572. begin
  4573. count:=0;
  4574. hp:=p^.left;
  4575. while assigned(hp) do
  4576. begin
  4577. if cs_regalloc in aktglobalswitches then
  4578. begin
  4579. { Codeumstellungen }
  4580. { Funktionsresultate an exit anh„ngen }
  4581. { this is wrong for string or other complex
  4582. result types !!! }
  4583. if ret_in_acc(procinfo.retdef) and
  4584. assigned(hp^.left) and
  4585. (hp^.left^.right^.treetype=exitn) and
  4586. (hp^.right^.treetype=assignn) and
  4587. (hp^.right^.left^.treetype=funcretn) then
  4588. begin
  4589. if assigned(hp^.left^.right^.left) then
  4590. CGMessage(cg_n_inefficient_code)
  4591. else
  4592. begin
  4593. hp^.left^.right^.left:=getcopy(hp^.right^.right);
  4594. disposetree(hp^.right);
  4595. hp^.right:=nil;
  4596. end;
  4597. end
  4598. { warning if unreachable code occurs and elimate this }
  4599. else if (hp^.right^.treetype in
  4600. [exitn,breakn,continuen,goton]) and
  4601. assigned(hp^.left) and
  4602. (hp^.left^.treetype<>labeln) then
  4603. begin
  4604. { use correct line number }
  4605. aktfilepos:=hp^.left^.fileinfo;
  4606. disposetree(hp^.left);
  4607. hp^.left:=nil;
  4608. CGMessage(cg_w_unreachable_code);
  4609. { old lines }
  4610. aktfilepos:=hp^.right^.fileinfo;
  4611. end;
  4612. end;
  4613. if assigned(hp^.right) then
  4614. begin
  4615. cleartempgen;
  4616. firstpass(hp^.right);
  4617. if (not (cs_extsyntax in aktmoduleswitches)) and
  4618. assigned(hp^.right^.resulttype) and
  4619. (hp^.right^.resulttype<>pdef(voiddef)) then
  4620. CGMessage(cg_e_illegal_expression);
  4621. if codegenerror then
  4622. exit;
  4623. hp^.registers32:=hp^.right^.registers32;
  4624. hp^.registersfpu:=hp^.right^.registersfpu;
  4625. {$ifdef SUPPORT_MMX}
  4626. hp^.registersmmx:=hp^.right^.registersmmx;
  4627. {$endif SUPPORT_MMX}
  4628. end
  4629. else
  4630. hp^.registers32:=0;
  4631. if hp^.registers32>p^.registers32 then
  4632. p^.registers32:=hp^.registers32;
  4633. if hp^.registersfpu>p^.registersfpu then
  4634. p^.registersfpu:=hp^.registersfpu;
  4635. {$ifdef SUPPORT_MMX}
  4636. if hp^.registersmmx>p^.registersmmx then
  4637. p^.registersmmx:=hp^.registersmmx;
  4638. {$endif}
  4639. inc(count);
  4640. hp:=hp^.left;
  4641. end;
  4642. { p^.registers32:=round(p^.registers32/count); }
  4643. end;
  4644. procedure first_while_repeat(var p : ptree);
  4645. var
  4646. old_t_times : longint;
  4647. begin
  4648. old_t_times:=t_times;
  4649. { Registergewichtung bestimmen }
  4650. if not(cs_littlesize in aktglobalswitches ) then
  4651. t_times:=t_times*8;
  4652. cleartempgen;
  4653. must_be_valid:=true;
  4654. firstpass(p^.left);
  4655. if codegenerror then
  4656. exit;
  4657. if not((p^.left^.resulttype^.deftype=orddef) and
  4658. (porddef(p^.left^.resulttype)^.typ in [bool8bit,bool16bit,bool32bit])) then
  4659. begin
  4660. CGMessage(type_e_mismatch);
  4661. exit;
  4662. end;
  4663. p^.registers32:=p^.left^.registers32;
  4664. p^.registersfpu:=p^.left^.registersfpu;
  4665. {$ifdef SUPPORT_MMX}
  4666. p^.registersmmx:=p^.left^.registersmmx;
  4667. {$endif SUPPORT_MMX}
  4668. { loop instruction }
  4669. if assigned(p^.right) then
  4670. begin
  4671. cleartempgen;
  4672. firstpass(p^.right);
  4673. if codegenerror then
  4674. exit;
  4675. if p^.registers32<p^.right^.registers32 then
  4676. p^.registers32:=p^.right^.registers32;
  4677. if p^.registersfpu<p^.right^.registersfpu then
  4678. p^.registersfpu:=p^.right^.registersfpu;
  4679. {$ifdef SUPPORT_MMX}
  4680. if p^.registersmmx<p^.right^.registersmmx then
  4681. p^.registersmmx:=p^.right^.registersmmx;
  4682. {$endif SUPPORT_MMX}
  4683. end;
  4684. t_times:=old_t_times;
  4685. end;
  4686. procedure firstif(var p : ptree);
  4687. var
  4688. old_t_times : longint;
  4689. hp : ptree;
  4690. begin
  4691. old_t_times:=t_times;
  4692. cleartempgen;
  4693. must_be_valid:=true;
  4694. firstpass(p^.left);
  4695. if codegenerror then
  4696. exit;
  4697. if not((p^.left^.resulttype^.deftype=orddef) and
  4698. (porddef(p^.left^.resulttype)^.typ in [bool8bit,bool16bit,bool32bit])) then
  4699. begin
  4700. CGMessage(type_e_mismatch);
  4701. exit;
  4702. end;
  4703. p^.registers32:=p^.left^.registers32;
  4704. p^.registersfpu:=p^.left^.registersfpu;
  4705. {$ifdef SUPPORT_MMX}
  4706. p^.registersmmx:=p^.left^.registersmmx;
  4707. {$endif SUPPORT_MMX}
  4708. { determines registers weigths }
  4709. if not(cs_littlesize in aktglobalswitches) then
  4710. t_times:=t_times div 2;
  4711. if t_times=0 then
  4712. t_times:=1;
  4713. { if path }
  4714. if assigned(p^.right) then
  4715. begin
  4716. cleartempgen;
  4717. firstpass(p^.right);
  4718. if codegenerror then
  4719. exit;
  4720. if p^.registers32<p^.right^.registers32 then
  4721. p^.registers32:=p^.right^.registers32;
  4722. if p^.registersfpu<p^.right^.registersfpu then
  4723. p^.registersfpu:=p^.right^.registersfpu;
  4724. {$ifdef SUPPORT_MMX}
  4725. if p^.registersmmx<p^.right^.registersmmx then
  4726. p^.registersmmx:=p^.right^.registersmmx;
  4727. {$endif SUPPORT_MMX}
  4728. end;
  4729. { else path }
  4730. if assigned(p^.t1) then
  4731. begin
  4732. cleartempgen;
  4733. firstpass(p^.t1);
  4734. if codegenerror then
  4735. exit;
  4736. if p^.registers32<p^.t1^.registers32 then
  4737. p^.registers32:=p^.t1^.registers32;
  4738. if p^.registersfpu<p^.t1^.registersfpu then
  4739. p^.registersfpu:=p^.t1^.registersfpu;
  4740. {$ifdef SUPPORT_MMX}
  4741. if p^.registersmmx<p^.t1^.registersmmx then
  4742. p^.registersmmx:=p^.t1^.registersmmx;
  4743. {$endif SUPPORT_MMX}
  4744. end;
  4745. if p^.left^.treetype=ordconstn then
  4746. begin
  4747. { optimize }
  4748. if p^.left^.value=1 then
  4749. begin
  4750. disposetree(p^.left);
  4751. hp:=p^.right;
  4752. disposetree(p^.t1);
  4753. { we cannot set p to nil !!! }
  4754. if assigned(hp) then
  4755. begin
  4756. putnode(p);
  4757. p:=hp;
  4758. end
  4759. else
  4760. begin
  4761. p^.left:=nil;
  4762. p^.t1:=nil;
  4763. p^.treetype:=nothingn;
  4764. end;
  4765. end
  4766. else
  4767. begin
  4768. disposetree(p^.left);
  4769. hp:=p^.t1;
  4770. disposetree(p^.right);
  4771. { we cannot set p to nil !!! }
  4772. if assigned(hp) then
  4773. begin
  4774. putnode(p);
  4775. p:=hp;
  4776. end
  4777. else
  4778. begin
  4779. p^.left:=nil;
  4780. p^.right:=nil;
  4781. p^.treetype:=nothingn;
  4782. end;
  4783. end;
  4784. end;
  4785. t_times:=old_t_times;
  4786. end;
  4787. procedure firstexitn(var p : ptree);
  4788. begin
  4789. if assigned(p^.left) then
  4790. begin
  4791. firstpass(p^.left);
  4792. p^.registers32:=p^.left^.registers32;
  4793. p^.registersfpu:=p^.left^.registersfpu;
  4794. {$ifdef SUPPORT_MMX}
  4795. p^.registersmmx:=p^.left^.registersmmx;
  4796. {$endif SUPPORT_MMX}
  4797. end;
  4798. end;
  4799. procedure firstfor(var p : ptree);
  4800. var
  4801. old_t_times : longint;
  4802. begin
  4803. { Registergewichtung bestimmen
  4804. (nicht genau), }
  4805. old_t_times:=t_times;
  4806. if not(cs_littlesize in aktglobalswitches) then
  4807. t_times:=t_times*8;
  4808. cleartempgen;
  4809. if assigned(p^.t1) then
  4810. begin
  4811. firstpass(p^.t1);
  4812. if codegenerror then
  4813. exit;
  4814. end;
  4815. p^.registers32:=p^.t1^.registers32;
  4816. p^.registersfpu:=p^.t1^.registersfpu;
  4817. {$ifdef SUPPORT_MMX}
  4818. p^.registersmmx:=p^.left^.registersmmx;
  4819. {$endif SUPPORT_MMX}
  4820. if p^.left^.treetype<>assignn then
  4821. CGMessage(cg_e_illegal_expression);
  4822. { Laufvariable retten }
  4823. p^.t2:=getcopy(p^.left^.left);
  4824. { Check count var }
  4825. if (p^.t2^.treetype<>loadn) then
  4826. CGMessage(cg_e_illegal_count_var);
  4827. if (not(is_ordinal(p^.t2^.resulttype))) then
  4828. CGMessage(type_e_ordinal_expr_expected);
  4829. cleartempgen;
  4830. must_be_valid:=false;
  4831. firstpass(p^.left);
  4832. must_be_valid:=true;
  4833. if p^.left^.registers32>p^.registers32 then
  4834. p^.registers32:=p^.left^.registers32;
  4835. if p^.left^.registersfpu>p^.registersfpu then
  4836. p^.registersfpu:=p^.left^.registersfpu;
  4837. {$ifdef SUPPORT_MMX}
  4838. if p^.left^.registersmmx>p^.registersmmx then
  4839. p^.registersmmx:=p^.left^.registersmmx;
  4840. {$endif SUPPORT_MMX}
  4841. cleartempgen;
  4842. firstpass(p^.t2);
  4843. if p^.t2^.registers32>p^.registers32 then
  4844. p^.registers32:=p^.t2^.registers32;
  4845. if p^.t2^.registersfpu>p^.registersfpu then
  4846. p^.registersfpu:=p^.t2^.registersfpu;
  4847. {$ifdef SUPPORT_MMX}
  4848. if p^.t2^.registersmmx>p^.registersmmx then
  4849. p^.registersmmx:=p^.t2^.registersmmx;
  4850. {$endif SUPPORT_MMX}
  4851. cleartempgen;
  4852. firstpass(p^.right);
  4853. if p^.right^.treetype<>ordconstn then
  4854. begin
  4855. p^.right:=gentypeconvnode(p^.right,p^.t2^.resulttype);
  4856. cleartempgen;
  4857. firstpass(p^.right);
  4858. end;
  4859. if p^.right^.registers32>p^.registers32 then
  4860. p^.registers32:=p^.right^.registers32;
  4861. if p^.right^.registersfpu>p^.registersfpu then
  4862. p^.registersfpu:=p^.right^.registersfpu;
  4863. {$ifdef SUPPORT_MMX}
  4864. if p^.right^.registersmmx>p^.registersmmx then
  4865. p^.registersmmx:=p^.right^.registersmmx;
  4866. {$endif SUPPORT_MMX}
  4867. t_times:=old_t_times;
  4868. end;
  4869. procedure firstasm(var p : ptree);
  4870. begin
  4871. { it's a f... to determine the used registers }
  4872. { should be done by getnode
  4873. I think also, that all value_str should be set to their maximum (FK)
  4874. p^.registers32:=0;
  4875. p^.registersfpu:=0;
  4876. p^.registersmmx:=0;
  4877. }
  4878. procinfo.flags:=procinfo.flags or pi_uses_asm;
  4879. end;
  4880. procedure firstgoto(var p : ptree);
  4881. begin
  4882. {
  4883. p^.registers32:=0;
  4884. p^.registersfpu:=0;
  4885. }
  4886. p^.resulttype:=voiddef;
  4887. end;
  4888. procedure firstlabel(var p : ptree);
  4889. begin
  4890. cleartempgen;
  4891. firstpass(p^.left);
  4892. p^.registers32:=p^.left^.registers32;
  4893. p^.registersfpu:=p^.left^.registersfpu;
  4894. {$ifdef SUPPORT_MMX}
  4895. p^.registersmmx:=p^.left^.registersmmx;
  4896. {$endif SUPPORT_MMX}
  4897. p^.resulttype:=voiddef;
  4898. end;
  4899. procedure firstcase(var p : ptree);
  4900. var
  4901. old_t_times : longint;
  4902. hp : ptree;
  4903. begin
  4904. { evalutes the case expression }
  4905. cleartempgen;
  4906. must_be_valid:=true;
  4907. firstpass(p^.left);
  4908. if codegenerror then
  4909. exit;
  4910. p^.registers32:=p^.left^.registers32;
  4911. p^.registersfpu:=p^.left^.registersfpu;
  4912. {$ifdef SUPPORT_MMX}
  4913. p^.registersmmx:=p^.left^.registersmmx;
  4914. {$endif SUPPORT_MMX}
  4915. { walk through all instructions }
  4916. { estimates the repeat of each instruction }
  4917. old_t_times:=t_times;
  4918. if not(cs_littlesize in aktglobalswitches) then
  4919. begin
  4920. t_times:=t_times div case_count_labels(p^.nodes);
  4921. if t_times<1 then
  4922. t_times:=1;
  4923. end;
  4924. { first case }
  4925. hp:=p^.right;
  4926. while assigned(hp) do
  4927. begin
  4928. cleartempgen;
  4929. firstpass(hp^.right);
  4930. { searchs max registers }
  4931. if hp^.right^.registers32>p^.registers32 then
  4932. p^.registers32:=hp^.right^.registers32;
  4933. if hp^.right^.registersfpu>p^.registersfpu then
  4934. p^.registersfpu:=hp^.right^.registersfpu;
  4935. {$ifdef SUPPORT_MMX}
  4936. if hp^.right^.registersmmx>p^.registersmmx then
  4937. p^.registersmmx:=hp^.right^.registersmmx;
  4938. {$endif SUPPORT_MMX}
  4939. hp:=hp^.left;
  4940. end;
  4941. { may be handle else tree }
  4942. if assigned(p^.elseblock) then
  4943. begin
  4944. cleartempgen;
  4945. firstpass(p^.elseblock);
  4946. if codegenerror then
  4947. exit;
  4948. if p^.registers32<p^.elseblock^.registers32 then
  4949. p^.registers32:=p^.elseblock^.registers32;
  4950. if p^.registersfpu<p^.elseblock^.registersfpu then
  4951. p^.registersfpu:=p^.elseblock^.registersfpu;
  4952. {$ifdef SUPPORT_MMX}
  4953. if p^.registersmmx<p^.elseblock^.registersmmx then
  4954. p^.registersmmx:=p^.elseblock^.registersmmx;
  4955. {$endif SUPPORT_MMX}
  4956. end;
  4957. t_times:=old_t_times;
  4958. { there is one register required for the case expression }
  4959. if p^.registers32<1 then p^.registers32:=1;
  4960. end;
  4961. procedure firsttryexcept(var p : ptree);
  4962. begin
  4963. cleartempgen;
  4964. firstpass(p^.left);
  4965. { on statements }
  4966. if assigned(p^.right) then
  4967. begin
  4968. cleartempgen;
  4969. firstpass(p^.right);
  4970. p^.registers32:=max(p^.registers32,p^.right^.registers32);
  4971. p^.registersfpu:=max(p^.registersfpu,p^.right^.registersfpu);
  4972. {$ifdef SUPPORT_MMX}
  4973. p^.registersmmx:=max(p^.registersmmx,p^.right^.registersmmx);
  4974. {$endif SUPPORT_MMX}
  4975. end;
  4976. { else block }
  4977. if assigned(p^.t1) then
  4978. begin
  4979. firstpass(p^.t1);
  4980. p^.registers32:=max(p^.registers32,p^.t1^.registers32);
  4981. p^.registersfpu:=max(p^.registersfpu,p^.t1^.registersfpu);
  4982. {$ifdef SUPPORT_MMX}
  4983. p^.registersmmx:=max(p^.registersmmx,p^.t1^.registersmmx);
  4984. {$endif SUPPORT_MMX}
  4985. end;
  4986. end;
  4987. procedure firsttryfinally(var p : ptree);
  4988. begin
  4989. p^.resulttype:=voiddef;
  4990. cleartempgen;
  4991. must_be_valid:=true;
  4992. firstpass(p^.left);
  4993. cleartempgen;
  4994. must_be_valid:=true;
  4995. firstpass(p^.right);
  4996. if codegenerror then
  4997. exit;
  4998. left_right_max(p);
  4999. end;
  5000. procedure firstis(var p : ptree);
  5001. begin
  5002. firstpass(p^.left);
  5003. firstpass(p^.right);
  5004. if (p^.right^.resulttype^.deftype<>classrefdef) then
  5005. CGMessage(type_e_mismatch);
  5006. if codegenerror then
  5007. exit;
  5008. left_right_max(p);
  5009. { left must be a class }
  5010. if (p^.left^.resulttype^.deftype<>objectdef) or
  5011. not(pobjectdef(p^.left^.resulttype)^.isclass) then
  5012. CGMessage(type_e_mismatch);
  5013. { the operands must be related }
  5014. if (not(pobjectdef(p^.left^.resulttype)^.isrelated(
  5015. pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)))) and
  5016. (not(pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)^.isrelated(
  5017. pobjectdef(p^.left^.resulttype)))) then
  5018. CGMessage(type_e_mismatch);
  5019. p^.location.loc:=LOC_FLAGS;
  5020. p^.resulttype:=booldef;
  5021. end;
  5022. procedure firstas(var p : ptree);
  5023. begin
  5024. firstpass(p^.right);
  5025. firstpass(p^.left);
  5026. if (p^.right^.resulttype^.deftype<>classrefdef) then
  5027. CGMessage(type_e_mismatch);
  5028. if codegenerror then
  5029. exit;
  5030. left_right_max(p);
  5031. { left must be a class }
  5032. if (p^.left^.resulttype^.deftype<>objectdef) or
  5033. not(pobjectdef(p^.left^.resulttype)^.isclass) then
  5034. CGMessage(type_e_mismatch);
  5035. { the operands must be related }
  5036. if (not(pobjectdef(p^.left^.resulttype)^.isrelated(
  5037. pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)))) and
  5038. (not(pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)^.isrelated(
  5039. pobjectdef(p^.left^.resulttype)))) then
  5040. CGMessage(type_e_mismatch);
  5041. set_location(p^.location,p^.left^.location);
  5042. p^.resulttype:=pclassrefdef(p^.right^.resulttype)^.definition;
  5043. end;
  5044. procedure firstloadvmt(var p : ptree);
  5045. begin
  5046. { resulttype must be set !
  5047. p^.registersfpu:=0;
  5048. }
  5049. p^.registers32:=1;
  5050. p^.location.loc:=LOC_REGISTER;
  5051. end;
  5052. procedure firstraise(var p : ptree);
  5053. begin
  5054. p^.resulttype:=voiddef;
  5055. {
  5056. p^.registersfpu:=0;
  5057. p^.registers32:=0;
  5058. }
  5059. if assigned(p^.left) then
  5060. begin
  5061. firstpass(p^.left);
  5062. { this must be a _class_ }
  5063. if (p^.left^.resulttype^.deftype<>objectdef) or
  5064. ((pobjectdef(p^.left^.resulttype)^.options and oois_class)=0) then
  5065. CGMessage(type_e_mismatch);
  5066. p^.registersfpu:=p^.left^.registersfpu;
  5067. p^.registers32:=p^.left^.registers32;
  5068. {$ifdef SUPPORT_MMX}
  5069. p^.registersmmx:=p^.left^.registersmmx;
  5070. {$endif SUPPORT_MMX}
  5071. if assigned(p^.right) then
  5072. begin
  5073. firstpass(p^.right);
  5074. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  5075. firstpass(p^.right);
  5076. left_right_max(p);
  5077. end;
  5078. end;
  5079. end;
  5080. procedure firstwith(var p : ptree);
  5081. begin
  5082. if assigned(p^.left) and assigned(p^.right) then
  5083. begin
  5084. firstpass(p^.left);
  5085. if codegenerror then
  5086. exit;
  5087. firstpass(p^.right);
  5088. if codegenerror then
  5089. exit;
  5090. left_right_max(p);
  5091. p^.resulttype:=voiddef;
  5092. end
  5093. else
  5094. begin
  5095. { optimization }
  5096. disposetree(p);
  5097. p:=nil;
  5098. end;
  5099. end;
  5100. procedure firstonn(var p : ptree);
  5101. begin
  5102. { that's really an example procedure for a firstpass :) }
  5103. cleartempgen;
  5104. p^.resulttype:=voiddef;
  5105. p^.registers32:=0;
  5106. p^.registersfpu:=0;
  5107. {$ifdef SUPPORT_MMX}
  5108. p^.registersmmx:=0;
  5109. {$endif SUPPORT_MMX}
  5110. if assigned(p^.left) then
  5111. begin
  5112. firstpass(p^.left);
  5113. p^.registers32:=p^.left^.registers32;
  5114. p^.registersfpu:=p^.left^.registersfpu;
  5115. {$ifdef SUPPORT_MMX}
  5116. p^.registersmmx:=p^.left^.registersmmx;
  5117. {$endif SUPPORT_MMX}
  5118. end;
  5119. cleartempgen;
  5120. if assigned(p^.right) then
  5121. begin
  5122. firstpass(p^.right);
  5123. p^.registers32:=max(p^.registers32,p^.right^.registers32);
  5124. p^.registersfpu:=max(p^.registersfpu,p^.right^.registersfpu);
  5125. {$ifdef SUPPORT_MMX}
  5126. p^.registersmmx:=max(p^.registersmmx,p^.right^.registersmmx);
  5127. {$endif SUPPORT_MMX}
  5128. end;
  5129. end;
  5130. procedure firstprocinline(var p : ptree);
  5131. begin
  5132. {left contains the code in tree form }
  5133. { but it has already been firstpassed }
  5134. { so firstpass(p^.left); does not seem required }
  5135. { might be required later if we change the arg handling !! }
  5136. end;
  5137. type
  5138. firstpassproc = procedure(var p : ptree);
  5139. procedure firstpass(var p : ptree);
  5140. (* ttreetyp = (addn, {Represents the + operator.}
  5141. muln, {Represents the * operator.}
  5142. subn, {Represents the - operator.}
  5143. divn, {Represents the div operator.}
  5144. symdifn, {Represents the >< operator.}
  5145. modn, {Represents the mod operator.}
  5146. assignn, {Represents an assignment.}
  5147. loadn, {Represents the use of a variabele.}
  5148. rangen, {Represents a range (i.e. 0..9).}
  5149. ltn, {Represents the < operator.}
  5150. lten, {Represents the <= operator.}
  5151. gtn, {Represents the > operator.}
  5152. gten, {Represents the >= operator.}
  5153. equaln, {Represents the = operator.}
  5154. unequaln, {Represents the <> operator.}
  5155. inn, {Represents the in operator.}
  5156. orn, {Represents the or operator.}
  5157. xorn, {Represents the xor operator.}
  5158. shrn, {Represents the shr operator.}
  5159. shln, {Represents the shl operator.}
  5160. slashn, {Represents the / operator.}
  5161. andn, {Represents the and operator.}
  5162. subscriptn, {??? Field in a record/object?}
  5163. derefn, {Dereferences a pointer.}
  5164. addrn, {Represents the @ operator.}
  5165. doubleaddrn, {Represents the @@ operator.}
  5166. ordconstn, {Represents an ordinal value.}
  5167. typeconvn, {Represents type-conversion/typecast.}
  5168. calln, {Represents a call node.}
  5169. callparan, {Represents a parameter.}
  5170. realconstn, {Represents a real value.}
  5171. fixconstn, {Represents a fixed value.}
  5172. umminusn, {Represents a sign change (i.e. -2).}
  5173. asmn, {Represents an assembler node }
  5174. vecn, {Represents array indexing.}
  5175. stringconstn, {Represents a string constant.}
  5176. funcretn, {Represents the function result var.}
  5177. selfn, {Represents the self parameter.}
  5178. notn, {Represents the not operator.}
  5179. inlinen, {Internal procedures (i.e. writeln).}
  5180. niln, {Represents the nil pointer.}
  5181. errorn, {This part of the tree could not be
  5182. parsed because of a compiler error.}
  5183. typen, {A type name. Used for i.e. typeof(obj).}
  5184. hnewn, {The new operation, constructor call.}
  5185. hdisposen, {The dispose operation with destructor call.}
  5186. newn, {The new operation, constructor call.}
  5187. simpledisposen, {The dispose operation.}
  5188. setelen, {A set element (i.e. [a,b]).}
  5189. setconstrn, {A set constant (i.e. [1,2]).}
  5190. blockn, {A block of statements.}
  5191. statementn, {One statement in list of nodes.}
  5192. loopn, { used in genloopnode, must be converted }
  5193. ifn, {An if statement.}
  5194. breakn, {A break statement.}
  5195. continuen, {A continue statement.}
  5196. repeatn, {A repeat until block.}
  5197. whilen, {A while do statement.}
  5198. forn, {A for loop.}
  5199. exitn, {An exit statement.}
  5200. withn, {A with statement.}
  5201. casen, {A case statement.}
  5202. labeln, {A label.}
  5203. goton, {A goto statement.}
  5204. simplenewn, {The new operation.}
  5205. tryexceptn, {A try except block.}
  5206. raisen, {A raise statement.}
  5207. switchesn, {??? Currently unused...}
  5208. tryfinallyn, {A try finally statement.}
  5209. isn, {Represents the is operator.}
  5210. asn, {Represents the as typecast.}
  5211. caretn, {Represents the ^ operator.}
  5212. failn, {Represents the fail statement.}
  5213. starstarn, {Represents the ** operator exponentiation }
  5214. procinlinen, {Procedures that can be inlined }
  5215. { added for optimizations where we cannot suppress }
  5216. nothingn,
  5217. loadvmtn); {???.} *)
  5218. const
  5219. procedures : array[ttreetyp] of firstpassproc =
  5220. (firstadd,firstadd,firstadd,firstmoddiv,firstadd,
  5221. firstmoddiv,firstassignment,firstload,firstrange,
  5222. firstadd,firstadd,firstadd,firstadd,
  5223. firstadd,firstadd,firstin,firstadd,
  5224. firstadd,firstshlshr,firstshlshr,firstadd,
  5225. firstadd,firstsubscriptn,firstderef,firstaddr,firstdoubleaddr,
  5226. firstordconst,firsttypeconv,firstcalln,firstnothing,
  5227. firstrealconst,firstfixconst,firstumminus,firstasm,firstvecn,
  5228. firststringconst,firstfuncret,firstselfn,
  5229. firstnot,firstinline,firstniln,firsterror,
  5230. firsttypen,firsthnewn,firsthdisposen,firstnewn,
  5231. firstsimplenewdispose,firstsetele,firstsetcons,firstblock,
  5232. firststatement,firstnothing,firstif,firstnothing,
  5233. firstnothing,first_while_repeat,first_while_repeat,firstfor,
  5234. firstexitn,firstwith,firstcase,firstlabel,
  5235. firstgoto,firstsimplenewdispose,firsttryexcept,
  5236. firstraise,firstnothing,firsttryfinally,
  5237. firstonn,firstis,firstas,firstadd,
  5238. firstnothing,firstadd,firstprocinline,
  5239. firstarrayconstruct,firstarrayconstructrange,
  5240. firstnothing,firstloadvmt);
  5241. var
  5242. oldcodegenerror : boolean;
  5243. oldlocalswitches : tlocalswitches;
  5244. oldpos : tfileposinfo;
  5245. {$ifdef extdebug}
  5246. str1,str2 : string;
  5247. oldp : ptree;
  5248. not_first : boolean;
  5249. {$endif extdebug}
  5250. begin
  5251. {$ifdef extdebug}
  5252. inc(total_of_firstpass);
  5253. if (p^.firstpasscount>0) and only_one_pass then
  5254. exit;
  5255. {$endif extdebug}
  5256. oldcodegenerror:=codegenerror;
  5257. oldpos:=aktfilepos;
  5258. oldlocalswitches:=aktlocalswitches;
  5259. {$ifdef extdebug}
  5260. if p^.firstpasscount>0 then
  5261. begin
  5262. move(p^,str1[1],sizeof(ttree));
  5263. str1[0]:=char(sizeof(ttree));
  5264. new(oldp);
  5265. oldp^:=p^;
  5266. not_first:=true;
  5267. inc(firstpass_several);
  5268. end
  5269. else
  5270. not_first:=false;
  5271. {$endif extdebug}
  5272. aktfilepos:=p^.fileinfo;
  5273. aktlocalswitches:=p^.localswitches;
  5274. if not p^.error then
  5275. begin
  5276. codegenerror:=false;
  5277. procedures[p^.treetype](p);
  5278. p^.error:=codegenerror;
  5279. codegenerror:=codegenerror or oldcodegenerror;
  5280. end
  5281. else
  5282. codegenerror:=true;
  5283. {$ifdef extdebug}
  5284. if not_first then
  5285. begin
  5286. { dirty trick to compare two ttree's (PM) }
  5287. move(p^,str2[1],sizeof(ttree));
  5288. str2[0]:=char(sizeof(ttree));
  5289. if str1<>str2 then
  5290. begin
  5291. comment(v_debug,'tree changed after first counting pass '
  5292. +tostr(longint(p^.treetype)));
  5293. compare_trees(oldp,p);
  5294. end;
  5295. dispose(oldp);
  5296. end;
  5297. if count_ref then
  5298. inc(p^.firstpasscount);
  5299. {$endif extdebug}
  5300. aktlocalswitches:=oldlocalswitches;
  5301. aktfilepos:=oldpos;
  5302. end;
  5303. function do_firstpass(var p : ptree) : boolean;
  5304. begin
  5305. codegenerror:=false;
  5306. firstpass(p);
  5307. do_firstpass:=codegenerror;
  5308. end;
  5309. { to be called only for a whole function }
  5310. { to insert code at entry and exit }
  5311. function function_firstpass(var p : ptree) : boolean;
  5312. begin
  5313. codegenerror:=false;
  5314. firstpass(p);
  5315. function_firstpass:=codegenerror;
  5316. end;
  5317. end.
  5318. {
  5319. $Log$
  5320. Revision 1.93 1998-09-23 17:50:00 peter
  5321. * high(arrayconstructor) is now correct
  5322. * procvardef support for variant record
  5323. Revision 1.92 1998/09/23 15:46:37 florian
  5324. * problem with with and classes fixed
  5325. Revision 1.91 1998/09/23 12:03:53 peter
  5326. * overloading fix for array of const
  5327. Revision 1.90 1998/09/23 09:58:49 peter
  5328. * first working array of const things
  5329. Revision 1.89 1998/09/22 15:34:10 peter
  5330. + pchar -> string conversion
  5331. Revision 1.88 1998/09/21 08:45:14 pierre
  5332. + added vmt_offset in tobjectdef.write for fututre use
  5333. (first steps to have objects without vmt if no virtual !!)
  5334. + added fpu_used field for tabstractprocdef :
  5335. sets this level to 2 if the functions return with value in FPU
  5336. (is then set to correct value at parsing of implementation)
  5337. THIS MIGHT refuse some code with FPU expression too complex
  5338. that were accepted before and even in some cases
  5339. that don't overflow in fact
  5340. ( like if f : float; is a forward that finally in implementation
  5341. only uses one fpu register !!)
  5342. Nevertheless I think that it will improve security on
  5343. FPU operations !!
  5344. * most other changes only for UseBrowser code
  5345. (added symtable references for record and objects)
  5346. local switch for refs to args and local of each function
  5347. (static symtable still missing)
  5348. UseBrowser still not stable and probably broken by
  5349. the definition hash array !!
  5350. Revision 1.87 1998/09/20 18:00:21 florian
  5351. * small compiling problems fixed
  5352. Revision 1.86 1998/09/20 17:46:50 florian
  5353. * some things regarding ansistrings fixed
  5354. Revision 1.85 1998/09/17 09:42:38 peter
  5355. + pass_2 for cg386
  5356. * Message() -> CGMessage() for pass_1/pass_2
  5357. Revision 1.84 1998/09/16 01:06:17 carl
  5358. * bugfix of crash with firstaddr on valid code!
  5359. Revision 1.83 1998/09/11 15:40:21 pierre
  5360. * wrong checks for colon paras in write commented out
  5361. Revision 1.82.2.1 1998/09/11 15:36:37 pierre
  5362. * wrong check code for colon in write commented out
  5363. Revision 1.82 1998/09/09 15:54:42 florian
  5364. * my last fix was buggy, corrected
  5365. Revision 1.81 1998/09/09 14:37:39 florian
  5366. * mod/div for cardinal type fixed
  5367. Revision 1.80 1998/09/08 14:10:11 pierre
  5368. * typen check in read write
  5369. there are probably other inline function that have the same bug !!
  5370. Revision 1.79 1998/09/08 13:50:17 peter
  5371. * removed last fix becasue it was not 100%
  5372. Revision 1.78 1998/09/08 13:36:24 peter
  5373. + can't write type syms anymore
  5374. Revision 1.77 1998/09/07 22:25:52 peter
  5375. * fixed str(boolean,string) which was allowed
  5376. * fixed write(' ':<int expression>) only constants where allowed :(
  5377. Revision 1.76 1998/09/07 18:46:05 peter
  5378. * update smartlinking, uses getdatalabel
  5379. * renamed ptree.value vars to value_str,value_real,value_set
  5380. Revision 1.75 1998/09/05 23:51:06 florian
  5381. * possible bug with too few registers in first/secondin fixed
  5382. Revision 1.74 1998/09/05 23:04:00 florian
  5383. * some fixes to get -Or work:
  5384. - inc/dec didn't take care of CREGISTER
  5385. - register calculcation of inc/dec was wrong
  5386. - var/const parameters get now assigned 32 bit register, but
  5387. const parameters only if they are passed by reference !
  5388. Revision 1.73 1998/09/05 22:29:57 florian
  5389. + the boolean comparision a=true generates now the same code as only a,
  5390. (a=1 was compiled to cmp 1,a now it is compiled to cmp 0,a)
  5391. Revision 1.72 1998/09/05 22:11:01 florian
  5392. + switch -vb
  5393. * while/repeat loops accept now also word/longbool conditions
  5394. * makebooltojump did an invalid ungetregister32, fixed
  5395. Revision 1.71 1998/09/04 11:55:18 florian
  5396. * problem with -Or fixed
  5397. Revision 1.70 1998/09/04 08:42:00 peter
  5398. * updated some error CGMessages
  5399. Revision 1.69 1998/09/01 17:39:47 peter
  5400. + internal constant functions
  5401. Revision 1.68 1998/09/01 09:02:52 peter
  5402. * moved CGMessage() to hcodegen, so pass_2 also uses them
  5403. Revision 1.67 1998/09/01 07:54:20 pierre
  5404. * UseBrowser a little updated (might still be buggy !!)
  5405. * bug in psub.pas in function specifier removed
  5406. * stdcall allowed in interface and in implementation
  5407. (FPC will not yet complain if it is missing in either part
  5408. because stdcall is only a dummy !!)
  5409. Revision 1.66 1998/08/31 08:52:05 peter
  5410. * fixed error 10 with succ() and pref()
  5411. Revision 1.65 1998/08/28 12:51:40 florian
  5412. + ansistring to pchar type cast fixed
  5413. Revision 1.64 1998/08/28 10:54:22 peter
  5414. * fixed smallset generation from elements, it has never worked before!
  5415. Revision 1.63 1998/08/24 10:05:39 florian
  5416. + class types and class reference types are now compatible with void
  5417. pointers
  5418. + class can be stored now registers, even if a type conversation is applied
  5419. Revision 1.62 1998/08/23 16:07:22 florian
  5420. * internalerror with mod/div fixed
  5421. Revision 1.61 1998/08/21 14:08:47 pierre
  5422. + TEST_FUNCRET now default (old code removed)
  5423. works also for m68k (at least compiles)
  5424. Revision 1.60 1998/08/20 12:59:57 peter
  5425. - removed obsolete in_*
  5426. Revision 1.59 1998/08/20 09:26:39 pierre
  5427. + funcret setting in underproc testing
  5428. compile with _dTEST_FUNCRET
  5429. Revision 1.58 1998/08/19 16:07:51 jonas
  5430. * changed optimizer switches + cleanup of DestroyRefs in daopt386.pas
  5431. Revision 1.57 1998/08/19 00:42:39 peter
  5432. + subrange types for enums
  5433. + checking for bounds type with ranges
  5434. Revision 1.56 1998/08/18 09:24:42 pierre
  5435. * small warning position bug fixed
  5436. * support_mmx switches splitting was missing
  5437. * rhide error and warning output corrected
  5438. Revision 1.55 1998/08/14 18:18:44 peter
  5439. + dynamic set contruction
  5440. * smallsets are now working (always longint size)
  5441. Revision 1.54 1998/08/13 11:00:10 peter
  5442. * fixed procedure<>procedure construct
  5443. Revision 1.53 1998/08/12 19:39:28 peter
  5444. * fixed some crashes
  5445. Revision 1.52 1998/08/10 14:50:08 peter
  5446. + localswitches, moduleswitches, globalswitches splitting
  5447. Revision 1.51 1998/08/10 10:18:29 peter
  5448. + Compiler,Comphook unit which are the new interface units to the
  5449. compiler
  5450. Revision 1.50 1998/08/08 21:51:39 peter
  5451. * small crash prevent is firstassignment
  5452. Revision 1.49 1998/07/30 16:07:08 florian
  5453. * try ... expect <statement> end; works now
  5454. Revision 1.48 1998/07/30 13:30:35 florian
  5455. * final implemenation of exception support, maybe it needs
  5456. some fixes :)
  5457. Revision 1.47 1998/07/30 11:18:17 florian
  5458. + first implementation of try ... except on .. do end;
  5459. * limitiation of 65535 bytes parameters for cdecl removed
  5460. Revision 1.46 1998/07/28 21:52:52 florian
  5461. + implementation of raise and try..finally
  5462. + some misc. exception stuff
  5463. Revision 1.45 1998/07/26 21:58:59 florian
  5464. + better support for switch $H
  5465. + index access to ansi strings added
  5466. + assigment of data (records/arrays) containing ansi strings
  5467. Revision 1.44 1998/07/24 22:16:59 florian
  5468. * internal error 10 together with array access fixed. I hope
  5469. that's the final fix.
  5470. Revision 1.43 1998/07/20 18:40:14 florian
  5471. * handling of ansi string constants should now work
  5472. Revision 1.42 1998/07/20 10:23:01 florian
  5473. * better ansi string assignement
  5474. Revision 1.41 1998/07/18 22:54:27 florian
  5475. * some ansi/wide/longstring support fixed:
  5476. o parameter passing
  5477. o returning as result from functions
  5478. Revision 1.40 1998/07/18 17:11:09 florian
  5479. + ansi string constants fixed
  5480. + switch $H partial implemented
  5481. Revision 1.39 1998/07/14 21:46:47 peter
  5482. * updated CGMessages file
  5483. Revision 1.38 1998/07/14 14:46:50 peter
  5484. * released NEWINPUT
  5485. Revision 1.37 1998/07/07 12:31:44 peter
  5486. * fixed string:= which allowed almost any type
  5487. Revision 1.36 1998/07/07 11:20:00 peter
  5488. + NEWINPUT for a better inputfile and scanner object
  5489. Revision 1.35 1998/06/25 14:04:19 peter
  5490. + internal inc/dec
  5491. Revision 1.34 1998/06/25 08:48:14 florian
  5492. * first version of rtti support
  5493. Revision 1.33 1998/06/16 08:56:24 peter
  5494. + targetcpu
  5495. * cleaner pmodules for newppu
  5496. Revision 1.32 1998/06/14 18:23:57 peter
  5497. * fixed xor bug (from mailinglist)
  5498. Revision 1.31 1998/06/13 00:10:09 peter
  5499. * working browser and newppu
  5500. * some small fixes against crashes which occured in bp7 (but not in
  5501. fpc?!)
  5502. Revision 1.30 1998/06/12 10:32:28 pierre
  5503. * column problem hopefully solved
  5504. + C vars declaration changed
  5505. Revision 1.29 1998/06/09 16:01:44 pierre
  5506. + added procedure directive parsing for procvars
  5507. (accepted are popstack cdecl and pascal)
  5508. + added C vars with the following syntax
  5509. var C calias 'true_c_name';(can be followed by external)
  5510. reason is that you must add the Cprefix
  5511. which is target dependent
  5512. Revision 1.28 1998/06/05 14:37:29 pierre
  5513. * fixes for inline for operators
  5514. * inline procedure more correctly restricted
  5515. Revision 1.27 1998/06/05 00:01:06 florian
  5516. * bugs with assigning related objects and passing objects by reference
  5517. to a procedure
  5518. Revision 1.26 1998/06/04 09:55:39 pierre
  5519. * demangled name of procsym reworked to become independant
  5520. of the mangling scheme
  5521. Revision 1.25 1998/06/03 22:48:57 peter
  5522. + wordbool,longbool
  5523. * rename bis,von -> high,low
  5524. * moved some systemunit loading/creating to psystem.pas
  5525. Revision 1.24 1998/06/02 17:03:01 pierre
  5526. * with node corrected for objects
  5527. * small bugs for SUPPORT_MMX fixed
  5528. Revision 1.23 1998/06/01 16:50:20 peter
  5529. + boolean -> ord conversion
  5530. * fixed ord -> boolean conversion
  5531. Revision 1.22 1998/05/28 17:26:49 peter
  5532. * fixed -R switch, it didn't work after my previous akt/init patch
  5533. * fixed bugs 110,130,136
  5534. Revision 1.21 1998/05/25 17:11:41 pierre
  5535. * firstpasscount bug fixed
  5536. now all is already set correctly the first time
  5537. under EXTDEBUG try -gp to skip all other firstpasses
  5538. it works !!
  5539. * small bug fixes
  5540. - for smallsets with -dTESTSMALLSET
  5541. - some warnings removed (by correcting code !)
  5542. Revision 1.20 1998/05/23 01:21:17 peter
  5543. + aktasmmode, aktoptprocessor, aktoutputformat
  5544. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  5545. + $LIBNAME to set the library name where the unit will be put in
  5546. * splitted cgi386 a bit (codeseg to large for bp7)
  5547. * nasm, tasm works again. nasm moved to ag386nsm.pas
  5548. Revision 1.19 1998/05/20 09:42:34 pierre
  5549. + UseTokenInfo now default
  5550. * unit in interface uses and implementation uses gives error now
  5551. * only one error for unknown symbol (uses lastsymknown boolean)
  5552. the problem came from the label code !
  5553. + first inlined procedures and function work
  5554. (warning there might be allowed cases were the result is still wrong !!)
  5555. * UseBrower updated gives a global list of all position of all used symbols
  5556. with switch -gb
  5557. Revision 1.18 1998/05/11 13:07:55 peter
  5558. + $ifdef NEWPPU for the new ppuformat
  5559. + $define GDB not longer required
  5560. * removed all warnings and stripped some log comments
  5561. * no findfirst/findnext anymore to remove smartlink *.o files
  5562. Revision 1.17 1998/05/06 08:38:43 pierre
  5563. * better position info with UseTokenInfo
  5564. UseTokenInfo greatly simplified
  5565. + added check for changed tree after first time firstpass
  5566. (if we could remove all the cases were it happen
  5567. we could skip all firstpass if firstpasscount > 1)
  5568. Only with ExtDebug
  5569. Revision 1.16 1998/05/01 16:38:45 florian
  5570. * handling of private and protected fixed
  5571. + change_keywords_to_tp implemented to remove
  5572. keywords which aren't supported by tp
  5573. * break and continue are now symbols of the system unit
  5574. + widestring, longstring and ansistring type released
  5575. Revision 1.15 1998/05/01 09:01:23 florian
  5576. + correct semantics of private and protected
  5577. * small fix in variable scope:
  5578. a id can be used in a parameter list of a method, even it is used in
  5579. an anchestor class as field id
  5580. Revision 1.14 1998/04/30 15:59:41 pierre
  5581. * GDB works again better :
  5582. correct type info in one pass
  5583. + UseTokenInfo for better source position
  5584. * fixed one remaining bug in scanner for line counts
  5585. * several little fixes
  5586. Revision 1.13 1998/04/29 10:33:56 pierre
  5587. + added some code for ansistring (not complete nor working yet)
  5588. * corrected operator overloading
  5589. * corrected nasm output
  5590. + started inline procedures
  5591. + added starstarn : use ** for exponentiation (^ gave problems)
  5592. + started UseTokenInfo cond to get accurate positions
  5593. Revision 1.12 1998/04/22 21:06:50 florian
  5594. * last fixes before the release:
  5595. - veryyyy slow firstcall fixed
  5596. Revision 1.11 1998/04/21 10:16:48 peter
  5597. * patches from strasbourg
  5598. * objects is not used anymore in the fpc compiled version
  5599. Revision 1.10 1998/04/14 23:27:03 florian
  5600. + exclude/include with constant second parameter added
  5601. Revision 1.9 1998/04/13 21:15:42 florian
  5602. * error handling of pass_1 and cgi386 fixed
  5603. * the following bugs fixed: 0117, 0118, 0119 and 0129, 0122 was already
  5604. fixed, verified
  5605. Revision 1.8 1998/04/13 08:42:52 florian
  5606. * call by reference and call by value open arrays fixed
  5607. Revision 1.7 1998/04/12 22:39:44 florian
  5608. * problem with read access to properties solved
  5609. * correct handling of hidding methods via virtual (COM)
  5610. * correct result type of constructor calls (COM), the resulttype
  5611. depends now on the type of the class reference
  5612. Revision 1.6 1998/04/09 22:16:34 florian
  5613. * problem with previous REGALLOC solved
  5614. * improved property support
  5615. Revision 1.5 1998/04/08 16:58:04 pierre
  5616. * several bugfixes
  5617. ADD ADC and AND are also sign extended
  5618. nasm output OK (program still crashes at end
  5619. and creates wrong assembler files !!)
  5620. procsym types sym in tdef removed !!
  5621. Revision 1.4 1998/04/07 22:45:04 florian
  5622. * bug0092, bug0115 and bug0121 fixed
  5623. + packed object/class/array
  5624. }