pass_1.pas 175 KB

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