pass_1.pas 203 KB

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