pass_1.pas 179 KB

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