pass_1.pas 188 KB

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