pass_1.pas 219 KB

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