GCC Middle and Back End API Reference
gengtype-parse.c File Reference
#include "config.h"
#include "system.h"
#include "gengtype.h"
Include dependency graph for gengtype-parse.c:

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: 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(), NULL, 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 ')' '(' ')' <– 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

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(), CONST_CAST, and require().

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

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.