pass_1.pas 204 KB

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