pass_1.pas 210 KB

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