#define YYDEBUG 1
#include "config.h"
#include "system.h"
#include "input.h"
#include "tree.h"
#include "lex.h"
#include "cp-tree.h"
#include "parse.h"
#include "flags.h"
#include "obstack.h"
#include "c-pragma.h"
#include "toplev.h"
#include "output.h"
#ifdef MULTIBYTE_CHARS
#include "mbchar.h"
#include <locale.h>
#endif
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
#ifndef DIR_SEPARATOR
#define DIR_SEPARATOR '/'
#endif
extern struct obstack permanent_obstack;
extern struct obstack *current_obstack, *saveable_obstack;
extern int flag_altivec;
extern void yyprint PROTO((FILE *, int, YYSTYPE));
static tree get_time_identifier PROTO((const char *));
static int check_newline PROTO((void));
static int skip_white_space PROTO((int));
static void finish_defarg PROTO((void));
static int my_get_run_time PROTO((void));
static int get_last_nonwhite_on_line PROTO((void));
static int interface_strcmp PROTO((const char *));
static int readescape PROTO((int *));
static char *extend_token_buffer PROTO((const char *));
static void consume_string PROTO((struct obstack *, int));
static int set_typedecl_interface_info PROTO((tree *, void *));
static void feed_defarg PROTO((tree, tree));
static int set_vardecl_interface_info PROTO((tree *, void *));
static void store_pending_inline PROTO((tree, struct pending_inline *));
static void reinit_parse_for_expr PROTO((struct obstack *));
static int *init_cpp_parse PROTO((void));
static int handle_cp_pragma PROTO((const char *));
#ifdef HANDLE_GENERIC_PRAGMAS
static int handle_generic_pragma PROTO((int));
#endif
#ifdef GATHER_STATISTICS
#ifdef REDUCE_LENGTH
static int reduce_cmp PROTO((int *, int *));
static int token_cmp PROTO((int *, int *));
#endif
#endif
static void begin_definition_of_inclass_inline PROTO((struct pending_inline*));
static void parse_float PROTO((PTR));
static int is_global PROTO((tree));
static void init_filename_times PROTO((void));
char *
file_name_nondirectory (x)
const char *x;
{
char *tmp = (char *) rindex (x, '/');
if (DIR_SEPARATOR != '/' && ! tmp)
tmp = (char *) rindex (x, DIR_SEPARATOR);
if (tmp)
return (char *) (tmp + 1);
else
return (char *) x;
}
struct obstack inline_text_obstack;
char *inline_text_firstobj;
#if USE_CPPLIB
#include "cpplib.h"
extern cpp_reader parse_in;
extern cpp_options parse_options;
extern unsigned char *yy_cur, *yy_lim;
#else
FILE *finput;
#endif
int end_of_file;
int pending_lang_change = 0;
static int c_header_level = 0;
extern int first_token;
extern struct obstack token_obstack;
#if 1
#include "input.c"
#else
extern void put_back ();
extern int input_redirected ();
extern void feed_input ();
#endif
char **opname_tab;
char **assignop_tab;
extern int yychar;
extern YYSTYPE yylval;
#if 0
YYLTYPE yylloc;
#endif
#ifdef OBJCPLUS
#include "objc/objc-act.h"
extern tree objc_method_context;
extern tree objc_ivar_chain;
extern int objc_receiver_context;
extern int objc_declarator_context;
extern int objc_msg_context;
extern tree current_objc_implementation_context (void);
#endif
tree lastiddecl;
tree ridpointers[(int) RID_MAX];
#if (defined (NEXT_SEMANTICS) || defined (NEXT_PDO)) && !defined (OBJCPLUS)
int doing_objc_thang;
#endif
static int header_time, body_time;
static tree filename_times;
static tree this_filename_time;
extern int *token_count;
tree
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 `*'");
#ifdef OBJCPLUS
target = build_nt (INDIRECT_REF, target);
#else
target = build_parse_node (INDIRECT_REF, target);
#endif
TREE_TYPE (target) = cv_qualifiers;
return target;
}
tree
make_reference_declarator (cv_qualifiers, target)
tree cv_qualifiers, target;
{
if (target)
{
if (TREE_CODE (target) == ADDR_EXPR)
{
error ("cannot declare references to references");
return target;
}
if (TREE_CODE (target) == INDIRECT_REF)
{
error ("cannot declare pointers to references");
return target;
}
if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target))
error ("type name expected before `&'");
}
#ifdef OBJCPLUS
target = build_nt (ADDR_EXPR, target);
#else
target = build_parse_node (ADDR_EXPR, target);
#endif
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;
}
tree ansi_opname[LAST_CPLUS_TREE_CODE];
tree ansi_assopname[LAST_CPLUS_TREE_CODE];
char *
operator_name_string (name)
tree name;
{
char *opname = IDENTIFIER_POINTER (name) + 2;
tree *opname_table;
int i, assign;
if (IDENTIFIER_GLOBAL_VALUE (name)
&& TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL)
return IDENTIFIER_POINTER (name);
if (opname[0] == 'a' && opname[2] != '\0' && opname[2] != '_')
{
opname += 1;
assign = 1;
opname_table = ansi_assopname;
}
else
{
assign = 0;
opname_table = ansi_opname;
}
for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
{
if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign]
&& opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign])
break;
}
if (i == LAST_CPLUS_TREE_CODE)
return "<invalid operator>";
if (assign)
return assignop_tab[i];
else
return opname_tab[i];
}
int interface_only;
int interface_unknown;
#ifndef WCHAR_TYPE_SIZE
#ifdef INT_TYPE_SIZE
#define WCHAR_TYPE_SIZE INT_TYPE_SIZE
#else
#define WCHAR_TYPE_SIZE BITS_PER_WORD
#endif
#endif
#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT)
static int maxtoken;
char *token_buffer;
#ifndef OBJCPLUS
#include "hash.h"
#else
#include "../obcp/hash.h"
int cplusplus_keywords_disabled = 0;
extern int objc_declarator_context;
extern int objc_receiver_context;
extern int objc_msg_context;
extern tree objc_ivar_chain;
extern tree objc_method_context;
void install_reserved_words (enum languages lang)
{
int i, n = TOTAL_KEYWORDS;
cplusplus_keywords_disabled = (lang != lang_cplusplus);
for (i = 0; i < n; i++)
{
if (wordlist[i].name && *wordlist[i].name != '\0')
{
if (lang == lang_c || lang == lang_objc)
{
if (wordlist[i].lang == lang_cplusplus)
{
wordlist[i].save = wordlist[i].name;
wordlist[i].name = "";
}
}
}
else if (wordlist[i].save && *wordlist[i].save != '\0')
{
if (lang == lang_cplusplus)
{
if (wordlist[i].lang == lang_cplusplus)
{
wordlist[i].name = wordlist[i].save;
wordlist[i].save = "";
}
}
}
}
}
void
forget_protocol_qualifiers ()
{
int i, n = TOTAL_KEYWORDS;
forget_saved_protocol_qualifiers ();
for (i = 0; i < n; i++)
{
if (wordlist[i].rid >= RID_IN && wordlist[i].rid <= RID_ONEWAY)
wordlist[i].name = "";
}
}
void
remember_protocol_qualifiers ()
{
int i, n = TOTAL_KEYWORDS;
for (i = 0; i < n; i++)
{
if (wordlist[i].rid == RID_IN)
wordlist[i].name = "in";
else if (wordlist[i].rid == RID_OUT)
wordlist[i].name = "out";
else if (wordlist[i].rid == RID_INOUT)
wordlist[i].name = "inout";
else if (wordlist[i].rid == RID_BYCOPY)
wordlist[i].name = "bycopy";
else if (wordlist[i].rid == RID_BYREF)
wordlist[i].name = "byref";
else if (wordlist[i].rid == RID_ONEWAY)
wordlist[i].name = "oneway";
}
}
#endif
static int ignore_escape_flag = 0;
static tree
get_time_identifier (name)
const char *name;
{
tree time_identifier;
int len = strlen (name);
char *buf = (char *) alloca (len + 6);
strcpy (buf, "file ");
bcopy (name, buf+5, len);
buf[len+5] = '\0';
time_identifier = get_identifier (buf);
if (TIME_IDENTIFIER_TIME (time_identifier) == NULL_TREE)
{
push_obstacks_nochange ();
end_temporary_allocation ();
TIME_IDENTIFIER_TIME (time_identifier) = build_int_2 (0, 0);
TIME_IDENTIFIER_FILEINFO (time_identifier)
= build_int_2 (0, 1);
SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times);
filename_times = time_identifier;
pop_obstacks ();
}
return time_identifier;
}
#ifdef __GNUC__
__inline
#endif
static int
my_get_run_time ()
{
int old_quiet_flag = quiet_flag;
int this_time;
quiet_flag = 0;
this_time = get_run_time ();
quiet_flag = old_quiet_flag;
return this_time;
}
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
char cplus_tree_code_type[] = {
'x',
#include "cp-tree.def"
};
#undef DEFTREECODE
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
int cplus_tree_code_length[] = {
0,
#include "cp-tree.def"
};
#undef DEFTREECODE
#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
const char *cplus_tree_code_name[] = {
"@@dummy",
#include "cp-tree.def"
};
#undef DEFTREECODE
void
lang_init_options ()
{
#if USE_CPPLIB
cpp_reader_init (&parse_in);
parse_in.opts = &parse_options;
cpp_options_init (&parse_options);
#endif
flag_exceptions = 1;
}
void
lang_init ()
{
#if ! USE_CPPLIB
put_back (check_newline ());
#else
check_newline ();
yy_cur--;
#endif
if (flag_gnu_xref) GNU_xref_begin (input_filename);
init_repo (input_filename);
#ifdef OBJCPLUS
objc_lang_init ();
#endif
}
void
lang_finish ()
{
extern int errorcount, sorrycount;
if (flag_gnu_xref) GNU_xref_end (errorcount+sorrycount);
}
char *
lang_identify ()
{
return "cplusplus";
}
static void
init_filename_times ()
{
this_filename_time = get_time_identifier ("<top level>");
if (flag_detailed_statistics)
{
header_time = 0;
body_time = my_get_run_time ();
TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
= body_time;
}
}
#if 0
void
reinit_lang_specific ()
{
init_filename_times ();
reinit_search_statistics ();
}
#endif
static int *
init_cpp_parse ()
{
#ifdef GATHER_STATISTICS
#ifdef REDUCE_LENGTH
reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1));
bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1));
reduce_count += 1;
token_count = (int *)malloc (sizeof (int) * (TOKEN_LENGTH + 1));
bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1));
token_count += 1;
#endif
#endif
return token_count;
}
char *
init_parse (filename)
char *filename;
{
extern int flag_no_gnu_keywords;
extern int flag_operator_names;
#ifdef OBJCPLUS
extern int doing_objc_thang;
#endif
int i;
#ifdef MULTIBYTE_CHARS
setlocale (LC_CTYPE, "");
literal_codeset = getenv ("LANG");
#endif
#if USE_CPPLIB
parse_in.show_column = 1;
if (! cpp_start_read (&parse_in, filename))
abort ();
yy_cur = parse_in.token_buffer;
yy_lim = CPP_PWRITTEN (&parse_in);
#else
if (filename == 0 || !strcmp (filename, "-"))
{
finput = stdin;
filename = "stdin";
}
else
finput = fopen (filename, "r");
if (finput == 0)
pfatal_with_name (filename);
#ifdef IO_BUFFER_SIZE
setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
#endif
#endif
init_spew ();
set_identifier_size (sizeof (struct lang_identifier));
decl_printable_name = lang_printable_name;
init_cplus_expand ();
bcopy (cplus_tree_code_type,
tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE,
(int)LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE);
bcopy ((char *)cplus_tree_code_length,
(char *)(tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE),
(LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int));
bcopy ((char *)cplus_tree_code_name,
(char *)(tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE),
(LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *));
opname_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
bzero ((char *)opname_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
assignop_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *));
bzero ((char *)assignop_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *));
ansi_opname[0] = get_identifier ("<invalid operator>");
for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++)
{
ansi_opname[i] = ansi_opname[0];
ansi_assopname[i] = ansi_opname[0];
}
ansi_opname[(int) MULT_EXPR] = get_identifier ("__ml");
IDENTIFIER_OPNAME_P (ansi_opname[(int) MULT_EXPR]) = 1;
ansi_opname[(int) INDIRECT_REF] = ansi_opname[(int) MULT_EXPR];
ansi_assopname[(int) MULT_EXPR] = get_identifier ("__aml");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) MULT_EXPR]) = 1;
ansi_assopname[(int) INDIRECT_REF] = ansi_assopname[(int) MULT_EXPR];
ansi_opname[(int) TRUNC_MOD_EXPR] = get_identifier ("__md");
IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUNC_MOD_EXPR]) = 1;
ansi_assopname[(int) TRUNC_MOD_EXPR] = get_identifier ("__amd");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) TRUNC_MOD_EXPR]) = 1;
ansi_opname[(int) CEIL_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
ansi_opname[(int) FLOOR_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
ansi_opname[(int) ROUND_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR];
ansi_opname[(int) MINUS_EXPR] = get_identifier ("__mi");
IDENTIFIER_OPNAME_P (ansi_opname[(int) MINUS_EXPR]) = 1;
ansi_opname[(int) NEGATE_EXPR] = ansi_opname[(int) MINUS_EXPR];
ansi_assopname[(int) MINUS_EXPR] = get_identifier ("__ami");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) MINUS_EXPR]) = 1;
ansi_assopname[(int) NEGATE_EXPR] = ansi_assopname[(int) MINUS_EXPR];
ansi_opname[(int) RSHIFT_EXPR] = get_identifier ("__rs");
IDENTIFIER_OPNAME_P (ansi_opname[(int) RSHIFT_EXPR]) = 1;
ansi_assopname[(int) RSHIFT_EXPR] = get_identifier ("__ars");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) RSHIFT_EXPR]) = 1;
ansi_opname[(int) NE_EXPR] = get_identifier ("__ne");
IDENTIFIER_OPNAME_P (ansi_opname[(int) NE_EXPR]) = 1;
ansi_opname[(int) GT_EXPR] = get_identifier ("__gt");
IDENTIFIER_OPNAME_P (ansi_opname[(int) GT_EXPR]) = 1;
ansi_opname[(int) GE_EXPR] = get_identifier ("__ge");
IDENTIFIER_OPNAME_P (ansi_opname[(int) GE_EXPR]) = 1;
ansi_opname[(int) BIT_IOR_EXPR] = get_identifier ("__or");
IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_IOR_EXPR]) = 1;
ansi_assopname[(int) BIT_IOR_EXPR] = get_identifier ("__aor");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_IOR_EXPR]) = 1;
ansi_opname[(int) TRUTH_ANDIF_EXPR] = get_identifier ("__aa");
IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ANDIF_EXPR]) = 1;
ansi_opname[(int) TRUTH_NOT_EXPR] = get_identifier ("__nt");
IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_NOT_EXPR]) = 1;
ansi_opname[(int) PREINCREMENT_EXPR] = get_identifier ("__pp");
IDENTIFIER_OPNAME_P (ansi_opname[(int) PREINCREMENT_EXPR]) = 1;
ansi_opname[(int) POSTINCREMENT_EXPR] = ansi_opname[(int) PREINCREMENT_EXPR];
ansi_opname[(int) MODIFY_EXPR] = get_identifier ("__as");
IDENTIFIER_OPNAME_P (ansi_opname[(int) MODIFY_EXPR]) = 1;
ansi_assopname[(int) NOP_EXPR] = ansi_opname[(int) MODIFY_EXPR];
ansi_opname[(int) COMPOUND_EXPR] = get_identifier ("__cm");
IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPOUND_EXPR]) = 1;
ansi_opname[(int) EXACT_DIV_EXPR] = get_identifier ("__dv");
IDENTIFIER_OPNAME_P (ansi_opname[(int) EXACT_DIV_EXPR]) = 1;
ansi_assopname[(int) EXACT_DIV_EXPR] = get_identifier ("__adv");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) EXACT_DIV_EXPR]) = 1;
ansi_opname[(int) TRUNC_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
ansi_opname[(int) CEIL_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
ansi_opname[(int) FLOOR_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
ansi_opname[(int) ROUND_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR];
ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl");
ansi_assopname[(int) TRUNC_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR];
IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1;
ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) PLUS_EXPR]) = 1;
ansi_opname[(int) CONVERT_EXPR] = ansi_opname[(int) PLUS_EXPR];
ansi_assopname[(int) CONVERT_EXPR] = ansi_assopname[(int) PLUS_EXPR];
ansi_opname[(int) LSHIFT_EXPR] = get_identifier ("__ls");
IDENTIFIER_OPNAME_P (ansi_opname[(int) LSHIFT_EXPR]) = 1;
ansi_assopname[(int) LSHIFT_EXPR] = get_identifier ("__als");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) LSHIFT_EXPR]) = 1;
ansi_opname[(int) EQ_EXPR] = get_identifier ("__eq");
IDENTIFIER_OPNAME_P (ansi_opname[(int) EQ_EXPR]) = 1;
ansi_opname[(int) LT_EXPR] = get_identifier ("__lt");
IDENTIFIER_OPNAME_P (ansi_opname[(int) LT_EXPR]) = 1;
ansi_opname[(int) LE_EXPR] = get_identifier ("__le");
IDENTIFIER_OPNAME_P (ansi_opname[(int) LE_EXPR]) = 1;
ansi_opname[(int) BIT_AND_EXPR] = get_identifier ("__ad");
IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_AND_EXPR]) = 1;
ansi_assopname[(int) BIT_AND_EXPR] = get_identifier ("__aad");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_AND_EXPR]) = 1;
ansi_opname[(int) ADDR_EXPR] = ansi_opname[(int) BIT_AND_EXPR];
ansi_assopname[(int) ADDR_EXPR] = ansi_assopname[(int) BIT_AND_EXPR];
ansi_opname[(int) BIT_XOR_EXPR] = get_identifier ("__er");
IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_XOR_EXPR]) = 1;
ansi_assopname[(int) BIT_XOR_EXPR] = get_identifier ("__aer");
IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_XOR_EXPR]) = 1;
ansi_opname[(int) TRUTH_ORIF_EXPR] = get_identifier ("__oo");
IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ORIF_EXPR]) = 1;
ansi_opname[(int) BIT_NOT_EXPR] = get_identifier ("__co");
IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_NOT_EXPR]) = 1;
ansi_opname[(int) PREDECREMENT_EXPR] = get_identifier ("__mm");
IDENTIFIER_OPNAME_P (ansi_opname[(int) PREDECREMENT_EXPR]) = 1;
ansi_opname[(int) POSTDECREMENT_EXPR] = ansi_opname[(int) PREDECREMENT_EXPR];
ansi_opname[(int) COMPONENT_REF] = get_identifier ("__rf");
IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPONENT_REF]) = 1;
ansi_opname[(int) MEMBER_REF] = get_identifier ("__rm");
IDENTIFIER_OPNAME_P (ansi_opname[(int) MEMBER_REF]) = 1;
ansi_opname[(int) CALL_EXPR] = get_identifier ("__cl");
IDENTIFIER_OPNAME_P (ansi_opname[(int) CALL_EXPR]) = 1;
ansi_opname[(int) ARRAY_REF] = get_identifier ("__vc");
IDENTIFIER_OPNAME_P (ansi_opname[(int) ARRAY_REF]) = 1;
ansi_opname[(int) NEW_EXPR] = get_identifier ("__nw");
IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1;
ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl");
IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1;
ansi_opname[(int) VEC_NEW_EXPR] = get_identifier ("__vn");
IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1;
ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd");
IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1;
ansi_opname[(int) TYPE_EXPR] = get_identifier (OPERATOR_TYPENAME_FORMAT);
IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1;
ansi_opname[(int) MIN_EXPR] = get_identifier ("__mn");
IDENTIFIER_OPNAME_P (ansi_opname[(int) MIN_EXPR]) = 1;
ansi_opname[(int) MAX_EXPR] = get_identifier ("__mx");
IDENTIFIER_OPNAME_P (ansi_opname[(int) MAX_EXPR]) = 1;
ansi_opname[(int) COND_EXPR] = get_identifier ("__cn");
IDENTIFIER_OPNAME_P (ansi_opname[(int) COND_EXPR]) = 1;
ansi_opname[(int) SIZEOF_EXPR] = get_identifier ("__sz");
IDENTIFIER_OPNAME_P (ansi_opname[(int) SIZEOF_EXPR]) = 1;
init_method ();
init_error ();
gcc_obstack_init (&inline_text_obstack);
inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0);
lineno = 0;
input_filename = "<internal>";
current_function_decl = NULL;
maxtoken = 40;
token_buffer = (char *) xmalloc (maxtoken + 2);
ridpointers[(int) RID_INT] = get_identifier ("int");
ridpointers[(int) RID_BOOL] = get_identifier ("bool");
ridpointers[(int) RID_CHAR] = get_identifier ("char");
ridpointers[(int) RID_VOID] = get_identifier ("void");
ridpointers[(int) RID_FLOAT] = get_identifier ("float");
ridpointers[(int) RID_DOUBLE] = get_identifier ("double");
ridpointers[(int) RID_SHORT] = get_identifier ("short");
ridpointers[(int) RID_LONG] = get_identifier ("long");
ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned");
ridpointers[(int) RID_SIGNED] = get_identifier ("signed");
ridpointers[(int) RID_INLINE] = get_identifier ("inline");
ridpointers[(int) RID_CONST] = get_identifier ("const");
ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
ridpointers[(int) RID_RESTRICT] = get_identifier ("__restrict");
ridpointers[(int) RID_AUTO] = get_identifier ("auto");
ridpointers[(int) RID_STATIC] = get_identifier ("static");
ridpointers[(int) RID_EXTERN] = get_identifier ("extern");
ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef");
ridpointers[(int) RID_REGISTER] = get_identifier ("register");
ridpointers[(int) RID_COMPLEX] = get_identifier ("__complex");
#ifdef OBJCPLUS
ridpointers[(int) RID_ID] = get_identifier ("id");
ridpointers[(int) RID_IN] = get_identifier ("in");
ridpointers[(int) RID_OUT] = get_identifier ("out");
ridpointers[(int) RID_INOUT] = get_identifier ("inout");
ridpointers[(int) RID_BYCOPY] = get_identifier ("bycopy");
ridpointers[(int) RID_ONEWAY] = get_identifier ("oneway");
forget_protocol_qualifiers ();
#endif
#if defined (WIN32) && defined (NEXT_PDO)
ridpointers[(int) RID_STDCALL] = get_identifier ("stdcall");
ridpointers[(int) RID_DECLSPEC] = get_identifier ("declspec");
ridpointers[(int) RID_DLLIMPORT] = get_identifier ("dllimport");
ridpointers[(int) RID_DLLEXPORT] = get_identifier ("dllexport");
#endif
ridpointers[(int) RID_PIXEL] = get_identifier ("__pixel");
ridpointers[(int) RID_VECTOR] = get_identifier ("__vector");
ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t");
class_type_node = build_int_2 (class_type, 0);
TREE_TYPE (class_type_node) = class_type_node;
ridpointers[(int) RID_CLASS] = class_type_node;
record_type_node = build_int_2 (record_type, 0);
TREE_TYPE (record_type_node) = record_type_node;
ridpointers[(int) RID_RECORD] = record_type_node;
union_type_node = build_int_2 (union_type, 0);
TREE_TYPE (union_type_node) = union_type_node;
ridpointers[(int) RID_UNION] = union_type_node;
enum_type_node = build_int_2 (enum_type, 0);
TREE_TYPE (enum_type_node) = enum_type_node;
ridpointers[(int) RID_ENUM] = enum_type_node;
ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual");
ridpointers[(int) RID_EXPLICIT] = get_identifier ("explicit");
ridpointers[(int) RID_EXPORT] = get_identifier ("export");
ridpointers[(int) RID_FRIEND] = get_identifier ("friend");
ridpointers[(int) RID_PUBLIC] = get_identifier ("public");
ridpointers[(int) RID_PRIVATE] = get_identifier ("private");
ridpointers[(int) RID_PROTECTED] = get_identifier ("protected");
ridpointers[(int) RID_TEMPLATE] = get_identifier ("template");
ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable");
signature_type_node = build_int_2 (signature_type, 0);
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) 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) CALL_EXPR] = "()";
opname_tab[(int) PLUS_EXPR] = "+";
opname_tab[(int) MINUS_EXPR] = "-";
opname_tab[(int) MULT_EXPR] = "*";
opname_tab[(int) TRUNC_DIV_EXPR] = "/";
opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)";
opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)";
opname_tab[(int) ROUND_DIV_EXPR] = "(round /)";
opname_tab[(int) TRUNC_MOD_EXPR] = "%";
opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)";
opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)";
opname_tab[(int) ROUND_MOD_EXPR] = "(round %)";
opname_tab[(int) NEGATE_EXPR] = "-";
opname_tab[(int) MIN_EXPR] = "<?";
opname_tab[(int) MAX_EXPR] = ">?";
opname_tab[(int) ABS_EXPR] = "abs";
opname_tab[(int) FFS_EXPR] = "ffs";
opname_tab[(int) LSHIFT_EXPR] = "<<";
opname_tab[(int) RSHIFT_EXPR] = ">>";
opname_tab[(int) BIT_IOR_EXPR] = "|";
opname_tab[(int) BIT_XOR_EXPR] = "^";
opname_tab[(int) BIT_AND_EXPR] = "&";
opname_tab[(int) BIT_ANDTC_EXPR] = "&~";
opname_tab[(int) BIT_NOT_EXPR] = "~";
opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&";
opname_tab[(int) TRUTH_ORIF_EXPR] = "||";
opname_tab[(int) TRUTH_AND_EXPR] = "strict &&";
opname_tab[(int) TRUTH_OR_EXPR] = "strict ||";
opname_tab[(int) TRUTH_NOT_EXPR] = "!";
opname_tab[(int) LT_EXPR] = "<";
opname_tab[(int) LE_EXPR] = "<=";
opname_tab[(int) GT_EXPR] = ">";
opname_tab[(int) GE_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] = "+";
opname_tab[(int) ADDR_EXPR] = "&";
opname_tab[(int) PREDECREMENT_EXPR] = "--";
opname_tab[(int) PREINCREMENT_EXPR] = "++";
opname_tab[(int) POSTDECREMENT_EXPR] = "--";
opname_tab[(int) POSTINCREMENT_EXPR] = "++";
opname_tab[(int) COMPOUND_EXPR] = ",";
assignop_tab[(int) NOP_EXPR] = "=";
assignop_tab[(int) PLUS_EXPR] = "+=";
assignop_tab[(int) CONVERT_EXPR] = "+=";
assignop_tab[(int) MINUS_EXPR] = "-=";
assignop_tab[(int) NEGATE_EXPR] = "-=";
assignop_tab[(int) MULT_EXPR] = "*=";
assignop_tab[(int) INDIRECT_REF] = "*=";
assignop_tab[(int) TRUNC_DIV_EXPR] = "/=";
assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)";
assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)";
assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)";
assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)";
assignop_tab[(int) TRUNC_MOD_EXPR] = "%=";
assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)";
assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)";
assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)";
assignop_tab[(int) MIN_EXPR] = "<?=";
assignop_tab[(int) MAX_EXPR] = ">?=";
assignop_tab[(int) LSHIFT_EXPR] = "<<=";
assignop_tab[(int) RSHIFT_EXPR] = ">>=";
assignop_tab[(int) BIT_IOR_EXPR] = "|=";
assignop_tab[(int) BIT_XOR_EXPR] = "^=";
assignop_tab[(int) BIT_AND_EXPR] = "&=";
assignop_tab[(int) ADDR_EXPR] = "&=";
init_filename_times ();
#define UNSET_RESERVED_WORD(STRING) \
do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \
if (s) s->name = ""; } while (0)
#if 0
if (!flag_exceptions)
{
UNSET_RESERVED_WORD ("throw");
UNSET_RESERVED_WORD ("try");
UNSET_RESERVED_WORD ("catch");
}
#endif
if (!flag_rtti || flag_no_gnu_keywords)
{
UNSET_RESERVED_WORD ("classof");
UNSET_RESERVED_WORD ("headof");
}
if (! flag_handle_signatures || flag_no_gnu_keywords)
{
UNSET_RESERVED_WORD ("signature");
UNSET_RESERVED_WORD ("sigof");
}
if (flag_no_asm || flag_no_gnu_keywords)
UNSET_RESERVED_WORD ("typeof");
if (! flag_operator_names)
{
UNSET_RESERVED_WORD ("and");
UNSET_RESERVED_WORD ("and_eq");
UNSET_RESERVED_WORD ("bitand");
UNSET_RESERVED_WORD ("bitor");
UNSET_RESERVED_WORD ("compl");
UNSET_RESERVED_WORD ("not");
UNSET_RESERVED_WORD ("not_eq");
UNSET_RESERVED_WORD ("or");
UNSET_RESERVED_WORD ("or_eq");
UNSET_RESERVED_WORD ("xor");
UNSET_RESERVED_WORD ("xor_eq");
}
if (!flag_altivec)
{
UNSET_RESERVED_WORD ("__vector");
UNSET_RESERVED_WORD ("__pixel");
UNSET_RESERVED_WORD ("vector");
UNSET_RESERVED_WORD ("pixel");
UNSET_RESERVED_WORD ("vec_step");
}
token_count = init_cpp_parse ();
interface_unknown = 1;
return filename;
}
void
finish_parse ()
{
#if USE_CPPLIB
cpp_finish (&parse_in);
#else
fclose (finput);
#endif
}
void
reinit_parse_for_function ()
{
current_base_init_list = NULL_TREE;
current_member_init_list = NULL_TREE;
}
#ifdef __GNUC__
__inline
#endif
void
yyprint (file, yychar, yylval)
FILE *file;
int yychar;
YYSTYPE yylval;
{
tree t;
switch (yychar)
{
case IDENTIFIER:
case TYPENAME:
case TYPESPEC:
case PTYPENAME:
case IDENTIFIER_DEFN:
case TYPENAME_DEFN:
case PTYPENAME_DEFN:
case SCSPEC:
case PRE_PARSED_CLASS_DECL:
t = yylval.ttype;
if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == TEMPLATE_DECL)
{
fprintf (file, " `%s'", IDENTIFIER_POINTER (DECL_NAME (t)));
break;
}
my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224);
if (IDENTIFIER_POINTER (t))
fprintf (file, " `%s'", IDENTIFIER_POINTER (t));
break;
case AGGR:
if (yylval.ttype == class_type_node)
fprintf (file, " `class'");
else if (yylval.ttype == record_type_node)
fprintf (file, " `struct'");
else if (yylval.ttype == union_type_node)
fprintf (file, " `union'");
else if (yylval.ttype == enum_type_node)
fprintf (file, " `enum'");
else if (yylval.ttype == signature_type_node)
fprintf (file, " `signature'");
else
my_friendly_abort (80);
break;
}
}
#if defined(GATHER_STATISTICS) && defined(REDUCE_LENGTH)
static int *reduce_count;
#endif
int *token_count;
#if 0
#define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0]))
#define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0]))
#endif
#ifdef GATHER_STATISTICS
#ifdef REDUCE_LENGTH
void
yyhook (yyn)
int yyn;
{
reduce_count[yyn] += 1;
}
static int
reduce_cmp (p, q)
int *p, *q;
{
return reduce_count[*q] - reduce_count[*p];
}
static int
token_cmp (p, q)
int *p, *q;
{
return token_count[*q] - token_count[*p];
}
#endif
#endif
void
print_parse_statistics ()
{
#ifdef GATHER_STATISTICS
#ifdef REDUCE_LENGTH
#if YYDEBUG != 0
int i;
int maxlen = REDUCE_LENGTH;
unsigned *sorted;
if (reduce_count[-1] == 0)
return;
if (TOKEN_LENGTH > REDUCE_LENGTH)
maxlen = TOKEN_LENGTH;
sorted = (unsigned *) alloca (sizeof (int) * maxlen);
for (i = 0; i < TOKEN_LENGTH; i++)
sorted[i] = i;
qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp);
for (i = 0; i < TOKEN_LENGTH; i++)
{
int idx = sorted[i];
if (token_count[idx] == 0)
break;
if (token_count[idx] < token_count[-1])
break;
fprintf (stderr, "token %d, `%s', count = %d\n",
idx, yytname[YYTRANSLATE (idx)], token_count[idx]);
}
fprintf (stderr, "\n");
for (i = 0; i < REDUCE_LENGTH; i++)
sorted[i] = i;
qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp);
for (i = 0; i < REDUCE_LENGTH; i++)
{
int idx = sorted[i];
if (reduce_count[idx] == 0)
break;
if (reduce_count[idx] < reduce_count[-1])
break;
fprintf (stderr, "rule %d, line %d, count = %d\n",
idx, yyrline[idx], reduce_count[idx]);
}
fprintf (stderr, "\n");
#endif
#endif
#endif
}
void
set_yydebug (value)
int value;
{
#if YYDEBUG != 0
extern int yydebug;
yydebug = value;
#else
warning ("YYDEBUG not defined.");
#endif
}
struct impl_files
{
char *filename;
struct impl_files *next;
};
static struct impl_files *impl_file_chain;
void
extract_interface_info ()
{
tree fileinfo = 0;
if (flag_alt_external_templates)
{
struct tinst_level *til = tinst_for_decl ();
if (til)
fileinfo = get_time_identifier (til->file);
}
if (!fileinfo)
fileinfo = get_time_identifier (input_filename);
fileinfo = TIME_IDENTIFIER_FILEINFO (fileinfo);
interface_only = TREE_INT_CST_LOW (fileinfo);
interface_unknown = TREE_INT_CST_HIGH (fileinfo);
}
static int
interface_strcmp (s)
const char *s;
{
struct impl_files *ifiles;
const char *s1;
for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
{
const char *t1 = ifiles->filename;
s1 = s;
if (*s1 != *t1 || *s1 == 0)
continue;
while (*s1 == *t1 && *s1 != 0)
s1++, t1++;
if (*s1 == *t1)
return 0;
if (index (s1, '.') || index (t1, '.'))
continue;
if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
continue;
return 0;
}
return 1;
}
static int
set_typedecl_interface_info (t, data)
tree *t;
void *data ATTRIBUTE_UNUSED;
{
tree id = get_time_identifier (DECL_SOURCE_FILE (*t));
tree fileinfo = TIME_IDENTIFIER_FILEINFO (id);
tree type = TREE_TYPE (*t);
CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo)
= interface_strcmp (file_name_nondirectory (DECL_SOURCE_FILE (*t)));
return 0;
}
static int
set_vardecl_interface_info (t, data)
tree *t;
void *data ATTRIBUTE_UNUSED;
{
tree type = DECL_CONTEXT (*t);
if (CLASSTYPE_INTERFACE_KNOWN (type))
{
if (CLASSTYPE_INTERFACE_ONLY (type))
set_typedecl_interface_info (&TYPE_MAIN_DECL (type), data);
else
CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1;
DECL_EXTERNAL (*t) = CLASSTYPE_INTERFACE_ONLY (type);
TREE_PUBLIC (*t) = 1;
return 1;
}
return 0;
}
static void
begin_definition_of_inclass_inline (pi)
struct pending_inline* pi;
{
tree context;
if (!pi->fndecl)
return;
context = hack_decl_function_context (pi->fndecl);
if (context)
push_cp_function_context (context);
feed_input (pi->buf, pi->len);
lineno = pi->lineno;
input_filename = pi->filename;
yychar = PRE_PARSED_FUNCTION_DECL;
yylval.ttype = build_tree_list ((tree) pi, pi->fndecl);
DECL_PENDING_INLINE_INFO (pi->fndecl) = 0;
interface_unknown = pi->interface == 1;
interface_only = pi->interface == 0;
}
void
do_pending_inlines ()
{
struct pending_inline *t;
if (yychar == PRE_PARSED_FUNCTION_DECL)
return;
{
struct pending_inline *prev = 0, *tail;
t = pending_inlines;
pending_inlines = 0;
for (; t; t = tail)
{
tail = t->next;
t->next = prev;
t->deja_vu = 1;
prev = t;
}
t = prev;
}
if (t == 0)
return;
begin_definition_of_inclass_inline (t);
}
static int nextchar = -1;
void
process_next_inline (t)
tree t;
{
tree context;
struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t);
context = hack_decl_function_context (i->fndecl);
if (context)
pop_cp_function_context (context);
i = i->next;
if (yychar == YYEMPTY)
yychar = yylex ();
if (yychar != END_OF_SAVED_INPUT)
{
error ("parse error at end of saved function text");
nextchar = -1;
}
yychar = YYEMPTY;
end_input ();
if (i)
begin_definition_of_inclass_inline (i);
else
extract_interface_info ();
}
static void
consume_string (this_obstack, matching_char)
register struct obstack *this_obstack;
int matching_char;
{
register int c;
int starting_lineno = lineno;
do
{
c = getch ();
if (c == EOF)
{
int save_lineno = lineno;
lineno = starting_lineno;
if (matching_char == '"')
error ("end of file encountered inside string constant");
else
error ("end of file encountered inside character constant");
lineno = save_lineno;
return;
}
if (c == '\\')
{
obstack_1grow (this_obstack, c);
c = getch ();
obstack_1grow (this_obstack, c);
c = 0;
continue;
}
if (c == '\n')
{
if (pedantic)
pedwarn ("ANSI C++ forbids newline in string constant");
lineno++;
}
obstack_1grow (this_obstack, c);
}
while (c != matching_char);
}
static int nextyychar = YYEMPTY;
static YYSTYPE nextyylval;
struct pending_input {
int nextchar, yychar, nextyychar, eof;
YYSTYPE yylval, nextyylval;
struct obstack token_obstack;
int first_token;
};
struct pending_input *
save_pending_input ()
{
struct pending_input *p;
p = (struct pending_input *) xmalloc (sizeof (struct pending_input));
p->nextchar = nextchar;
p->yychar = yychar;
p->nextyychar = nextyychar;
p->yylval = yylval;
p->nextyylval = nextyylval;
p->eof = end_of_file;
yychar = nextyychar = YYEMPTY;
nextchar = -1;
p->first_token = first_token;
p->token_obstack = token_obstack;
first_token = 0;
gcc_obstack_init (&token_obstack);
end_of_file = 0;
return p;
}
void
restore_pending_input (p)
struct pending_input *p;
{
my_friendly_assert (nextchar == -1, 229);
nextchar = p->nextchar;
my_friendly_assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT, 230);
yychar = p->yychar;
my_friendly_assert (nextyychar == YYEMPTY, 231);
nextyychar = p->nextyychar;
yylval = p->yylval;
nextyylval = p->nextyylval;
first_token = p->first_token;
obstack_free (&token_obstack, (char *) 0);
token_obstack = p->token_obstack;
end_of_file = p->eof;
free (p);
}
void
yyungetc (ch, rescan)
int ch;
int rescan;
{
if (yychar == YYEMPTY || rescan == 0)
{
if (nextchar >= 0)
put_back (nextchar);
nextchar = ch;
}
else
{
my_friendly_assert (nextyychar == YYEMPTY, 232);
nextyychar = yychar;
nextyylval = yylval;
yychar = ch;
}
}
void
clear_inline_text_obstack ()
{
obstack_free (&inline_text_obstack, inline_text_firstobj);
}
static void
store_pending_inline (decl, t)
tree decl;
struct pending_inline *t;
{
t->fndecl = decl;
DECL_PENDING_INLINE_INFO (decl) = t;
t->next = pending_inlines;
pending_inlines = t;
}
void
reinit_parse_for_method (yychar, decl)
int yychar;
tree decl;
{
int len;
int starting_lineno = lineno;
char *starting_filename = input_filename;
reinit_parse_for_block (yychar, &inline_text_obstack);
len = obstack_object_size (&inline_text_obstack);
current_base_init_list = NULL_TREE;
current_member_init_list = NULL_TREE;
if (decl == void_type_node
|| (current_class_type && TYPE_REDEFINED (current_class_type)))
{
char *buf = obstack_finish (&inline_text_obstack);
obstack_free (&inline_text_obstack, buf);
return;
}
else
{
struct pending_inline *t;
char *buf = obstack_finish (&inline_text_obstack);
t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,
sizeof (struct pending_inline));
t->lineno = starting_lineno;
t->filename = starting_filename;
t->token = YYEMPTY;
t->token_value = 0;
t->buf = buf;
t->len = len;
t->deja_vu = 0;
#if 0
if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl))
warn_if_unknown_interface (decl);
#endif
t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2));
store_pending_inline (decl, t);
}
}
void
reinit_parse_for_block (pyychar, obstackp)
int pyychar;
struct obstack *obstackp;
{
register int c = 0;
int blev = 1;
int starting_lineno = lineno;
char *starting_filename = input_filename;
int len;
int look_for_semicolon = 0;
int look_for_lbrac = 0;
if (pyychar == '{')
obstack_1grow (obstackp, '{');
else if (pyychar == '=')
look_for_semicolon = 1;
else if (pyychar == ':')
{
obstack_1grow (obstackp, pyychar);
obstack_1grow (obstackp, ' ');
look_for_lbrac = 1;
blev = 0;
}
else if (pyychar == RETURN_KEYWORD)
{
obstack_grow (obstackp, "return", 6);
look_for_lbrac = 1;
blev = 0;
}
else if (pyychar == TRY)
{
obstack_grow (obstackp, "try", 3);
look_for_lbrac = 1;
blev = 0;
}
else
{
yyerror ("parse error in method specification");
obstack_1grow (obstackp, '{');
}
if (nextchar != EOF)
{
c = nextchar;
nextchar = EOF;
}
else
c = getch ();
while (c != EOF)
{
int this_lineno = lineno;
c = skip_white_space (c);
if (lineno == this_lineno + 1)
obstack_1grow (obstackp, '\n');
else if (lineno == this_lineno)
;
else if (lineno - this_lineno < 10)
{
int i;
for (i = lineno - this_lineno; i > 0; i--)
obstack_1grow (obstackp, '\n');
}
else
{
char buf[16];
sprintf (buf, "\n# %d \"", lineno);
len = strlen (buf);
obstack_grow (obstackp, buf, len);
len = strlen (input_filename);
obstack_grow (obstackp, input_filename, len);
obstack_1grow (obstackp, '\"');
obstack_1grow (obstackp, '\n');
}
while (c > ' ')
{
obstack_1grow (obstackp, c);
if (c == '{')
{
look_for_lbrac = 0;
blev++;
}
else if (c == '}')
{
blev--;
if (blev == 0 && !look_for_semicolon)
{
if (pyychar == TRY)
{
if (peekyylex () == CATCH)
{
yylex ();
obstack_grow (obstackp, " catch ", 7);
look_for_lbrac = 1;
}
else
{
yychar = '{';
goto done;
}
}
else
{
goto done;
}
}
}
else if (c == '\\')
{
c = getch ();
if (c == EOF)
{
error_with_file_and_line (starting_filename,
starting_lineno,
"end of file read inside definition");
goto done;
}
obstack_1grow (obstackp, c);
}
else if (c == '\"')
consume_string (obstackp, c);
else if (c == '\'')
consume_string (obstackp, c);
else if (c == ';')
{
if (look_for_lbrac)
{
error ("function body for constructor missing");
obstack_1grow (obstackp, '{');
obstack_1grow (obstackp, '}');
len += 2;
goto done;
}
else if (look_for_semicolon && blev == 0)
goto done;
}
c = getch ();
}
if (c == EOF)
{
error_with_file_and_line (starting_filename,
starting_lineno,
"end of file read inside definition");
goto done;
}
else if (c != '\n')
{
obstack_1grow (obstackp, c);
c = getch ();
}
}
done:
obstack_1grow (obstackp, '\0');
}
static void
reinit_parse_for_expr (obstackp)
struct obstack *obstackp;
{
register int c = 0;
int starting_lineno = lineno;
char *starting_filename = input_filename;
int len;
int plev = 0;
if (nextchar != EOF)
{
c = nextchar;
nextchar = EOF;
}
else
c = getch ();
while (c != EOF)
{
int this_lineno = lineno;
c = skip_white_space (c);
if (lineno == this_lineno + 1)
obstack_1grow (obstackp, '\n');
else if (lineno == this_lineno)
;
else if (lineno - this_lineno < 10)
{
int i;
for (i = lineno - this_lineno; i > 0; --i)
obstack_1grow (obstackp, '\n');
}
else
{
char buf[16];
sprintf (buf, "\n# %d \"", lineno);
len = strlen (buf);
obstack_grow (obstackp, buf, len);
len = strlen (input_filename);
obstack_grow (obstackp, input_filename, len);
obstack_1grow (obstackp, '\"');
obstack_1grow (obstackp, '\n');
}
while (c > ' ')
{
if (plev <= 0 && (c == ')' || c == ','))
{
put_back (c);
goto done;
}
obstack_1grow (obstackp, c);
if (c == '(' || c == '[')
++plev;
else if (c == ']' || c == ')')
--plev;
else if (c == '\\')
{
c = getch ();
if (c == EOF)
{
error_with_file_and_line (starting_filename,
starting_lineno,
"end of file read inside definition");
goto done;
}
obstack_1grow (obstackp, c);
}
else if (c == '\"')
consume_string (obstackp, c);
else if (c == '\'')
consume_string (obstackp, c);
c = getch ();
}
if (c == EOF)
{
error_with_file_and_line (starting_filename,
starting_lineno,
"end of file read inside definition");
goto done;
}
else if (c != '\n')
{
obstack_1grow (obstackp, c);
c = getch ();
}
}
done:
obstack_1grow (obstackp, '\0');
}
int do_snarf_defarg;
void
maybe_snarf_defarg ()
{
if (current_class_type && TYPE_BEING_DEFINED (current_class_type))
do_snarf_defarg = 1;
}
tree defarg_fns;
tree defarg_parm;
tree
snarf_defarg ()
{
int len;
char *buf;
tree arg;
reinit_parse_for_expr (&inline_text_obstack);
len = obstack_object_size (&inline_text_obstack);
buf = obstack_finish (&inline_text_obstack);
push_obstacks (&inline_text_obstack, &inline_text_obstack);
arg = make_node (DEFAULT_ARG);
DEFARG_LENGTH (arg) = len - 1;
DEFARG_POINTER (arg) = buf;
pop_obstacks ();
return arg;
}
void
add_defarg_fn (decl)
tree decl;
{
if (TREE_CODE (decl) == FUNCTION_DECL)
TREE_VALUE (defarg_fns) = decl;
else
{
push_obstacks (&inline_text_obstack, &inline_text_obstack);
defarg_fns = tree_cons (current_class_type, decl, defarg_fns);
pop_obstacks ();
}
}
static void
feed_defarg (f, p)
tree f, p;
{
tree d = TREE_PURPOSE (p);
feed_input (DEFARG_POINTER (d), DEFARG_LENGTH (d));
if (TREE_CODE (f) == FUNCTION_DECL)
{
lineno = DECL_SOURCE_LINE (f);
input_filename = DECL_SOURCE_FILE (f);
}
yychar = DEFARG_MARKER;
yylval.ttype = p;
}
static void
finish_defarg ()
{
if (yychar == YYEMPTY)
yychar = yylex ();
if (yychar != END_OF_SAVED_INPUT)
{
error ("parse error at end of saved function text");
nextchar = -1;
}
yychar = YYEMPTY;
end_input ();
}
void
do_pending_defargs ()
{
if (defarg_parm)
finish_defarg ();
for (; defarg_fns; defarg_fns = TREE_CHAIN (defarg_fns))
{
tree defarg_fn = TREE_VALUE (defarg_fns);
if (defarg_parm == NULL_TREE)
{
push_nested_class (TREE_PURPOSE (defarg_fns), 1);
pushlevel (0);
if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
maybe_begin_member_template_processing (defarg_fn);
if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
{
#if 0
tree p;
for (p = DECL_ARGUMENTS (defarg_fn); p; p = TREE_CHAIN (p))
pushdecl (copy_node (p));
#endif
defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn));
}
else
defarg_parm = TYPE_ARG_TYPES (defarg_fn);
}
else
defarg_parm = TREE_CHAIN (defarg_parm);
for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm))
if (TREE_PURPOSE (defarg_parm)
&& TREE_CODE (TREE_PURPOSE (defarg_parm)) == DEFAULT_ARG)
{
feed_defarg (defarg_fn, defarg_parm);
return;
}
if (TREE_CODE (defarg_fn) == FUNCTION_DECL)
{
maybe_end_member_template_processing ();
check_default_args (defarg_fn);
}
poplevel (0, 0, 0);
pop_nested_class ();
}
}
tree
cons_up_default_function (type, full_name, kind)
tree type, full_name;
int kind;
{
extern tree void_list_node;
tree declspecs = NULL_TREE;
tree fn, args = NULL_TREE;
tree argtype;
int retref = 0;
tree name = constructor_name (full_name);
switch (kind)
{
case 1:
declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_VIRTUAL]);
case 0:
name = build_parse_node (BIT_NOT_EXPR, name);
args = void_list_node;
break;
case 2:
args = void_list_node;
break;
case 3:
type = build_qualified_type (type, TYPE_QUAL_CONST);
case 4:
argtype = build_reference_type (type);
args = tree_cons (NULL_TREE,
build_tree_list (hash_tree_chain (argtype, NULL_TREE),
get_identifier ("_ctor_arg")),
void_list_node);
break;
case 5:
case 6:
retref = 1;
declspecs = build_decl_list (NULL_TREE, type);
if (kind == 5)
type = build_qualified_type (type, TYPE_QUAL_CONST);
name = ansi_opname [(int) MODIFY_EXPR];
argtype = build_reference_type (type);
args = tree_cons (NULL_TREE,
build_tree_list (hash_tree_chain (argtype, NULL_TREE),
get_identifier ("_ctor_arg")),
void_list_node);
break;
default:
my_friendly_abort (59);
}
declspecs = decl_tree_cons (NULL_TREE, ridpointers [(int) RID_INLINE],
declspecs);
TREE_PARMLIST (args) = 1;
{
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);
}
if (fn == void_type_node)
return fn;
if (kind > 2)
SET_DECL_ARTIFICIAL (TREE_CHAIN (DECL_ARGUMENTS (fn)));
#if 0
if (processing_template_defn)
{
SET_DECL_IMPLICIT_INSTANTIATION (fn);
repo_template_used (fn);
}
#endif
#if 0
if (CLASSTYPE_INTERFACE_KNOWN (type))
{
DECL_INTERFACE_KNOWN (fn) = 1;
DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type)
&& flag_implement_inlines);
}
else
#endif
DECL_NOT_REALLY_EXTERN (fn) = 1;
mark_inline_for_output (fn);
#ifdef DEBUG_DEFAULT_FUNCTIONS
{ char *fn_type = NULL;
tree t = name;
switch (kind)
{
case 0: fn_type = "default destructor"; break;
case 1: fn_type = "virtual destructor"; break;
case 2: fn_type = "default constructor"; break;
case 3: fn_type = "default X(const X&)"; break;
case 4: fn_type = "default X(X&)"; break;
}
if (fn_type)
{
if (TREE_CODE (name) == BIT_NOT_EXPR)
t = TREE_OPERAND (name, 0);
fprintf (stderr, "[[[[ %s for %s:\n%s]]]]\n", fn_type,
IDENTIFIER_POINTER (t), func_buf);
}
}
#endif
SET_DECL_ARTIFICIAL (fn);
return fn;
}
void
check_for_missing_semicolon (type)
tree type;
{
if (yychar < 0)
yychar = yylex ();
if ((yychar > 255
&& yychar != SCSPEC
&& yychar != IDENTIFIER
&& yychar != TYPENAME
&& yychar != CV_QUALIFIER
&& yychar != SELFNAME)
|| end_of_file)
{
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
error ("semicolon missing after %s declaration",
TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
else
cp_error ("semicolon missing after declaration of `%T'", type);
shadow_tag (build_tree_list (0, type));
}
clear_anon_tags ();
}
void
note_got_semicolon (type)
tree type;
{
if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')
my_friendly_abort (60);
if (CLASS_TYPE_P (type))
CLASSTYPE_GOT_SEMICOLON (type) = 1;
}
void
note_list_got_semicolon (declspecs)
tree declspecs;
{
tree link;
for (link = declspecs; link; link = TREE_CHAIN (link))
{
tree type = TREE_VALUE (link);
if (TREE_CODE_CLASS (TREE_CODE (type)) == 't')
note_got_semicolon (type);
}
clear_anon_tags ();
}
static int
skip_white_space (c)
register int c;
{
for (;;)
{
switch (c)
{
case '\n':
c = check_newline ();
break;
case ' ':
case '\t':
case '\f':
case '\r':
case '\v':
case '\b':
do
c = getch ();
while (c == ' ' || c == '\t');
break;
case '\\':
c = getch ();
if (c == '\n')
lineno++;
else
error ("stray '\\' in program");
c = getch ();
break;
default:
return (c);
}
}
}
static char *
extend_token_buffer (p)
const char *p;
{
int offset = p - token_buffer;
maxtoken = maxtoken * 2 + 10;
token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2);
return token_buffer + offset;
}
static int
get_last_nonwhite_on_line ()
{
register int c;
if (nextchar >= 0)
c = nextchar, nextchar = -1;
else
c = getch ();
while (c == ' ' || c == '\t')
c = getch ();
return c;
}
#if defined HANDLE_PRAGMA
static int
pragma_getc ()
{
int c;
if (nextchar != EOF)
{
c = nextchar;
nextchar = EOF;
}
else
c = getch ();
return c;
}
static void
pragma_ungetc (arg)
int arg;
{
yyungetc (arg, 0);
}
#endif
int linemode;
static int
check_newline ()
{
register int c;
register int token;
int saw_line = 0;
do
c = getch ();
while (c == ' ' || c == '\t');
lineno++;
if (c != '#')
{
return c;
}
linemode = 1;
do
c = getch ();
while (c == ' ' || c == '\t');
if (ISALPHA (c))
{
if (c == 'p')
{
if (getch () == 'r'
&& getch () == 'a'
&& getch () == 'g'
&& getch () == 'm'
&& getch () == 'a')
{
token = real_yylex ();
if (token == IDENTIFIER
&& TREE_CODE (yylval.ttype) == IDENTIFIER_NODE)
{
if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype)))
goto skipline;
}
else if (token == END_OF_LINE)
goto skipline;
#ifdef HANDLE_PRAGMA
#if defined (NEXT_SEMANTICS) || defined (NEXT_PDO)
if (nextchar >= 0)
c = nextchar, nextchar = -1;
else
c = getch ();
if (c == EOF)
c = '\n';
ungetc (c, finput);
#endif
if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc,
IDENTIFIER_POINTER (yylval.ttype)))
goto skipline;
#endif
#ifdef HANDLE_GENERIC_PRAGMAS
if (handle_generic_pragma (token))
goto skipline;
#endif
if (warn_unknown_pragmas > 1
|| (warn_unknown_pragmas && ! in_system_header))
warning ("ignoring pragma: %s", token_buffer);
}
goto skipline;
}
else if (c == 'd')
{
if (getch () == 'e'
&& getch () == 'f'
&& getch () == 'i'
&& getch () == 'n'
&& getch () == 'e'
&& ((c = getch ()) == ' ' || c == '\t'))
{
debug_define (lineno, GET_DIRECTIVE_LINE ());
goto skipline;
}
}
else if (c == 'u')
{
if (getch () == 'n'
&& getch () == 'd'
&& getch () == 'e'
&& getch () == 'f'
&& ((c = getch ()) == ' ' || c == '\t'))
{
debug_undef (lineno, GET_DIRECTIVE_LINE ());
goto skipline;
}
}
else if (c == 'l')
{
if (getch () == 'i'
&& getch () == 'n'
&& getch () == 'e'
&& ((c = getch ()) == ' ' || c == '\t'))
{
saw_line = 1;
goto linenum;
}
}
else if (c == 'i')
{
if (getch () == 'd'
&& getch () == 'e'
&& getch () == 'n'
&& getch () == 't'
&& ((c = getch ()) == ' ' || c == '\t'))
{
token = real_yylex ();
if (token == END_OF_LINE)
goto skipline;
if (token != STRING
|| TREE_CODE (yylval.ttype) != STRING_CST)
{
error ("invalid #ident");
goto skipline;
}
if (! flag_no_ident)
{
#ifdef ASM_OUTPUT_IDENT
ASM_OUTPUT_IDENT (asm_out_file,
TREE_STRING_POINTER (yylval.ttype));
#endif
}
goto skipline;
}
}
else if (c == 'n')
{
if (getch () == 'e'
&& getch () == 'w'
&& getch () == 'w'
&& getch () == 'o'
&& getch () == 'r'
&& getch () == 'l'
&& getch () == 'd'
&& ((c = getch ()) == ' ' || c == '\t'))
{
sorry ("#pragma newworld");
goto skipline;
}
}
error ("undefined or invalid # directive");
goto skipline;
}
linenum:
while (c == ' ' || c == '\t')
c = getch ();
if (c == EOF)
goto skipline;
put_back (c);
token = real_yylex ();
if (token == CONSTANT
&& TREE_CODE (yylval.ttype) == INTEGER_CST)
{
int old_lineno = lineno;
enum { act_none, act_push, act_pop } action = act_none;
int entering_system_header = 0;
int entering_c_header = 0;
int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
c = get_last_nonwhite_on_line ();
if (c == EOF)
{
lineno = l;
goto skipline;
}
put_back (c);
if (saw_line)
{
ignore_escape_flag = 1;
}
token = real_yylex ();
ignore_escape_flag = 0;
if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
{
error ("invalid #line");
goto skipline;
}
if (flag_detailed_statistics)
{
int this_time = my_get_run_time ();
tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype));
header_time += this_time - body_time;
TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
+= this_time - body_time;
this_filename_time = time_identifier;
body_time = this_time;
}
input_filename
= (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
lineno = l;
GNU_xref_file (input_filename);
if (main_input_filename == 0)
{
struct impl_files *ifiles = impl_file_chain;
if (ifiles)
{
while (ifiles->next)
ifiles = ifiles->next;
ifiles->filename = file_name_nondirectory (input_filename);
}
main_input_filename = input_filename;
if (write_virtuals == 3)
{
walk_globals (vtable_decl_p,
set_vardecl_interface_info,
0);
walk_globals (vtype_decl_p,
set_typedecl_interface_info,
0);
}
}
extract_interface_info ();
c = get_last_nonwhite_on_line ();
if (c == EOF)
{
if (input_file_stack)
input_file_stack->name = input_filename;
}
else
{
put_back (c);
token = real_yylex ();
if (token == CONSTANT
&& TREE_CODE (yylval.ttype) == INTEGER_CST)
{
if (TREE_INT_CST_LOW (yylval.ttype) == 1)
action = act_push;
else if (TREE_INT_CST_LOW (yylval.ttype) == 2)
action = act_pop;
if (action)
{
c = get_last_nonwhite_on_line ();
if (c != EOF)
{
put_back (c);
token = real_yylex ();
}
}
}
if (token == CONSTANT
&& TREE_CODE (yylval.ttype) == INTEGER_CST
&& TREE_INT_CST_LOW (yylval.ttype) == 3)
{
entering_system_header = 1;
c = get_last_nonwhite_on_line ();
if (c != EOF)
{
put_back (c);
token = real_yylex ();
}
}
if (token == CONSTANT
&& TREE_CODE (yylval.ttype) == INTEGER_CST
&& TREE_INT_CST_LOW (yylval.ttype) == 4)
{
entering_c_header = 1;
c = get_last_nonwhite_on_line ();
if (c != EOF)
{
put_back (c);
token = real_yylex ();
}
}
if (action == act_push)
{
struct file_stack *p;
p = (struct file_stack *) xmalloc (sizeof (struct file_stack));
input_file_stack->line = old_lineno;
p->next = input_file_stack;
p->name = input_filename;
input_file_stack = p;
input_file_stack_tick++;
debug_start_source_file (input_filename);
in_system_header = entering_system_header;
if (c_header_level)
++c_header_level;
else if (entering_c_header)
{
c_header_level = 1;
++pending_lang_change;
}
}
else if (action == act_pop)
{
if (input_file_stack->next)
{
struct file_stack *p;
if (c_header_level && --c_header_level == 0)
{
if (entering_c_header)
warning ("badly nested C headers from preprocessor");
--pending_lang_change;
}
in_system_header = entering_system_header;
p = input_file_stack;
input_file_stack = p->next;
free (p);
input_file_stack_tick++;
debug_end_source_file (input_file_stack->line);
}
else
error ("#-lines for entering and leaving files don't match");
}
else
in_system_header = entering_system_header;
}
if (nextchar == EOF)
c = EOF;
}
else
error ("invalid #-line");
skipline:
linemode = 0;
end_of_file = 0;
nextchar = -1;
while ((c = getch ()) != EOF && c != '\n');
return c;
}
void
do_pending_lang_change ()
{
for (; pending_lang_change > 0; --pending_lang_change)
#if 0
if (doing_objc_thang)
push_lang_context (lang_name_objc);
else
#endif
push_lang_context (lang_name_c);
for (; pending_lang_change < 0; ++pending_lang_change)
pop_lang_context ();
}
#define ENDFILE -1
#ifdef PASCAL_STRINGS
#endif
static int
readescape (ignore_ptr)
int *ignore_ptr;
{
register int c = getch ();
register int code;
register unsigned count;
unsigned firstdig = 0;
int nonnull;
switch (c)
{
case 'x':
code = 0;
count = 0;
nonnull = 0;
while (1)
{
c = getch ();
if (! ISXDIGIT (c))
{
put_back (c);
break;
}
code *= 16;
if (c >= 'a' && c <= 'f')
code += c - 'a' + 10;
if (c >= 'A' && c <= 'F')
code += c - 'A' + 10;
if (c >= '0' && c <= '9')
code += c - '0';
if (code != 0 || count != 0)
{
if (count == 0)
firstdig = code;
count++;
}
nonnull = 1;
}
if (! nonnull)
error ("\\x used with no following hex digits");
else if (count == 0)
;
else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
|| (count > 1
&& (((unsigned)1 <<
(TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
<= firstdig)))
pedwarn ("hex escape out of range");
return code;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7':
code = 0;
count = 0;
while ((c <= '7') && (c >= '0') && (count++ < 3))
{
code = (code * 8) + (c - '0');
c = getch ();
}
put_back (c);
return code;
case '\\': case '\'': case '"':
return c;
case '\n':
lineno++;
*ignore_ptr = 1;
return 0;
case 'n':
return TARGET_NEWLINE;
case 't':
return TARGET_TAB;
case 'r':
return TARGET_CR;
case 'f':
return TARGET_FF;
case 'b':
return TARGET_BS;
case 'a':
return TARGET_BELL;
case 'v':
return TARGET_VT;
case 'e':
case 'E':
if (pedantic)
pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
return 033;
case '?':
return c;
case '(':
case '{':
case '[':
case '%':
if (pedantic)
pedwarn ("unknown escape sequence `\\%c'", c);
return c;
#ifdef PASCAL_STRINGS
case 'p':
if (flag_pascal_strings)
return -1;
#endif
}
if (ISGRAPH (c))
pedwarn ("unknown escape sequence `\\%c'", c);
else
pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
return c;
}
int looking_for_typename;
#ifdef __GNUC__
__inline
#endif
int
identifier_type (decl)
tree decl;
{
tree t;
if (TREE_CODE (decl) == TEMPLATE_DECL)
{
if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL)
return PTYPENAME;
else if (looking_for_template)
return PFUNCNAME;
}
if (looking_for_template && really_overloaded_fn (decl))
{
if (TREE_CODE (decl) == TREE_LIST)
decl = TREE_VALUE (decl);
for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t))
if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t)))
return PFUNCNAME;
}
if (TREE_CODE (decl) == NAMESPACE_DECL)
return NSNAME;
if (TREE_CODE (decl) != TYPE_DECL)
return IDENTIFIER;
if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type)
return SELFNAME;
t = got_scope;
if (t && TREE_CODE (t) == TYPENAME_TYPE)
t = TREE_TYPE (t);
decl = TREE_TYPE (decl);
if (TREE_CODE (decl) == TYPENAME_TYPE)
decl = TREE_TYPE (decl);
if (t && t == decl)
return SELFNAME;
return TYPENAME;
}
void
see_typename ()
{
looking_for_typename = 2;
if (yychar < 0)
if ((yychar = yylex ()) < 0) yychar = 0;
looking_for_typename = 0;
if (yychar == IDENTIFIER)
{
lastiddecl = lookup_name (yylval.ttype, -2);
if (lastiddecl == 0)
{
if (flag_labels_ok)
lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype);
}
else
yychar = identifier_type (lastiddecl);
}
}
static int
is_global (d)
tree d;
{
while (1)
switch (TREE_CODE (d))
{
case ERROR_MARK:
return 1;
case OVERLOAD: d = OVL_FUNCTION (d); continue;
case TREE_LIST: d = TREE_VALUE (d); continue;
default:
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (d)) == 'd', 980629);
d = CP_DECL_CONTEXT (d);
return TREE_CODE (d) == NAMESPACE_DECL;
}
}
tree
do_identifier (token, parsing, args)
register tree token;
int parsing;
tree args;
{
register tree id;
int lexing = (parsing == 1);
int in_call = (parsing == 2);
#ifdef OBJCPLUS
int is_objc_receiver_context = objc_receiver_context;
objc_receiver_context = 0;
#endif
if (! lexing || IDENTIFIER_OPNAME_P (token))
id = lookup_name (token, 0);
else
id = lastiddecl;
#ifdef OBJCPLUS
if (objc_msg_context)
id = lookup_name (token, 0);
#endif
#if 0
if ((!id || is_global (id))
&& current_class_type != 0
&& TYPE_SIZE (current_class_type) == 0)
{
tree field = lookup_field (current_class_type, token, 1, 0);
if (field == 0)
;
else if (field == error_mark_node)
id = lookup_field (current_class_type, token, 0, 0);
else if (TREE_CODE (field) == VAR_DECL
|| TREE_CODE (field) == CONST_DECL
|| TREE_CODE (field) == TEMPLATE_DECL)
id = field;
else if (TREE_CODE (field) == TYPE_DECL
&& DECL_ARTIFICIAL (field)
&& IMPLICIT_TYPENAME_P (TREE_TYPE (field)))
;
else if (TREE_CODE (field) != FIELD_DECL)
my_friendly_abort (61);
else
{
cp_error ("invalid use of member `%D'", field);
id = error_mark_node;
return id;
}
}
#endif
if (args && !current_template_parms && (!id || is_global (id)))
id = lookup_arg_dependent (token, id, args);
if (id && parsing
&& TREE_CODE (id) != OVERLOAD)
maybe_note_name_used_in_class (token, id);
if (id == error_mark_node)
{
id = lookup_name (token, 0);
return error_mark_node;
}
if (!id)
{
if (current_template_parms)
return build_min_nt (LOOKUP_EXPR, token);
else if (IDENTIFIER_OPNAME_P (token))
{
if (token != ansi_opname[ERROR_MARK])
cp_error ("`%D' not defined", token);
id = error_mark_node;
}
else if (in_call && ! flag_strict_prototype)
{
#ifdef OBJCPLUS
if (objc_method_context && is_ivar (objc_ivar_chain, token))
{
id = build_ivar_reference (token);
}
else
#endif
id = implicitly_declare (token);
}
else if (current_function_decl == 0)
{
cp_error ("`%D' was not declared in this scope", token);
id = error_mark_node;
}
else
#ifdef OBJCPLUS
if (is_objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (token), "super"))
{
id = get_super_receiver ();
}
else if (objc_method_context
&& is_ivar (objc_ivar_chain, token))
{
id = build_ivar_reference (token);
}
else
#endif
{
if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node
|| IDENTIFIER_ERROR_LOCUS (token) != current_function_decl)
{
static int undeclared_variable_notice;
cp_error ("`%D' undeclared (first use this function)", token);
if (! undeclared_variable_notice)
{
error ("(Each undeclared identifier is reported only once");
error ("for each function it appears in.)");
undeclared_variable_notice = 1;
}
}
id = error_mark_node;
SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl);
}
}
#ifdef OBJCPLUS
else
{
if (is_objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (token), "super"))
{
id = get_super_receiver ();
}
else
{
if (objc_method_context && is_ivar (objc_ivar_chain, token))
{
if (IDENTIFIER_LOCAL_VALUE (token))
warning ("local declaration of `%s' "
"hides instance variable",
IDENTIFIER_POINTER (token));
else
id = build_ivar_reference (token);
}
}
}
#endif
if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id))
{
tree shadowed = DECL_SHADOWED_FOR_VAR (id);
while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL
&& DECL_DEAD_FOR_LOCAL (shadowed))
shadowed = DECL_SHADOWED_FOR_VAR (shadowed);
if (!shadowed)
shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (id));
if (shadowed)
{
if (!DECL_ERROR_REPORTED (id))
{
warning ("name lookup of `%s' changed",
IDENTIFIER_POINTER (token));
cp_warning_at (" matches this `%D' under current ANSI rules",
shadowed);
cp_warning_at (" matches this `%D' under old rules", id);
DECL_ERROR_REPORTED (id) = 1;
}
id = shadowed;
}
else if (!DECL_ERROR_REPORTED (id))
{
static char msg[]
= "name lookup of `%s' changed for new ANSI `for' scoping";
DECL_ERROR_REPORTED (id) = 1;
if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (id)))
{
error (msg, IDENTIFIER_POINTER (token));
cp_error_at (" cannot use obsolete binding at `%D' because it has a destructor", id);
id = error_mark_node;
}
else
{
pedwarn (msg, IDENTIFIER_POINTER (token));
cp_pedwarn_at (" using obsolete binding at `%D'", id);
}
}
}
if (TREE_CODE (id) == CONST_DECL)
{
if (IDENTIFIER_CLASS_VALUE (token) == id)
enforce_access (DECL_REAL_CONTEXT(id), id);
if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
id = DECL_INITIAL (id);
}
else
id = hack_identifier (id, token);
if (current_template_parms
&& (is_overloaded_fn (id)
|| !TREE_PERMANENT (id)
|| (TREE_CODE (id) == VAR_DECL
&& CP_DECL_CONTEXT (id)
&& TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL)
|| TREE_CODE (id) == PARM_DECL
|| TREE_CODE (id) == RESULT_DECL
|| TREE_CODE (id) == USING_DECL))
id = build_min_nt (LOOKUP_EXPR, token);
return id;
}
tree
do_scoped_id (token, parsing)
tree token;
int parsing;
{
tree id;
if (parsing)
{
struct tree_binding _b;
id = binding_init (&_b);
if (!qualified_lookup_using_namespace (token, global_namespace, id, 0))
id = NULL_TREE;
else
id = BINDING_VALUE (id);
}
else
id = IDENTIFIER_GLOBAL_VALUE (token);
if (parsing && yychar == YYEMPTY)
yychar = yylex ();
if (! id)
{
if (processing_template_decl)
{
id = build_min_nt (LOOKUP_EXPR, token);
LOOKUP_EXPR_GLOBAL (id) = 1;
return id;
}
if (parsing && (yychar == '(' || yychar == LEFT_RIGHT)
&& ! flag_strict_prototype)
id = implicitly_declare (token);
else
{
if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node)
cp_error ("`::%D' undeclared (first use here)", token);
id = error_mark_node;
SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
}
}
else
{
if (TREE_CODE (id) == ADDR_EXPR)
mark_used (TREE_OPERAND (id, 0));
else if (TREE_CODE (id) != OVERLOAD)
mark_used (id);
}
if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl)
{
id = DECL_INITIAL (id);
id = build1 (NOP_EXPR, TREE_TYPE (id), id);
TREE_CONSTANT (id) = 1;
}
if (processing_template_decl)
{
if (is_overloaded_fn (id))
{
id = build_min_nt (LOOKUP_EXPR, token);
LOOKUP_EXPR_GLOBAL (id) = 1;
return id;
}
}
return convert_from_reference (id);
}
tree
identifier_typedecl_value (node)
tree node;
{
tree t, type;
type = IDENTIFIER_TYPE_VALUE (node);
if (type == NULL_TREE)
return NULL_TREE;
if (IDENTIFIER_BINDING (node))
{
t = IDENTIFIER_VALUE (node);
if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
return t;
}
if (IDENTIFIER_NAMESPACE_VALUE (node))
{
t = IDENTIFIER_NAMESPACE_VALUE (node);
if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type)
return t;
}
if (TYPE_MAIN_DECL (type))
return TYPE_MAIN_DECL (type);
return NULL_TREE;
}
static unsigned long this_token_number, last_vector_token_number = -2;
static char peekahead_id_buf[9];
struct pf_args
{
char *p;
int c;
int imag;
tree type;
REAL_VALUE_TYPE value;
};
static void
parse_float (data)
PTR data;
{
struct pf_args * args = (struct pf_args *) data;
int fflag = 0, lflag = 0;
char *copy = (char *) alloca (args->p - token_buffer + 1);
bcopy (token_buffer, copy, args->p - token_buffer + 1);
while (1)
{
int lose = 0;
switch (args->c)
{
case 'f': case 'F':
if (fflag)
error ("more than one `f' in numeric constant");
fflag = 1;
break;
case 'l': case 'L':
if (lflag)
error ("more than one `l' in numeric constant");
lflag = 1;
break;
case 'i': case 'I':
if (args->imag)
error ("more than one `i' or `j' in numeric constant");
else if (pedantic)
pedwarn ("ANSI C++ forbids imaginary numeric constants");
args->imag = 1;
break;
default:
lose = 1;
}
if (lose)
break;
if (args->p >= token_buffer + maxtoken - 3)
args->p = extend_token_buffer (args->p);
*(args->p++) = args->c;
*(args->p) = 0;
args->c = getch ();
}
if (fflag)
{
if (lflag)
error ("both `f' and `l' in floating constant");
args->type = float_type_node;
args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
if (REAL_VALUE_ISINF (args->value) && pedantic)
warning ("floating point number exceeds range of `float'");
}
else if (lflag)
{
args->type = long_double_type_node;
args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
if (REAL_VALUE_ISINF (args->value) && pedantic)
warning ("floating point number exceeds range of `long double'");
}
else
{
args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type));
if (REAL_VALUE_ISINF (args->value) && pedantic)
warning ("floating point number exceeds range of `double'");
}
}
int
real_yylex ()
{
register int c;
register int value;
int wide_flag = 0;
#ifdef OBJCPLUS
int objc_flag = 0;
#endif
int dollar_seen = 0;
int i;
++this_token_number;
if (peekahead_id_buf[0] != 0)
goto letter;
if (nextchar >= 0)
c = nextchar, nextchar = -1;
else
c = getch ();
while (1)
switch (c)
{
case ' ':
case '\t':
case '\f':
case '\v':
case '\b':
c = getch ();
break;
case '\r':
case '\n':
case '/':
case '\\':
c = skip_white_space (c);
default:
goto found_nonwhite;
}
found_nonwhite:
token_buffer[0] = c;
token_buffer[1] = 0;
switch (c)
{
case EOF:
token_buffer[0] = '\0';
end_of_file = 1;
if (input_redirected ())
value = END_OF_SAVED_INPUT;
else if (linemode)
value = END_OF_LINE;
else
value = ENDFILE;
break;
case '$':
if (! dollars_in_ident)
error ("`$' in identifier");
else if (pedantic)
pedwarn ("`$' in identifier");
dollar_seen = 1;
goto letter;
case 'L':
{
register int c = getch ();
if (c == '\'')
{
wide_flag = 1;
goto char_constant;
}
if (c == '"')
{
wide_flag = 1;
goto string_constant;
}
put_back (c);
}
#ifdef OBJCPLUS
case '@':
if (doing_objc_thang)
{
register int c = getc (finput);
if (c == '"')
{
objc_flag = 1;
goto string_constant;
}
ungetc (c, finput);
}
else
{
warning ("possible Objective-C token in C++ input. Use -ObjC");
}
#endif
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'l': case 'm': case 'n': case 'o':
case 'p': case 'q': case 'r': case 's': case 't':
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
case '_':
letter:
{
register char *p;
p = token_buffer;
if (peekahead_id_buf[0] != 0)
{
char *src = peekahead_id_buf;
while (*p++ = *src++)
;
peekahead_id_buf[0] = 0;
c = *(p -= 2);
}
if (input == 0)
{
*p++ = c;
c = getch ();
while (ISALNUM (c) || (c == '_') || c == '$')
{
if (c == '$')
{
if (! dollars_in_ident)
error ("`$' in identifier");
else if (pedantic)
pedwarn ("`$' in identifier");
}
if (p >= token_buffer + maxtoken)
p = extend_token_buffer (p);
*p++ = c;
c = getch ();
}
if (linemode && c == '\n')
{
put_back (c);
c = EOF;
}
}
else
{
*p++ = c;
c = getch ();
while (ISALNUM (c) || (c == '_') || c == '$')
{
if (c == '$')
{
if (! dollars_in_ident)
error ("`$' in identifier");
else if (pedantic)
pedwarn ("`$' in identifier");
}
if (p >= token_buffer + maxtoken)
p = extend_token_buffer (p);
*p++ = c;
c = getch ();
}
}
*p = 0;
nextchar = c;
value = IDENTIFIER;
yylval.itype = 0;
{
register struct resword *ptr;
if ((ptr = is_reserved_word (token_buffer, p - token_buffer)))
{
if (ptr->rid)
{
tree old_ttype = ridpointers[(int) ptr->rid];
if (flag_altivec && ptr->rid == RID_VECTOR)
{
int is_keyword = 0;
if (token_buffer[0] == '_')
is_keyword = 1;
else
{
nextchar = skip_white_space (nextchar);
if (nextchar == 'u' || nextchar == 's' || nextchar == 'b'
|| nextchar == 'f' || nextchar == 'p' || nextchar == 'c'
|| nextchar == 'i' || nextchar == 'l')
{
char *pb = peekahead_id_buf;
*pb++ = nextchar;
c = getch ();
while (ISALPHA (c) && pb < &peekahead_id_buf[sizeof(peekahead_id_buf)-1])
{
*pb++ = c;
c = getch();
}
*pb = 0;
put_back (c);
nextchar = -1;
pb = peekahead_id_buf;
if (ISALNUM (c) || c == '_' || c == '$')
;
else
if (! strcmp (pb, "pixel") || ! strcmp (pb, "unsigned")
|| ! strcmp (pb, "signed") || ! strcmp (pb, "bool")
|| ! strcmp (pb, "float") || ! strcmp (pb, "char")
|| ! strcmp (pb, "int") || ! strcmp (pb, "short")
|| ! strcmp (pb, "long"))
{
is_keyword = 1;
}
}
}
if (is_keyword)
last_vector_token_number = this_token_number;
else
goto check_identifier;
}
else
if (flag_altivec && ptr->rid == RID_PIXEL
&& token_buffer[0] != '_')
{
if (last_vector_token_number != this_token_number - 1)
goto check_identifier;
}
if (TREE_CODE (old_ttype) == IDENTIFIER_NODE
&& IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0
&& TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL)
looking_for_typename = 0;
else if (ptr->token == AGGR || ptr->token == ENUM)
looking_for_typename = 2;
nextchar = skip_white_space (nextchar);
if (nextchar == '"')
{
if (ptr->rid != RID_EXTERN)
error ("invalid modifier `%s' for language string",
ptr->name);
real_yylex ();
value = EXTERN_LANG_STRING;
yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype));
break;
}
if (ptr->token == VISSPEC)
{
switch (ptr->rid)
{
case RID_PUBLIC:
yylval.ttype = access_public_node;
break;
case RID_PRIVATE:
yylval.ttype = access_private_node;
break;
case RID_PROTECTED:
yylval.ttype = access_protected_node;
break;
default:
my_friendly_abort (63);
}
}
else
yylval.ttype = old_ttype;
}
else if (ptr->token == EQCOMPARE)
{
yylval.code = NE_EXPR;
token_buffer[0] = '!';
token_buffer[1] = '=';
token_buffer[2] = 0;
}
else if (ptr->token == ASSIGN)
{
if (strcmp ("and_eq", token_buffer) == 0)
{
yylval.code = BIT_AND_EXPR;
token_buffer[0] = '&';
}
else if (strcmp ("or_eq", token_buffer) == 0)
{
yylval.code = BIT_IOR_EXPR;
token_buffer[0] = '|';
}
else if (strcmp ("xor_eq", token_buffer) == 0)
{
yylval.code = BIT_XOR_EXPR;
token_buffer[0] = '^';
}
token_buffer[1] = '=';
token_buffer[2] = 0;
}
else if (ptr->token == '&')
{
yylval.code = BIT_AND_EXPR;
token_buffer[0] = '&';
token_buffer[1] = 0;
}
else if (ptr->token == '|')
{
yylval.code = BIT_IOR_EXPR;
token_buffer[0] = '|';
token_buffer[1] = 0;
}
else if (ptr->token == '^')
{
yylval.code = BIT_XOR_EXPR;
token_buffer[0] = '^';
token_buffer[1] = 0;
}
value = (int) ptr->token;
#ifdef OBJCPLUS
if (value == OBJECTNAME)
{
lastiddecl = lookup_name (yylval.ttype, 1);
if (!objc_declarator_context
&& doing_objc_thang
&& lastiddecl
&& TREE_CODE (lastiddecl) == TYPE_DECL)
value = OBJECTNAME;
else
value = IDENTIFIER;
}
#endif
}
}
check_identifier:
if (value == IDENTIFIER || value == TYPESPEC)
GNU_xref_ref (current_function_decl, token_buffer);
if (value == IDENTIFIER)
{
register tree tmp = get_identifier (token_buffer);
#ifdef OBJCPLUS
identifier:
if (token_buffer[0] == '@')
error ("illegal identifier `%s'", token_buffer);
#endif
#if !defined(VMS) && defined(JOINER)
if (JOINER == '$'
&& dollar_seen
&& (THIS_NAME_P (tmp)
|| VPTR_NAME_P (tmp)
|| DESTRUCTOR_NAME_P (tmp)
|| VTABLE_NAME_P (tmp)
|| TEMP_NAME_P (tmp)
|| ANON_AGGRNAME_P (tmp)
|| ANON_PARMNAME_P (tmp)))
warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy",
token_buffer);
#ifdef OBJCPLUS
else
#endif
#endif
#ifdef OBJCPLUS
if (doing_objc_thang
&& is_class_name (tmp)
&& !got_scope
&& (lookup_name(tmp, -2) == IDENTIFIER_GLOBAL_VALUE(tmp)))
value = CLASSNAME;
#endif
yylval.ttype = tmp;
}
if (value == NEW && ! global_bindings_p ())
{
value = NEW;
goto done;
}
}
break;
case '.':
{
register int c1 = getch ();
token_buffer[0] = c;
token_buffer[1] = c1;
if (c1 == '*')
{
value = DOT_STAR;
token_buffer[2] = 0;
goto done;
}
if (c1 == '.')
{
c1 = getch ();
if (c1 == '.')
{
token_buffer[2] = c1;
token_buffer[3] = 0;
value = ELLIPSIS;
goto done;
}
error ("parse error at `..'");
}
if (ISDIGIT (c1))
{
put_back (c1);
goto resume_numerical_scan;
}
nextchar = c1;
value = '.';
token_buffer[1] = 0;
goto done;
}
case '0': case '1':
{
register int c1 = getch ();
if (! ISALNUM (c1) && c1 != '.')
{
token_buffer[0] = c;
token_buffer[1] = 0;
if (c == '0')
yylval.ttype = integer_zero_node;
else
yylval.ttype = integer_one_node;
nextchar = c1;
value = CONSTANT;
goto done;
}
put_back (c1);
}
case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
resume_numerical_scan:
{
register char *p;
int base = 10;
int count = 0;
int largest_digit = 0;
int numdigits = 0;
#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2)
int parts[TOTAL_PARTS];
int overflow = 0;
enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag
= NOT_FLOAT;
for (count = 0; count < TOTAL_PARTS; count++)
parts[count] = 0;
p = token_buffer;
*p++ = c;
if (c == '0')
{
*p++ = (c = getch ());
if ((c == 'x') || (c == 'X'))
{
base = 16;
*p++ = (c = getch ());
}
else if (c >= '0' && c <= '9')
{
base = 8;
numdigits++;
}
else
numdigits++;
}
while (c == '.'
|| (ISALNUM (c) && (c != 'l') && (c != 'L')
&& (c != 'u') && (c != 'U')
&& c != 'i' && c != 'I' && c != 'j' && c != 'J'
&& (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F')))))
{
if (c == '.')
{
if (base == 16)
error ("floating constant may not be in radix 16");
if (floatflag == TOO_MANY_POINTS)
;
else if (floatflag == AFTER_POINT)
{
error ("malformed floating constant");
floatflag = TOO_MANY_POINTS;
p[-1] = '\0';
}
else
floatflag = AFTER_POINT;
base = 10;
*p++ = c = getch ();
if (p == token_buffer + 2 && !ISDIGIT (c))
{
if (c == '.')
{
c = getch ();
if (c == '.')
{
*p++ = '.';
*p = '\0';
value = ELLIPSIS;
goto done;
}
error ("parse error at `..'");
}
nextchar = c;
token_buffer[1] = '\0';
value = '.';
goto done;
}
}
else
{
if (ISDIGIT (c))
{
c = c - '0';
}
else if (base <= 10)
{
if (c == 'e' || c == 'E')
{
base = 10;
floatflag = AFTER_POINT;
break;
}
error ("nondigits in number and not hexadecimal");
c = 0;
}
else if (c >= 'a')
{
c = c - 'a' + 10;
}
else
{
c = c - 'A' + 10;
}
if (c >= largest_digit)
largest_digit = c;
numdigits++;
for (count = 0; count < TOTAL_PARTS; count++)
{
parts[count] *= base;
if (count)
{
parts[count]
+= (parts[count-1] >> HOST_BITS_PER_CHAR);
parts[count-1]
&= (1 << HOST_BITS_PER_CHAR) - 1;
}
else
parts[0] += c;
}
if (parts[TOTAL_PARTS - 1] != 0)
overflow = 1;
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = (c = getch ());
}
}
if (numdigits == 0)
error ("numeric constant with no digits");
if (largest_digit >= base)
error ("numeric constant contains digits beyond the radix");
*--p = 0;
if (floatflag != NOT_FLOAT)
{
tree type = double_type_node;
int exceeds_double = 0;
int imag = 0;
REAL_VALUE_TYPE value;
struct pf_args args;
if ((c == 'e') || (c == 'E'))
{
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
c = getch ();
if ((c == '+') || (c == '-'))
{
*p++ = c;
c = getch ();
}
if (! ISDIGIT (c))
error ("floating constant exponent has no digits");
while (ISDIGIT (c))
{
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
c = getch ();
}
}
*p = 0;
errno = 0;
args.p = p;
args.c = c;
args.imag = imag;
args.type = type;
if (do_float_handler (parse_float, (PTR) &args))
{
value = args.value;
}
else
{
error ("floating constant out of range");
value = dconst0;
}
p = args.p;
c = args.c;
imag = args.imag;
type = args.type;
#ifdef ERANGE
if (errno == ERANGE && pedantic)
{
if (REAL_VALUES_LESS (dconst1, value)
|| REAL_VALUES_LESS (value, dconstm1))
{
pedwarn ("floating point number exceeds range of `%s'",
IDENTIFIER_POINTER (TYPE_IDENTIFIER (type)));
exceeds_double = 1;
}
}
#endif
if (REAL_VALUE_ISNAN (value))
value = dconst0;
if (imag)
yylval.ttype = build_complex (NULL_TREE,
cp_convert (type, integer_zero_node),
build_real (type, value));
else
yylval.ttype = build_real (type, value);
}
else
{
tree type;
HOST_WIDE_INT high, low;
int spec_unsigned = 0;
int spec_long = 0;
int spec_long_long = 0;
int spec_imag = 0;
int bytes, warn;
while (1)
{
if (c == 'u' || c == 'U')
{
if (spec_unsigned)
error ("two `u's in integer constant");
spec_unsigned = 1;
}
else if (c == 'l' || c == 'L')
{
if (spec_long)
{
if (spec_long_long)
error ("three `l's in integer constant");
else if (pedantic && ! in_system_header && warn_long_long)
pedwarn ("ANSI C++ forbids long long integer constants");
spec_long_long = 1;
}
spec_long = 1;
}
else if (c == 'i' || c == 'j' || c == 'I' || c == 'J')
{
if (spec_imag)
error ("more than one `i' or `j' in numeric constant");
else if (pedantic)
pedwarn ("ANSI C++ forbids imaginary numeric constants");
spec_imag = 1;
}
else
break;
if (p >= token_buffer + maxtoken - 3)
p = extend_token_buffer (p);
*p++ = c;
c = getch ();
}
if (spec_long_long)
bytes = TYPE_PRECISION (long_long_integer_type_node) / 8;
else
bytes = TYPE_PRECISION (long_integer_type_node) / 8;
warn = overflow;
for (i = bytes; i < TOTAL_PARTS; i++)
if (parts[i])
warn = 1;
if (warn)
pedwarn ("integer constant out of range");
high = low = 0;
for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++)
{
high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT
/ HOST_BITS_PER_CHAR)]
<< (i * HOST_BITS_PER_CHAR));
low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR);
}
yylval.ttype = build_int_2 (low, high);
TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node;
if (!spec_long && !spec_unsigned
&& int_fits_type_p (yylval.ttype, integer_type_node))
type = integer_type_node;
else if (!spec_long && (base != 10 || spec_unsigned)
&& int_fits_type_p (yylval.ttype, unsigned_type_node))
type = unsigned_type_node;
else if (!spec_unsigned && !spec_long_long
&& int_fits_type_p (yylval.ttype, long_integer_type_node))
type = long_integer_type_node;
else if (! spec_long_long)
type = long_unsigned_type_node;
else if (! spec_unsigned
&& TREE_INT_CST_HIGH (yylval.ttype) >= 0
&& int_fits_type_p (yylval.ttype,
long_long_integer_type_node))
type = long_long_integer_type_node;
else
type = long_long_unsigned_type_node;
if (!int_fits_type_p (yylval.ttype, type) && !warn)
pedwarn ("integer constant out of range");
if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type))
warning ("decimal integer constant is so large that it is unsigned");
if (spec_imag)
{
if (TYPE_PRECISION (type)
<= TYPE_PRECISION (integer_type_node))
yylval.ttype
= build_complex (NULL_TREE, integer_zero_node,
cp_convert (integer_type_node,
yylval.ttype));
else
error ("complex integer constant is too wide for `__complex int'");
}
else
TREE_TYPE (yylval.ttype) = type;
}
put_back (c);
*p = 0;
value = CONSTANT; break;
}
case '\'':
char_constant:
{
register int result = 0;
register int num_chars = 0;
int chars_seen = 0;
unsigned width = TYPE_PRECISION (char_type_node);
int max_chars;
#ifdef MULTIBYTE_CHARS
int longest_char = local_mb_cur_max ();
(void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
#endif
max_chars = TYPE_PRECISION (integer_type_node) / width;
if (wide_flag)
width = WCHAR_TYPE_SIZE;
while (1)
{
tryagain:
c = getch ();
if (c == '\'' || c == EOF)
break;
++chars_seen;
if (c == '\\')
{
int ignore = 0;
c = readescape (&ignore);
if (ignore)
goto tryagain;
#ifdef PASCAL_STRINGS
if (flag_pascal_strings && c < 0)
{
pedwarn ("pascal string-length escape (\\p) not"
" allowed in character constant");
c = 'p';
}
#endif
if (width < HOST_BITS_PER_INT
&& (unsigned) c >= ((unsigned)1 << width))
pedwarn ("escape sequence out of range for character");
#ifdef MAP_CHARACTER
if (ISPRINT (c))
c = MAP_CHARACTER (c);
#endif
}
else if (c == '\n')
{
if (pedantic)
pedwarn ("ANSI C forbids newline in character constant");
lineno++;
}
else
{
#ifdef MULTIBYTE_CHARS
wchar_t wc;
int i;
int char_len = -1;
for (i = 1; i <= longest_char; ++i)
{
if (i > maxtoken - 4)
extend_token_buffer (token_buffer);
token_buffer[i] = c;
char_len = local_mbtowc (& wc,
token_buffer + 1,
i);
if (char_len != -1)
break;
c = getch ();
}
if (char_len > 1)
{
if (char_len < i)
put_back (c);
if (! wide_flag)
{
for (i = 1; i <= char_len; ++i)
{
if (i > max_chars)
break;
if (width < HOST_BITS_PER_INT)
result = (result << width)
| (token_buffer[i]
& ((1 << width) - 1));
else
result = token_buffer[i];
}
num_chars += char_len;
goto tryagain;
}
c = wc;
}
else
{
if (char_len == -1)
warning ("Ignoring invalid multibyte character");
if (wide_flag)
c = wc;
#ifdef MAP_CHARACTER
else
c = MAP_CHARACTER (c);
#endif
}
#else
#ifdef MAP_CHARACTER
c = MAP_CHARACTER (c);
#endif
#endif
}
if (wide_flag)
{
if (chars_seen == 1)
result = c;
goto tryagain;
}
num_chars++;
if (num_chars < max_chars + 1)
{
if (width < HOST_BITS_PER_INT)
result = (result << width) | (c & ((1 << width) - 1));
else
result = c;
}
}
if (c != '\'')
error ("malformatted character constant");
else if (chars_seen == 0)
error ("empty character constant");
else if (num_chars > max_chars)
{
num_chars = max_chars;
error ("character constant too long");
}
#ifdef FOUR_CHAR_CONSTANTS
else if (chars_seen != 1)
if (warn_multichar &&
(warn_four_char_constants || chars_seen != 4))
warning ("multi-character character constant");
#else
else if (chars_seen != 1 && warn_multichar)
warning ("multi-character character constant");
#endif
if (! wide_flag)
{
int num_bits = num_chars * width;
if (num_bits == 0)
yylval.ttype = build_int_2 (0, 0);
else if (TREE_UNSIGNED (char_type_node)
|| ((result >> (num_bits - 1)) & 1) == 0)
yylval.ttype
= build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0
>> (HOST_BITS_PER_WIDE_INT - num_bits)),
0);
else
yylval.ttype
= build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0
>> (HOST_BITS_PER_WIDE_INT - num_bits)),
-1);
if (chars_seen <= 1)
TREE_TYPE (yylval.ttype) = char_type_node;
else
TREE_TYPE (yylval.ttype) = integer_type_node;
}
else
{
yylval.ttype = build_int_2 (result, 0);
TREE_TYPE (yylval.ttype) = wchar_type_node;
}
value = CONSTANT;
break;
}
case '"':
string_constant:
{
register char *p;
#ifdef PASCAL_STRINGS
int is_pascal_string = 0;
#endif
unsigned width = wide_flag ? WCHAR_TYPE_SIZE
: TYPE_PRECISION (char_type_node);
#ifdef MULTIBYTE_CHARS
int longest_char = local_mb_cur_max ();
(void) local_mbtowc (NULL_PTR, NULL_PTR, 0);
#endif
c = getch ();
p = token_buffer + 1;
while (c != '"' && c >= 0)
{
if (!ignore_escape_flag && c == '\\')
{
int ignore = 0;
c = readescape (&ignore);
if (ignore)
goto skipnewline;
#ifdef PASCAL_STRINGS
if (flag_pascal_strings && c < 0)
{
if (wide_flag)
{
pedwarn ("pascal string-length escape (\\p) not"
" allowed in wide string");
c = 'p';
}
#ifdef OBJCPLUS
else if (objc_flag)
{
pedwarn ("pascal string-length escape (\\p) not"
" allowed in Objective-C string");
c = 'p';
}
#endif
else if (p == token_buffer + 1)
{
is_pascal_string = 1;
c = 0;
}
else
{
pedwarn ("pascal string-length escape (\\p) must"
" be at beginning of string");
c = 'p';
}
}
#endif
if (width < HOST_BITS_PER_INT
&& (unsigned) c >= ((unsigned)1 << width))
warning ("escape sequence out of range for character");
}
else if (c == '\n')
{
if (pedantic)
pedwarn ("ANSI C++ forbids newline in string constant");
lineno++;
}
else
{
#ifdef MULTIBYTE_CHARS
wchar_t wc;
int i;
int char_len = -1;
for (i = 0; i < longest_char; ++i)
{
if (p + i >= token_buffer + maxtoken)
p = extend_token_buffer (p);
p[i] = c;
char_len = local_mbtowc (& wc, p, i + 1);
if (char_len != -1)
break;
c = getch ();
}
if (char_len == -1)
warning ("Ignoring invalid multibyte character");
else
{
if (char_len <= i)
put_back (c);
if (! wide_flag)
{
p += (i + 1);
c = getch ();
continue;
}
c = wc;
}
#endif
}
if (wide_flag)
{
unsigned width = TYPE_PRECISION (char_type_node);
unsigned bytemask = (1 << width) - 1;
int byte;
if (p + WCHAR_BYTES > token_buffer + maxtoken)
p = extend_token_buffer (p);
for (byte = 0; byte < WCHAR_BYTES; ++byte)
{
int value;
if (byte >= (int) sizeof(c))
value = 0;
else
value = (c >> (byte * width)) & bytemask;
if (BYTES_BIG_ENDIAN)
p[WCHAR_BYTES - byte - 1] = value;
else
p[byte] = value;
}
p += WCHAR_BYTES;
}
else
{
if (p >= token_buffer + maxtoken)
p = extend_token_buffer (p);
*p++ = c;
}
skipnewline:
c = getch ();
if (c == EOF) {
error ("Unterminated string");
break;
}
}
if (wide_flag)
{
if (p + WCHAR_BYTES > token_buffer + maxtoken)
p = extend_token_buffer (p);
bzero (p, WCHAR_BYTES);
p += WCHAR_BYTES;
}
else
{
if (p >= token_buffer + maxtoken)
p = extend_token_buffer (p);
*p++ = 0;
}
#ifdef OBJCPLUS
if (objc_flag)
{
extern tree build_objc_string();
yylval.ttype = build_objc_string (p - token_buffer,
token_buffer + 1);
value = OBJC_STRING;
break;
}
#endif
if (processing_template_decl)
push_obstacks (&permanent_obstack, &permanent_obstack);
#ifdef PASCAL_STRINGS
if (is_pascal_string)
{
int slen = p - token_buffer -3;
if (slen > 255)
{
error ("pascal string too long");
slen = 255;
}
token_buffer[1] = slen;
yylval.ttype = build_string (slen + 2, token_buffer + 1);
if (processing_template_decl)
pop_obstacks ();
TREE_TYPE (yylval.ttype) = unsigned_char_array_type_node;
}
else {
#endif
yylval.ttype = build_string (p - (token_buffer + 1), token_buffer + 1);
if (processing_template_decl)
pop_obstacks ();
if (wide_flag)
TREE_TYPE (yylval.ttype) = wchar_array_type_node;
else
TREE_TYPE (yylval.ttype) = char_array_type_node;
#ifdef PASCAL_STRINGS
}
#endif
value = STRING; break;
}
case '+':
case '-':
case '&':
case '|':
case '<':
case '>':
case '*':
case '/':
case '%':
case '^':
case '!':
case '=':
{
register int c1;
combine:
switch (c)
{
case '+':
yylval.code = PLUS_EXPR; break;
case '-':
yylval.code = MINUS_EXPR; break;
case '&':
yylval.code = BIT_AND_EXPR; break;
case '|':
yylval.code = BIT_IOR_EXPR; break;
case '*':
yylval.code = MULT_EXPR; break;
case '/':
yylval.code = TRUNC_DIV_EXPR; break;
case '%':
yylval.code = TRUNC_MOD_EXPR; break;
case '^':
yylval.code = BIT_XOR_EXPR; break;
case LSHIFT:
yylval.code = LSHIFT_EXPR; break;
case RSHIFT:
yylval.code = RSHIFT_EXPR; break;
case '<':
yylval.code = LT_EXPR; break;
case '>':
yylval.code = GT_EXPR; break;
}
token_buffer[1] = c1 = getch ();
token_buffer[2] = 0;
if (c1 == '=')
{
switch (c)
{
case '<':
value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
case '>':
value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
case '!':
value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
case '=':
value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
}
value = ASSIGN; goto done;
}
else if (c == c1)
switch (c)
{
case '+':
value = PLUSPLUS; goto done;
case '-':
value = MINUSMINUS; goto done;
case '&':
value = ANDAND; goto done;
case '|':
value = OROR; goto done;
case '<':
c = LSHIFT;
goto combine;
case '>':
c = RSHIFT;
goto combine;
}
else if ((c == '-') && (c1 == '>'))
{
nextchar = getch ();
if (nextchar == '*')
{
nextchar = -1;
value = POINTSAT_STAR;
}
else
value = POINTSAT;
goto done;
}
else if (c1 == '?' && (c == '<' || c == '>'))
{
token_buffer[3] = 0;
c1 = getch ();
yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR);
if (c1 == '=')
{
token_buffer[2] = c1;
value = ASSIGN;
}
else
{
value = MIN_MAX;
nextchar = c1;
}
if (pedantic)
pedwarn ("use of `operator %s' is not standard C++",
token_buffer);
goto done;
}
else if (c == '<' && c1 == '%')
{ value = '{'; goto done; }
else if (c == '<' && c1 == ':')
{ value = '['; goto done; }
else if (c == '%' && c1 == '>')
{ value = '}'; goto done; }
else if (c == '%' && c1 == ':')
{ value = '#'; goto done; }
nextchar = c1;
token_buffer[1] = 0;
value = c;
goto done;
}
case ':':
c = getch ();
if (c == ':')
{
token_buffer[1] = ':';
token_buffer[2] = '\0';
value = SCOPE;
yylval.itype = 1;
}
else if (c == '>')
{
value = ']';
goto done;
}
else
{
nextchar = c;
value = ':';
}
break;
case 0:
value = 1;
break;
case '(':
nextchar = skip_white_space (getch ());
if (nextchar == '*')
{
int next_c = skip_white_space (getch ());
if (next_c == ')')
{
nextchar = -1;
yylval.ttype = build1 (INDIRECT_REF, 0, 0);
value = PAREN_STAR_PAREN;
}
else
{
put_back (next_c);
value = c;
}
}
else if (nextchar == ')')
{
nextchar = -1;
yylval.ttype = NULL_TREE;
value = LEFT_RIGHT;
}
else value = c;
break;
default:
value = c;
}
done:
#ifdef GATHER_STATISTICS
#ifdef REDUCE_LENGTH
token_count[value] += 1;
#endif
#endif
return value;
}
int
is_rid (t)
tree t;
{
struct resword *r;
r = is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));
if (r && flag_altivec && (r->rid == RID_VECTOR || r->rid == RID_PIXEL)
&& * (IDENTIFIER_POINTER (t)) != '_')
{
r = 0;
}
return !!r;
}
#ifdef GATHER_STATISTICS
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 free_lang_decl_chain;
tree
build_lang_decl (code, name, type)
enum tree_code code;
tree name;
tree type;
{
register tree t = build_decl (code, name, type);
retrofit_lang_decl (t);
return t;
}
void
retrofit_lang_decl (t)
tree t;
{
struct obstack *obstack = current_obstack;
register int i = sizeof (struct lang_decl) / sizeof (int);
register int *pi;
if (! TREE_PERMANENT (t))
obstack = saveable_obstack;
else
obstack = &permanent_obstack;
if (free_lang_decl_chain && obstack == &permanent_obstack)
{
pi = (int *)free_lang_decl_chain;
free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain);
}
else
pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl));
while (i > 0)
pi[--i] = 0;
DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
LANG_DECL_PERMANENT ((struct lang_decl *) pi)
= obstack == &permanent_obstack;
my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi)
== TREE_PERMANENT (t), 234);
DECL_MAIN_VARIANT (t) = t;
if (current_lang_name == lang_name_cplusplus)
DECL_LANGUAGE (t) = lang_cplusplus;
else if (current_lang_name == lang_name_c)
DECL_LANGUAGE (t) = lang_c;
else if (current_lang_name == lang_name_java)
DECL_LANGUAGE (t) = lang_java;
#ifdef OBJCPLUS
else if (current_lang_name == lang_name_objc)
DECL_LANGUAGE (t) = lang_objc;
#endif
else my_friendly_abort (64);
#if 0
if (code == TYPE_DECL)
{
tree id;
id = get_identifier (build_overload_name (type, 1, 1));
DECL_ASSEMBLER_NAME (t) = id;
}
#endif
#ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_decl] += 1;
tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
#endif
}
tree
build_lang_field_decl (code, name, type)
enum tree_code code;
tree name;
tree type;
{
extern struct obstack *current_obstack, *saveable_obstack;
register tree t = build_decl (code, name, type);
struct obstack *obstack = current_obstack;
register int i = sizeof (struct lang_decl_flags) / sizeof (int);
register int *pi;
#if 0
if (code == TYPE_DECL)
{
tree id;
id = get_identifier (build_overload_name (type, 1, 1));
DECL_ASSEMBLER_NAME (t) = id;
}
#endif
if (! TREE_PERMANENT (t))
obstack = saveable_obstack;
else
my_friendly_assert (obstack == &permanent_obstack, 235);
pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags));
while (i > 0)
pi[--i] = 0;
DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi;
return t;
}
void
copy_lang_decl (node)
tree node;
{
int size;
int *pi;
if (! DECL_LANG_SPECIFIC (node))
return;
if (TREE_CODE (node) == FIELD_DECL)
size = sizeof (struct lang_decl_flags);
else
size = sizeof (struct lang_decl);
pi = (int *)obstack_alloc (&permanent_obstack, size);
bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size);
DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi;
}
tree
make_lang_type (code)
enum tree_code code;
{
extern struct obstack *current_obstack, *saveable_obstack;
register tree t = make_node (code);
if (IS_AGGR_TYPE_CODE (code))
{
struct obstack *obstack = current_obstack;
struct lang_type *pi;
SET_IS_AGGR_TYPE (t, 1);
if (! TREE_PERMANENT (t))
obstack = saveable_obstack;
else
my_friendly_assert (obstack == &permanent_obstack, 236);
pi = (struct lang_type *) obstack_alloc (obstack, sizeof (struct lang_type));
bzero ((char *) pi, (int) sizeof (struct lang_type));
TYPE_LANG_SPECIFIC (t) = pi;
SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
build_pointer_type (t);
#ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_type] += 1;
tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
#endif
}
else
TYPE_ALIAS_SET (t) = 0;
if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM)
TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE);
return t;
}
void
dump_time_statistics ()
{
register tree prev = 0, decl, next;
int this_time = my_get_run_time ();
TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time))
+= this_time - body_time;
fprintf (stderr, "\n******\n");
print_time ("header files (total)", header_time);
print_time ("main file (total)", this_time - body_time);
fprintf (stderr, "ratio = %g : 1\n",
(double)header_time / (double)(this_time - body_time));
fprintf (stderr, "\n******\n");
for (decl = filename_times; decl; decl = next)
{
next = IDENTIFIER_GLOBAL_VALUE (decl);
SET_IDENTIFIER_GLOBAL_VALUE (decl, prev);
prev = decl;
}
for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl))
print_time (IDENTIFIER_POINTER (decl),
TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (decl)));
}
void
compiler_error VPROTO ((const char *msg, ...))
{
#ifndef ANSI_PROTOTYPES
const char *msg;
#endif
char buf[1024];
va_list ap;
VA_START (ap, msg);
#ifndef ANSI_PROTOTYPES
msg = va_arg (ap, const char *);
#endif
vsprintf (buf, msg, ap);
error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
}
void
yyerror (string)
const char *string;
{
extern int end_of_file;
char buf[200];
strcpy (buf, string);
if (end_of_file)
strcat (buf, input_redirected ()
? " at end of saved text"
: " at end of input");
else if (token_buffer[0] == 0)
strcat (buf, " at null character");
else if (token_buffer[0] == '"')
strcat (buf, " before string constant");
else if (token_buffer[0] == '\'')
strcat (buf, " before character constant");
else if (!ISGRAPH ((unsigned char)token_buffer[0]))
sprintf (buf + strlen (buf), " before character 0%o",
(unsigned char) token_buffer[0]);
else
strcat (buf, " before `%s'");
error (buf, token_buffer);
}
static int
handle_cp_pragma (pname)
const char *pname;
{
register int token;
if (! strcmp (pname, "vtable"))
{
extern tree pending_vtables;
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"))
{
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
= TIME_IDENTIFIER_FILEINFO (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");
write_virtuals = 3;
if (impl_file_chain == 0)
{
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 = TIME_IDENTIFIER_FILEINFO (fi);
TREE_INT_CST_LOW (fi) = 0;
TREE_INT_CST_HIGH (fi) = 1;
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);
#ifdef MULTIPLE_SYMBOL_SPACES
if (! interface_only)
interface_unknown = 0;
#else
interface_unknown = 0;
#endif
TREE_INT_CST_LOW (fileinfo) = interface_only;
TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
return 1;
}
else if (! strcmp (pname, "implementation"))
{
tree fileinfo
= TIME_IDENTIFIER_FILEINFO (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");
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
interface_unknown = 1;
#else
interface_unknown = 0;
#endif
TREE_INT_CST_LOW (fileinfo) = interface_only;
TREE_INT_CST_HIGH (fileinfo) = interface_unknown;
return 1;
}
return 0;
}
int
cp_type_qual_from_rid (rid)
tree rid;
{
if (rid == ridpointers[(int) RID_CONST])
return TYPE_QUAL_CONST;
else if (rid == ridpointers[(int) RID_VOLATILE])
return TYPE_QUAL_VOLATILE;
else if (rid == ridpointers[(int) RID_RESTRICT])
return TYPE_QUAL_RESTRICT;
my_friendly_abort (0);
return TYPE_UNQUALIFIED;
}
#ifdef HANDLE_GENERIC_PRAGMAS
static int
handle_generic_pragma (token)
register int token;
{
for (;;)
{
switch (token)
{
case IDENTIFIER:
case TYPENAME:
case STRING:
case CONSTANT:
handle_pragma_token (token_buffer, yylval.ttype);
break;
case LEFT_RIGHT:
handle_pragma_token ("(", NULL_TREE);
handle_pragma_token (")", NULL_TREE);
break;
case END_OF_LINE:
return handle_pragma_token (NULL_PTR, NULL_TREE);
default:
handle_pragma_token (token_buffer, NULL_TREE);
}
token = real_yylex ();
}
}
#endif