mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 22:11:12 +01:00 
			
		
		
		
	 bf6369f1b5
			
		
	
	
		bf6369f1b5
		
	
	
	
	
		
			
			+ added ppheap for better info on tracegetmem of heaptrc
    (adds line column and file index)
  * several memory leaks removed ith help of heaptrc !!
		
	
			
		
			
				
	
	
		
			1825 lines
		
	
	
		
			58 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			1825 lines
		
	
	
		
			58 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
| {
 | |
|     $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
 | |
|        cobjects,globals,symtable,aasm
 | |
| {$ifdef i386}
 | |
|        ,i386
 | |
| {$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_u8bit_2_s32bit,
 | |
|                       tc_only_rangechecks32bit,tc_s8bit_2_s32bit,
 | |
|                       tc_u16bit_2_s32bit,tc_s16bit_2_s32bit,
 | |
|                       tc_s32bit_2_s16bit,tc_s32bit_2_u8bit,
 | |
|                       tc_s32bit_2_u16bit,tc_string_to_string,
 | |
|                       tc_cstring_charpointer,tc_string_chararray,
 | |
|                       tc_array_to_pointer,tc_pointer_to_array,
 | |
|                       tc_char_to_string,tc_u8bit_2_s16bit,
 | |
|                       tc_u8bit_2_u16bit,tc_s8bit_2_s16bit,
 | |
|                       tc_s16bit_2_s8bit,tc_s16bit_2_u8bit,
 | |
|                       tc_u16bit_2_s8bit,tc_u16bit_2_u8bit,
 | |
|                       tc_s8bit_2_u16bit,tc_s32bit_2_s8bit,
 | |
|                       tc_s32bit_2_u32bit,tc_s16bit_2_u32bit,
 | |
|                       tc_s8bit_2_u32bit,tc_u16bit_2_u32bit,
 | |
|                       tc_u8bit_2_u32bit,tc_u32bit_2_s32bit,
 | |
|                       tc_u32bit_2_s8bit,tc_u32bit_2_u8bit,
 | |
|                       tc_u32bit_2_s16bit,tc_u32bit_2_u16bit,
 | |
|                       tc_bool_2_int,tc_int_2_bool,
 | |
|                       tc_int_2_real,tc_real_2_fix,
 | |
|                       tc_fix_2_real,tc_int_2_fix,tc_real_2_real,
 | |
|                       tc_chararray_2_string,
 | |
|                       tc_proc2procvar,tc_cchar_charpointer,tc_load_smallset,
 | |
|                       tc_ansistring_2_pchar,tc_pchar_2_string,
 | |
|                       tc_arrayconstructor_2_set);
 | |
| 
 | |
|        { allows to determine which elementes are to be replaced }
 | |
|        tdisposetyp = (dt_nothing,dt_leftright,dt_left,
 | |
|                       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 : plabel;
 | |
| 
 | |
|           { label of instruction }
 | |
|           statement : plabel;
 | |
| 
 | |
|           { 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}
 | |
|           case treetype : ttreetyp of
 | |
|              addn : (use_strconcat : boolean;string_typ : tstringtype);
 | |
|              callparan : (is_colon_para : boolean;exact_match_found : boolean);
 | |
|              assignn : (assigntyp : tassigntyp;concat_string : boolean);
 | |
|              loadn : (symtableentry : psym;symtable : psymtable;
 | |
|                       is_absolute,is_first : boolean);
 | |
|              calln : (symtableprocentry : psym;
 | |
|                       symtableproc : psymtable;procdefinition : pprocdef;
 | |
|                       methodpointer : ptree;
 | |
|                       no_check,unit_specific,return_value_used : boolean);
 | |
|              ordconstn : (value : longint);
 | |
|              realconstn : (value_real : bestreal;lab_real : plabel;realtyp : tait);
 | |
|              fixconstn : (value_fix: longint);
 | |
|              funcretn : (funcretprocinfo : pointer;retdef : pdef);
 | |
|              subscriptn : (vs : pvarsym);
 | |
|              vecn : (memindex,memseg:boolean;callunique : boolean);
 | |
| {$ifdef UseAnsiString}
 | |
|              stringconstn : (value_str : pchar;length : longint; lab_str : plabel;stringtype : tstringtype);
 | |
| {$else UseAnsiString}
 | |
|              stringconstn : (value_str : pstring; lab_str:plabel;stringtype : tstringtype);
 | |
| {$endif UseAnsiString}
 | |
|              typeconvn : (convtyp : tconverttype;explizit : boolean);
 | |
|              inlinen : (inlinenumber : longint;inlineconst:boolean);
 | |
|              procinlinen : (inlineprocdef : pprocdef;
 | |
|                             retoffset,para_offset,para_size : longint);
 | |
|              setconstn : (value_set : pconstset;lab_set:plabel);
 | |
|              loopn : (t1,t2 : ptree;backward : boolean);
 | |
|              asmn : (p_asm : paasmoutput;object_preserved : boolean);
 | |
|              casen : (nodes : pcaserecord;elseblock : ptree);
 | |
|              labeln,goton : (labelnr : plabel);
 | |
|              withn : (withsymtable : psymtable;tablecount : longint);
 | |
|              onn : (exceptsymtable : psymtable;excepttype : pobjectdef);
 | |
|            end;
 | |
| 
 | |
|     function gennode(t : ttreetyp;l,r : ptree) : ptree;
 | |
|     function genlabelnode(t : ttreetyp;nr : plabel) : ptree;
 | |
|     function genloadnode(v : pvarsym;st : psymtable) : ptree;
 | |
|     function genloadcallnode(v: pprocsym;st: psymtable): 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 gencallparanode(expr,next : ptree) : ptree;
 | |
|     function genrealconstnode(v : bestreal) : 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;
 | |
| {$ifdef UseAnsiString}
 | |
|     { length is required for ansistrings }
 | |
|     function genpcharconstnode(s : pchar;length : longint) : ptree;
 | |
|     { helper routine for conststring node }
 | |
|     function getpcharcopy(p : ptree) : pchar;
 | |
| {$endif UseAnsiString}
 | |
| 
 | |
|     function genzeronode(t : ttreetyp) : ptree;
 | |
|     function geninlinenode(number : longint;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 : psymtable;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;
 | |
| 
 | |
| {$I innr.inc}
 | |
| 
 | |
|   implementation
 | |
| 
 | |
|     uses
 | |
|        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
 | |
| {$ifndef UseAnsiString}
 | |
|                    stringdispose(p^.value_str);
 | |
| {$else UseAnsiString}
 | |
|                    ansistringdispose(p^.value_str,p^.length);
 | |
| {$endif UseAnsiString}
 | |
|                  end;
 | |
|      setconstn : begin
 | |
|                    if assigned(p^.value_set) then
 | |
|                      dispose(p^.value_set);
 | |
|                  end;
 | |
|          end;
 | |
|          { reference info }
 | |
|          if (p^.location.loc in [LOC_MEM,LOC_REFERENCE]) and
 | |
|             assigned(p^.location.reference.symbol) then
 | |
|            stringdispose(p^.location.reference.symbol);
 | |
| {$ifdef extdebug}
 | |
|          if p^.firstpasscount>maxfirstpasscount then
 | |
|             maxfirstpasscount:=p^.firstpasscount;
 | |
| {$endif extdebug}
 | |
|          dispose(p);
 | |
|       end;
 | |
| 
 | |
|     function getcopy(p : ptree) : ptree;
 | |
| 
 | |
|       var
 | |
|          hp : ptree;
 | |
| 
 | |
|       begin
 | |
|          hp:=getnode;
 | |
|          hp^:=p^;
 | |
|          if assigned(p^.location.reference.symbol) then
 | |
|            hp^.location.reference.symbol:=stringdup(p^.location.reference.symbol^);
 | |
|          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_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
 | |
| {$ifdef UseAnsiString}
 | |
|                    hp^.value_str:=getpcharcopy(p);
 | |
|                    hp^.length:=p^.length;
 | |
| {$else UseAnsiString}
 | |
|                    hp^.value_str:=stringdup(p^.value_str^);
 | |
| {$endif UseAnsiString}
 | |
|                  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);
 | |
|          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 : psymtable;
 | |
|          i : longint;
 | |
|          
 | |
|       begin
 | |
|          if not(assigned(p)) then
 | |
|            exit;
 | |
|          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_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:=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 : psymtable;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;
 | |
|          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_leftright;
 | |
|          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^.is_colon_para:=false;
 | |
|          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;
 | |
|          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) : 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}
 | |
| {$ifdef i386}
 | |
|          p^.resulttype:=c64floatdef;
 | |
|          p^.value_real:=v;
 | |
|          { default value is double }
 | |
|          p^.realtyp:=ait_real_64bit;
 | |
| {$endif}
 | |
| {$ifdef m68k}
 | |
|          p^.resulttype:=new(pfloatdef,init(s32real));
 | |
|          p^.value_real:=v;
 | |
|          { default value is double }
 | |
|          p^.realtyp:=ait_real_32bit;
 | |
| {$endif}
 | |
|          p^.lab_real:=nil;
 | |
|          genrealconstnode:=p;
 | |
|       end;
 | |
| 
 | |
|     function genstringconstnode(const s : string) : ptree;
 | |
| 
 | |
|       var
 | |
|          p : ptree;
 | |
| {$ifdef UseAnsiString}
 | |
|          l : longint;
 | |
| {$endif UseAnsiString}
 | |
|       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^.resulttype:=cstringdef;
 | |
| {$ifdef UseAnsiString}
 | |
|          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;
 | |
| {$else UseAnsiString}
 | |
|          p^.value_str:=stringdup(s);
 | |
| {$endif UseAnsiString}
 | |
|          p^.lab_str:=nil;
 | |
|          p^.stringtype:=st_shortstring;
 | |
|          genstringconstnode:=p;
 | |
|       end;
 | |
| 
 | |
| {$ifdef UseAnsiString}
 | |
|     function getpcharcopy(p : ptree) : pchar;
 | |
| 
 | |
|       var
 | |
|          pc : pchar;
 | |
| 
 | |
|       begin
 | |
|          pc:=nil;
 | |
|          getmem(pc,p^.length+1);
 | |
|          { Peter can you change that ? }
 | |
|          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^.resulttype:=cstringdef;
 | |
|          p^.length:=length;
 | |
|          p^.value_str:=s;
 | |
|          p^.lab_str:=nil;
 | |
|          genpcharconstnode:=p;
 | |
|       end;
 | |
| {$endif UseAnsiString}
 | |
| 
 | |
|     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;
 | |
|          p^.disposetyp:=dt_nothing;
 | |
|          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^.resulttype:=v^.definition;
 | |
|          p^.symtableentry:=v;
 | |
|          p^.symtable:=st;
 | |
|          p^.is_first := False;
 | |
|          p^.disposetyp:=dt_nothing;
 | |
|          genloadcallnode:=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^.resulttype:=sym^.definition;
 | |
|          p^.symtableentry:=pvarsym(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 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 : plabel) : 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 : longint;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_left;
 | |
|          p^.treetype:=procinlinen;
 | |
|          p^.inlineprocdef:=callp^.procdefinition;
 | |
|          p^.retoffset:=-4; { less dangerous as zero (PM) }
 | |
|          p^.para_offset:=0;
 | |
|          p^.para_size:=p^.inlineprocdef^.para_size;
 | |
|          if ret_in_param(p^.inlineprocdef^.retdef) then
 | |
|            p^.para_size:=p^.para_size+sizeof(pointer);
 | |
|          { copy args }
 | |
|          p^.left:=getcopy(code);
 | |
|          p^.registers32:=code^.registers32;
 | |
|          p^.registersfpu:=code^.registersfpu;
 | |
| {$ifdef SUPPORT_MMX}
 | |
|          p^.registersmmx:=0;
 | |
| {$endif SUPPORT_MMX}
 | |
|          p^.resulttype:=p^.inlineprocdef^.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;
 | |
|              (*realconstn : (valued : bestreal;labnumber : longint;realtyp : tait);
 | |
|              fixconstn : (valuef: longint);
 | |
|              funcretn : (funcretprocinfo : pointer;retdef : pdef);
 | |
|              subscriptn : (vs : pvarsym);
 | |
|              vecn : (memindex,memseg:boolean);
 | |
|              { stringconstn : (length : longint; value_str : pstring;labstrnumber : longint); }
 | |
|              { string const can be longer then 255 with ansistring !! }
 | |
| {$ifdef UseAnsiString}
 | |
|              stringconstn : (value_str : pchar;length : longint; labstrnumber : longint);
 | |
| {$else UseAnsiString}
 | |
|              stringconstn : (value_str : pstring; labstrnumber : longint);
 | |
| {$endif UseAnsiString}
 | |
|              typeconvn : (convtyp : tconverttype;explizit : boolean);
 | |
|              inlinen : (inlinenumber : longint);
 | |
|              procinlinen : (inlineprocdef : pprocdef);
 | |
|              setconstrn : (constset : pconstset);
 | |
|              loopn : (t1,t2 : ptree;backward : boolean);
 | |
|              asmn : (p_asm : paasmoutput);
 | |
|              casen : (nodes : pcaserecord;elseblock : ptree);
 | |
|              labeln,goton : (labelnr : plabel);
 | |
|              withn : (withsymtable : psymtable;tablecount : longint);
 | |
|            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
 | |
|         if assigned(loc.reference.symbol) then
 | |
|           stringdispose(loc.reference.symbol);
 | |
|         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
 | |
|         if assigned(destloc.reference.symbol) then
 | |
|           stringdispose(destloc.reference.symbol);
 | |
|         destloc:= sourceloc;
 | |
|         if sourceloc.loc in [LOC_MEM,LOC_REFERENCE] then
 | |
|           begin
 | |
|              if assigned(sourceloc.reference.symbol) then
 | |
|                destloc.reference.symbol:=
 | |
|                  stringdup(sourceloc.reference.symbol^);
 | |
|           end
 | |
|         else
 | |
|           destloc.reference.symbol:=nil;
 | |
|       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
 | |
| {$ifdef UseAnsiString}
 | |
|          str_length:=p^.length;
 | |
| {$else UseAnsiString}
 | |
|          str_length:=length(p^.value_str^);
 | |
| {$endif UseAnsiString}
 | |
|       end;
 | |
| 
 | |
| 
 | |
| end.
 | |
| {
 | |
|   $Log$
 | |
|   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
 | |
| }
 | |
| 
 |