tree.pas 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127
  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 is_constresourcestringnode(p : ptree) : boolean;
  325. function str_length(p : ptree) : longint;
  326. function is_emptyset(p : ptree):boolean;
  327. { counts the labels }
  328. function case_count_labels(root : pcaserecord) : longint;
  329. { searches the highest label }
  330. function case_get_max(root : pcaserecord) : longint;
  331. { searches the lowest label }
  332. function case_get_min(root : pcaserecord) : longint;
  333. type
  334. pptree = ^ptree;
  335. {$ifdef TEMPREGDEBUG}
  336. const
  337. curptree : pptree = nil;
  338. {$endif TEMPREGDEBUG}
  339. {$I innr.inc}
  340. {$ifdef newcg}
  341. {$I nodeh.inc}
  342. {$endif newcg}
  343. implementation
  344. uses
  345. systems,
  346. globals,verbose,files,types,
  347. {$ifdef newcg}
  348. cgbase
  349. {$else newcg}
  350. hcodegen
  351. {$endif newcg}
  352. {$IFDEF NEWST}
  353. ,symtablt
  354. {$ENDIF}
  355. ;
  356. function getnode : ptree;
  357. var
  358. hp : ptree;
  359. begin
  360. new(hp);
  361. { makes error tracking easier }
  362. fillchar(hp^,sizeof(ttree),0);
  363. { reset }
  364. hp^.location.loc:=LOC_INVALID;
  365. { save local info }
  366. hp^.fileinfo:=aktfilepos;
  367. hp^.localswitches:=aktlocalswitches;
  368. getnode:=hp;
  369. end;
  370. procedure putnode(p : ptree);
  371. begin
  372. { clean up the contents of a node }
  373. case p^.treetype of
  374. asmn : if assigned(p^.p_asm) then
  375. dispose(p^.p_asm,done);
  376. stringconstn : begin
  377. ansistringdispose(p^.value_str,p^.length);
  378. end;
  379. setconstn : begin
  380. if assigned(p^.value_set) then
  381. dispose(p^.value_set);
  382. end;
  383. end;
  384. {$ifdef extdebug}
  385. if p^.firstpasscount>maxfirstpasscount then
  386. maxfirstpasscount:=p^.firstpasscount;
  387. {$endif extdebug}
  388. dispose(p);
  389. end;
  390. function getcopy(p : ptree) : ptree;
  391. var
  392. hp : ptree;
  393. begin
  394. if not assigned(p) then
  395. begin
  396. getcopy:=nil;
  397. exit;
  398. end;
  399. hp:=getnode;
  400. hp^:=p^;
  401. case p^.disposetyp of
  402. dt_leftright :
  403. begin
  404. if assigned(p^.left) then
  405. hp^.left:=getcopy(p^.left);
  406. if assigned(p^.right) then
  407. hp^.right:=getcopy(p^.right);
  408. end;
  409. dt_leftrighthigh :
  410. begin
  411. if assigned(p^.left) then
  412. hp^.left:=getcopy(p^.left);
  413. if assigned(p^.right) then
  414. hp^.right:=getcopy(p^.right);
  415. if assigned(p^.hightree) then
  416. hp^.hightree:=getcopy(p^.hightree);
  417. end;
  418. dt_leftrightframe :
  419. begin
  420. if assigned(p^.left) then
  421. hp^.left:=getcopy(p^.left);
  422. if assigned(p^.right) then
  423. hp^.right:=getcopy(p^.right);
  424. if assigned(p^.frametree) then
  425. hp^.frametree:=getcopy(p^.frametree);
  426. end;
  427. dt_leftrightmethod :
  428. begin
  429. if assigned(p^.left) then
  430. hp^.left:=getcopy(p^.left);
  431. if assigned(p^.right) then
  432. hp^.right:=getcopy(p^.right);
  433. if assigned(p^.methodpointer) then
  434. hp^.methodpointer:=getcopy(p^.methodpointer);
  435. end;
  436. dt_nothing : ;
  437. dt_left :
  438. if assigned(p^.left) then
  439. hp^.left:=getcopy(p^.left);
  440. dt_mbleft :
  441. if assigned(p^.left) then
  442. hp^.left:=getcopy(p^.left);
  443. dt_mbleft_and_method :
  444. begin
  445. if assigned(p^.left) then
  446. hp^.left:=getcopy(p^.left);
  447. hp^.methodpointer:=getcopy(p^.methodpointer);
  448. end;
  449. dt_loop :
  450. begin
  451. if assigned(p^.left) then
  452. hp^.left:=getcopy(p^.left);
  453. if assigned(p^.right) then
  454. hp^.right:=getcopy(p^.right);
  455. if assigned(p^.t1) then
  456. hp^.t1:=getcopy(p^.t1);
  457. if assigned(p^.t2) then
  458. hp^.t2:=getcopy(p^.t2);
  459. end;
  460. dt_typeconv : hp^.left:=getcopy(p^.left);
  461. dt_inlinen :
  462. if assigned(p^.left) then
  463. hp^.left:=getcopy(p^.left);
  464. else internalerror(11);
  465. end;
  466. { now check treetype }
  467. case p^.treetype of
  468. stringconstn : begin
  469. hp^.value_str:=getpcharcopy(p);
  470. hp^.length:=p^.length;
  471. end;
  472. setconstn : begin
  473. new(hp^.value_set);
  474. hp^.value_set:=p^.value_set;
  475. end;
  476. end;
  477. getcopy:=hp;
  478. end;
  479. procedure deletecaselabels(p : pcaserecord);
  480. begin
  481. if assigned(p^.greater) then
  482. deletecaselabels(p^.greater);
  483. if assigned(p^.less) then
  484. deletecaselabels(p^.less);
  485. dispose(p);
  486. end;
  487. procedure swaptree(p:Ptree);
  488. var swapp:Ptree;
  489. begin
  490. swapp:=p^.right;
  491. p^.right:=p^.left;
  492. p^.left:=swapp;
  493. p^.swaped:=not(p^.swaped);
  494. end;
  495. procedure disposetree(p : ptree);
  496. var
  497. symt : psymtable;
  498. i : longint;
  499. begin
  500. if not(assigned(p)) then
  501. exit;
  502. if not(p^.treetype in [addn..loadvmtn]) then
  503. internalerror(26219);
  504. case p^.disposetyp of
  505. dt_leftright :
  506. begin
  507. if assigned(p^.left) then
  508. disposetree(p^.left);
  509. if assigned(p^.right) then
  510. disposetree(p^.right);
  511. end;
  512. dt_leftrighthigh :
  513. begin
  514. if assigned(p^.left) then
  515. disposetree(p^.left);
  516. if assigned(p^.right) then
  517. disposetree(p^.right);
  518. if assigned(p^.hightree) then
  519. disposetree(p^.hightree);
  520. end;
  521. dt_leftrightframe :
  522. begin
  523. if assigned(p^.left) then
  524. disposetree(p^.left);
  525. if assigned(p^.right) then
  526. disposetree(p^.right);
  527. if assigned(p^.frametree) then
  528. disposetree(p^.frametree);
  529. end;
  530. dt_leftrightmethod :
  531. begin
  532. if assigned(p^.left) then
  533. disposetree(p^.left);
  534. if assigned(p^.right) then
  535. disposetree(p^.right);
  536. if assigned(p^.methodpointer) then
  537. disposetree(p^.methodpointer);
  538. end;
  539. dt_case :
  540. begin
  541. if assigned(p^.left) then
  542. disposetree(p^.left);
  543. if assigned(p^.right) then
  544. disposetree(p^.right);
  545. if assigned(p^.nodes) then
  546. deletecaselabels(p^.nodes);
  547. if assigned(p^.elseblock) then
  548. disposetree(p^.elseblock);
  549. end;
  550. dt_nothing : ;
  551. dt_left :
  552. if assigned(p^.left) then
  553. disposetree(p^.left);
  554. dt_mbleft :
  555. if assigned(p^.left) then
  556. disposetree(p^.left);
  557. dt_mbleft_and_method :
  558. begin
  559. if assigned(p^.left) then disposetree(p^.left);
  560. disposetree(p^.methodpointer);
  561. end;
  562. dt_typeconv : disposetree(p^.left);
  563. dt_inlinen :
  564. if assigned(p^.left) then
  565. disposetree(p^.left);
  566. dt_loop :
  567. begin
  568. if assigned(p^.left) then
  569. disposetree(p^.left);
  570. if assigned(p^.right) then
  571. disposetree(p^.right);
  572. if assigned(p^.t1) then
  573. disposetree(p^.t1);
  574. if assigned(p^.t2) then
  575. disposetree(p^.t2);
  576. end;
  577. dt_onn:
  578. begin
  579. if assigned(p^.left) then
  580. disposetree(p^.left);
  581. if assigned(p^.right) then
  582. disposetree(p^.right);
  583. if assigned(p^.exceptsymtable) then
  584. dispose(p^.exceptsymtable,done);
  585. end;
  586. dt_with :
  587. begin
  588. if assigned(p^.left) then
  589. disposetree(p^.left);
  590. if assigned(p^.right) then
  591. disposetree(p^.right);
  592. {$IFDEF NEWST}
  593. dispose(p^.withsymtables,done);
  594. {$ELSE}
  595. symt:=p^.withsymtable;
  596. for i:=1 to p^.tablecount do
  597. begin
  598. if assigned(symt) then
  599. begin
  600. p^.withsymtable:=pwithsymtable(symt^.next);
  601. dispose(symt,done);
  602. end;
  603. symt:=p^.withsymtable;
  604. end;
  605. {$ENDIF NEWST}
  606. end;
  607. else internalerror(12);
  608. end;
  609. putnode(p);
  610. end;
  611. procedure set_file_line(from,_to : ptree);
  612. begin
  613. if assigned(from) then
  614. _to^.fileinfo:=from^.fileinfo;
  615. end;
  616. procedure set_tree_filepos(p : ptree;const filepos : tfileposinfo);
  617. begin
  618. p^.fileinfo:=filepos;
  619. end;
  620. {$IFDEF NEWST}
  621. function genwithnode(symtables:Pcollection;l,r : ptree) : ptree;
  622. var
  623. p : ptree;
  624. begin
  625. p:=getnode;
  626. p^.disposetyp:=dt_with;
  627. p^.treetype:=withn;
  628. p^.left:=l;
  629. p^.right:=r;
  630. p^.registers32:=0;
  631. {$ifdef SUPPORT_MMX}
  632. p^.registersmmx:=0;
  633. {$endif SUPPORT_MMX}
  634. p^.resulttype:=nil;
  635. p^.withsymtables:=symtables;
  636. p^.withreference:=nil;
  637. p^.islocal:=false;
  638. set_file_line(l,p);
  639. genwithnode:=p;
  640. end;
  641. {$ELSE}
  642. function genwithnode(symtable : pwithsymtable;l,r : ptree;count : longint) : ptree;
  643. var
  644. p : ptree;
  645. begin
  646. p:=getnode;
  647. p^.disposetyp:=dt_with;
  648. p^.treetype:=withn;
  649. p^.left:=l;
  650. p^.right:=r;
  651. p^.registers32:=0;
  652. {$ifdef SUPPORT_MMX}
  653. p^.registersmmx:=0;
  654. {$endif SUPPORT_MMX}
  655. p^.resulttype:=nil;
  656. p^.withsymtable:=symtable;
  657. p^.tablecount:=count;
  658. p^.withreference:=nil;
  659. p^.islocal:=false;
  660. set_file_line(l,p);
  661. genwithnode:=p;
  662. end;
  663. {$ENDIF NEWST}
  664. function genfixconstnode(v : longint;def : pdef) : ptree;
  665. var
  666. p : ptree;
  667. begin
  668. p:=getnode;
  669. p^.disposetyp:=dt_nothing;
  670. p^.treetype:=fixconstn;
  671. p^.registers32:=0;
  672. { p^.registers16:=0;
  673. p^.registers8:=0; }
  674. p^.registersfpu:=0;
  675. {$ifdef SUPPORT_MMX}
  676. p^.registersmmx:=0;
  677. {$endif SUPPORT_MMX}
  678. p^.resulttype:=def;
  679. p^.value:=v;
  680. genfixconstnode:=p;
  681. end;
  682. function gencallparanode(expr,next : ptree) : ptree;
  683. var
  684. p : ptree;
  685. begin
  686. p:=getnode;
  687. p^.disposetyp:=dt_leftrighthigh;
  688. p^.treetype:=callparan;
  689. p^.left:=expr;
  690. p^.right:=next;
  691. p^.registers32:=0;
  692. { p^.registers16:=0;
  693. p^.registers8:=0; }
  694. {$ifdef SUPPORT_MMX}
  695. p^.registersmmx:=0;
  696. {$endif SUPPORT_MMX}
  697. p^.registersfpu:=0;
  698. p^.resulttype:=nil;
  699. p^.exact_match_found:=false;
  700. p^.convlevel1found:=false;
  701. p^.convlevel2found:=false;
  702. p^.is_colon_para:=false;
  703. p^.hightree:=nil;
  704. set_file_line(expr,p);
  705. gencallparanode:=p;
  706. end;
  707. function gennode(t : ttreetyp;l,r : ptree) : ptree;
  708. var
  709. p : ptree;
  710. begin
  711. p:=getnode;
  712. p^.disposetyp:=dt_leftright;
  713. p^.treetype:=t;
  714. p^.left:=l;
  715. p^.right:=r;
  716. p^.registers32:=0;
  717. { p^.registers16:=0;
  718. p^.registers8:=0; }
  719. p^.registersfpu:=0;
  720. {$ifdef SUPPORT_MMX}
  721. p^.registersmmx:=0;
  722. {$endif SUPPORT_MMX}
  723. p^.resulttype:=nil;
  724. gennode:=p;
  725. end;
  726. function gencasenode(l,r : ptree;nodes : pcaserecord) : ptree;
  727. var
  728. p : ptree;
  729. begin
  730. p:=getnode;
  731. p^.disposetyp:=dt_case;
  732. p^.treetype:=casen;
  733. p^.left:=l;
  734. p^.right:=r;
  735. p^.nodes:=nodes;
  736. p^.registers32:=0;
  737. p^.registersfpu:=0;
  738. {$ifdef SUPPORT_MMX}
  739. p^.registersmmx:=0;
  740. {$endif SUPPORT_MMX}
  741. p^.resulttype:=nil;
  742. set_file_line(l,p);
  743. gencasenode:=p;
  744. end;
  745. function genloopnode(t : ttreetyp;l,r,n1 : ptree;back : boolean) : ptree;
  746. var
  747. p : ptree;
  748. begin
  749. p:=getnode;
  750. p^.disposetyp:=dt_loop;
  751. p^.treetype:=t;
  752. p^.left:=l;
  753. p^.right:=r;
  754. p^.t1:=n1;
  755. p^.t2:=nil;
  756. p^.registers32:=0;
  757. p^.backward:=back;
  758. { p^.registers16:=0;
  759. p^.registers8:=0; }
  760. p^.registersfpu:=0;
  761. {$ifdef SUPPORT_MMX}
  762. p^.registersmmx:=0;
  763. {$endif SUPPORT_MMX}
  764. p^.resulttype:=nil;
  765. set_file_line(l,p);
  766. genloopnode:=p;
  767. end;
  768. function genordinalconstnode(v : longint;def : pdef) : ptree;
  769. var
  770. p : ptree;
  771. begin
  772. p:=getnode;
  773. p^.disposetyp:=dt_nothing;
  774. p^.treetype:=ordconstn;
  775. p^.registers32:=0;
  776. { p^.registers16:=0;
  777. p^.registers8:=0; }
  778. p^.registersfpu:=0;
  779. {$ifdef SUPPORT_MMX}
  780. p^.registersmmx:=0;
  781. {$endif SUPPORT_MMX}
  782. p^.resulttype:=def;
  783. p^.value:=v;
  784. {$IFDEF NEWST}
  785. if typeof(p^.resulttype^)=typeof(Torddef) then
  786. testrange(p^.resulttype,p^.value);
  787. {$ELSE NEWST}
  788. if p^.resulttype^.deftype=orddef then
  789. testrange(p^.resulttype,p^.value);
  790. {$ENDIF}
  791. genordinalconstnode:=p;
  792. end;
  793. function genpointerconstnode(v : longint;def : pdef) : ptree;
  794. var
  795. p : ptree;
  796. begin
  797. p:=getnode;
  798. p^.disposetyp:=dt_nothing;
  799. p^.treetype:=pointerconstn;
  800. p^.registers32:=0;
  801. { p^.registers16:=0;
  802. p^.registers8:=0; }
  803. p^.registersfpu:=0;
  804. {$ifdef SUPPORT_MMX}
  805. p^.registersmmx:=0;
  806. {$endif SUPPORT_MMX}
  807. p^.resulttype:=def;
  808. p^.value:=v;
  809. genpointerconstnode:=p;
  810. end;
  811. function genenumnode(v : penumsym) : ptree;
  812. var
  813. p : ptree;
  814. begin
  815. p:=getnode;
  816. p^.disposetyp:=dt_nothing;
  817. p^.treetype:=ordconstn;
  818. p^.registers32:=0;
  819. { p^.registers16:=0;
  820. p^.registers8:=0; }
  821. p^.registersfpu:=0;
  822. {$ifdef SUPPORT_MMX}
  823. p^.registersmmx:=0;
  824. {$endif SUPPORT_MMX}
  825. p^.resulttype:=v^.definition;
  826. p^.value:=v^.value;
  827. testrange(p^.resulttype,p^.value);
  828. genenumnode:=p;
  829. end;
  830. function genrealconstnode(v : bestreal;def : pdef) : ptree;
  831. var
  832. p : ptree;
  833. begin
  834. p:=getnode;
  835. p^.disposetyp:=dt_nothing;
  836. p^.treetype:=realconstn;
  837. p^.registers32:=0;
  838. { p^.registers16:=0;
  839. p^.registers8:=0; }
  840. p^.registersfpu:=0;
  841. {$ifdef SUPPORT_MMX}
  842. p^.registersmmx:=0;
  843. {$endif SUPPORT_MMX}
  844. p^.resulttype:=def;
  845. p^.value_real:=v;
  846. p^.lab_real:=nil;
  847. genrealconstnode:=p;
  848. end;
  849. function genstringconstnode(const s : string;st:tstringtype) : ptree;
  850. var
  851. p : ptree;
  852. l : longint;
  853. begin
  854. p:=getnode;
  855. p^.disposetyp:=dt_nothing;
  856. p^.treetype:=stringconstn;
  857. p^.registers32:=0;
  858. { p^.registers16:=0;
  859. p^.registers8:=0; }
  860. p^.registersfpu:=0;
  861. {$ifdef SUPPORT_MMX}
  862. p^.registersmmx:=0;
  863. {$endif SUPPORT_MMX}
  864. l:=length(s);
  865. p^.length:=l;
  866. { stringdup write even past a #0 }
  867. getmem(p^.value_str,l+1);
  868. move(s[1],p^.value_str^,l);
  869. p^.value_str[l]:=#0;
  870. p^.lab_str:=nil;
  871. if st=st_default then
  872. begin
  873. if cs_ansistrings in aktlocalswitches then
  874. p^.stringtype:=st_ansistring
  875. else
  876. p^.stringtype:=st_shortstring;
  877. end
  878. else
  879. p^.stringtype:=st;
  880. case p^.stringtype of
  881. st_shortstring :
  882. p^.resulttype:=cshortstringdef;
  883. st_ansistring :
  884. p^.resulttype:=cansistringdef;
  885. else
  886. internalerror(44990099);
  887. end;
  888. genstringconstnode:=p;
  889. end;
  890. function getpcharcopy(p : ptree) : pchar;
  891. var
  892. pc : pchar;
  893. begin
  894. pc:=nil;
  895. getmem(pc,p^.length+1);
  896. if pc=nil then
  897. Message(general_f_no_memory_left);
  898. move(p^.value_str^,pc^,p^.length+1);
  899. getpcharcopy:=pc;
  900. end;
  901. function genpcharconstnode(s : pchar;length : longint) : ptree;
  902. var
  903. p : ptree;
  904. begin
  905. p:=getnode;
  906. p^.disposetyp:=dt_nothing;
  907. p^.treetype:=stringconstn;
  908. p^.registers32:=0;
  909. { p^.registers16:=0;
  910. p^.registers8:=0; }
  911. p^.registersfpu:=0;
  912. {$ifdef SUPPORT_MMX}
  913. p^.registersmmx:=0;
  914. {$endif SUPPORT_MMX}
  915. p^.length:=length;
  916. if (cs_ansistrings in aktlocalswitches) or
  917. (length>255) then
  918. begin
  919. p^.stringtype:=st_ansistring;
  920. p^.resulttype:=cansistringdef;
  921. end
  922. else
  923. begin
  924. p^.stringtype:=st_shortstring;
  925. p^.resulttype:=cshortstringdef;
  926. end;
  927. p^.value_str:=s;
  928. p^.lab_str:=nil;
  929. genpcharconstnode:=p;
  930. end;
  931. function gensinglenode(t : ttreetyp;l : ptree) : ptree;
  932. var
  933. p : ptree;
  934. begin
  935. p:=getnode;
  936. p^.disposetyp:=dt_left;
  937. p^.treetype:=t;
  938. p^.left:=l;
  939. p^.registers32:=0;
  940. { p^.registers16:=0;
  941. p^.registers8:=0; }
  942. p^.registersfpu:=0;
  943. {$ifdef SUPPORT_MMX}
  944. p^.registersmmx:=0;
  945. {$endif SUPPORT_MMX}
  946. p^.resulttype:=nil;
  947. gensinglenode:=p;
  948. end;
  949. function genasmnode(p_asm : paasmoutput) : ptree;
  950. var
  951. p : ptree;
  952. begin
  953. p:=getnode;
  954. p^.disposetyp:=dt_nothing;
  955. p^.treetype:=asmn;
  956. p^.registers32:=4;
  957. p^.p_asm:=p_asm;
  958. p^.object_preserved:=false;
  959. { p^.registers16:=0;
  960. p^.registers8:=0; }
  961. p^.registersfpu:=8;
  962. {$ifdef SUPPORT_MMX}
  963. p^.registersmmx:=8;
  964. {$endif SUPPORT_MMX}
  965. p^.resulttype:=nil;
  966. genasmnode:=p;
  967. end;
  968. function genloadnode(v : pvarsym;st : psymtable) : ptree;
  969. var
  970. p : ptree;
  971. begin
  972. p:=getnode;
  973. p^.registers32:=0;
  974. { p^.registers16:=0;
  975. p^.registers8:=0; }
  976. p^.registersfpu:=0;
  977. {$ifdef SUPPORT_MMX}
  978. p^.registersmmx:=0;
  979. {$endif SUPPORT_MMX}
  980. p^.treetype:=loadn;
  981. {$IFDEF NEWST}
  982. p^.resulttype:=v^.definition;
  983. {$ELSE}
  984. p^.resulttype:=v^.vartype.def;
  985. {$ENDIF NEWST}
  986. p^.symtableentry:=v;
  987. p^.symtable:=st;
  988. p^.is_first := False;
  989. { method pointer load nodes can use the left subtree }
  990. p^.disposetyp:=dt_left;
  991. p^.left:=nil;
  992. genloadnode:=p;
  993. end;
  994. function genloadcallnode(v: pprocsym;st: psymtable): ptree;
  995. var
  996. p : ptree;
  997. begin
  998. p:=getnode;
  999. p^.registers32:=0;
  1000. { p^.registers16:=0;
  1001. p^.registers8:=0; }
  1002. p^.registersfpu:=0;
  1003. {$ifdef SUPPORT_MMX}
  1004. p^.registersmmx:=0;
  1005. {$endif SUPPORT_MMX}
  1006. p^.treetype:=loadn;
  1007. p^.left:=nil;
  1008. {$IFDEF NEWST}
  1009. p^.resulttype:=nil; {We don't know which overloaded procedure is
  1010. wanted...}
  1011. {$ELSE}
  1012. p^.resulttype:=v^.definition;
  1013. {$ENDIF}
  1014. p^.symtableentry:=v;
  1015. p^.symtable:=st;
  1016. p^.is_first := False;
  1017. p^.disposetyp:=dt_nothing;
  1018. genloadcallnode:=p;
  1019. end;
  1020. function genloadmethodcallnode(v: pprocsym;st: psymtable; mp:ptree): ptree;
  1021. var
  1022. p : ptree;
  1023. begin
  1024. p:=getnode;
  1025. p^.registers32:=0;
  1026. { p^.registers16:=0;
  1027. p^.registers8:=0; }
  1028. p^.registersfpu:=0;
  1029. {$ifdef SUPPORT_MMX}
  1030. p^.registersmmx:=0;
  1031. {$endif SUPPORT_MMX}
  1032. p^.treetype:=loadn;
  1033. p^.left:=nil;
  1034. {$IFDEF NEWST}
  1035. p^.resulttype:=nil; {We don't know which overloaded procedure is
  1036. wanted...}
  1037. {$ELSE}
  1038. p^.resulttype:=v^.definition;
  1039. {$ENDIF}
  1040. p^.symtableentry:=v;
  1041. p^.symtable:=st;
  1042. p^.is_first := False;
  1043. p^.disposetyp:=dt_left;
  1044. p^.left:=mp;
  1045. genloadmethodcallnode:=p;
  1046. end;
  1047. function gentypedconstloadnode(sym : ptypedconstsym;st : psymtable) : ptree;
  1048. var
  1049. p : ptree;
  1050. begin
  1051. p:=getnode;
  1052. p^.registers32:=0;
  1053. { p^.registers16:=0;
  1054. p^.registers8:=0; }
  1055. p^.registersfpu:=0;
  1056. {$ifdef SUPPORT_MMX}
  1057. p^.registersmmx:=0;
  1058. {$endif SUPPORT_MMX}
  1059. p^.treetype:=loadn;
  1060. p^.left:=nil;
  1061. {$IFDEF NEWST}
  1062. p^.resulttype:=sym^.definition;
  1063. {$ELSE}
  1064. p^.resulttype:=sym^.typedconsttype.def;
  1065. {$ENDIF NEWST}
  1066. p^.symtableentry:=sym;
  1067. p^.symtable:=st;
  1068. p^.disposetyp:=dt_nothing;
  1069. gentypedconstloadnode:=p;
  1070. end;
  1071. function gentypeconvnode(node : ptree;t : pdef) : ptree;
  1072. var
  1073. p : ptree;
  1074. begin
  1075. p:=getnode;
  1076. p^.disposetyp:=dt_typeconv;
  1077. p^.treetype:=typeconvn;
  1078. p^.left:=node;
  1079. p^.registers32:=0;
  1080. { p^.registers16:=0;
  1081. p^.registers8:=0; }
  1082. p^.convtyp:=tc_equal;
  1083. p^.registersfpu:=0;
  1084. {$ifdef SUPPORT_MMX}
  1085. p^.registersmmx:=0;
  1086. {$endif SUPPORT_MMX}
  1087. p^.resulttype:=t;
  1088. p^.explizit:=false;
  1089. set_file_line(node,p);
  1090. gentypeconvnode:=p;
  1091. end;
  1092. function gentypenode(t : pdef;sym:ptypesym) : ptree;
  1093. var
  1094. p : ptree;
  1095. begin
  1096. p:=getnode;
  1097. p^.disposetyp:=dt_nothing;
  1098. p^.treetype:=typen;
  1099. p^.registers32:=0;
  1100. { p^.registers16:=0;
  1101. p^.registers8:=0; }
  1102. p^.registersfpu:=0;
  1103. {$ifdef SUPPORT_MMX}
  1104. p^.registersmmx:=0;
  1105. {$endif SUPPORT_MMX}
  1106. p^.resulttype:=generrordef;
  1107. p^.typenodetype:=t;
  1108. p^.typenodesym:=sym;
  1109. gentypenode:=p;
  1110. end;
  1111. function gencallnode(v : pprocsym;st : psymtable) : ptree;
  1112. var
  1113. p : ptree;
  1114. begin
  1115. p:=getnode;
  1116. p^.registers32:=0;
  1117. { p^.registers16:=0;
  1118. p^.registers8:=0; }
  1119. p^.registersfpu:=0;
  1120. {$ifdef SUPPORT_MMX}
  1121. p^.registersmmx:=0;
  1122. {$endif SUPPORT_MMX}
  1123. p^.treetype:=calln;
  1124. p^.symtableprocentry:=v;
  1125. p^.symtableproc:=st;
  1126. p^.unit_specific:=false;
  1127. p^.no_check:=false;
  1128. p^.return_value_used:=true;
  1129. p^.disposetyp := dt_leftrightmethod;
  1130. p^.methodpointer:=nil;
  1131. p^.left:=nil;
  1132. p^.right:=nil;
  1133. p^.procdefinition:=nil;
  1134. gencallnode:=p;
  1135. end;
  1136. function genmethodcallnode(v : pprocsym;st : psymtable;mp : ptree) : ptree;
  1137. var
  1138. p : ptree;
  1139. begin
  1140. p:=getnode;
  1141. p^.registers32:=0;
  1142. { p^.registers16:=0;
  1143. p^.registers8:=0; }
  1144. p^.registersfpu:=0;
  1145. {$ifdef SUPPORT_MMX}
  1146. p^.registersmmx:=0;
  1147. {$endif SUPPORT_MMX}
  1148. p^.treetype:=calln;
  1149. p^.return_value_used:=true;
  1150. p^.symtableprocentry:=v;
  1151. p^.symtableproc:=st;
  1152. p^.disposetyp:=dt_leftrightmethod;
  1153. p^.left:=nil;
  1154. p^.right:=nil;
  1155. p^.methodpointer:=mp;
  1156. p^.procdefinition:=nil;
  1157. genmethodcallnode:=p;
  1158. end;
  1159. function gensubscriptnode(varsym : pvarsym;l : ptree) : ptree;
  1160. var
  1161. p : ptree;
  1162. begin
  1163. p:=getnode;
  1164. p^.disposetyp:=dt_left;
  1165. p^.treetype:=subscriptn;
  1166. p^.left:=l;
  1167. p^.registers32:=0;
  1168. p^.vs:=varsym;
  1169. { p^.registers16:=0;
  1170. p^.registers8:=0; }
  1171. p^.registersfpu:=0;
  1172. {$ifdef SUPPORT_MMX}
  1173. p^.registersmmx:=0;
  1174. {$endif SUPPORT_MMX}
  1175. p^.resulttype:=nil;
  1176. gensubscriptnode:=p;
  1177. end;
  1178. function genzeronode(t : ttreetyp) : ptree;
  1179. var
  1180. p : ptree;
  1181. begin
  1182. p:=getnode;
  1183. p^.disposetyp:=dt_nothing;
  1184. p^.treetype:=t;
  1185. p^.registers32:=0;
  1186. { p^.registers16:=0;
  1187. p^.registers8:=0; }
  1188. p^.registersfpu:=0;
  1189. {$ifdef SUPPORT_MMX}
  1190. p^.registersmmx:=0;
  1191. {$endif SUPPORT_MMX}
  1192. p^.resulttype:=nil;
  1193. genzeronode:=p;
  1194. end;
  1195. function genlabelnode(t : ttreetyp;nr : pasmlabel) : ptree;
  1196. var
  1197. p : ptree;
  1198. begin
  1199. p:=getnode;
  1200. p^.disposetyp:=dt_nothing;
  1201. p^.treetype:=t;
  1202. p^.registers32:=0;
  1203. { p^.registers16:=0;
  1204. p^.registers8:=0; }
  1205. p^.registersfpu:=0;
  1206. {$ifdef SUPPORT_MMX}
  1207. p^.registersmmx:=0;
  1208. {$endif SUPPORT_MMX}
  1209. p^.resulttype:=nil;
  1210. { for security }
  1211. { nr^.is_used:=true;}
  1212. p^.labelnr:=nr;
  1213. p^.exceptionblock:=nil;
  1214. genlabelnode:=p;
  1215. end;
  1216. function genselfnode(_class : pdef) : ptree;
  1217. var
  1218. p : ptree;
  1219. begin
  1220. p:=getnode;
  1221. p^.disposetyp:=dt_nothing;
  1222. p^.treetype:=selfn;
  1223. p^.registers32:=0;
  1224. { p^.registers16:=0;
  1225. p^.registers8:=0; }
  1226. p^.registersfpu:=0;
  1227. {$ifdef SUPPORT_MMX}
  1228. p^.registersmmx:=0;
  1229. {$endif SUPPORT_MMX}
  1230. p^.resulttype:=_class;
  1231. genselfnode:=p;
  1232. end;
  1233. function geninlinenode(number : byte;is_const:boolean;l : ptree) : ptree;
  1234. var
  1235. p : ptree;
  1236. begin
  1237. p:=getnode;
  1238. p^.disposetyp:=dt_inlinen;
  1239. p^.treetype:=inlinen;
  1240. p^.left:=l;
  1241. p^.inlinenumber:=number;
  1242. p^.inlineconst:=is_const;
  1243. p^.registers32:=0;
  1244. { p^.registers16:=0;
  1245. p^.registers8:=0; }
  1246. p^.registersfpu:=0;
  1247. {$ifdef SUPPORT_MMX}
  1248. p^.registersmmx:=0;
  1249. {$endif SUPPORT_MMX}
  1250. p^.resulttype:=nil;
  1251. geninlinenode:=p;
  1252. end;
  1253. { uses the callnode to create the new procinline node }
  1254. function genprocinlinenode(callp,code : ptree) : ptree;
  1255. var
  1256. p : ptree;
  1257. begin
  1258. p:=getnode;
  1259. p^.disposetyp:=dt_nothing;
  1260. p^.treetype:=procinlinen;
  1261. p^.inlineprocsym:=callp^.symtableprocentry;
  1262. p^.retoffset:=-4; { less dangerous as zero (PM) }
  1263. p^.para_offset:=0;
  1264. {$IFDEF NEWST}
  1265. {Fixme!!}
  1266. internalerror($00022801);
  1267. {$ELSE}
  1268. p^.para_size:=p^.inlineprocsym^.definition^.para_size(target_os.stackalignment);
  1269. if ret_in_param(p^.inlineprocsym^.definition^.rettype.def) then
  1270. p^.para_size:=p^.para_size+target_os.size_of_pointer;
  1271. {$ENDIF NEWST}
  1272. { copy args }
  1273. p^.inlinetree:=code;
  1274. p^.registers32:=code^.registers32;
  1275. p^.registersfpu:=code^.registersfpu;
  1276. {$ifdef SUPPORT_MMX}
  1277. p^.registersmmx:=0;
  1278. {$endif SUPPORT_MMX}
  1279. {$IFDEF NEWST}
  1280. {Fixme!!}
  1281. {$ELSE}
  1282. p^.resulttype:=p^.inlineprocsym^.definition^.rettype.def;
  1283. {$ENDIF NEWST}
  1284. genprocinlinenode:=p;
  1285. end;
  1286. function gensetconstnode(s : pconstset;settype : psetdef) : ptree;
  1287. var
  1288. p : ptree;
  1289. begin
  1290. p:=getnode;
  1291. p^.disposetyp:=dt_nothing;
  1292. p^.treetype:=setconstn;
  1293. p^.registers32:=0;
  1294. p^.registersfpu:=0;
  1295. {$ifdef SUPPORT_MMX}
  1296. p^.registersmmx:=0;
  1297. {$endif SUPPORT_MMX}
  1298. p^.resulttype:=settype;
  1299. p^.left:=nil;
  1300. new(p^.value_set);
  1301. p^.value_set^:=s^;
  1302. gensetconstnode:=p;
  1303. end;
  1304. {$ifdef extdebug}
  1305. procedure compare_trees(oldp,p : ptree);
  1306. var
  1307. error_found : boolean;
  1308. begin
  1309. if oldp^.resulttype<>p^.resulttype then
  1310. begin
  1311. error_found:=true;
  1312. if is_equal(oldp^.resulttype,p^.resulttype) then
  1313. comment(v_debug,'resulttype fields are different but equal')
  1314. else
  1315. comment(v_warning,'resulttype fields are really different');
  1316. end;
  1317. if oldp^.treetype<>p^.treetype then
  1318. begin
  1319. comment(v_warning,'treetype field different');
  1320. error_found:=true;
  1321. end
  1322. else
  1323. comment(v_debug,' treetype '+tostr(longint(oldp^.treetype)));
  1324. if oldp^.error<>p^.error then
  1325. begin
  1326. comment(v_warning,'error field different');
  1327. error_found:=true;
  1328. end;
  1329. if oldp^.disposetyp<>p^.disposetyp then
  1330. begin
  1331. comment(v_warning,'disposetyp field different');
  1332. error_found:=true;
  1333. end;
  1334. { is true, if the right and left operand are swaped }
  1335. if oldp^.swaped<>p^.swaped then
  1336. begin
  1337. comment(v_warning,'swaped field different');
  1338. error_found:=true;
  1339. end;
  1340. { the location of the result of this node }
  1341. if oldp^.location.loc<>p^.location.loc then
  1342. begin
  1343. comment(v_warning,'location.loc field different');
  1344. error_found:=true;
  1345. end;
  1346. { the number of registers needed to evalute the node }
  1347. if oldp^.registers32<>p^.registers32 then
  1348. begin
  1349. comment(v_warning,'registers32 field different');
  1350. comment(v_warning,' old '+tostr(oldp^.registers32)+'<> new '+tostr(p^.registers32));
  1351. error_found:=true;
  1352. end;
  1353. if oldp^.registersfpu<>p^.registersfpu then
  1354. begin
  1355. comment(v_warning,'registersfpu field different');
  1356. error_found:=true;
  1357. end;
  1358. {$ifdef SUPPORT_MMX}
  1359. if oldp^.registersmmx<>p^.registersmmx then
  1360. begin
  1361. comment(v_warning,'registersmmx field different');
  1362. error_found:=true;
  1363. end;
  1364. {$endif SUPPORT_MMX}
  1365. if oldp^.left<>p^.left then
  1366. begin
  1367. comment(v_warning,'left field different');
  1368. error_found:=true;
  1369. end;
  1370. if oldp^.right<>p^.right then
  1371. begin
  1372. comment(v_warning,'right field different');
  1373. error_found:=true;
  1374. end;
  1375. if oldp^.fileinfo.line<>p^.fileinfo.line then
  1376. begin
  1377. comment(v_warning,'fileinfo.line field different');
  1378. error_found:=true;
  1379. end;
  1380. if oldp^.fileinfo.column<>p^.fileinfo.column then
  1381. begin
  1382. comment(v_warning,'fileinfo.column field different');
  1383. error_found:=true;
  1384. end;
  1385. if oldp^.fileinfo.fileindex<>p^.fileinfo.fileindex then
  1386. begin
  1387. comment(v_warning,'fileinfo.fileindex field different');
  1388. error_found:=true;
  1389. end;
  1390. if oldp^.localswitches<>p^.localswitches then
  1391. begin
  1392. comment(v_warning,'localswitches field different');
  1393. error_found:=true;
  1394. end;
  1395. {$ifdef extdebug}
  1396. if oldp^.firstpasscount<>p^.firstpasscount then
  1397. begin
  1398. comment(v_warning,'firstpasscount field different');
  1399. error_found:=true;
  1400. end;
  1401. {$endif extdebug}
  1402. if oldp^.treetype=p^.treetype then
  1403. case oldp^.treetype of
  1404. addn :
  1405. begin
  1406. if oldp^.use_strconcat<>p^.use_strconcat then
  1407. begin
  1408. comment(v_warning,'use_strconcat field different');
  1409. error_found:=true;
  1410. end;
  1411. if oldp^.string_typ<>p^.string_typ then
  1412. begin
  1413. comment(v_warning,'stringtyp field different');
  1414. error_found:=true;
  1415. end;
  1416. end;
  1417. callparan :
  1418. {(is_colon_para : boolean;exact_match_found : boolean);}
  1419. begin
  1420. if oldp^.is_colon_para<>p^.is_colon_para then
  1421. begin
  1422. comment(v_warning,'use_strconcat field different');
  1423. error_found:=true;
  1424. end;
  1425. if oldp^.exact_match_found<>p^.exact_match_found then
  1426. begin
  1427. comment(v_warning,'exact_match_found field different');
  1428. error_found:=true;
  1429. end;
  1430. end;
  1431. assignn :
  1432. {(assigntyp : tassigntyp;concat_string : boolean);}
  1433. begin
  1434. if oldp^.assigntyp<>p^.assigntyp then
  1435. begin
  1436. comment(v_warning,'assigntyp field different');
  1437. error_found:=true;
  1438. end;
  1439. if oldp^.concat_string<>p^.concat_string then
  1440. begin
  1441. comment(v_warning,'concat_string field different');
  1442. error_found:=true;
  1443. end;
  1444. end;
  1445. loadn :
  1446. {(symtableentry : psym;symtable : psymtable;
  1447. is_absolute,is_first : boolean);}
  1448. begin
  1449. if oldp^.symtableentry<>p^.symtableentry then
  1450. begin
  1451. comment(v_warning,'symtableentry field different');
  1452. error_found:=true;
  1453. end;
  1454. if oldp^.symtable<>p^.symtable then
  1455. begin
  1456. comment(v_warning,'symtable field different');
  1457. error_found:=true;
  1458. end;
  1459. if oldp^.is_absolute<>p^.is_absolute then
  1460. begin
  1461. comment(v_warning,'is_absolute field different');
  1462. error_found:=true;
  1463. end;
  1464. if oldp^.is_first<>p^.is_first then
  1465. begin
  1466. comment(v_warning,'is_first field different');
  1467. error_found:=true;
  1468. end;
  1469. end;
  1470. calln :
  1471. {(symtableprocentry : pprocsym;
  1472. symtableproc : psymtable;procdefinition : pprocdef;
  1473. methodpointer : ptree;
  1474. no_check,unit_specific : boolean);}
  1475. begin
  1476. if oldp^.symtableprocentry<>p^.symtableprocentry then
  1477. begin
  1478. comment(v_warning,'symtableprocentry field different');
  1479. error_found:=true;
  1480. end;
  1481. if oldp^.symtableproc<>p^.symtableproc then
  1482. begin
  1483. comment(v_warning,'symtableproc field different');
  1484. error_found:=true;
  1485. end;
  1486. if oldp^.procdefinition<>p^.procdefinition then
  1487. begin
  1488. comment(v_warning,'procdefinition field different');
  1489. error_found:=true;
  1490. end;
  1491. if oldp^.methodpointer<>p^.methodpointer then
  1492. begin
  1493. comment(v_warning,'methodpointer field different');
  1494. error_found:=true;
  1495. end;
  1496. if oldp^.no_check<>p^.no_check then
  1497. begin
  1498. comment(v_warning,'no_check field different');
  1499. error_found:=true;
  1500. end;
  1501. if oldp^.unit_specific<>p^.unit_specific then
  1502. begin
  1503. error_found:=true;
  1504. comment(v_warning,'unit_specific field different');
  1505. end;
  1506. end;
  1507. ordconstn :
  1508. begin
  1509. if oldp^.value<>p^.value then
  1510. begin
  1511. comment(v_warning,'value field different');
  1512. error_found:=true;
  1513. end;
  1514. end;
  1515. realconstn :
  1516. begin
  1517. if oldp^.value_real<>p^.value_real then
  1518. begin
  1519. comment(v_warning,'valued field different');
  1520. error_found:=true;
  1521. end;
  1522. if oldp^.lab_real<>p^.lab_real then
  1523. begin
  1524. comment(v_warning,'labnumber field different');
  1525. error_found:=true;
  1526. end;
  1527. { if oldp^.realtyp<>p^.realtyp then
  1528. begin
  1529. comment(v_warning,'realtyp field different');
  1530. error_found:=true;
  1531. end; }
  1532. end;
  1533. end;
  1534. if not error_found then
  1535. comment(v_warning,'did not find difference in trees');
  1536. end;
  1537. {$endif extdebug}
  1538. function equal_trees(t1,t2 : ptree) : boolean;
  1539. begin
  1540. if t1^.treetype=t2^.treetype then
  1541. begin
  1542. case t1^.treetype of
  1543. addn,
  1544. muln,
  1545. equaln,
  1546. orn,
  1547. xorn,
  1548. andn,
  1549. unequaln:
  1550. begin
  1551. equal_trees:=(equal_trees(t1^.left,t2^.left) and
  1552. equal_trees(t1^.right,t2^.right)) or
  1553. (equal_trees(t1^.right,t2^.left) and
  1554. equal_trees(t1^.left,t2^.right));
  1555. end;
  1556. subn,
  1557. divn,
  1558. modn,
  1559. assignn,
  1560. ltn,
  1561. lten,
  1562. gtn,
  1563. gten,
  1564. inn,
  1565. shrn,
  1566. shln,
  1567. slashn,
  1568. rangen:
  1569. begin
  1570. equal_trees:=(equal_trees(t1^.left,t2^.left) and
  1571. equal_trees(t1^.right,t2^.right));
  1572. end;
  1573. unaryminusn,
  1574. notn,
  1575. derefn,
  1576. addrn:
  1577. begin
  1578. equal_trees:=(equal_trees(t1^.left,t2^.left));
  1579. end;
  1580. loadn:
  1581. begin
  1582. equal_trees:=(t1^.symtableentry=t2^.symtableentry)
  1583. { not necessary
  1584. and (t1^.symtable=t2^.symtable)};
  1585. end;
  1586. {
  1587. subscriptn,
  1588. ordconstn,typeconvn,calln,callparan,
  1589. realconstn,asmn,vecn,
  1590. stringconstn,funcretn,selfn,
  1591. inlinen,niln,errorn,
  1592. typen,hnewn,hdisposen,newn,
  1593. disposen,setelen,setconstrn
  1594. }
  1595. else equal_trees:=false;
  1596. end;
  1597. end
  1598. else
  1599. equal_trees:=false;
  1600. end;
  1601. {$ifdef newoptimizations2}
  1602. function multiple_uses(t1,t2: ptree): boolean;
  1603. var nr: longint;
  1604. procedure check_tree(t: ptree);
  1605. begin
  1606. inc(nr,ord(equal_trees(t1,t)));
  1607. if (nr < 2) and assigned(t^.left) then
  1608. check_tree(t^.left);
  1609. if (nr < 2) and assigned(t^.right) then
  1610. check_tree(t^.right);
  1611. end;
  1612. begin
  1613. nr := 0;
  1614. check_tree(t2);
  1615. multiple_uses := nr > 1;
  1616. end;
  1617. {$endif newoptimizations2}
  1618. procedure set_unique(p : ptree);
  1619. begin
  1620. if assigned(p) then
  1621. begin
  1622. case p^.treetype of
  1623. vecn:
  1624. p^.callunique:=true;
  1625. typeconvn,subscriptn,derefn:
  1626. set_unique(p^.left);
  1627. end;
  1628. end;
  1629. end;
  1630. procedure set_funcret_is_valid(p : ptree);
  1631. begin
  1632. if assigned(p) then
  1633. begin
  1634. case p^.treetype of
  1635. funcretn:
  1636. begin
  1637. if p^.is_first_funcret then
  1638. pprocinfo(p^.funcretprocinfo)^.funcret_state:=vs_assigned;
  1639. end;
  1640. vecn,typeconvn,subscriptn{,derefn}:
  1641. set_funcret_is_valid(p^.left);
  1642. end;
  1643. end;
  1644. end;
  1645. procedure set_varstate(p : ptree;must_be_valid : boolean);
  1646. begin
  1647. if not assigned(p) then
  1648. exit
  1649. else
  1650. begin
  1651. if p^.varstateset then
  1652. exit;
  1653. case p^.treetype of
  1654. typeconvn :
  1655. if p^.convtyp in
  1656. [
  1657. tc_cchar_2_pchar,
  1658. tc_cstring_2_pchar,
  1659. tc_array_2_pointer
  1660. ] then
  1661. set_varstate(p^.left,false)
  1662. else if p^.convtyp in
  1663. [
  1664. tc_pchar_2_string,
  1665. tc_pointer_2_array
  1666. ] then
  1667. set_varstate(p^.left,true)
  1668. else
  1669. set_varstate(p^.left,must_be_valid);
  1670. subscriptn :
  1671. set_varstate(p^.left,must_be_valid);
  1672. vecn:
  1673. begin
  1674. {$IFDEF NEWST}
  1675. if (typeof(p^.left^.resulttype^)=typeof(Tstringdef)) or
  1676. (typeof(p^.left^.resulttype^)=typeof(Tarraydef)) then
  1677. set_varstate(p^.left,must_be_valid)
  1678. else
  1679. set_varstate(p^.left,true);
  1680. {$ELSE}
  1681. if (p^.left^.resulttype^.deftype in [stringdef,arraydef]) then
  1682. set_varstate(p^.left,must_be_valid)
  1683. else
  1684. set_varstate(p^.left,true);
  1685. {$ENDIF NEWST}
  1686. set_varstate(p^.right,true);
  1687. end;
  1688. { do not parse calln }
  1689. calln : ;
  1690. callparan:
  1691. begin
  1692. set_varstate(p^.left,must_be_valid);
  1693. set_varstate(p^.right,must_be_valid);
  1694. end;
  1695. loadn :
  1696. {$IFDEF NEWST}
  1697. if (typeof(p^.symtableentry^)=typeof(Tvarsym)) or
  1698. (typeof(p^.symtableentry^)=typeof(Tparamsym)) then
  1699. begin
  1700. if must_be_valid and p^.is_first then
  1701. begin
  1702. if (pvarsym(p^.symtableentry)^.state=vs_declared_and_first_found) or
  1703. (pvarsym(p^.symtableentry)^.state=vs_set_but_first_not_passed) then
  1704. if (assigned(pvarsym(p^.symtableentry)^.owner) and
  1705. assigned(aktprocsym) and
  1706. (pvarsym(p^.symtableentry)^.owner=
  1707. Pcontainingsymtable(aktprocdef^.localst))) then
  1708. begin
  1709. if typeof(p^.symtable^)=typeof(Tprocsymtable) then
  1710. CGMessage1(sym_n_uninitialized_local_variable,pvarsym(p^.symtableentry)^.name)
  1711. else
  1712. CGMessage1(sym_n_uninitialized_variable,pvarsym(p^.symtableentry)^.name);
  1713. end;
  1714. end;
  1715. if (p^.is_first) then
  1716. begin
  1717. if pvarsym(p^.symtableentry)^.state=vs_declared_and_first_found then
  1718. { this can only happen at left of an assignment, no ? PM }
  1719. if (parsing_para_level=0) and not must_be_valid then
  1720. pvarsym(p^.symtableentry)^.state:=vs_assigned
  1721. else
  1722. pvarsym(p^.symtableentry)^.state:=vs_used;
  1723. if pvarsym(p^.symtableentry)^.state=vs_set_but_first_not_passed then
  1724. pvarsym(p^.symtableentry)^.state:=vs_used;
  1725. p^.is_first:=false;
  1726. end
  1727. else
  1728. begin
  1729. if (pvarsym(p^.symtableentry)^.state=vs_assigned) and
  1730. (must_be_valid or (parsing_para_level>0) or
  1731. (typeof(p^.resulttype^)=typeof(Tprocvardef))) then
  1732. pvarsym(p^.symtableentry)^.state:=vs_used;
  1733. if (pvarsym(p^.symtableentry)^.state=vs_declared_and_first_found) and
  1734. (must_be_valid or (parsing_para_level>0) or
  1735. (typeof(p^.resulttype^)=typeof(Tprocvardef))) then
  1736. pvarsym(p^.symtableentry)^.state:=vs_set_but_first_not_passed;
  1737. end;
  1738. end;
  1739. {$ELSE}
  1740. if (p^.symtableentry^.typ=varsym) then
  1741. begin
  1742. if must_be_valid and p^.is_first then
  1743. begin
  1744. if (pvarsym(p^.symtableentry)^.varstate=vs_declared_and_first_found) or
  1745. (pvarsym(p^.symtableentry)^.varstate=vs_set_but_first_not_passed) then
  1746. if (assigned(pvarsym(p^.symtableentry)^.owner) and
  1747. assigned(aktprocsym) and
  1748. (pvarsym(p^.symtableentry)^.owner = aktprocsym^.definition^.localst)) then
  1749. begin
  1750. if p^.symtable^.symtabletype=localsymtable then
  1751. CGMessage1(sym_n_uninitialized_local_variable,pvarsym(p^.symtableentry)^.name)
  1752. else
  1753. CGMessage1(sym_n_uninitialized_variable,pvarsym(p^.symtableentry)^.name);
  1754. end;
  1755. end;
  1756. if (p^.is_first) then
  1757. begin
  1758. if pvarsym(p^.symtableentry)^.varstate=vs_declared_and_first_found then
  1759. { this can only happen at left of an assignment, no ? PM }
  1760. if (parsing_para_level=0) and not must_be_valid then
  1761. pvarsym(p^.symtableentry)^.varstate:=vs_assigned
  1762. else
  1763. pvarsym(p^.symtableentry)^.varstate:=vs_used;
  1764. if pvarsym(p^.symtableentry)^.varstate=vs_set_but_first_not_passed then
  1765. pvarsym(p^.symtableentry)^.varstate:=vs_used;
  1766. p^.is_first:=false;
  1767. end
  1768. else
  1769. begin
  1770. if (pvarsym(p^.symtableentry)^.varstate=vs_assigned) and
  1771. (must_be_valid or (parsing_para_level>0) or
  1772. (p^.resulttype^.deftype=procvardef)) then
  1773. pvarsym(p^.symtableentry)^.varstate:=vs_used;
  1774. if (pvarsym(p^.symtableentry)^.varstate=vs_declared_and_first_found) and
  1775. (must_be_valid or (parsing_para_level>0) or
  1776. (p^.resulttype^.deftype=procvardef)) then
  1777. pvarsym(p^.symtableentry)^.varstate:=vs_set_but_first_not_passed;
  1778. end;
  1779. end;
  1780. {$ENDIF NEWST}
  1781. funcretn:
  1782. begin
  1783. { no claim if setting higher return value_str }
  1784. if must_be_valid and
  1785. (procinfo=pprocinfo(p^.funcretprocinfo)) and
  1786. ((procinfo^.funcret_state=vs_declared) or
  1787. ((p^.is_first_funcret) and
  1788. (procinfo^.funcret_state=vs_declared_and_first_found))) then
  1789. begin
  1790. CGMessage(sym_w_function_result_not_set);
  1791. { avoid multiple warnings }
  1792. procinfo^.funcret_state:=vs_assigned;
  1793. end;
  1794. if p^.is_first_funcret and not must_be_valid then
  1795. pprocinfo(p^.funcretprocinfo)^.funcret_state:=vs_assigned;
  1796. end;
  1797. else
  1798. begin
  1799. {internalerror(565656);}
  1800. end;
  1801. end;{case }
  1802. p^.varstateset:=true;
  1803. end;
  1804. end;
  1805. procedure clear_location(var loc : tlocation);
  1806. begin
  1807. loc.loc:=LOC_INVALID;
  1808. end;
  1809. {This is needed if you want to be able to delete the string with the nodes !!}
  1810. procedure set_location(var destloc,sourceloc : tlocation);
  1811. begin
  1812. destloc:= sourceloc;
  1813. end;
  1814. procedure swap_location(var destloc,sourceloc : tlocation);
  1815. var
  1816. swapl : tlocation;
  1817. begin
  1818. swapl := destloc;
  1819. destloc := sourceloc;
  1820. sourceloc := swapl;
  1821. end;
  1822. function get_ordinal_value(p : ptree) : longint;
  1823. begin
  1824. if p^.treetype=ordconstn then
  1825. get_ordinal_value:=p^.value
  1826. else
  1827. begin
  1828. Message(type_e_ordinal_expr_expected);
  1829. get_ordinal_value:=0;
  1830. end;
  1831. end;
  1832. function is_constnode(p : ptree) : boolean;
  1833. begin
  1834. is_constnode:=(p^.treetype in [ordconstn,realconstn,stringconstn,fixconstn,setconstn]);
  1835. end;
  1836. function is_constintnode(p : ptree) : boolean;
  1837. begin
  1838. is_constintnode:=(p^.treetype=ordconstn) and is_integer(p^.resulttype);
  1839. end;
  1840. function is_constcharnode(p : ptree) : boolean;
  1841. begin
  1842. is_constcharnode:=(p^.treetype=ordconstn) and is_char(p^.resulttype);
  1843. end;
  1844. function is_constrealnode(p : ptree) : boolean;
  1845. begin
  1846. is_constrealnode:=(p^.treetype=realconstn);
  1847. end;
  1848. function is_constboolnode(p : ptree) : boolean;
  1849. begin
  1850. is_constboolnode:=(p^.treetype=ordconstn) and is_boolean(p^.resulttype);
  1851. end;
  1852. function is_constresourcestringnode(p : ptree) : boolean;
  1853. begin
  1854. is_constresourcestringnode:=(p^.treetype=loadn) and
  1855. (p^.symtableentry^.typ=constsym) and
  1856. (pconstsym(p^.symtableentry)^.consttyp=constresourcestring);
  1857. end;
  1858. function str_length(p : ptree) : longint;
  1859. begin
  1860. str_length:=p^.length;
  1861. end;
  1862. function is_emptyset(p : ptree):boolean;
  1863. {
  1864. return true if set s is empty
  1865. }
  1866. var
  1867. i : longint;
  1868. begin
  1869. i:=0;
  1870. if p^.treetype=setconstn then
  1871. begin
  1872. while (i<32) and (p^.value_set^[i]=0) do
  1873. inc(i);
  1874. end;
  1875. is_emptyset:=(i=32);
  1876. end;
  1877. {*****************************************************************************
  1878. Case Helpers
  1879. *****************************************************************************}
  1880. function case_count_labels(root : pcaserecord) : longint;
  1881. var
  1882. _l : longint;
  1883. procedure count(p : pcaserecord);
  1884. begin
  1885. inc(_l);
  1886. if assigned(p^.less) then
  1887. count(p^.less);
  1888. if assigned(p^.greater) then
  1889. count(p^.greater);
  1890. end;
  1891. begin
  1892. _l:=0;
  1893. count(root);
  1894. case_count_labels:=_l;
  1895. end;
  1896. function case_get_max(root : pcaserecord) : longint;
  1897. var
  1898. hp : pcaserecord;
  1899. begin
  1900. hp:=root;
  1901. while assigned(hp^.greater) do
  1902. hp:=hp^.greater;
  1903. case_get_max:=hp^._high;
  1904. end;
  1905. function case_get_min(root : pcaserecord) : longint;
  1906. var
  1907. hp : pcaserecord;
  1908. begin
  1909. hp:=root;
  1910. while assigned(hp^.less) do
  1911. hp:=hp^.less;
  1912. case_get_min:=hp^._low;
  1913. end;
  1914. {$ifdef newcg}
  1915. {$I node.inc}
  1916. {$endif newcg}
  1917. end.
  1918. {
  1919. $Log$
  1920. Revision 1.2 2000-07-13 11:32:52 michael
  1921. + removed logs
  1922. }