pass_1.pas 174 KB

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