pass_1.pas 185 KB

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