pass_1.pas 187 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014
  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. exit;
  1715. p^.registers32:=max(p^.left^.registers32,1);
  1716. p^.registersfpu:=p^.left^.registersfpu;
  1717. {$ifdef SUPPORT_MMX}
  1718. p^.registersmmx:=p^.left^.registersmmx;
  1719. {$endif SUPPORT_MMX}
  1720. if p^.left^.resulttype^.deftype<>pointerdef then
  1721. Message(cg_e_invalid_qualifier);
  1722. p^.resulttype:=ppointerdef(p^.left^.resulttype)^.definition;
  1723. p^.location.loc:=LOC_REFERENCE;
  1724. end;
  1725. procedure firstrange(var p : ptree);
  1726. var
  1727. ct : tconverttype;
  1728. begin
  1729. firstpass(p^.left);
  1730. firstpass(p^.right);
  1731. if codegenerror then
  1732. exit;
  1733. { allow only ordinal constants }
  1734. if not((p^.left^.treetype=ordconstn) and
  1735. (p^.right^.treetype=ordconstn)) then
  1736. Message(cg_e_illegal_expression);
  1737. { upper limit must be greater or equalt than lower limit }
  1738. { not if u32bit }
  1739. if (p^.left^.value>p^.right^.value) and
  1740. (( p^.left^.value<0) or (p^.right^.value>=0)) then
  1741. Message(cg_e_upper_lower_than_lower);
  1742. { both types must be compatible }
  1743. if not(isconvertable(p^.left^.resulttype,p^.right^.resulttype,
  1744. ct,ordconstn,false)) and
  1745. not(is_equal(p^.left^.resulttype,p^.right^.resulttype)) then
  1746. Message(sym_e_type_mismatch);
  1747. end;
  1748. procedure firstvecn(var p : ptree);
  1749. var
  1750. harr : pdef;
  1751. ct : tconverttype;
  1752. begin
  1753. firstpass(p^.left);
  1754. firstpass(p^.right);
  1755. if codegenerror then
  1756. exit;
  1757. { range check only for arrays }
  1758. if (p^.left^.resulttype^.deftype=arraydef) then
  1759. begin
  1760. if not(isconvertable(p^.right^.resulttype,
  1761. parraydef(p^.left^.resulttype)^.rangedef,
  1762. ct,ordconstn,false)) and
  1763. not(is_equal(p^.right^.resulttype,
  1764. parraydef(p^.left^.resulttype)^.rangedef)) then
  1765. Message(sym_e_type_mismatch);
  1766. end;
  1767. { Never convert a boolean or a char !}
  1768. { maybe type conversion }
  1769. if (p^.right^.resulttype^.deftype<>enumdef) and
  1770. not ((p^.right^.resulttype^.deftype=orddef) and
  1771. (Porddef(p^.right^.resulttype)^.typ in [bool8bit,uchar])) then
  1772. begin
  1773. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  1774. { once more firstpass }
  1775. {?? It's better to only firstpass when the tree has
  1776. changed, isn't it ?}
  1777. firstpass(p^.right);
  1778. end;
  1779. if codegenerror then
  1780. exit;
  1781. { determine return type }
  1782. if not assigned(p^.resulttype) then
  1783. if p^.left^.resulttype^.deftype=arraydef then
  1784. p^.resulttype:=parraydef(p^.left^.resulttype)^.definition
  1785. else if (p^.left^.resulttype^.deftype=pointerdef) then
  1786. begin
  1787. { convert pointer to array }
  1788. harr:=new(parraydef,init(0,$7fffffff,s32bitdef));
  1789. parraydef(harr)^.definition:=ppointerdef(p^.left^.resulttype)^.definition;
  1790. p^.left:=gentypeconvnode(p^.left,harr);
  1791. firstpass(p^.left);
  1792. if codegenerror then
  1793. exit;
  1794. p^.resulttype:=parraydef(harr)^.definition
  1795. end
  1796. else
  1797. { indexed access to arrays }
  1798. p^.resulttype:=cchardef;
  1799. { the register calculation is easy if a const index is used }
  1800. if p^.right^.treetype=ordconstn then
  1801. p^.registers32:=p^.left^.registers32
  1802. else
  1803. begin
  1804. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  1805. { not correct, but what works better ? }
  1806. if p^.left^.registers32>0 then
  1807. p^.registers32:=max(p^.registers32,2)
  1808. else
  1809. { min. one register }
  1810. p^.registers32:=max(p^.registers32,1);
  1811. end;
  1812. p^.registersfpu:=max(p^.left^.registersfpu,p^.right^.registersfpu);
  1813. {$ifdef SUPPORT_MMX}
  1814. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  1815. {$endif SUPPORT_MMX}
  1816. p^.location.loc:=p^.left^.location.loc;
  1817. end;
  1818. type
  1819. tfirstconvproc = procedure(var p : ptree);
  1820. procedure first_bigger_smaller(var p : ptree);
  1821. begin
  1822. if (p^.left^.location.loc<>LOC_REGISTER) and (p^.registers32=0) then
  1823. p^.registers32:=1;
  1824. p^.location.loc:=LOC_REGISTER;
  1825. end;
  1826. procedure first_cstring_charpointer(var p : ptree);
  1827. begin
  1828. p^.registers32:=1;
  1829. p^.location.loc:=LOC_REGISTER;
  1830. end;
  1831. procedure first_string_chararray(var p : ptree);
  1832. begin
  1833. p^.registers32:=1;
  1834. p^.location.loc:=LOC_REGISTER;
  1835. end;
  1836. procedure first_string_string(var p : ptree);
  1837. begin
  1838. if pstringdef(p^.resulttype)^.string_typ<>
  1839. pstringdef(p^.left^.resulttype)^.string_typ then
  1840. begin
  1841. { call shortstring_to_ansistring or ansistring_to_shortstring }
  1842. procinfo.flags:=procinfo.flags or pi_do_call;
  1843. end;
  1844. { for simplicity lets first keep all ansistrings
  1845. as LOC_MEM, could also become LOC_REGISTER }
  1846. p^.location.loc:=LOC_MEM;
  1847. end;
  1848. procedure first_char_to_string(var p : ptree);
  1849. var
  1850. hp : ptree;
  1851. begin
  1852. if p^.left^.treetype=ordconstn then
  1853. begin
  1854. hp:=genstringconstnode(chr(p^.left^.value));
  1855. firstpass(hp);
  1856. disposetree(p);
  1857. p:=hp;
  1858. end
  1859. else
  1860. p^.location.loc:=LOC_MEM;
  1861. end;
  1862. procedure first_nothing(var p : ptree);
  1863. begin
  1864. p^.location.loc:=LOC_MEM;
  1865. end;
  1866. procedure first_array_to_pointer(var p : ptree);
  1867. begin
  1868. if p^.registers32<1 then
  1869. p^.registers32:=1;
  1870. p^.location.loc:=LOC_REGISTER;
  1871. end;
  1872. procedure first_int_real(var p : ptree);
  1873. var t : ptree;
  1874. begin
  1875. if p^.left^.treetype=ordconstn then
  1876. begin
  1877. { convert constants direct }
  1878. { not because of type conversion }
  1879. t:=genrealconstnode(p^.left^.value);
  1880. { do a first pass here
  1881. because firstpass of typeconv does
  1882. not redo it for left field !! }
  1883. firstpass(t);
  1884. { the type can be something else than s64real !!}
  1885. t:=gentypeconvnode(t,p^.resulttype);
  1886. firstpass(t);
  1887. disposetree(p);
  1888. p:=t;
  1889. exit;
  1890. end
  1891. else
  1892. begin
  1893. if p^.registersfpu<1 then
  1894. p^.registersfpu:=1;
  1895. p^.location.loc:=LOC_FPU;
  1896. end;
  1897. end;
  1898. procedure first_int_fix(var p : ptree);
  1899. begin
  1900. if p^.left^.treetype=ordconstn then
  1901. begin
  1902. { convert constants direct }
  1903. p^.treetype:=fixconstn;
  1904. p^.valuef:=p^.left^.value shl 16;
  1905. p^.disposetyp:=dt_nothing;
  1906. disposetree(p^.left);
  1907. p^.location.loc:=LOC_MEM;
  1908. end
  1909. else
  1910. begin
  1911. if p^.registers32<1 then
  1912. p^.registers32:=1;
  1913. p^.location.loc:=LOC_REGISTER;
  1914. end;
  1915. end;
  1916. procedure first_real_fix(var p : ptree);
  1917. begin
  1918. if p^.left^.treetype=realconstn then
  1919. begin
  1920. { convert constants direct }
  1921. p^.treetype:=fixconstn;
  1922. p^.valuef:=round(p^.left^.valued*65536);
  1923. p^.disposetyp:=dt_nothing;
  1924. disposetree(p^.left);
  1925. p^.location.loc:=LOC_MEM;
  1926. end
  1927. else
  1928. begin
  1929. { at least one fpu and int register needed }
  1930. if p^.registers32<1 then
  1931. p^.registers32:=1;
  1932. if p^.registersfpu<1 then
  1933. p^.registersfpu:=1;
  1934. p^.location.loc:=LOC_REGISTER;
  1935. end;
  1936. end;
  1937. procedure first_fix_real(var p : ptree);
  1938. begin
  1939. if p^.left^.treetype=fixconstn then
  1940. begin
  1941. { convert constants direct }
  1942. p^.treetype:=realconstn;
  1943. p^.valued:=round(p^.left^.valuef/65536.0);
  1944. p^.disposetyp:=dt_nothing;
  1945. disposetree(p^.left);
  1946. p^.location.loc:=LOC_MEM;
  1947. end
  1948. else
  1949. begin
  1950. if p^.registersfpu<1 then
  1951. p^.registersfpu:=1;
  1952. p^.location.loc:=LOC_FPU;
  1953. end;
  1954. end;
  1955. procedure first_real_real(var p : ptree);
  1956. begin
  1957. if p^.registersfpu<1 then
  1958. p^.registersfpu:=1;
  1959. p^.location.loc:=LOC_FPU;
  1960. end;
  1961. procedure first_pointer_to_array(var p : ptree);
  1962. begin
  1963. if p^.registers32<1 then
  1964. p^.registers32:=1;
  1965. p^.location.loc:=LOC_REFERENCE;
  1966. end;
  1967. procedure first_chararray_string(var p : ptree);
  1968. begin
  1969. { the only important information is the location of the }
  1970. { result }
  1971. { other stuff is done by firsttypeconv }
  1972. p^.location.loc:=LOC_MEM;
  1973. end;
  1974. procedure first_cchar_charpointer(var p : ptree);
  1975. begin
  1976. p^.left:=gentypeconvnode(p^.left,cstringdef);
  1977. { convert constant char to constant string }
  1978. firstpass(p^.left);
  1979. { evalute tree }
  1980. firstpass(p);
  1981. end;
  1982. procedure first_locmem(var p : ptree);
  1983. begin
  1984. p^.location.loc:=LOC_MEM;
  1985. end;
  1986. procedure first_bool_byte(var p : ptree);
  1987. begin
  1988. p^.location.loc:=LOC_REGISTER;
  1989. { Florian I think this is overestimated
  1990. but I still do not really understand how to get this right (PM) }
  1991. { Hmmm, I think we need only one reg to return the result of }
  1992. { this node => so }
  1993. if p^.registers32<1 then
  1994. p^.registers32:=1;
  1995. { should work (FK)
  1996. p^.registers32:=p^.left^.registers32+1;}
  1997. end;
  1998. procedure first_proc_to_procvar(var p : ptree);
  1999. begin
  2000. firstpass(p^.left);
  2001. if codegenerror then
  2002. exit;
  2003. if (p^.left^.location.loc<>LOC_REFERENCE) then
  2004. Message(cg_e_illegal_expression);
  2005. p^.registers32:=p^.left^.registers32;
  2006. if p^.registers32<1 then
  2007. p^.registers32:=1;
  2008. p^.location.loc:=LOC_REGISTER;
  2009. end;
  2010. function is_procsym_load(p:Ptree):boolean;
  2011. begin
  2012. is_procsym_load:=((p^.treetype=loadn) and (p^.symtableentry^.typ=procsym)) or
  2013. ((p^.treetype=addrn) and (p^.left^.treetype=loadn)
  2014. and (p^.left^.symtableentry^.typ=procsym)) ;
  2015. end;
  2016. { change a proc call to a procload for assignment to a procvar }
  2017. { this can only happen for proc/function without arguments }
  2018. function is_procsym_call(p:Ptree):boolean;
  2019. begin
  2020. is_procsym_call:=(p^.treetype=calln) and (p^.left=nil) and
  2021. (((p^.symtableprocentry^.typ=procsym) and (p^.right=nil)) or
  2022. ((p^.right<>nil) and (p^.right^.symtableprocentry^.typ=varsym)));
  2023. end;
  2024. {***}
  2025. function is_assignment_overloaded(from_def,to_def : pdef) : boolean;
  2026. var
  2027. passproc : pprocdef;
  2028. begin
  2029. is_assignment_overloaded:=false;
  2030. if assigned(overloaded_operators[assignment]) then
  2031. passproc:=overloaded_operators[assignment]^.definition
  2032. else
  2033. passproc:=nil;
  2034. while passproc<>nil do
  2035. begin
  2036. if (passproc^.retdef=to_def) and (passproc^.para1^.data=from_def) then
  2037. begin
  2038. is_assignment_overloaded:=true;
  2039. break;
  2040. end;
  2041. passproc:=passproc^.nextoverloaded;
  2042. end;
  2043. end;
  2044. { Attention: do *** no *** recursive call of firstpass }
  2045. { because the child tree is always passed }
  2046. procedure firsttypeconv(var p : ptree);
  2047. var
  2048. hp : ptree;
  2049. aprocdef : pprocdef;
  2050. proctype : tdeftype;
  2051. const
  2052. firstconvert : array[tc_u8bit_2_s32bit..tc_cchar_charpointer] of
  2053. tfirstconvproc = (first_bigger_smaller,first_nothing,first_bigger_smaller,
  2054. first_bigger_smaller,first_bigger_smaller,
  2055. first_bigger_smaller,first_bigger_smaller,
  2056. first_bigger_smaller,first_string_string,
  2057. first_cstring_charpointer,first_string_chararray,
  2058. first_array_to_pointer,first_pointer_to_array,
  2059. first_char_to_string,first_bigger_smaller,
  2060. first_bigger_smaller,first_bigger_smaller,
  2061. first_bigger_smaller,first_bigger_smaller,
  2062. first_bigger_smaller,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_int_real,first_real_fix,
  2070. first_fix_real,first_int_fix,first_real_real,
  2071. first_locmem,first_bool_byte,first_proc_to_procvar,
  2072. first_cchar_charpointer);
  2073. begin
  2074. aprocdef:=nil;
  2075. { if explicite type conversation, then run firstpass }
  2076. if p^.explizit then
  2077. firstpass(p^.left);
  2078. if codegenerror then
  2079. exit;
  2080. if not assigned(p^.left^.resulttype) then
  2081. begin
  2082. codegenerror:=true;
  2083. internalerror(52349);
  2084. exit;
  2085. end;
  2086. { remove obsolete type conversions }
  2087. if is_equal(p^.left^.resulttype,p^.resulttype) then
  2088. begin
  2089. hp:=p;
  2090. p:=p^.left;
  2091. p^.resulttype:=hp^.resulttype;
  2092. putnode(hp);
  2093. exit;
  2094. end;
  2095. p^.registers32:=p^.left^.registers32;
  2096. p^.registersfpu:=p^.left^.registersfpu;
  2097. {$ifdef SUPPORT_MMX}
  2098. p^.registersmmx:=p^.left^.registersmmx;
  2099. {$endif}
  2100. set_location(p^.location,p^.left^.location);
  2101. if (not(isconvertable(p^.left^.resulttype,p^.resulttype,
  2102. p^.convtyp,p^.left^.treetype,p^.explizit))) then
  2103. begin
  2104. if is_assignment_overloaded(p^.left^.resulttype,p^.resulttype) then
  2105. begin
  2106. procinfo.flags:=procinfo.flags or pi_do_call;
  2107. hp:=gencallnode(overloaded_operators[assignment],nil);
  2108. hp^.left:=gencallparanode(p^.left,nil);
  2109. putnode(p);
  2110. p:=hp;
  2111. firstpass(p);
  2112. exit;
  2113. end;
  2114. {Procedures have a resulttype of voiddef and functions of their
  2115. own resulttype. They will therefore always be incompatible with
  2116. a procvar. Because isconvertable cannot check for procedures we
  2117. use an extra check for them.}
  2118. if (cs_tp_compatible in aktswitches) and
  2119. ((is_procsym_load(p^.left) or is_procsym_call(p^.left)) and
  2120. (p^.resulttype^.deftype=procvardef)) then
  2121. begin
  2122. { just a test: p^.explizit:=false; }
  2123. if is_procsym_call(p^.left) then
  2124. begin
  2125. if p^.left^.right=nil then
  2126. begin
  2127. p^.left^.treetype:=loadn;
  2128. { are at same offset so this could be spared, but
  2129. it more secure to do it anyway }
  2130. p^.left^.symtableentry:=p^.left^.symtableprocentry;
  2131. p^.left^.resulttype:=pprocsym(p^.left^.symtableentry)^.definition;
  2132. aprocdef:=pprocdef(p^.left^.resulttype);
  2133. end
  2134. else
  2135. begin
  2136. p^.left^.right^.treetype:=loadn;
  2137. p^.left^.right^.symtableentry:=p^.left^.right^.symtableentry;
  2138. P^.left^.right^.resulttype:=pvarsym(p^.left^.symtableentry)^.definition;
  2139. hp:=p^.left^.right;
  2140. putnode(p^.left);
  2141. p^.left:=hp;
  2142. { should we do that ? }
  2143. firstpass(p^.left);
  2144. if not is_equal(p^.left^.resulttype,p^.resulttype) then
  2145. begin
  2146. Message(sym_e_type_mismatch);
  2147. exit;
  2148. end
  2149. else
  2150. begin
  2151. hp:=p;
  2152. p:=p^.left;
  2153. p^.resulttype:=hp^.resulttype;
  2154. putnode(hp);
  2155. exit;
  2156. end;
  2157. end;
  2158. end
  2159. else
  2160. begin
  2161. if p^.left^.treetype=addrn then
  2162. begin
  2163. hp:=p^.left;
  2164. p^.left:=p^.left^.left;
  2165. putnode(p^.left);
  2166. end
  2167. else
  2168. aprocdef:=pprocsym(p^.left^.symtableentry)^.definition;
  2169. end;
  2170. p^.convtyp:=tc_proc2procvar;
  2171. { Now check if the procedure we are going to assign to
  2172. the procvar, is compatible with the procvar's type.
  2173. Did the original procvar support do such a check?
  2174. I can't find any.}
  2175. { answer : is_equal works for procvardefs !! }
  2176. { but both must be procvardefs, so we cheet little }
  2177. if assigned(aprocdef) then
  2178. begin
  2179. proctype:=aprocdef^.deftype;
  2180. aprocdef^.deftype:=procvardef;
  2181. if not is_equal(aprocdef,p^.resulttype) then
  2182. begin
  2183. aprocdef^.deftype:=proctype;
  2184. Message(sym_e_type_mismatch);
  2185. end;
  2186. aprocdef^.deftype:=proctype;
  2187. firstconvert[p^.convtyp](p);
  2188. end
  2189. else
  2190. Message(sym_e_type_mismatch);
  2191. exit;
  2192. end
  2193. else
  2194. begin
  2195. if p^.explizit then
  2196. begin
  2197. { boolean to byte are special because the
  2198. location can be different }
  2199. if (p^.resulttype^.deftype=orddef) and
  2200. (porddef(p^.resulttype)^.typ=u8bit) and
  2201. (p^.left^.resulttype^.deftype=orddef) and
  2202. (porddef(p^.left^.resulttype)^.typ=bool8bit) then
  2203. begin
  2204. p^.convtyp:=tc_bool_2_u8bit;
  2205. firstconvert[p^.convtyp](p);
  2206. exit;
  2207. end;
  2208. { normal tc_equal-Konvertierung durchf�hren }
  2209. p^.convtyp:=tc_equal;
  2210. { wenn Aufz„hltyp nach Ordinal konvertiert werden soll }
  2211. { dann Aufz„hltyp=s32bit }
  2212. if (p^.left^.resulttype^.deftype=enumdef) and
  2213. is_ordinal(p^.resulttype) then
  2214. begin
  2215. if p^.left^.treetype=ordconstn then
  2216. begin
  2217. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  2218. disposetree(p);
  2219. firstpass(hp);
  2220. p:=hp;
  2221. exit;
  2222. end
  2223. else
  2224. begin
  2225. if not isconvertable(s32bitdef,p^.resulttype,p^.convtyp,
  2226. ordconstn { nur Dummy},false ) then
  2227. Message(cg_e_illegal_type_conversion);
  2228. end;
  2229. end
  2230. { ordinal to enumeration }
  2231. else
  2232. if (p^.resulttype^.deftype=enumdef) and
  2233. is_ordinal(p^.left^.resulttype) then
  2234. begin
  2235. if p^.left^.treetype=ordconstn then
  2236. begin
  2237. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  2238. disposetree(p);
  2239. firstpass(hp);
  2240. p:=hp;
  2241. exit;
  2242. end
  2243. else
  2244. begin
  2245. if not isconvertable(p^.left^.resulttype,s32bitdef,p^.convtyp,
  2246. ordconstn { nur Dummy},false ) then
  2247. Message(cg_e_illegal_type_conversion);
  2248. end;
  2249. end
  2250. {Are we typecasting an ordconst to a char?}
  2251. else
  2252. if is_equal(p^.resulttype,cchardef) and
  2253. is_ordinal(p^.left^.resulttype) then
  2254. begin
  2255. if p^.left^.treetype=ordconstn then
  2256. begin
  2257. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  2258. firstpass(hp);
  2259. disposetree(p);
  2260. p:=hp;
  2261. exit;
  2262. end
  2263. else
  2264. begin
  2265. { this is wrong because it converts to a 4 byte long var !!
  2266. if not isconvertable(p^.left^.resulttype,s32bitdef,p^.convtyp,ordconstn nur Dummy ) then }
  2267. if not isconvertable(p^.left^.resulttype,u8bitdef,
  2268. p^.convtyp,ordconstn { nur Dummy},false ) then
  2269. Message(cg_e_illegal_type_conversion);
  2270. end;
  2271. end
  2272. { only if the same size or formal def }
  2273. { why do we allow typecasting of voiddef ?? (PM) }
  2274. else
  2275. if not(
  2276. (p^.left^.resulttype^.deftype=formaldef) or
  2277. (p^.left^.resulttype^.size=p^.resulttype^.size) or
  2278. (is_equal(p^.left^.resulttype,voiddef) and
  2279. (p^.left^.treetype=derefn))
  2280. ) then
  2281. Message(cg_e_illegal_type_conversion);
  2282. { the conversion into a strutured type is only }
  2283. { possible, if the source is no register }
  2284. if (p^.resulttype^.deftype in [recorddef,stringdef,arraydef,objectdef]) and
  2285. (p^.left^.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
  2286. Message(cg_e_illegal_type_conversion);
  2287. end
  2288. else
  2289. Message(sym_e_type_mismatch);
  2290. end
  2291. end
  2292. else
  2293. begin
  2294. { just a test: p^.explizit:=false; }
  2295. { ordinale contants are direct converted }
  2296. if (p^.left^.treetype=ordconstn) and is_ordinal(p^.resulttype) then
  2297. begin
  2298. { perform range checking }
  2299. if not(p^.explizit and (cs_tp_compatible in aktswitches)) then
  2300. testrange(p^.resulttype,p^.left^.value);
  2301. hp:=genordinalconstnode(p^.left^.value,p^.resulttype);
  2302. disposetree(p);
  2303. firstpass(hp);
  2304. p:=hp;
  2305. exit;
  2306. end;
  2307. if p^.convtyp<>tc_equal then
  2308. firstconvert[p^.convtyp](p);
  2309. end;
  2310. end;
  2311. { *************** subroutine handling **************** }
  2312. procedure firstcallparan(var p : ptree;defcoll : pdefcoll);
  2313. var store_valid : boolean;
  2314. convtyp : tconverttype;
  2315. begin
  2316. inc(parsing_para_level);
  2317. if assigned(p^.right) then
  2318. begin
  2319. if defcoll=nil then
  2320. firstcallparan(p^.right,nil)
  2321. else
  2322. firstcallparan(p^.right,defcoll^.next);
  2323. p^.registers32:=p^.right^.registers32;
  2324. p^.registersfpu:=p^.right^.registersfpu;
  2325. {$ifdef SUPPORT_MMX}
  2326. p^.registersmmx:=p^.right^.registersmmx;
  2327. {$endif}
  2328. end;
  2329. if defcoll=nil then
  2330. begin
  2331. { this breaks typeconversions in write !!! (PM) }
  2332. {if not(assigned(p^.resulttype)) then }
  2333. if not(assigned(p^.resulttype)) or
  2334. (p^.left^.treetype=typeconvn) then
  2335. firstpass(p^.left);
  2336. {else
  2337. exit; this broke the
  2338. value of registers32 !! }
  2339. if codegenerror then
  2340. begin
  2341. dec(parsing_para_level);
  2342. exit;
  2343. end;
  2344. p^.resulttype:=p^.left^.resulttype;
  2345. end
  2346. { if we know the routine which is called, then the type }
  2347. { conversions are inserted }
  2348. else
  2349. begin
  2350. if count_ref then
  2351. begin
  2352. store_valid:=must_be_valid;
  2353. if (defcoll^.paratyp<>vs_var) then
  2354. must_be_valid:=true
  2355. else
  2356. must_be_valid:=false;
  2357. { here we must add something for the implicit type }
  2358. { conversion from array of char to pchar }
  2359. if isconvertable(p^.left^.resulttype,defcoll^.data,convtyp,
  2360. p^.left^.treetype,false) then
  2361. if convtyp=tc_array_to_pointer then
  2362. must_be_valid:=false;
  2363. firstpass(p^.left);
  2364. must_be_valid:=store_valid;
  2365. end;
  2366. if not((p^.left^.resulttype^.deftype=stringdef) and
  2367. (defcoll^.data^.deftype=stringdef)) and
  2368. (defcoll^.data^.deftype<>formaldef) then
  2369. begin
  2370. if (defcoll^.paratyp=vs_var) and
  2371. { allows conversion from word to integer and
  2372. byte to shortint }
  2373. (not(
  2374. (p^.left^.resulttype^.deftype=orddef) and
  2375. (defcoll^.data^.deftype=orddef) and
  2376. (p^.left^.resulttype^.size=defcoll^.data^.size)
  2377. ) and
  2378. { an implicit pointer conversion is allowed }
  2379. not(
  2380. (p^.left^.resulttype^.deftype=pointerdef) and
  2381. (defcoll^.data^.deftype=pointerdef)
  2382. ) and
  2383. { an implicit file conversion is also allowed }
  2384. { from a typed file to an untyped one }
  2385. not(
  2386. (p^.left^.resulttype^.deftype=filedef) and
  2387. (defcoll^.data^.deftype=filedef) and
  2388. (pfiledef(defcoll^.data)^.filetype = ft_untyped) and
  2389. (pfiledef(p^.left^.resulttype)^.filetype = ft_typed)
  2390. ) and
  2391. not(is_equal(p^.left^.resulttype,defcoll^.data))) then
  2392. Message(parser_e_call_by_ref_without_typeconv);
  2393. { don't generate an type conversion for open arrays }
  2394. { else we loss the ranges }
  2395. if not(is_open_array(defcoll^.data)) then
  2396. begin
  2397. p^.left:=gentypeconvnode(p^.left,defcoll^.data);
  2398. firstpass(p^.left);
  2399. end;
  2400. if codegenerror then
  2401. begin
  2402. dec(parsing_para_level);
  2403. exit;
  2404. end;
  2405. end;
  2406. { check var strings }
  2407. if (cs_strict_var_strings in aktswitches) and
  2408. (p^.left^.resulttype^.deftype=stringdef) and
  2409. (defcoll^.data^.deftype=stringdef) and
  2410. (defcoll^.paratyp=vs_var) and
  2411. not(is_equal(p^.left^.resulttype,defcoll^.data)) then
  2412. Message(parser_e_strict_var_string_violation);
  2413. { Variablen, die call by reference �bergeben werden, }
  2414. { k”nnen nicht in ein Register kopiert werden }
  2415. { is this usefull here ? }
  2416. { this was missing in formal parameter list }
  2417. if defcoll^.paratyp=vs_var then
  2418. make_not_regable(p^.left);
  2419. p^.resulttype:=defcoll^.data;
  2420. end;
  2421. if p^.left^.registers32>p^.registers32 then
  2422. p^.registers32:=p^.left^.registers32;
  2423. if p^.left^.registersfpu>p^.registersfpu then
  2424. p^.registersfpu:=p^.left^.registersfpu;
  2425. {$ifdef SUPPORT_MMX}
  2426. if p^.left^.registersmmx>p^.registersmmx then
  2427. p^.registersmmx:=p^.left^.registersmmx;
  2428. {$endif SUPPORT_MMX}
  2429. dec(parsing_para_level);
  2430. end;
  2431. procedure firstcalln(var p : ptree);
  2432. type
  2433. pprocdefcoll = ^tprocdefcoll;
  2434. tprocdefcoll = record
  2435. data : pprocdef;
  2436. nextpara : pdefcoll;
  2437. firstpara : pdefcoll;
  2438. next : pprocdefcoll;
  2439. end;
  2440. var
  2441. hp,procs,hp2 : pprocdefcoll;
  2442. pd : pprocdef;
  2443. actprocsym : pprocsym;
  2444. def_from,def_to,conv_to : pdef;
  2445. pt,inlinecode : ptree;
  2446. exactmatch,inlined : boolean;
  2447. paralength,l : longint;
  2448. pdc : pdefcoll;
  2449. {$ifdef UseBrowser}
  2450. curtokenpos : tfileposinfo;
  2451. {$endif UseBrowser}
  2452. { only Dummy }
  2453. hcvt : tconverttype;
  2454. regi : tregister;
  2455. store_valid, old_count_ref : boolean;
  2456. { types.is_equal can't handle a formaldef ! }
  2457. function is_equal(def1,def2 : pdef) : boolean;
  2458. begin
  2459. { all types can be passed to a formaldef }
  2460. is_equal:=(def1^.deftype=formaldef) or
  2461. (assigned(def2) and types.is_equal(def1,def2));
  2462. end;
  2463. function is_in_limit(def_from,def_to : pdef) : boolean;
  2464. begin
  2465. is_in_limit:=(def_from^.deftype = orddef) and
  2466. (def_to^.deftype = orddef) and
  2467. (porddef(def_from)^.von>porddef(def_to)^.von) and
  2468. (porddef(def_from)^.bis<porddef(def_to)^.bis);
  2469. end;
  2470. begin
  2471. { release registers! }
  2472. { if procdefinition<>nil then we called firstpass already }
  2473. { it seems to be bad because of the registers }
  2474. { at least we can avoid the overloaded search !! }
  2475. procs:=nil;
  2476. { made this global for disposing !! }
  2477. store_valid:=must_be_valid;
  2478. must_be_valid:=false;
  2479. inlined:=false;
  2480. if assigned(p^.procdefinition) and
  2481. ((p^.procdefinition^.options and poinline)<>0) then
  2482. begin
  2483. inlinecode:=p^.right;
  2484. if assigned(inlinecode) then
  2485. begin
  2486. inlined:=true;
  2487. p^.procdefinition^.options:=p^.procdefinition^.options and (not poinline);
  2488. end;
  2489. p^.right:=nil;
  2490. end;
  2491. { procedure variable ? }
  2492. if assigned(p^.right) then
  2493. begin
  2494. { procedure does a call }
  2495. procinfo.flags:=procinfo.flags or pi_do_call;
  2496. { calc the correture value for the register }
  2497. {$ifdef i386}
  2498. for regi:=R_EAX to R_EDI do
  2499. inc(reg_pushes[regi],t_times*2);
  2500. {$endif}
  2501. {$ifdef m68k}
  2502. for regi:=R_D0 to R_A6 do
  2503. inc(reg_pushes[regi],t_times*2);
  2504. {$endif}
  2505. { calculate the type of the parameters }
  2506. if assigned(p^.left) then
  2507. begin
  2508. old_count_ref:=count_ref;
  2509. count_ref:=false;
  2510. firstcallparan(p^.left,nil);
  2511. count_ref:=old_count_ref;
  2512. if codegenerror then
  2513. exit;
  2514. end;
  2515. firstpass(p^.right);
  2516. { check the parameters }
  2517. pdc:=pprocvardef(p^.right^.resulttype)^.para1;
  2518. pt:=p^.left;
  2519. while assigned(pdc) and assigned(pt) do
  2520. begin
  2521. pt:=pt^.right;
  2522. pdc:=pdc^.next;
  2523. end;
  2524. if assigned(pt) or assigned(pdc) then
  2525. Message(parser_e_illegal_parameter_list);
  2526. { insert type conversions }
  2527. if assigned(p^.left) then
  2528. begin
  2529. old_count_ref:=count_ref;
  2530. count_ref:=true;
  2531. firstcallparan(p^.left,pprocvardef(p^.right^.resulttype)^.para1);
  2532. count_ref:=old_count_ref;
  2533. if codegenerror then
  2534. exit;
  2535. end;
  2536. p^.resulttype:=pprocvardef(p^.right^.resulttype)^.retdef;
  2537. { this was missing, leads to a bug below if
  2538. the procvar is a function }
  2539. p^.procdefinition:=pprocdef(p^.right^.resulttype);
  2540. end
  2541. else
  2542. { not a procedure variable }
  2543. begin
  2544. { determine the type of the parameters }
  2545. if assigned(p^.left) then
  2546. begin
  2547. old_count_ref:=count_ref;
  2548. count_ref:=false;
  2549. store_valid:=must_be_valid;
  2550. must_be_valid:=false;
  2551. firstcallparan(p^.left,nil);
  2552. count_ref:=old_count_ref;
  2553. must_be_valid:=store_valid;
  2554. if codegenerror then
  2555. exit;
  2556. end;
  2557. { do we know the procedure to call ? }
  2558. if not(assigned(p^.procdefinition)) then
  2559. begin
  2560. actprocsym:=p^.symtableprocentry;
  2561. { determine length of parameter list }
  2562. pt:=p^.left;
  2563. paralength:=0;
  2564. while assigned(pt) do
  2565. begin
  2566. inc(paralength);
  2567. pt:=pt^.right;
  2568. end;
  2569. { alle in Frage kommenden Prozeduren in eine }
  2570. { verkettete Liste einf�gen }
  2571. pd:=actprocsym^.definition;
  2572. while assigned(pd) do
  2573. begin
  2574. { we should also check that the overloaded function
  2575. has been declared in a unit that is in the uses !! }
  2576. { pd^.owner should be in the symtablestack !! }
  2577. { Laenge der deklarierten Parameterliste feststellen: }
  2578. { not necessary why nextprocsym field }
  2579. {st:=symtablestack;
  2580. if (pd^.owner^.symtabletype<>objectsymtable) then
  2581. while assigned(st) do
  2582. begin
  2583. if (st=pd^.owner) then break;
  2584. st:=st^.next;
  2585. end;
  2586. if assigned(st) then }
  2587. begin
  2588. pdc:=pd^.para1;
  2589. l:=0;
  2590. while assigned(pdc) do
  2591. begin
  2592. inc(l);
  2593. pdc:=pdc^.next;
  2594. end;
  2595. { nur wenn die Parameterl„nge paát, dann Einf�gen }
  2596. if l=paralength then
  2597. begin
  2598. new(hp);
  2599. hp^.data:=pd;
  2600. hp^.next:=procs;
  2601. hp^.nextpara:=pd^.para1;
  2602. hp^.firstpara:=pd^.para1;
  2603. procs:=hp;
  2604. end;
  2605. end;
  2606. pd:=pd^.nextoverloaded;
  2607. {$ifdef CHAINPROCSYMS}
  2608. if (pd=nil) and not (p^.unit_specific) then
  2609. begin
  2610. actprocsym:=actprocsym^.nextprocsym;
  2611. if assigned(actprocsym) then
  2612. pd:=actprocsym^.definition;
  2613. end;
  2614. {$endif CHAINPROCSYMS}
  2615. end;
  2616. { nun alle Parameter nacheinander vergleichen }
  2617. pt:=p^.left;
  2618. while assigned(pt) do
  2619. begin
  2620. { matches a parameter of one procedure exact ? }
  2621. exactmatch:=false;
  2622. hp:=procs;
  2623. while assigned(hp) do
  2624. begin
  2625. if is_equal(hp^.nextpara^.data,pt^.resulttype) then
  2626. begin
  2627. if hp^.nextpara^.data=pt^.resulttype then
  2628. begin
  2629. pt^.exact_match_found:=true;
  2630. hp^.nextpara^.argconvtyp:=act_exact;
  2631. end
  2632. else
  2633. hp^.nextpara^.argconvtyp:=act_equal;
  2634. exactmatch:=true;
  2635. end
  2636. else
  2637. hp^.nextpara^.argconvtyp:=act_convertable;
  2638. hp:=hp^.next;
  2639. end;
  2640. { .... if yes, del all the other procedures }
  2641. if exactmatch then
  2642. begin
  2643. { the first .... }
  2644. while (assigned(procs)) and not(is_equal(procs^.nextpara^.data,pt^.resulttype)) do
  2645. begin
  2646. hp:=procs^.next;
  2647. dispose(procs);
  2648. procs:=hp;
  2649. end;
  2650. { and the others }
  2651. hp:=procs;
  2652. while (assigned(hp)) and assigned(hp^.next) do
  2653. begin
  2654. if not(is_equal(hp^.next^.nextpara^.data,pt^.resulttype)) then
  2655. begin
  2656. hp2:=hp^.next^.next;
  2657. dispose(hp^.next);
  2658. hp^.next:=hp2;
  2659. end
  2660. else
  2661. hp:=hp^.next;
  2662. end;
  2663. end
  2664. { sollte nirgendwo ein Parameter exakt passen, }
  2665. { so alle Prozeduren entfernen, bei denen }
  2666. { der Parameter auch nach einer impliziten }
  2667. { Typkonvertierung nicht passt }
  2668. else
  2669. begin
  2670. { erst am Anfang }
  2671. while (assigned(procs)) and
  2672. not(isconvertable(pt^.resulttype,procs^.nextpara^.data,
  2673. hcvt,pt^.left^.treetype,false)) do
  2674. begin
  2675. hp:=procs^.next;
  2676. dispose(procs);
  2677. procs:=hp;
  2678. end;
  2679. { und jetzt aus der Mitte }
  2680. hp:=procs;
  2681. while (assigned(hp)) and assigned(hp^.next) do
  2682. begin
  2683. if not(isconvertable(pt^.resulttype,hp^.next^.nextpara^.data,
  2684. hcvt,pt^.left^.treetype,false)) then
  2685. begin
  2686. hp2:=hp^.next^.next;
  2687. dispose(hp^.next);
  2688. hp^.next:=hp2;
  2689. end
  2690. else
  2691. hp:=hp^.next;
  2692. end;
  2693. end;
  2694. { nun bei denn Prozeduren den nextpara-Zeiger auf den }
  2695. { naechsten Parameter setzen }
  2696. hp:=procs;
  2697. while assigned(hp) do
  2698. begin
  2699. hp^.nextpara:=hp^.nextpara^.next;
  2700. hp:=hp^.next;
  2701. end;
  2702. pt:=pt^.right;
  2703. end;
  2704. if procs=nil then
  2705. if (parsing_para_level=0) or (p^.left<>nil) then
  2706. begin
  2707. Message(parser_e_illegal_parameter_list);
  2708. exit;
  2709. end
  2710. else
  2711. begin
  2712. { try to convert to procvar }
  2713. p^.treetype:=loadn;
  2714. p^.resulttype:=pprocsym(p^.symtableprocentry)^.definition;
  2715. p^.symtableentry:=p^.symtableprocentry;
  2716. p^.is_first:=false;
  2717. p^.disposetyp:=dt_nothing;
  2718. firstpass(p);
  2719. exit;
  2720. end;
  2721. { if there are several choices left then for orddef }
  2722. { if a type is totally included in the other }
  2723. { we don't fear an overflow , }
  2724. { so we can do as if it is an exact match }
  2725. { this will convert integer to longint }
  2726. { rather than to words }
  2727. { conversion of byte to integer or longint }
  2728. {would still not be solved }
  2729. if assigned(procs^.next) then
  2730. begin
  2731. hp:=procs;
  2732. while assigned(hp) do
  2733. begin
  2734. hp^.nextpara:=hp^.firstpara;
  2735. hp:=hp^.next;
  2736. end;
  2737. pt:=p^.left;
  2738. while assigned(pt) do
  2739. begin
  2740. { matches a parameter of one procedure exact ? }
  2741. exactmatch:=false;
  2742. def_from:=pt^.resulttype;
  2743. hp:=procs;
  2744. while assigned(hp) do
  2745. begin
  2746. if not is_equal(hp^.nextpara^.data,pt^.resulttype) then
  2747. begin
  2748. def_to:=hp^.nextpara^.data;
  2749. if (def_from^.deftype=orddef) and (def_to^.deftype=orddef) then
  2750. if is_in_limit(def_from,def_to) or
  2751. ((hp^.nextpara^.paratyp=vs_var) and
  2752. (def_from^.size=def_to^.size)) then
  2753. begin
  2754. exactmatch:=true;
  2755. conv_to:=def_to;
  2756. end;
  2757. end;
  2758. hp:=hp^.next;
  2759. end;
  2760. { .... if yes, del all the other procedures }
  2761. if exactmatch then
  2762. begin
  2763. { the first .... }
  2764. while (assigned(procs)) and not(is_in_limit(def_from,procs^.nextpara^.data)) do
  2765. begin
  2766. hp:=procs^.next;
  2767. dispose(procs);
  2768. procs:=hp;
  2769. end;
  2770. { and the others }
  2771. hp:=procs;
  2772. while (assigned(hp)) and assigned(hp^.next) do
  2773. begin
  2774. if not(is_in_limit(def_from,hp^.next^.nextpara^.data)) then
  2775. begin
  2776. hp2:=hp^.next^.next;
  2777. dispose(hp^.next);
  2778. hp^.next:=hp2;
  2779. end
  2780. else
  2781. begin
  2782. def_to:=hp^.next^.nextpara^.data;
  2783. if (conv_to^.size>def_to^.size) or
  2784. ((porddef(conv_to)^.von<porddef(def_to)^.von) and
  2785. (porddef(conv_to)^.bis>porddef(def_to)^.bis)) then
  2786. begin
  2787. hp2:=procs;
  2788. procs:=hp;
  2789. conv_to:=def_to;
  2790. dispose(hp2);
  2791. end
  2792. else
  2793. hp:=hp^.next;
  2794. end;
  2795. end;
  2796. end;
  2797. { nun bei denn Prozeduren den nextpara-Zeiger auf den }
  2798. { naechsten Parameter setzen }
  2799. hp:=procs;
  2800. while assigned(hp) do
  2801. begin
  2802. hp^.nextpara:=hp^.nextpara^.next;
  2803. hp:=hp^.next;
  2804. end;
  2805. pt:=pt^.right;
  2806. end;
  2807. end;
  2808. { let's try to eliminate equal is exact is there }
  2809. {if assigned(procs^.next) then
  2810. begin
  2811. pt:=p^.left;
  2812. while assigned(pt) do
  2813. begin
  2814. if pt^.exact_match_found then
  2815. begin
  2816. hp:=procs;
  2817. while (assigned(procs)) and (procs^.nextpara^.data<>pt^.resulttype) do
  2818. begin
  2819. hp:=procs^.next;
  2820. dispose(procs);
  2821. procs:=hp;
  2822. end;
  2823. end;
  2824. pt:=pt^.right;
  2825. end;
  2826. end; }
  2827. {$ifndef CHAINPROCSYMS}
  2828. if assigned(procs^.next) then
  2829. Message(cg_e_cant_choose_overload_function);
  2830. {$else CHAINPROCSYMS}
  2831. if assigned(procs^.next) then
  2832. { if the last retained is the only one }
  2833. { from a unit it is OK PM }
  2834. { the last is the one coming from the first symtable }
  2835. { as the diff defcoll are inserted in front }
  2836. begin
  2837. hp2:=procs;
  2838. while assigned(hp2^.next) and assigned(hp2^.next^.next) do
  2839. hp2:=hp2^.next;
  2840. if (hp2^.data^.owner<>hp2^.next^.data^.owner) then
  2841. begin
  2842. hp:=procs^.next;
  2843. {hp2 is the correct one }
  2844. hp2:=hp2^.next;
  2845. while hp<>hp2 do
  2846. begin
  2847. dispose(procs);
  2848. procs:=hp;
  2849. hp:=procs^.next;
  2850. end;
  2851. procs:=hp2;
  2852. end
  2853. else
  2854. Message(cg_e_cant_choose_overload_function);
  2855. error(too_much_matches);
  2856. end;
  2857. {$endif CHAINPROCSYMS}
  2858. {$ifdef UseBrowser}
  2859. if make_ref then
  2860. begin
  2861. get_cur_file_pos(curtokenpos);
  2862. add_new_ref(procs^.data^.lastref,@curtokenpos);
  2863. end;
  2864. {$endif UseBrowser}
  2865. p^.procdefinition:=procs^.data;
  2866. p^.resulttype:=procs^.data^.retdef;
  2867. p^.symtableproc:=p^.procdefinition^.owner;
  2868. p^.location.loc:=LOC_MEM;
  2869. {$ifdef CHAINPROCSYMS}
  2870. { object with method read;
  2871. call to read(x) will be a usual procedure call }
  2872. if assigned(p^.methodpointer) and
  2873. (p^.procdefinition^._class=nil) then
  2874. begin
  2875. { not ok for extended }
  2876. case p^.methodpointer^.treetype of
  2877. typen,hnewn : fatalerror(no_para_match);
  2878. end;
  2879. disposetree(p^.methodpointer);
  2880. p^.methodpointer:=nil;
  2881. end;
  2882. {$endif CHAINPROCSYMS}
  2883. end;{ end of procedure to call determination }
  2884. { handle predefined procedures }
  2885. if (p^.procdefinition^.options and pointernproc)<>0 then
  2886. begin
  2887. { settextbuf needs two args }
  2888. if assigned(p^.left^.right) then
  2889. pt:=geninlinenode(pprocdef(p^.procdefinition)^.extnumber,p^.left)
  2890. else
  2891. begin
  2892. pt:=geninlinenode(pprocdef(p^.procdefinition)^.extnumber,p^.left^.left);
  2893. putnode(p^.left);
  2894. end;
  2895. putnode(p);
  2896. firstpass(pt);
  2897. { was placed after the exit }
  2898. { caused GPF }
  2899. { error caused and corrected by (PM) }
  2900. p:=pt;
  2901. must_be_valid:=store_valid;
  2902. if codegenerror then
  2903. exit;
  2904. dispose(procs);
  2905. exit;
  2906. end
  2907. else
  2908. { no intern procedure => we do a call }
  2909. { calc the correture value for the register }
  2910. { handle predefined procedures }
  2911. if (p^.procdefinition^.options and poinline)<>0 then
  2912. begin
  2913. if assigned(p^.methodpointer) then
  2914. comment(v_fatal,'Unable to inline object methods');
  2915. if assigned(p^.right) and (p^.right^.treetype<>procinlinen) then
  2916. comment(v_fatal,'Unable to inline procvar calls');
  2917. { p^.treetype:=procinlinen; }
  2918. if not assigned(p^.right) then
  2919. begin
  2920. if assigned(p^.procdefinition^.code) then
  2921. inlinecode:=genprocinlinenode(p,ptree(p^.procdefinition^.code))
  2922. else
  2923. comment(v_fatal,'no code for inline procedure stored');
  2924. if assigned(inlinecode) then
  2925. begin
  2926. firstpass(inlinecode);
  2927. { consider it has not inlined if called
  2928. again inside the args }
  2929. p^.procdefinition^.options:=p^.procdefinition^.options and (not poinline);
  2930. inlined:=true;
  2931. end;
  2932. end;
  2933. end
  2934. else
  2935. procinfo.flags:=procinfo.flags or pi_do_call;
  2936. { work trough all parameters to insert the type conversions }
  2937. { !!! done now after internproc !! (PM) }
  2938. if assigned(p^.left) then
  2939. begin
  2940. old_count_ref:=count_ref;
  2941. count_ref:=true;
  2942. firstcallparan(p^.left,p^.procdefinition^.para1);
  2943. count_ref:=old_count_ref;
  2944. end;
  2945. {$ifdef i386}
  2946. for regi:=R_EAX to R_EDI do
  2947. begin
  2948. if (p^.procdefinition^.usedregisters and ($80 shr word(regi)))<>0 then
  2949. inc(reg_pushes[regi],t_times*2);
  2950. end;
  2951. {$endif}
  2952. {$ifdef m68k}
  2953. for regi:=R_D0 to R_A6 do
  2954. begin
  2955. if (p^.procdefinition^.usedregisters and ($800 shr word(regi)))<>0 then
  2956. inc(reg_pushes[regi],t_times*2);
  2957. end;
  2958. {$endif}
  2959. end;
  2960. { ensure that the result type is set }
  2961. p^.resulttype:=p^.procdefinition^.retdef;
  2962. { get a register for the return value }
  2963. if (p^.resulttype<>pdef(voiddef)) then
  2964. begin
  2965. if (p^.procdefinition^.options and poconstructor)<>0 then
  2966. begin
  2967. { extra handling of classes }
  2968. { p^.methodpointer should be assigned! }
  2969. if assigned(p^.methodpointer) and assigned(p^.methodpointer^.resulttype) and
  2970. (p^.methodpointer^.resulttype^.deftype=classrefdef) then
  2971. begin
  2972. p^.location.loc:=LOC_REGISTER;
  2973. p^.registers32:=1;
  2974. { the result type depends on the classref }
  2975. p^.resulttype:=pclassrefdef(p^.methodpointer^.resulttype)^.definition;
  2976. end
  2977. { a object constructor returns the result with the flags }
  2978. else
  2979. p^.location.loc:=LOC_FLAGS;
  2980. end
  2981. else
  2982. begin
  2983. {$ifdef SUPPORT_MMX}
  2984. if (cs_mmx in aktswitches) and
  2985. is_mmx_able_array(p^.resulttype) then
  2986. begin
  2987. p^.location.loc:=LOC_MMXREGISTER;
  2988. p^.registersmmx:=1;
  2989. end
  2990. else
  2991. {$endif SUPPORT_MMX}
  2992. if ret_in_acc(p^.resulttype) then
  2993. begin
  2994. p^.location.loc:=LOC_REGISTER;
  2995. p^.registers32:=1;
  2996. end
  2997. else if (p^.resulttype^.deftype=floatdef) then
  2998. begin
  2999. p^.location.loc:=LOC_FPU;
  3000. p^.registersfpu:=1;
  3001. end
  3002. end;
  3003. end;
  3004. {$ifdef StoreFPULevel}
  3005. { a fpu can be used in any procedure !! }
  3006. p^.registersfpu:=p^.procdefinition^.fpu_used;
  3007. {$endif StoreFPULevel}
  3008. { if this is a call to a method calc the registers }
  3009. if (p^.methodpointer<>nil) then
  3010. begin
  3011. case p^.methodpointer^.treetype of
  3012. { but only, if this is not a supporting node }
  3013. typen,hnewn : ;
  3014. else
  3015. begin
  3016. { R.Assign is not a constructor !!! }
  3017. { but for R^.Assign, R must be valid !! }
  3018. if ((p^.procdefinition^.options and poconstructor) <> 0) or
  3019. ((p^.methodpointer^.treetype=loadn) and
  3020. ((pobjectdef(p^.methodpointer^.resulttype)^.options and oo_hasvirtual) = 0)) then
  3021. must_be_valid:=false
  3022. else
  3023. must_be_valid:=true;
  3024. firstpass(p^.methodpointer);
  3025. p^.registersfpu:=max(p^.methodpointer^.registersfpu,p^.registersfpu);
  3026. p^.registers32:=max(p^.methodpointer^.registers32,p^.registers32);
  3027. {$ifdef SUPPORT_MMX}
  3028. p^.registersmmx:=max(p^.methodpointer^.registersmmx,p^.registersmmx);
  3029. {$endif SUPPORT_MMX}
  3030. end;
  3031. end;
  3032. end;
  3033. if inlined then
  3034. begin
  3035. p^.right:=inlinecode;
  3036. p^.procdefinition^.options:=p^.procdefinition^.options or poinline;
  3037. end;
  3038. { determine the registers of the procedure variable }
  3039. { is this OK for inlined procs also ?? (PM) }
  3040. if assigned(p^.right) then
  3041. begin
  3042. p^.registersfpu:=max(p^.right^.registersfpu,p^.registersfpu);
  3043. p^.registers32:=max(p^.right^.registers32,p^.registers32);
  3044. {$ifdef SUPPORT_MMX}
  3045. p^.registersmmx:=max(p^.right^.registersmmx,p^.registersmmx);
  3046. {$endif SUPPORT_MMX}
  3047. end;
  3048. { determine the registers of the procedure }
  3049. if assigned(p^.left) then
  3050. begin
  3051. p^.registersfpu:=max(p^.left^.registersfpu,p^.registersfpu);
  3052. p^.registers32:=max(p^.left^.registers32,p^.registers32);
  3053. {$ifdef SUPPORT_MMX}
  3054. p^.registersmmx:=max(p^.left^.registersmmx,p^.registersmmx);
  3055. {$endif SUPPORT_MMX}
  3056. end;
  3057. if assigned(procs) then
  3058. dispose(procs);
  3059. must_be_valid:=store_valid;
  3060. end;
  3061. procedure firstfuncret(var p : ptree);
  3062. begin
  3063. {$ifdef TEST_FUNCRET}
  3064. p^.resulttype:=p^.retdef;
  3065. p^.location.loc:=LOC_REFERENCE;
  3066. if ret_in_param(p^.retdef) or
  3067. (@procinfo<>pprocinfo(p^.funcretprocinfo)) then
  3068. p^.registers32:=1;
  3069. if must_be_valid and not pprocinfo(p^.funcretprocinfo)^.funcret_is_valid then
  3070. note(uninitialized_function_return);
  3071. if count_ref then pprocinfo(p^.funcretprocinfo)^.funcret_is_valid:=true;
  3072. {$else TEST_FUNCRET}
  3073. p^.resulttype:=procinfo.retdef;
  3074. p^.location.loc:=LOC_REFERENCE;
  3075. if ret_in_param(procinfo.retdef) then
  3076. p^.registers32:=1;
  3077. if must_be_valid and
  3078. not(procinfo.funcret_is_valid) {and
  3079. ((procinfo.flags and pi_uses_asm)=0)} then
  3080. Message(sym_w_function_result_not_set);
  3081. if count_ref then procinfo.funcret_is_valid:=true;
  3082. {$endif TEST_FUNCRET}
  3083. end;
  3084. { intern inline suborutines }
  3085. procedure firstinline(var p : ptree);
  3086. var
  3087. hp,hpp : ptree;
  3088. store_count_ref,isreal,store_valid,file_is_typed : boolean;
  3089. procedure do_lowhigh(adef : pdef);
  3090. var
  3091. v : longint;
  3092. enum : penumsym;
  3093. begin
  3094. case Adef^.deftype of
  3095. orddef:
  3096. begin
  3097. if p^.inlinenumber=in_low_x then
  3098. v:=porddef(Adef)^.von
  3099. else
  3100. v:=porddef(Adef)^.bis;
  3101. hp:=genordinalconstnode(v,adef);
  3102. firstpass(hp);
  3103. disposetree(p);
  3104. p:=hp;
  3105. end;
  3106. enumdef:
  3107. begin
  3108. enum:=Penumdef(Adef)^.first;
  3109. if p^.inlinenumber=in_high_x then
  3110. while enum^.next<>nil do
  3111. enum:=enum^.next;
  3112. hp:=genenumnode(enum);
  3113. disposetree(p);
  3114. p:=hp;
  3115. end
  3116. end;
  3117. end;
  3118. begin
  3119. store_valid:=must_be_valid;
  3120. store_count_ref:=count_ref;
  3121. count_ref:=false;
  3122. { if we handle writeln; p^.left contains no valid address }
  3123. if assigned(p^.left) then
  3124. begin
  3125. if p^.left^.treetype=callparan then
  3126. firstcallparan(p^.left,nil)
  3127. else
  3128. firstpass(p^.left);
  3129. p^.registers32:=p^.left^.registers32;
  3130. p^.registersfpu:=p^.left^.registersfpu;
  3131. {$ifdef SUPPORT_MMX}
  3132. p^.registersmmx:=p^.left^.registersmmx;
  3133. {$endif SUPPORT_MMX}
  3134. set_location(p^.location,p^.left^.location);
  3135. end;
  3136. if not (p^.inlinenumber in [in_read_x,in_readln_x,in_sizeof_x,
  3137. in_typeof_x,in_ord_x,
  3138. in_reset_typedfile,in_rewrite_typedfile]) then
  3139. must_be_valid:=true
  3140. else must_be_valid:=false;
  3141. case p^.inlinenumber of
  3142. in_lo_word,in_hi_word:
  3143. begin
  3144. if p^.registers32<1 then
  3145. p^.registers32:=1;
  3146. p^.resulttype:=u8bitdef;
  3147. p^.location.loc:=LOC_REGISTER;
  3148. end;
  3149. in_lo_long,in_hi_long:
  3150. begin
  3151. if p^.registers32<1 then
  3152. p^.registers32:=1;
  3153. p^.resulttype:=u16bitdef;
  3154. p^.location.loc:=LOC_REGISTER;
  3155. end;
  3156. in_sizeof_x:
  3157. begin
  3158. if p^.registers32<1 then
  3159. p^.registers32:=1;
  3160. p^.resulttype:=s32bitdef;
  3161. p^.location.loc:=LOC_REGISTER;
  3162. end;
  3163. in_typeof_x:
  3164. begin
  3165. if p^.registers32<1 then
  3166. p^.registers32:=1;
  3167. p^.location.loc:=LOC_REGISTER;
  3168. p^.resulttype:=voidpointerdef;
  3169. end;
  3170. in_ord_x:
  3171. begin
  3172. if (p^.left^.treetype=ordconstn) then
  3173. begin
  3174. hp:=genordinalconstnode(p^.left^.value,s32bitdef);
  3175. disposetree(p);
  3176. p:=hp;
  3177. firstpass(p);
  3178. end
  3179. else
  3180. begin
  3181. if (p^.left^.resulttype^.deftype=orddef) then
  3182. if (porddef(p^.left^.resulttype)^.typ=uchar) or
  3183. (porddef(p^.left^.resulttype)^.typ=bool8bit) then
  3184. begin
  3185. if porddef(p^.left^.resulttype)^.typ=bool8bit then
  3186. begin
  3187. hp:=gentypeconvnode(p^.left,u8bitdef);
  3188. putnode(p);
  3189. p:=hp;
  3190. p^.convtyp:=tc_bool_2_u8bit;
  3191. p^.explizit:=true;
  3192. firstpass(p);
  3193. end
  3194. else
  3195. begin
  3196. hp:=gentypeconvnode(p^.left,u8bitdef);
  3197. putnode(p);
  3198. p:=hp;
  3199. p^.explizit:=true;
  3200. firstpass(p);
  3201. end;
  3202. end
  3203. { can this happen ? }
  3204. else if (porddef(p^.left^.resulttype)^.typ=uvoid) then
  3205. Message(sym_e_type_mismatch)
  3206. else
  3207. { all other orddef need no transformation }
  3208. begin
  3209. hp:=p^.left;
  3210. putnode(p);
  3211. p:=hp;
  3212. end
  3213. else if (p^.left^.resulttype^.deftype=enumdef) then
  3214. begin
  3215. hp:=gentypeconvnode(p^.left,s32bitdef);
  3216. putnode(p);
  3217. p:=hp;
  3218. p^.explizit:=true;
  3219. firstpass(p);
  3220. end
  3221. else
  3222. begin
  3223. { can anything else be ord() ?}
  3224. Message(sym_e_type_mismatch);
  3225. end;
  3226. end;
  3227. end;
  3228. in_chr_byte:
  3229. begin
  3230. hp:=gentypeconvnode(p^.left,cchardef);
  3231. putnode(p);
  3232. p:=hp;
  3233. p^.explizit:=true;
  3234. firstpass(p);
  3235. end;
  3236. in_length_string:
  3237. begin
  3238. {$ifdef UseAnsiString}
  3239. if is_ansistring(p^.left^.resulttype) then
  3240. p^.resulttype:=s32bitdef
  3241. else
  3242. {$endif UseAnsiString}
  3243. p^.resulttype:=u8bitdef;
  3244. { wer don't need string conversations here }
  3245. if (p^.left^.treetype=typeconvn) and
  3246. (p^.left^.left^.resulttype^.deftype=stringdef) then
  3247. begin
  3248. hp:=p^.left^.left;
  3249. putnode(p^.left);
  3250. p^.left:=hp;
  3251. end;
  3252. { evalutes length of constant strings direct }
  3253. if (p^.left^.treetype=stringconstn) then
  3254. begin
  3255. hp:=genordinalconstnode(length(p^.left^.values^),s32bitdef);
  3256. disposetree(p);
  3257. firstpass(hp);
  3258. p:=hp;
  3259. end;
  3260. end;
  3261. in_assigned_x:
  3262. begin
  3263. p^.resulttype:=booldef;
  3264. p^.location.loc:=LOC_FLAGS;
  3265. end;
  3266. in_pred_x,
  3267. in_succ_x:
  3268. begin
  3269. p^.resulttype:=p^.left^.resulttype;
  3270. p^.location.loc:=LOC_REGISTER;
  3271. if not is_ordinal(p^.resulttype) then
  3272. Message(sym_e_type_mismatch)
  3273. else
  3274. begin
  3275. if (p^.resulttype^.deftype=enumdef) and
  3276. (penumdef(p^.resulttype)^.has_jumps) then
  3277. begin
  3278. Message(parser_e_succ_and_pred_enums_with_assign_not_possible);
  3279. end
  3280. else if p^.left^.treetype=ordconstn then
  3281. begin
  3282. if p^.inlinenumber=in_pred_x then
  3283. hp:=genordinalconstnode(p^.left^.value+1,
  3284. p^.left^.resulttype)
  3285. else
  3286. hp:=genordinalconstnode(p^.left^.value-1,
  3287. p^.left^.resulttype);
  3288. disposetree(p);
  3289. firstpass(hp);
  3290. p:=hp;
  3291. end;
  3292. end;
  3293. end;
  3294. in_dec_dword,
  3295. in_dec_word,
  3296. in_dec_byte,
  3297. in_inc_dword,
  3298. in_inc_word,
  3299. in_inc_byte :
  3300. begin
  3301. p^.resulttype:=voiddef;
  3302. if p^.left^.location.loc<>LOC_REFERENCE then
  3303. Message(cg_e_illegal_expression);
  3304. end;
  3305. in_inc_x,
  3306. in_dec_x:
  3307. begin
  3308. p^.resulttype:=voiddef;
  3309. if assigned(p^.left) then
  3310. begin
  3311. firstcallparan(p^.left,nil);
  3312. { first param must be var }
  3313. if p^.left^.left^.location.loc<>LOC_REFERENCE then
  3314. Message(cg_e_illegal_expression);
  3315. { check type }
  3316. if (p^.left^.resulttype^.deftype=pointerdef) or
  3317. (p^.left^.resulttype^.deftype=enumdef) or
  3318. ( (p^.left^.resulttype^.deftype=orddef) and
  3319. (porddef(p^.left^.resulttype)^.typ in [u8bit,s8bit,u16bit,s16bit,u32bit,s32bit])
  3320. ) then
  3321. begin
  3322. { two paras ? }
  3323. if assigned(p^.left^.right) then
  3324. begin
  3325. { insert a type conversion }
  3326. { the second param is always longint }
  3327. p^.left^.right^.left:=gentypeconvnode(
  3328. p^.left^.right^.left,
  3329. s32bitdef);
  3330. { check the type conversion }
  3331. firstpass(p^.left^.right^.left);
  3332. if assigned(p^.left^.right^.right) then
  3333. Message(cg_e_illegal_expression);
  3334. end;
  3335. end
  3336. else
  3337. Message(sym_e_type_mismatch);
  3338. end
  3339. else
  3340. Message(sym_e_type_mismatch);
  3341. end;
  3342. in_read_x,
  3343. in_readln_x,
  3344. in_write_x,
  3345. in_writeln_x :
  3346. begin
  3347. { needs a call }
  3348. procinfo.flags:=procinfo.flags or pi_do_call;
  3349. p^.resulttype:=voiddef;
  3350. { we must know if it is a typed file or not }
  3351. { but we must first do the firstpass for it }
  3352. file_is_typed:=false;
  3353. if assigned(p^.left) then
  3354. begin
  3355. firstcallparan(p^.left,nil);
  3356. { now we can check }
  3357. hp:=p^.left;
  3358. while assigned(hp^.right) do
  3359. hp:=hp^.right;
  3360. { if resulttype is not assigned, then automatically }
  3361. { file is not typed. }
  3362. if assigned(hp) and assigned(hp^.resulttype) then
  3363. Begin
  3364. if (hp^.resulttype^.deftype=filedef) and
  3365. (pfiledef(hp^.resulttype)^.filetype=ft_typed) then
  3366. begin
  3367. file_is_typed:=true;
  3368. { test the type here
  3369. so we can use a trick in cgi386 (PM) }
  3370. hpp:=p^.left;
  3371. while (hpp<>hp) do
  3372. begin
  3373. { should we allow type conversion ? (PM)
  3374. if not isconvertable(hpp^.resulttype,
  3375. pfiledef(hp^.resulttype)^.typed_as,convtyp,hpp^.treetype) then
  3376. Message(sym_e_type_mismatch);
  3377. if not(is_equal(hpp^.resulttype,pfiledef(hp^.resulttype)^.typed_as)) then
  3378. begin
  3379. hpp^.left:=gentypeconvnode(hpp^.left,pfiledef(hp^.resulttype)^.typed_as);
  3380. end; }
  3381. if not is_equal(hpp^.resulttype,pfiledef(hp^.resulttype)^.typed_as) then
  3382. Message(sym_e_type_mismatch);
  3383. hpp:=hpp^.right;
  3384. end;
  3385. { once again for typeconversions }
  3386. firstcallparan(p^.left,nil);
  3387. end;
  3388. end; { endif assigned(hp) }
  3389. { insert type conversions for write(ln) }
  3390. if (not file_is_typed) and
  3391. ((p^.inlinenumber=in_write_x) or (p^.inlinenumber=in_writeln_x)) then
  3392. begin
  3393. hp:=p^.left;
  3394. while assigned(hp) do
  3395. begin
  3396. if assigned(hp^.left^.resulttype) then
  3397. begin
  3398. if hp^.left^.resulttype^.deftype=floatdef then
  3399. begin
  3400. isreal:=true;
  3401. end
  3402. else if hp^.left^.resulttype^.deftype=orddef then
  3403. case porddef(hp^.left^.resulttype)^.typ of
  3404. u8bit,s8bit,
  3405. u16bit,s16bit :
  3406. hp^.left:=gentypeconvnode(hp^.left,s32bitdef);
  3407. end
  3408. { but we convert only if the first index<>0, because in this case }
  3409. { we have a ASCIIZ string }
  3410. else if (hp^.left^.resulttype^.deftype=arraydef) and
  3411. (parraydef(hp^.left^.resulttype)^.lowrange<>0) and
  3412. (parraydef(hp^.left^.resulttype)^.definition^.deftype=orddef) and
  3413. (porddef(parraydef(hp^.left^.resulttype)^.definition)^.typ=uchar) then
  3414. hp^.left:=gentypeconvnode(hp^.left,cstringdef);
  3415. end;
  3416. hp:=hp^.right;
  3417. end;
  3418. end;
  3419. { pass all parameters again }
  3420. firstcallparan(p^.left,nil);
  3421. end;
  3422. end;
  3423. in_settextbuf_file_x :
  3424. begin
  3425. { warning here p^.left is the callparannode
  3426. not the argument directly }
  3427. { p^.left^.left is text var }
  3428. { p^.left^.right^.left is the buffer var }
  3429. { firstcallparan(p^.left,nil);
  3430. already done in firstcalln }
  3431. { now we know the type of buffer }
  3432. getsymonlyin(systemunit,'SETTEXTBUF');
  3433. hp:=gencallnode(pprocsym(srsym),systemunit);
  3434. hp^.left:=gencallparanode(
  3435. genordinalconstnode(p^.left^.left^.resulttype^.size,s32bitdef),p^.left);
  3436. putnode(p);
  3437. p:=hp;
  3438. firstpass(p);
  3439. end;
  3440. { the firstpass of the arg has been done in firstcalln ? }
  3441. in_reset_typedfile,in_rewrite_typedfile :
  3442. begin
  3443. procinfo.flags:=procinfo.flags or pi_do_call;
  3444. { to be sure the right definition is loaded }
  3445. p^.left^.resulttype:=nil;
  3446. firstload(p^.left);
  3447. p^.resulttype:=voiddef;
  3448. end;
  3449. in_str_x_string :
  3450. begin
  3451. procinfo.flags:=procinfo.flags or pi_do_call;
  3452. p^.resulttype:=voiddef;
  3453. if assigned(p^.left) then
  3454. begin
  3455. hp:=p^.left^.right;
  3456. { first pass just the string for first local use }
  3457. must_be_valid:=false;
  3458. count_ref:=true;
  3459. p^.left^.right:=nil;
  3460. firstcallparan(p^.left,nil);
  3461. p^.left^.right:=hp;
  3462. must_be_valid:=true;
  3463. firstcallparan(p^.left,nil);
  3464. hp:=p^.left;
  3465. isreal:=false;
  3466. { valid string ? }
  3467. if not assigned(hp) or
  3468. (hp^.left^.resulttype^.deftype<>stringdef) or
  3469. (hp^.right=nil) or
  3470. (hp^.left^.location.loc<>LOC_REFERENCE) then
  3471. Message(cg_e_illegal_expression);
  3472. { !!!! check length of string }
  3473. while assigned(hp^.right) do hp:=hp^.right;
  3474. { check and convert the first param }
  3475. if hp^.is_colon_para then
  3476. Message(cg_e_illegal_expression)
  3477. else if hp^.resulttype^.deftype=orddef then
  3478. case porddef(hp^.left^.resulttype)^.typ of
  3479. u8bit,s8bit,
  3480. u16bit,s16bit :
  3481. hp^.left:=gentypeconvnode(hp^.left,s32bitdef);
  3482. end
  3483. else if hp^.resulttype^.deftype=floatdef then
  3484. begin
  3485. isreal:=true;
  3486. end
  3487. else Message(cg_e_illegal_expression);
  3488. { some format options ? }
  3489. hp:=p^.left^.right;
  3490. if assigned(hp) and hp^.is_colon_para then
  3491. begin
  3492. hp^.left:=gentypeconvnode(hp^.left,s32bitdef);
  3493. hp:=hp^.right;
  3494. end;
  3495. if assigned(hp) and hp^.is_colon_para then
  3496. begin
  3497. if isreal then
  3498. hp^.left:=gentypeconvnode(hp^.left,s32bitdef)
  3499. else
  3500. Message(parser_e_illegal_colon_qualifier);
  3501. hp:=hp^.right;
  3502. end;
  3503. { for first local use }
  3504. must_be_valid:=false;
  3505. count_ref:=true;
  3506. if assigned(hp) then
  3507. firstcallparan(hp,nil);
  3508. end
  3509. else
  3510. Message(parser_e_illegal_parameter_list);
  3511. { check params once more }
  3512. if codegenerror then
  3513. exit;
  3514. must_be_valid:=true;
  3515. firstcallparan(p^.left,nil);
  3516. end;
  3517. in_include_x_y,
  3518. in_exclude_x_y:
  3519. begin
  3520. p^.resulttype:=voiddef;
  3521. if assigned(p^.left) then
  3522. begin
  3523. firstcallparan(p^.left,nil);
  3524. p^.registers32:=p^.left^.registers32;
  3525. p^.registersfpu:=p^.left^.registersfpu;
  3526. {$ifdef SUPPORT_MMX}
  3527. p^.registersmmx:=p^.left^.registersmmx;
  3528. {$endif SUPPORT_MMX}
  3529. { first param must be var }
  3530. if (p^.left^.left^.location.loc<>LOC_REFERENCE) and
  3531. (p^.left^.left^.location.loc<>LOC_CREGISTER) then
  3532. Message(cg_e_illegal_expression);
  3533. { check type }
  3534. if (p^.left^.resulttype^.deftype=setdef) then
  3535. begin
  3536. { two paras ? }
  3537. if assigned(p^.left^.right) then
  3538. begin
  3539. { insert a type conversion }
  3540. { to the type of the set elements }
  3541. p^.left^.right^.left:=gentypeconvnode(
  3542. p^.left^.right^.left,
  3543. psetdef(p^.left^.resulttype)^.setof);
  3544. { check the type conversion }
  3545. firstpass(p^.left^.right^.left);
  3546. { only three parameters are allowed }
  3547. if assigned(p^.left^.right^.right) then
  3548. Message(cg_e_illegal_expression);
  3549. end;
  3550. end
  3551. else
  3552. Message(sym_e_type_mismatch);
  3553. end
  3554. else
  3555. Message(sym_e_type_mismatch);
  3556. end;
  3557. in_low_x,in_high_x:
  3558. begin
  3559. if p^.left^.treetype in [typen,loadn] then
  3560. begin
  3561. case p^.left^.resulttype^.deftype of
  3562. orddef,enumdef:
  3563. begin
  3564. do_lowhigh(p^.left^.resulttype);
  3565. firstpass(p);
  3566. end;
  3567. setdef:
  3568. begin
  3569. do_lowhigh(Psetdef(p^.left^.resulttype)^.setof);
  3570. firstpass(p);
  3571. end;
  3572. arraydef:
  3573. begin
  3574. if is_open_array(p^.left^.resulttype) then
  3575. begin
  3576. if p^.inlinenumber=in_low_x then
  3577. begin
  3578. hp:=genordinalconstnode(Parraydef(p^.left^.resulttype)^.lowrange,s32bitdef);
  3579. disposetree(p);
  3580. p:=hp;
  3581. firstpass(p);
  3582. end
  3583. else
  3584. begin
  3585. p^.resulttype:=s32bitdef;
  3586. p^.registers32:=max(1,
  3587. p^.registers32);
  3588. p^.location.loc:=LOC_REGISTER;
  3589. end;
  3590. end
  3591. else
  3592. begin
  3593. if p^.inlinenumber=in_low_x then
  3594. hp:=genordinalconstnode(Parraydef(p^.left^.resulttype)^.lowrange,s32bitdef)
  3595. else
  3596. hp:=genordinalconstnode(Parraydef(p^.left^.resulttype)^.highrange,s32bitdef);
  3597. disposetree(p);
  3598. p:=hp;
  3599. firstpass(p);
  3600. end;
  3601. end;
  3602. stringdef:
  3603. begin
  3604. if p^.inlinenumber=in_low_x then
  3605. hp:=genordinalconstnode(0,u8bitdef)
  3606. else
  3607. hp:=genordinalconstnode(Pstringdef(p^.left^.resulttype)^.len,u8bitdef);
  3608. disposetree(p);
  3609. p:=hp;
  3610. firstpass(p);
  3611. end;
  3612. else
  3613. Message(sym_e_type_mismatch);
  3614. end;
  3615. end
  3616. else
  3617. Message(parser_e_varid_or_typeid_expected);
  3618. end
  3619. else internalerror(8);
  3620. end;
  3621. must_be_valid:=store_valid;
  3622. count_ref:=store_count_ref;
  3623. end;
  3624. procedure firstsubscriptn(var p : ptree);
  3625. begin
  3626. firstpass(p^.left);
  3627. if codegenerror then
  3628. exit;
  3629. p^.resulttype:=p^.vs^.definition;
  3630. { this must be done in the parser
  3631. if count_ref and not must_be_valid then
  3632. if (p^.vs^.properties and sp_protected)<>0 then
  3633. Message(parser_e_cant_write_protected_member);
  3634. }
  3635. p^.registers32:=p^.left^.registers32;
  3636. p^.registersfpu:=p^.left^.registersfpu;
  3637. {$ifdef SUPPORT_MMX}
  3638. p^.registersmmx:=p^.left^.registersmmx;
  3639. {$endif SUPPORT_MMX}
  3640. { classes must be dereferenced implicit }
  3641. if (p^.left^.resulttype^.deftype=objectdef) and
  3642. pobjectdef(p^.left^.resulttype)^.isclass then
  3643. begin
  3644. if p^.registers32=0 then
  3645. p^.registers32:=1;
  3646. p^.location.loc:=LOC_REFERENCE;
  3647. end
  3648. else
  3649. begin
  3650. if (p^.left^.location.loc<>LOC_MEM) and
  3651. (p^.left^.location.loc<>LOC_REFERENCE) then
  3652. Message(cg_e_illegal_expression);
  3653. set_location(p^.location,p^.left^.location);
  3654. end;
  3655. end;
  3656. procedure firstselfn(var p : ptree);
  3657. begin
  3658. if (p^.resulttype^.deftype=classrefdef) or
  3659. ((p^.resulttype^.deftype=objectdef)
  3660. and pobjectdef(p^.resulttype)^.isclass
  3661. ) then
  3662. p^.location.loc:=LOC_REGISTER
  3663. else
  3664. p^.location.loc:=LOC_REFERENCE;
  3665. end;
  3666. procedure firsttypen(var p : ptree);
  3667. begin
  3668. { DM: Why not allowed? For example: low(word) results in a type
  3669. id of word.
  3670. error(typeid_here_not_allowed);}
  3671. end;
  3672. procedure firsthnewn(var p : ptree);
  3673. begin
  3674. end;
  3675. procedure firsthdisposen(var p : ptree);
  3676. begin
  3677. firstpass(p^.left);
  3678. if codegenerror then
  3679. exit;
  3680. p^.registers32:=p^.left^.registers32;
  3681. p^.registersfpu:=p^.left^.registersfpu;
  3682. {$ifdef SUPPORT_MMX}
  3683. p^.registersmmx:=p^.left^.registersmmx;
  3684. {$endif SUPPORT_MMX}
  3685. if p^.registers32<1 then
  3686. p^.registers32:=1;
  3687. {
  3688. if p^.left^.location.loc<>LOC_REFERENCE then
  3689. Message(cg_e_illegal_expression);
  3690. }
  3691. p^.location.loc:=LOC_REFERENCE;
  3692. p^.resulttype:=ppointerdef(p^.left^.resulttype)^.definition;
  3693. end;
  3694. procedure firstnewn(var p : ptree);
  3695. begin
  3696. { Standardeinleitung }
  3697. firstpass(p^.left);
  3698. if codegenerror then
  3699. exit;
  3700. p^.registers32:=p^.left^.registers32;
  3701. p^.registersfpu:=p^.left^.registersfpu;
  3702. {$ifdef SUPPORT_MMX}
  3703. p^.registersmmx:=p^.left^.registersmmx;
  3704. {$endif SUPPORT_MMX}
  3705. { result type is already set }
  3706. procinfo.flags:=procinfo.flags or pi_do_call;
  3707. p^.location.loc:=LOC_REGISTER;
  3708. end;
  3709. procedure firstsimplenewdispose(var p : ptree);
  3710. begin
  3711. { this cannot be in a register !! }
  3712. make_not_regable(p^.left);
  3713. firstpass(p^.left);
  3714. { check the type }
  3715. if (p^.left^.resulttype=nil) or (p^.left^.resulttype^.deftype<>pointerdef) then
  3716. Message(parser_e_pointer_type_expected);
  3717. if (p^.left^.location.loc<>LOC_REFERENCE) {and
  3718. (p^.left^.location.loc<>LOC_CREGISTER)} then
  3719. Message(cg_e_illegal_expression);
  3720. p^.registers32:=p^.left^.registers32;
  3721. p^.registersfpu:=p^.left^.registersfpu;
  3722. {$ifdef SUPPORT_MMX}
  3723. p^.registersmmx:=p^.left^.registersmmx;
  3724. {$endif SUPPORT_MMX}
  3725. p^.resulttype:=voiddef;
  3726. procinfo.flags:=procinfo.flags or pi_do_call;
  3727. end;
  3728. procedure firstsetcons(var p : ptree);
  3729. var
  3730. hp : ptree;
  3731. begin
  3732. p^.location.loc:=LOC_MEM;
  3733. hp:=p^.left;
  3734. { is done by getnode*
  3735. p^.registers32:=0;
  3736. p^.registersfpu:=0;
  3737. }
  3738. while assigned(hp) do
  3739. begin
  3740. firstpass(hp^.left);
  3741. if codegenerror then
  3742. exit;
  3743. p^.registers32:=max(p^.registers32,hp^.left^.registers32);
  3744. p^.registersfpu:=max(p^.registersfpu,hp^.left^.registersfpu);;
  3745. {$ifdef SUPPORT_MMX}
  3746. p^.registersmmx:=max(p^.registersmmx,hp^.left^.registersmmx);
  3747. {$endif SUPPORT_MMX}
  3748. hp:=hp^.right;
  3749. end;
  3750. { result type is already set }
  3751. end;
  3752. procedure firstin(var p : ptree);
  3753. begin
  3754. p^.location.loc:=LOC_FLAGS;
  3755. p^.resulttype:=booldef;
  3756. firstpass(p^.right);
  3757. if codegenerror then
  3758. exit;
  3759. if p^.right^.resulttype^.deftype<>setdef then
  3760. Message(sym_e_set_expected);
  3761. firstpass(p^.left);
  3762. if codegenerror then
  3763. exit;
  3764. p^.left:=gentypeconvnode(p^.left,psetdef(p^.right^.resulttype)^.setof);
  3765. firstpass(p^.left);
  3766. if codegenerror then
  3767. exit;
  3768. left_right_max(p);
  3769. { this is not allways true due to optimization }
  3770. { but if we don't set this we get problems with optimizing self code }
  3771. if psetdef(p^.right^.resulttype)^.settype<>smallset then
  3772. procinfo.flags:=procinfo.flags or pi_do_call;
  3773. end;
  3774. procedure firststatement(var p : ptree);
  3775. begin
  3776. { left is the next statement in the list }
  3777. p^.resulttype:=voiddef;
  3778. { no temps over several statements }
  3779. cleartempgen;
  3780. { right is the statement itself calln assignn or a complex one }
  3781. firstpass(p^.right);
  3782. if (not (cs_extsyntax in aktswitches)) and
  3783. assigned(p^.right^.resulttype) and
  3784. (p^.right^.resulttype<>pdef(voiddef)) then
  3785. Message(cg_e_illegal_expression);
  3786. if codegenerror then
  3787. exit;
  3788. p^.registers32:=p^.right^.registers32;
  3789. p^.registersfpu:=p^.right^.registersfpu;
  3790. {$ifdef SUPPORT_MMX}
  3791. p^.registersmmx:=p^.right^.registersmmx;
  3792. {$endif SUPPORT_MMX}
  3793. { left is the next in the list }
  3794. firstpass(p^.left);
  3795. if codegenerror then
  3796. exit;
  3797. if p^.right^.registers32>p^.registers32 then
  3798. p^.registers32:=p^.right^.registers32;
  3799. if p^.right^.registersfpu>p^.registersfpu then
  3800. p^.registersfpu:=p^.right^.registersfpu;
  3801. {$ifdef SUPPORT_MMX}
  3802. if p^.right^.registersmmx>p^.registersmmx then
  3803. p^.registersmmx:=p^.right^.registersmmx;
  3804. {$endif}
  3805. end;
  3806. procedure firstblock(var p : ptree);
  3807. var
  3808. hp : ptree;
  3809. count : longint;
  3810. begin
  3811. count:=0;
  3812. hp:=p^.left;
  3813. while assigned(hp) do
  3814. begin
  3815. if cs_maxoptimieren in aktswitches then
  3816. begin
  3817. { Codeumstellungen }
  3818. { Funktionsresultate an exit anh„ngen }
  3819. { this is wrong for string or other complex
  3820. result types !!! }
  3821. if ret_in_acc(procinfo.retdef) and
  3822. assigned(hp^.left) and
  3823. (hp^.left^.right^.treetype=exitn) and
  3824. (hp^.right^.treetype=assignn) and
  3825. (hp^.right^.left^.treetype=funcretn) then
  3826. begin
  3827. if assigned(hp^.left^.right^.left) then
  3828. Message(cg_n_inefficient_code)
  3829. else
  3830. begin
  3831. hp^.left^.right^.left:=getcopy(hp^.right^.right);
  3832. disposetree(hp^.right);
  3833. hp^.right:=nil;
  3834. end;
  3835. end
  3836. { warning if unreachable code occurs and elimate this }
  3837. else if (hp^.right^.treetype in
  3838. [exitn,breakn,continuen,goton]) and
  3839. assigned(hp^.left) and
  3840. (hp^.left^.treetype<>labeln) then
  3841. begin
  3842. { use correct line number }
  3843. set_current_file_line(hp^.left);
  3844. disposetree(hp^.left);
  3845. hp^.left:=nil;
  3846. Message(cg_w_unreachable_code);
  3847. { old lines }
  3848. set_current_file_line(hp^.right);
  3849. end;
  3850. end;
  3851. if assigned(hp^.right) then
  3852. begin
  3853. cleartempgen;
  3854. firstpass(hp^.right);
  3855. if (not (cs_extsyntax in aktswitches)) and
  3856. assigned(hp^.right^.resulttype) and
  3857. (hp^.right^.resulttype<>pdef(voiddef)) then
  3858. Message(cg_e_illegal_expression);
  3859. if codegenerror then
  3860. exit;
  3861. hp^.registers32:=hp^.right^.registers32;
  3862. hp^.registersfpu:=hp^.right^.registersfpu;
  3863. {$ifdef SUPPORT_MMX}
  3864. hp^.registersmmx:=hp^.right^.registersmmx;
  3865. {$endif SUPPORT_MMX}
  3866. end
  3867. else
  3868. hp^.registers32:=0;
  3869. if hp^.registers32>p^.registers32 then
  3870. p^.registers32:=hp^.registers32;
  3871. if hp^.registersfpu>p^.registersfpu then
  3872. p^.registersfpu:=hp^.registersfpu;
  3873. {$ifdef SUPPORT_MMX}
  3874. if hp^.registersmmx>p^.registersmmx then
  3875. p^.registersmmx:=hp^.registersmmx;
  3876. {$endif}
  3877. inc(count);
  3878. hp:=hp^.left;
  3879. end;
  3880. { p^.registers32:=round(p^.registers32/count); }
  3881. end;
  3882. procedure first_while_repeat(var p : ptree);
  3883. var
  3884. old_t_times : longint;
  3885. begin
  3886. old_t_times:=t_times;
  3887. { Registergewichtung bestimmen }
  3888. if not(cs_littlesize in aktswitches ) then
  3889. t_times:=t_times*8;
  3890. cleartempgen;
  3891. must_be_valid:=true;
  3892. firstpass(p^.left);
  3893. if codegenerror then
  3894. exit;
  3895. if not((p^.left^.resulttype^.deftype=orddef) and
  3896. (porddef(p^.left^.resulttype)^.typ=bool8bit)) then
  3897. begin
  3898. Message(sym_e_type_mismatch);
  3899. exit;
  3900. end;
  3901. p^.registers32:=p^.left^.registers32;
  3902. p^.registersfpu:=p^.left^.registersfpu;
  3903. {$ifdef SUPPORT_MMX}
  3904. p^.registersmmx:=p^.left^.registersmmx;
  3905. {$endif SUPPORT_MMX}
  3906. { loop instruction }
  3907. if assigned(p^.right) then
  3908. begin
  3909. cleartempgen;
  3910. firstpass(p^.right);
  3911. if codegenerror then
  3912. exit;
  3913. if p^.registers32<p^.right^.registers32 then
  3914. p^.registers32:=p^.right^.registers32;
  3915. if p^.registersfpu<p^.right^.registersfpu then
  3916. p^.registersfpu:=p^.right^.registersfpu;
  3917. {$ifdef SUPPORT_MMX}
  3918. if p^.registersmmx<p^.right^.registersmmx then
  3919. p^.registersmmx:=p^.right^.registersmmx;
  3920. {$endif SUPPORT_MMX}
  3921. end;
  3922. t_times:=old_t_times;
  3923. end;
  3924. procedure firstif(var p : ptree);
  3925. var
  3926. old_t_times : longint;
  3927. hp : ptree;
  3928. begin
  3929. old_t_times:=t_times;
  3930. cleartempgen;
  3931. must_be_valid:=true;
  3932. firstpass(p^.left);
  3933. if codegenerror then
  3934. exit;
  3935. if not((p^.left^.resulttype^.deftype=orddef) and
  3936. (porddef(p^.left^.resulttype)^.typ=bool8bit)) then
  3937. begin
  3938. Message(sym_e_type_mismatch);
  3939. exit;
  3940. end;
  3941. p^.registers32:=p^.left^.registers32;
  3942. p^.registersfpu:=p^.left^.registersfpu;
  3943. {$ifdef SUPPORT_MMX}
  3944. p^.registersmmx:=p^.left^.registersmmx;
  3945. {$endif SUPPORT_MMX}
  3946. { determines registers weigths }
  3947. if not(cs_littlesize in aktswitches ) then
  3948. t_times:=t_times div 2;
  3949. if t_times=0 then
  3950. t_times:=1;
  3951. { if path }
  3952. if assigned(p^.right) then
  3953. begin
  3954. cleartempgen;
  3955. firstpass(p^.right);
  3956. if codegenerror then
  3957. exit;
  3958. if p^.registers32<p^.right^.registers32 then
  3959. p^.registers32:=p^.right^.registers32;
  3960. if p^.registersfpu<p^.right^.registersfpu then
  3961. p^.registersfpu:=p^.right^.registersfpu;
  3962. {$ifdef SUPPORT_MMX}
  3963. if p^.registersmmx<p^.right^.registersmmx then
  3964. p^.registersmmx:=p^.right^.registersmmx;
  3965. {$endif SUPPORT_MMX}
  3966. end;
  3967. { else path }
  3968. if assigned(p^.t1) then
  3969. begin
  3970. cleartempgen;
  3971. firstpass(p^.t1);
  3972. if codegenerror then
  3973. exit;
  3974. if p^.registers32<p^.t1^.registers32 then
  3975. p^.registers32:=p^.t1^.registers32;
  3976. if p^.registersfpu<p^.t1^.registersfpu then
  3977. p^.registersfpu:=p^.t1^.registersfpu;
  3978. {$ifdef SUPPORT_MMX}
  3979. if p^.registersmmx<p^.t1^.registersmmx then
  3980. p^.registersmmx:=p^.t1^.registersmmx;
  3981. {$endif SUPPORT_MMX}
  3982. end;
  3983. if p^.left^.treetype=ordconstn then
  3984. begin
  3985. { optimize }
  3986. if p^.left^.value=1 then
  3987. begin
  3988. disposetree(p^.left);
  3989. hp:=p^.right;
  3990. disposetree(p^.t1);
  3991. { we cannot set p to nil !!! }
  3992. if assigned(hp) then
  3993. begin
  3994. putnode(p);
  3995. p:=hp;
  3996. end
  3997. else
  3998. begin
  3999. p^.left:=nil;
  4000. p^.t1:=nil;
  4001. p^.treetype:=nothingn;
  4002. end;
  4003. end
  4004. else
  4005. begin
  4006. disposetree(p^.left);
  4007. hp:=p^.t1;
  4008. disposetree(p^.right);
  4009. { we cannot set p to nil !!! }
  4010. if assigned(hp) then
  4011. begin
  4012. putnode(p);
  4013. p:=hp;
  4014. end
  4015. else
  4016. begin
  4017. p^.left:=nil;
  4018. p^.right:=nil;
  4019. p^.treetype:=nothingn;
  4020. end;
  4021. end;
  4022. end;
  4023. t_times:=old_t_times;
  4024. end;
  4025. procedure firstexitn(var p : ptree);
  4026. begin
  4027. if assigned(p^.left) then
  4028. begin
  4029. firstpass(p^.left);
  4030. p^.registers32:=p^.left^.registers32;
  4031. p^.registersfpu:=p^.left^.registersfpu;
  4032. {$ifdef SUPPORT_MMX}
  4033. p^.registersmmx:=p^.left^.registersmmx;
  4034. {$endif SUPPORT_MMX}
  4035. end;
  4036. end;
  4037. procedure firstfor(var p : ptree);
  4038. var
  4039. old_t_times : longint;
  4040. begin
  4041. { Registergewichtung bestimmen
  4042. (nicht genau), }
  4043. old_t_times:=t_times;
  4044. if not(cs_littlesize in aktswitches ) then
  4045. t_times:=t_times*8;
  4046. cleartempgen;
  4047. if p^.t1<>nil then
  4048. firstpass(p^.t1);
  4049. p^.registers32:=p^.t1^.registers32;
  4050. p^.registersfpu:=p^.t1^.registersfpu;
  4051. {$ifdef SUPPORT_MMX}
  4052. p^.registersmmx:=p^.left^.registersmmx;
  4053. {$endif SUPPORT_MMX}
  4054. if p^.left^.treetype<>assignn then
  4055. Message(cg_e_illegal_expression);
  4056. { Laufvariable retten }
  4057. p^.t2:=getcopy(p^.left^.left);
  4058. { Check count var }
  4059. if (p^.t2^.treetype<>loadn) then
  4060. Message(cg_e_illegal_count_var);
  4061. if (not(is_ordinal(p^.t2^.resulttype))) then
  4062. Message(parser_e_ordinal_expected);
  4063. cleartempgen;
  4064. must_be_valid:=false;
  4065. firstpass(p^.left);
  4066. must_be_valid:=true;
  4067. if p^.left^.registers32>p^.registers32 then
  4068. p^.registers32:=p^.left^.registers32;
  4069. if p^.left^.registersfpu>p^.registersfpu then
  4070. p^.registersfpu:=p^.left^.registersfpu;
  4071. {$ifdef SUPPORT_MMX}
  4072. if p^.left^.registersmmx>p^.registersmmx then
  4073. p^.registersmmx:=p^.left^.registersmmx;
  4074. {$endif SUPPORT_MMX}
  4075. cleartempgen;
  4076. firstpass(p^.t2);
  4077. if p^.t2^.registers32>p^.registers32 then
  4078. p^.registers32:=p^.t2^.registers32;
  4079. if p^.t2^.registersfpu>p^.registersfpu then
  4080. p^.registersfpu:=p^.t2^.registersfpu;
  4081. {$ifdef SUPPORT_MMX}
  4082. if p^.t2^.registersmmx>p^.registersmmx then
  4083. p^.registersmmx:=p^.t2^.registersmmx;
  4084. {$endif SUPPORT_MMX}
  4085. cleartempgen;
  4086. firstpass(p^.right);
  4087. if p^.right^.treetype<>ordconstn then
  4088. begin
  4089. p^.right:=gentypeconvnode(p^.right,p^.t2^.resulttype);
  4090. cleartempgen;
  4091. firstpass(p^.right);
  4092. end;
  4093. if p^.right^.registers32>p^.registers32 then
  4094. p^.registers32:=p^.right^.registers32;
  4095. if p^.right^.registersfpu>p^.registersfpu then
  4096. p^.registersfpu:=p^.right^.registersfpu;
  4097. {$ifdef SUPPORT_MMX}
  4098. if p^.right^.registersmmx>p^.registersmmx then
  4099. p^.registersmmx:=p^.right^.registersmmx;
  4100. {$endif SUPPORT_MMX}
  4101. t_times:=old_t_times;
  4102. end;
  4103. procedure firstasm(var p : ptree);
  4104. begin
  4105. { it's a f... to determine the used registers }
  4106. { should be done by getnode
  4107. I think also, that all values should be set to their maximum (FK)
  4108. p^.registers32:=0;
  4109. p^.registersfpu:=0;
  4110. p^.registersmmx:=0;
  4111. }
  4112. procinfo.flags:=procinfo.flags or pi_uses_asm;
  4113. end;
  4114. procedure firstgoto(var p : ptree);
  4115. begin
  4116. {
  4117. p^.registers32:=0;
  4118. p^.registersfpu:=0;
  4119. }
  4120. p^.resulttype:=voiddef;
  4121. end;
  4122. procedure firstlabel(var p : ptree);
  4123. begin
  4124. cleartempgen;
  4125. firstpass(p^.left);
  4126. p^.registers32:=p^.left^.registers32;
  4127. p^.registersfpu:=p^.left^.registersfpu;
  4128. {$ifdef SUPPORT_MMX}
  4129. p^.registersmmx:=p^.left^.registersmmx;
  4130. {$endif SUPPORT_MMX}
  4131. p^.resulttype:=voiddef;
  4132. end;
  4133. procedure firstcase(var p : ptree);
  4134. var
  4135. old_t_times : longint;
  4136. hp : ptree;
  4137. begin
  4138. { evalutes the case expression }
  4139. cleartempgen;
  4140. must_be_valid:=true;
  4141. firstpass(p^.left);
  4142. if codegenerror then
  4143. exit;
  4144. p^.registers32:=p^.left^.registers32;
  4145. p^.registersfpu:=p^.left^.registersfpu;
  4146. {$ifdef SUPPORT_MMX}
  4147. p^.registersmmx:=p^.left^.registersmmx;
  4148. {$endif SUPPORT_MMX}
  4149. { walk through all instructions }
  4150. { estimates the repeat of each instruction }
  4151. old_t_times:=t_times;
  4152. if not(cs_littlesize in aktswitches ) then
  4153. begin
  4154. t_times:=t_times div case_count_labels(p^.nodes);
  4155. if t_times<1 then
  4156. t_times:=1;
  4157. end;
  4158. { first case }
  4159. hp:=p^.right;
  4160. while assigned(hp) do
  4161. begin
  4162. cleartempgen;
  4163. firstpass(hp^.right);
  4164. { searchs max registers }
  4165. if hp^.right^.registers32>p^.registers32 then
  4166. p^.registers32:=hp^.right^.registers32;
  4167. if hp^.right^.registersfpu>p^.registersfpu then
  4168. p^.registersfpu:=hp^.right^.registersfpu;
  4169. {$ifdef SUPPORT_MMX}
  4170. if hp^.right^.registersmmx>p^.registersmmx then
  4171. p^.registersmmx:=hp^.right^.registersmmx;
  4172. {$endif SUPPORT_MMX}
  4173. hp:=hp^.left;
  4174. end;
  4175. { may be handle else tree }
  4176. if assigned(p^.elseblock) then
  4177. begin
  4178. cleartempgen;
  4179. firstpass(p^.elseblock);
  4180. if codegenerror then
  4181. exit;
  4182. if p^.registers32<p^.elseblock^.registers32 then
  4183. p^.registers32:=p^.elseblock^.registers32;
  4184. if p^.registersfpu<p^.elseblock^.registersfpu then
  4185. p^.registersfpu:=p^.elseblock^.registersfpu;
  4186. {$ifdef SUPPORT_MMX}
  4187. if p^.registersmmx<p^.elseblock^.registersmmx then
  4188. p^.registersmmx:=p^.elseblock^.registersmmx;
  4189. {$endif SUPPORT_MMX}
  4190. end;
  4191. t_times:=old_t_times;
  4192. { there is one register required for the case expression }
  4193. if p^.registers32<1 then p^.registers32:=1;
  4194. end;
  4195. procedure firsttryexcept(var p : ptree);
  4196. begin
  4197. end;
  4198. procedure firsttryfinally(var p : ptree);
  4199. begin
  4200. end;
  4201. procedure firstis(var p : ptree);
  4202. begin
  4203. firstpass(p^.left);
  4204. firstpass(p^.right);
  4205. if (p^.right^.resulttype^.deftype<>classrefdef) then
  4206. Message(sym_e_type_mismatch);
  4207. if codegenerror then
  4208. exit;
  4209. left_right_max(p);
  4210. { left must be a class }
  4211. if (p^.left^.resulttype^.deftype<>objectdef) or
  4212. not(pobjectdef(p^.left^.resulttype)^.isclass) then
  4213. Message(sym_e_type_mismatch);
  4214. { the operands must be related }
  4215. if (not(pobjectdef(p^.left^.resulttype)^.isrelated(
  4216. pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)))) and
  4217. (not(pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)^.isrelated(
  4218. pobjectdef(p^.left^.resulttype)))) then
  4219. Message(sym_e_type_mismatch);
  4220. p^.location.loc:=LOC_FLAGS;
  4221. p^.resulttype:=booldef;
  4222. end;
  4223. procedure firstas(var p : ptree);
  4224. begin
  4225. firstpass(p^.right);
  4226. firstpass(p^.left);
  4227. if (p^.right^.resulttype^.deftype<>classrefdef) then
  4228. Message(sym_e_type_mismatch);
  4229. if codegenerror then
  4230. exit;
  4231. left_right_max(p);
  4232. (* this was wrong,no ??
  4233. p^.registersfpu:=max(p^.left^.registersfpu,p^.left^.registersfpu);
  4234. p^.registers32:=max(p^.left^.registers32,p^.right^.registers32);
  4235. {$ifdef SUPPORT_MMX}
  4236. p^.registersmmx:=max(p^.left^.registersmmx,p^.right^.registersmmx);
  4237. {$endif SUPPORT_MMX} *)
  4238. { left must be a class }
  4239. if (p^.left^.resulttype^.deftype<>objectdef) or
  4240. not(pobjectdef(p^.left^.resulttype)^.isclass) then
  4241. Message(sym_e_type_mismatch);
  4242. { the operands must be related }
  4243. if (not(pobjectdef(p^.left^.resulttype)^.isrelated(
  4244. pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)))) and
  4245. (not(pobjectdef(pclassrefdef(p^.right^.resulttype)^.definition)^.isrelated(
  4246. pobjectdef(p^.left^.resulttype)))) then
  4247. Message(sym_e_type_mismatch);
  4248. p^.location:=p^.left^.location;
  4249. p^.resulttype:=pclassrefdef(p^.right^.resulttype)^.definition;
  4250. end;
  4251. procedure firstloadvmt(var p : ptree);
  4252. begin
  4253. { resulttype must be set !
  4254. p^.registersfpu:=0;
  4255. }
  4256. p^.registers32:=1;
  4257. p^.location.loc:=LOC_REGISTER;
  4258. end;
  4259. procedure firstraise(var p : ptree);
  4260. begin
  4261. p^.resulttype:=voiddef;
  4262. {
  4263. p^.registersfpu:=0;
  4264. p^.registers32:=0;
  4265. }
  4266. if assigned(p^.left) then
  4267. begin
  4268. firstpass(p^.left);
  4269. { this must be a _class_ }
  4270. if (p^.left^.resulttype^.deftype<>objectdef) or
  4271. ((pobjectdef(p^.left^.resulttype)^.options and oois_class)=0) then
  4272. Message(sym_e_type_mismatch);
  4273. p^.registersfpu:=p^.left^.registersfpu;
  4274. p^.registers32:=p^.left^.registers32;
  4275. {$ifdef SUPPORT_MMX}
  4276. p^.registersmmx:=p^.left^.registersmmx;
  4277. {$endif SUPPORT_MMX}
  4278. if assigned(p^.right) then
  4279. begin
  4280. firstpass(p^.right);
  4281. p^.right:=gentypeconvnode(p^.right,s32bitdef);
  4282. firstpass(p^.right);
  4283. left_right_max(p);
  4284. end;
  4285. end;
  4286. end;
  4287. procedure firstwith(var p : ptree);
  4288. begin
  4289. if assigned(p^.left) and assigned(p^.right) then
  4290. begin
  4291. firstpass(p^.left);
  4292. if codegenerror then
  4293. exit;
  4294. firstpass(p^.right);
  4295. if codegenerror then
  4296. exit;
  4297. left_right_max(p);
  4298. p^.resulttype:=voiddef;
  4299. end
  4300. else
  4301. begin
  4302. { optimization }
  4303. disposetree(p);
  4304. p:=nil;
  4305. end;
  4306. end;
  4307. procedure firstprocinline(var p : ptree);
  4308. begin
  4309. {left contains the code in tree form }
  4310. { but it has already been firstpassed }
  4311. { so firstpass(p^.left); does not seem required }
  4312. { might be required later if we change the arg handling !! }
  4313. end;
  4314. type
  4315. firstpassproc = procedure(var p : ptree);
  4316. procedure firstpass(var p : ptree);
  4317. (* ttreetyp = (addn, {Represents the + operator.}
  4318. muln, {Represents the * operator.}
  4319. subn, {Represents the - operator.}
  4320. divn, {Represents the div operator.}
  4321. symdifn, {Represents the >< operator.}
  4322. modn, {Represents the mod operator.}
  4323. assignn, {Represents an assignment.}
  4324. loadn, {Represents the use of a variabele.}
  4325. rangen, {Represents a range (i.e. 0..9).}
  4326. ltn, {Represents the < operator.}
  4327. lten, {Represents the <= operator.}
  4328. gtn, {Represents the > operator.}
  4329. gten, {Represents the >= operator.}
  4330. equaln, {Represents the = operator.}
  4331. unequaln, {Represents the <> operator.}
  4332. inn, {Represents the in operator.}
  4333. orn, {Represents the or operator.}
  4334. xorn, {Represents the xor operator.}
  4335. shrn, {Represents the shr operator.}
  4336. shln, {Represents the shl operator.}
  4337. slashn, {Represents the / operator.}
  4338. andn, {Represents the and operator.}
  4339. subscriptn, {??? Field in a record/object?}
  4340. derefn, {Dereferences a pointer.}
  4341. addrn, {Represents the @ operator.}
  4342. doubleaddrn, {Represents the @@ operator.}
  4343. ordconstn, {Represents an ordinal value.}
  4344. typeconvn, {Represents type-conversion/typecast.}
  4345. calln, {Represents a call node.}
  4346. callparan, {Represents a parameter.}
  4347. realconstn, {Represents a real value.}
  4348. fixconstn, {Represents a fixed value.}
  4349. umminusn, {Represents a sign change (i.e. -2).}
  4350. asmn, {Represents an assembler node }
  4351. vecn, {Represents array indexing.}
  4352. stringconstn, {Represents a string constant.}
  4353. funcretn, {Represents the function result var.}
  4354. selfn, {Represents the self parameter.}
  4355. notn, {Represents the not operator.}
  4356. inlinen, {Internal procedures (i.e. writeln).}
  4357. niln, {Represents the nil pointer.}
  4358. errorn, {This part of the tree could not be
  4359. parsed because of a compiler error.}
  4360. typen, {A type name. Used for i.e. typeof(obj).}
  4361. hnewn, {The new operation, constructor call.}
  4362. hdisposen, {The dispose operation with destructor call.}
  4363. newn, {The new operation, constructor call.}
  4364. simpledisposen, {The dispose operation.}
  4365. setelen, {A set element (i.e. [a,b]).}
  4366. setconstrn, {A set constant (i.e. [1,2]).}
  4367. blockn, {A block of statements.}
  4368. statementn, {One statement in list of nodes.}
  4369. loopn, { used in genloopnode, must be converted }
  4370. ifn, {An if statement.}
  4371. breakn, {A break statement.}
  4372. continuen, {A continue statement.}
  4373. repeatn, {A repeat until block.}
  4374. whilen, {A while do statement.}
  4375. forn, {A for loop.}
  4376. exitn, {An exit statement.}
  4377. withn, {A with statement.}
  4378. casen, {A case statement.}
  4379. labeln, {A label.}
  4380. goton, {A goto statement.}
  4381. simplenewn, {The new operation.}
  4382. tryexceptn, {A try except block.}
  4383. raisen, {A raise statement.}
  4384. switchesn, {??? Currently unused...}
  4385. tryfinallyn, {A try finally statement.}
  4386. isn, {Represents the is operator.}
  4387. asn, {Represents the as typecast.}
  4388. caretn, {Represents the ^ operator.}
  4389. failn, {Represents the fail statement.}
  4390. starstarn, {Represents the ** operator exponentiation }
  4391. procinlinen, {Procedures that can be inlined }
  4392. { added for optimizations where we cannot suppress }
  4393. nothingn,
  4394. loadvmtn); {???.} *)
  4395. const
  4396. procedures : array[ttreetyp] of firstpassproc =
  4397. (firstadd,firstadd,firstadd,firstmoddiv,firstadd,
  4398. firstmoddiv,firstassignment,firstload,firstrange,
  4399. firstadd,firstadd,firstadd,firstadd,
  4400. firstadd,firstadd,firstin,firstadd,
  4401. firstadd,firstshlshr,firstshlshr,firstadd,
  4402. firstadd,firstsubscriptn,firstderef,firstaddr,firstdoubleaddr,
  4403. firstordconst,firsttypeconv,firstcalln,firstnothing,
  4404. firstrealconst,firstfixconst,firstumminus,firstasm,firstvecn,
  4405. firststringconst,firstfuncret,firstselfn,
  4406. firstnot,firstinline,firstniln,firsterror,
  4407. firsttypen,firsthnewn,firsthdisposen,firstnewn,
  4408. firstsimplenewdispose,firstnothing,firstsetcons,firstblock,
  4409. firststatement,firstnothing,firstif,firstnothing,
  4410. firstnothing,first_while_repeat,first_while_repeat,firstfor,
  4411. firstexitn,firstwith,firstcase,firstlabel,
  4412. firstgoto,firstsimplenewdispose,firsttryexcept,firstraise,
  4413. firstnothing,firsttryfinally,firstis,firstas,firstadd,
  4414. firstnothing,firstadd,firstprocinline,firstnothing,firstloadvmt);
  4415. var
  4416. oldcodegenerror : boolean;
  4417. oldswitches : Tcswitches;
  4418. { there some calls of do_firstpass in the parser }
  4419. oldis : pinputfile;
  4420. oldnr : longint;
  4421. {$ifdef extdebug}
  4422. str1,str2 : string;
  4423. oldp : ptree;
  4424. not_first : boolean;
  4425. {$endif extdebug}
  4426. begin
  4427. {$ifdef extdebug}
  4428. if (p^.firstpasscount>0) and only_one_pass then
  4429. exit;
  4430. {$endif extdebug}
  4431. { if we save there the whole stuff, }
  4432. { line numbers become more correct }
  4433. oldis:=current_module^.current_inputfile;
  4434. oldnr:=current_module^.current_inputfile^.line_no;
  4435. oldcodegenerror:=codegenerror;
  4436. oldswitches:=aktswitches;
  4437. {$ifdef extdebug}
  4438. if p^.firstpasscount>0 then
  4439. begin
  4440. move(p^,str1[1],sizeof(ttree));
  4441. str1[0]:=char(sizeof(ttree));
  4442. new(oldp);
  4443. oldp^:=p^;
  4444. not_first:=true;
  4445. end
  4446. else
  4447. not_first:=false;
  4448. {$endif extdebug}
  4449. codegenerror:=false;
  4450. current_module^.current_inputfile:=
  4451. pinputfile(current_module^.sourcefiles.get_file(p^.fileinfo.fileindex));
  4452. current_module^.current_inputfile^.line_no:=p^.fileinfo.line;
  4453. aktswitches:=p^.pragmas;
  4454. if not(p^.error) then
  4455. begin
  4456. procedures[p^.treetype](p);
  4457. p^.error:=codegenerror;
  4458. codegenerror:=codegenerror or oldcodegenerror;
  4459. end
  4460. else codegenerror:=true;
  4461. {$ifdef extdebug}
  4462. if not_first then
  4463. begin
  4464. { dirty trick to compare two ttree's (PM) }
  4465. move(p^,str2[1],sizeof(ttree));
  4466. str2[0]:=char(sizeof(ttree));
  4467. if str1<>str2 then
  4468. begin
  4469. comment(v_debug,'tree changed after first counting pass '
  4470. +tostr(longint(p^.treetype)));
  4471. compare_trees(oldp,p);
  4472. end;
  4473. dispose(oldp);
  4474. end;
  4475. if count_ref then
  4476. inc(p^.firstpasscount);
  4477. {$endif extdebug}
  4478. aktswitches:=oldswitches;
  4479. current_module^.current_inputfile:=oldis;
  4480. current_module^.current_inputfile^.line_no:=oldnr;
  4481. end;
  4482. function do_firstpass(var p : ptree) : boolean;
  4483. begin
  4484. codegenerror:=false;
  4485. firstpass(p);
  4486. do_firstpass:=codegenerror;
  4487. end;
  4488. { to be called only for a whole function }
  4489. { to insert code at entry and exit }
  4490. function function_firstpass(var p : ptree) : boolean;
  4491. begin
  4492. codegenerror:=false;
  4493. firstpass(p);
  4494. function_firstpass:=codegenerror;
  4495. end;
  4496. end.
  4497. {
  4498. $Log$
  4499. Revision 1.21 1998-05-25 17:11:41 pierre
  4500. * firstpasscount bug fixed
  4501. now all is already set correctly the first time
  4502. under EXTDEBUG try -gp to skip all other firstpasses
  4503. it works !!
  4504. * small bug fixes
  4505. - for smallsets with -dTESTSMALLSET
  4506. - some warnings removed (by correcting code !)
  4507. Revision 1.20 1998/05/23 01:21:17 peter
  4508. + aktasmmode, aktoptprocessor, aktoutputformat
  4509. + smartlink per module $SMARTLINK-/+ (like MMX) and moved to aktswitches
  4510. + $LIBNAME to set the library name where the unit will be put in
  4511. * splitted cgi386 a bit (codeseg to large for bp7)
  4512. * nasm, tasm works again. nasm moved to ag386nsm.pas
  4513. Revision 1.19 1998/05/20 09:42:34 pierre
  4514. + UseTokenInfo now default
  4515. * unit in interface uses and implementation uses gives error now
  4516. * only one error for unknown symbol (uses lastsymknown boolean)
  4517. the problem came from the label code !
  4518. + first inlined procedures and function work
  4519. (warning there might be allowed cases were the result is still wrong !!)
  4520. * UseBrower updated gives a global list of all position of all used symbols
  4521. with switch -gb
  4522. Revision 1.18 1998/05/11 13:07:55 peter
  4523. + $ifdef NEWPPU for the new ppuformat
  4524. + $define GDB not longer required
  4525. * removed all warnings and stripped some log comments
  4526. * no findfirst/findnext anymore to remove smartlink *.o files
  4527. Revision 1.17 1998/05/06 08:38:43 pierre
  4528. * better position info with UseTokenInfo
  4529. UseTokenInfo greatly simplified
  4530. + added check for changed tree after first time firstpass
  4531. (if we could remove all the cases were it happen
  4532. we could skip all firstpass if firstpasscount > 1)
  4533. Only with ExtDebug
  4534. Revision 1.16 1998/05/01 16:38:45 florian
  4535. * handling of private and protected fixed
  4536. + change_keywords_to_tp implemented to remove
  4537. keywords which aren't supported by tp
  4538. * break and continue are now symbols of the system unit
  4539. + widestring, longstring and ansistring type released
  4540. Revision 1.15 1998/05/01 09:01:23 florian
  4541. + correct semantics of private and protected
  4542. * small fix in variable scope:
  4543. a id can be used in a parameter list of a method, even it is used in
  4544. an anchestor class as field id
  4545. Revision 1.14 1998/04/30 15:59:41 pierre
  4546. * GDB works again better :
  4547. correct type info in one pass
  4548. + UseTokenInfo for better source position
  4549. * fixed one remaining bug in scanner for line counts
  4550. * several little fixes
  4551. Revision 1.13 1998/04/29 10:33:56 pierre
  4552. + added some code for ansistring (not complete nor working yet)
  4553. * corrected operator overloading
  4554. * corrected nasm output
  4555. + started inline procedures
  4556. + added starstarn : use ** for exponentiation (^ gave problems)
  4557. + started UseTokenInfo cond to get accurate positions
  4558. Revision 1.12 1998/04/22 21:06:50 florian
  4559. * last fixes before the release:
  4560. - veryyyy slow firstcall fixed
  4561. Revision 1.11 1998/04/21 10:16:48 peter
  4562. * patches from strasbourg
  4563. * objects is not used anymore in the fpc compiled version
  4564. Revision 1.10 1998/04/14 23:27:03 florian
  4565. + exclude/include with constant second parameter added
  4566. Revision 1.9 1998/04/13 21:15:42 florian
  4567. * error handling of pass_1 and cgi386 fixed
  4568. * the following bugs fixed: 0117, 0118, 0119 and 0129, 0122 was already
  4569. fixed, verified
  4570. Revision 1.8 1998/04/13 08:42:52 florian
  4571. * call by reference and call by value open arrays fixed
  4572. Revision 1.7 1998/04/12 22:39:44 florian
  4573. * problem with read access to properties solved
  4574. * correct handling of hidding methods via virtual (COM)
  4575. * correct result type of constructor calls (COM), the resulttype
  4576. depends now on the type of the class reference
  4577. Revision 1.6 1998/04/09 22:16:34 florian
  4578. * problem with previous REGALLOC solved
  4579. * improved property support
  4580. Revision 1.5 1998/04/08 16:58:04 pierre
  4581. * several bugfixes
  4582. ADD ADC and AND are also sign extended
  4583. nasm output OK (program still crashes at end
  4584. and creates wrong assembler files !!)
  4585. procsym types sym in tdef removed !!
  4586. Revision 1.4 1998/04/07 22:45:04 florian
  4587. * bug0092, bug0115 and bug0121 fixed
  4588. + packed object/class/array
  4589. }