Support "pascal void foo() = { 0x1234 };" syntax in gcc.

This commit is contained in:
Wolfgang Thaller 2015-08-27 21:53:51 +02:00
parent 6a05091d37
commit ee736a689c
3 changed files with 104 additions and 11 deletions

View File

@ -4088,7 +4088,8 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
break;
case FUNCTION_DECL:
error ("function %qD is initialized like a variable", decl);
//error ("function %qD is initialized like a variable", decl);
// Retro68: a function defined by inline opcodes does not count as initialized.
initialized = 0;
break;

View File

@ -1253,6 +1253,8 @@ static bool c_parser_cilk_verify_simd (c_parser *, enum pragma_context);
static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
static tree c_parser_cilk_clause_vectorlength (c_parser *, tree, bool);
static tree c_parser_inline_opcodes(c_parser *);
/* Parse a translation unit (C90 6.7, C99 6.9).
translation-unit:
@ -1747,17 +1749,26 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
/* The declaration of the variable is in effect while
its initializer is parsed. */
d = start_decl (declarator, specs, true,
chainon (postfix_attrs, all_prefix_attrs));
chainon (postfix_attrs, all_prefix_attrs));
if (!d)
d = error_mark_node;
if (omp_declare_simd_clauses.exists ()
|| !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
c_finish_omp_declare_simd (parser, d, NULL_TREE,
omp_declare_simd_clauses);
start_init (d, asm_name, global_bindings_p ());
init_loc = c_parser_peek_token (parser)->location;
init = c_parser_initializer (parser);
finish_init ();
if (omp_declare_simd_clauses.exists ()
|| !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
c_finish_omp_declare_simd (parser, d, NULL_TREE,
omp_declare_simd_clauses);
if(TREE_CODE(d) == FUNCTION_DECL)
{
tree rawinline_attr = c_parser_inline_opcodes(parser);
decl_attributes (&d, rawinline_attr, 0);
}
else
{
start_init (d, asm_name, global_bindings_p ());
init_loc = c_parser_peek_token (parser)->location;
init = c_parser_initializer (parser);
finish_init ();
}
}
if (d != error_mark_node)
{
@ -14182,4 +14193,30 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index,
return value_tree;
}
static tree c_parser_inline_opcodes(c_parser * parser)
{
tree attr_args;
vec<tree, va_gc> *expr_list;
bool braced = false;
braced = c_parser_next_token_is(parser, CPP_OPEN_BRACE);
if(braced)
c_parser_consume_token(parser);
expr_list = c_parser_expr_list (parser, false, true,
NULL, NULL, NULL, NULL);
attr_args = build_tree_list_vec (expr_list);
release_tree_vector (expr_list);
if(braced)
{
if(c_parser_next_token_is(parser, CPP_CLOSE_BRACE))
c_parser_consume_token(parser);
else
c_parser_error (parser, "expected %<}%>");
}
return build_tree_list (get_identifier("__raw_inline__"), attr_args);
}
#include "gt-c-c-parser.h"

View File

@ -2474,6 +2474,8 @@ static tree cp_parser_make_typename_type
static cp_declarator * cp_parser_make_indirect_declarator
(enum tree_code, tree, cp_cv_quals, cp_declarator *, tree);
static tree cp_parser_inline_opcodes(cp_parser * parser);
/* Returns nonzero if we are parsing tentatively. */
static inline bool
@ -16813,7 +16815,17 @@ cp_parser_init_declarator (cp_parser* parser,
{
cp_token *initializer_start_token = cp_lexer_peek_token (parser->lexer);
if (initialization_kind == CPP_EQ)
initializer = cp_parser_pure_specifier (parser);
{
if(member_p)
initializer = cp_parser_pure_specifier (parser);
else
{
is_initialized = false;
cp_lexer_consume_token (parser->lexer);
tree rawinline_attr = cp_parser_inline_opcodes (parser);
decl_attributes (&decl, rawinline_attr, 0);
}
}
else
{
/* If the declaration was erroneous, we don't really
@ -32215,4 +32227,47 @@ finish_fully_implicit_template (cp_parser *parser, tree member_decl_opt)
return member_decl_opt;
}
static tree cp_parser_inline_opcodes(cp_parser * parser)
{
tree attr_args;
bool braced = false;
braced = cp_lexer_next_token_is(parser->lexer, CPP_OPEN_BRACE);
if(braced)
cp_lexer_consume_token(parser->lexer);
vec<tree, va_gc> *expr_list = make_tree_vector ();
if(!braced || !cp_lexer_next_token_is(parser->lexer, CPP_CLOSE_BRACE))
{
for(;;)
{
tree val = cp_parser_constant_expression (parser,
/*allow_non_constant_p=*/false,
NULL);
vec_safe_push (expr_list, val);
if(cp_lexer_next_token_is(parser->lexer, CPP_COMMA))
cp_lexer_consume_token(parser->lexer);
else
break;
}
}
attr_args = build_tree_list_vec (expr_list);
release_tree_vector (expr_list);
if(braced)
{
if(cp_lexer_next_token_is(parser->lexer, CPP_CLOSE_BRACE))
cp_lexer_consume_token(parser->lexer);
else
cp_parser_error (parser, "expected %<}%>");
}
return build_tree_list (get_identifier("__raw_inline__"), attr_args);
}
#include "gt-cp-parser.h"