diff --git a/gcc/gcc/c/c-decl.c b/gcc/gcc/c/c-decl.c index 47907d5ec7..ef012d91fe 100644 --- a/gcc/gcc/c/c-decl.c +++ b/gcc/gcc/c/c-decl.c @@ -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; diff --git a/gcc/gcc/c/c-parser.c b/gcc/gcc/c/c-parser.c index a51af2e305..ebb92225a5 100644 --- a/gcc/gcc/c/c-parser.c +++ b/gcc/gcc/c/c-parser.c @@ -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 *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" diff --git a/gcc/gcc/cp/parser.c b/gcc/gcc/cp/parser.c index 16ddd5d9e7..42a46f2aaf 100644 --- a/gcc/gcc/cp/parser.c +++ b/gcc/gcc/cp/parser.c @@ -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 *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"