pass_1.pas 206 KB

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