pass_1.pas 203 KB

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