* class.c (instantiate_type): Change error message text.
* typeck2.c (store_init_value): Likewise.
+Tue Jan 31 13:28:56 1995 Mike Stump <mrs@cygnus.com>
+
+ * gc.c (get_typeid): Pawn off error messages to build_t_desc.
+ (build_t_desc): Inform the user here if they try and build
+ with -frtti and don't include <typeinfo.h>.
+
+ * decl2.c (finish_prevtable_vardecl): Support rescanning.
+ (finish_file): Move finish_prevtable_vardecl up to before the global
+ initializers are done as tdecls are initialized in the global
+ initializer. Also Pick up any new tdecls or vtables needed by
+ synthesized methods.
+
+ * class.c (finish_struct): Simplify. We have to do rtti scanning at
+ end, so we might as well do all of it there.
+
+Tue Jan 31 05:35:02 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * call.c (build_method_call): Fix -fthis-is-variable for 32-bit
+ targets, too.
+
+Tue Jan 31 00:11:04 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_prevtable_vardecl): New routine, mostly split from
+ finish_vtable_vardecl. It has the first half functionality from
+ that routine.
+ * decl2.c (finish_vtable_vardecl): Update to not include stuff not
+ in finish_prevtable_vardecl.
+ * decl2.c (finish_file): Call finish_prevtable_vardecl.
+ * gc.c (build_generic_desc): Allow it to be called when not at the
+ global binding layer, but behave as if we were.
+ (build_t_desc): Rearrange a bit so that it really works and is
+ easier to follow.
+ * class.c (finish_struct): Don't decide on tdecls here, as we have
+ to wait until the end of the file in general to decide whether or
+ not they come out.
+
+Mon Jan 30 01:00:40 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_delete): Check access to operator delete before
+ calling the destructor.
+ * method.c (build_opfncall, DELETE_EXPR): build_method is allowed to
+ return error_mark_node.
+ * call.c (build_method_call): Use the one-argument op delete even if
+ it's an error.
+
+ * init.c (build_new): Fix -fthis-is-variable support.
+ * call.c (build_method_call): Ditto.
+
+ * call.c (convert_harshness): Make conversion from a pointer to bool
+ worse than conversion to another pointer.
+
+Sat Jan 28 16:46:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * init.c (build_new): Check new return value if -fcheck-new.
+
+ * lex.c (check_newline): Clear end_of_file when we're done, too.
+
+Sat Jan 28 10:38:39 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Make rtti TD tables follow
+ vtables whereever they go.
+
+ * gc.c (build_t_desc): Remove old way of setting it up, as it wasn't
+ right.
+
+Sat Jan 28 09:10:44 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (finish_vtable_vardecl): Now set the
+ interface/implementation of vtables on the first virtual function,
+ if one exists, otherwise we use the old method. This is a major win
+ in terms of cutting down the size of objects and executables in
+ terms of text space and data space. Now most of the savings that
+ #pragma interface/implementation gives is automatic in a fair number
+ of cases.
+
+Sat Jan 28 04:57:33 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grokdeclarator): Discard the template parameters in a
+ template constructor declaration so that the function is always
+ named constructor_name (ctype).
+
+ * lex.c (check_newline): Use ungetc to put back the character before
+ calling HANDLE_PRAGMA.
+
+Fri Jan 27 17:23:47 1995 Mike Stump <mrs@cygnus.com>
+
+ * decl2.c (check_classfn): If the cname is T<int> and fn_name is T,
+ make sure we still match them.
+
+Fri Jan 27 16:32:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * parse.y: Add END_OF_LINE token.
+
+ * lex.c (check_newline): Set linemode when we see a # directive, and
+ unset it when we're done. Turn all 'return's into 'goto skipline'.
+ Fix all uses of '\n', since we won't see it anymore. Put back the
+ character we read before checking for a sysv or target pragma.
+ (real_yylex): If we see an EOF in linemode, return END_OF_LINE.
+ (handle_sysv_pragma): Don't look at the input stream; quit when we
+ see an END_OF_LINE token.
+
+ * input.c (getch): Return EOF if we're in line mode and at the end
+ of a line.
+ (put_back): Don't put back an EOF.
+
+Thu Jan 26 19:26:34 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (expand_throw): Do the newing of the exception object
+ before we load the type descriptor or the address so that we don't
+ wipe any of the values out.
+
+Thu Jan 26 19:20:00 1995 Mike Stump <mrs@cygnus.com>
+
+ * except.c (init_exception_processing): Don't use r12 on the rs6000.
+
+Tue Jan 24 16:36:31 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (grokparms): Don't try to build up a reference at this point.
+
+ * typeck2.c (build_functional_cast): Don't assume that a NOP_EXPR
+ will suffice to convert from integer_zero_node.
+
Mon Jan 23 21:57:14 1995 Mike Stump <mrs@cygnus.com>
* pt.c (tsubst): When we copy a node, don't forget to copy
if (codel == BOOLEAN_TYPE)
{
- if (INTEGRAL_CODE_P (coder) || coder == REAL_TYPE
- || coder == POINTER_TYPE || coder == OFFSET_TYPE)
+ if (INTEGRAL_CODE_P (coder) || coder == REAL_TYPE)
return STD_RETURN (h);
+ else if (coder == POINTER_TYPE || coder == OFFSET_TYPE)
+ {
+ /* Make this worse than any conversion to another pointer.
+ FIXME this is how I think the language should work, but it may not
+ end up being how the language is standardized (jason 1/30/95). */
+ h.distance = 32767;
+ return STD_RETURN (h);
+ }
return EVIL_RETURN (h);
}
result = build_method_call (instance, name, parms, basetype_path,
(LOOKUP_SPECULATIVELY|flags)
&~LOOKUP_COMPLAIN);
- /* If it works, return it. */
- if (result && result != error_mark_node)
+ /* If it finds a match, return it. */
+ if (result)
return build_method_call (instance, name, parms, basetype_path, flags);
/* If it doesn't work, two argument delete must work */
TREE_CHAIN (parms) = save_last;
{
constp = 0;
volatilep = 0;
- parms = tree_cons (NULL_TREE,
- build1 (NOP_EXPR, TYPE_POINTER_TO (basetype),
- integer_zero_node), parms);
+ instance_ptr = build_int_2 (0, 0);
+ TREE_TYPE (instance_ptr) = TYPE_POINTER_TO (basetype);
+ parms = tree_cons (NULL_TREE, instance_ptr, parms);
}
else
{
TYPE_BEING_DEFINED (t) = 0;
hack_incomplete_structures (t);
- if (flag_rtti && TYPE_VIRTUAL_P (t) && CLASSTYPE_VTABLE_NEEDS_WRITING (t))
- {
- tree variants;
- tree tdecl, td;
-
- /* Now instantiate its type descriptors. */
- td = build_t_desc (t, 1);
- if (td == NULL_TREE)
- {
- cp_error ("failed to build type descriptor node of '%T', maybe typeinfo.h not included", t);
- tdecl = NULL_TREE;
- }
- else
- tdecl = TREE_OPERAND (td, 0);
-
-#if 0
- /* I see no need for building the following TD */
- variants = TYPE_POINTER_TO (t);
- build_type_variant (variants, 1, 0);
- while (variants)
- {
- build_t_desc (variants, 1);
- variants = TYPE_NEXT_VARIANT (variants);
- }
-#endif
- variants = build_reference_type (t);
- build_type_variant (variants, 1, 0);
- while (variants)
- {
- build_t_desc (variants, 1);
- variants = TYPE_NEXT_VARIANT (variants);
- }
- if (tdecl != NULL_TREE)
- DECL_CONTEXT (tdecl) = t;
- }
-#if 0
- /* Still need to instantiate this C struct's type descriptor. */
- else if (flag_rtti && ! CLASSTYPE_RTTI (t))
- build_t_desc (t, 1);
-#endif
-
#if 0
if (TYPE_NAME (t) && TYPE_IDENTIFIER (t))
undo_template_name_overload (TYPE_IDENTIFIER (t), 1);
return 0;
}
innermost_code = TREE_CODE (decl);
- decl = TREE_OPERAND (decl, 0);
if (decl_context == FIELD && ctype == NULL_TREE)
ctype = current_class_type;
+ if (ctype
+ && TREE_OPERAND (decl, 0) == constructor_name_full (ctype))
+ TREE_OPERAND (decl, 0) = constructor_name (ctype);
+ decl = TREE_OPERAND (decl, 0);
if (ctype != NULL_TREE
&& decl != NULL_TREE && flags != DTOR_FLAG
&& decl == constructor_name (ctype))
}
}
+ if (ctype
+ && TREE_OPERAND (decl, 1) == constructor_name_full (ctype))
+ TREE_OPERAND (decl, 1) = constructor_name (ctype);
decl = TREE_OPERAND (decl, 1);
if (ctype)
{
}
else if (TREE_CODE (decl) == BIT_NOT_EXPR
&& TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE
- && constructor_name (ctype) == TREE_OPERAND (decl, 0))
+ && (constructor_name (ctype) == TREE_OPERAND (decl, 0)
+ || constructor_name_full (ctype) == TREE_OPERAND (decl, 0)))
{
return_type = return_dtor;
ctor_return_type = ctype;
flags = DTOR_FLAG;
- decl = TREE_OPERAND (decl, 0);
+ decl = TREE_OPERAND (decl, 0) = constructor_name (ctype);
}
}
}
else
init = require_instantiated_type (type, init, integer_zero_node);
- init = convert_for_initialization
- (NULL_TREE, type, init, LOOKUP_NORMAL,
- "argument passing", 0, 0);
+ /* Don't actually try to build up a reference here. */
+ {
+ tree t = type;
+ if (TREE_CODE (t) == REFERENCE_TYPE)
+ t = TREE_TYPE (t);
+ init = convert_for_initialization
+ (NULL_TREE, t, init, LOOKUP_NORMAL,
+ "argument passing", 0, 0);
+ }
}
#if 0 /* This is too early to check; trailing parms might be merged in by
duplicate_decls. */
int flag_operator_names;
+/* Nonzero if we want to check the return value of new and avoid calling
+ constructors if it is a null pointer. */
+
+int flag_check_new;
+
/* Table of language-dependent -f options.
STRING is the option name. VARIABLE is the address of the variable.
ON_VALUE is the value to store in VARIABLE
{"access-control", &flag_access_control, 1},
{"nonansi-builtins", &flag_no_nonansi_builtin, 0},
{"gnu-keywords", &flag_no_gnu_keywords, 0},
- {"operator-names", &flag_operator_names, 1}
+ {"operator-names", &flag_operator_names, 1},
+ {"check-new", &flag_check_new, 1}
};
/* Decode the string P as a language-specific option.
end = TREE_VEC_END (method_vec);
/* First suss out ctors and dtors. */
- if (*methods && fn_name == cname)
+ if (*methods
+ && (fn_name == cname || fn_name == DECL_NAME (*methods)))
goto got_it;
while (++methods != end)
}
}
-/* Set TREE_PUBLIC and/or TREE_EXTERN on the vtable DECL,
+/* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL,
based on TYPE and other static flags.
Note that anything public is tagged TREE_PUBLIC, whether
}
static void
-finish_vtable_vardecl (prev, vars)
+finish_prevtable_vardecl (prev, vars)
tree prev, vars;
{
tree ctype = DECL_CONTEXT (vars);
import_export_template (ctype);
import_export_vtable (vars, ctype);
- if (flag_vtable_thunks && !CLASSTYPE_INTERFACE_KNOWN (ctype))
+ if (CLASSTYPE_INTERFACE_UNKNOWN (ctype))
{
tree method;
for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE;
&& !DECL_ABSTRACT_VIRTUAL_P (method))
{
SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
+ CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method);
CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method);
TREE_PUBLIC (vars) = 1;
DECL_EXTERNAL (vars) = DECL_EXTERNAL (method);
{
extern tree the_null_vtable_entry;
- /* Stuff this virtual function table's size into
- `pfn' slot of `the_null_vtable_entry'. */
-#if 0
- /* we do not put size as first entry any more */
- tree nelts = array_type_nelts (TREE_TYPE (vars));
- if (flag_vtable_thunks)
- TREE_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (vars))) = nelts;
- else
- SET_FNADDR_FROM_VTABLE_ENTRY (the_null_vtable_entry, nelts);
-#endif
-
/* Kick out the type descriptor before writing out the vtable. */
if (flag_rtti)
- rest_of_decl_compilation (TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (CONSTRUCTOR_ELTS (DECL_INITIAL (vars)))), 0), 0, 1, 1);
+ {
+ build_t_desc (ctype, 1);
+ }
+
+ /* Write it out. */
+ mark_vtable_entries (vars);
+ }
+}
+
+static void
+finish_vtable_vardecl (prev, vars)
+ tree prev, vars;
+{
+ tree ctype = DECL_CONTEXT (vars);
+ import_export_template (ctype);
+ import_export_vtable (vars, ctype);
+
+ if (CLASSTYPE_INTERFACE_UNKNOWN (ctype))
+ {
+ tree method;
+ for (method = CLASSTYPE_METHODS (ctype); method != NULL_TREE;
+ method = DECL_NEXT_METHOD (method))
+ {
+ if (DECL_VINDEX (method) != NULL_TREE && !DECL_SAVED_INSNS (method)
+ && !DECL_ABSTRACT_VIRTUAL_P (method))
+ {
+ SET_CLASSTYPE_INTERFACE_KNOWN (ctype);
+ CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = ! DECL_EXTERNAL (method);
+ CLASSTYPE_INTERFACE_ONLY (ctype) = DECL_EXTERNAL (method);
+ TREE_PUBLIC (vars) = 1;
+ DECL_EXTERNAL (vars) = DECL_EXTERNAL (method);
+ if (flag_rtti)
+ cp_warning ("compiler error: rtti entry for `%T' decided too late", ctype);
+ break;
+ }
+ }
+ }
+
+ if (write_virtuals >= 0
+ && ! DECL_EXTERNAL (vars) && (TREE_PUBLIC (vars) || TREE_USED (vars)))
+ {
+ extern tree the_null_vtable_entry;
/* Write it out. */
mark_vtable_entries (vars);
needs_messing_up |= TYPE_NEEDS_CONSTRUCTING (type);
vars = TREE_CHAIN (vars);
}
- if (needs_cleaning == 0)
- goto mess_up;
/* Otherwise, GDB can get confused, because in only knows
about source for LINENO-1 lines. */
lineno -= 1;
+ interface_unknown = 1;
+ interface_only = 0;
+
+ /* Walk to mark the inline functions we need, then output them so
+ that we can pick up any other tdecls that those routines need. */
+ walk_vtables ((void (*)())0, finish_prevtable_vardecl);
+ for (vars = saved_inlines; vars; vars = TREE_CHAIN (vars))
+ {
+ tree decl = TREE_VALUE (vars);
+
+ if (DECL_ARTIFICIAL (decl)
+ && ! DECL_INITIAL (decl)
+ && (TREE_USED (decl) || ! DECL_EXTERNAL (decl)))
+ synthesize_method (decl);
+ }
+ walk_vtables ((void (*)())0, finish_prevtable_vardecl);
+
+ if (needs_cleaning == 0)
+ goto mess_up;
+
fnname = get_file_function_name ('D');
start_function (void_list_node, build_parse_node (CALL_EXPR, fnname, void_list_node, NULL_TREE), 0, 0);
fnname = DECL_ASSEMBLER_NAME (current_function_decl);
pushdecl (vars);
#endif
- interface_unknown = 1;
- interface_only = 0;
-
- for (vars = saved_inlines; vars; vars = TREE_CHAIN (vars))
- {
- tree decl = TREE_VALUE (vars);
-
- if (DECL_ARTIFICIAL (decl)
- && ! DECL_INITIAL (decl)
- && (TREE_USED (decl) || ! DECL_EXTERNAL (decl)))
- synthesize_method (decl);
- }
-
walk_vtables ((void (*)())0, finish_vtable_vardecl);
if (flag_handle_signatures)
walk_sigtables ((void (*)())0, finish_sigtable_vardecl);
exception, so that the matching routine knows to search out. */
label = gen_label_rtx ();
emit_label (label);
- emit_move_insn (saved_pc, gen_rtx (LABEL_REF, Pmode, label));
if (exp)
{
rtx throw_type_rtx = expand_expr (throw_type, NULL_RTX, VOIDmode, 0);
rtx throw_value_rtx;
- emit_move_insn (saved_throw_type, throw_type_rtx);
exp = convert_to_reference (build_reference_type (build_type_variant (TREE_TYPE (exp), 1, 0)), exp, CONV_STATIC, LOOKUP_COMPLAIN, error_mark_node);
/* Make a copy of the thrown object. WP 15.1.5 */
error (" in thrown expression");
throw_value_rtx = expand_expr (exp, NULL_RTX, VOIDmode, 0);
emit_move_insn (saved_throw_value, throw_value_rtx);
+ emit_move_insn (saved_throw_type, throw_type_rtx);
}
}
else
/* This part is easy, as we dont' have to do anything else. */
}
+ emit_move_insn (saved_pc, gen_rtx (LABEL_REF, Pmode, label));
make_first_label(throw_label);
emit_jump (throw_label);
}
PLACEMENT is the `placement' list for user-defined operator new (). */
+extern int flag_check_new;
+
tree
build_new (placement, decl, init, use_global_new)
tree placement;
{
tree type, true_type, size, rval;
tree nelts;
+ tree alloc_expr;
int has_array = 0;
enum tree_code code = NEW_EXPR;
TREE_CALLS_NEW (rval) = 1;
}
+ if (flag_check_new)
+ {
+ if (rval)
+ rval = save_expr (rval);
+ alloc_expr = rval;
+ }
+
/* if rval is NULL_TREE I don't have to allocate it, but are we totally
sure we have some extra bytes in that case for the BI_header_size
cookies? And how does that interact with the code below? (mrs) */
{
tree tmp = rval;
- if (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE)
+ if (tmp && TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE)
tmp = build_indirect_ref (tmp, NULL_PTR);
newrval = build_method_call (tmp, constructor_name_full (true_type),
}
}
done:
+
+ if (flag_check_new && alloc_expr && rval != alloc_expr)
+ {
+ tree ifexp = build_binary_op (NE_EXPR, alloc_expr, integer_zero_node, 1);
+ rval = build_conditional_expr (ifexp, rval, convert (TREE_TYPE (rval),
+ integer_zero_node));
+ }
+
if (rval && TREE_TYPE (rval) != build_pointer_type (type))
{
/* The type of new int [3][3] is not int *, but int [3] * */
auto_delete, integer_two_node));
}
else
- passed_auto_delete = auto_delete;
+ {
+ if (TYPE_GETS_REG_DELETE (type))
+ {
+ /* Only do access checking here; we'll be calling op delete
+ from the destructor. */
+ tree t = build_opfncall (DELETE_EXPR, LOOKUP_NORMAL, addr,
+ size_zero_node, NULL_TREE);
+ if (t == error_mark_node)
+ return error_mark_node;
+ }
+ passed_auto_delete = auto_delete;
+ }
if (flags & LOOKUP_PROTECT)
{
struct pending_input *to_be_restored; /* XXX */
extern int end_of_file;
-int
-getch ()
+static inline int
+sub_getch ()
{
if (putback_char != -1)
{
put_back (ch)
int ch;
{
- my_friendly_assert (putback_char == -1, 224);
- putback_char = ch;
+ if (ch != EOF)
+ {
+ my_friendly_assert (putback_char == -1, 224);
+ putback_char = ch;
+ }
+}
+
+extern int linemode;
+
+int
+getch ()
+{
+ int ch = sub_getch ();
+ if (linemode && ch == '\n')
+ {
+ put_back (ch);
+ ch = EOF;
+ }
+ return ch;
}
inline
If the line is a #-directive, read the entire line and return a newline.
Otherwise, return the line's first non-whitespace character. */
+int linemode;
+
int
check_newline ()
{
return c;
}
+ /* Don't read beyond this line. */
+ linemode = 1;
+
/* Read first nonwhite char after the `#'. */
do
&& getch () == 'b'
&& getch () == 'l'
&& getch () == 'e'
- && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
+ && ((c = getch ()) == ' ' || c == '\t'))
{
extern tree pending_vtables;
if (nextchar < 0)
nextchar = getch ();
c = nextchar;
- if (c != '\n')
+ if (c != EOF)
warning ("trailing characters ignored");
}
else if (c == 'u'
&& getch () == 'n'
&& getch () == 'i'
&& getch () == 't'
- && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
+ && ((c = getch ()) == ' ' || c == '\t'))
{
/* More follows: it must be a string constant (unit name). */
token = real_yylex ();
if (nextchar < 0)
nextchar = getch ();
c = nextchar;
- if (c != '\n')
+ if (c != EOF)
warning ("trailing characters ignored");
}
else if (c == 'i')
&& getch () == 'a'
&& getch () == 'c'
&& getch () == 'e'
- && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
+ && ((c = getch ()) == ' ' || c == '\t' || c == EOF))
{
int warned_already = 0;
char *main_filename = input_filename;
main_filename = FILE_NAME_NONDIRECTORY (main_filename);
while (c == ' ' || c == '\t')
c = getch ();
- if (c != '\n')
+ if (c != EOF)
{
put_back (c);
token = real_yylex ();
while (c == ' ' || c == '\t')
c = getch ();
- while (c != '\n')
+ while (c != EOF)
{
if (!warned_already && extra_warnings
- && c != ' ' && c != '\t' && c != '\n')
+ && c != ' ' && c != '\t')
{
warning ("garbage after `#pragma interface' ignored");
warned_already = 1;
&& getch () == 'i'
&& getch () == 'o'
&& getch () == 'n'
- && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
+ && ((c = getch ()) == ' ' || c == '\t' || c == EOF))
{
int warned_already = 0;
char *main_filename = main_input_filename ? main_input_filename : input_filename;
main_filename = FILE_NAME_NONDIRECTORY (main_filename);
while (c == ' ' || c == '\t')
c = getch ();
- if (c != '\n')
+ if (c != EOF)
{
put_back (c);
token = real_yylex ();
while (c == ' ' || c == '\t')
c = getch ();
- while (c != '\n')
+ while (c != EOF)
{
if (!warned_already && extra_warnings
- && c != ' ' && c != '\t' && c != '\n')
+ && c != ' ' && c != '\t')
{
warning ("garbage after `#pragma implementation' ignored");
warned_already = 1;
}
#ifdef HANDLE_SYSV_PRAGMA
else
- return handle_sysv_pragma (finput, c);
+ {
+ put_back (c);
+ handle_sysv_pragma ();
+ }
#else
#ifdef HANDLE_PRAGMA
+ /* FIXME: This will break if we're doing any of the C++ input
+ tricks. */
else
- HANDLE_PRAGMA (finput);
+ {
+ ungetc (c, finput);
+ HANDLE_PRAGMA (finput);
+ }
#endif
#endif
}
&& getch () == 'i'
&& getch () == 'n'
&& getch () == 'e'
- && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
+ && ((c = getch ()) == ' ' || c == '\t'))
{
#ifdef DWARF_DEBUGGING_INFO
if ((debug_info_level == DINFO_LEVEL_VERBOSE)
&& getch () == 'd'
&& getch () == 'e'
&& getch () == 'f'
- && ((c = getch ()) == ' ' || c == '\t' || c == '\n'))
+ && ((c = getch ()) == ' ' || c == '\t'))
{
#ifdef DWARF_DEBUGGING_INFO
if ((debug_info_level == DINFO_LEVEL_VERBOSE)
c = getch ();
/* If no argument, ignore the line. */
- if (c == '\n')
- return c;
+ if (c == EOF)
+ goto skipline;
put_back (c);
token = real_yylex ();
/* If the # is the only nonwhite char on the line,
just ignore it. Check the new newline. */
- if (c == '\n')
- return c;
+ if (c == EOF)
+ goto skipline;
/* Something follows the #; read a token. */
int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
c = get_last_nonwhite_on_line ();
- if (c == '\n')
+ if (c == EOF)
{
/* No more: store the line number and check following line. */
lineno = l;
- return c;
+ goto skipline;
}
put_back (c);
extract_interface_info ();
c = get_last_nonwhite_on_line ();
- if (c != '\n')
+ if (c != EOF)
{
put_back (c);
if (action)
{
c = get_last_nonwhite_on_line ();
- if (c != '\n')
+ if (c != EOF)
{
put_back (c);
token = real_yylex ();
entering_system_header = 1;
c = get_last_nonwhite_on_line ();
- if (c != '\n')
+ if (c != EOF)
{
put_back (c);
token = real_yylex ();
entering_c_header = 1;
c = get_last_nonwhite_on_line ();
- if (c != '\n')
+ if (c != EOF)
{
put_back (c);
token = real_yylex ();
}
/* If NEXTCHAR is not end of line, we don't care what it is. */
- if (nextchar == '\n')
- return '\n';
+ if (nextchar == EOF)
+ c = EOF;
}
else
error ("invalid #-line");
/* skip the rest of this line. */
skipline:
- if (c == '\n')
- return c;
+ linemode = 0;
+ end_of_file = 0;
while ((c = getch ()) != EOF && c != '\n');
return c;
}
end_of_file = 1;
if (input_redirected ())
value = END_OF_SAVED_INPUT;
+ else if (linemode)
+ value = END_OF_LINE;
else if (do_pending_expansions ())
/* this will set yychar for us */
return yychar;
/* This function has to be in this file, in order to get at
the token types. */
-int
-handle_sysv_pragma (input, c)
- FILE *input;
- int c;
+handle_sysv_pragma ()
{
for (;;)
{
- while (c == ' ' || c == '\t')
- c = getc (input);
- if (c == '\n' || c == EOF)
- {
- handle_pragma_token (0, 0);
- return c;
- }
- ungetc (c, input);
switch (yylex ())
{
case IDENTIFIER:
case CONSTANT:
handle_pragma_token (token_buffer, yylval.ttype);
break;
+ case END_OF_LINE:
+ handle_pragma_token (0, 0);
+ return;
default:
handle_pragma_token (token_buffer, 0);
}
- if (nextchar >= 0)
- c = nextchar, nextchar = -1;
- else
- c = getc (input);
}
}
#endif /* HANDLE_SYSV_PRAGMA */
fnname, tree_cons (NULL_TREE, xarg1,
build_tree_list (NULL_TREE, xarg2)),
NULL_TREE, flags);
- /* This happens when the user mis-declares `operator delete'.
- Should now be impossible. */
+#if 0
+ /* This can happen when operator delete is protected. */
my_friendly_assert (rval != error_mark_node, 250);
TREE_TYPE (rval) = void_type_node;
+#endif
return rval;
}
break;
%type <strtype> .pushlevel
+/* Used in lex.c for parsing pragmas. */
+%token END_OF_LINE
+
/* spew.c depends on this being the last token. Define
any new tokens before this one! */
%token END_OF_SAVED_INPUT
{
/* this must build a C cast */
if (parms == NULL_TREE)
- return build1 (NOP_EXPR, type, integer_zero_node);
+ parms = integer_zero_node;
else if (TREE_CHAIN (parms) != NULL_TREE)
{
pedwarn ("initializer list being treated as compound expression");