pass_1.pas 193 KB

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