tree.pas 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Florian Klaempfl
  4. This units exports some routines to manage the parse tree
  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. {$E+,N+}
  20. {$endif}
  21. unit tree;
  22. interface
  23. uses
  24. globtype,cobjects
  25. {$IFDEF NEWST}
  26. ,objects,symtable,symbols,defs
  27. {$ELSE}
  28. ,symconst,symtable
  29. {$ENDIF NEWST}
  30. ,aasm,cpubase;
  31. type
  32. pconstset = ^tconstset;
  33. tconstset = array[0..31] of byte;
  34. ttreetyp = (
  35. addn, {Represents the + operator.}
  36. muln, {Represents the * operator.}
  37. subn, {Represents the - operator.}
  38. divn, {Represents the div operator.}
  39. symdifn, {Represents the >< operator.}
  40. modn, {Represents the mod operator.}
  41. assignn, {Represents an assignment.}
  42. loadn, {Represents the use of a variabele.}
  43. rangen, {Represents a range (i.e. 0..9).}
  44. ltn, {Represents the < operator.}
  45. lten, {Represents the <= operator.}
  46. gtn, {Represents the > operator.}
  47. gten, {Represents the >= operator.}
  48. equaln, {Represents the = operator.}
  49. unequaln, {Represents the <> operator.}
  50. inn, {Represents the in operator.}
  51. orn, {Represents the or operator.}
  52. xorn, {Represents the xor operator.}
  53. shrn, {Represents the shr operator.}
  54. shln, {Represents the shl operator.}
  55. slashn, {Represents the / operator.}
  56. andn, {Represents the and operator.}
  57. subscriptn, {??? Field in a record/object?}
  58. derefn, {Dereferences a pointer.}
  59. addrn, {Represents the @ operator.}
  60. doubleaddrn, {Represents the @@ operator.}
  61. ordconstn, {Represents an ordinal value.}
  62. typeconvn, {Represents type-conversion/typecast.}
  63. calln, {Represents a call node.}
  64. callparan, {Represents a parameter.}
  65. realconstn, {Represents a real value.}
  66. fixconstn, {Represents a fixed value.}
  67. unaryminusn, {Represents a sign change (i.e. -2).}
  68. asmn, {Represents an assembler node }
  69. vecn, {Represents array indexing.}
  70. pointerconstn,
  71. stringconstn, {Represents a string constant.}
  72. funcretn, {Represents the function result var.}
  73. selfn, {Represents the self parameter.}
  74. notn, {Represents the not operator.}
  75. inlinen, {Internal procedures (i.e. writeln).}
  76. niln, {Represents the nil pointer.}
  77. errorn, {This part of the tree could not be
  78. parsed because of a compiler error.}
  79. typen, {A type name. Used for i.e. typeof(obj).}
  80. hnewn, {The new operation, constructor call.}
  81. hdisposen, {The dispose operation with destructor call.}
  82. newn, {The new operation, constructor call.}
  83. simpledisposen, {The dispose operation.}
  84. setelementn, {A set element(s) (i.e. [a,b] and also [a..b]).}
  85. setconstn, {A set constant (i.e. [1,2]).}
  86. blockn, {A block of statements.}
  87. statementn, {One statement in a block of nodes.}
  88. loopn, { used in genloopnode, must be converted }
  89. ifn, {An if statement.}
  90. breakn, {A break statement.}
  91. continuen, {A continue statement.}
  92. repeatn, {A repeat until block.}
  93. whilen, {A while do statement.}
  94. forn, {A for loop.}
  95. exitn, {An exit statement.}
  96. withn, {A with statement.}
  97. casen, {A case statement.}
  98. labeln, {A label.}
  99. goton, {A goto statement.}
  100. simplenewn, {The new operation.}
  101. tryexceptn, {A try except block.}
  102. raisen, {A raise statement.}
  103. switchesn, {??? Currently unused...}
  104. tryfinallyn, {A try finally statement.}
  105. onn, { for an on statement in exception code }
  106. isn, {Represents the is operator.}
  107. asn, {Represents the as typecast.}
  108. caretn, {Represents the ^ operator.}
  109. failn, {Represents the fail statement.}
  110. starstarn, {Represents the ** operator exponentiation }
  111. procinlinen, {Procedures that can be inlined }
  112. arrayconstructn, {Construction node for [...] parsing}
  113. arrayconstructrangen, {Range element to allow sets in array construction tree}
  114. { added for optimizations where we cannot suppress }
  115. nothingn,
  116. loadvmtn
  117. );
  118. tconverttype = (
  119. tc_equal,
  120. tc_not_possible,
  121. tc_string_2_string,
  122. tc_char_2_string,
  123. tc_pchar_2_string,
  124. tc_cchar_2_pchar,
  125. tc_cstring_2_pchar,
  126. tc_ansistring_2_pchar,
  127. tc_string_2_chararray,
  128. tc_chararray_2_string,
  129. tc_array_2_pointer,
  130. tc_pointer_2_array,
  131. tc_int_2_int,
  132. tc_int_2_bool,
  133. tc_bool_2_bool,
  134. tc_bool_2_int,
  135. tc_real_2_real,
  136. tc_int_2_real,
  137. tc_int_2_fix,
  138. tc_real_2_fix,
  139. tc_fix_2_real,
  140. tc_proc_2_procvar,
  141. tc_arrayconstructor_2_set,
  142. tc_load_smallset,
  143. tc_cord_2_pointer
  144. );
  145. { allows to determine which elementes are to be replaced }
  146. tdisposetyp = (dt_nothing,dt_leftright,dt_left,dt_leftrighthigh,
  147. dt_mbleft,dt_typeconv,dt_inlinen,dt_leftrightmethod,
  148. dt_mbleft_and_method,dt_loop,dt_case,dt_with,dt_onn,
  149. dt_leftrightframe);
  150. { different assignment types }
  151. tassigntyp = (at_normal,at_plus,at_minus,at_star,at_slash);
  152. pcaserecord = ^tcaserecord;
  153. tcaserecord = record
  154. { range }
  155. _low,_high : longint;
  156. { only used by gentreejmp }
  157. _at : pasmlabel;
  158. { label of instruction }
  159. statement : pasmlabel;
  160. { is this the first of an case entry, needed to release statement
  161. label (PFV) }
  162. firstlabel : boolean;
  163. { left and right tree node }
  164. less,greater : pcaserecord;
  165. end;
  166. ptree = ^ttree;
  167. ttree = record
  168. error : boolean;
  169. disposetyp : tdisposetyp;
  170. { is true, if the right and left operand are swaped }
  171. swaped : boolean;
  172. { do we need to parse childs to set var state }
  173. varstateset : boolean;
  174. { the location of the result of this node }
  175. location : tlocation;
  176. { the number of registers needed to evalute the node }
  177. registers32,registersfpu : longint; { must be longint !!!! }
  178. {$ifdef SUPPORT_MMX}
  179. registersmmx : longint;
  180. {$endif SUPPORT_MMX}
  181. left,right : ptree;
  182. resulttype : pdef;
  183. fileinfo : tfileposinfo;
  184. localswitches : tlocalswitches;
  185. isproperty : boolean;
  186. {$ifdef extdebug}
  187. firstpasscount : longint;
  188. {$endif extdebug}
  189. {$ifdef TEMPREGDEBUG}
  190. usableregs : longint;
  191. {$endif TEMPREGDEBUG}
  192. {$ifdef EXTTEMPREGDEBUG}
  193. reallyusedregs : longint;
  194. {$endif EXTTEMPREGDEBUG}
  195. {$ifdef TEMPS_NOT_PUSH}
  196. temp_offset : longint;
  197. {$endif TEMPS_NOT_PUSH}
  198. case treetype : ttreetyp of
  199. addn : (use_strconcat : boolean;string_typ : tstringtype);
  200. callparan : (is_colon_para : boolean;exact_match_found,
  201. convlevel1found,convlevel2found:boolean;hightree:ptree);
  202. assignn : (assigntyp : tassigntyp;concat_string : boolean);
  203. loadn : (symtableentry : psym;symtable : psymtable;
  204. is_absolute,is_first : boolean);
  205. calln : (symtableprocentry : pprocsym;
  206. symtableproc : psymtable;procdefinition : pabstractprocdef;
  207. methodpointer : ptree;
  208. no_check,unit_specific,
  209. return_value_used,static_call : boolean);
  210. addrn : (procvarload:boolean);
  211. ordconstn : (value : longint);
  212. realconstn : (value_real : bestreal;lab_real : pasmlabel);
  213. fixconstn : (value_fix: longint);
  214. funcretn : (funcretprocinfo : pointer;
  215. {$IFDEF NEWST}
  216. retsym:Psym;
  217. {$ELSE}
  218. rettype : ttype;
  219. {$ENDIF}
  220. is_first_funcret : boolean);
  221. subscriptn : (vs : pvarsym);
  222. raisen : (frametree : ptree);
  223. vecn : (memindex,memseg:boolean;callunique : boolean);
  224. stringconstn : (value_str : pchar;length : longint; lab_str : pasmlabel;stringtype : tstringtype);
  225. typeconvn : (convtyp : tconverttype;explizit : boolean);
  226. typen : (typenodetype : pdef;typenodesym:ptypesym);
  227. inlinen : (inlinenumber : byte;inlineconst:boolean);
  228. procinlinen : (inlinetree:ptree;inlineprocsym:pprocsym;retoffset,para_offset,para_size : longint);
  229. setconstn : (value_set : pconstset;lab_set:pasmlabel);
  230. loopn : (t1,t2 : ptree;backward : boolean);
  231. asmn : (p_asm : paasmoutput;object_preserved : boolean);
  232. casen : (nodes : pcaserecord;elseblock : ptree);
  233. labeln,goton : (labelnr : pasmlabel;exceptionblock : ptree;labsym : plabelsym);
  234. {$IFDEF NEWST}
  235. withn : (withsymtables:Pcollection;
  236. withreference:preference;
  237. islocal:boolean);
  238. {$ELSE}
  239. withn : (withsymtable : pwithsymtable;
  240. tablecount : longint;
  241. withreference:preference;
  242. islocal:boolean);
  243. {$ENDIF NEWST}
  244. onn : (exceptsymtable : psymtable;excepttype : pobjectdef);
  245. arrayconstructn : (cargs,cargswap,forcevaria,novariaallowed: boolean;constructdef:pdef);
  246. end;
  247. function gennode(t : ttreetyp;l,r : ptree) : ptree;
  248. function genlabelnode(t : ttreetyp;nr : pasmlabel) : ptree;
  249. function genloadnode(v : pvarsym;st : psymtable) : ptree;
  250. function genloadcallnode(v: pprocsym;st: psymtable): ptree;
  251. function genloadmethodcallnode(v: pprocsym;st: psymtable; mp:ptree): ptree;
  252. function gensinglenode(t : ttreetyp;l : ptree) : ptree;
  253. function gensubscriptnode(varsym : pvarsym;l : ptree) : ptree;
  254. function genordinalconstnode(v : longint;def : pdef) : ptree;
  255. function genpointerconstnode(v : longint;def : pdef) : ptree;
  256. function genfixconstnode(v : longint;def : pdef) : ptree;
  257. function gentypeconvnode(node : ptree;t : pdef) : ptree;
  258. function gentypenode(t : pdef;sym:ptypesym) : ptree;
  259. function gencallparanode(expr,next : ptree) : ptree;
  260. function genrealconstnode(v : bestreal;def : pdef) : ptree;
  261. function gencallnode(v : pprocsym;st : psymtable) : ptree;
  262. function genmethodcallnode(v : pprocsym;st : psymtable;mp : ptree) : ptree;
  263. { allow pchar or string for defining a pchar node }
  264. function genstringconstnode(const s : string;st:tstringtype) : ptree;
  265. { length is required for ansistrings }
  266. function genpcharconstnode(s : pchar;length : longint) : ptree;
  267. { helper routine for conststring node }
  268. function getpcharcopy(p : ptree) : pchar;
  269. function genzeronode(t : ttreetyp) : ptree;
  270. function geninlinenode(number : byte;is_const:boolean;l : ptree) : ptree;
  271. function genprocinlinenode(callp,code : ptree) : ptree;
  272. function gentypedconstloadnode(sym : ptypedconstsym;st : psymtable) : ptree;
  273. function genenumnode(v : penumsym) : ptree;
  274. function genselfnode(_class : pdef) : ptree;
  275. function gensetconstnode(s : pconstset;settype : psetdef) : ptree;
  276. function genloopnode(t : ttreetyp;l,r,n1: ptree;back : boolean) : ptree;
  277. function genasmnode(p_asm : paasmoutput) : ptree;
  278. function gencasenode(l,r : ptree;nodes : pcaserecord) : ptree;
  279. {$IFDEF NEWST}
  280. function genwithnode(symtables:Pcollection;l,r : ptree) : ptree;
  281. {$ELSE}
  282. function genwithnode(symtable:pwithsymtable;l,r : ptree;count : longint) : ptree;
  283. {$ENDIF NEWST}
  284. function getcopy(p : ptree) : ptree;
  285. function equal_trees(t1,t2 : ptree) : boolean;
  286. {$ifdef newoptimizations2}
  287. { checks if t1 is loaded more than once in t2 and its sub-trees }
  288. function multiple_uses(t1,t2: ptree): boolean;
  289. {$endif newoptimizations2}
  290. procedure swaptree(p:Ptree);
  291. procedure disposetree(p : ptree);
  292. procedure putnode(p : ptree);
  293. function getnode : ptree;
  294. procedure clear_location(var loc : tlocation);
  295. procedure set_location(var destloc,sourceloc : tlocation);
  296. procedure swap_location(var destloc,sourceloc : tlocation);
  297. procedure set_file_line(from,_to : ptree);
  298. procedure set_tree_filepos(p : ptree;const filepos : tfileposinfo);
  299. {$ifdef extdebug}
  300. procedure compare_trees(oldp,p : ptree);
  301. const
  302. maxfirstpasscount : longint = 0;
  303. {$endif extdebug}
  304. { sets the callunique flag, if the node is a vecn, }
  305. { takes care of type casts etc. }
  306. procedure set_unique(p : ptree);
  307. { sets funcret_is_valid to true, if p contains a funcref node }
  308. procedure set_funcret_is_valid(p : ptree);
  309. {
  310. type
  311. tvarstaterequire = (vsr_can_be_undefined,vsr_must_be_valid,
  312. vsr_is_used_after,vsr_must_be_valid_and_is_used_after); }
  313. { sets varsym varstate field correctly }
  314. procedure set_varstate(p : ptree;must_be_valid : boolean);
  315. { gibt den ordinalen Werten der Node zurueck oder falls sie }
  316. { keinen ordinalen Wert hat, wird ein Fehler erzeugt }
  317. function get_ordinal_value(p : ptree) : longint;
  318. function is_constnode(p : ptree) : boolean;
  319. { true, if p is a pointer to a const int value }
  320. function is_constintnode(p : ptree) : boolean;
  321. function is_constboolnode(p : ptree) : boolean;
  322. function is_constrealnode(p : ptree) : boolean;
  323. function is_constcharnode(p : ptree) : boolean;
  324. function str_length(p : ptree) : longint;
  325. function is_emptyset(p : ptree):boolean;
  326. { counts the labels }
  327. function case_count_labels(root : pcaserecord) : longint;
  328. { searches the highest label }
  329. function case_get_max(root : pcaserecord) : longint;
  330. { searches the lowest label }
  331. function case_get_min(root : pcaserecord) : longint;
  332. type
  333. pptree = ^ptree;
  334. {$ifdef TEMPREGDEBUG}
  335. const
  336. curptree : pptree = nil;
  337. {$endif TEMPREGDEBUG}
  338. {$I innr.inc}
  339. {$ifdef newcg}
  340. {$I nodeh.inc}
  341. {$endif newcg}
  342. implementation
  343. uses
  344. systems,
  345. globals,verbose,files,types,
  346. {$ifdef newcg}
  347. cgbase
  348. {$else newcg}
  349. hcodegen
  350. {$endif newcg}
  351. {$IFDEF NEWST}
  352. ,symtablt
  353. {$ENDIF}
  354. ;
  355. function getnode : ptree;
  356. var
  357. hp : ptree;
  358. begin
  359. new(hp);
  360. { makes error tracking easier }
  361. fillchar(hp^,sizeof(ttree),0);
  362. { reset }
  363. hp^.location.loc:=LOC_INVALID;
  364. { save local info }
  365. hp^.fileinfo:=aktfilepos;
  366. hp^.localswitches:=aktlocalswitches;
  367. getnode:=hp;
  368. end;
  369. procedure putnode(p : ptree);
  370. begin
  371. { clean up the contents of a node }
  372. case p^.treetype of
  373. asmn : if assigned(p^.p_asm) then
  374. dispose(p^.p_asm,done);
  375. stringconstn : begin
  376. ansistringdispose(p^.value_str,p^.length);
  377. end;
  378. setconstn : begin
  379. if assigned(p^.value_set) then
  380. dispose(p^.value_set);
  381. end;
  382. end;
  383. {$ifdef extdebug}
  384. if p^.firstpasscount>maxfirstpasscount then
  385. maxfirstpasscount:=p^.firstpasscount;
  386. {$endif extdebug}
  387. dispose(p);
  388. end;
  389. function getcopy(p : ptree) : ptree;
  390. var
  391. hp : ptree;
  392. begin
  393. if not assigned(p) then
  394. begin
  395. getcopy:=nil;
  396. exit;
  397. end;
  398. hp:=getnode;
  399. hp^:=p^;
  400. case p^.disposetyp of
  401. dt_leftright :
  402. begin
  403. if assigned(p^.left) then
  404. hp^.left:=getcopy(p^.left);
  405. if assigned(p^.right) then
  406. hp^.right:=getcopy(p^.right);
  407. end;
  408. dt_leftrighthigh :
  409. begin
  410. if assigned(p^.left) then
  411. hp^.left:=getcopy(p^.left);
  412. if assigned(p^.right) then
  413. hp^.right:=getcopy(p^.right);
  414. if assigned(p^.hightree) then
  415. hp^.left:=getcopy(p^.hightree);
  416. end;
  417. dt_leftrightframe :
  418. begin
  419. if assigned(p^.left) then
  420. hp^.left:=getcopy(p^.left);
  421. if assigned(p^.right) then
  422. hp^.right:=getcopy(p^.right);
  423. if assigned(p^.frametree) then
  424. hp^.left:=getcopy(p^.frametree);
  425. end;
  426. dt_leftrightmethod :
  427. begin
  428. if assigned(p^.left) then
  429. hp^.left:=getcopy(p^.left);
  430. if assigned(p^.right) then
  431. hp^.right:=getcopy(p^.right);
  432. if assigned(p^.methodpointer) then
  433. hp^.left:=getcopy(p^.methodpointer);
  434. end;
  435. dt_nothing : ;
  436. dt_left :
  437. if assigned(p^.left) then
  438. hp^.left:=getcopy(p^.left);
  439. dt_mbleft :
  440. if assigned(p^.left) then
  441. hp^.left:=getcopy(p^.left);
  442. dt_mbleft_and_method :
  443. begin
  444. if assigned(p^.left) then
  445. hp^.left:=getcopy(p^.left);
  446. hp^.methodpointer:=getcopy(p^.methodpointer);
  447. end;
  448. dt_loop :
  449. begin
  450. if assigned(p^.left) then
  451. hp^.left:=getcopy(p^.left);
  452. if assigned(p^.right) then
  453. hp^.right:=getcopy(p^.right);
  454. if assigned(p^.t1) then
  455. hp^.t1:=getcopy(p^.t1);
  456. if assigned(p^.t2) then
  457. hp^.t2:=getcopy(p^.t2);
  458. end;
  459. dt_typeconv : hp^.left:=getcopy(p^.left);
  460. dt_inlinen :
  461. if assigned(p^.left) then
  462. hp^.left:=getcopy(p^.left);
  463. else internalerror(11);
  464. end;
  465. { now check treetype }
  466. case p^.treetype of
  467. stringconstn : begin
  468. hp^.value_str:=getpcharcopy(p);
  469. hp^.length:=p^.length;
  470. end;
  471. setconstn : begin
  472. new(hp^.value_set);
  473. hp^.value_set:=p^.value_set;
  474. end;
  475. end;
  476. getcopy:=hp;
  477. end;
  478. procedure deletecaselabels(p : pcaserecord);
  479. begin
  480. if assigned(p^.greater) then
  481. deletecaselabels(p^.greater);
  482. if assigned(p^.less) then
  483. deletecaselabels(p^.less);
  484. dispose(p);
  485. end;
  486. procedure swaptree(p:Ptree);
  487. var swapp:Ptree;
  488. begin
  489. swapp:=p^.right;
  490. p^.right:=p^.left;
  491. p^.left:=swapp;
  492. p^.swaped:=not(p^.swaped);
  493. end;
  494. procedure disposetree(p : ptree);
  495. var
  496. symt : psymtable;
  497. i : longint;
  498. begin
  499. if not(assigned(p)) then
  500. exit;
  501. if not(p^.treetype in [addn..loadvmtn]) then
  502. internalerror(26219);
  503. case p^.disposetyp of
  504. dt_leftright :
  505. begin
  506. if assigned(p^.left) then
  507. disposetree(p^.left);
  508. if assigned(p^.right) then
  509. disposetree(p^.right);
  510. end;
  511. dt_leftrighthigh :
  512. begin
  513. if assigned(p^.left) then
  514. disposetree(p^.left);
  515. if assigned(p^.right) then
  516. disposetree(p^.right);
  517. if assigned(p^.hightree) then
  518. disposetree(p^.hightree);
  519. end;
  520. dt_leftrightframe :
  521. begin
  522. if assigned(p^.left) then
  523. disposetree(p^.left);
  524. if assigned(p^.right) then
  525. disposetree(p^.right);
  526. if assigned(p^.frametree) then
  527. disposetree(p^.frametree);
  528. end;
  529. dt_leftrightmethod :
  530. begin
  531. if assigned(p^.left) then
  532. disposetree(p^.left);
  533. if assigned(p^.right) then
  534. disposetree(p^.right);
  535. if assigned(p^.methodpointer) then
  536. disposetree(p^.methodpointer);
  537. end;
  538. dt_case :
  539. begin
  540. if assigned(p^.left) then
  541. disposetree(p^.left);
  542. if assigned(p^.right) then
  543. disposetree(p^.right);
  544. if assigned(p^.nodes) then
  545. deletecaselabels(p^.nodes);
  546. if assigned(p^.elseblock) then
  547. disposetree(p^.elseblock);
  548. end;
  549. dt_nothing : ;
  550. dt_left :
  551. if assigned(p^.left) then
  552. disposetree(p^.left);
  553. dt_mbleft :
  554. if assigned(p^.left) then
  555. disposetree(p^.left);
  556. dt_mbleft_and_method :
  557. begin
  558. if assigned(p^.left) then disposetree(p^.left);
  559. disposetree(p^.methodpointer);
  560. end;
  561. dt_typeconv : disposetree(p^.left);
  562. dt_inlinen :
  563. if assigned(p^.left) then
  564. disposetree(p^.left);
  565. dt_loop :
  566. begin
  567. if assigned(p^.left) then
  568. disposetree(p^.left);
  569. if assigned(p^.right) then
  570. disposetree(p^.right);
  571. if assigned(p^.t1) then
  572. disposetree(p^.t1);
  573. if assigned(p^.t2) then
  574. disposetree(p^.t2);
  575. end;
  576. dt_onn:
  577. begin
  578. if assigned(p^.left) then
  579. disposetree(p^.left);
  580. if assigned(p^.right) then
  581. disposetree(p^.right);
  582. if assigned(p^.exceptsymtable) then
  583. dispose(p^.exceptsymtable,done);
  584. end;
  585. dt_with :
  586. begin
  587. if assigned(p^.left) then
  588. disposetree(p^.left);
  589. if assigned(p^.right) then
  590. disposetree(p^.right);
  591. {$IFDEF NEWST}
  592. dispose(p^.withsymtables,done);
  593. {$ELSE}
  594. symt:=p^.withsymtable;
  595. for i:=1 to p^.tablecount do
  596. begin
  597. if assigned(symt) then
  598. begin
  599. p^.withsymtable:=pwithsymtable(symt^.next);
  600. dispose(symt,done);
  601. end;
  602. symt:=p^.withsymtable;
  603. end;
  604. {$ENDIF NEWST}
  605. end;
  606. else internalerror(12);
  607. end;
  608. putnode(p);
  609. end;
  610. procedure set_file_line(from,_to : ptree);
  611. begin
  612. if assigned(from) then
  613. _to^.fileinfo:=from^.fileinfo;
  614. end;
  615. procedure set_tree_filepos(p : ptree;const filepos : tfileposinfo);
  616. begin
  617. p^.fileinfo:=filepos;
  618. end;
  619. {$IFDEF NEWST}
  620. function genwithnode(symtables:Pcollection;l,r : ptree) : ptree;
  621. var
  622. p : ptree;
  623. begin
  624. p:=getnode;
  625. p^.disposetyp:=dt_with;
  626. p^.treetype:=withn;
  627. p^.left:=l;
  628. p^.right:=r;
  629. p^.registers32:=0;
  630. {$ifdef SUPPORT_MMX}
  631. p^.registersmmx:=0;
  632. {$endif SUPPORT_MMX}
  633. p^.resulttype:=nil;
  634. p^.withsymtables:=symtables;
  635. p^.withreference:=nil;
  636. p^.islocal:=false;
  637. set_file_line(l,p);
  638. genwithnode:=p;
  639. end;
  640. {$ELSE}
  641. function genwithnode(symtable : pwithsymtable;l,r : ptree;count : longint) : ptree;
  642. var
  643. p : ptree;
  644. begin
  645. p:=getnode;
  646. p^.disposetyp:=dt_with;
  647. p^.treetype:=withn;
  648. p^.left:=l;
  649. p^.right:=r;
  650. p^.registers32:=0;
  651. {$ifdef SUPPORT_MMX}
  652. p^.registersmmx:=0;
  653. {$endif SUPPORT_MMX}
  654. p^.resulttype:=nil;
  655. p^.withsymtable:=symtable;
  656. p^.tablecount:=count;
  657. p^.withreference:=nil;
  658. p^.islocal:=false;
  659. set_file_line(l,p);
  660. genwithnode:=p;
  661. end;
  662. {$ENDIF NEWST}
  663. function genfixconstnode(v : longint;def : pdef) : ptree;
  664. var
  665. p : ptree;
  666. begin
  667. p:=getnode;
  668. p^.disposetyp:=dt_nothing;
  669. p^.treetype:=fixconstn;
  670. p^.registers32:=0;
  671. { p^.registers16:=0;
  672. p^.registers8:=0; }
  673. p^.registersfpu:=0;
  674. {$ifdef SUPPORT_MMX}
  675. p^.registersmmx:=0;
  676. {$endif SUPPORT_MMX}
  677. p^.resulttype:=def;
  678. p^.value:=v;
  679. genfixconstnode:=p;
  680. end;
  681. function gencallparanode(expr,next : ptree) : ptree;
  682. var
  683. p : ptree;
  684. begin
  685. p:=getnode;
  686. p^.disposetyp:=dt_leftrighthigh;
  687. p^.treetype:=callparan;
  688. p^.left:=expr;
  689. p^.right:=next;
  690. p^.registers32:=0;
  691. { p^.registers16:=0;
  692. p^.registers8:=0; }
  693. {$ifdef SUPPORT_MMX}
  694. p^.registersmmx:=0;
  695. {$endif SUPPORT_MMX}
  696. p^.registersfpu:=0;
  697. p^.resulttype:=nil;
  698. p^.exact_match_found:=false;
  699. p^.convlevel1found:=false;
  700. p^.convlevel2found:=false;
  701. p^.is_colon_para:=false;
  702. p^.hightree:=nil;
  703. set_file_line(expr,p);
  704. gencallparanode:=p;
  705. end;
  706. function gennode(t : ttreetyp;l,r : ptree) : ptree;
  707. var
  708. p : ptree;
  709. begin
  710. p:=getnode;
  711. p^.disposetyp:=dt_leftright;
  712. p^.treetype:=t;
  713. p^.left:=l;
  714. p^.right:=r;
  715. p^.registers32:=0;
  716. { p^.registers16:=0;
  717. p^.registers8:=0; }
  718. p^.registersfpu:=0;
  719. {$ifdef SUPPORT_MMX}
  720. p^.registersmmx:=0;
  721. {$endif SUPPORT_MMX}
  722. p^.resulttype:=nil;
  723. gennode:=p;
  724. end;
  725. function gencasenode(l,r : ptree;nodes : pcaserecord) : ptree;
  726. var
  727. p : ptree;
  728. begin
  729. p:=getnode;
  730. p^.disposetyp:=dt_case;
  731. p^.treetype:=casen;
  732. p^.left:=l;
  733. p^.right:=r;
  734. p^.nodes:=nodes;
  735. p^.registers32:=0;
  736. p^.registersfpu:=0;
  737. {$ifdef SUPPORT_MMX}
  738. p^.registersmmx:=0;
  739. {$endif SUPPORT_MMX}
  740. p^.resulttype:=nil;
  741. set_file_line(l,p);
  742. gencasenode:=p;
  743. end;
  744. function genloopnode(t : ttreetyp;l,r,n1 : ptree;back : boolean) : ptree;
  745. var
  746. p : ptree;
  747. begin
  748. p:=getnode;
  749. p^.disposetyp:=dt_loop;
  750. p^.treetype:=t;
  751. p^.left:=l;
  752. p^.right:=r;
  753. p^.t1:=n1;
  754. p^.t2:=nil;
  755. p^.registers32:=0;
  756. p^.backward:=back;
  757. { p^.registers16:=0;
  758. p^.registers8:=0; }
  759. p^.registersfpu:=0;
  760. {$ifdef SUPPORT_MMX}
  761. p^.registersmmx:=0;
  762. {$endif SUPPORT_MMX}
  763. p^.resulttype:=nil;
  764. set_file_line(l,p);
  765. genloopnode:=p;
  766. end;
  767. function genordinalconstnode(v : longint;def : pdef) : ptree;
  768. var
  769. p : ptree;
  770. begin
  771. p:=getnode;
  772. p^.disposetyp:=dt_nothing;
  773. p^.treetype:=ordconstn;
  774. p^.registers32:=0;
  775. { p^.registers16:=0;
  776. p^.registers8:=0; }
  777. p^.registersfpu:=0;
  778. {$ifdef SUPPORT_MMX}
  779. p^.registersmmx:=0;
  780. {$endif SUPPORT_MMX}
  781. p^.resulttype:=def;
  782. p^.value:=v;
  783. {$IFDEF NEWST}
  784. if typeof(p^.resulttype^)=typeof(Torddef) then
  785. testrange(p^.resulttype,p^.value);
  786. {$ELSE NEWST}
  787. if p^.resulttype^.deftype=orddef then
  788. testrange(p^.resulttype,p^.value);
  789. {$ENDIF}
  790. genordinalconstnode:=p;
  791. end;
  792. function genpointerconstnode(v : longint;def : pdef) : ptree;
  793. var
  794. p : ptree;
  795. begin
  796. p:=getnode;
  797. p^.disposetyp:=dt_nothing;
  798. p^.treetype:=pointerconstn;
  799. p^.registers32:=0;
  800. { p^.registers16:=0;
  801. p^.registers8:=0; }
  802. p^.registersfpu:=0;
  803. {$ifdef SUPPORT_MMX}
  804. p^.registersmmx:=0;
  805. {$endif SUPPORT_MMX}
  806. p^.resulttype:=def;
  807. p^.value:=v;
  808. genpointerconstnode:=p;
  809. end;
  810. function genenumnode(v : penumsym) : ptree;
  811. var
  812. p : ptree;
  813. begin
  814. p:=getnode;
  815. p^.disposetyp:=dt_nothing;
  816. p^.treetype:=ordconstn;
  817. p^.registers32:=0;
  818. { p^.registers16:=0;
  819. p^.registers8:=0; }
  820. p^.registersfpu:=0;
  821. {$ifdef SUPPORT_MMX}
  822. p^.registersmmx:=0;
  823. {$endif SUPPORT_MMX}
  824. p^.resulttype:=v^.definition;
  825. p^.value:=v^.value;
  826. testrange(p^.resulttype,p^.value);
  827. genenumnode:=p;
  828. end;
  829. function genrealconstnode(v : bestreal;def : pdef) : ptree;
  830. var
  831. p : ptree;
  832. begin
  833. p:=getnode;
  834. p^.disposetyp:=dt_nothing;
  835. p^.treetype:=realconstn;
  836. p^.registers32:=0;
  837. { p^.registers16:=0;
  838. p^.registers8:=0; }
  839. p^.registersfpu:=0;
  840. {$ifdef SUPPORT_MMX}
  841. p^.registersmmx:=0;
  842. {$endif SUPPORT_MMX}
  843. p^.resulttype:=def;
  844. p^.value_real:=v;
  845. p^.lab_real:=nil;
  846. genrealconstnode:=p;
  847. end;
  848. function genstringconstnode(const s : string;st:tstringtype) : ptree;
  849. var
  850. p : ptree;
  851. l : longint;
  852. begin
  853. p:=getnode;
  854. p^.disposetyp:=dt_nothing;
  855. p^.treetype:=stringconstn;
  856. p^.registers32:=0;
  857. { p^.registers16:=0;
  858. p^.registers8:=0; }
  859. p^.registersfpu:=0;
  860. {$ifdef SUPPORT_MMX}
  861. p^.registersmmx:=0;
  862. {$endif SUPPORT_MMX}
  863. l:=length(s);
  864. p^.length:=l;
  865. { stringdup write even past a #0 }
  866. getmem(p^.value_str,l+1);
  867. move(s[1],p^.value_str^,l);
  868. p^.value_str[l]:=#0;
  869. p^.lab_str:=nil;
  870. if st=st_default then
  871. begin
  872. if cs_ansistrings in aktlocalswitches then
  873. p^.stringtype:=st_ansistring
  874. else
  875. p^.stringtype:=st_shortstring;
  876. end
  877. else
  878. p^.stringtype:=st;
  879. case p^.stringtype of
  880. st_shortstring :
  881. p^.resulttype:=cshortstringdef;
  882. st_ansistring :
  883. p^.resulttype:=cansistringdef;
  884. else
  885. internalerror(44990099);
  886. end;
  887. genstringconstnode:=p;
  888. end;
  889. function getpcharcopy(p : ptree) : pchar;
  890. var
  891. pc : pchar;
  892. begin
  893. pc:=nil;
  894. getmem(pc,p^.length+1);
  895. if pc=nil then
  896. Message(general_f_no_memory_left);
  897. move(p^.value_str^,pc^,p^.length+1);
  898. getpcharcopy:=pc;
  899. end;
  900. function genpcharconstnode(s : pchar;length : longint) : ptree;
  901. var
  902. p : ptree;
  903. begin
  904. p:=getnode;
  905. p^.disposetyp:=dt_nothing;
  906. p^.treetype:=stringconstn;
  907. p^.registers32:=0;
  908. { p^.registers16:=0;
  909. p^.registers8:=0; }
  910. p^.registersfpu:=0;
  911. {$ifdef SUPPORT_MMX}
  912. p^.registersmmx:=0;
  913. {$endif SUPPORT_MMX}
  914. p^.length:=length;
  915. if (cs_ansistrings in aktlocalswitches) or
  916. (length>255) then
  917. begin
  918. p^.stringtype:=st_ansistring;
  919. p^.resulttype:=cansistringdef;
  920. end
  921. else
  922. begin
  923. p^.stringtype:=st_shortstring;
  924. p^.resulttype:=cshortstringdef;
  925. end;
  926. p^.value_str:=s;
  927. p^.lab_str:=nil;
  928. genpcharconstnode:=p;
  929. end;
  930. function gensinglenode(t : ttreetyp;l : ptree) : ptree;
  931. var
  932. p : ptree;
  933. begin
  934. p:=getnode;
  935. p^.disposetyp:=dt_left;
  936. p^.treetype:=t;
  937. p^.left:=l;
  938. p^.registers32:=0;
  939. { p^.registers16:=0;
  940. p^.registers8:=0; }
  941. p^.registersfpu:=0;
  942. {$ifdef SUPPORT_MMX}
  943. p^.registersmmx:=0;
  944. {$endif SUPPORT_MMX}
  945. p^.resulttype:=nil;
  946. gensinglenode:=p;
  947. end;
  948. function genasmnode(p_asm : paasmoutput) : ptree;
  949. var
  950. p : ptree;
  951. begin
  952. p:=getnode;
  953. p^.disposetyp:=dt_nothing;
  954. p^.treetype:=asmn;
  955. p^.registers32:=4;
  956. p^.p_asm:=p_asm;
  957. p^.object_preserved:=false;
  958. { p^.registers16:=0;
  959. p^.registers8:=0; }
  960. p^.registersfpu:=8;
  961. {$ifdef SUPPORT_MMX}
  962. p^.registersmmx:=8;
  963. {$endif SUPPORT_MMX}
  964. p^.resulttype:=nil;
  965. genasmnode:=p;
  966. end;
  967. function genloadnode(v : pvarsym;st : psymtable) : ptree;
  968. var
  969. p : ptree;
  970. begin
  971. p:=getnode;
  972. p^.registers32:=0;
  973. { p^.registers16:=0;
  974. p^.registers8:=0; }
  975. p^.registersfpu:=0;
  976. {$ifdef SUPPORT_MMX}
  977. p^.registersmmx:=0;
  978. {$endif SUPPORT_MMX}
  979. p^.treetype:=loadn;
  980. {$IFDEF NEWST}
  981. p^.resulttype:=v^.definition;
  982. {$ELSE}
  983. p^.resulttype:=v^.vartype.def;
  984. {$ENDIF NEWST}
  985. p^.symtableentry:=v;
  986. p^.symtable:=st;
  987. p^.is_first := False;
  988. { method pointer load nodes can use the left subtree }
  989. p^.disposetyp:=dt_left;
  990. p^.left:=nil;
  991. genloadnode:=p;
  992. end;
  993. function genloadcallnode(v: pprocsym;st: psymtable): ptree;
  994. var
  995. p : ptree;
  996. begin
  997. p:=getnode;
  998. p^.registers32:=0;
  999. { p^.registers16:=0;
  1000. p^.registers8:=0; }
  1001. p^.registersfpu:=0;
  1002. {$ifdef SUPPORT_MMX}
  1003. p^.registersmmx:=0;
  1004. {$endif SUPPORT_MMX}
  1005. p^.treetype:=loadn;
  1006. p^.left:=nil;
  1007. {$IFDEF NEWST}
  1008. p^.resulttype:=nil; {We don't know which overloaded procedure is
  1009. wanted...}
  1010. {$ELSE}
  1011. p^.resulttype:=v^.definition;
  1012. {$ENDIF}
  1013. p^.symtableentry:=v;
  1014. p^.symtable:=st;
  1015. p^.is_first := False;
  1016. p^.disposetyp:=dt_nothing;
  1017. genloadcallnode:=p;
  1018. end;
  1019. function genloadmethodcallnode(v: pprocsym;st: psymtable; mp:ptree): ptree;
  1020. var
  1021. p : ptree;
  1022. begin
  1023. p:=getnode;
  1024. p^.registers32:=0;
  1025. { p^.registers16:=0;
  1026. p^.registers8:=0; }
  1027. p^.registersfpu:=0;
  1028. {$ifdef SUPPORT_MMX}
  1029. p^.registersmmx:=0;
  1030. {$endif SUPPORT_MMX}
  1031. p^.treetype:=loadn;
  1032. p^.left:=nil;
  1033. {$IFDEF NEWST}
  1034. p^.resulttype:=nil; {We don't know which overloaded procedure is
  1035. wanted...}
  1036. {$ELSE}
  1037. p^.resulttype:=v^.definition;
  1038. {$ENDIF}
  1039. p^.symtableentry:=v;
  1040. p^.symtable:=st;
  1041. p^.is_first := False;
  1042. p^.disposetyp:=dt_left;
  1043. p^.left:=mp;
  1044. genloadmethodcallnode:=p;
  1045. end;
  1046. function gentypedconstloadnode(sym : ptypedconstsym;st : psymtable) : ptree;
  1047. var
  1048. p : ptree;
  1049. begin
  1050. p:=getnode;
  1051. p^.registers32:=0;
  1052. { p^.registers16:=0;
  1053. p^.registers8:=0; }
  1054. p^.registersfpu:=0;
  1055. {$ifdef SUPPORT_MMX}
  1056. p^.registersmmx:=0;
  1057. {$endif SUPPORT_MMX}
  1058. p^.treetype:=loadn;
  1059. p^.left:=nil;
  1060. {$IFDEF NEWST}
  1061. p^.resulttype:=sym^.definition;
  1062. {$ELSE}
  1063. p^.resulttype:=sym^.typedconsttype.def;
  1064. {$ENDIF NEWST}
  1065. p^.symtableentry:=sym;
  1066. p^.symtable:=st;
  1067. p^.disposetyp:=dt_nothing;
  1068. gentypedconstloadnode:=p;
  1069. end;
  1070. function gentypeconvnode(node : ptree;t : pdef) : ptree;
  1071. var
  1072. p : ptree;
  1073. begin
  1074. p:=getnode;
  1075. p^.disposetyp:=dt_typeconv;
  1076. p^.treetype:=typeconvn;
  1077. p^.left:=node;
  1078. p^.registers32:=0;
  1079. { p^.registers16:=0;
  1080. p^.registers8:=0; }
  1081. p^.convtyp:=tc_equal;
  1082. p^.registersfpu:=0;
  1083. {$ifdef SUPPORT_MMX}
  1084. p^.registersmmx:=0;
  1085. {$endif SUPPORT_MMX}
  1086. p^.resulttype:=t;
  1087. p^.explizit:=false;
  1088. set_file_line(node,p);
  1089. gentypeconvnode:=p;
  1090. end;
  1091. function gentypenode(t : pdef;sym:ptypesym) : ptree;
  1092. var
  1093. p : ptree;
  1094. begin
  1095. p:=getnode;
  1096. p^.disposetyp:=dt_nothing;
  1097. p^.treetype:=typen;
  1098. p^.registers32:=0;
  1099. { p^.registers16:=0;
  1100. p^.registers8:=0; }
  1101. p^.registersfpu:=0;
  1102. {$ifdef SUPPORT_MMX}
  1103. p^.registersmmx:=0;
  1104. {$endif SUPPORT_MMX}
  1105. p^.resulttype:=generrordef;
  1106. p^.typenodetype:=t;
  1107. p^.typenodesym:=sym;
  1108. gentypenode:=p;
  1109. end;
  1110. function gencallnode(v : pprocsym;st : psymtable) : ptree;
  1111. var
  1112. p : ptree;
  1113. begin
  1114. p:=getnode;
  1115. p^.registers32:=0;
  1116. { p^.registers16:=0;
  1117. p^.registers8:=0; }
  1118. p^.registersfpu:=0;
  1119. {$ifdef SUPPORT_MMX}
  1120. p^.registersmmx:=0;
  1121. {$endif SUPPORT_MMX}
  1122. p^.treetype:=calln;
  1123. p^.symtableprocentry:=v;
  1124. p^.symtableproc:=st;
  1125. p^.unit_specific:=false;
  1126. p^.no_check:=false;
  1127. p^.return_value_used:=true;
  1128. p^.disposetyp := dt_leftrightmethod;
  1129. p^.methodpointer:=nil;
  1130. p^.left:=nil;
  1131. p^.right:=nil;
  1132. p^.procdefinition:=nil;
  1133. gencallnode:=p;
  1134. end;
  1135. function genmethodcallnode(v : pprocsym;st : psymtable;mp : ptree) : ptree;
  1136. var
  1137. p : ptree;
  1138. begin
  1139. p:=getnode;
  1140. p^.registers32:=0;
  1141. { p^.registers16:=0;
  1142. p^.registers8:=0; }
  1143. p^.registersfpu:=0;
  1144. {$ifdef SUPPORT_MMX}
  1145. p^.registersmmx:=0;
  1146. {$endif SUPPORT_MMX}
  1147. p^.treetype:=calln;
  1148. p^.return_value_used:=true;
  1149. p^.symtableprocentry:=v;
  1150. p^.symtableproc:=st;
  1151. p^.disposetyp:=dt_leftrightmethod;
  1152. p^.left:=nil;
  1153. p^.right:=nil;
  1154. p^.methodpointer:=mp;
  1155. p^.procdefinition:=nil;
  1156. genmethodcallnode:=p;
  1157. end;
  1158. function gensubscriptnode(varsym : pvarsym;l : ptree) : ptree;
  1159. var
  1160. p : ptree;
  1161. begin
  1162. p:=getnode;
  1163. p^.disposetyp:=dt_left;
  1164. p^.treetype:=subscriptn;
  1165. p^.left:=l;
  1166. p^.registers32:=0;
  1167. p^.vs:=varsym;
  1168. { p^.registers16:=0;
  1169. p^.registers8:=0; }
  1170. p^.registersfpu:=0;
  1171. {$ifdef SUPPORT_MMX}
  1172. p^.registersmmx:=0;
  1173. {$endif SUPPORT_MMX}
  1174. p^.resulttype:=nil;
  1175. gensubscriptnode:=p;
  1176. end;
  1177. function genzeronode(t : ttreetyp) : ptree;
  1178. var
  1179. p : ptree;
  1180. begin
  1181. p:=getnode;
  1182. p^.disposetyp:=dt_nothing;
  1183. p^.treetype:=t;
  1184. p^.registers32:=0;
  1185. { p^.registers16:=0;
  1186. p^.registers8:=0; }
  1187. p^.registersfpu:=0;
  1188. {$ifdef SUPPORT_MMX}
  1189. p^.registersmmx:=0;
  1190. {$endif SUPPORT_MMX}
  1191. p^.resulttype:=nil;
  1192. genzeronode:=p;
  1193. end;
  1194. function genlabelnode(t : ttreetyp;nr : pasmlabel) : ptree;
  1195. var
  1196. p : ptree;
  1197. begin
  1198. p:=getnode;
  1199. p^.disposetyp:=dt_nothing;
  1200. p^.treetype:=t;
  1201. p^.registers32:=0;
  1202. { p^.registers16:=0;
  1203. p^.registers8:=0; }
  1204. p^.registersfpu:=0;
  1205. {$ifdef SUPPORT_MMX}
  1206. p^.registersmmx:=0;
  1207. {$endif SUPPORT_MMX}
  1208. p^.resulttype:=nil;
  1209. { for security }
  1210. { nr^.is_used:=true;}
  1211. p^.labelnr:=nr;
  1212. p^.exceptionblock:=nil;
  1213. genlabelnode:=p;
  1214. end;
  1215. function genselfnode(_class : pdef) : ptree;
  1216. var
  1217. p : ptree;
  1218. begin
  1219. p:=getnode;
  1220. p^.disposetyp:=dt_nothing;
  1221. p^.treetype:=selfn;
  1222. p^.registers32:=0;
  1223. { p^.registers16:=0;
  1224. p^.registers8:=0; }
  1225. p^.registersfpu:=0;
  1226. {$ifdef SUPPORT_MMX}
  1227. p^.registersmmx:=0;
  1228. {$endif SUPPORT_MMX}
  1229. p^.resulttype:=_class;
  1230. genselfnode:=p;
  1231. end;
  1232. function geninlinenode(number : byte;is_const:boolean;l : ptree) : ptree;
  1233. var
  1234. p : ptree;
  1235. begin
  1236. p:=getnode;
  1237. p^.disposetyp:=dt_inlinen;
  1238. p^.treetype:=inlinen;
  1239. p^.left:=l;
  1240. p^.inlinenumber:=number;
  1241. p^.inlineconst:=is_const;
  1242. p^.registers32:=0;
  1243. { p^.registers16:=0;
  1244. p^.registers8:=0; }
  1245. p^.registersfpu:=0;
  1246. {$ifdef SUPPORT_MMX}
  1247. p^.registersmmx:=0;
  1248. {$endif SUPPORT_MMX}
  1249. p^.resulttype:=nil;
  1250. geninlinenode:=p;
  1251. end;
  1252. { uses the callnode to create the new procinline node }
  1253. function genprocinlinenode(callp,code : ptree) : ptree;
  1254. var
  1255. p : ptree;
  1256. begin
  1257. p:=getnode;
  1258. p^.disposetyp:=dt_nothing;
  1259. p^.treetype:=procinlinen;
  1260. p^.inlineprocsym:=callp^.symtableprocentry;
  1261. p^.retoffset:=-4; { less dangerous as zero (PM) }
  1262. p^.para_offset:=0;
  1263. {$IFDEF NEWST}
  1264. {Fixme!!}
  1265. internalerror($00022801);
  1266. {$ELSE}
  1267. p^.para_size:=p^.inlineprocsym^.definition^.para_size(target_os.stackalignment);
  1268. if ret_in_param(p^.inlineprocsym^.definition^.rettype.def) then
  1269. p^.para_size:=p^.para_size+target_os.size_of_pointer;
  1270. {$ENDIF NEWST}
  1271. { copy args }
  1272. p^.inlinetree:=code;
  1273. p^.registers32:=code^.registers32;
  1274. p^.registersfpu:=code^.registersfpu;
  1275. {$ifdef SUPPORT_MMX}
  1276. p^.registersmmx:=0;
  1277. {$endif SUPPORT_MMX}
  1278. {$IFDEF NEWST}
  1279. {Fixme!!}
  1280. {$ELSE}
  1281. p^.resulttype:=p^.inlineprocsym^.definition^.rettype.def;
  1282. {$ENDIF NEWST}
  1283. genprocinlinenode:=p;
  1284. end;
  1285. function gensetconstnode(s : pconstset;settype : psetdef) : ptree;
  1286. var
  1287. p : ptree;
  1288. begin
  1289. p:=getnode;
  1290. p^.disposetyp:=dt_nothing;
  1291. p^.treetype:=setconstn;
  1292. p^.registers32:=0;
  1293. p^.registersfpu:=0;
  1294. {$ifdef SUPPORT_MMX}
  1295. p^.registersmmx:=0;
  1296. {$endif SUPPORT_MMX}
  1297. p^.resulttype:=settype;
  1298. p^.left:=nil;
  1299. new(p^.value_set);
  1300. p^.value_set^:=s^;
  1301. gensetconstnode:=p;
  1302. end;
  1303. {$ifdef extdebug}
  1304. procedure compare_trees(oldp,p : ptree);
  1305. var
  1306. error_found : boolean;
  1307. begin
  1308. if oldp^.resulttype<>p^.resulttype then
  1309. begin
  1310. error_found:=true;
  1311. if is_equal(oldp^.resulttype,p^.resulttype) then
  1312. comment(v_debug,'resulttype fields are different but equal')
  1313. else
  1314. comment(v_warning,'resulttype fields are really different');
  1315. end;
  1316. if oldp^.treetype<>p^.treetype then
  1317. begin
  1318. comment(v_warning,'treetype field different');
  1319. error_found:=true;
  1320. end
  1321. else
  1322. comment(v_debug,' treetype '+tostr(longint(oldp^.treetype)));
  1323. if oldp^.error<>p^.error then
  1324. begin
  1325. comment(v_warning,'error field different');
  1326. error_found:=true;
  1327. end;
  1328. if oldp^.disposetyp<>p^.disposetyp then
  1329. begin
  1330. comment(v_warning,'disposetyp field different');
  1331. error_found:=true;
  1332. end;
  1333. { is true, if the right and left operand are swaped }
  1334. if oldp^.swaped<>p^.swaped then
  1335. begin
  1336. comment(v_warning,'swaped field different');
  1337. error_found:=true;
  1338. end;
  1339. { the location of the result of this node }
  1340. if oldp^.location.loc<>p^.location.loc then
  1341. begin
  1342. comment(v_warning,'location.loc field different');
  1343. error_found:=true;
  1344. end;
  1345. { the number of registers needed to evalute the node }
  1346. if oldp^.registers32<>p^.registers32 then
  1347. begin
  1348. comment(v_warning,'registers32 field different');
  1349. comment(v_warning,' old '+tostr(oldp^.registers32)+'<> new '+tostr(p^.registers32));
  1350. error_found:=true;
  1351. end;
  1352. if oldp^.registersfpu<>p^.registersfpu then
  1353. begin
  1354. comment(v_warning,'registersfpu field different');
  1355. error_found:=true;
  1356. end;
  1357. {$ifdef SUPPORT_MMX}
  1358. if oldp^.registersmmx<>p^.registersmmx then
  1359. begin
  1360. comment(v_warning,'registersmmx field different');
  1361. error_found:=true;
  1362. end;
  1363. {$endif SUPPORT_MMX}
  1364. if oldp^.left<>p^.left then
  1365. begin
  1366. comment(v_warning,'left field different');
  1367. error_found:=true;
  1368. end;
  1369. if oldp^.right<>p^.right then
  1370. begin
  1371. comment(v_warning,'right field different');
  1372. error_found:=true;
  1373. end;
  1374. if oldp^.fileinfo.line<>p^.fileinfo.line then
  1375. begin
  1376. comment(v_warning,'fileinfo.line field different');
  1377. error_found:=true;
  1378. end;
  1379. if oldp^.fileinfo.column<>p^.fileinfo.column then
  1380. begin
  1381. comment(v_warning,'fileinfo.column field different');
  1382. error_found:=true;
  1383. end;
  1384. if oldp^.fileinfo.fileindex<>p^.fileinfo.fileindex then
  1385. begin
  1386. comment(v_warning,'fileinfo.fileindex field different');
  1387. error_found:=true;
  1388. end;
  1389. if oldp^.localswitches<>p^.localswitches then
  1390. begin
  1391. comment(v_warning,'localswitches field different');
  1392. error_found:=true;
  1393. end;
  1394. {$ifdef extdebug}
  1395. if oldp^.firstpasscount<>p^.firstpasscount then
  1396. begin
  1397. comment(v_warning,'firstpasscount field different');
  1398. error_found:=true;
  1399. end;
  1400. {$endif extdebug}
  1401. if oldp^.treetype=p^.treetype then
  1402. case oldp^.treetype of
  1403. addn :
  1404. begin
  1405. if oldp^.use_strconcat<>p^.use_strconcat then
  1406. begin
  1407. comment(v_warning,'use_strconcat field different');
  1408. error_found:=true;
  1409. end;
  1410. if oldp^.string_typ<>p^.string_typ then
  1411. begin
  1412. comment(v_warning,'stringtyp field different');
  1413. error_found:=true;
  1414. end;
  1415. end;
  1416. callparan :
  1417. {(is_colon_para : boolean;exact_match_found : boolean);}
  1418. begin
  1419. if oldp^.is_colon_para<>p^.is_colon_para then
  1420. begin
  1421. comment(v_warning,'use_strconcat field different');
  1422. error_found:=true;
  1423. end;
  1424. if oldp^.exact_match_found<>p^.exact_match_found then
  1425. begin
  1426. comment(v_warning,'exact_match_found field different');
  1427. error_found:=true;
  1428. end;
  1429. end;
  1430. assignn :
  1431. {(assigntyp : tassigntyp;concat_string : boolean);}
  1432. begin
  1433. if oldp^.assigntyp<>p^.assigntyp then
  1434. begin
  1435. comment(v_warning,'assigntyp field different');
  1436. error_found:=true;
  1437. end;
  1438. if oldp^.concat_string<>p^.concat_string then
  1439. begin
  1440. comment(v_warning,'concat_string field different');
  1441. error_found:=true;
  1442. end;
  1443. end;
  1444. loadn :
  1445. {(symtableentry : psym;symtable : psymtable;
  1446. is_absolute,is_first : boolean);}
  1447. begin
  1448. if oldp^.symtableentry<>p^.symtableentry then
  1449. begin
  1450. comment(v_warning,'symtableentry field different');
  1451. error_found:=true;
  1452. end;
  1453. if oldp^.symtable<>p^.symtable then
  1454. begin
  1455. comment(v_warning,'symtable field different');
  1456. error_found:=true;
  1457. end;
  1458. if oldp^.is_absolute<>p^.is_absolute then
  1459. begin
  1460. comment(v_warning,'is_absolute field different');
  1461. error_found:=true;
  1462. end;
  1463. if oldp^.is_first<>p^.is_first then
  1464. begin
  1465. comment(v_warning,'is_first field different');
  1466. error_found:=true;
  1467. end;
  1468. end;
  1469. calln :
  1470. {(symtableprocentry : pprocsym;
  1471. symtableproc : psymtable;procdefinition : pprocdef;
  1472. methodpointer : ptree;
  1473. no_check,unit_specific : boolean);}
  1474. begin
  1475. if oldp^.symtableprocentry<>p^.symtableprocentry then
  1476. begin
  1477. comment(v_warning,'symtableprocentry field different');
  1478. error_found:=true;
  1479. end;
  1480. if oldp^.symtableproc<>p^.symtableproc then
  1481. begin
  1482. comment(v_warning,'symtableproc field different');
  1483. error_found:=true;
  1484. end;
  1485. if oldp^.procdefinition<>p^.procdefinition then
  1486. begin
  1487. comment(v_warning,'procdefinition field different');
  1488. error_found:=true;
  1489. end;
  1490. if oldp^.methodpointer<>p^.methodpointer then
  1491. begin
  1492. comment(v_warning,'methodpointer field different');
  1493. error_found:=true;
  1494. end;
  1495. if oldp^.no_check<>p^.no_check then
  1496. begin
  1497. comment(v_warning,'no_check field different');
  1498. error_found:=true;
  1499. end;
  1500. if oldp^.unit_specific<>p^.unit_specific then
  1501. begin
  1502. error_found:=true;
  1503. comment(v_warning,'unit_specific field different');
  1504. end;
  1505. end;
  1506. ordconstn :
  1507. begin
  1508. if oldp^.value<>p^.value then
  1509. begin
  1510. comment(v_warning,'value field different');
  1511. error_found:=true;
  1512. end;
  1513. end;
  1514. realconstn :
  1515. begin
  1516. if oldp^.value_real<>p^.value_real then
  1517. begin
  1518. comment(v_warning,'valued field different');
  1519. error_found:=true;
  1520. end;
  1521. if oldp^.lab_real<>p^.lab_real then
  1522. begin
  1523. comment(v_warning,'labnumber field different');
  1524. error_found:=true;
  1525. end;
  1526. { if oldp^.realtyp<>p^.realtyp then
  1527. begin
  1528. comment(v_warning,'realtyp field different');
  1529. error_found:=true;
  1530. end; }
  1531. end;
  1532. end;
  1533. if not error_found then
  1534. comment(v_warning,'did not find difference in trees');
  1535. end;
  1536. {$endif extdebug}
  1537. function equal_trees(t1,t2 : ptree) : boolean;
  1538. begin
  1539. if t1^.treetype=t2^.treetype then
  1540. begin
  1541. case t1^.treetype of
  1542. addn,
  1543. muln,
  1544. equaln,
  1545. orn,
  1546. xorn,
  1547. andn,
  1548. unequaln:
  1549. begin
  1550. equal_trees:=(equal_trees(t1^.left,t2^.left) and
  1551. equal_trees(t1^.right,t2^.right)) or
  1552. (equal_trees(t1^.right,t2^.left) and
  1553. equal_trees(t1^.left,t2^.right));
  1554. end;
  1555. subn,
  1556. divn,
  1557. modn,
  1558. assignn,
  1559. ltn,
  1560. lten,
  1561. gtn,
  1562. gten,
  1563. inn,
  1564. shrn,
  1565. shln,
  1566. slashn,
  1567. rangen:
  1568. begin
  1569. equal_trees:=(equal_trees(t1^.left,t2^.left) and
  1570. equal_trees(t1^.right,t2^.right));
  1571. end;
  1572. unaryminusn,
  1573. notn,
  1574. derefn,
  1575. addrn:
  1576. begin
  1577. equal_trees:=(equal_trees(t1^.left,t2^.left));
  1578. end;
  1579. loadn:
  1580. begin
  1581. equal_trees:=(t1^.symtableentry=t2^.symtableentry)
  1582. { not necessary
  1583. and (t1^.symtable=t2^.symtable)};
  1584. end;
  1585. {
  1586. subscriptn,
  1587. ordconstn,typeconvn,calln,callparan,
  1588. realconstn,asmn,vecn,
  1589. stringconstn,funcretn,selfn,
  1590. inlinen,niln,errorn,
  1591. typen,hnewn,hdisposen,newn,
  1592. disposen,setelen,setconstrn
  1593. }
  1594. else equal_trees:=false;
  1595. end;
  1596. end
  1597. else
  1598. equal_trees:=false;
  1599. end;
  1600. {$ifdef newoptimizations2}
  1601. function multiple_uses(t1,t2: ptree): boolean;
  1602. var nr: longint;
  1603. procedure check_tree(t: ptree);
  1604. begin
  1605. inc(nr,ord(equal_trees(t1,t)));
  1606. if (nr < 2) and assigned(t^.left) then
  1607. check_tree(t^.left);
  1608. if (nr < 2) and assigned(t^.right) then
  1609. check_tree(t^.right);
  1610. end;
  1611. begin
  1612. nr := 0;
  1613. check_tree(t2);
  1614. multiple_uses := nr > 1;
  1615. end;
  1616. {$endif newoptimizations2}
  1617. procedure set_unique(p : ptree);
  1618. begin
  1619. if assigned(p) then
  1620. begin
  1621. case p^.treetype of
  1622. vecn:
  1623. p^.callunique:=true;
  1624. typeconvn,subscriptn,derefn:
  1625. set_unique(p^.left);
  1626. end;
  1627. end;
  1628. end;
  1629. procedure set_funcret_is_valid(p : ptree);
  1630. begin
  1631. if assigned(p) then
  1632. begin
  1633. case p^.treetype of
  1634. funcretn:
  1635. begin
  1636. if p^.is_first_funcret then
  1637. pprocinfo(p^.funcretprocinfo)^.funcret_state:=vs_assigned;
  1638. end;
  1639. vecn,typeconvn,subscriptn,derefn:
  1640. set_funcret_is_valid(p^.left);
  1641. end;
  1642. end;
  1643. end;
  1644. procedure set_varstate(p : ptree;must_be_valid : boolean);
  1645. begin
  1646. if not assigned(p) then
  1647. exit
  1648. else
  1649. begin
  1650. if p^.varstateset then
  1651. exit;
  1652. case p^.treetype of
  1653. typeconvn :
  1654. if p^.convtyp in
  1655. [
  1656. tc_cchar_2_pchar,
  1657. tc_cstring_2_pchar,
  1658. tc_array_2_pointer
  1659. ] then
  1660. set_varstate(p^.left,false)
  1661. else if p^.convtyp in
  1662. [
  1663. tc_pchar_2_string,
  1664. tc_pointer_2_array
  1665. ] then
  1666. set_varstate(p^.left,true)
  1667. else
  1668. set_varstate(p^.left,must_be_valid);
  1669. subscriptn :
  1670. set_varstate(p^.left,must_be_valid);
  1671. vecn:
  1672. begin
  1673. {$IFDEF NEWST}
  1674. if (typeof(p^.left^.resulttype^)=typeof(Tstringdef)) or
  1675. (typeof(p^.left^.resulttype^)=typeof(Tarraydef)) then
  1676. set_varstate(p^.left,must_be_valid)
  1677. else
  1678. set_varstate(p^.left,true);
  1679. {$ELSE}
  1680. if (p^.left^.resulttype^.deftype in [stringdef,arraydef]) then
  1681. set_varstate(p^.left,must_be_valid)
  1682. else
  1683. set_varstate(p^.left,true);
  1684. {$ENDIF NEWST}
  1685. set_varstate(p^.right,true);
  1686. end;
  1687. { do not parse calln }
  1688. calln : ;
  1689. callparan:
  1690. begin
  1691. set_varstate(p^.left,must_be_valid);
  1692. set_varstate(p^.right,must_be_valid);
  1693. end;
  1694. loadn :
  1695. {$IFDEF NEWST}
  1696. if (typeof(p^.symtableentry^)=typeof(Tvarsym)) or
  1697. (typeof(p^.symtableentry^)=typeof(Tparamsym)) then
  1698. begin
  1699. if must_be_valid and p^.is_first then
  1700. begin
  1701. if (pvarsym(p^.symtableentry)^.state=vs_declared_and_first_found) or
  1702. (pvarsym(p^.symtableentry)^.state=vs_set_but_first_not_passed) then
  1703. if (assigned(pvarsym(p^.symtableentry)^.owner) and
  1704. assigned(aktprocsym) and
  1705. (pvarsym(p^.symtableentry)^.owner=
  1706. Pcontainingsymtable(aktprocdef^.localst))) then
  1707. begin
  1708. if typeof(p^.symtable^)=typeof(Tprocsymtable) then
  1709. CGMessage1(sym_n_uninitialized_local_variable,pvarsym(p^.symtableentry)^.name)
  1710. else
  1711. CGMessage1(sym_n_uninitialized_variable,pvarsym(p^.symtableentry)^.name);
  1712. end;
  1713. end;
  1714. if (p^.is_first) then
  1715. begin
  1716. if pvarsym(p^.symtableentry)^.state=vs_declared_and_first_found then
  1717. { this can only happen at left of an assignment, no ? PM }
  1718. if (parsing_para_level=0) and not must_be_valid then
  1719. pvarsym(p^.symtableentry)^.state:=vs_assigned
  1720. else
  1721. pvarsym(p^.symtableentry)^.state:=vs_used;
  1722. if pvarsym(p^.symtableentry)^.state=vs_set_but_first_not_passed then
  1723. pvarsym(p^.symtableentry)^.state:=vs_used;
  1724. p^.is_first:=false;
  1725. end
  1726. else
  1727. begin
  1728. if (pvarsym(p^.symtableentry)^.state=vs_assigned) and
  1729. (must_be_valid or (parsing_para_level>0) or
  1730. (typeof(p^.resulttype^)=typeof(Tprocvardef))) then
  1731. pvarsym(p^.symtableentry)^.state:=vs_used;
  1732. if (pvarsym(p^.symtableentry)^.state=vs_declared_and_first_found) and
  1733. (must_be_valid or (parsing_para_level>0) or
  1734. (typeof(p^.resulttype^)=typeof(Tprocvardef))) then
  1735. pvarsym(p^.symtableentry)^.state:=vs_set_but_first_not_passed;
  1736. end;
  1737. end;
  1738. {$ELSE}
  1739. if (p^.symtableentry^.typ=varsym) then
  1740. begin
  1741. if must_be_valid and p^.is_first then
  1742. begin
  1743. if (pvarsym(p^.symtableentry)^.varstate=vs_declared_and_first_found) or
  1744. (pvarsym(p^.symtableentry)^.varstate=vs_set_but_first_not_passed) then
  1745. if (assigned(pvarsym(p^.symtableentry)^.owner) and
  1746. assigned(aktprocsym) and
  1747. (pvarsym(p^.symtableentry)^.owner = aktprocsym^.definition^.localst)) then
  1748. begin
  1749. if p^.symtable^.symtabletype=localsymtable then
  1750. CGMessage1(sym_n_uninitialized_local_variable,pvarsym(p^.symtableentry)^.name)
  1751. else
  1752. CGMessage1(sym_n_uninitialized_variable,pvarsym(p^.symtableentry)^.name);
  1753. end;
  1754. end;
  1755. if (p^.is_first) then
  1756. begin
  1757. if pvarsym(p^.symtableentry)^.varstate=vs_declared_and_first_found then
  1758. { this can only happen at left of an assignment, no ? PM }
  1759. if (parsing_para_level=0) and not must_be_valid then
  1760. pvarsym(p^.symtableentry)^.varstate:=vs_assigned
  1761. else
  1762. pvarsym(p^.symtableentry)^.varstate:=vs_used;
  1763. if pvarsym(p^.symtableentry)^.varstate=vs_set_but_first_not_passed then
  1764. pvarsym(p^.symtableentry)^.varstate:=vs_used;
  1765. p^.is_first:=false;
  1766. end
  1767. else
  1768. begin
  1769. if (pvarsym(p^.symtableentry)^.varstate=vs_assigned) and
  1770. (must_be_valid or (parsing_para_level>0) or
  1771. (p^.resulttype^.deftype=procvardef)) then
  1772. pvarsym(p^.symtableentry)^.varstate:=vs_used;
  1773. if (pvarsym(p^.symtableentry)^.varstate=vs_declared_and_first_found) and
  1774. (must_be_valid or (parsing_para_level>0) or
  1775. (p^.resulttype^.deftype=procvardef)) then
  1776. pvarsym(p^.symtableentry)^.varstate:=vs_set_but_first_not_passed;
  1777. end;
  1778. end;
  1779. {$ENDIF NEWST}
  1780. funcretn:
  1781. begin
  1782. { no claim if setting higher return value_str }
  1783. if must_be_valid and
  1784. (procinfo=pprocinfo(p^.funcretprocinfo)) and
  1785. ((procinfo^.funcret_state=vs_declared) or
  1786. ((p^.is_first_funcret) and
  1787. (procinfo^.funcret_state=vs_declared_and_first_found))) then
  1788. begin
  1789. CGMessage(sym_w_function_result_not_set);
  1790. { avoid multiple warnings }
  1791. procinfo^.funcret_state:=vs_assigned;
  1792. end;
  1793. if p^.is_first_funcret and not must_be_valid then
  1794. pprocinfo(p^.funcretprocinfo)^.funcret_state:=vs_assigned;
  1795. end;
  1796. else
  1797. begin
  1798. {internalerror(565656);}
  1799. end;
  1800. end;{case }
  1801. p^.varstateset:=true;
  1802. end;
  1803. end;
  1804. procedure clear_location(var loc : tlocation);
  1805. begin
  1806. loc.loc:=LOC_INVALID;
  1807. end;
  1808. {This is needed if you want to be able to delete the string with the nodes !!}
  1809. procedure set_location(var destloc,sourceloc : tlocation);
  1810. begin
  1811. destloc:= sourceloc;
  1812. end;
  1813. procedure swap_location(var destloc,sourceloc : tlocation);
  1814. var
  1815. swapl : tlocation;
  1816. begin
  1817. swapl := destloc;
  1818. destloc := sourceloc;
  1819. sourceloc := swapl;
  1820. end;
  1821. function get_ordinal_value(p : ptree) : longint;
  1822. begin
  1823. if p^.treetype=ordconstn then
  1824. get_ordinal_value:=p^.value
  1825. else
  1826. begin
  1827. Message(type_e_ordinal_expr_expected);
  1828. get_ordinal_value:=0;
  1829. end;
  1830. end;
  1831. function is_constnode(p : ptree) : boolean;
  1832. begin
  1833. is_constnode:=(p^.treetype in [ordconstn,realconstn,stringconstn,fixconstn,setconstn]);
  1834. end;
  1835. function is_constintnode(p : ptree) : boolean;
  1836. begin
  1837. is_constintnode:=(p^.treetype=ordconstn) and is_integer(p^.resulttype);
  1838. end;
  1839. function is_constcharnode(p : ptree) : boolean;
  1840. begin
  1841. is_constcharnode:=(p^.treetype=ordconstn) and is_char(p^.resulttype);
  1842. end;
  1843. function is_constrealnode(p : ptree) : boolean;
  1844. begin
  1845. is_constrealnode:=(p^.treetype=realconstn);
  1846. end;
  1847. function is_constboolnode(p : ptree) : boolean;
  1848. begin
  1849. is_constboolnode:=(p^.treetype=ordconstn) and is_boolean(p^.resulttype);
  1850. end;
  1851. function str_length(p : ptree) : longint;
  1852. begin
  1853. str_length:=p^.length;
  1854. end;
  1855. function is_emptyset(p : ptree):boolean;
  1856. {
  1857. return true if set s is empty
  1858. }
  1859. var
  1860. i : longint;
  1861. begin
  1862. i:=0;
  1863. if p^.treetype=setconstn then
  1864. begin
  1865. while (i<32) and (p^.value_set^[i]=0) do
  1866. inc(i);
  1867. end;
  1868. is_emptyset:=(i=32);
  1869. end;
  1870. {*****************************************************************************
  1871. Case Helpers
  1872. *****************************************************************************}
  1873. function case_count_labels(root : pcaserecord) : longint;
  1874. var
  1875. _l : longint;
  1876. procedure count(p : pcaserecord);
  1877. begin
  1878. inc(_l);
  1879. if assigned(p^.less) then
  1880. count(p^.less);
  1881. if assigned(p^.greater) then
  1882. count(p^.greater);
  1883. end;
  1884. begin
  1885. _l:=0;
  1886. count(root);
  1887. case_count_labels:=_l;
  1888. end;
  1889. function case_get_max(root : pcaserecord) : longint;
  1890. var
  1891. hp : pcaserecord;
  1892. begin
  1893. hp:=root;
  1894. while assigned(hp^.greater) do
  1895. hp:=hp^.greater;
  1896. case_get_max:=hp^._high;
  1897. end;
  1898. function case_get_min(root : pcaserecord) : longint;
  1899. var
  1900. hp : pcaserecord;
  1901. begin
  1902. hp:=root;
  1903. while assigned(hp^.less) do
  1904. hp:=hp^.less;
  1905. case_get_min:=hp^._low;
  1906. end;
  1907. {$ifdef newcg}
  1908. {$I node.inc}
  1909. {$endif newcg}
  1910. end.
  1911. {
  1912. $Log$
  1913. Revision 1.119 2000-04-25 14:43:37 jonas
  1914. - disabled "string_var := string_var + ... " and "string_var + char_var"
  1915. optimizations (were only active with -dnewoptimizations) because of
  1916. several internal issues
  1917. Revision 1.118 2000/04/24 11:11:50 peter
  1918. * backtraces for exceptions are now only generated from the place of the
  1919. exception
  1920. * frame is also pushed for exceptions
  1921. * raise statement enhanced with [,<frame>]
  1922. Revision 1.117 2000/04/08 16:22:11 jonas
  1923. * fixed concat_string optimization and enabled it when
  1924. -dnewoptimizations is used
  1925. Revision 1.116 2000/03/01 15:36:12 florian
  1926. * some new stuff for the new cg
  1927. Revision 1.115 2000/03/01 11:43:55 daniel
  1928. * Some more work on the new symtable.
  1929. + Symtable stack unit 'symstack' added.
  1930. Revision 1.114 2000/02/28 17:23:57 daniel
  1931. * Current work of symtable integration committed. The symtable can be
  1932. activated by defining 'newst', but doesn't compile yet. Changes in type
  1933. checking and oop are completed. What is left is to write a new
  1934. symtablestack and adapt the parser to use it.
  1935. Revision 1.113 2000/02/20 20:49:46 florian
  1936. * newcg is compiling
  1937. * fixed the dup id problem reported by Paul Y.
  1938. Revision 1.112 2000/02/17 14:53:43 florian
  1939. * some updates for the newcg
  1940. Revision 1.111 2000/02/09 13:23:09 peter
  1941. * log truncated
  1942. Revision 1.110 2000/01/26 12:02:30 peter
  1943. * abstractprocdef.para_size needs alignment parameter
  1944. * secondcallparan gets para_alignment size instead of dword_align
  1945. Revision 1.109 2000/01/09 23:16:07 peter
  1946. * added st_default stringtype
  1947. * genstringconstnode extended with stringtype parameter using st_default
  1948. will do the old behaviour
  1949. Revision 1.108 2000/01/07 01:14:48 peter
  1950. * updated copyright to 2000
  1951. Revision 1.107 2000/01/06 01:10:33 pierre
  1952. * fixes for set_varstate on conversions
  1953. Revision 1.106 1999/12/22 01:01:52 peter
  1954. - removed freelabel()
  1955. * added undefined label detection in internal assembler, this prevents
  1956. a lot of ld crashes and wrong .o files
  1957. * .o files aren't written anymore if errors have occured
  1958. * inlining of assembler labels is now correct
  1959. Revision 1.105 1999/12/14 09:58:42 florian
  1960. + compiler checks now if a goto leaves an exception block
  1961. Revision 1.104 1999/11/30 10:40:59 peter
  1962. + ttype, tsymlist
  1963. Revision 1.103 1999/11/18 15:34:51 pierre
  1964. * Notes/Hints for local syms changed to
  1965. Set_varstate function
  1966. Revision 1.102 1999/11/17 17:05:07 pierre
  1967. * Notes/hints changes
  1968. Revision 1.101 1999/11/06 14:34:31 peter
  1969. * truncated log to 20 revs
  1970. Revision 1.100 1999/10/22 14:37:31 peter
  1971. * error when properties are passed to var parameters
  1972. Revision 1.99 1999/09/27 23:45:03 peter
  1973. * procinfo is now a pointer
  1974. * support for result setting in sub procedure
  1975. Revision 1.98 1999/09/26 21:30:22 peter
  1976. + constant pointer support which can happend with typecasting like
  1977. const p=pointer(1)
  1978. * better procvar parsing in typed consts
  1979. Revision 1.97 1999/09/17 17:14:13 peter
  1980. * @procvar fixes for tp mode
  1981. * @<id>:= gives now an error
  1982. Revision 1.96 1999/09/16 11:34:59 pierre
  1983. * typo correction
  1984. Revision 1.95 1999/09/10 18:48:11 florian
  1985. * some bug fixes (e.g. must_be_valid and procinfo^.funcret_is_valid)
  1986. * most things for stored properties fixed
  1987. Revision 1.94 1999/09/07 07:52:20 peter
  1988. * > < >= <= support for boolean
  1989. * boolean constants are now calculated like integer constants
  1990. Revision 1.93 1999/08/27 10:38:31 pierre
  1991. + EXTTEMPREGDEBUG code added
  1992. Revision 1.92 1999/08/26 21:10:08 peter
  1993. * better error recovery for case
  1994. Revision 1.91 1999/08/23 23:26:00 pierre
  1995. + TEMPREGDEBUG code, test of register allocation
  1996. if a tree uses more than registers32 regs then
  1997. internalerror(10) is issued
  1998. + EXTTEMPREGDEBUG will also give internalerror(10) if
  1999. a same register is freed twice (happens in several part
  2000. of current compiler like addn for strings and sets)
  2001. }