Commit ad321293 by Mark Mitchell Committed by Mark Mitchell

semantics.c: New file, containing routines to perform the semantic phase of parsing.

	* semantics.c: New file, containing routines to perform the
	semantic phase of parsing.
	* parse.y: Use it.
	* pt.c (tsubst_expr): Likewise.
	* cp-tree.h: Declare the various functions in semantics.c.
	Provide macros to access _STMT tree nodes.
	* cp-tree.def: Add ASM_STMT tree node.
	* Makefile.in, Make-lang.in: Add dependencies on and for
	semantics.c.

From-SVN: r18658
parent cbe36725
Wed Mar 18 10:09:51 1998 Mark Mitchell <mmitchell@usa.net>
* semantics.c: New file, containing routines to perform the
semantic phase of parsing.
* parse.y: Use it.
* pt.c (tsubst_expr): Likewise.
* cp-tree.h: Declare the various functions in semantics.c.
Provide macros to access _STMT tree nodes.
* cp-tree.def: Add ASM_STMT tree node.
* Makefile.in, Make-lang.in: Add dependencies on and for
semantics.c.
Wed Mar 18 00:24:10 1998 Jason Merrill <jason@yorick.cygnus.com>
* pt.c (push_template_decl): Only check primary templates.
......
......@@ -122,7 +122,7 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \
$(srcdir)/cp/search.c $(srcdir)/cp/typeck.c $(srcdir)/cp/decl.c \
$(srcdir)/cp/error.c $(srcdir)/cp/friend.c $(srcdir)/cp/init.c \
$(srcdir)/cp/parse.y $(srcdir)/cp/sig.c $(srcdir)/cp/typeck2.c \
$(srcdir)/cp/repo.c
$(srcdir)/cp/repo.c $(srcdir)/cp/semantics.c
cc1plus: $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o \
$(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def
......
......@@ -166,7 +166,7 @@ INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config
CXX_OBJS = call.o decl.o errfn.o expr.o pt.o sig.o typeck2.o \
class.o decl2.o error.o lex.o parse.o ptree.o rtti.o spew.o typeck.o cvt.o \
except.o friend.o init.o method.o search.o tree.o xref.o repo.o
except.o friend.o init.o method.o search.o semantics.o tree.o xref.o repo.o
# Language-independent object files.
OBJS = `cat ../stamp-objlist` ../c-common.o ../c-pragma.o
......@@ -259,6 +259,8 @@ error.o : error.c $(CONFIG_H) $(CXX_TREE_H)
errfn.o : errfn.c $(CONFIG_H) $(CXX_TREE_H)
sig.o : sig.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h
repo.o : repo.c $(CONFIG_H) $(CXX_TREE_H)
semantics.o: semantics.c $(CONFIG_H) $(CXX_TREE_H) lex.h $(srcdir)/../except.h
#
# These exist for maintenance purposes.
......
......@@ -200,6 +200,7 @@ DEFTREECODE (BREAK_STMT, "break_stmt", 'e', 0)
DEFTREECODE (CONTINUE_STMT, "continue_stmt", 'e', 0)
DEFTREECODE (SWITCH_STMT, "switch_stmt", 'e', 2)
DEFTREECODE (GOTO_STMT, "goto_stmt", 'e', 1)
DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 5)
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2)
DEFTREECODE (CASE_LABEL, "case_label", 'e', 2)
......
......@@ -1524,6 +1524,37 @@ extern int flag_new_for_scope;
#define builtin_function(NAME, TYPE, CODE, LIBNAME) \
define_function (NAME, TYPE, CODE, (void (*) PROTO((tree)))pushdecl, LIBNAME)
/* These macros provide convenient access to the various _STMT nodes
created when parsing template declarations. */
#define IF_COND(NODE) TREE_OPERAND (NODE, 0)
#define THEN_CLAUSE(NODE) TREE_OPERAND (NODE, 1)
#define ELSE_CLAUSE(NODE) TREE_OPERAND (NODE, 2)
#define WHILE_COND(NODE) TREE_OPERAND (NODE, 0)
#define WHILE_BODY(NODE) TREE_OPERAND (NODE, 1)
#define DO_COND(NODE) TREE_OPERAND (NODE, 0)
#define DO_BODY(NODE) TREE_OPERAND (NODE, 1)
#define RETURN_EXPR(NODE) TREE_OPERAND (NODE, 0)
#define EXPR_STMT_EXPR(NODE) TREE_OPERAND (NODE, 0)
#define FOR_INIT_STMT(NODE) TREE_OPERAND (NODE, 0)
#define FOR_COND(NODE) TREE_OPERAND (NODE, 1)
#define FOR_EXPR(NODE) TREE_OPERAND (NODE, 2)
#define FOR_BODY(NODE) TREE_OPERAND (NODE, 3)
#define SWITCH_COND(NODE) TREE_OPERAND (NODE, 0)
#define SWITCH_BODY(NODE) TREE_OPERAND (NODE, 1)
#define CASE_LOW(NODE) TREE_OPERAND (NODE, 0)
#define CASE_HIGH(NODE) TREE_OPERAND (NODE, 1)
#define GOTO_DESTINATION(NODE) TREE_OPERAND (NODE, 0)
#define TRY_STMTS(NODE) TREE_OPERAND (NODE, 0)
#define TRY_HANDLERS(NODE) TREE_OPERAND (NODE, 1)
#define HANDLER_PARMS(NODE) TREE_OPERAND (NODE, 0)
#define HANDLER_BODY(NODE) TREE_OPERAND (NODE, 1)
#define COMPOUND_BODY(NODE) TREE_OPERAND (NODE, 0)
#define ASM_CV_QUAL(NODE) TREE_OPERAND (NODE, 0)
#define ASM_STRING(NODE) TREE_OPERAND (NODE, 1)
#define ASM_OUTPUTS(NODE) TREE_OPERAND (NODE, 2)
#define ASM_INPUTS(NODE) TREE_OPERAND (NODE, 3)
#define ASM_CLOBBERS(NODE) TREE_OPERAND (NODE, 4)
/* An enumeration of the kind of tags that C++ accepts. */
enum tag_types { record_type, class_type, union_type, enum_type,
signature_type };
......@@ -2511,6 +2542,42 @@ extern tree current_scope PROTO((void));
extern tree lookup_conversions PROTO((tree));
extern tree get_template_base PROTO((tree, tree));
/* in semantics.c */
extern void finish_expr_stmt PROTO((tree));
extern tree begin_if_stmt PROTO((void));
extern void finish_if_stmt_cond PROTO((tree, tree));
extern tree finish_then_clause PROTO((tree));
extern void begin_else_clause PROTO((void));
extern void finish_else_clause PROTO((tree));
extern void finish_if_stmt PROTO((void));
extern tree begin_while_stmt PROTO((void));
extern void finish_while_stmt_cond PROTO((tree, tree));
extern void finish_while_stmt PROTO((tree));
extern tree begin_do_stmt PROTO((void));
extern void finish_do_body PROTO((tree));
extern void finish_do_stmt PROTO((tree, tree));
extern void finish_return_stmt PROTO((tree));
extern tree begin_for_stmt PROTO((void));
extern void finish_for_init_stmt PROTO((tree));
extern void finish_for_cond PROTO((tree, tree));
extern void finish_for_expression PROTO((tree, tree));
extern void finish_for_stmt PROTO((tree, tree));
extern void finish_break_stmt PROTO((void));
extern void finish_continue_stmt PROTO((void));
extern void begin_switch_stmt PROTO((void));
extern tree finish_switch_cond PROTO((tree));
extern void finish_switch_stmt PROTO((tree, tree));
extern void finish_case_label PROTO((tree, tree));
extern void finish_goto_stmt PROTO((tree));
extern tree begin_try_block PROTO((void));
extern void finish_try_block PROTO((tree));
extern void finish_handler_sequence PROTO((tree));
extern tree begin_handler PROTO((void));
extern void finish_handler_parms PROTO((tree));
extern void finish_handler PROTO((tree));
extern tree begin_compound_stmt PROTO((int));
extern tree finish_compound_stmt PROTO((int, tree));
extern void finish_asm_stmt PROTO((tree, tree, tree, tree, tree));
/* in sig.c */
extern tree build_signature_pointer_type PROTO((tree, int, int));
extern tree build_signature_reference_type PROTO((tree, int, int));
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -4690,24 +4690,14 @@ tsubst_expr (t, args, in_decl)
{
case RETURN_STMT:
lineno = TREE_COMPLEXITY (t);
emit_line_note (input_filename, lineno);
c_expand_return
(tsubst_expr (TREE_OPERAND (t, 0), args, in_decl));
finish_stmt ();
finish_return_stmt (tsubst_expr (RETURN_EXPR (t),
args, in_decl));
break;
case EXPR_STMT:
lineno = TREE_COMPLEXITY (t);
emit_line_note (input_filename, lineno);
t = tsubst_expr (TREE_OPERAND (t, 0), args, in_decl);
/* Do default conversion if safe and possibly important,
in case within ({...}). */
if ((TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE && lvalue_p (t))
|| TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
t = default_conversion (t);
cplus_expand_expr_stmt (t);
clear_momentary ();
finish_stmt ();
finish_expr_stmt (tsubst_expr (EXPR_STMT_EXPR (t),
args, in_decl));
break;
case DECL_STMT:
......@@ -4731,184 +4721,117 @@ tsubst_expr (t, args, in_decl)
case FOR_STMT:
{
tree tmp;
int init_scope = (flag_new_for_scope > 0 && TREE_OPERAND (t, 0)
&& TREE_CODE (TREE_OPERAND (t, 0)) == DECL_STMT);
int cond_scope = (TREE_OPERAND (t, 1)
&& TREE_CODE (TREE_OPERAND (t, 1)) == DECL_STMT);
lineno = TREE_COMPLEXITY (t);
emit_line_note (input_filename, lineno);
if (init_scope)
do_pushlevel ();
for (tmp = TREE_OPERAND (t, 0); tmp; tmp = TREE_CHAIN (tmp))
tsubst_expr (tmp, args, in_decl);
emit_nop ();
emit_line_note (input_filename, lineno);
expand_start_loop_continue_elsewhere (1);
if (cond_scope)
do_pushlevel ();
tmp = tsubst_expr (TREE_OPERAND (t, 1), args, in_decl);
emit_line_note (input_filename, lineno);
if (tmp)
expand_exit_loop_if_false (0, condition_conversion (tmp));
if (! cond_scope)
do_pushlevel ();
tsubst_expr (TREE_OPERAND (t, 3), args, in_decl);
do_poplevel ();
emit_line_note (input_filename, lineno);
expand_loop_continue_here ();
tmp = tsubst_expr (TREE_OPERAND (t, 2), args, in_decl);
if (tmp)
cplus_expand_expr_stmt (tmp);
expand_end_loop ();
if (init_scope)
do_poplevel ();
finish_stmt ();
begin_for_stmt ();
for (tmp = FOR_INIT_STMT (t); tmp; tmp = TREE_CHAIN (tmp))
tsubst_expr (tmp, args, in_decl);
finish_for_init_stmt (NULL_TREE);
finish_for_cond (tsubst_expr (FOR_COND (t), args,
in_decl),
NULL_TREE);
tmp = tsubst_expr (FOR_EXPR (t), args, in_decl);
finish_for_expr (tmp, NULL_TREE);
tsubst_expr (FOR_BODY (t), args, in_decl);
finish_for_stmt (tmp, NULL_TREE);
}
break;
case WHILE_STMT:
{
tree cond;
lineno = TREE_COMPLEXITY (t);
emit_nop ();
emit_line_note (input_filename, lineno);
expand_start_loop (1);
cond = TREE_OPERAND (t, 0);
if (TREE_CODE (cond) == DECL_STMT)
do_pushlevel ();
cond = tsubst_expr (cond, args, in_decl);
emit_line_note (input_filename, lineno);
expand_exit_loop_if_false (0, condition_conversion (cond));
if (TREE_CODE (TREE_OPERAND (t, 0)) != DECL_STMT)
do_pushlevel ();
tsubst_expr (TREE_OPERAND (t, 1), args, in_decl);
do_poplevel ();
expand_end_loop ();
finish_stmt ();
begin_while_stmt ();
finish_while_stmt_cond (tsubst_expr (WHILE_COND (t),
args, in_decl),
NULL_TREE);
tsubst_expr (WHILE_BODY (t), args, in_decl);
finish_while_stmt (NULL_TREE);
}
break;
case DO_STMT:
{
tree cond;
lineno = TREE_COMPLEXITY (t);
emit_nop ();
emit_line_note (input_filename, lineno);
expand_start_loop_continue_elsewhere (1);
tsubst_expr (TREE_OPERAND (t, 0), args, in_decl);
expand_loop_continue_here ();
cond = tsubst_expr (TREE_OPERAND (t, 1), args, in_decl);
emit_line_note (input_filename, lineno);
expand_exit_loop_if_false (0, condition_conversion (cond));
expand_end_loop ();
clear_momentary ();
finish_stmt ();
begin_do_stmt ();
tsubst_expr (DO_BODY (t), args, in_decl);
finish_do_body (NULL_TREE);
finish_do_stmt (tsubst_expr (DO_COND (t), args,
in_decl),
NULL_TREE);
}
break;
case IF_STMT:
{
tree tmp;
int cond_scope = (TREE_CODE (TREE_OPERAND (t, 0)) == DECL_STMT);
lineno = TREE_COMPLEXITY (t);
if (cond_scope)
do_pushlevel ();
tmp = tsubst_expr (TREE_OPERAND (t, 0), args, in_decl);
emit_line_note (input_filename, lineno);
expand_start_cond (condition_conversion (tmp), 0);
if (tmp = TREE_OPERAND (t, 1), tmp)
tsubst_expr (tmp, args, in_decl);
begin_if_stmt ();
finish_if_stmt_cond (tsubst_expr (IF_COND (t),
args, in_decl),
NULL_TREE);
if (tmp = TREE_OPERAND (t, 2), tmp)
if (tmp = THEN_CLAUSE (t), tmp)
{
expand_start_else ();
tsubst_expr (tmp, args, in_decl);
finish_then_clause (NULL_TREE);
}
expand_end_cond ();
if (cond_scope)
do_poplevel ();
if (tmp = ELSE_CLAUSE (t), tmp)
{
begin_else_clause ();
tsubst_expr (tmp, args, in_decl);
finish_else_clause (NULL_TREE);
}
finish_stmt ();
finish_if_stmt ();
}
break;
case COMPOUND_STMT:
{
tree substmt = TREE_OPERAND (t, 0);
tree substmt;
lineno = TREE_COMPLEXITY (t);
if (COMPOUND_STMT_NO_SCOPE (t) == 0)
do_pushlevel ();
for (; substmt; substmt = TREE_CHAIN (substmt))
begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t));
for (substmt = COMPOUND_BODY (t);
substmt != NULL_TREE;
substmt = TREE_CHAIN (substmt))
tsubst_expr (substmt, args, in_decl);
if (COMPOUND_STMT_NO_SCOPE (t) == 0)
return do_poplevel ();
return finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t),
NULL_TREE);
}
break;
case BREAK_STMT:
lineno = TREE_COMPLEXITY (t);
emit_line_note (input_filename, lineno);
if (! expand_exit_something ())
error ("break statement not within loop or switch");
finish_break_stmt ();
break;
case CONTINUE_STMT:
lineno = TREE_COMPLEXITY (t);
emit_line_note (input_filename, lineno);
if (! expand_continue_loop (0))
error ("continue statement not within a loop");
finish_continue_stmt ();
break;
case SWITCH_STMT:
{
tree val, tmp;
int cond_scope = (TREE_CODE (TREE_OPERAND (t, 0)) == DECL_STMT);
lineno = TREE_COMPLEXITY (t);
if (cond_scope)
do_pushlevel ();
val = tsubst_expr (TREE_OPERAND (t, 0), args, in_decl);
emit_line_note (input_filename, lineno);
c_expand_start_case (val);
push_switch ();
begin_switch_stmt ();
val = tsubst_expr (SWITCH_COND (t), args, in_decl);
finish_switch_cond (val);
if (tmp = TREE_OPERAND (t, 1), tmp)
tsubst_expr (tmp, args, in_decl);
expand_end_case (val);
pop_switch ();
if (cond_scope)
do_poplevel ();
finish_stmt ();
finish_switch_stmt (val, NULL_TREE);
}
break;
case CASE_LABEL:
do_case (tsubst_expr (TREE_OPERAND (t, 0), args, in_decl),
tsubst_expr (TREE_OPERAND (t, 1), args, in_decl));
finish_case_label (tsubst_expr (CASE_LOW (t), args, in_decl),
tsubst_expr (CASE_HIGH (t), args, in_decl));
break;
case LABEL_DECL:
......@@ -4920,47 +4843,47 @@ tsubst_expr (t, args, in_decl)
case GOTO_STMT:
lineno = TREE_COMPLEXITY (t);
emit_line_note (input_filename, lineno);
if (TREE_CODE (TREE_OPERAND (t, 0)) == IDENTIFIER_NODE)
{
tree decl = lookup_label (TREE_OPERAND (t, 0));
TREE_USED (decl) = 1;
expand_goto (decl);
}
else
expand_computed_goto
(tsubst_expr (TREE_OPERAND (t, 0), args, in_decl));
finish_goto_stmt (tsubst_expr (GOTO_DESTINATION (t),
args, in_decl));
break;
case ASM_STMT:
lineno = TREE_COMPLEXITY (t);
finish_asm_stmt (tsubst_expr (ASM_CV_QUAL (t), args, in_decl),
tsubst_expr (ASM_STRING (t), args, in_decl),
tsubst_expr (ASM_OUTPUTS (t), args, in_decl),
tsubst_expr (ASM_INPUTS (t), args, in_decl),
tsubst_expr (ASM_CLOBBERS (t), args, in_decl));
break;
case TRY_BLOCK:
lineno = TREE_COMPLEXITY (t);
emit_line_note (input_filename, lineno);
expand_start_try_stmts ();
tsubst_expr (TREE_OPERAND (t, 0), args, in_decl);
expand_start_all_catch ();
begin_try_block ();
tsubst_expr (TRY_STMTS (t), args, in_decl);
finish_try_block (NULL_TREE);
{
tree handler = TREE_OPERAND (t, 1);
tree handler = TRY_HANDLERS (t);
for (; handler; handler = TREE_CHAIN (handler))
tsubst_expr (handler, args, in_decl);
}
expand_end_all_catch ();
finish_handler_sequence (NULL_TREE);
break;
case HANDLER:
lineno = TREE_COMPLEXITY (t);
do_pushlevel ();
if (TREE_OPERAND (t, 0))
begin_handler ();
if (HANDLER_PARMS (t))
{
tree d = TREE_OPERAND (t, 0);
tree d = HANDLER_PARMS (t);
expand_start_catch_block
(tsubst (TREE_OPERAND (d, 1), args, in_decl),
tsubst (TREE_OPERAND (d, 0), args, in_decl));
}
else
expand_start_catch_block (NULL_TREE, NULL_TREE);
tsubst_expr (TREE_OPERAND (t, 1), args, in_decl);
expand_end_catch_block ();
do_poplevel ();
finish_handler_parms (NULL_TREE);
tsubst_expr (HANDLER_BODY (t), args, in_decl);
finish_handler (NULL_TREE);
break;
case TAG_DEFN:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment