pass_1.pas 193 KB

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