#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. */
\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. */
+
void
reinit_lang_specific ()
{
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;
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;
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;
/* Fall through... */
case 6:
retref = 1;
- declspecs = build_decl_list (NULL_TREE, full_name);
+ declspecs = build_decl_list (NULL_TREE, type);
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)
{
/* 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 handle_cp_pragma ();
+
int
check_newline ()
{
&& 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'))
- {
- 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");
- }
- else if (c == 'u'
- && getch () == 'n'
- && getch () == 'i'
- && getch () == 't'
- && ((c = getch ()) == ' ' || c == '\t'))
+ token = real_yylex ();
+ if (token == IDENTIFIER
+ && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE)
{
- /* 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");
+ /* 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 == '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')
{
/* 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)
{
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;
}
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))
{
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 ()
{
|| strcmp ("try", token_buffer) == 0)
{
static int did_warn = 0;
- if (! did_warn && ! flag_handle_exceptions)
+ if (! did_warn && ! flag_exceptions)
{
pedwarn ("`catch', `throw', and `try' are all C++ reserved words");
did_warn = 1;
&& 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)
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. */
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);
error (buf, token_buffer);
}
\f
+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));
+ int warned_already = 0;
+ 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);
+ }
+
+ while (token != END_OF_LINE)
+ {
+ if (!warned_already && extra_warnings)
+ {
+ warning ("garbage after `#pragma interface' ignored");
+ warned_already = 1;
+ }
+ token = real_yylex ();
+ }
+
+#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));
+ int warned_already = 0;
+ 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);
+ }
+
+ while (token != END_OF_LINE)
+ {
+ if (!warned_already && extra_warnings)
+ {
+ warning ("garbage after `#pragma implementation' ignored");
+ warned_already = 1;
+ }
+ token = real_yylex ();
+ }
+
+#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 ()
+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 */