/* Separate lexical analyzer for GNU C++.
- Copyright (C) 1987, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1987, 89, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
#include "input.h"
#include "tree.h"
#include "lex.h"
-#include "parse.h"
#include "cp-tree.h"
+#include "parse.h"
#include "flags.h"
#include "obstack.h"
#include "c-pragma.h"
\f
/* Return something to represent absolute declarators containing a *.
TARGET is the absolute declarator that the * contains.
- TYPE_QUALS is a list of modifiers such as const or volatile
+ CV_QUALIFIERS is a list of modifiers such as const or volatile
to apply to the pointer type, represented as identifiers.
We return an INDIRECT_REF whose "contents" are TARGET
and whose type is the modifier list. */
tree
-make_pointer_declarator (type_quals, target)
- tree type_quals, target;
+make_pointer_declarator (cv_qualifiers, target)
+ tree cv_qualifiers, target;
{
if (target && TREE_CODE (target) == IDENTIFIER_NODE
&& ANON_AGGRNAME_P (target))
error ("type name expected before `*'");
target = build_parse_node (INDIRECT_REF, target);
- TREE_TYPE (target) = type_quals;
+ TREE_TYPE (target) = cv_qualifiers;
return target;
}
/* Return something to represent absolute declarators containing a &.
TARGET is the absolute declarator that the & contains.
- TYPE_QUALS is a list of modifiers such as const or volatile
+ CV_QUALIFIERS is a list of modifiers such as const or volatile
to apply to the reference type, represented as identifiers.
We return an ADDR_EXPR whose "contents" are TARGET
and whose type is the modifier list. */
tree
-make_reference_declarator (type_quals, target)
- tree type_quals, target;
+make_reference_declarator (cv_qualifiers, target)
+ tree cv_qualifiers, target;
{
if (target)
{
error ("type name expected before `&'");
}
target = build_parse_node (ADDR_EXPR, target);
- TREE_TYPE (target) = type_quals;
+ TREE_TYPE (target) = cv_qualifiers;
+ return target;
+}
+
+tree
+make_call_declarator (target, parms, cv_qualifiers, exception_specification)
+ tree target, parms, cv_qualifiers, exception_specification;
+{
+ target = build_parse_node (CALL_EXPR, target, parms, cv_qualifiers);
+ TREE_TYPE (target) = exception_specification;
return target;
}
+
+void
+set_quals_and_spec (call_declarator, cv_qualifiers, exception_specification)
+ tree call_declarator, cv_qualifiers, exception_specification;
+{
+ TREE_OPERAND (call_declarator, 2) = cv_qualifiers;
+ TREE_TYPE (call_declarator) = exception_specification;
+}
\f
/* Build names and nodes for overloaded operators. */
#include "hash.h"
\f
-int check_newline ();
+static int check_newline ();
/* Nonzero tells yylex to ignore \ in string constants. */
static int ignore_escape_flag = 0;
\f
/* Table indexed by tree code giving a string containing a character
classifying the tree code. Possibilities are
- t, d, s, c, r, <, 1 and 2. See cp/tree.def for details. */
+ t, d, s, c, r, <, 1 and 2. See cp/cp-tree.def for details. */
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
char *cplus_tree_code_type[] = {
"x",
-#include "tree.def"
+#include "cp-tree.def"
};
#undef DEFTREECODE
int cplus_tree_code_length[] = {
0,
-#include "tree.def"
+#include "cp-tree.def"
};
#undef DEFTREECODE
char *cplus_tree_code_name[] = {
"@@dummy",
-#include "tree.def"
+#include "cp-tree.def"
};
#undef DEFTREECODE
\f
/* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989.
Stuck this hack in to get the files open correctly; this is called
in place of init_lex if we are an unexec'd binary. */
+
+#if 0
void
reinit_lang_specific ()
{
init_filename_times ();
reinit_search_statistics ();
}
+#endif
int *init_parse ();
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER],
build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER]));
- /* C++ extensions. These are probably not correctly named. */
+ /* C++ extensions. These are probably not correctly named. */
ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_WCHAR],
build_tree_list (NULL_TREE, ridpointers[(int) RID_WCHAR]));
ridpointers[(int) RID_TEMPLATE] = get_identifier ("template");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TEMPLATE],
build_tree_list (NULL_TREE, ridpointers[(int) RID_TEMPLATE]));
- /* This is for ANSI C++. */
+ /* This is for ANSI C++. */
ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE],
build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE]));
TREE_TYPE (signature_type_node) = signature_type_node;
ridpointers[(int) RID_SIGNATURE] = signature_type_node;
+ null_node = build_int_2 (0, 0);
+ ridpointers[RID_NULL] = null_node;
+
opname_tab[(int) COMPONENT_REF] = "->";
opname_tab[(int) MEMBER_REF] = "->*";
opname_tab[(int) METHOD_CALL_EXPR] = "->()";
- opname_tab[(int) INDIRECT_REF] = "(unary *)";
+ opname_tab[(int) INDIRECT_REF] = "*";
opname_tab[(int) ARRAY_REF] = "[]";
opname_tab[(int) MODIFY_EXPR] = "=";
opname_tab[(int) NEW_EXPR] = "new";
opname_tab[(int) DELETE_EXPR] = "delete";
opname_tab[(int) VEC_NEW_EXPR] = "new []";
opname_tab[(int) VEC_DELETE_EXPR] = "delete []";
- opname_tab[(int) COND_EXPR] = "... ? ... : ...";
+ opname_tab[(int) COND_EXPR] = "?:";
opname_tab[(int) CALL_EXPR] = "()";
opname_tab[(int) PLUS_EXPR] = "+";
opname_tab[(int) MINUS_EXPR] = "-";
opname_tab[(int) EQ_EXPR] = "==";
opname_tab[(int) NE_EXPR] = "!=";
opname_tab[(int) IN_EXPR] = "in";
- opname_tab[(int) RANGE_EXPR] = "..";
- opname_tab[(int) CONVERT_EXPR] = "(unary +)";
- opname_tab[(int) ADDR_EXPR] = "(unary &)";
+ opname_tab[(int) RANGE_EXPR] = "...";
+ opname_tab[(int) CONVERT_EXPR] = "+";
+ opname_tab[(int) ADDR_EXPR] = "&";
opname_tab[(int) PREDECREMENT_EXPR] = "--";
opname_tab[(int) PREINCREMENT_EXPR] = "++";
opname_tab[(int) POSTDECREMENT_EXPR] = "--";
#if 0
/* let's parse things, and if they use it, then give them an error. */
- if (!flag_handle_exceptions)
+ if (!flag_exceptions)
{
UNSET_RESERVED_WORD ("throw");
UNSET_RESERVED_WORD ("try");
UNSET_RESERVED_WORD ("xor");
UNSET_RESERVED_WORD ("xor_eq");
}
- if (! flag_traditional)
- UNSET_RESERVED_WORD ("overload");
token_count = init_parse ();
interface_unknown = 1;
case SCSPEC:
case PRE_PARSED_CLASS_DECL:
t = yylval.ttype;
+ if (TREE_CODE (t) == TYPE_DECL)
+ {
+ fprintf (file, " `%s'", DECL_NAME (t));
+ break;
+ }
my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224);
if (IDENTIFIER_POINTER (t))
fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp);
for (i = 0; i < TOKEN_LENGTH; i++)
{
- int index = sorted[i];
- if (token_count[index] == 0)
+ int idx = sorted[i];
+ if (token_count[idx] == 0)
break;
- if (token_count[index] < token_count[-1])
+ if (token_count[idx] < token_count[-1])
break;
fprintf (stderr, "token %d, `%s', count = %d\n",
- index, yytname[YYTRANSLATE (index)], token_count[index]);
+ idx, yytname[YYTRANSLATE (idx)], token_count[idx]);
}
fprintf (stderr, "\n");
for (i = 0; i < REDUCE_LENGTH; i++)
qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp);
for (i = 0; i < REDUCE_LENGTH; i++)
{
- int index = sorted[i];
- if (reduce_count[index] == 0)
+ int idx = sorted[i];
+ if (reduce_count[idx] == 0)
break;
- if (reduce_count[index] < reduce_count[-1])
+ if (reduce_count[idx] < reduce_count[-1])
break;
fprintf (stderr, "rule %d, line %d, count = %d\n",
- index, yyrline[index], reduce_count[index]);
+ idx, yyrline[idx], reduce_count[idx]);
}
fprintf (stderr, "\n");
#endif
/* Sets the value of the 'yydebug' variable to VALUE.
This is a function so we don't have to have YYDEBUG defined
in order to build the compiler. */
+
void
set_yydebug (value)
int value;
/* Helper function to load global variables with interface
information. */
+
void
extract_interface_info ()
{
/* Return nonzero if S is not considered part of an
INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */
+
static int
interface_strcmp (s)
char *s;
return 1;
}
-void
+static void
set_typedecl_interface_info (prev, vars)
tree prev, vars;
{
= interface_strcmp (FILE_NAME_NONDIRECTORY (DECL_SOURCE_FILE (vars)));
}
-void
+static int
set_vardecl_interface_info (prev, vars)
tree prev, vars;
{
if (CLASSTYPE_INTERFACE_KNOWN (type))
{
if (CLASSTYPE_INTERFACE_ONLY (type))
- set_typedecl_interface_info (prev, TYPE_NAME (type));
+ set_typedecl_interface_info (prev, TYPE_MAIN_DECL (type));
else
CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type);
TREE_PUBLIC (vars) = 1;
+ return 1;
}
+ return 0;
}
\f
/* Called from the top level: if there are any pending inlines to
do, set up to process them now. This function sets up the first function
to be parsed; after it has been, the rule for fndef in parse.y will
call process_next_inline to start working on the next one. */
+
void
do_pending_inlines ()
{
/* Called from the fndecl rule in the parser when the function just parsed
was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from
do_pending_inlines). */
+
void
process_next_inline (t)
tree t;
if (yychar != END_OF_SAVED_INPUT)
{
error ("parse error at end of saved function text");
+
/* restore_pending_input will abort unless yychar is either
- * END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
- * hosed, feed back YYEMPTY.
- * We also need to discard nextchar, since that may have gotten
- * set as well.
- */
+ END_OF_SAVED_INPUT or YYEMPTY; since we already know we're
+ hosed, feed back YYEMPTY. We also need to discard nextchar,
+ since that may have gotten set as well. */
nextchar = -1;
}
yychar = YYEMPTY;
/* Return next non-whitespace input character, which may come
from `finput', or from `nextchar'. */
+
static int
yynextch ()
{
/* Unget character CH from the input stream.
If RESCAN is non-zero, then we want to `see' this
character as the next input token. */
+
void
yyungetc (ch, rescan)
int ch;
pending_inlines = t;
}
-void reinit_parse_for_block ();
+static void reinit_parse_for_block PROTO((int, struct obstack *));
void
reinit_parse_for_method (yychar, decl)
/* Consume a block -- actually, a method beginning
with `:' or `{' -- and save it away on the specified obstack. */
-void
+static void
reinit_parse_for_block (pyychar, obstackp)
int pyychar;
struct obstack *obstackp;
break;
case 5:
- type = build_type_variant (type, 1, 0);
- /* Fall through... */
case 6:
retref = 1;
- declspecs = build_decl_list (NULL_TREE, full_name);
+ declspecs = build_decl_list (NULL_TREE, type);
+
+ if (kind == 5)
+ type = build_type_variant (type, 1, 0);
name = ansi_opname [(int) MODIFY_EXPR];
TREE_PARMLIST (args) = 1;
{
- tree declarator = build_parse_node (CALL_EXPR, name, args, NULL_TREE);
+ tree declarator = make_call_declarator (name, args, NULL_TREE, NULL_TREE);
if (retref)
declarator = build_parse_node (ADDR_EXPR, declarator);
- fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE,
- NULL_TREE, NULL_TREE);
+ fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE);
}
if (fn == void_type_node)
return fn;
+ if (kind > 2)
+ SET_DECL_ARTIFICIAL (TREE_CHAIN (DECL_ARGUMENTS (fn)));
+
#if 0
if (processing_template_defn)
{
}
#endif
+#if 0
if (CLASSTYPE_INTERFACE_KNOWN (type))
{
DECL_INTERFACE_KNOWN (fn) = 1;
&& flag_implement_inlines);
}
else
+#endif
DECL_NOT_REALLY_EXTERN (fn) = 1;
mark_inline_for_output (fn);
/* Heuristic to tell whether the user is missing a semicolon
after a struct or enum declaration. Emit an error message
if we know the user has blown it. */
+
void
check_for_missing_semicolon (type)
tree type;
if ((yychar > 255
&& yychar != SCSPEC
&& yychar != IDENTIFIER
- && yychar != TYPENAME)
+ && yychar != TYPENAME
+ && yychar != SELFNAME)
|| end_of_file)
{
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
int linemode;
-int
+#ifdef HANDLE_SYSV_PRAGMA
+static int handle_sysv_pragma ();
+#endif
+static int handle_cp_pragma ();
+
+static int
check_newline ()
{
register int c;
&& getch () == 'm'
&& getch () == 'a')
{
- /* Read first nonwhite char after the `#pragma'. */
-
- do
- c = getch ();
- while (c == ' ' || c == '\t');
-
- if (c == 'v'
- && getch () == 't'
- && getch () == 'a'
- && getch () == 'b'
- && getch () == 'l'
- && getch () == 'e'
- && ((c = getch ()) == ' ' || c == '\t'))
+ token = real_yylex ();
+ if (token == IDENTIFIER
+ && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE)
{
- extern tree pending_vtables;
-
- /* More follows: it must be a string constant (class name). */
- token = real_yylex ();
- if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
- {
- error ("invalid #pragma vtable");
- goto skipline;
- }
- if (write_virtuals != 2)
- {
- warning ("use `+e2' option to enable #pragma vtable");
- goto skipline;
- }
- pending_vtables = perm_tree_cons (NULL_TREE, get_identifier (TREE_STRING_POINTER (yylval.ttype)), pending_vtables);
- if (nextchar < 0)
- nextchar = getch ();
- c = nextchar;
- if (c != EOF)
- warning ("trailing characters ignored");
+ /* If this is 1, we handled it; if it's -1, it was one we
+ wanted but had something wrong with it. Only if it's
+ 0 was it not handled. */
+ if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype)))
+ goto skipline;
}
- else if (c == 'u'
- && getch () == 'n'
- && getch () == 'i'
- && getch () == 't'
- && ((c = getch ()) == ' ' || c == '\t'))
- {
- /* More follows: it must be a string constant (unit name). */
- token = real_yylex ();
- if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
- {
- error ("invalid #pragma unit");
- goto skipline;
- }
- if (nextchar < 0)
- nextchar = getch ();
- c = nextchar;
- if (c != EOF)
- warning ("trailing characters ignored");
- }
- else if (c == 'i')
- {
- tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
- c = getch ();
-
- if (c == 'n'
- && getch () == 't'
- && getch () == 'e'
- && getch () == 'r'
- && getch () == 'f'
- && getch () == 'a'
- && getch () == 'c'
- && getch () == 'e'
- && ((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 != EOF)
- {
- put_back (c);
- token = real_yylex ();
- if (token != STRING
- || TREE_CODE (yylval.ttype) != STRING_CST)
- {
- error ("invalid `#pragma interface'");
- goto skipline;
- }
- main_filename = TREE_STRING_POINTER (yylval.ttype);
- c = getch();
- put_back (c);
- }
-
- while (c == ' ' || c == '\t')
- c = getch ();
-
- while (c != EOF)
- {
- if (!warned_already && extra_warnings
- && c != ' ' && c != '\t')
- {
- warning ("garbage after `#pragma interface' ignored");
- warned_already = 1;
- }
- c = getch ();
- }
-
- write_virtuals = 3;
-
- if (impl_file_chain == 0)
- {
- /* If this is zero at this point, then we are
- auto-implementing. */
- if (main_input_filename == 0)
- main_input_filename = input_filename;
-
-#ifdef AUTO_IMPLEMENT
- filename = FILE_NAME_NONDIRECTORY (main_input_filename);
- fi = get_time_identifier (filename);
- fi = IDENTIFIER_CLASS_VALUE (fi);
- TREE_INT_CST_LOW (fi) = 0;
- TREE_INT_CST_HIGH (fi) = 1;
- /* Get default. */
- impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
- impl_file_chain->filename = filename;
- impl_file_chain->next = 0;
-#endif
- }
-
- interface_only = interface_strcmp (main_filename);
- interface_unknown = 0;
- TREE_INT_CST_LOW (fileinfo) = interface_only;
- TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
- }
- else if (c == 'm'
- && getch () == 'p'
- && getch () == 'l'
- && getch () == 'e'
- && getch () == 'm'
- && getch () == 'e'
- && getch () == 'n'
- && getch () == 't'
- && getch () == 'a'
- && getch () == 't'
- && getch () == 'i'
- && getch () == 'o'
- && getch () == '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 != EOF)
- {
- put_back (c);
- token = real_yylex ();
- if (token != STRING
- || TREE_CODE (yylval.ttype) != STRING_CST)
- {
- error ("invalid `#pragma implementation'");
- goto skipline;
- }
- main_filename = TREE_STRING_POINTER (yylval.ttype);
- c = getch();
- put_back (c);
- }
-
- while (c == ' ' || c == '\t')
- c = getch ();
-
- while (c != EOF)
- {
- if (!warned_already && extra_warnings
- && c != ' ' && c != '\t')
- {
- warning ("garbage after `#pragma implementation' ignored");
- warned_already = 1;
- }
- c = getch ();
- }
+ else if (token == END_OF_LINE)
+ goto skipline;
- if (write_virtuals == 3)
- {
- struct impl_files *ifiles = impl_file_chain;
- while (ifiles)
- {
- if (! strcmp (ifiles->filename, main_filename))
- break;
- ifiles = ifiles->next;
- }
- if (ifiles == 0)
- {
- ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
- ifiles->filename = main_filename;
- ifiles->next = impl_file_chain;
- impl_file_chain = ifiles;
- }
- }
- else if ((main_input_filename != 0
- && ! strcmp (main_input_filename, input_filename))
- || ! strcmp (input_filename, main_filename))
- {
- write_virtuals = 3;
- if (impl_file_chain == 0)
- {
- impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
- impl_file_chain->filename = main_filename;
- impl_file_chain->next = 0;
- }
- }
- else
- error ("`#pragma implementation' can only appear at top-level");
- interface_only = 0;
-#if 1
- /* We make this non-zero so that we infer decl linkage
- in the impl file only for variables first declared
- in the interface file. */
- interface_unknown = 1;
-#else
- /* We make this zero so that templates in the impl
- file will be emitted properly. */
- interface_unknown = 0;
-#endif
- TREE_INT_CST_LOW (fileinfo) = interface_only;
- TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
- }
- }
#ifdef HANDLE_SYSV_PRAGMA
- else
- {
- put_back (c);
- handle_sysv_pragma ();
- }
+ if (handle_sysv_pragma (finput, token))
+ goto skipline;
#else
#ifdef HANDLE_PRAGMA
- /* FIXME: This will break if we're doing any of the C++ input
- tricks. */
- else
- {
- c = HANDLE_PRAGMA (finput, c);
- }
+ if (HANDLE_PRAGMA (finput, yylval.ttype))
+ goto skipline;
#endif
#endif
- goto skipline;
}
+ goto skipline;
}
else if (c == 'd')
{
&& getch () == 'e'
&& ((c = getch ()) == ' ' || c == '\t'))
{
-#ifdef DWARF_DEBUGGING_INFO
- if ((debug_info_level == DINFO_LEVEL_VERBOSE)
- && (write_symbols == DWARF_DEBUG))
- dwarfout_define (lineno, get_directive_line (finput));
-#endif /* DWARF_DEBUGGING_INFO */
+ debug_define (lineno, get_directive_line (finput));
goto skipline;
}
}
&& getch () == 'f'
&& ((c = getch ()) == ' ' || c == '\t'))
{
-#ifdef DWARF_DEBUGGING_INFO
- if ((debug_info_level == DINFO_LEVEL_VERBOSE)
- && (write_symbols == DWARF_DEBUG))
- dwarfout_undef (lineno, get_directive_line (finput));
-#endif /* DWARF_DEBUGGING_INFO */
+ debug_undef (lineno, get_directive_line (finput));
goto skipline;
}
}
/* Here we have just seen `#ident '.
A string constant should follow. */
- while (c == ' ' || c == '\t')
- c = getch ();
-
- /* If no argument, ignore the line. */
- if (c == EOF)
- goto skipline;
-
- put_back (c);
token = real_yylex ();
+ if (token == END_OF_LINE)
+ goto skipline;
if (token != STRING
|| TREE_CODE (yylval.ttype) != STRING_CST)
{
p->name = input_filename;
input_file_stack = p;
input_file_stack_tick++;
-#ifdef DBX_DEBUGGING_INFO
- if (write_symbols == DBX_DEBUG)
- dbxout_start_new_source_file (input_filename);
-#endif
-#ifdef DWARF_DEBUGGING_INFO
- if (debug_info_level == DINFO_LEVEL_VERBOSE
- && write_symbols == DWARF_DEBUG)
- dwarfout_start_new_source_file (input_filename);
-#endif /* DWARF_DEBUGGING_INFO */
+ debug_start_source_file (input_filename);
in_system_header = entering_system_header;
if (c_header_level)
++c_header_level;
input_file_stack = p->next;
free (p);
input_file_stack_tick++;
-#ifdef DBX_DEBUGGING_INFO
- if (write_symbols == DBX_DEBUG)
- dbxout_resume_previous_source_file ();
-#endif
-#ifdef DWARF_DEBUGGING_INFO
- if (debug_info_level == DINFO_LEVEL_VERBOSE
- && write_symbols == DWARF_DEBUG)
- dwarfout_resume_previous_source_file (input_file_stack->line);
-#endif /* DWARF_DEBUGGING_INFO */
+ debug_end_source_file (input_file_stack->line);
}
else
error ("#-lines for entering and leaving files don't match");
skipline:
linemode = 0;
end_of_file = 0;
+ nextchar = -1;
while ((c = getch ()) != EOF && c != '\n');
return c;
}
switch (c)
{
case 'x':
- if (warn_traditional)
- warning ("the meaning of `\\x' varies with -traditional");
-
- if (flag_traditional)
- return c;
-
code = 0;
count = 0;
nonnull = 0;
return TARGET_BS;
case 'a':
- if (warn_traditional)
- warning ("the meaning of `\\a' varies with -traditional");
-
- if (flag_traditional)
- return c;
return TARGET_BELL;
case 'v':
Value is 0 if we treat this name in a default fashion. */
int looking_for_typename = 0;
-#if 0
-/* NO LONGER USED: Value is -1 if we must not see a type name. */
-void
-dont_see_typename ()
-{
- looking_for_typename = -1;
- if (yychar == TYPENAME || yychar == PTYPENAME)
- {
- yychar = IDENTIFIER;
- lastiddecl = 0;
- }
-}
-#endif
-
#ifdef __GNUC__
extern __inline int identifier_type ();
__inline
return NSNAME;
if (TREE_CODE (decl) != TYPE_DECL)
return IDENTIFIER;
+ if (((got_scope && TREE_TYPE (decl) == got_scope)
+ || TREE_TYPE (decl) == current_class_type)
+ && DECL_ARTIFICIAL (decl))
+ return SELFNAME;
return TYPENAME;
}
{
looking_for_typename = 1;
if (yychar < 0)
- if ((yychar = yylex()) < 0) yychar = 0;
+ if ((yychar = yylex ()) < 0) yychar = 0;
looking_for_typename = 0;
if (yychar == IDENTIFIER)
{
/* Remember that this name has been used in the class definition, as per
[class.scope0] */
- if (id && current_class_type
+ if (id && current_class_type && parsing
&& TYPE_BEING_DEFINED (current_class_type)
- && ! IDENTIFIER_CLASS_VALUE (token))
+ && ! IDENTIFIER_CLASS_VALUE (token)
+ /* Avoid breaking if we get called for a default argument that
+ refers to an overloaded method. Eventually this will not be
+ necessary, since default arguments shouldn't be parsed until
+ after the class is complete. (jason 3/12/97) */
+ && TREE_CODE (id) != TREE_LIST)
pushdecl_class_level (id);
if (!id || id == error_mark_node)
else if (IDENTIFIER_OPNAME_P (token))
{
if (token != ansi_opname[ERROR_MARK])
- cp_error ("operator %O not defined", token);
+ cp_error ("`%D' not defined", token);
id = error_mark_node;
}
else if (parsing && (yychar == '(' || yychar == LEFT_RIGHT))
cp_error ("enum `%D' is private", id);
/* protected is OK, since it's an enum of `this'. */
}
- if (! current_template_parms
+ if (! processing_template_decl
|| (DECL_INITIAL (id)
&& TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_CONST_PARM))
id = DECL_INITIAL (id);
yychar = yylex ();
if (! id)
{
- if (current_template_parms)
+ if (processing_template_decl)
{
id = build_min_nt (LOOKUP_EXPR, token, NULL_TREE);
LOOKUP_EXPR_GLOBAL (id) = 1;
else if (TREE_CODE (id) != TREE_LIST)
mark_used (id);
}
- if (TREE_CODE (id) == CONST_DECL && ! current_template_parms)
+ if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
{
/* XXX CHS - should we set TREE_USED of the constant? */
id = DECL_INITIAL (id);
TREE_CONSTANT (id) = 1;
}
- if (current_template_parms)
+ if (processing_template_decl)
{
if (is_overloaded_fn (id))
{
do (IDENTIFIER_GLOBAL_VALUE (node));
#undef do
/* Will this one ever happen? */
- if (TYPE_NAME (type))
- return TYPE_NAME (type);
+ if (TYPE_MAIN_DECL (type))
+ return TYPE_MAIN_DECL (type);
/* We used to do an internal error of 62 here, but instead we will
handle the return of a null appropriately in the callers. */
return NULL_TREE;
}
-struct try_type
-{
- tree *node_var;
- char unsigned_flag;
- char long_flag;
- char long_long_flag;
-};
-
-struct try_type type_sequence[] =
-{
- { &integer_type_node, 0, 0, 0},
- { &unsigned_type_node, 1, 0, 0},
- { &long_integer_type_node, 0, 1, 0},
- { &long_unsigned_type_node, 1, 1, 0},
- { &long_long_integer_type_node, 0, 1, 1},
- { &long_long_unsigned_type_node, 1, 1, 1}
-};
-
int
real_yylex ()
{
token_buffer[0] = '^';
token_buffer[1] = 0;
}
+ else if (ptr->token == NAMESPACE)
+ {
+ static int warned;
+ if (! warned)
+ warning ("namespaces are mostly broken in this version of g++");
+
+ warned = 1;
+ }
value = (int) ptr->token;
}
/* If we did not find a keyword, look for an identifier
(or a typename). */
- if (strcmp ("catch", token_buffer) == 0
- || strcmp ("throw", token_buffer) == 0
- || strcmp ("try", token_buffer) == 0)
- {
- static int did_warn = 0;
- if (! did_warn && ! flag_handle_exceptions)
- {
- pedwarn ("`catch', `throw', and `try' are all C++ reserved words");
- did_warn = 1;
- }
- }
-
if (value == IDENTIFIER || value == TYPESPEC)
GNU_xref_ref (current_function_decl, token_buffer);
&& DECL_INITIAL (tmp) != NULL_TREE
&& TREE_CODE (DECL_INITIAL (tmp)) == STRING_CST)
{
- yylval.ttype = DECL_INITIAL (tmp);
+ tree stringval = DECL_INITIAL (tmp);
+
+ /* Copy the string value so that we won't clobber anything
+ if we put something in the TREE_CHAIN of this one. */
+ yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),
+ TREE_STRING_POINTER (stringval));
value = STRING;
}
}
}
put_back (c1);
}
- /* fall through... */
+ /* fall through... */
case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
resume_numerical_scan:
set_float_handler (handler);
/* The second argument, machine_mode, of REAL_VALUE_ATOF
tells the desired precision of the binary result of
- decimal-to-binary conversion. */
+ decimal-to-binary conversion. */
/* Read the suffixes to choose a data type. */
switch (c)
))
{
pedwarn ("floating point number exceeds range of `%s'",
- IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
+ IDENTIFIER_POINTER (TYPE_IDENTIFIER (type)));
}
/* Note: garbage_chars is -1 if first char is *not* garbage. */
while (isalnum (c))
yylval.ttype = build_int_2 (low, high);
TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
-#if 0
- /* Find the first allowable type that the value fits in. */
- type = 0;
- for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
- i++)
- if (!(spec_long && !type_sequence[i].long_flag)
- && !(spec_long_long && !type_sequence[i].long_long_flag)
- && !(spec_unsigned && !type_sequence[i].unsigned_flag)
- /* A hex or octal constant traditionally is unsigned. */
- && !(base != 10 && flag_traditional
- && !type_sequence[i].unsigned_flag)
- /* A decimal constant can't be unsigned int
- unless explicitly specified. */
- && !(base == 10 && !spec_unsigned
- && *type_sequence[i].node_var == unsigned_type_node))
- if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
- {
- type = *type_sequence[i].node_var;
- break;
- }
- if (flag_traditional && type == long_unsigned_type_node
- && !spec_unsigned)
- type = long_integer_type_node;
-
- if (type == 0)
- {
- type = long_long_integer_type_node;
- warning ("integer constant out of range");
- }
-
- /* Warn about some cases where the type of a given constant
- changes from traditional C to ANSI C. */
- if (warn_traditional)
- {
- tree other_type = 0;
-
- /* This computation is the same as the previous one
- except that flag_traditional is used backwards. */
- for (i = 0; i < sizeof (type_sequence) / sizeof (type_sequence[0]);
- i++)
- if (!(spec_long && !type_sequence[i].long_flag)
- && !(spec_long_long && !type_sequence[i].long_long_flag)
- && !(spec_unsigned && !type_sequence[i].unsigned_flag)
- /* A hex or octal constant traditionally is unsigned. */
- && !(base != 10 && !flag_traditional
- && !type_sequence[i].unsigned_flag)
- /* A decimal constant can't be unsigned int
- unless explicitly specified. */
- && !(base == 10 && !spec_unsigned
- && *type_sequence[i].node_var == unsigned_type_node))
- if (int_fits_type_p (yylval.ttype, *type_sequence[i].node_var))
- {
- other_type = *type_sequence[i].node_var;
- break;
- }
- if (!flag_traditional && type == long_unsigned_type_node
- && !spec_unsigned)
- type = long_integer_type_node;
-
- if (other_type != 0 && other_type != type)
- {
- if (flag_traditional)
- warning ("type of integer constant would be different without -traditional");
- else
- warning ("type of integer constant would be different with -traditional");
- }
- }
-
-#else /* 1 */
if (!spec_long && !spec_unsigned
- && !(flag_traditional && base != 10)
&& int_fits_type_p (yylval.ttype, integer_type_node))
{
-#if 0
- if (warn_traditional && base != 10)
- warning ("small nondecimal constant becomes signed in ANSI C++");
-#endif
type = integer_type_node;
}
else if (!spec_long && (base != 10 || spec_unsigned)
else if (! spec_long_long
&& int_fits_type_p (yylval.ttype,
long_unsigned_type_node))
- {
-#if 0
- if (warn_traditional && !spec_unsigned)
- warning ("large integer constant becomes unsigned in ANSI C++");
-#endif
- if (flag_traditional && !spec_unsigned)
- type = long_integer_type_node;
- else
- type = long_unsigned_type_node;
- }
+ type = long_unsigned_type_node;
else if (! spec_unsigned
/* Verify value does not overflow into sign bit. */
else if (int_fits_type_p (yylval.ttype,
long_long_unsigned_type_node))
- {
-#if 0
- if (warn_traditional && !spec_unsigned)
- warning ("large nondecimal constant is unsigned in ANSI C++");
-#endif
-
- if (flag_traditional && !spec_unsigned)
- type = long_long_integer_type_node;
- else
- type = long_long_unsigned_type_node;
- }
+ type = long_long_unsigned_type_node;
else
{
if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
warning ("decimal integer constant is so large that it is unsigned");
}
-#endif
TREE_TYPE (yylval.ttype) = type;
*p = 0;
num_chars = max_chars;
error ("character constant too long");
}
- else if (num_chars != 1 && ! flag_traditional)
+ else if (num_chars != 1)
warning ("multi-character character constant");
/* If char type is signed, sign-extend the constant. */
skipnewline:
c = getch ();
if (c == EOF) {
- error("Unterminated string");
+ error ("Unterminated string");
break;
}
}
len = p - token_buffer - 1;
}
#endif
- if (current_template_parms)
+ if (processing_template_decl)
push_obstacks (&permanent_obstack, &permanent_obstack);
yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep);
- if (current_template_parms)
+ if (processing_template_decl)
pop_obstacks ();
TREE_TYPE (yylval.ttype) = wchar_array_type_node;
}
else
{
- if (current_template_parms)
+ if (processing_template_decl)
push_obstacks (&permanent_obstack, &permanent_obstack);
yylval.ttype = build_string (p - token_buffer, token_buffer + 1);
- if (current_template_parms)
+ if (processing_template_decl)
pop_obstacks ();
TREE_TYPE (yylval.ttype) = char_array_type_node;
}
}
#ifdef GATHER_STATISTICS
+/* The original for tree_node_kind is in the toplevel tree.c; changes there
+ need to be brought into here, unless this were actually put into a header
+ instead. */
+/* Statistics-gathering stuff. */
+typedef enum
+{
+ d_kind,
+ t_kind,
+ b_kind,
+ s_kind,
+ r_kind,
+ e_kind,
+ c_kind,
+ id_kind,
+ op_id_kind,
+ perm_list_kind,
+ temp_list_kind,
+ vec_kind,
+ x_kind,
+ lang_decl,
+ lang_type,
+ all_kinds
+} tree_node_kind;
+
extern int tree_node_counts[];
extern int tree_node_sizes[];
#endif
== TREE_PERMANENT (t), 234);
DECL_MAIN_VARIANT (t) = t;
if (current_lang_name == lang_name_cplusplus)
- {
- DECL_LANGUAGE (t) = lang_cplusplus;
-#if 0
-#ifndef NO_AUTO_OVERLOAD
- if (code == FUNCTION_DECL && name != 0
- && ! (IDENTIFIER_LENGTH (name) == 4
- && IDENTIFIER_POINTER (name)[0] == 'm'
- && strcmp (IDENTIFIER_POINTER (name), "main") == 0)
- && ! (IDENTIFIER_LENGTH (name) > 10
- && IDENTIFIER_POINTER (name)[0] == '_'
- && IDENTIFIER_POINTER (name)[1] == '_'
- && strncmp (IDENTIFIER_POINTER (name)+2, "builtin_", 8) == 0))
- TREE_OVERLOADED (name) = 1;
-#endif
-#endif
- }
+ DECL_LANGUAGE (t) = lang_cplusplus;
else if (current_lang_name == lang_name_c)
DECL_LANGUAGE (t) = lang_c;
else my_friendly_abort (64);
#endif
#ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_decl] += 1;
- tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
+ tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
#endif
return t;
#ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_type] += 1;
- tree_node_sizes[(int)lang_type] += sizeof(struct lang_type);
+ tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
#endif
return t;
}
void
-copy_decl_lang_specific (decl)
- tree decl;
-{
- extern struct obstack *current_obstack, *saveable_obstack;
- register int *old = (int *)DECL_LANG_SPECIFIC (decl);
- struct obstack *obstack = current_obstack;
- register int i = sizeof (struct lang_decl) / sizeof (int);
- register int *pi;
-
- if (! TREE_PERMANENT (decl))
- obstack = saveable_obstack;
- else
- my_friendly_assert (obstack == &permanent_obstack, 237);
-
- pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
- while (i-- > 0)
- pi[i] = old[i];
-
- DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) pi;
-
-#ifdef GATHER_STATISTICS
- tree_node_counts[(int)lang_decl] += 1;
- tree_node_sizes[(int)lang_decl] += sizeof(struct lang_decl);
-#endif
-}
-
-void
dump_time_statistics ()
{
register tree prev = 0, decl, next;
sprintf (buf, s, v, v2);
error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
}
-
-void
-compiler_error_with_decl (decl, s)
- tree decl;
- char *s;
-{
- char *name;
- count_error (0);
-
- report_error_function (0);
-
- if (TREE_CODE (decl) == PARM_DECL)
- fprintf (stderr, "%s:%d: ",
- DECL_SOURCE_FILE (DECL_CONTEXT (decl)),
- DECL_SOURCE_LINE (DECL_CONTEXT (decl)));
- else
- fprintf (stderr, "%s:%d: ",
- DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
-
- name = lang_printable_name (decl);
- if (name)
- fprintf (stderr, s, name);
- else
- fprintf (stderr, s, "((anonymous))");
- fprintf (stderr, " (compiler error)\n");
-}
\f
void
yyerror (string)
error (buf, token_buffer);
}
\f
+static int
+handle_cp_pragma (pname)
+ char *pname;
+{
+ register int token;
+
+ if (! strcmp (pname, "vtable"))
+ {
+ extern tree pending_vtables;
+
+ /* More follows: it must be a string constant (class name). */
+ token = real_yylex ();
+ if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
+ {
+ error ("invalid #pragma vtable");
+ return -1;
+ }
+
+ if (write_virtuals != 2)
+ {
+ warning ("use `+e2' option to enable #pragma vtable");
+ return -1;
+ }
+ pending_vtables
+ = perm_tree_cons (NULL_TREE,
+ get_identifier (TREE_STRING_POINTER (yylval.ttype)),
+ pending_vtables);
+ token = real_yylex ();
+ if (token != END_OF_LINE)
+ warning ("trailing characters ignored");
+ return 1;
+ }
+ else if (! strcmp (pname, "unit"))
+ {
+ /* More follows: it must be a string constant (unit name). */
+ token = real_yylex ();
+ if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
+ {
+ error ("invalid #pragma unit");
+ return -1;
+ }
+ token = real_yylex ();
+ if (token != END_OF_LINE)
+ warning ("trailing characters ignored");
+ return 1;
+ }
+ else if (! strcmp (pname, "interface"))
+ {
+ tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
+ char *main_filename = input_filename;
+
+ main_filename = FILE_NAME_NONDIRECTORY (main_filename);
+
+ token = real_yylex ();
+
+ if (token != END_OF_LINE)
+ {
+ if (token != STRING
+ || TREE_CODE (yylval.ttype) != STRING_CST)
+ {
+ error ("invalid `#pragma interface'");
+ return -1;
+ }
+ main_filename = TREE_STRING_POINTER (yylval.ttype);
+ token = real_yylex ();
+ }
+
+ if (token != END_OF_LINE)
+ warning ("garbage after `#pragma interface' ignored");
+
+#ifndef NO_LINKAGE_HEURISTICS
+ write_virtuals = 3;
+
+ if (impl_file_chain == 0)
+ {
+ /* If this is zero at this point, then we are
+ auto-implementing. */
+ if (main_input_filename == 0)
+ main_input_filename = input_filename;
+
+#ifdef AUTO_IMPLEMENT
+ filename = FILE_NAME_NONDIRECTORY (main_input_filename);
+ fi = get_time_identifier (filename);
+ fi = IDENTIFIER_CLASS_VALUE (fi);
+ TREE_INT_CST_LOW (fi) = 0;
+ TREE_INT_CST_HIGH (fi) = 1;
+ /* Get default. */
+ impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files));
+ impl_file_chain->filename = filename;
+ impl_file_chain->next = 0;
+#endif
+ }
+
+ interface_only = interface_strcmp (main_filename);
+ interface_unknown = 0;
+ TREE_INT_CST_LOW (fileinfo) = interface_only;
+ TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
+#endif /* NO_LINKAGE_HEURISTICS */
+
+ return 1;
+ }
+ else if (! strcmp (pname, "implementation"))
+ {
+ tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename));
+ char *main_filename = main_input_filename ? main_input_filename : input_filename;
+
+ main_filename = FILE_NAME_NONDIRECTORY (main_filename);
+ token = real_yylex ();
+ if (token != END_OF_LINE)
+ {
+ if (token != STRING
+ || TREE_CODE (yylval.ttype) != STRING_CST)
+ {
+ error ("invalid `#pragma implementation'");
+ return -1;
+ }
+ main_filename = TREE_STRING_POINTER (yylval.ttype);
+ token = real_yylex ();
+ }
+
+ if (token != END_OF_LINE)
+ warning ("garbage after `#pragma implementation' ignored");
+
+#ifndef NO_LINKAGE_HEURISTICS
+ if (write_virtuals == 3)
+ {
+ struct impl_files *ifiles = impl_file_chain;
+ while (ifiles)
+ {
+ if (! strcmp (ifiles->filename, main_filename))
+ break;
+ ifiles = ifiles->next;
+ }
+ if (ifiles == 0)
+ {
+ ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files));
+ ifiles->filename = main_filename;
+ ifiles->next = impl_file_chain;
+ impl_file_chain = ifiles;
+ }
+ }
+ else if ((main_input_filename != 0
+ && ! strcmp (main_input_filename, input_filename))
+ || ! strcmp (input_filename, main_filename))
+ {
+ write_virtuals = 3;
+ if (impl_file_chain == 0)
+ {
+ impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files));
+ impl_file_chain->filename = main_filename;
+ impl_file_chain->next = 0;
+ }
+ }
+ else
+ error ("`#pragma implementation' can only appear at top-level");
+ interface_only = 0;
+#if 1
+ /* We make this non-zero so that we infer decl linkage
+ in the impl file only for variables first declared
+ in the interface file. */
+ interface_unknown = 1;
+#else
+ /* We make this zero so that templates in the impl
+ file will be emitted properly. */
+ interface_unknown = 0;
+#endif
+ TREE_INT_CST_LOW (fileinfo) = interface_only;
+ TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
+#endif /* NO_LINKAGE_HEURISTICS */
+
+ return 1;
+ }
+
+ return 0;
+}
+\f
#ifdef HANDLE_SYSV_PRAGMA
/* Handle a #pragma directive. INPUT is the current input stream,
/* This function has to be in this file, in order to get at
the token types. */
-handle_sysv_pragma ()
+static int
+handle_sysv_pragma (finput, token)
+ FILE *finput;
+ register int token;
{
for (;;)
{
- switch (yylex ())
+ switch (token)
{
case IDENTIFIER:
case TYPENAME:
handle_pragma_token (")", NULL_TREE);
break;
case END_OF_LINE:
- handle_pragma_token (NULL_PTR, NULL_TREE);
- return;
default:
handle_pragma_token (NULL_PTR, NULL_TREE);
- while (yylex () != END_OF_LINE)
- /* continue */;
- return;
+ return 1;
}
+ token = real_yylex ();
}
}
#endif /* HANDLE_SYSV_PRAGMA */