bool Compiler::process_file(const Path& path, const Flags& flags) { FlagsManager new_flags(*this, flags); cxx::Backend backend(*this); Path output_path = get_cxx_output_path(flags, path) + "cpp"; std::ofstream output(output_path.c_str()); add_header(output); const SourceFileAst* src = reader()->read_file(path, flags); FormatterContext ctx; for (auto ast : src->asts) { const Expression* expr = elaborate(ast).code(); if (auto imp = is<Import>(expr)) process_import(backend, output, *imp); else if (expr != nullptr) { if (auto tl = backend.translate_top_level(expr)) push_top_level(ctx, tl); } } for (auto x: get_specializations()) { auto decl = specs_to_decl(backend, x); if (auto fundef = dynamic_cast<const cxx::FunDef*>(decl)) ctx.fun_defs.push_back(fundef); else push_decl(ctx, decl); } format_cxx(ctx, output); if (not compile_cxx_file(output_path)) internal_error("intermediate C++ translation failed to compile"); return true; }
static void push_top_level(FormatterContext& ctx, const cxx::Toplevel* tl) { if (tl == nullptr) return; // This will always be a top level decl. if (auto topdecl = dynamic_cast<const cxx::TopDecl*>(tl)) { auto decl = topdecl->declaration(); if (auto decl_pack = dynamic_cast<const cxx::DeclPack*>(decl)) { for (auto spec: decl_pack->specializations()) { if (auto fundef = dynamic_cast<const cxx::FunDef*>(spec)) ctx.fun_defs.push_back(fundef); else push_decl(ctx, spec); } push_decl(ctx, decl_pack->primary()); } else { push_decl(ctx, decl); } } else internal_error("formatter: found a non-declaration top level statement"); }
static bool ortho_init (void) { tree n; input_location = BUILTINS_LOCATION; /* Create a global binding. */ push_binding (); build_common_tree_nodes (0); size_type_node = type_for_size (GET_MODE_BITSIZE (Pmode), 1); set_sizetype (size_type_node); build_common_tree_nodes_2 (0); n = build_decl (UNKNOWN_LOCATION, TYPE_DECL, get_identifier ("int"), integer_type_node); push_decl (n); n = build_decl (UNKNOWN_LOCATION, TYPE_DECL, get_identifier ("char"), char_type_node); push_decl (n); /* Create alloca builtin. */ { tree args_type = tree_cons (NULL_TREE, size_type_node, void_list_node); tree func_type = build_function_type (ptr_type_node, args_type); implicit_built_in_decls[BUILT_IN_ALLOCA] = builtin_function ("__builtin_alloca", func_type, BUILT_IN_ALLOCA, BUILT_IN_NORMAL, NULL, NULL_TREE); stack_alloc_function_ptr = build1 (ADDR_EXPR, build_pointer_type (func_type), implicit_built_in_decls[BUILT_IN_ALLOCA]); } { tree ptr_ftype = build_function_type (ptr_type_node, NULL_TREE); implicit_built_in_decls[BUILT_IN_STACK_SAVE] = builtin_function ("__builtin_stack_save", ptr_ftype, BUILT_IN_STACK_SAVE, BUILT_IN_NORMAL, NULL, NULL_TREE); } { tree ftype_ptr; ftype_ptr = build_function_type (void_type_node, tree_cons (NULL_TREE, ptr_type_node, NULL_TREE)); implicit_built_in_decls[BUILT_IN_STACK_RESTORE] = builtin_function ("__builtin_stack_restore", ftype_ptr, BUILT_IN_STACK_RESTORE, BUILT_IN_NORMAL, NULL, NULL_TREE); } { REAL_VALUE_TYPE v; REAL_VALUE_FROM_INT (v, 1, 0, DFmode); real_ldexp (&fp_const_p5, &v, -1); REAL_VALUE_FROM_INT (v, -1, -1, DFmode); real_ldexp (&fp_const_m_p5, &v, -1); REAL_VALUE_FROM_INT (fp_const_zero, 0, 0, DFmode); } ortho_fe_init (); return true; }
static tree pop_binding (void) { tree res; struct binding_level *cur; cur = cur_binding_level; res = cur->bind; if (cur->save_stack) { tree tmp_var; tree save; tree save_call; tree restore; tree t; /* Create an artificial var to save the stack pointer. */ /* build_decl got a new parameter * http://www.mail-archive.com/[email protected]/msg01245.html */ tmp_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL, ptr_type_node); DECL_ARTIFICIAL (tmp_var) = true; DECL_IGNORED_P (tmp_var) = true; TREE_USED (tmp_var) = true; push_decl (tmp_var); /* * The functions * build_function_call_expr * * were eliminated in newer versions of GCC. See * http://patchwork.ozlabs.org/patch/57555/ * http://patchwork.ozlabs.org/patch/57906/ * http://patchwork.ozlabs.org/patch/57911/ * http://patchwork.ozlabs.org/patch/57962/ * * */ /* Create the save stmt. */ /* * build_function_call_expr was removed with patch 57962 * http://patchwork.ozlabs.org/patch/57962/ * * The signature was * build_function_call_expr (location_t loc, tree fndecl, tree arglist) * A new function build_call_expr_loc_vec was introduced. * See examples in the patch how to replace that function. */ save_call = build_call_expr_loc (UNKNOWN_LOCATION, implicit_built_in_decls[BUILT_IN_STACK_SAVE], 0); save = build2 (MODIFY_EXPR, ptr_type_node, tmp_var, save_call); TREE_SIDE_EFFECTS (save) = true; /* Create the restore stmt. */ restore = build_call_expr_loc (UNKNOWN_LOCATION, implicit_built_in_decls[BUILT_IN_STACK_RESTORE], 1, tmp_var); /* Build a try-finally block. The statement list is the block of current statements. */ t = build2 (TRY_FINALLY_EXPR, void_type_node, cur_stmts, NULL_TREE); TREE_SIDE_EFFECTS (t) = true; /* The finally block is the restore stmt. */ append_to_statement_list (restore, &TREE_OPERAND (t, 1)); /* The body of the BIND_BLOCK is the save stmt, followed by the try block. */ BIND_EXPR_BODY (res) = NULL_TREE; append_to_statement_list (save, &BIND_EXPR_BODY (res)); append_to_statement_list (t, &BIND_EXPR_BODY (res)); } else { /* The body of the BIND_BLOCK is the statement block. */ BIND_EXPR_BODY (res) = cur_stmts; } BIND_EXPR_VARS (res) = cur->first_decl; BLOCK_SUBBLOCKS (cur->block) = cur->first_block; BLOCK_VARS (cur->block) = cur->first_decl; cur_binding_level = cur->prev; cur->prev = old_binding_levels; old_binding_levels = cur; return res; }