summaryrefslogtreecommitdiff
path: root/compiler/pass_2.pas
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/pass_2.pas')
-rw-r--r--compiler/pass_2.pas210
1 files changed, 210 insertions, 0 deletions
diff --git a/compiler/pass_2.pas b/compiler/pass_2.pas
new file mode 100644
index 0000000000..9905c27e65
--- /dev/null
+++ b/compiler/pass_2.pas
@@ -0,0 +1,210 @@
+{
+ Copyright (c) 1998-2002 by Florian Klaempfl
+
+ This unit handles the codegeneration pass
+
+ 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.
+
+ ****************************************************************************
+}
+unit pass_2;
+
+{$i fpcdefs.inc}
+
+interface
+
+uses
+ node;
+
+ type
+ tenumflowcontrol = (fc_exit,fc_break,fc_continue);
+ tflowcontrol = set of tenumflowcontrol;
+
+ var
+ flowcontrol : tflowcontrol;
+
+{ produces the actual code }
+function do_secondpass(var p : tnode) : boolean;
+procedure secondpass(var p : tnode);
+
+
+implementation
+
+ uses
+{$ifdef EXTDEBUG}
+ cutils,
+{$endif}
+ globtype,systems,verbose,
+ globals,
+ paramgr,
+ aasmtai,
+ cgbase,
+ nflw,cgobj;
+
+{*****************************************************************************
+ SecondPass
+*****************************************************************************}
+
+{$ifdef EXTDEBUG}
+ procedure logsecond(ht:tnodetype; entry: boolean);
+ const
+ secondnames: array[tnodetype] of string[13] =
+ ('<emptynode>',
+ 'add-addn', {addn}
+ 'add-muln', {muln}
+ 'add-subn', {subn}
+ 'moddiv-divn', {divn}
+ 'add-symdifn', {symdifn}
+ 'moddiv-modn', {modn}
+ 'assignment', {assignn}
+ 'load', {loadn}
+ 'nothing-range', {range}
+ 'add-ltn', {ltn}
+ 'add-lten', {lten}
+ 'add-gtn', {gtn}
+ 'add-gten', {gten}
+ 'add-equaln', {equaln}
+ 'add-unequaln', {unequaln}
+ 'in', {inn}
+ 'add-orn', {orn}
+ 'add-xorn', {xorn}
+ 'shlshr-shrn', {shrn}
+ 'shlshr-shln', {shln}
+ 'add-slashn', {slashn}
+ 'add-andn', {andn}
+ 'subscriptn', {subscriptn}
+ 'deref', {derefn}
+ 'addr', {addrn}
+ 'ordconst', {ordconstn}
+ 'typeconv', {typeconvn}
+ 'calln', {calln}
+ 'noth-callpar',{callparan}
+ 'realconst', {realconstn}
+ 'unaryminus', {unaryminusn}
+ 'asm', {asmn}
+ 'vecn', {vecn}
+ 'pointerconst',{pointerconstn}
+ 'stringconst', {stringconstn}
+ 'not', {notn}
+ 'inline', {inlinen}
+ 'niln', {niln}
+ 'error', {errorn}
+ 'nothing-typen', {typen}
+ 'setelement', {setelementn}
+ 'setconst', {setconstn}
+ 'blockn', {blockn}
+ 'statement', {statementn}
+ 'ifn', {ifn}
+ 'breakn', {breakn}
+ 'continuen', {continuen}
+ 'while_repeat', {whilerepeatn}
+ 'for', {forn}
+ 'exitn', {exitn}
+ 'with', {withn}
+ 'case', {casen}
+ 'label', {labeln}
+ 'goto', {goton}
+ 'tryexcept', {tryexceptn}
+ 'raise', {raisen}
+ 'tryfinally', {tryfinallyn}
+ 'on', {onn}
+ 'is', {isn}
+ 'as', {asn}
+ 'error-caret', {caretn}
+ 'add-starstar', {starstarn}
+ 'arrayconstruc', {arrayconstructn}
+ 'noth-arrcnstr', {arrayconstructrangen}
+ 'tempcreaten',
+ 'temprefn',
+ 'tempdeleten',
+ 'addoptn',
+ 'nothing-nothg', {nothingn}
+ 'loadvmt', {loadvmtn}
+ 'guidconstn',
+ 'rttin',
+ 'loadparentfpn'
+ );
+ var
+ p: pchar;
+ begin
+ if entry then
+ p := strpnew('second '+secondnames[ht]+' (entry)')
+ else
+ p := strpnew('second '+secondnames[ht]+' (exit)');
+ exprasmlist.concat(tai_comment.create(p));
+ end;
+{$endif EXTDEBUG}
+
+ procedure secondpass(var p : tnode);
+ var
+ oldcodegenerror : boolean;
+ oldlocalswitches : tlocalswitches;
+ oldpos : tfileposinfo;
+ begin
+ if not assigned(p) then
+ internalerror(200208221);
+ if not(nf_error in p.flags) then
+ begin
+ oldcodegenerror:=codegenerror;
+ oldlocalswitches:=aktlocalswitches;
+ oldpos:=aktfilepos;
+ if not inlining_procedure then
+ aktfilepos:=p.fileinfo;
+ aktlocalswitches:=p.localswitches;
+ codegenerror:=false;
+{$ifdef EXTDEBUG}
+ if (p.expectloc=LOC_INVALID) then
+ Comment(V_Warning,'ExpectLoc is not set before secondpass: '+nodetype2str[p.nodetype]);
+ if (p.location.loc<>LOC_INVALID) then
+ Comment(V_Warning,'Location.Loc is already set before secondpass: '+nodetype2str[p.nodetype]);
+ if (cs_asm_nodes in aktglobalswitches) then
+ logsecond(p.nodetype,true);
+{$endif EXTDEBUG}
+ p.pass_2;
+{$ifdef EXTDEBUG}
+ if (cs_asm_nodes in aktglobalswitches) then
+ logsecond(p.nodetype,false);
+ if (not codegenerror) then
+ begin
+ if (p.location.loc=LOC_INVALID) then
+ Comment(V_Warning,'Location not set in secondpass: '+nodetype2str[p.nodetype]);
+ end;
+{$endif EXTDEBUG}
+ if codegenerror then
+ include(p.flags,nf_error);
+ codegenerror:=codegenerror or oldcodegenerror;
+ aktlocalswitches:=oldlocalswitches;
+ aktfilepos:=oldpos;
+ end
+ else
+ codegenerror:=true;
+ end;
+
+
+ function do_secondpass(var p : tnode) : boolean;
+ begin
+ { exprasmlist must be empty }
+ if not exprasmlist.empty then
+ internalerror(200405201);
+
+ { clear errors before starting }
+ codegenerror:=false;
+ if not(nf_error in p.flags) then
+ secondpass(p);
+ do_secondpass:=codegenerror;
+ end;
+
+
+end.