1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993 |
- {
- $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.}
- unaryminusn, {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;
- { do we need to parse childs to set var state }
- varstateset : 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;rettype : ttype;
- 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);
- {
- type
- tvarstaterequire = (vsr_can_be_undefined,vsr_must_be_valid,
- vsr_is_used_after,vsr_must_be_valid_and_is_used_after); }
- { sets varsym varstate field correctly }
- procedure set_varstate(p : ptree;must_be_valid : boolean);
- { 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^.vartype.def;
- 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^.typedconsttype.def;
- 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^.rettype.def) 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^.rettype.def;
- 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;
- unaryminusn,
- 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 set_varstate(p : ptree;must_be_valid : boolean);
- begin
- if not assigned(p) then
- exit
- else
- begin
- if p^.varstateset then
- exit;
- case p^.treetype of
- typeconvn,subscriptn :
- set_varstate(p^.left,must_be_valid);
- vecn:
- begin
- if (p^.left^.resulttype^.deftype in [stringdef,arraydef]) then
- set_varstate(p^.left,must_be_valid)
- else
- set_varstate(p^.left,true);
- set_varstate(p^.right,true);
- end;
- { do not parse calln }
- calln : ;
- callparan:
- begin
- set_varstate(p^.left,must_be_valid);
- set_varstate(p^.right,must_be_valid);
- end;
- loadn :
- if (p^.symtableentry^.typ=varsym) then
- begin
- if must_be_valid and p^.is_first then
- begin
- if (pvarsym(p^.symtableentry)^.varstate=vs_declared_and_first_found) or
- (pvarsym(p^.symtableentry)^.varstate=vs_set_but_first_not_passed) then
- if (assigned(pvarsym(p^.symtableentry)^.owner) and
- assigned(aktprocsym) and
- (pvarsym(p^.symtableentry)^.owner = aktprocsym^.definition^.localst)) then
- begin
- if p^.symtable^.symtabletype=localsymtable then
- CGMessage1(sym_n_uninitialized_local_variable,pvarsym(p^.symtableentry)^.name)
- else
- CGMessage1(sym_n_uninitialized_variable,pvarsym(p^.symtableentry)^.name);
- end;
- end;
- if (p^.is_first) then
- begin
- if pvarsym(p^.symtableentry)^.varstate=vs_declared_and_first_found then
- { this can only happen at left of an assignment, no ? PM }
- if (parsing_para_level=0) and not must_be_valid then
- pvarsym(p^.symtableentry)^.varstate:=vs_assigned
- else
- pvarsym(p^.symtableentry)^.varstate:=vs_used;
- if pvarsym(p^.symtableentry)^.varstate=vs_set_but_first_not_passed then
- pvarsym(p^.symtableentry)^.varstate:=vs_used;
- p^.is_first:=false;
- end
- else
- begin
- if (pvarsym(p^.symtableentry)^.varstate=vs_assigned) and
- (must_be_valid or (parsing_para_level>0) or
- (p^.resulttype^.deftype=procvardef)) then
- pvarsym(p^.symtableentry)^.varstate:=vs_used;
- if (pvarsym(p^.symtableentry)^.varstate=vs_declared_and_first_found) and
- (must_be_valid or (parsing_para_level>0) or
- (p^.resulttype^.deftype=procvardef)) then
- pvarsym(p^.symtableentry)^.varstate:=vs_set_but_first_not_passed;
- end;
- end;
- funcretn:
- begin
- { no claim if setting higher return value_str }
- if must_be_valid and
- (procinfo=pprocinfo(p^.funcretprocinfo)) and
- ((procinfo^.funcret_state=vs_declared) or
- ((p^.is_first_funcret) and
- (procinfo^.funcret_state=vs_declared_and_first_found))) then
- begin
- CGMessage(sym_w_function_result_not_set);
- { avoid multiple warnings }
- procinfo^.funcret_state:=vs_assigned;
- end;
- if p^.is_first_funcret and not must_be_valid then
- pprocinfo(p^.funcretprocinfo)^.funcret_state:=vs_assigned;
- end;
- else
- begin
- {internalerror(565656);}
- end;
- end;{case }
- p^.varstateset:=true;
- 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.104 1999-11-30 10:40:59 peter
- + ttype, tsymlist
- Revision 1.103 1999/11/18 15:34:51 pierre
- * Notes/Hints for local syms changed to
- Set_varstate function
- 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
- }
|