pass_1.pas 221 KB

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