pass_1.pas 177 KB

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