pass_1.pas 189 KB

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