pass_1.pas 190 KB

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