198 lines
6.6 KiB
C
198 lines
6.6 KiB
C
/* Declarations for the parser for C and Objective-C.
|
|
Copyright (C) 1987-2021 Free Software Foundation, Inc.
|
|
|
|
Parser actions based on the old Bison parser; structure somewhat
|
|
influenced by and fragments based on the C++ parser.
|
|
|
|
This file is part of GCC.
|
|
|
|
GCC is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free
|
|
Software Foundation; either version 3, or (at your option) any later
|
|
version.
|
|
|
|
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GCC; see the file COPYING3. If not see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#ifndef GCC_C_PARSER_H
|
|
#define GCC_C_PARSER_H
|
|
|
|
/* The C lexer intermediates between the lexer in cpplib and c-lex.c
|
|
and the C parser. Unlike the C++ lexer, the parser structure
|
|
stores the lexer information instead of using a separate structure.
|
|
Identifiers are separated into ordinary identifiers, type names,
|
|
keywords and some other Objective-C types of identifiers, and some
|
|
look-ahead is maintained.
|
|
|
|
??? It might be a good idea to lex the whole file up front (as for
|
|
C++). It would then be possible to share more of the C and C++
|
|
lexer code, if desired. */
|
|
|
|
/* More information about the type of a CPP_NAME token. */
|
|
enum c_id_kind {
|
|
/* An ordinary identifier. */
|
|
C_ID_ID,
|
|
/* An identifier declared as a typedef name. */
|
|
C_ID_TYPENAME,
|
|
/* An identifier declared as an Objective-C class name. */
|
|
C_ID_CLASSNAME,
|
|
/* An address space identifier. */
|
|
C_ID_ADDRSPACE,
|
|
/* Not an identifier. */
|
|
C_ID_NONE
|
|
};
|
|
|
|
/* A single C token after string literal concatenation and conversion
|
|
of preprocessing tokens to tokens. */
|
|
struct GTY (()) c_token {
|
|
/* The kind of token. */
|
|
ENUM_BITFIELD (cpp_ttype) type : 8;
|
|
/* If this token is a CPP_NAME, this value indicates whether also
|
|
declared as some kind of type. Otherwise, it is C_ID_NONE. */
|
|
ENUM_BITFIELD (c_id_kind) id_kind : 8;
|
|
/* If this token is a keyword, this value indicates which keyword.
|
|
Otherwise, this value is RID_MAX. */
|
|
ENUM_BITFIELD (rid) keyword : 8;
|
|
/* If this token is a CPP_PRAGMA, this indicates the pragma that
|
|
was seen. Otherwise it is PRAGMA_NONE. */
|
|
ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
|
|
/* The location at which this token was found. */
|
|
location_t location;
|
|
/* The value associated with this token, if any. */
|
|
tree value;
|
|
/* Token flags. */
|
|
unsigned char flags;
|
|
|
|
source_range get_range () const
|
|
{
|
|
return get_range_from_loc (line_table, location);
|
|
}
|
|
|
|
location_t get_finish () const
|
|
{
|
|
return get_range ().m_finish;
|
|
}
|
|
};
|
|
|
|
/* The parser. */
|
|
struct c_parser;
|
|
|
|
/* Possibly kinds of declarator to parse. */
|
|
enum c_dtr_syn {
|
|
/* A normal declarator with an identifier. */
|
|
C_DTR_NORMAL,
|
|
/* An abstract declarator (maybe empty). */
|
|
C_DTR_ABSTRACT,
|
|
/* A parameter declarator: may be either, but after a type name does
|
|
not redeclare a typedef name as an identifier if it can
|
|
alternatively be interpreted as a typedef name; see DR#009,
|
|
applied in C90 TC1, omitted from C99 and reapplied in C99 TC2
|
|
following DR#249. For example, given a typedef T, "int T" and
|
|
"int *T" are valid parameter declarations redeclaring T, while
|
|
"int (T)" and "int * (T)" and "int (T[])" and "int (T (int))" are
|
|
abstract declarators rather than involving redundant parentheses;
|
|
the same applies with attributes inside the parentheses before
|
|
"T". */
|
|
C_DTR_PARM
|
|
};
|
|
|
|
/* The binary operation precedence levels, where 0 is a dummy lowest level
|
|
used for the bottom of the stack. */
|
|
enum c_parser_prec {
|
|
PREC_NONE,
|
|
PREC_LOGOR,
|
|
PREC_LOGAND,
|
|
PREC_BITOR,
|
|
PREC_BITXOR,
|
|
PREC_BITAND,
|
|
PREC_EQ,
|
|
PREC_REL,
|
|
PREC_SHIFT,
|
|
PREC_ADD,
|
|
PREC_MULT,
|
|
NUM_PRECS
|
|
};
|
|
|
|
enum c_lookahead_kind {
|
|
/* Always treat unknown identifiers as typenames. */
|
|
cla_prefer_type,
|
|
|
|
/* Could be parsing a nonabstract declarator. Only treat an identifier
|
|
as a typename if followed by another identifier or a star. */
|
|
cla_nonabstract_decl,
|
|
|
|
/* Never treat identifiers as typenames. */
|
|
cla_prefer_id
|
|
};
|
|
|
|
|
|
extern c_token * c_parser_peek_token (c_parser *parser);
|
|
extern c_token * c_parser_peek_2nd_token (c_parser *parser);
|
|
extern c_token * c_parser_peek_nth_token (c_parser *parser, unsigned int n);
|
|
extern bool c_parser_require (c_parser *parser, enum cpp_ttype type,
|
|
const char *msgid,
|
|
location_t matching_location = UNKNOWN_LOCATION,
|
|
bool type_is_unique=true);
|
|
extern bool c_parser_error (c_parser *parser, const char *gmsgid);
|
|
extern void c_parser_consume_token (c_parser *parser);
|
|
extern void c_parser_skip_until_found (c_parser *parser, enum cpp_ttype type,
|
|
const char *msgid,
|
|
location_t = UNKNOWN_LOCATION);
|
|
extern bool c_parser_next_token_starts_declspecs (c_parser *parser);
|
|
bool c_parser_next_tokens_start_declaration (c_parser *parser);
|
|
bool c_token_starts_typename (c_token *token);
|
|
|
|
/* Abstraction to avoid defining c_parser here which messes up gengtype
|
|
output wrt ObjC due to vec<c_token> routines being put in gtype-c.h
|
|
but not gtype-objc.h. */
|
|
extern c_token * c_parser_tokens_buf (c_parser *parser, unsigned n);
|
|
extern bool c_parser_error (c_parser *parser);
|
|
extern void c_parser_set_error (c_parser *parser, bool);
|
|
|
|
/* A bit of a hack to have this here. It would be better in a c-decl.h. */
|
|
extern bool old_style_parameter_scope (void);
|
|
|
|
/* Return true if the next token from PARSER has the indicated
|
|
TYPE. */
|
|
|
|
static inline bool
|
|
c_parser_next_token_is (c_parser *parser, enum cpp_ttype type)
|
|
{
|
|
return c_parser_peek_token (parser)->type == type;
|
|
}
|
|
|
|
/* Return true if the next token from PARSER does not have the
|
|
indicated TYPE. */
|
|
|
|
static inline bool
|
|
c_parser_next_token_is_not (c_parser *parser, enum cpp_ttype type)
|
|
{
|
|
return !c_parser_next_token_is (parser, type);
|
|
}
|
|
|
|
/* Return true if the next token from PARSER is the indicated
|
|
KEYWORD. */
|
|
|
|
static inline bool
|
|
c_parser_next_token_is_keyword (c_parser *parser, enum rid keyword)
|
|
{
|
|
return c_parser_peek_token (parser)->keyword == keyword;
|
|
}
|
|
|
|
struct c_expr c_parser_string_literal (c_parser *, bool, bool);
|
|
extern struct c_declarator *
|
|
c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
|
|
bool *seen_id);
|
|
extern void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool,
|
|
bool, bool, bool, bool, bool,
|
|
enum c_lookahead_kind);
|
|
extern struct c_type_name *c_parser_type_name (c_parser *, bool = false);
|
|
|
|
#endif
|