12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084 |
- {
- $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,symtable,aasm
- {$ifdef i386}
- ,i386base
- {$endif}
- {$ifdef m68k}
- ,m68k
- {$endif}
- {$ifdef alpha}
- ,alpha
- {$endif}
- ;
- 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.}
- 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
- );
- { 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_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;
- {$ifdef extdebug}
- firstpasscount : longint;
- {$endif extdebug}
- {$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);
- ordconstn : (value : longint);
- realconstn : (value_real : bestreal;lab_real : pasmlabel);
- fixconstn : (value_fix: longint);
- funcretn : (funcretprocinfo : pointer;retdef : pdef);
- 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);
- 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: boolean);
- 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 genfixconstnode(v : longint;def : pdef) : ptree;
- function gentypeconvnode(node : ptree;t : pdef) : ptree;
- function gentypenode(t : pdef) : 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);
- { 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;
- {$I innr.inc}
- implementation
- uses
- systems,
- globals,verbose,files,types;
- 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_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_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 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) : 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;
- 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_leftright;
- 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_mbleft_and_method;
- 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:
- set_unique(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
- Message(type_e_ordinal_expr_expected);
- 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
- (p^.resulttype^.deftype=orddef) and
- (porddef(p^.resulttype)^.typ=uchar));
- 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
- (p^.resulttype^.deftype=orddef) and
- (porddef(p^.resulttype)^.typ in [bool8bit,bool16bit,bool32bit]));
- 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.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
- Revision 1.80 1999/05/17 23:51:48 peter
- * with temp vars now use a reference with a persistant temp instead
- of setting datasize
- Revision 1.79 1999/05/17 13:00:36 pierre
- * old field suppressed was still in debug code
- Revision 1.78 1999/05/12 00:20:03 peter
- * removed R_DEFAULT_SEG
- * uniform float names
- Revision 1.77 1999/05/06 09:05:39 peter
- * generic write_float and str_float
- * fixed constant float conversions
- Revision 1.76 1999/05/04 14:27:04 pierre
- * avoid RTE220 in gentypedconstloadnode
- Revision 1.75 1999/05/01 13:25:02 peter
- * merged nasm compiler
- * old asm moved to oldasm/
- Revision 1.74 1999/04/21 21:45:31 pierre
- * wrong log fro v1.73 corrected
- Revision 1.73 1999/04/21 16:31:49 pierre
- + offset field for temp storage added $ifdef TEMPS_NOT_PUSH
- Revision 1.72 1999/04/15 09:01:35 peter
- * fixed set loading
- * object inheritance support for browser
- Revision 1.71 1999/03/31 13:55:28 peter
- * assembler inlining working for ag386bin
- Revision 1.70 1999/03/26 00:05:49 peter
- * released valintern
- + deffile is now removed when compiling is finished
- * ^( compiles now correct
- + static directive
- * shrd fixed
- Revision 1.69 1999/03/24 23:17:41 peter
- * fixed bugs 212,222,225,227,229,231,233
- Revision 1.68 1999/03/02 18:24:25 peter
- * fixed overloading of array of char
- Revision 1.67 1999/02/25 21:02:56 peter
- * ag386bin updates
- + coff writer
- Revision 1.66 1999/02/22 02:15:59 peter
- * updates for ag386bin
- Revision 1.65 1999/02/11 09:46:31 pierre
- * fix for normal method calls inside static methods :
- WARNING there were both parser and codegen errors !!
- added static_call boolean to calln tree
- Revision 1.64 1999/01/27 12:57:22 pierre
- * memory leaks with hightree solved by adding a new disposetyp
- dt_leftrighthigh
- Revision 1.63 1999/01/27 00:14:00 florian
- * "procedure of object"-stuff fixed
- Revision 1.62 1999/01/21 22:10:52 peter
- * fixed array of const
- * generic platform independent high() support
- Revision 1.61 1999/01/21 16:41:09 pierre
- * fix for constructor inside with statements
- Revision 1.60 1998/12/15 11:52:19 peter
- * fixed dup release of statement label in case
- Revision 1.59 1998/12/15 10:23:32 peter
- + -iSO, -iSP, -iTO, -iTP
- Revision 1.58 1998/12/11 00:04:02 peter
- + globtype,tokens,version unit splitted from globals
- Revision 1.57 1998/12/04 10:18:13 florian
- * some stuff for procedures of object added
- * bug with overridden virtual constructors fixed (reported by Italo Gomes)
- Revision 1.56 1998/12/02 16:23:32 jonas
- * changed "if longintvar in set" to case or "if () or () .." statements
- * tree.pas: changed inlinenumber (and associated constructor/vars) to a byte
- Revision 1.55 1998/11/29 12:40:20 peter
- * newcnv -> not oldcnv
- Revision 1.54 1998/11/26 13:10:44 peter
- * new int - int conversion -dNEWCNV
- * some function renamings
- Revision 1.53 1998/11/24 12:52:42 peter
- * sets are not written twice anymore
- * optimize for emptyset+single element which uses a new routine from
- set.inc FPC_SET_CREATE_ELEMENT
- Revision 1.52 1998/11/23 17:51:58 pierre
- * added checking before dispose of reference string
- Revision 1.51 1998/11/13 10:15:53 peter
- * fixed ptr() with constants
- Revision 1.50 1998/11/10 10:09:20 peter
- * va_list -> array of const
- Revision 1.49 1998/11/05 12:03:07 peter
- * released useansistring
- * removed -Sv, its now available in fpc modes
- Revision 1.48 1998/10/21 15:12:59 pierre
- * bug fix for IOCHECK inside a procedure with iocheck modifier
- * removed the GPF for unexistant overloading
- (firstcall was called with procedinition=nil !)
- * changed typen to what Florian proposed
- gentypenode(p : pdef) sets the typenodetype field
- and resulttype is only set if inside bt_type block !
- Revision 1.47 1998/10/20 08:07:07 pierre
- * several memory corruptions due to double freemem solved
- => never use p^.loc.location:=p^.left^.loc.location;
- + finally I added now by default
- that ra386dir translates global and unit symbols
- + added a first field in tsymtable and
- a nextsym field in tsym
- (this allows to obtain ordered type info for
- records and objects in gdb !)
- Revision 1.46 1998/10/08 17:17:37 pierre
- * current_module old scanner tagged as invalid if unit is recompiled
- + added ppheap for better info on tracegetmem of heaptrc
- (adds line column and file index)
- * several memory leaks removed ith help of heaptrc !!
- Revision 1.45 1998/10/05 21:33:33 peter
- * fixed 161,165,166,167,168
- Revision 1.44 1998/09/28 16:57:28 pierre
- * changed all length(p^.value_str^) into str_length(p)
- to get it work with and without ansistrings
- * changed sourcefiles field of tmodule to a pointer
- Revision 1.43 1998/09/27 10:16:28 florian
- * type casts pchar<->ansistring fixed
- * ansistring[..] calls does now an unique call
- Revision 1.42 1998/09/23 12:03:59 peter
- * overloading fix for array of const
- Revision 1.41 1998/09/23 09:58:55 peter
- * first working array of const things
- Revision 1.40 1998/09/22 15:34:07 peter
- + pchar -> string conversion
- Revision 1.39 1998/09/21 08:45:27 pierre
- + added vmt_offset in tobjectdef.write for fututre use
- (first steps to have objects without vmt if no virtual !!)
- + added fpu_used field for tabstractprocdef :
- sets this level to 2 if the functions return with value in FPU
- (is then set to correct value at parsing of implementation)
- THIS MIGHT refuse some code with FPU expression too complex
- that were accepted before and even in some cases
- that don't overflow in fact
- ( like if f : float; is a forward that finally in implementation
- only uses one fpu register !!)
- Nevertheless I think that it will improve security on
- FPU operations !!
- * most other changes only for UseBrowser code
- (added symtable references for record and objects)
- local switch for refs to args and local of each function
- (static symtable still missing)
- UseBrowser still not stable and probably broken by
- the definition hash array !!
- Revision 1.38 1998/09/16 01:06:47 carl
- * crash bugfix in firstaddr
- Revision 1.37 1998/09/08 10:38:04 pierre
- * some variable fields inside conditionnal were not updated
- Revision 1.36 1998/09/07 18:46:17 peter
- * update smartlinking, uses getdatalabel
- * renamed ptree.value vars to value_str,value_real,value_set
- Revision 1.35 1998/09/04 08:42:11 peter
- * updated some error messages
- Revision 1.34 1998/09/01 17:39:54 peter
- + internal constant functions
- Revision 1.33 1998/08/28 12:51:44 florian
- + ansistring to pchar type cast fixed
- Revision 1.32 1998/08/28 10:54:25 peter
- * fixed smallset generation from elements, it has never worked before!
- Revision 1.31 1998/08/21 14:08:58 pierre
- + TEST_FUNCRET now default (old code removed)
- works also for m68k (at least compiles)
- Revision 1.30 1998/08/18 09:24:47 pierre
- * small warning position bug fixed
- * support_mmx switches splitting was missing
- * rhide error and warning output corrected
- Revision 1.29 1998/08/14 18:18:48 peter
- + dynamic set contruction
- * smallsets are now working (always longint size)
- Revision 1.28 1998/08/13 11:00:13 peter
- * fixed procedure<>procedure construct
- Revision 1.27 1998/08/10 14:50:35 peter
- + localswitches, moduleswitches, globalswitches splitting
- Revision 1.26 1998/08/10 09:57:19 peter
- - Remove InitTree which was empty and obsolete
- Revision 1.25 1998/08/02 16:42:02 florian
- * on o : tobject do should also work now, the exceptsymtable shouldn't be
- disposed by dellexlevel
- Revision 1.24 1998/07/30 11:18:23 florian
- + first implementation of try ... except on .. do end;
- * limitiation of 65535 bytes parameters for cdecl removed
- Revision 1.23 1998/07/24 22:17:01 florian
- * internal error 10 together with array access fixed. I hope
- that's the final fix.
- Revision 1.22 1998/07/20 10:23:05 florian
- * better ansi string assignement
- Revision 1.21 1998/07/14 21:46:56 peter
- * updated messages file
- Revision 1.20 1998/07/14 14:47:11 peter
- * released NEWINPUT
- Revision 1.19 1998/07/08 14:56:53 daniel
- * Fixed $ifdef TP.
- Revision 1.18 1998/07/07 11:20:18 peter
- + NEWINPUT for a better inputfile and scanner object
- Revision 1.17 1998/06/22 08:59:03 daniel
- - Removed pool of nodes.
- Revision 1.16 1998/06/12 14:50:49 peter
- * removed the tree dependency to types.pas
- * long_fil.pas support (not fully tested yet)
- Revision 1.15 1998/06/06 08:39:07 peter
- * it needs types
- Revision 1.14 1998/06/05 14:37:40 pierre
- * fixes for inline for operators
- * inline procedure more correctly restricted
- Revision 1.13 1998/06/04 09:55:49 pierre
- * demangled name of procsym reworked to become independant of the mangling scheme
- Revision 1.12 1998/06/03 22:49:06 peter
- + wordbool,longbool
- * rename bis,von -> high,low
- * moved some systemunit loading/creating to psystem.pas
- Revision 1.10 1998/05/20 09:42:38 pierre
- + UseTokenInfo now default
- * unit in interface uses and implementation uses gives error now
- * only one error for unknown symbol (uses lastsymknown boolean)
- the problem came from the label code !
- + first inlined procedures and function work
- (warning there might be allowed cases were the result is still wrong !!)
- * UseBrower updated gives a global list of all position of all used symbols
- with switch -gb
- Revision 1.9 1998/05/12 10:47:00 peter
- * moved printstatus to verb_def
- + V_Normal which is between V_Error and V_Warning and doesn't have a
- prefix like error: warning: and is included in V_Default
- * fixed some messages
- * first time parameter scan is only for -v and -T
- - removed old style messages
- Revision 1.8 1998/05/07 00:17:01 peter
- * smartlinking for sets
- + consts labels are now concated/generated in hcodegen
- * moved some cpu code to cga and some none cpu depended code from cga
- to tree and hcodegen and cleanup of hcodegen
- * assembling .. output reduced for smartlinking ;)
- Revision 1.7 1998/05/06 15:04:21 pierre
- + when trying to find source files of a ppufile
- check the includepathlist for included files
- the main file must still be in the same directory
- Revision 1.6 1998/05/06 08:38:52 pierre
- * better position info with UseTokenInfo
- UseTokenInfo greatly simplified
- + added check for changed tree after first time firstpass
- (if we could remove all the cases were it happen
- we could skip all firstpass if firstpasscount > 1)
- Only with ExtDebug
- Revision 1.5 1998/04/30 15:59:43 pierre
- * GDB works again better :
- correct type info in one pass
- + UseTokenInfo for better source position
- * fixed one remaining bug in scanner for line counts
- * several little fixes
- Revision 1.4 1998/04/29 10:34:08 pierre
- + added some code for ansistring (not complete nor working yet)
- * corrected operator overloading
- * corrected nasm output
- + started inline procedures
- + added starstarn : use ** for exponentiation (^ gave problems)
- + started UseTokenInfo cond to get accurate positions
- Revision 1.3 1998/04/21 10:16:49 peter
- * patches from strasbourg
- * objects is not used anymore in the fpc compiled version
- Revision 1.2 1998/04/07 22:45:05 florian
- * bug0092, bug0115 and bug0121 fixed
- + packed object/class/array
- }
|