pass_1.pas 213 KB

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