pass_1.pas 201 KB

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