123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884 |
- {
- $Id$
- Copyright (c) 1993-98 by Florian Klaempfl
- This units exports some routines to manage the parse tree
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************
- }
- {$ifdef tp}
- {$E+,N+}
- {$endif}
- unit tree;
- interface
- uses
- globtype,cobjects,
- symconst,symtable,aasm,cpubase;
- type
- pconstset = ^tconstset;
- tconstset = array[0..31] of byte;
- ttreetyp = (
- addn, {Represents the + operator.}
- muln, {Represents the * operator.}
- subn, {Represents the - operator.}
- divn, {Represents the div operator.}
- symdifn, {Represents the >< operator.}
- modn, {Represents the mod operator.}
- assignn, {Represents an assignment.}
- loadn, {Represents the use of a variabele.}
- rangen, {Represents a range (i.e. 0..9).}
- ltn, {Represents the < operator.}
- lten, {Represents the <= operator.}
- gtn, {Represents the > operator.}
- gten, {Represents the >= operator.}
- equaln, {Represents the = operator.}
- unequaln, {Represents the <> operator.}
- inn, {Represents the in operator.}
- orn, {Represents the or operator.}
- xorn, {Represents the xor operator.}
- shrn, {Represents the shr operator.}
- shln, {Represents the shl operator.}
- slashn, {Represents the / operator.}
- andn, {Represents the and operator.}
- subscriptn, {??? Field in a record/object?}
- derefn, {Dereferences a pointer.}
- addrn, {Represents the @ operator.}
- doubleaddrn, {Represents the @@ operator.}
- ordconstn, {Represents an ordinal value.}
- typeconvn, {Represents type-conversion/typecast.}
- calln, {Represents a call node.}
- callparan, {Represents a parameter.}
- realconstn, {Represents a real value.}
- fixconstn, {Represents a fixed value.}
- umminusn, {Represents a sign change (i.e. -2).}
- asmn, {Represents an assembler node }
- vecn, {Represents array indexing.}
- pointerconstn,
- stringconstn, {Represents a string constant.}
- funcretn, {Represents the function result var.}
- selfn, {Represents the self parameter.}
- notn, {Represents the not operator.}
- inlinen, {Internal procedures (i.e. writeln).}
- niln, {Represents the nil pointer.}
- errorn, {This part of the tree could not be
- parsed because of a compiler error.}
- typen, {A type name. Used for i.e. typeof(obj).}
- hnewn, {The new operation, constructor call.}
- hdisposen, {The dispose operation with destructor call.}
- newn, {The new operation, constructor call.}
- simpledisposen, {The dispose operation.}
- setelementn, {A set element(s) (i.e. [a,b] and also [a..b]).}
- setconstn, {A set constant (i.e. [1,2]).}
- blockn, {A block of statements.}
- statementn, {One statement in a block of nodes.}
- loopn, { used in genloopnode, must be converted }
- ifn, {An if statement.}
- breakn, {A break statement.}
- continuen, {A continue statement.}
- repeatn, {A repeat until block.}
- whilen, {A while do statement.}
- forn, {A for loop.}
- exitn, {An exit statement.}
- withn, {A with statement.}
- casen, {A case statement.}
- labeln, {A label.}
- goton, {A goto statement.}
- simplenewn, {The new operation.}
- tryexceptn, {A try except block.}
- raisen, {A raise statement.}
- switchesn, {??? Currently unused...}
- tryfinallyn, {A try finally statement.}
- onn, { for an on statement in exception code }
- isn, {Represents the is operator.}
- asn, {Represents the as typecast.}
- caretn, {Represents the ^ operator.}
- failn, {Represents the fail statement.}
- starstarn, {Represents the ** operator exponentiation }
- procinlinen, {Procedures that can be inlined }
- arrayconstructn, {Construction node for [...] parsing}
- arrayconstructrangen, {Range element to allow sets in array construction tree}
- { added for optimizations where we cannot suppress }
- nothingn,
- loadvmtn
- );
- tconverttype = (
- tc_equal,
- tc_not_possible,
- tc_string_2_string,
- tc_char_2_string,
- tc_pchar_2_string,
- tc_cchar_2_pchar,
- tc_cstring_2_pchar,
- tc_ansistring_2_pchar,
- tc_string_2_chararray,
- tc_chararray_2_string,
- tc_array_2_pointer,
- tc_pointer_2_array,
- tc_int_2_int,
- tc_int_2_bool,
- tc_bool_2_bool,
- tc_bool_2_int,
- tc_real_2_real,
- tc_int_2_real,
- tc_int_2_fix,
- tc_real_2_fix,
- tc_fix_2_real,
- tc_proc_2_procvar,
- tc_arrayconstructor_2_set,
- tc_load_smallset,
- tc_cord_2_pointer
- );
- { allows to determine which elementes are to be replaced }
- tdisposetyp = (dt_nothing,dt_leftright,dt_left,dt_leftrighthigh,
- dt_mbleft,dt_typeconv,dt_inlinen,dt_leftrightmethod,
- dt_mbleft_and_method,dt_loop,dt_case,dt_with,dt_onn);
- { different assignment types }
- tassigntyp = (at_normal,at_plus,at_minus,at_star,at_slash);
- pcaserecord = ^tcaserecord;
- tcaserecord = record
- { range }
- _low,_high : longint;
- { only used by gentreejmp }
- _at : pasmlabel;
- { label of instruction }
- statement : pasmlabel;
- { is this the first of an case entry, needed to release statement
- label (PFV) }
- firstlabel : boolean;
- { left and right tree node }
- less,greater : pcaserecord;
- end;
- ptree = ^ttree;
- ttree = record
- error : boolean;
- disposetyp : tdisposetyp;
- { is true, if the right and left operand are swaped }
- swaped : boolean;
- { the location of the result of this node }
- location : tlocation;
- { the number of registers needed to evalute the node }
- registers32,registersfpu : longint; { must be longint !!!! }
- {$ifdef SUPPORT_MMX}
- registersmmx : longint;
- {$endif SUPPORT_MMX}
- left,right : ptree;
- resulttype : pdef;
- fileinfo : tfileposinfo;
- localswitches : tlocalswitches;
- isproperty : boolean;
- {$ifdef extdebug}
- firstpasscount : longint;
- {$endif extdebug}
- {$ifdef TEMPREGDEBUG}
- usableregs : longint;
- {$endif TEMPREGDEBUG}
- {$ifdef EXTTEMPREGDEBUG}
- reallyusedregs : longint;
- {$endif EXTTEMPREGDEBUG}
- {$ifdef TEMPS_NOT_PUSH}
- temp_offset : longint;
- {$endif TEMPS_NOT_PUSH}
- case treetype : ttreetyp of
- addn : (use_strconcat : boolean;string_typ : tstringtype);
- callparan : (is_colon_para : boolean;exact_match_found,
- convlevel1found,convlevel2found:boolean;hightree:ptree);
- assignn : (assigntyp : tassigntyp;concat_string : boolean);
- loadn : (symtableentry : psym;symtable : psymtable;
- is_absolute,is_first : boolean);
- calln : (symtableprocentry : pprocsym;
- symtableproc : psymtable;procdefinition : pabstractprocdef;
- methodpointer : ptree;
- no_check,unit_specific,
- return_value_used,static_call : boolean);
- addrn : (procvarload:boolean);
- ordconstn : (value : longint);
- realconstn : (value_real : bestreal;lab_real : pasmlabel);
- fixconstn : (value_fix: longint);
- funcretn : (funcretprocinfo : pointer;retdef : pdef;
- is_first_funcret : boolean);
- subscriptn : (vs : pvarsym);
- vecn : (memindex,memseg:boolean;callunique : boolean);
- stringconstn : (value_str : pchar;length : longint; lab_str : pasmlabel;stringtype : tstringtype);
- typeconvn : (convtyp : tconverttype;explizit : boolean);
- typen : (typenodetype : pdef;typenodesym:ptypesym);
- inlinen : (inlinenumber : byte;inlineconst:boolean);
- procinlinen : (inlinetree:ptree;inlineprocsym:pprocsym;retoffset,para_offset,para_size : longint);
- setconstn : (value_set : pconstset;lab_set:pasmlabel);
- loopn : (t1,t2 : ptree;backward : boolean);
- asmn : (p_asm : paasmoutput;object_preserved : boolean);
- casen : (nodes : pcaserecord;elseblock : ptree);
- labeln,goton : (labelnr : pasmlabel);
- withn : (withsymtable : pwithsymtable;tablecount : longint;withreference:preference;islocal:boolean);
- onn : (exceptsymtable : psymtable;excepttype : pobjectdef);
- arrayconstructn : (cargs,cargswap,forcevaria,novariaallowed: boolean;constructdef:pdef);
- end;
- function gennode(t : ttreetyp;l,r : ptree) : ptree;
- function genlabelnode(t : ttreetyp;nr : pasmlabel) : ptree;
- function genloadnode(v : pvarsym;st : psymtable) : ptree;
- function genloadcallnode(v: pprocsym;st: psymtable): ptree;
- function genloadmethodcallnode(v: pprocsym;st: psymtable; mp:ptree): ptree;
- function gensinglenode(t : ttreetyp;l : ptree) : ptree;
- function gensubscriptnode(varsym : pvarsym;l : ptree) : ptree;
- function genordinalconstnode(v : longint;def : pdef) : ptree;
- function genpointerconstnode(v : longint;def : pdef) : ptree;
- function genfixconstnode(v : longint;def : pdef) : ptree;
- function gentypeconvnode(node : ptree;t : pdef) : ptree;
- function gentypenode(t : pdef;sym:ptypesym) : ptree;
- function gencallparanode(expr,next : ptree) : ptree;
- function genrealconstnode(v : bestreal;def : pdef) : ptree;
- function gencallnode(v : pprocsym;st : psymtable) : ptree;
- function genmethodcallnode(v : pprocsym;st : psymtable;mp : ptree) : ptree;
- { allow pchar or string for defining a pchar node }
- function genstringconstnode(const s : string) : ptree;
- { length is required for ansistrings }
- function genpcharconstnode(s : pchar;length : longint) : ptree;
- { helper routine for conststring node }
- function getpcharcopy(p : ptree) : pchar;
- function genzeronode(t : ttreetyp) : ptree;
- function geninlinenode(number : byte;is_const:boolean;l : ptree) : ptree;
- function genprocinlinenode(callp,code : ptree) : ptree;
- function gentypedconstloadnode(sym : ptypedconstsym;st : psymtable) : ptree;
- function genenumnode(v : penumsym) : ptree;
- function genselfnode(_class : pdef) : ptree;
- function gensetconstnode(s : pconstset;settype : psetdef) : ptree;
- function genloopnode(t : ttreetyp;l,r,n1: ptree;back : boolean) : ptree;
- function genasmnode(p_asm : paasmoutput) : ptree;
- function gencasenode(l,r : ptree;nodes : pcaserecord) : ptree;
- function genwithnode(symtable : pwithsymtable;l,r : ptree;count : longint) : ptree;
- function getcopy(p : ptree) : ptree;
- function equal_trees(t1,t2 : ptree) : boolean;
- procedure swaptree(p:Ptree);
- procedure disposetree(p : ptree);
- procedure putnode(p : ptree);
- function getnode : ptree;
- procedure clear_location(var loc : tlocation);
- procedure set_location(var destloc,sourceloc : tlocation);
- procedure swap_location(var destloc,sourceloc : tlocation);
- procedure set_file_line(from,_to : ptree);
- procedure set_tree_filepos(p : ptree;const filepos : tfileposinfo);
- {$ifdef extdebug}
- procedure compare_trees(oldp,p : ptree);
- const
- maxfirstpasscount : longint = 0;
- {$endif extdebug}
- { sets the callunique flag, if the node is a vecn, }
- { takes care of type casts etc. }
- procedure set_unique(p : ptree);
- { sets funcret_is_valid to true, if p contains a funcref node }
- procedure set_funcret_is_valid(p : ptree);
- { gibt den ordinalen Werten der Node zurueck oder falls sie }
- { keinen ordinalen Wert hat, wird ein Fehler erzeugt }
- function get_ordinal_value(p : ptree) : longint;
- function is_constnode(p : ptree) : boolean;
- { true, if p is a pointer to a const int value }
- function is_constintnode(p : ptree) : boolean;
- function is_constboolnode(p : ptree) : boolean;
- function is_constrealnode(p : ptree) : boolean;
- function is_constcharnode(p : ptree) : boolean;
- function str_length(p : ptree) : longint;
- function is_emptyset(p : ptree):boolean;
- { counts the labels }
- function case_count_labels(root : pcaserecord) : longint;
- { searches the highest label }
- function case_get_max(root : pcaserecord) : longint;
- { searches the lowest label }
- function case_get_min(root : pcaserecord) : longint;
- type
- pptree = ^ptree;
- {$ifdef TEMPREGDEBUG}
- const
- curptree : pptree = nil;
- {$endif TEMPREGDEBUG}
- {$I innr.inc}
- implementation
- uses
- systems,
- globals,verbose,files,types,hcodegen;
- function getnode : ptree;
- var
- hp : ptree;
- begin
- new(hp);
- { makes error tracking easier }
- fillchar(hp^,sizeof(ttree),0);
- { reset }
- hp^.location.loc:=LOC_INVALID;
- { save local info }
- hp^.fileinfo:=aktfilepos;
- hp^.localswitches:=aktlocalswitches;
- getnode:=hp;
- end;
- procedure putnode(p : ptree);
- begin
- { clean up the contents of a node }
- case p^.treetype of
- asmn : if assigned(p^.p_asm) then
- dispose(p^.p_asm,done);
- stringconstn : begin
- ansistringdispose(p^.value_str,p^.length);
- end;
- setconstn : begin
- if assigned(p^.value_set) then
- dispose(p^.value_set);
- end;
- end;
- {$ifdef extdebug}
- if p^.firstpasscount>maxfirstpasscount then
- maxfirstpasscount:=p^.firstpasscount;
- {$endif extdebug}
- dispose(p);
- end;
- function getcopy(p : ptree) : ptree;
- var
- hp : ptree;
- begin
- if not assigned(p) then
- begin
- getcopy:=nil;
- exit;
- end;
- hp:=getnode;
- hp^:=p^;
- case p^.disposetyp of
- dt_leftright :
- begin
- if assigned(p^.left) then
- hp^.left:=getcopy(p^.left);
- if assigned(p^.right) then
- hp^.right:=getcopy(p^.right);
- end;
- dt_leftrighthigh :
- begin
- if assigned(p^.left) then
- hp^.left:=getcopy(p^.left);
- if assigned(p^.right) then
- hp^.right:=getcopy(p^.right);
- if assigned(p^.hightree) then
- hp^.left:=getcopy(p^.hightree);
- end;
- dt_leftrightmethod :
- begin
- if assigned(p^.left) then
- hp^.left:=getcopy(p^.left);
- if assigned(p^.right) then
- hp^.right:=getcopy(p^.right);
- if assigned(p^.methodpointer) then
- hp^.left:=getcopy(p^.methodpointer);
- end;
- dt_nothing : ;
- dt_left :
- if assigned(p^.left) then
- hp^.left:=getcopy(p^.left);
- dt_mbleft :
- if assigned(p^.left) then
- hp^.left:=getcopy(p^.left);
- dt_mbleft_and_method :
- begin
- if assigned(p^.left) then
- hp^.left:=getcopy(p^.left);
- hp^.methodpointer:=getcopy(p^.methodpointer);
- end;
- dt_loop :
- begin
- if assigned(p^.left) then
- hp^.left:=getcopy(p^.left);
- if assigned(p^.right) then
- hp^.right:=getcopy(p^.right);
- if assigned(p^.t1) then
- hp^.t1:=getcopy(p^.t1);
- if assigned(p^.t2) then
- hp^.t2:=getcopy(p^.t2);
- end;
- dt_typeconv : hp^.left:=getcopy(p^.left);
- dt_inlinen :
- if assigned(p^.left) then
- hp^.left:=getcopy(p^.left);
- else internalerror(11);
- end;
- { now check treetype }
- case p^.treetype of
- stringconstn : begin
- hp^.value_str:=getpcharcopy(p);
- hp^.length:=p^.length;
- end;
- setconstn : begin
- new(hp^.value_set);
- hp^.value_set:=p^.value_set;
- end;
- end;
- getcopy:=hp;
- end;
- procedure deletecaselabels(p : pcaserecord);
- begin
- if assigned(p^.greater) then
- deletecaselabels(p^.greater);
- if assigned(p^.less) then
- deletecaselabels(p^.less);
- freelabel(p^._at);
- if p^.firstlabel then
- freelabel(p^.statement);
- dispose(p);
- end;
- procedure swaptree(p:Ptree);
- var swapp:Ptree;
- begin
- swapp:=p^.right;
- p^.right:=p^.left;
- p^.left:=swapp;
- p^.swaped:=not(p^.swaped);
- end;
- procedure disposetree(p : ptree);
- var
- symt : pwithsymtable;
- i : longint;
- begin
- if not(assigned(p)) then
- exit;
- if not(p^.treetype in [addn..loadvmtn]) then
- internalerror(26219);
- case p^.disposetyp of
- dt_leftright :
- begin
- if assigned(p^.left) then
- disposetree(p^.left);
- if assigned(p^.right) then
- disposetree(p^.right);
- end;
- dt_leftrighthigh :
- begin
- if assigned(p^.left) then
- disposetree(p^.left);
- if assigned(p^.right) then
- disposetree(p^.right);
- if assigned(p^.hightree) then
- disposetree(p^.hightree);
- end;
- dt_leftrightmethod :
- begin
- if assigned(p^.left) then
- disposetree(p^.left);
- if assigned(p^.right) then
- disposetree(p^.right);
- if assigned(p^.methodpointer) then
- disposetree(p^.methodpointer);
- end;
- dt_case :
- begin
- if assigned(p^.left) then
- disposetree(p^.left);
- if assigned(p^.right) then
- disposetree(p^.right);
- if assigned(p^.nodes) then
- deletecaselabels(p^.nodes);
- if assigned(p^.elseblock) then
- disposetree(p^.elseblock);
- end;
- dt_nothing : ;
- dt_left :
- if assigned(p^.left) then
- disposetree(p^.left);
- dt_mbleft :
- if assigned(p^.left) then
- disposetree(p^.left);
- dt_mbleft_and_method :
- begin
- if assigned(p^.left) then disposetree(p^.left);
- disposetree(p^.methodpointer);
- end;
- dt_typeconv : disposetree(p^.left);
- dt_inlinen :
- if assigned(p^.left) then
- disposetree(p^.left);
- dt_loop :
- begin
- if assigned(p^.left) then
- disposetree(p^.left);
- if assigned(p^.right) then
- disposetree(p^.right);
- if assigned(p^.t1) then
- disposetree(p^.t1);
- if assigned(p^.t2) then
- disposetree(p^.t2);
- end;
- dt_onn:
- begin
- if assigned(p^.left) then
- disposetree(p^.left);
- if assigned(p^.right) then
- disposetree(p^.right);
- if assigned(p^.exceptsymtable) then
- dispose(p^.exceptsymtable,done);
- end;
- dt_with :
- begin
- if assigned(p^.left) then
- disposetree(p^.left);
- if assigned(p^.right) then
- disposetree(p^.right);
- symt:=p^.withsymtable;
- for i:=1 to p^.tablecount do
- begin
- if assigned(symt) then
- begin
- p^.withsymtable:=pwithsymtable(symt^.next);
- dispose(symt,done);
- end;
- symt:=p^.withsymtable;
- end;
- end;
- else internalerror(12);
- end;
- putnode(p);
- end;
- procedure set_file_line(from,_to : ptree);
- begin
- if assigned(from) then
- _to^.fileinfo:=from^.fileinfo;
- end;
- procedure set_tree_filepos(p : ptree;const filepos : tfileposinfo);
- begin
- p^.fileinfo:=filepos;
- end;
- function genwithnode(symtable : pwithsymtable;l,r : ptree;count : longint) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_with;
- p^.treetype:=withn;
- p^.left:=l;
- p^.right:=r;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=nil;
- p^.withsymtable:=symtable;
- p^.tablecount:=count;
- p^.withreference:=nil;
- p^.islocal:=false;
- set_file_line(l,p);
- genwithnode:=p;
- end;
- function genfixconstnode(v : longint;def : pdef) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=fixconstn;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=def;
- p^.value:=v;
- genfixconstnode:=p;
- end;
- function gencallparanode(expr,next : ptree) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_leftrighthigh;
- p^.treetype:=callparan;
- p^.left:=expr;
- p^.right:=next;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.registersfpu:=0;
- p^.resulttype:=nil;
- p^.exact_match_found:=false;
- p^.convlevel1found:=false;
- p^.convlevel2found:=false;
- p^.is_colon_para:=false;
- p^.hightree:=nil;
- set_file_line(expr,p);
- gencallparanode:=p;
- end;
- function gennode(t : ttreetyp;l,r : ptree) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_leftright;
- p^.treetype:=t;
- p^.left:=l;
- p^.right:=r;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=nil;
- gennode:=p;
- end;
- function gencasenode(l,r : ptree;nodes : pcaserecord) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_case;
- p^.treetype:=casen;
- p^.left:=l;
- p^.right:=r;
- p^.nodes:=nodes;
- p^.registers32:=0;
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=nil;
- set_file_line(l,p);
- gencasenode:=p;
- end;
- function genloopnode(t : ttreetyp;l,r,n1 : ptree;back : boolean) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_loop;
- p^.treetype:=t;
- p^.left:=l;
- p^.right:=r;
- p^.t1:=n1;
- p^.t2:=nil;
- p^.registers32:=0;
- p^.backward:=back;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=nil;
- set_file_line(l,p);
- genloopnode:=p;
- end;
- function genordinalconstnode(v : longint;def : pdef) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=ordconstn;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=def;
- p^.value:=v;
- if p^.resulttype^.deftype=orddef then
- testrange(p^.resulttype,p^.value);
- genordinalconstnode:=p;
- end;
- function genpointerconstnode(v : longint;def : pdef) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=pointerconstn;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=def;
- p^.value:=v;
- genpointerconstnode:=p;
- end;
- function genenumnode(v : penumsym) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=ordconstn;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=v^.definition;
- p^.value:=v^.value;
- testrange(p^.resulttype,p^.value);
- genenumnode:=p;
- end;
- function genrealconstnode(v : bestreal;def : pdef) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=realconstn;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=def;
- p^.value_real:=v;
- p^.lab_real:=nil;
- genrealconstnode:=p;
- end;
- function genstringconstnode(const s : string) : ptree;
- var
- p : ptree;
- l : longint;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=stringconstn;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- l:=length(s);
- p^.length:=l;
- { stringdup write even past a #0 }
- getmem(p^.value_str,l+1);
- move(s[1],p^.value_str^,l);
- p^.value_str[l]:=#0;
- p^.lab_str:=nil;
- if cs_ansistrings in aktlocalswitches then
- begin
- p^.stringtype:=st_ansistring;
- p^.resulttype:=cansistringdef;
- end
- else
- begin
- p^.stringtype:=st_shortstring;
- p^.resulttype:=cshortstringdef;
- end;
- genstringconstnode:=p;
- end;
- function getpcharcopy(p : ptree) : pchar;
- var
- pc : pchar;
- begin
- pc:=nil;
- getmem(pc,p^.length+1);
- if pc=nil then
- Message(general_f_no_memory_left);
- move(p^.value_str^,pc^,p^.length+1);
- getpcharcopy:=pc;
- end;
- function genpcharconstnode(s : pchar;length : longint) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=stringconstn;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.length:=length;
- if (cs_ansistrings in aktlocalswitches) or
- (length>255) then
- begin
- p^.stringtype:=st_ansistring;
- p^.resulttype:=cansistringdef;
- end
- else
- begin
- p^.stringtype:=st_shortstring;
- p^.resulttype:=cshortstringdef;
- end;
- p^.value_str:=s;
- p^.lab_str:=nil;
- genpcharconstnode:=p;
- end;
- function gensinglenode(t : ttreetyp;l : ptree) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_left;
- p^.treetype:=t;
- p^.left:=l;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=nil;
- gensinglenode:=p;
- end;
- function genasmnode(p_asm : paasmoutput) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=asmn;
- p^.registers32:=4;
- p^.p_asm:=p_asm;
- p^.object_preserved:=false;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=8;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=8;
- {$endif SUPPORT_MMX}
- p^.resulttype:=nil;
- genasmnode:=p;
- end;
- function genloadnode(v : pvarsym;st : psymtable) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.treetype:=loadn;
- p^.resulttype:=v^.definition;
- p^.symtableentry:=v;
- p^.symtable:=st;
- p^.is_first := False;
- { method pointer load nodes can use the left subtree }
- p^.disposetyp:=dt_left;
- p^.left:=nil;
- genloadnode:=p;
- end;
- function genloadcallnode(v: pprocsym;st: psymtable): ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.treetype:=loadn;
- p^.left:=nil;
- p^.resulttype:=v^.definition;
- p^.symtableentry:=v;
- p^.symtable:=st;
- p^.is_first := False;
- p^.disposetyp:=dt_nothing;
- genloadcallnode:=p;
- end;
- function genloadmethodcallnode(v: pprocsym;st: psymtable; mp:ptree): ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.treetype:=loadn;
- p^.left:=nil;
- p^.resulttype:=v^.definition;
- p^.symtableentry:=v;
- p^.symtable:=st;
- p^.is_first := False;
- p^.disposetyp:=dt_left;
- p^.left:=mp;
- genloadmethodcallnode:=p;
- end;
- function gentypedconstloadnode(sym : ptypedconstsym;st : psymtable) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.treetype:=loadn;
- p^.left:=nil;
- p^.resulttype:=sym^.definition;
- p^.symtableentry:=sym;
- p^.symtable:=st;
- p^.disposetyp:=dt_nothing;
- gentypedconstloadnode:=p;
- end;
- function gentypeconvnode(node : ptree;t : pdef) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_typeconv;
- p^.treetype:=typeconvn;
- p^.left:=node;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.convtyp:=tc_equal;
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=t;
- p^.explizit:=false;
- set_file_line(node,p);
- gentypeconvnode:=p;
- end;
- function gentypenode(t : pdef;sym:ptypesym) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=typen;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=generrordef;
- p^.typenodetype:=t;
- p^.typenodesym:=sym;
- gentypenode:=p;
- end;
- function gencallnode(v : pprocsym;st : psymtable) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.treetype:=calln;
- p^.symtableprocentry:=v;
- p^.symtableproc:=st;
- p^.unit_specific:=false;
- p^.no_check:=false;
- p^.return_value_used:=true;
- p^.disposetyp := dt_leftrightmethod;
- p^.methodpointer:=nil;
- p^.left:=nil;
- p^.right:=nil;
- p^.procdefinition:=nil;
- gencallnode:=p;
- end;
- function genmethodcallnode(v : pprocsym;st : psymtable;mp : ptree) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.treetype:=calln;
- p^.return_value_used:=true;
- p^.symtableprocentry:=v;
- p^.symtableproc:=st;
- p^.disposetyp:=dt_leftrightmethod;
- p^.left:=nil;
- p^.right:=nil;
- p^.methodpointer:=mp;
- p^.procdefinition:=nil;
- genmethodcallnode:=p;
- end;
- function gensubscriptnode(varsym : pvarsym;l : ptree) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_left;
- p^.treetype:=subscriptn;
- p^.left:=l;
- p^.registers32:=0;
- p^.vs:=varsym;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=nil;
- gensubscriptnode:=p;
- end;
- function genzeronode(t : ttreetyp) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=t;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=nil;
- genzeronode:=p;
- end;
- function genlabelnode(t : ttreetyp;nr : pasmlabel) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=t;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=nil;
- { for security }
- { nr^.is_used:=true;}
- p^.labelnr:=nr;
- genlabelnode:=p;
- end;
- function genselfnode(_class : pdef) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=selfn;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=_class;
- genselfnode:=p;
- end;
- function geninlinenode(number : byte;is_const:boolean;l : ptree) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_inlinen;
- p^.treetype:=inlinen;
- p^.left:=l;
- p^.inlinenumber:=number;
- p^.inlineconst:=is_const;
- p^.registers32:=0;
- { p^.registers16:=0;
- p^.registers8:=0; }
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=nil;
- geninlinenode:=p;
- end;
- { uses the callnode to create the new procinline node }
- function genprocinlinenode(callp,code : ptree) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=procinlinen;
- p^.inlineprocsym:=callp^.symtableprocentry;
- p^.retoffset:=-4; { less dangerous as zero (PM) }
- p^.para_offset:=0;
- p^.para_size:=p^.inlineprocsym^.definition^.para_size;
- if ret_in_param(p^.inlineprocsym^.definition^.retdef) then
- p^.para_size:=p^.para_size+target_os.size_of_pointer;
- { copy args }
- p^.inlinetree:=code;
- p^.registers32:=code^.registers32;
- p^.registersfpu:=code^.registersfpu;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=p^.inlineprocsym^.definition^.retdef;
- genprocinlinenode:=p;
- end;
- function gensetconstnode(s : pconstset;settype : psetdef) : ptree;
- var
- p : ptree;
- begin
- p:=getnode;
- p^.disposetyp:=dt_nothing;
- p^.treetype:=setconstn;
- p^.registers32:=0;
- p^.registersfpu:=0;
- {$ifdef SUPPORT_MMX}
- p^.registersmmx:=0;
- {$endif SUPPORT_MMX}
- p^.resulttype:=settype;
- p^.left:=nil;
- new(p^.value_set);
- p^.value_set^:=s^;
- gensetconstnode:=p;
- end;
- {$ifdef extdebug}
- procedure compare_trees(oldp,p : ptree);
- var
- error_found : boolean;
- begin
- if oldp^.resulttype<>p^.resulttype then
- begin
- error_found:=true;
- if is_equal(oldp^.resulttype,p^.resulttype) then
- comment(v_debug,'resulttype fields are different but equal')
- else
- comment(v_warning,'resulttype fields are really different');
- end;
- if oldp^.treetype<>p^.treetype then
- begin
- comment(v_warning,'treetype field different');
- error_found:=true;
- end
- else
- comment(v_debug,' treetype '+tostr(longint(oldp^.treetype)));
- if oldp^.error<>p^.error then
- begin
- comment(v_warning,'error field different');
- error_found:=true;
- end;
- if oldp^.disposetyp<>p^.disposetyp then
- begin
- comment(v_warning,'disposetyp field different');
- error_found:=true;
- end;
- { is true, if the right and left operand are swaped }
- if oldp^.swaped<>p^.swaped then
- begin
- comment(v_warning,'swaped field different');
- error_found:=true;
- end;
- { the location of the result of this node }
- if oldp^.location.loc<>p^.location.loc then
- begin
- comment(v_warning,'location.loc field different');
- error_found:=true;
- end;
- { the number of registers needed to evalute the node }
- if oldp^.registers32<>p^.registers32 then
- begin
- comment(v_warning,'registers32 field different');
- comment(v_warning,' old '+tostr(oldp^.registers32)+'<> new '+tostr(p^.registers32));
- error_found:=true;
- end;
- if oldp^.registersfpu<>p^.registersfpu then
- begin
- comment(v_warning,'registersfpu field different');
- error_found:=true;
- end;
- {$ifdef SUPPORT_MMX}
- if oldp^.registersmmx<>p^.registersmmx then
- begin
- comment(v_warning,'registersmmx field different');
- error_found:=true;
- end;
- {$endif SUPPORT_MMX}
- if oldp^.left<>p^.left then
- begin
- comment(v_warning,'left field different');
- error_found:=true;
- end;
- if oldp^.right<>p^.right then
- begin
- comment(v_warning,'right field different');
- error_found:=true;
- end;
- if oldp^.fileinfo.line<>p^.fileinfo.line then
- begin
- comment(v_warning,'fileinfo.line field different');
- error_found:=true;
- end;
- if oldp^.fileinfo.column<>p^.fileinfo.column then
- begin
- comment(v_warning,'fileinfo.column field different');
- error_found:=true;
- end;
- if oldp^.fileinfo.fileindex<>p^.fileinfo.fileindex then
- begin
- comment(v_warning,'fileinfo.fileindex field different');
- error_found:=true;
- end;
- if oldp^.localswitches<>p^.localswitches then
- begin
- comment(v_warning,'localswitches field different');
- error_found:=true;
- end;
- {$ifdef extdebug}
- if oldp^.firstpasscount<>p^.firstpasscount then
- begin
- comment(v_warning,'firstpasscount field different');
- error_found:=true;
- end;
- {$endif extdebug}
- if oldp^.treetype=p^.treetype then
- case oldp^.treetype of
- addn :
- begin
- if oldp^.use_strconcat<>p^.use_strconcat then
- begin
- comment(v_warning,'use_strconcat field different');
- error_found:=true;
- end;
- if oldp^.string_typ<>p^.string_typ then
- begin
- comment(v_warning,'stringtyp field different');
- error_found:=true;
- end;
- end;
- callparan :
- {(is_colon_para : boolean;exact_match_found : boolean);}
- begin
- if oldp^.is_colon_para<>p^.is_colon_para then
- begin
- comment(v_warning,'use_strconcat field different');
- error_found:=true;
- end;
- if oldp^.exact_match_found<>p^.exact_match_found then
- begin
- comment(v_warning,'exact_match_found field different');
- error_found:=true;
- end;
- end;
- assignn :
- {(assigntyp : tassigntyp;concat_string : boolean);}
- begin
- if oldp^.assigntyp<>p^.assigntyp then
- begin
- comment(v_warning,'assigntyp field different');
- error_found:=true;
- end;
- if oldp^.concat_string<>p^.concat_string then
- begin
- comment(v_warning,'concat_string field different');
- error_found:=true;
- end;
- end;
- loadn :
- {(symtableentry : psym;symtable : psymtable;
- is_absolute,is_first : boolean);}
- begin
- if oldp^.symtableentry<>p^.symtableentry then
- begin
- comment(v_warning,'symtableentry field different');
- error_found:=true;
- end;
- if oldp^.symtable<>p^.symtable then
- begin
- comment(v_warning,'symtable field different');
- error_found:=true;
- end;
- if oldp^.is_absolute<>p^.is_absolute then
- begin
- comment(v_warning,'is_absolute field different');
- error_found:=true;
- end;
- if oldp^.is_first<>p^.is_first then
- begin
- comment(v_warning,'is_first field different');
- error_found:=true;
- end;
- end;
- calln :
- {(symtableprocentry : pprocsym;
- symtableproc : psymtable;procdefinition : pprocdef;
- methodpointer : ptree;
- no_check,unit_specific : boolean);}
- begin
- if oldp^.symtableprocentry<>p^.symtableprocentry then
- begin
- comment(v_warning,'symtableprocentry field different');
- error_found:=true;
- end;
- if oldp^.symtableproc<>p^.symtableproc then
- begin
- comment(v_warning,'symtableproc field different');
- error_found:=true;
- end;
- if oldp^.procdefinition<>p^.procdefinition then
- begin
- comment(v_warning,'procdefinition field different');
- error_found:=true;
- end;
- if oldp^.methodpointer<>p^.methodpointer then
- begin
- comment(v_warning,'methodpointer field different');
- error_found:=true;
- end;
- if oldp^.no_check<>p^.no_check then
- begin
- comment(v_warning,'no_check field different');
- error_found:=true;
- end;
- if oldp^.unit_specific<>p^.unit_specific then
- begin
- error_found:=true;
- comment(v_warning,'unit_specific field different');
- end;
- end;
- ordconstn :
- begin
- if oldp^.value<>p^.value then
- begin
- comment(v_warning,'value field different');
- error_found:=true;
- end;
- end;
- realconstn :
- begin
- if oldp^.value_real<>p^.value_real then
- begin
- comment(v_warning,'valued field different');
- error_found:=true;
- end;
- if oldp^.lab_real<>p^.lab_real then
- begin
- comment(v_warning,'labnumber field different');
- error_found:=true;
- end;
- { if oldp^.realtyp<>p^.realtyp then
- begin
- comment(v_warning,'realtyp field different');
- error_found:=true;
- end; }
- end;
- end;
- if not error_found then
- comment(v_warning,'did not find difference in trees');
- end;
- {$endif extdebug}
- function equal_trees(t1,t2 : ptree) : boolean;
- begin
- if t1^.treetype=t2^.treetype then
- begin
- case t1^.treetype of
- addn,
- muln,
- equaln,
- orn,
- xorn,
- andn,
- unequaln:
- begin
- equal_trees:=(equal_trees(t1^.left,t2^.left) and
- equal_trees(t1^.right,t2^.right)) or
- (equal_trees(t1^.right,t2^.left) and
- equal_trees(t1^.left,t2^.right));
- end;
- subn,
- divn,
- modn,
- assignn,
- ltn,
- lten,
- gtn,
- gten,
- inn,
- shrn,
- shln,
- slashn,
- rangen:
- begin
- equal_trees:=(equal_trees(t1^.left,t2^.left) and
- equal_trees(t1^.right,t2^.right));
- end;
- umminusn,
- notn,
- derefn,
- addrn:
- begin
- equal_trees:=(equal_trees(t1^.left,t2^.left));
- end;
- loadn:
- begin
- equal_trees:=(t1^.symtableentry=t2^.symtableentry)
- { not necessary
- and (t1^.symtable=t2^.symtable)};
- end;
- {
- subscriptn,
- ordconstn,typeconvn,calln,callparan,
- realconstn,asmn,vecn,
- stringconstn,funcretn,selfn,
- inlinen,niln,errorn,
- typen,hnewn,hdisposen,newn,
- disposen,setelen,setconstrn
- }
- else equal_trees:=false;
- end;
- end
- else
- equal_trees:=false;
- end;
- procedure set_unique(p : ptree);
- begin
- if assigned(p) then
- begin
- case p^.treetype of
- vecn:
- p^.callunique:=true;
- typeconvn,subscriptn,derefn:
- set_unique(p^.left);
- end;
- end;
- end;
- procedure set_funcret_is_valid(p : ptree);
- begin
- if assigned(p) then
- begin
- case p^.treetype of
- funcretn:
- begin
- if p^.is_first_funcret then
- pprocinfo(p^.funcretprocinfo)^.funcret_state:=vs_assigned;
- end;
- vecn,typeconvn,subscriptn,derefn:
- set_funcret_is_valid(p^.left);
- end;
- end;
- end;
- procedure clear_location(var loc : tlocation);
- begin
- loc.loc:=LOC_INVALID;
- end;
- {This is needed if you want to be able to delete the string with the nodes !!}
- procedure set_location(var destloc,sourceloc : tlocation);
- begin
- destloc:= sourceloc;
- end;
- procedure swap_location(var destloc,sourceloc : tlocation);
- var
- swapl : tlocation;
- begin
- swapl := destloc;
- destloc := sourceloc;
- sourceloc := swapl;
- end;
- function get_ordinal_value(p : ptree) : longint;
- begin
- if p^.treetype=ordconstn then
- get_ordinal_value:=p^.value
- else
- begin
- Message(type_e_ordinal_expr_expected);
- get_ordinal_value:=0;
- end;
- end;
- function is_constnode(p : ptree) : boolean;
- begin
- is_constnode:=(p^.treetype in [ordconstn,realconstn,stringconstn,fixconstn,setconstn]);
- end;
- function is_constintnode(p : ptree) : boolean;
- begin
- is_constintnode:=(p^.treetype=ordconstn) and is_integer(p^.resulttype);
- end;
- function is_constcharnode(p : ptree) : boolean;
- begin
- is_constcharnode:=(p^.treetype=ordconstn) and is_char(p^.resulttype);
- end;
- function is_constrealnode(p : ptree) : boolean;
- begin
- is_constrealnode:=(p^.treetype=realconstn);
- end;
- function is_constboolnode(p : ptree) : boolean;
- begin
- is_constboolnode:=(p^.treetype=ordconstn) and is_boolean(p^.resulttype);
- end;
- function str_length(p : ptree) : longint;
- begin
- str_length:=p^.length;
- end;
- function is_emptyset(p : ptree):boolean;
- {
- return true if set s is empty
- }
- var
- i : longint;
- begin
- i:=0;
- if p^.treetype=setconstn then
- begin
- while (i<32) and (p^.value_set^[i]=0) do
- inc(i);
- end;
- is_emptyset:=(i=32);
- end;
- {*****************************************************************************
- Case Helpers
- *****************************************************************************}
- function case_count_labels(root : pcaserecord) : longint;
- var
- _l : longint;
- procedure count(p : pcaserecord);
- begin
- inc(_l);
- if assigned(p^.less) then
- count(p^.less);
- if assigned(p^.greater) then
- count(p^.greater);
- end;
- begin
- _l:=0;
- count(root);
- case_count_labels:=_l;
- end;
- function case_get_max(root : pcaserecord) : longint;
- var
- hp : pcaserecord;
- begin
- hp:=root;
- while assigned(hp^.greater) do
- hp:=hp^.greater;
- case_get_max:=hp^._high;
- end;
- function case_get_min(root : pcaserecord) : longint;
- var
- hp : pcaserecord;
- begin
- hp:=root;
- while assigned(hp^.less) do
- hp:=hp^.less;
- case_get_min:=hp^._low;
- end;
- end.
- {
- $Log$
- Revision 1.102 1999-11-17 17:05:07 pierre
- * Notes/hints changes
- Revision 1.101 1999/11/06 14:34:31 peter
- * truncated log to 20 revs
- Revision 1.100 1999/10/22 14:37:31 peter
- * error when properties are passed to var parameters
- Revision 1.99 1999/09/27 23:45:03 peter
- * procinfo is now a pointer
- * support for result setting in sub procedure
- Revision 1.98 1999/09/26 21:30:22 peter
- + constant pointer support which can happend with typecasting like
- const p=pointer(1)
- * better procvar parsing in typed consts
- Revision 1.97 1999/09/17 17:14:13 peter
- * @procvar fixes for tp mode
- * @<id>:= gives now an error
- Revision 1.96 1999/09/16 11:34:59 pierre
- * typo correction
- Revision 1.95 1999/09/10 18:48:11 florian
- * some bug fixes (e.g. must_be_valid and procinfo^.funcret_is_valid)
- * most things for stored properties fixed
- Revision 1.94 1999/09/07 07:52:20 peter
- * > < >= <= support for boolean
- * boolean constants are now calculated like integer constants
- Revision 1.93 1999/08/27 10:38:31 pierre
- + EXTTEMPREGDEBUG code added
- Revision 1.92 1999/08/26 21:10:08 peter
- * better error recovery for case
- Revision 1.91 1999/08/23 23:26:00 pierre
- + TEMPREGDEBUG code, test of register allocation
- if a tree uses more than registers32 regs then
- internalerror(10) is issued
- + EXTTEMPREGDEBUG will also give internalerror(10) if
- a same register is freed twice (happens in several part
- of current compiler like addn for strings and sets)
- Revision 1.90 1999/08/17 13:26:09 peter
- * arrayconstructor -> arrayofconst fixed when arraycosntructor was not
- variant.
- Revision 1.89 1999/08/16 23:23:42 peter
- * arrayconstructor -> openarray type conversions for element types
- Revision 1.88 1999/08/13 21:33:18 peter
- * support for array constructors extended and more error checking
- Revision 1.87 1999/08/09 22:14:46 peter
- * fixed disposing of tree node
- Revision 1.86 1999/08/04 00:23:49 florian
- * renamed i386asm and i386base to cpuasm and cpubase
- Revision 1.85 1999/08/03 22:03:40 peter
- * moved bitmask constants to sets
- * some other type/const renamings
- Revision 1.84 1999/07/27 23:42:24 peter
- * indirect type referencing is now allowed
- Revision 1.83 1999/05/27 19:45:29 peter
- * removed oldasm
- * plabel -> pasmlabel
- * -a switches to source writing automaticly
- * assembler readers OOPed
- * asmsymbol automaticly external
- * jumptables and other label fixes for asm readers
- Revision 1.82 1999/05/18 14:15:59 peter
- * containsself fixes
- * checktypes()
- Revision 1.81 1999/05/18 09:52:22 peter
- * procedure of object and addrn fixes
- }
|