pass_1.pas 186 KB

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