GCC Middle and Back End API Reference
gengtype-parse.c File Reference

Data Structures

struct  token

Functions

static int token ()
static const char * advance ()
static const char * print_token ()
static const char * print_cur_token ()
static void ATTRIBUTE_PRINTF_1 parse_error ()
static const char * require ()
static const char * require_without_advance ()
static const char * require2 ()
static const char * string_seq ()
static const char * require_template_declaration ()
static const char * typedef_name ()
static void consume_balanced ()
static void consume_until_eos ()
static bool consume_until_comma_or_eos ()
static type_p type (options_p *optsp, bool nested)
static options_p str_optvalue_opt ()
static type_p absdecl ()
static options_p type_optvalue ()
static options_p nestedptr_optvalue ()
static options_p option ()
static options_p option_seq ()
static options_p gtymarker ()
static options_p gtymarker_opt ()
static type_p array_and_function_declarators_opt ()
static type_p inner_declarator (type_p, const char **, options_p *, bool)
static type_p direct_declarator (type_p ty, const char **namep, options_p *optsp, bool in_struct)
static type_p declarator (type_p ty, const char **namep, options_p *optsp, bool in_struct=false)
static pair_p struct_field_seq ()
bool opts_have ()
static type_p type ()
static void typedef_decl ()
static void struct_or_union ()
static void extern_or_static ()
void parse_file ()

Variables

static struct token T
static const char *const token_names []
static const char *const token_value_format []

Function Documentation

static type_p absdecl ( )
static
   absdecl: type '*'*
   -- a vague approximation to what the C standard calls an abstract
   declarator.  The only kinds that are actually used are those that
   are just a bare type and those that have trailing pointer-stars.
   Further kinds should be implemented if and when they become
   necessary.  Used only within option values, therefore
   further tags within the type are invalid.  Note that the
   return value has already been run through adjust_field_type.  
static const char* advance ( )
inlinestatic
   Retrieve the value of the current token (if any) and mark it consumed.
   The next call to token() will get another token from the lexer.  

Referenced by array_and_function_declarators_opt(), gtymarker(), inner_declarator(), option(), require2(), and require_without_advance().

static type_p array_and_function_declarators_opt ( )
static
   Declarators. The logic here is largely lifted from c-parser.c.
   Note that we do not have to process abstract declarators, which can
   appear only in parameter type lists or casts (but see absdecl,
   above).  Also, type qualifiers are thrown out in gengtype-lex.l so
   we don't have to do it.  
   array_and_function_declarators_opt:
   \epsilon
   array_and_function_declarators_opt ARRAY
   array_and_function_declarators_opt '(' ... ')'

   where '...' indicates stuff we ignore except insofar as grouping
   symbols ()[]{} must balance.

   Subroutine of direct_declarator - do not use elsewhere. 
         We don't need exact types for functions.  

References advance(), gtymarker(), and require().

Referenced by gtymarker(), and gtymarker_opt().

static void consume_balanced ( )
static
   Absorb a sequence of tokens delimited by balanced ()[]{}.  

Referenced by gtymarker_opt().

static bool consume_until_comma_or_eos ( )
static
   Absorb a sequence of tokens, possibly including ()[]{}-delimited
   expressions, until we encounter a comma or semicolon outside any
   such delimiters; absorb that too.  Returns true if the loop ended
   with a comma.  
static void consume_until_eos ( )
static
   Absorb a sequence of tokens, possibly including ()[]{}-delimited
   expressions, until we encounter an end-of-statement marker (a ';' or
   a '}') outside any such delimiters; absorb that too.  

Referenced by declarator().

static type_p declarator ( type_p  ty,
const char **  namep,
options_p optsp,
bool  in_struct = false 
)
static
   declarator: '*'+ direct_declarator

   This is the sole public interface to this part of the grammar.
   Arguments are the type known so far, a pointer to where the name
   may be stored, and a pointer to where GTY options may be stored.

   IN_STRUCT is true when we are called to parse declarators inside
   a structure or class.

   Returns the final type.  

References consume_until_eos().

static type_p direct_declarator ( type_p  ty,
const char **  namep,
options_p optsp,
bool  in_struct 
)
static
   direct_declarator:
   '(' inner_declarator ')'
   '(' \epsilon ')'     <-- C++ ctors/dtors
   gtymarker_opt ID array_and_function_declarators_opt

   Subroutine of declarator, mutually recursive with inner_declarator;
   do not use elsewhere.

   IN_STRUCT is true if we are called while parsing structures or classes.  
     The first token in a direct-declarator must be an ID, a
     GTY marker, or an open parenthesis.  
         fall through 
         If the next token is '(', we are parsing a function declaration.
         Functions are ignored by gengtype, so we return NULL.  
         If the declarator starts with a '(', we have three options.  We
         are either parsing 'TYPE (*ID)' (i.e., a function pointer)
         or 'TYPE(...)'.

         The latter will be a constructor iff we are inside a
         structure or class.  Otherwise, it could be a typedef, but
         since we explicitly reject typedefs inside structures, we can
         assume that we found a ctor and return NULL.  
             Found a constructor.  Find and consume the closing ')'.  
             Tell the caller to ignore this.  
         Any C++ keyword like 'operator' means that we are not looking
         at a regular data declarator.  
         Do _not_ advance if what we have is a close squiggle brace, as
         we will get much better error recovery that way.  
static void extern_or_static ( )
static
   GC root declaration:
   (extern|static) gtymarker? type ID array_declarators_opt (';'|'=')
   If the gtymarker is not present, we ignore the rest of the declaration.  
static options_p gtymarker ( )
static
   GTY marker: 'GTY' '(' '(' option_seq? ')' ')' 

References advance(), and array_and_function_declarators_opt().

Referenced by array_and_function_declarators_opt(), and option_seq().

static options_p gtymarker_opt ( )
static
   Optional GTY marker.  

References array_and_function_declarators_opt(), and consume_balanced().

Referenced by type().

static type_p inner_declarator ( type_p  ty,
const char **  namep,
options_p optsp,
bool  in_struct 
)
static
   The difference between inner_declarator and declarator is in the
   handling of stars.  Consider this declaration:

   char * (*pfc) (void)

   It declares a pointer to a function that takes no arguments and
   returns a char*.  To construct the correct type for this
   declaration, the star outside the parentheses must be processed
   _before_ the function type, the star inside the parentheses must
   be processed _after_ the function type.  To accomplish this,
   declarator() creates pointers before recursing (it is actually
   coded as a while loop), whereas inner_declarator() recurses before
   creating pointers.  
   inner_declarator:
   '*' inner_declarator
   direct_declarator

   Mutually recursive subroutine of direct_declarator; do not use
   elsewhere.

   IN_STRUCT is true if we are called while parsing structures or classes.  

References advance(), and type().

static options_p nestedptr_optvalue ( )
static
   Nested pointer data: '(' type '*'* ',' string_seq ',' string_seq ')' 
static options_p option ( )
static
@verbatim 

One option: ID str_optvalue_opt | PTR_ALIAS type_optvalue | PARAM_IS type_optvalue | NESTED_PTR nestedptr_optvalue

References advance().

Referenced by enum_arg_to_value(), generate_option(), and option_flag_var().

static options_p option_seq ( )
static
   One comma-separated list of options.  

References gtymarker().

bool opts_have ( )
   Return true if OPTS contain the option named STR.  
static void ATTRIBUTE_PRINTF_1 parse_error ( )
static
   Report a parse error on the current line, with diagnostic MSG.
   Behaves as standard printf with respect to additional arguments and
   format escapes.  

Referenced by require(), and require_without_advance().

void parse_file ( )
   Parse the file FNAME for GC-relevant declarations and definitions.
   This is the only entry point to this file.  
static const char* print_cur_token ( )
inlinestatic
   Convenience wrapper around print_token which produces the printable
   representation of the current token.  

References fileloc::file, get_input_file_name(), lexer_line, and fileloc::line.

static const char* print_token ( )
static
   Produce a printable representation for a token defined by CODE and
   VALUE.  This sometimes returns pointers into malloc memory and
   sometimes not, therefore it is unsafe to free the pointer it
   returns, so that memory is leaked.  This does not matter, as this
   function is only used for diagnostics, and in a successful run of
   the program there will be none.  

Referenced by require(), and require_without_advance().

static const char* require ( )
static
   If the next token does not have code T, report a parse error; otherwise
   return the token's value.  

References parse_error(), print_token(), T, token(), and token::value.

Referenced by array_and_function_declarators_opt(), and require2().

static const char* require2 ( )
static
   If the next token does not have one of the codes T1 or T2, report a
   parse error; otherwise return the token's value.  

References advance(), require(), and strlen().

static const char* require_template_declaration ( )
static
   The caller has detected a template declaration that starts
   with TMPL_NAME.  Parse up to the closing '>'.  This recognizes
   simple template declarations of the form ID<ID1,ID2,...,IDn>.
   It does not try to parse anything more sophisticated than that.

   Returns the template declaration string "ID<ID1,ID2,...,IDn>".  
     Recognize the opening '<'.  
     Read the comma-separated list of identifiers.  
     Recognize the closing '>'.  
static const char* require_without_advance ( )
static
   As per require, but do not advance.  

References advance(), parse_error(), print_token(), and token().

static options_p str_optvalue_opt ( )
static
   Optional parenthesized string: ('(' string_seq ')')? 

Referenced by type_optvalue().

static const char* string_seq ( )
static
   Near-terminals.  
   C-style string constant concatenation: STRING+
   Bare STRING should appear nowhere else in this file.  
static pair_p struct_field_seq ( )
static
@verbatim 

Types and declarations.

   Structure field(s) declaration:
   (
   type bitfield ';'
   | type declarator bitfield? ( ',' declarator bitfield? )+ ';'
   )+

   Knows that such declarations must end with a close brace (or,
   erroneously, at EOF).
         Ignore access-control keywords ("public:" etc).  
             There could be any number of weird things after the declarator,
             notably bitfield declarations and __attribute__s.  If this
             function returns true, the last thing was a comma, so we have
             more than one declarator paired with the current type.  
static void struct_or_union ( )
static
   Structure definition: type() does all the work.  
     There may be junk after the type: notably, we cannot currently
     distinguish 'struct foo *function(prototype);' from 'struct foo;'
     ...  we could call declarator(), but it's a waste of time at
     present.  Instead, just eat whatever token is currently lookahead
     and go back to lexical skipping mode. 
static int token ( )
inlinestatic
   Retrieve the code of the current token; if there is no current token,
   get the next one from the lexer.  

Referenced by require(), and require_without_advance().

static type_p type ( )
static
   This is called type(), but what it parses (sort of) is what C calls
   declaration-specifiers and specifier-qualifier-list:

   SCALAR
   | ID     // typedef
   | (STRUCT|UNION) ID? gtymarker? ( '{' gtymarker? struct_field_seq '}' )?
   | ENUM ID ( '{' ... '}' )?

   Returns a partial type; under some conditions (notably
   "struct foo thing;") it may write an options
   structure to *OPTSP.

   NESTED is true when parsing a declaration already known to have a
   GTY marker. In these cases, typedef and enum declarations are not
   allowed because gengtype only understands types at the global
   scope.  
         By returning NULL here, we indicate to the caller that they
         should ignore everything following this keyword up to the
         next ';' or '}'.  
           GTY annotations follow attribute syntax
           GTY_BEFORE_ID is for union/struct declarations
           GTY_AFTER_ID is for variable declarations.  
           Top-level structures that are not explicitly tagged are treated as mere forward declarations.  This is because
           there are a lot of structures that we don't need to know
           about, and some of those have C++ and macro constructs that
           we cannot handle.  
           Unfortunately above GTY_TOKEN check does not capture the
           typedef struct_type GTY case.  
                   For GTY-marked types that are not "user", parse some C++
                   inheritance specifications.
                   We require single-inheritance from a non-template type.  
                   This may be either an access specifier, or the base name.  
                   For types lacking GTY-markings, skip over C++ inheritance
                   specification (and thus avoid having to parse e.g. template
                   types).  
                       Do not look inside user defined structures.  
         In C++, a typedef inside a struct/class/union defines a new
         type for that inner scope.  We cannot support this in
         gengtype because we have no concept of scoping.

         We handle typedefs in the global scope separately (see
         parse_file), so if we find a 'typedef', we must be inside
         a struct.  
         If after parsing the enum we are at the end of the statement,
         and we are currently inside a structure, then this was an
         enum declaration inside this scope.

         We cannot support this for the same reason we cannot support
         'typedef' inside structures (see the TYPEDEF handler above).
         If this happens, emit an error and return NULL.  

References gtymarker_opt().

static options_p type_optvalue ( )
static
   Type-option: '(' absdecl ')' 

References str_optvalue_opt().

static void typedef_decl ( )
static
   Top level constructs.  
   Dispatch declarations beginning with 'typedef'.  
         Yet another place where we could have junk (notably attributes)
         after the declarator.  
static const char* typedef_name ( )
static
   typedef_name: either an ID, or a template type
   specification of the form ID<t1,t2,...,tn>.  

Variable Documentation

const char* const token_names[]
static
Initial value:
{
"GTY",
"typedef",
"extern",
"static",
"union",
"struct",
"enum",
"...",
"ptr_alias",
"nested_ptr",
"a param<N>_is option",
"a number",
"a scalar type",
"an identifier",
"a string constant",
"a character constant",
"an array declarator",
"a C++ keyword to ignore"
}
   Diagnostics.  
   This array is indexed by the token code minus CHAR_TOKEN_OFFSET.  
const char* const token_value_format[]
static
Initial value:
{
"%s",
"'%s'",
"'%s'",
"'%s'",
"'\"%s\"'",
"\"'%s'\"",
"'[%s]'",
"'%s'",
}
   This array is indexed by token code minus FIRST_TOKEN_WITH_VALUE.