/* Set the DECL_ASSEMBLER_NAME for DECL. */ void lhd_set_decl_assembler_name (tree decl) { tree id; /* The language-independent code should never use the DECL_ASSEMBLER_NAME for lots of DECLs. Only FUNCTION_DECLs and VAR_DECLs for variables with static storage duration need a real DECL_ASSEMBLER_NAME. */ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL || (TREE_CODE (decl) == VAR_DECL && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || TREE_PUBLIC (decl)))); /* By default, assume the name to use in assembly code is the same as that used in the source language. (That's correct for C, and GCC used to set DECL_ASSEMBLER_NAME to the same value as DECL_NAME in build_decl, so this choice provides backwards compatibility with existing front-ends. This assumption is wrapped in a target hook, to allow for target-specific modification of the identifier. Can't use just the variable's own name for a variable whose scope is less than the whole compilation. Concatenate a distinguishing number - we use the DECL_UID. */ if (TREE_PUBLIC (decl) || DECL_FILE_SCOPE_P (decl)) id = targetm.mangle_decl_assembler_name (decl, DECL_NAME (decl)); else { const char *name = IDENTIFIER_POINTER (DECL_NAME (decl)); char *label; ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl)); id = get_identifier (label); } SET_DECL_ASSEMBLER_NAME (decl, id); }
static bool decl_is_java_type (tree decl, int err) { bool r = (TREE_CODE (decl) == POINTER_TYPE && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE && TYPE_FOR_JAVA (TREE_TYPE (decl))); if (err) { if (TREE_CODE (decl) == REFERENCE_TYPE && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE && TYPE_FOR_JAVA (TREE_TYPE (decl))) { /* Can't throw a reference. */ error ("type %qT is disallowed in Java %<throw%> or %<catch%>", decl); } if (r) { tree jthrow_node = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jthrowable")); if (jthrow_node == NULL_TREE) fatal_error ("call to Java %<catch%> or %<throw%> with %<jthrowable%> undefined"); jthrow_node = TREE_TYPE (TREE_TYPE (jthrow_node)); if (! DERIVED_FROM_P (jthrow_node, TREE_TYPE (decl))) { /* Thrown object must be a Throwable. */ error ("type %qT is not derived from %<java::lang::Throwable%>", TREE_TYPE (decl)); } } } return r; }
tree build_ivar_template (void) { tree objc_ivar_id, objc_ivar_record; tree decls, *chain = NULL; objc_ivar_id = get_identifier (UTAG_IVAR); objc_ivar_record = objc_start_struct (objc_ivar_id); /* char *ivar_name; */ decls = add_field_decl (string_type_node, "ivar_name", &chain); /* char *ivar_type; */ add_field_decl (string_type_node, "ivar_type", &chain); /* int ivar_offset; */ add_field_decl (integer_type_node, "ivar_offset", &chain); objc_finish_struct (objc_ivar_record, decls); return objc_ivar_record; }
static void mark_current_function_as_interrupt (void) { tree name; if (current_function_decl == NULL_TREE) { warning (0, "cannot set interrupt attribute: no current function"); return; } name = get_identifier ("interrupt"); if (name == NULL_TREE || TREE_CODE (name) != IDENTIFIER_NODE) { warning (0, "cannot set interrupt attribute: no such identifier"); return; } decl_attributes (¤t_function_decl, tree_cons (name, NULL_TREE, NULL_TREE), 0); }
static void create_vop_var (struct function *fn) { tree global_var; gcc_assert (fn->gimple_df->vop == NULL_TREE); global_var = build_decl (BUILTINS_LOCATION, VAR_DECL, get_identifier (".MEM"), void_type_node); DECL_ARTIFICIAL (global_var) = 1; DECL_IGNORED_P (global_var) = 1; TREE_READONLY (global_var) = 0; DECL_EXTERNAL (global_var) = 1; TREE_STATIC (global_var) = 1; TREE_USED (global_var) = 1; DECL_CONTEXT (global_var) = NULL_TREE; TREE_THIS_VOLATILE (global_var) = 0; TREE_ADDRESSABLE (global_var) = 0; VAR_DECL_IS_VIRTUAL_OPERAND (global_var) = 1; fn->gimple_df->vop = global_var; }
static void create_vop_var (void) { tree global_var; gcc_assert (cfun->gimple_df->vop == NULL_TREE); global_var = build_decl (BUILTINS_LOCATION, VAR_DECL, get_identifier (".MEM"), void_type_node); DECL_ARTIFICIAL (global_var) = 1; TREE_READONLY (global_var) = 0; DECL_EXTERNAL (global_var) = 1; TREE_STATIC (global_var) = 1; TREE_USED (global_var) = 1; DECL_CONTEXT (global_var) = NULL_TREE; TREE_THIS_VOLATILE (global_var) = 0; TREE_ADDRESSABLE (global_var) = 0; create_var_ann (global_var); add_referenced_var (global_var); cfun->gimple_df->vop = global_var; }
void write_resource_constructor (tree *list_p) { tree iter, t, register_resource_fn; if (resources == NULL) return; t = build_function_type_list (void_type_node, ptr_type_node, NULL); t = build_decl (FUNCTION_DECL, get_identifier ("_Jv_RegisterResource"), t); TREE_PUBLIC (t) = 1; DECL_EXTERNAL (t) = 1; register_resource_fn = t; /* Write out entries in the same order in which they were defined. */ for (iter = nreverse (resources); iter ; iter = TREE_CHAIN (iter)) { t = build_fold_addr_expr (TREE_VALUE (iter)); t = tree_cons (NULL, t, NULL); t = build_function_call_expr (register_resource_fn, t); append_to_statement_list (t, list_p); } }
void write_resource_constructor (tree *list_p) { tree decl, t, register_resource_fn; unsigned ix; if (resources == NULL) return; t = build_function_type_list (void_type_node, ptr_type_node, NULL); t = build_decl (input_location, FUNCTION_DECL, get_identifier ("_Jv_RegisterResource"), t); TREE_PUBLIC (t) = 1; DECL_EXTERNAL (t) = 1; register_resource_fn = t; /* Write out entries in the same order in which they were defined. */ FOR_EACH_VEC_ELT (tree, resources, ix, decl) { t = build_fold_addr_expr (decl); t = build_call_expr (register_resource_fn, 1, t); append_to_statement_list (t, list_p); }
static void i386_pe_mark_dllexport (tree decl) { const char *oldname; char *newname; rtx rtlname; rtx symref; tree idp; rtlname = XEXP (DECL_RTL (decl), 0); if (GET_CODE (rtlname) == MEM) rtlname = XEXP (rtlname, 0); gcc_assert (GET_CODE (rtlname) == SYMBOL_REF); oldname = XSTR (rtlname, 0); if (i386_pe_dllimport_name_p (oldname)) { warning (0, "inconsistent dll linkage for %q+D, dllexport assumed", decl); /* Remove DLL_IMPORT_PREFIX. */ oldname += strlen (DLL_IMPORT_PREFIX); } else if (i386_pe_dllexport_name_p (oldname)) return; /* already done */ newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1); sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname); /* We pass newname through get_identifier to ensure it has a unique address. RTL processing can sometimes peek inside the symbol ref and compare the string's addresses to see if two symbols are identical. */ idp = get_identifier (newname); symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp)); SET_SYMBOL_REF_DECL (symref, decl); XEXP (DECL_RTL (decl), 0) = symref; }
static tree build_equiv_decl (tree union_type, bool is_init, bool is_saved) { tree decl; char name[15]; static int serial = 0; if (is_init) { decl = gfc_create_var (union_type, "equiv"); TREE_STATIC (decl) = 1; GFC_DECL_COMMON_OR_EQUIV (decl) = 1; return decl; } snprintf (name, sizeof (name), "equiv.%d", serial++); decl = build_decl (input_location, VAR_DECL, get_identifier (name), union_type); DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 1; if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl)) || is_saved) TREE_STATIC (decl) = 1; TREE_ADDRESSABLE (decl) = 1; TREE_USED (decl) = 1; GFC_DECL_COMMON_OR_EQUIV (decl) = 1; /* The source location has been lost, and doesn't really matter. We need to set it to something though. */ gfc_set_decl_location (decl, &gfc_current_locus); gfc_add_decl_to_function (decl); return decl; }
tree build_java_argument_signature (tree type) { extern struct obstack temporary_obstack; tree sig = TYPE_ARGUMENT_SIGNATURE (type); if (sig == NULL_TREE) { tree args = TYPE_ARG_TYPES (type); if (TREE_CODE (type) == METHOD_TYPE) args = TREE_CHAIN (args); /* Skip "this" argument. */ for (; args != end_params_node; args = TREE_CHAIN (args)) { tree t = build_java_signature (TREE_VALUE (args)); obstack_grow (&temporary_obstack, IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t)); } obstack_1grow (&temporary_obstack, '\0'); sig = get_identifier ((char *) obstack_base (&temporary_obstack)); TYPE_ARGUMENT_SIGNATURE (type) = sig; obstack_free (&temporary_obstack, obstack_base (&temporary_obstack)); } return sig; }
static tree get_eh_handlers () { return build_component_ref (get_eh_info (), get_identifier ("handlers"), NULL_TREE, 0); }
? targetm.emutls.var_prefix : "__emutls_v" EMUTLS_SEPARATOR); return prefix_name (prefix, name); } /* Create the fields of the type for the control variables. Ordinarily this must match struct __emutls_object defined in emutls.c. However this is a target hook so that VxWorks can define its own layout. */ tree default_emutls_var_fields (tree type, tree *name ATTRIBUTE_UNUSED) { tree word_type_node, field, next_field; field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, get_identifier ("__templ"), ptr_type_node); DECL_CONTEXT (field) = type; next_field = field; field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, get_identifier ("__offset"), ptr_type_node); DECL_CONTEXT (field) = type; DECL_CHAIN (field) = next_field; next_field = field; word_type_node = lang_hooks.types.type_for_mode (word_mode, 1); field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, get_identifier ("__align"), word_type_node); DECL_CONTEXT (field) = type;
void maybe_add_lambda_conv_op (tree type) { bool nested = (cfun != NULL); bool nested_def = decl_function_context (TYPE_MAIN_DECL (type)); tree callop = lambda_function (type); if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE) return; if (processing_template_decl) return; bool const generic_lambda_p = (DECL_TEMPLATE_INFO (callop) && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (callop)) == callop); if (!generic_lambda_p && DECL_INITIAL (callop) == NULL_TREE) { /* If the op() wasn't instantiated due to errors, give up. */ gcc_assert (errorcount || sorrycount); return; } /* Non-template conversion operators are defined directly with build_call_a and using DIRECT_ARGVEC for arguments (including 'this'). Templates are deferred and the CALL is built in-place. In the case of a deduced return call op, the decltype expression, DECLTYPE_CALL, used as a substitute for the return type is also built in-place. The arguments of DECLTYPE_CALL in the return expression may differ in flags from those in the body CALL. In particular, parameter pack expansions are marked PACK_EXPANSION_LOCAL_P in the body CALL, but not in DECLTYPE_CALL. */ vec<tree, va_gc> *direct_argvec = 0; tree decltype_call = 0, call = 0; tree fn_result = TREE_TYPE (TREE_TYPE (callop)); if (generic_lambda_p) { /* Prepare the dependent member call for the static member function '_FUN' and, potentially, prepare another call to be used in a decltype return expression for a deduced return call op to allow for simple implementation of the conversion operator. */ tree instance = build_nop (type, null_pointer_node); tree objfn = build_min (COMPONENT_REF, NULL_TREE, instance, DECL_NAME (callop), NULL_TREE); int nargs = list_length (DECL_ARGUMENTS (callop)) - 1; call = prepare_op_call (objfn, nargs); if (type_uses_auto (fn_result)) decltype_call = prepare_op_call (objfn, nargs); } else { direct_argvec = make_tree_vector (); direct_argvec->quick_push (build1 (NOP_EXPR, TREE_TYPE (DECL_ARGUMENTS (callop)), null_pointer_node)); } /* Copy CALLOP's argument list (as per 'copy_list') as FN_ARGS in order to declare the static member function "_FUN" below. For each arg append to DIRECT_ARGVEC (for the non-template case) or populate the pre-allocated call args (for the template case). If a parameter pack is found, expand it, flagging it as PACK_EXPANSION_LOCAL_P for the body call. */ tree fn_args = NULL_TREE; { int ix = 0; tree src = DECL_CHAIN (DECL_ARGUMENTS (callop)); tree tgt; while (src) { tree new_node = copy_node (src); if (!fn_args) fn_args = tgt = new_node; else { TREE_CHAIN (tgt) = new_node; tgt = new_node; } mark_exp_read (tgt); if (generic_lambda_p) { if (DECL_PACK_P (tgt)) { tree a = make_pack_expansion (tgt); if (decltype_call) CALL_EXPR_ARG (decltype_call, ix) = copy_node (a); PACK_EXPANSION_LOCAL_P (a) = true; CALL_EXPR_ARG (call, ix) = a; } else { tree a = convert_from_reference (tgt); CALL_EXPR_ARG (call, ix) = a; if (decltype_call) CALL_EXPR_ARG (decltype_call, ix) = copy_node (a); } ++ix; } else vec_safe_push (direct_argvec, tgt); src = TREE_CHAIN (src); } } if (generic_lambda_p) { if (decltype_call) { ++processing_template_decl; fn_result = finish_decltype_type (decltype_call, /*id_expression_or_member_access_p=*/false, tf_warning_or_error); --processing_template_decl; } } else call = build_call_a (callop, direct_argvec->length (), direct_argvec->address ()); CALL_FROM_THUNK_P (call) = 1; tree stattype = build_function_type (fn_result, FUNCTION_ARG_CHAIN (callop)); /* First build up the conversion op. */ tree rettype = build_pointer_type (stattype); tree name = mangle_conv_op_name_for_type (rettype); tree thistype = cp_build_qualified_type (type, TYPE_QUAL_CONST); tree fntype = build_method_type_directly (thistype, rettype, void_list_node); tree convfn = build_lang_decl (FUNCTION_DECL, name, fntype); tree fn = convfn; DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop); if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT) DECL_ALIGN (fn) = 2 * BITS_PER_UNIT; SET_OVERLOADED_OPERATOR_CODE (fn, TYPE_EXPR); grokclassfn (type, fn, NO_SPECIAL); set_linkage_according_to_type (type, fn); rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof); DECL_IN_AGGR_P (fn) = 1; DECL_ARTIFICIAL (fn) = 1; DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_DECLARED_INLINE_P (fn) = 1; DECL_ARGUMENTS (fn) = build_this_parm (fntype, TYPE_QUAL_CONST); if (nested_def) DECL_INTERFACE_KNOWN (fn) = 1; if (generic_lambda_p) fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop)); add_method (type, fn, NULL_TREE); /* Generic thunk code fails for varargs; we'll complain in mark_used if the conversion op is used. */ if (varargs_function_p (callop)) { DECL_DELETED_FN (fn) = 1; return; } /* Now build up the thunk to be returned. */ name = get_identifier ("_FUN"); tree statfn = build_lang_decl (FUNCTION_DECL, name, stattype); fn = statfn; DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop); if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT) DECL_ALIGN (fn) = 2 * BITS_PER_UNIT; grokclassfn (type, fn, NO_SPECIAL); set_linkage_according_to_type (type, fn); rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof); DECL_IN_AGGR_P (fn) = 1; DECL_ARTIFICIAL (fn) = 1; DECL_NOT_REALLY_EXTERN (fn) = 1; DECL_DECLARED_INLINE_P (fn) = 1; DECL_STATIC_FUNCTION_P (fn) = 1; DECL_ARGUMENTS (fn) = fn_args; for (tree arg = fn_args; arg; arg = DECL_CHAIN (arg)) { /* Avoid duplicate -Wshadow warnings. */ DECL_NAME (arg) = NULL_TREE; DECL_CONTEXT (arg) = fn; } if (nested_def) DECL_INTERFACE_KNOWN (fn) = 1; if (generic_lambda_p) fn = add_inherited_template_parms (fn, DECL_TI_TEMPLATE (callop)); add_method (type, fn, NULL_TREE); if (nested) push_function_context (); else /* Still increment function_depth so that we don't GC in the middle of an expression. */ ++function_depth; /* Generate the body of the thunk. */ start_preparsed_function (statfn, NULL_TREE, SF_PRE_PARSED | SF_INCLASS_INLINE); if (DECL_ONE_ONLY (statfn)) { /* Put the thunk in the same comdat group as the call op. */ cgraph_node::get_create (statfn)->add_to_same_comdat_group (cgraph_node::get_create (callop)); } tree body = begin_function_body (); tree compound_stmt = begin_compound_stmt (0); if (!generic_lambda_p) { set_flags_from_callee (call); if (MAYBE_CLASS_TYPE_P (TREE_TYPE (call))) call = build_cplus_new (TREE_TYPE (call), call, tf_warning_or_error); } call = convert_from_reference (call); finish_return_stmt (call); finish_compound_stmt (compound_stmt); finish_function_body (body); fn = finish_function (/*inline*/2); if (!generic_lambda_p) expand_or_defer_fn (fn); /* Generate the body of the conversion op. */ start_preparsed_function (convfn, NULL_TREE, SF_PRE_PARSED | SF_INCLASS_INLINE); body = begin_function_body (); compound_stmt = begin_compound_stmt (0); /* decl_needed_p needs to see that it's used. */ TREE_USED (statfn) = 1; finish_return_stmt (decay_conversion (statfn, tf_warning_or_error)); finish_compound_stmt (compound_stmt); finish_function_body (body); fn = finish_function (/*inline*/2); if (!generic_lambda_p) expand_or_defer_fn (fn); if (nested) pop_function_context (); else --function_depth; }
tree add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p, bool explicit_init_p) { char *buf; tree type, member, name; bool vla = false; bool variadic = false; tree initializer = orig_init; if (PACK_EXPANSION_P (initializer)) { initializer = PACK_EXPANSION_PATTERN (initializer); variadic = true; } if (TREE_CODE (initializer) == TREE_LIST) initializer = build_x_compound_expr_from_list (initializer, ELK_INIT, tf_warning_or_error); type = TREE_TYPE (initializer); if (type == error_mark_node) return error_mark_node; if (array_of_runtime_bound_p (type)) { vla = true; if (!by_reference_p) error ("array of runtime bound cannot be captured by copy, " "only by reference"); /* For a VLA, we capture the address of the first element and the maximum index, and then reconstruct the VLA for the proxy. */ tree elt = cp_build_array_ref (input_location, initializer, integer_zero_node, tf_warning_or_error); initializer = build_constructor_va (init_list_type_node, 2, NULL_TREE, build_address (elt), NULL_TREE, array_type_nelts (type)); type = vla_capture_type (type); } else if (!dependent_type_p (type) && variably_modified_type_p (type, NULL_TREE)) { error ("capture of variable-size type %qT that is not an N3639 array " "of runtime bound", type); if (TREE_CODE (type) == ARRAY_TYPE && variably_modified_type_p (TREE_TYPE (type), NULL_TREE)) inform (input_location, "because the array element type %qT has " "variable size", TREE_TYPE (type)); type = error_mark_node; } else { type = lambda_capture_field_type (initializer, explicit_init_p); if (by_reference_p) { type = build_reference_type (type); if (!dependent_type_p (type) && !real_lvalue_p (initializer)) error ("cannot capture %qE by reference", initializer); } else { /* Capture by copy requires a complete type. */ type = complete_type (type); if (!dependent_type_p (type) && !COMPLETE_TYPE_P (type)) { error ("capture by copy of incomplete type %qT", type); cxx_incomplete_type_inform (type); return error_mark_node; } } } /* Add __ to the beginning of the field name so that user code won't find the field with name lookup. We can't just leave the name unset because template instantiation uses the name to find instantiated fields. */ buf = (char *) alloca (IDENTIFIER_LENGTH (id) + 3); buf[1] = buf[0] = '_'; memcpy (buf + 2, IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id) + 1); name = get_identifier (buf); /* If TREE_TYPE isn't set, we're still in the introducer, so check for duplicates. */ if (!LAMBDA_EXPR_CLOSURE (lambda)) { if (IDENTIFIER_MARKED (name)) { pedwarn (input_location, 0, "already captured %qD in lambda expression", id); return NULL_TREE; } IDENTIFIER_MARKED (name) = true; } if (variadic) type = make_pack_expansion (type); /* Make member variable. */ member = build_decl (input_location, FIELD_DECL, name, type); DECL_VLA_CAPTURE_P (member) = vla; if (!explicit_init_p) /* Normal captures are invisible to name lookup but uses are replaced with references to the capture field; we implement this by only really making them invisible in unevaluated context; see qualify_lookup. For now, let's make explicitly initialized captures always visible. */ DECL_NORMAL_CAPTURE_P (member) = true; if (id == this_identifier) LAMBDA_EXPR_THIS_CAPTURE (lambda) = member; /* Add it to the appropriate closure class if we've started it. */ if (current_class_type && current_class_type == LAMBDA_EXPR_CLOSURE (lambda)) finish_member_declaration (member); tree listmem = member; if (variadic) { listmem = make_pack_expansion (member); initializer = orig_init; } LAMBDA_EXPR_CAPTURE_LIST (lambda) = tree_cons (listmem, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda)); if (LAMBDA_EXPR_CLOSURE (lambda)) return build_capture_proxy (member); /* For explicit captures we haven't started the function yet, so we wait and build the proxy from cp_parser_lambda_body. */ return NULL_TREE; }
int main(int argc, const char* argv[]) { if (argc != 4) { std::cerr << "Usage: " << argv[0] << " system_xml_directory private_xml_directory command" << std::endl << std::endl << "Example: " << argv[0] << " /Applications/Karabiner.app/Contents/Resources" << " ~/Library/Application\\ Support/Karabiner" << " dump_data" << std::endl; exit(1); } pqrs::xml_compiler xml_compiler(argv[1], argv[2]); xml_compiler.reload(); if (xml_compiler.get_error_information().get_count() > 0) { std::cerr << xml_compiler.get_error_information().get_message() << std::endl; exit(1); } std::string command(argv[3]); if (command == "dump_data") { auto v = xml_compiler.get_remapclasses_initialize_vector().get(); for (auto& it : v) { std::cout << it << std::endl; } } else if (command == "dump_tree") { dump_tree(xml_compiler.get_preferences_checkbox_node_tree(), false); std::cout << std::endl; std::cout << std::endl; std::cout << "Total items: " << total_identifier_count_ << std::endl; } else if (command == "dump_tree_all") { dump_tree(xml_compiler.get_preferences_checkbox_node_tree(), true); std::cout << std::endl; std::cout << std::endl; std::cout << "Total items: " << total_identifier_count_ << std::endl; } else if (command == "dump_number") { dump_number(xml_compiler.get_preferences_number_node_tree()); } else if (command == "dump_identifier_except_essential") { for (int i = 0;; ++i) { auto identifier = xml_compiler.get_identifier(i); if (!identifier) break; std::cout << *identifier << std::endl; } } else if (command == "dump_symbol_map") { xml_compiler.get_symbol_map().dump(); } else if (command == "output_bridge_essential_configuration_enum_h") { std::cout << "enum {" << std::endl; for (size_t i = 0;; ++i) { auto essential_configuration = xml_compiler.get_essential_configuration(i); if (!essential_configuration) { std::cout << "BRIDGE_ESSENTIAL_CONFIG_INDEX__END__ = " << i << std::endl; break; } std::cout << "BRIDGE_ESSENTIAL_CONFIG_INDEX_" << essential_configuration->get_identifier() << " = " << i << "," << std::endl; } std::cout << "};" << std::endl; } else if (command == "output_bridge_essential_configuration_default_values_c") { for (size_t i = 0;; ++i) { auto essential_configuration = xml_compiler.get_essential_configuration(i); if (!essential_configuration) { break; } std::cout << essential_configuration->get_default_value() << "," << std::endl; } } else if (command == "output_bridge_essential_configuration_identifiers_m") { for (size_t i = 0;; ++i) { auto essential_configuration = xml_compiler.get_essential_configuration(i); if (!essential_configuration) { std::cout << "nil" << std::endl; break; } std::cout << "@\"" << essential_configuration->get_raw_identifier() << "\"" << "," << std::endl; } } return 0; }
/* Initialize the builtins. */ void initialize_builtins (void) { tree double_ftype_double, double_ftype_double_double; tree float_ftype_float_float; tree boolean_ftype_boolean_boolean; int i; for (i = 0; java_builtins[i].builtin_code != END_BUILTINS; ++i) { tree klass_id = get_identifier (java_builtins[i].class_name.s); tree m = get_identifier (java_builtins[i].method_name.s); java_builtins[i].class_name.t = klass_id; java_builtins[i].method_name.t = m; } void_list_node = end_params_node; float_ftype_float_float = build_function_type_list (float_type_node, float_type_node, float_type_node, NULL_TREE); double_ftype_double = build_function_type_list (double_type_node, double_type_node, NULL_TREE); double_ftype_double_double = build_function_type_list (double_type_node, double_type_node, double_type_node, NULL_TREE); define_builtin (BUILT_IN_FMOD, "__builtin_fmod", double_ftype_double_double, "fmod", ECF_CONST); define_builtin (BUILT_IN_FMODF, "__builtin_fmodf", float_ftype_float_float, "fmodf", ECF_CONST); define_builtin (BUILT_IN_ACOS, "__builtin_acos", double_ftype_double, "_ZN4java4lang4Math4acosEJdd", ECF_CONST); define_builtin (BUILT_IN_ASIN, "__builtin_asin", double_ftype_double, "_ZN4java4lang4Math4asinEJdd", ECF_CONST); define_builtin (BUILT_IN_ATAN, "__builtin_atan", double_ftype_double, "_ZN4java4lang4Math4atanEJdd", ECF_CONST); define_builtin (BUILT_IN_ATAN2, "__builtin_atan2", double_ftype_double_double, "_ZN4java4lang4Math5atan2EJddd", ECF_CONST); define_builtin (BUILT_IN_CEIL, "__builtin_ceil", double_ftype_double, "_ZN4java4lang4Math4ceilEJdd", ECF_CONST); define_builtin (BUILT_IN_COS, "__builtin_cos", double_ftype_double, "_ZN4java4lang4Math3cosEJdd", ECF_CONST); define_builtin (BUILT_IN_EXP, "__builtin_exp", double_ftype_double, "_ZN4java4lang4Math3expEJdd", ECF_CONST); define_builtin (BUILT_IN_FLOOR, "__builtin_floor", double_ftype_double, "_ZN4java4lang4Math5floorEJdd", ECF_CONST); define_builtin (BUILT_IN_LOG, "__builtin_log", double_ftype_double, "_ZN4java4lang4Math3logEJdd", ECF_CONST); define_builtin (BUILT_IN_POW, "__builtin_pow", double_ftype_double_double, "_ZN4java4lang4Math3powEJddd", ECF_CONST); define_builtin (BUILT_IN_SIN, "__builtin_sin", double_ftype_double, "_ZN4java4lang4Math3sinEJdd", ECF_CONST); define_builtin (BUILT_IN_SQRT, "__builtin_sqrt", double_ftype_double, "_ZN4java4lang4Math4sqrtEJdd", ECF_CONST); define_builtin (BUILT_IN_TAN, "__builtin_tan", double_ftype_double, "_ZN4java4lang4Math3tanEJdd", ECF_CONST); boolean_ftype_boolean_boolean = build_function_type_list (boolean_type_node, boolean_type_node, boolean_type_node, NULL_TREE); define_builtin (BUILT_IN_EXPECT, "__builtin_expect", boolean_ftype_boolean_boolean, "__builtin_expect", ECF_CONST | ECF_NOTHROW); define_builtin (BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4, "__sync_bool_compare_and_swap_4", build_function_type_list (boolean_type_node, int_type_node, build_pointer_type (int_type_node), int_type_node, NULL_TREE), "__sync_bool_compare_and_swap_4", ECF_NOTHROW | ECF_LEAF); define_builtin (BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8, "__sync_bool_compare_and_swap_8", build_function_type_list (boolean_type_node, long_type_node, build_pointer_type (long_type_node), int_type_node, NULL_TREE), "__sync_bool_compare_and_swap_8", ECF_NOTHROW | ECF_LEAF); define_builtin (BUILT_IN_SYNC_SYNCHRONIZE, "__sync_synchronize", build_function_type_list (void_type_node, NULL_TREE), "__sync_synchronize", ECF_NOTHROW | ECF_LEAF); define_builtin (BUILT_IN_RETURN_ADDRESS, "__builtin_return_address", build_function_type_list (ptr_type_node, int_type_node, NULL_TREE), "__builtin_return_address", ECF_NOTHROW | ECF_LEAF); define_builtin (BUILT_IN_TRAP, "__builtin_trap", build_function_type_list (void_type_node, NULL_TREE), "__builtin_trap", ECF_NOTHROW | ECF_LEAF | ECF_NORETURN); build_common_builtin_nodes (); }
void declare_function_name () { tree decl, type, init; char *name, *printable_name; int len; if (current_function_decl == NULL) { name = ""; printable_name = "top level"; } else { char *kind = "function"; if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE) kind = "method"; /* Allow functions to be nameless (such as artificial ones). */ if (DECL_NAME (current_function_decl)) name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl)); else name = ""; printable_name = (*decl_printable_name) (current_function_decl, &kind); } /* If the default size of char arrays isn't big enough for the name, make a bigger one. */ len = strlen (name) + 1; type = char_array_type_node; if (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TREE_TYPE (char_array_type_node))) < len) type = build_array_type (char_type_node, build_index_type (build_int_2 (len, 0))); push_obstacks_nochange (); decl = build_decl (VAR_DECL, get_identifier ("__FUNCTION__"), type); TREE_STATIC (decl) = 1; TREE_READONLY (decl) = 1; DECL_SOURCE_LINE (decl) = 0; DECL_IN_SYSTEM_HEADER (decl) = 1; DECL_IGNORED_P (decl) = 1; init = build_string (len, name); TREE_TYPE (init) = type; DECL_INITIAL (decl) = init; finish_decl (pushdecl (decl), init, NULL_TREE); len = strlen (printable_name) + 1; type = char_array_type_node; if (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TREE_TYPE (char_array_type_node))) < len) type = build_array_type (char_type_node, build_index_type (build_int_2 (len, 0))); push_obstacks_nochange (); decl = build_decl (VAR_DECL, get_identifier ("__PRETTY_FUNCTION__"), type); TREE_STATIC (decl) = 1; TREE_READONLY (decl) = 1; DECL_SOURCE_LINE (decl) = 0; DECL_IN_SYSTEM_HEADER (decl) = 1; DECL_IGNORED_P (decl) = 1; init = build_string (len, printable_name); TREE_TYPE (init) = type; DECL_INITIAL (decl) = init; finish_decl (pushdecl (decl), init, NULL_TREE); }
static tree create_field_decl (tree type, const char *name) { return build_decl (input_location, FIELD_DECL, get_identifier (name), type); }
void rest_of_decl_compilation (tree decl, int top_level, int at_end) { /* We deferred calling assemble_alias so that we could collect other attributes such as visibility. Emit the alias now. */ { tree alias; alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)); if (alias) { alias = TREE_VALUE (TREE_VALUE (alias)); alias = get_identifier (TREE_STRING_POINTER (alias)); assemble_alias (decl, alias); } } /* Emit tm_* attributes for declarations now */ { tree tm_attribute; tm_attribute = lookup_attribute ("tm_wrapper", DECL_ATTRIBUTES (decl)); if (tm_attribute == NULL) tm_attribute = lookup_attribute ("transaction_wrap", DECL_ATTRIBUTES (decl)); if (tm_attribute) { tm_attribute = TREE_VALUE (TREE_VALUE (tm_attribute)); tm_attribute = get_identifier (TREE_STRING_POINTER (tm_attribute)); assemble_tm_wrapper (decl, tm_attribute); } if (has_tm_pure_attribute(decl)) { assemble_tm_pure (decl); } if (has_tm_callable_attribute(decl)) { assemble_tm_callable (decl); } } /* Can't defer this, because it needs to happen before any later function definitions are processed. */ if (DECL_ASSEMBLER_NAME_SET_P (decl) && DECL_REGISTER (decl)) /* LLVM LOCAL begin */ #ifndef ENABLE_LLVM make_decl_rtl (decl); #else make_decl_llvm (decl); #endif /* LLVM LOCAL end */ /* Forward declarations for nested functions are not "external", but we need to treat them as if they were. */ if (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || TREE_CODE (decl) == FUNCTION_DECL) { timevar_push (TV_VARCONST); /* Don't output anything when a tentative file-scope definition is seen. But at end of compilation, do output code for them. We do output all variables when unit-at-a-time is active and rely on callgraph code to defer them except for forward declarations (see gcc.c-torture/compile/920624-1.c) */ if ((at_end || !DECL_DEFER_OUTPUT (decl) || DECL_INITIAL (decl)) && !DECL_EXTERNAL (decl)) { if (TREE_CODE (decl) != FUNCTION_DECL) cgraph_varpool_finalize_decl (decl); else assemble_variable (decl, top_level, at_end, 0); } #ifdef ASM_FINISH_DECLARE_OBJECT if (decl == last_assemble_variable_decl) { ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl, top_level, at_end); } #endif timevar_pop (TV_VARCONST); } else if (TREE_CODE (decl) == TYPE_DECL /* Like in rest_of_type_compilation, avoid confusing the debug information machinery when there are errors. */ && !(sorrycount || errorcount)) { /* LLVM LOCAL begin */ #ifndef ENABLE_LLVM timevar_push (TV_SYMOUT); debug_hooks->type_decl (decl, !top_level); timevar_pop (TV_SYMOUT); #else llvm_emit_typedef (decl); #endif /* LLVM LOCAL end */ } /* Let cgraph know about the existence of variables. */ if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl)) cgraph_varpool_node (decl); }
tree build_throw (tree exp) { if (exp == error_mark_node) return exp; if (processing_template_decl) { if (cfun) current_function_returns_abnormally = 1; exp = build_min (THROW_EXPR, void_type_node, exp); SET_EXPR_LOCATION (exp, input_location); return exp; } if (exp && null_node_p (exp)) warning (0, "throwing NULL, which has integral, not pointer type"); if (exp != NULL_TREE) { if (!is_admissible_throw_operand_or_catch_parameter (exp, true)) return error_mark_node; } if (! doing_eh ()) return error_mark_node; if (exp) { tree throw_type; tree temp_type; tree cleanup; tree object, ptr; tree tmp; tree allocate_expr; /* The CLEANUP_TYPE is the internal type of a destructor. */ if (!cleanup_type) { tmp = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE); cleanup_type = build_pointer_type (tmp); } if (!throw_fn) { tree name = get_identifier ("__cxa_throw"); throw_fn = get_global_binding (name); if (!throw_fn) { /* Declare void __cxa_throw (void*, void*, void (*)(void*)). */ /* ??? Second argument is supposed to be "std::type_info*". */ tmp = build_function_type_list (void_type_node, ptr_type_node, ptr_type_node, cleanup_type, NULL_TREE); throw_fn = push_throw_library_fn (name, tmp); if (flag_tm) { tree itm_name = get_identifier ("_ITM_cxa_throw"); tree itm_fn = get_global_binding (itm_name); if (!itm_fn) itm_fn = push_throw_library_fn (itm_name, tmp); apply_tm_attr (itm_fn, get_identifier ("transaction_pure")); record_tm_replacement (throw_fn, itm_fn); } } } /* [except.throw] A throw-expression initializes a temporary object, the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw and adjusting the type from "array of T" or "function return T" to "pointer to T" or "pointer to function returning T" respectively. */ temp_type = is_bitfield_expr_with_lowered_type (exp); if (!temp_type) temp_type = cv_unqualified (type_decays_to (TREE_TYPE (exp))); /* OK, this is kind of wacky. The standard says that we call terminate when the exception handling mechanism, after completing evaluation of the expression to be thrown but before the exception is caught (_except.throw_), calls a user function that exits via an uncaught exception. So we have to protect the actual initialization of the exception object with terminate(), but evaluate the expression first. Since there could be temps in the expression, we need to handle that, too. We also expand the call to __cxa_allocate_exception first (which doesn't matter, since it can't throw). */ /* Allocate the space for the exception. */ allocate_expr = do_allocate_exception (temp_type); allocate_expr = get_target_expr (allocate_expr); ptr = TARGET_EXPR_SLOT (allocate_expr); TARGET_EXPR_CLEANUP (allocate_expr) = do_free_exception (ptr); CLEANUP_EH_ONLY (allocate_expr) = 1; object = build_nop (build_pointer_type (temp_type), ptr); object = cp_build_fold_indirect_ref (object); /* And initialize the exception object. */ if (CLASS_TYPE_P (temp_type)) { int flags = LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING; vec<tree, va_gc> *exp_vec; bool converted = false; /* Under C++0x [12.8/16 class.copy], a thrown lvalue is sometimes treated as an rvalue for the purposes of overload resolution to favor move constructors over copy constructors. */ if (/* Must be a local, automatic variable. */ VAR_P (exp) && DECL_CONTEXT (exp) == current_function_decl && ! TREE_STATIC (exp) /* The variable must not have the `volatile' qualifier. */ && !(cp_type_quals (TREE_TYPE (exp)) & TYPE_QUAL_VOLATILE)) { tree moved = move (exp); exp_vec = make_tree_vector_single (moved); moved = (build_special_member_call (object, complete_ctor_identifier, &exp_vec, TREE_TYPE (object), flags|LOOKUP_PREFER_RVALUE, tf_none)); release_tree_vector (exp_vec); if (moved != error_mark_node) { exp = moved; converted = true; } } /* Call the copy constructor. */ if (!converted) { exp_vec = make_tree_vector_single (exp); exp = (build_special_member_call (object, complete_ctor_identifier, &exp_vec, TREE_TYPE (object), flags, tf_warning_or_error)); release_tree_vector (exp_vec); } if (exp == error_mark_node) { error (" in thrown expression"); return error_mark_node; } } else { tmp = decay_conversion (exp, tf_warning_or_error); if (tmp == error_mark_node) return error_mark_node; exp = build2 (INIT_EXPR, temp_type, object, tmp); } /* Mark any cleanups from the initialization as MUST_NOT_THROW, since they are run after the exception object is initialized. */ cp_walk_tree_without_duplicates (&exp, wrap_cleanups_r, 0); /* Prepend the allocation. */ exp = build2 (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp); /* Force all the cleanups to be evaluated here so that we don't have to do them during unwinding. */ exp = build1 (CLEANUP_POINT_EXPR, void_type_node, exp); throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object))); cleanup = NULL_TREE; if (type_build_dtor_call (TREE_TYPE (object))) { tree dtor_fn = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)), complete_dtor_identifier, 0); dtor_fn = BASELINK_FUNCTIONS (dtor_fn); mark_used (dtor_fn); if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object))) { cxx_mark_addressable (dtor_fn); /* Pretend it's a normal function. */ cleanup = build1 (ADDR_EXPR, cleanup_type, dtor_fn); } } if (cleanup == NULL_TREE) cleanup = build_int_cst (cleanup_type, 0); /* ??? Indicate that this function call throws throw_type. */ tmp = cp_build_function_call_nary (throw_fn, tf_warning_or_error, ptr, throw_type, cleanup, NULL_TREE); /* Tack on the initialization stuff. */ exp = build2 (COMPOUND_EXPR, TREE_TYPE (tmp), exp, tmp); } else { /* Rethrow current exception. */ if (!rethrow_fn) { tree name = get_identifier ("__cxa_rethrow"); rethrow_fn = get_global_binding (name); if (!rethrow_fn) /* Declare void __cxa_rethrow (void). */ rethrow_fn = push_throw_library_fn (name, build_function_type_list (void_type_node, NULL_TREE)); if (flag_tm) apply_tm_attr (rethrow_fn, get_identifier ("transaction_pure")); } /* ??? Indicate that this function call allows exceptions of the type of the enclosing catch block (if known). */ exp = cp_build_function_call_vec (rethrow_fn, NULL, tf_warning_or_error); } exp = build1 (THROW_EXPR, void_type_node, exp); SET_EXPR_LOCATION (exp, input_location); return exp; }
static tree get_eh_caught () { return build_component_ref (get_eh_info (), get_identifier ("caught"), NULL_TREE, 0); }
static tree get_eh_type () { return build_component_ref (get_eh_info (), get_identifier ("type"), NULL_TREE, 0); }
static tree call_eh_info () { tree fn; fn = get_identifier ("__start_cp_handler"); if (IDENTIFIER_GLOBAL_VALUE (fn)) fn = IDENTIFIER_GLOBAL_VALUE (fn); else { tree t1, t, fields[7]; /* Declare cp_eh_info * __start_cp_handler (void), as defined in exception.cc. */ /* struct cp_eh_info. This must match exception.cc. Note that this type is not pushed anywhere. */ t1= make_aggr_type (RECORD_TYPE); fields[0] = build_decl (FIELD_DECL, get_identifier ("handler_label"), ptr_type_node); fields[1] = build_decl (FIELD_DECL, get_identifier ("dynamic_handler_chain"), ptr_type_node); fields[2] = build_decl (FIELD_DECL, get_identifier ("info"), ptr_type_node); fields[3] = build_decl (FIELD_DECL, get_identifier ("table_index"), ptr_type_node); /* N.B.: The fourth field LEN is expected to be the number of fields - 1, not the total number of fields. */ finish_builtin_type (t1, "eh_context", fields, 3, ptr_type_node); t1 = build_pointer_type (t1); t1= make_aggr_type (RECORD_TYPE); #ifdef TARG_XTENSA fields[0] = build_decl (FIELD_DECL, get_identifier ("version"), integer_type_node); /* N.B.: The fourth field LEN is expected to be the number of fields - 1, not the total number of fields. */ finish_builtin_type (t1, "__eh_info", fields, 0, ptr_type_node); #else fields[0] = build_decl (FIELD_DECL, get_identifier ("match_function"), ptr_type_node); fields[1] = build_decl (FIELD_DECL, get_identifier ("language"), short_integer_type_node); fields[2] = build_decl (FIELD_DECL, get_identifier ("version"), short_integer_type_node); /* N.B.: The fourth field LEN is expected to be the number of fields - 1, not the total number of fields. */ finish_builtin_type (t1, "__eh_info", fields, 2, ptr_type_node); #endif t = make_aggr_type (RECORD_TYPE); fields[0] = build_decl (FIELD_DECL, get_identifier ("eh_info"), t1); fields[1] = build_decl (FIELD_DECL, get_identifier ("value"), ptr_type_node); fields[2] = build_decl (FIELD_DECL, get_identifier ("type"), ptr_type_node); fields[3] = build_decl (FIELD_DECL, get_identifier ("cleanup"), build_pointer_type (build_function_type (ptr_type_node, tree_cons (NULL_TREE, ptr_type_node, void_list_node)))); fields[4] = build_decl (FIELD_DECL, get_identifier ("caught"), boolean_type_node); fields[5] = build_decl (FIELD_DECL, get_identifier ("next"), build_pointer_type (t)); fields[6] = build_decl (FIELD_DECL, get_identifier ("handlers"), long_integer_type_node); /* N.B.: The fourth field LEN is expected to be the number of fields - 1, not the total number of fields. */ finish_builtin_type (t, "cp_eh_info", fields, 6, ptr_type_node); t = build_pointer_type (t); /* And now the function. */ fn = push_library_fn (fn, build_function_type (t, void_list_node)); } return build_function_call (fn, NULL_TREE); }
static void afdo_indirect_call (gimple_stmt_iterator *gsi, const icall_target_map &map, bool transform) { gimple *gs = gsi_stmt (*gsi); tree callee; if (map.size () == 0) return; gcall *stmt = dyn_cast <gcall *> (gs); if ((!stmt) || gimple_call_fndecl (stmt) != NULL_TREE) return; callee = gimple_call_fn (stmt); histogram_value hist = gimple_alloc_histogram_value ( cfun, HIST_TYPE_INDIR_CALL, stmt, callee); hist->n_counters = 3; hist->hvalue.counters = XNEWVEC (gcov_type, hist->n_counters); gimple_add_histogram_value (cfun, stmt, hist); gcov_type total = 0; icall_target_map::const_iterator max_iter = map.end (); for (icall_target_map::const_iterator iter = map.begin (); iter != map.end (); ++iter) { total += iter->second; if (max_iter == map.end () || max_iter->second < iter->second) max_iter = iter; } hist->hvalue.counters[0] = (unsigned long long)afdo_string_table->get_name (max_iter->first); hist->hvalue.counters[1] = max_iter->second; hist->hvalue.counters[2] = total; if (!transform) return; struct cgraph_edge *indirect_edge = cgraph_node::get (current_function_decl)->get_edge (stmt); struct cgraph_node *direct_call = cgraph_node::get_for_asmname ( get_identifier ((const char *) hist->hvalue.counters[0])); if (dump_file) { fprintf (dump_file, "Indirect call -> direct call "); print_generic_expr (dump_file, callee, TDF_SLIM); fprintf (dump_file, " => "); print_generic_expr (dump_file, direct_call->decl, TDF_SLIM); } if (direct_call == NULL || !check_ic_target (stmt, direct_call)) { if (dump_file) fprintf (dump_file, " not transforming\n"); return; } if (DECL_STRUCT_FUNCTION (direct_call->decl) == NULL) { if (dump_file) fprintf (dump_file, " no declaration\n"); return; } if (dump_file) { fprintf (dump_file, " transformation on insn "); print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); fprintf (dump_file, "\n"); } /* FIXME: Count should be initialized. */ struct cgraph_edge *new_edge = indirect_edge->make_speculative (direct_call, profile_count::uninitialized ()); new_edge->redirect_call_stmt_to_callee (); gimple_remove_histogram_value (cfun, stmt, hist); inline_call (new_edge, true, NULL, NULL, false); }
x_window get_x_window (widget w) { int id= get_identifier (w); if (id == 0) return NULL; else return (x_window) Window_to_window[(Window) id]; }
static void build_field (segment_info *h, tree union_type, record_layout_info rli) { tree field; tree name; HOST_WIDE_INT offset = h->offset; unsigned HOST_WIDE_INT desired_align, known_align; name = get_identifier (h->sym->name); field = build_decl (h->sym->declared_at.lb->location, FIELD_DECL, name, h->field); known_align = (offset & -offset) * BITS_PER_UNIT; if (known_align == 0 || known_align > BIGGEST_ALIGNMENT) known_align = BIGGEST_ALIGNMENT; desired_align = update_alignment_for_field (rli, field, known_align); if (desired_align > known_align) DECL_PACKED (field) = 1; DECL_FIELD_CONTEXT (field) = union_type; DECL_FIELD_OFFSET (field) = size_int (offset); DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node; SET_DECL_OFFSET_ALIGN (field, known_align); rli->offset = size_binop (MAX_EXPR, rli->offset, size_binop (PLUS_EXPR, DECL_FIELD_OFFSET (field), DECL_SIZE_UNIT (field))); /* If this field is assigned to a label, we create another two variables. One will hold the address of target label or format label. The other will hold the length of format label string. */ if (h->sym->attr.assign) { tree len; tree addr; gfc_allocate_lang_decl (field); GFC_DECL_ASSIGN (field) = 1; len = gfc_create_var_np (gfc_charlen_type_node,h->sym->name); addr = gfc_create_var_np (pvoid_type_node, h->sym->name); TREE_STATIC (len) = 1; TREE_STATIC (addr) = 1; DECL_INITIAL (len) = build_int_cst (gfc_charlen_type_node, -2); gfc_set_decl_location (len, &h->sym->declared_at); gfc_set_decl_location (addr, &h->sym->declared_at); GFC_DECL_STRING_LEN (field) = pushdecl_top_level (len); GFC_DECL_ASSIGN_ADDR (field) = pushdecl_top_level (addr); } /* If this field is volatile, mark it. */ if (h->sym->attr.volatile_) { tree new_type; TREE_THIS_VOLATILE (field) = 1; TREE_SIDE_EFFECTS (field) = 1; new_type = build_qualified_type (TREE_TYPE (field), TYPE_QUAL_VOLATILE); TREE_TYPE (field) = new_type; } h->field = field; }
tree decl_attributes (tree *node, tree attributes, int flags) { tree a; tree returned_attrs = NULL_TREE; if (TREE_TYPE (*node) == error_mark_node || attributes == error_mark_node) return NULL_TREE; if (!attributes_initialized) init_attributes (); /* If this is a function and the user used #pragma GCC optimize, add the options to the attribute((optimize(...))) list. */ if (TREE_CODE (*node) == FUNCTION_DECL && current_optimize_pragma) { tree cur_attr = lookup_attribute ("optimize", attributes); tree opts = copy_list (current_optimize_pragma); if (! cur_attr) attributes = tree_cons (get_identifier ("optimize"), opts, attributes); else TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr)); } if (TREE_CODE (*node) == FUNCTION_DECL && optimization_current_node != optimization_default_node && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)) DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node; /* If this is a function and the user used #pragma GCC target, add the options to the attribute((target(...))) list. */ if (TREE_CODE (*node) == FUNCTION_DECL && current_target_pragma && targetm.target_option.valid_attribute_p (*node, NULL_TREE, current_target_pragma, 0)) { tree cur_attr = lookup_attribute ("target", attributes); tree opts = copy_list (current_target_pragma); if (! cur_attr) attributes = tree_cons (get_identifier ("target"), opts, attributes); else TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr)); } /* A "naked" function attribute implies "noinline" and "noclone" for those targets that support it. */ if (TREE_CODE (*node) == FUNCTION_DECL && attributes && lookup_attribute_spec (get_identifier ("naked")) && lookup_attribute ("naked", attributes) != NULL) { if (lookup_attribute ("noinline", attributes) == NULL) attributes = tree_cons (get_identifier ("noinline"), NULL, attributes); if (lookup_attribute ("noclone", attributes) == NULL) attributes = tree_cons (get_identifier ("noclone"), NULL, attributes); } targetm.insert_attributes (*node, &attributes); for (a = attributes; a; a = TREE_CHAIN (a)) { tree ns = get_attribute_namespace (a); tree name = get_attribute_name (a); tree args = TREE_VALUE (a); tree *anode = node; const struct attribute_spec *spec = lookup_scoped_attribute_spec (ns, name); bool no_add_attrs = 0; int fn_ptr_quals = 0; tree fn_ptr_tmp = NULL_TREE; if (spec == NULL) { if (!(flags & (int) ATTR_FLAG_BUILT_IN)) { if (ns == NULL_TREE || !cxx11_attribute_p (a)) warning (OPT_Wattributes, "%qE attribute directive ignored", name); else warning (OPT_Wattributes, "%<%E::%E%> scoped attribute directive ignored", ns, name); } continue; } else if (list_length (args) < spec->min_length || (spec->max_length >= 0 && list_length (args) > spec->max_length)) { error ("wrong number of arguments specified for %qE attribute", name); continue; } gcc_assert (is_attribute_p (spec->name, name)); if (TYPE_P (*node) && cxx11_attribute_p (a) && !(flags & ATTR_FLAG_TYPE_IN_PLACE)) { /* This is a c++11 attribute that appertains to a type-specifier, outside of the definition of, a class type. Ignore it. */ warning (OPT_Wattributes, "attribute ignored"); inform (input_location, "an attribute that appertains to a type-specifier " "is ignored"); continue; } if (spec->decl_required && !DECL_P (*anode)) { if (flags & ((int) ATTR_FLAG_DECL_NEXT | (int) ATTR_FLAG_FUNCTION_NEXT | (int) ATTR_FLAG_ARRAY_NEXT)) { /* Pass on this attribute to be tried again. */ returned_attrs = tree_cons (name, args, returned_attrs); continue; } else { warning (OPT_Wattributes, "%qE attribute does not apply to types", name); continue; } } /* If we require a type, but were passed a decl, set up to make a new type and update the one in the decl. ATTR_FLAG_TYPE_IN_PLACE would have applied if we'd been passed a type, but we cannot modify the decl's type in place here. */ if (spec->type_required && DECL_P (*anode)) { anode = &TREE_TYPE (*anode); flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE; } if (spec->function_type_required && TREE_CODE (*anode) != FUNCTION_TYPE && TREE_CODE (*anode) != METHOD_TYPE) { if (TREE_CODE (*anode) == POINTER_TYPE && (TREE_CODE (TREE_TYPE (*anode)) == FUNCTION_TYPE || TREE_CODE (TREE_TYPE (*anode)) == METHOD_TYPE)) { /* OK, this is a bit convoluted. We can't just make a copy of the pointer type and modify its TREE_TYPE, because if we change the attributes of the target type the pointer type needs to have a different TYPE_MAIN_VARIANT. So we pull out the target type now, frob it as appropriate, and rebuild the pointer type later. This would all be simpler if attributes were part of the declarator, grumble grumble. */ fn_ptr_tmp = TREE_TYPE (*anode); fn_ptr_quals = TYPE_QUALS (*anode); anode = &fn_ptr_tmp; flags &= ~(int) ATTR_FLAG_TYPE_IN_PLACE; } else if (flags & (int) ATTR_FLAG_FUNCTION_NEXT) { /* Pass on this attribute to be tried again. */ returned_attrs = tree_cons (name, args, returned_attrs); continue; } if (TREE_CODE (*anode) != FUNCTION_TYPE && TREE_CODE (*anode) != METHOD_TYPE) { warning (OPT_Wattributes, "%qE attribute only applies to function types", name); continue; } } if (TYPE_P (*anode) && (flags & (int) ATTR_FLAG_TYPE_IN_PLACE) && TYPE_SIZE (*anode) != NULL_TREE) { warning (OPT_Wattributes, "type attributes ignored after type is already defined"); continue; } if (spec->handler != NULL) { int cxx11_flag = cxx11_attribute_p (a) ? ATTR_FLAG_CXX11 : 0; returned_attrs = chainon ((*spec->handler) (anode, name, args, flags|cxx11_flag, &no_add_attrs), returned_attrs); } /* Layout the decl in case anything changed. */ if (spec->type_required && DECL_P (*node) && (TREE_CODE (*node) == VAR_DECL || TREE_CODE (*node) == PARM_DECL || TREE_CODE (*node) == RESULT_DECL)) relayout_decl (*node); if (!no_add_attrs) { tree old_attrs; tree a; if (DECL_P (*anode)) old_attrs = DECL_ATTRIBUTES (*anode); else old_attrs = TYPE_ATTRIBUTES (*anode); for (a = lookup_attribute (spec->name, old_attrs); a != NULL_TREE; a = lookup_attribute (spec->name, TREE_CHAIN (a))) { if (simple_cst_equal (TREE_VALUE (a), args) == 1) break; } if (a == NULL_TREE) { /* This attribute isn't already in the list. */ if (DECL_P (*anode)) DECL_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs); else if (flags & (int) ATTR_FLAG_TYPE_IN_PLACE) { TYPE_ATTRIBUTES (*anode) = tree_cons (name, args, old_attrs); /* If this is the main variant, also push the attributes out to the other variants. */ if (*anode == TYPE_MAIN_VARIANT (*anode)) { tree variant; for (variant = *anode; variant; variant = TYPE_NEXT_VARIANT (variant)) { if (TYPE_ATTRIBUTES (variant) == old_attrs) TYPE_ATTRIBUTES (variant) = TYPE_ATTRIBUTES (*anode); else if (!lookup_attribute (spec->name, TYPE_ATTRIBUTES (variant))) TYPE_ATTRIBUTES (variant) = tree_cons (name, args, TYPE_ATTRIBUTES (variant)); } } } else *anode = build_type_attribute_variant (*anode, tree_cons (name, args, old_attrs)); } } if (fn_ptr_tmp) { /* Rebuild the function pointer type and put it in the appropriate place. */ fn_ptr_tmp = build_pointer_type (fn_ptr_tmp); if (fn_ptr_quals) fn_ptr_tmp = build_qualified_type (fn_ptr_tmp, fn_ptr_quals); if (DECL_P (*node)) TREE_TYPE (*node) = fn_ptr_tmp; else { gcc_assert (TREE_CODE (*node) == POINTER_TYPE); *node = fn_ptr_tmp; } } } return returned_attrs; }
static tree build_common_decl (gfc_common_head *com, tree union_type, bool is_init) { gfc_symbol *common_sym; tree decl; /* Create a namespace to store symbols for common blocks. */ if (gfc_common_ns == NULL) gfc_common_ns = gfc_get_namespace (NULL, 0); gfc_get_symbol (com->name, gfc_common_ns, &common_sym); decl = common_sym->backend_decl; /* Update the size of this common block as needed. */ if (decl != NULL_TREE) { tree size = TYPE_SIZE_UNIT (union_type); /* Named common blocks of the same name shall be of the same size in all scoping units of a program in which they appear, but blank common blocks may be of different sizes. */ if (!tree_int_cst_equal (DECL_SIZE_UNIT (decl), size) && strcmp (com->name, BLANK_COMMON_NAME)) gfc_warning ("Named COMMON block '%s' at %L shall be of the " "same size as elsewhere (%lu vs %lu bytes)", com->name, &com->where, (unsigned long) TREE_INT_CST_LOW (size), (unsigned long) TREE_INT_CST_LOW (DECL_SIZE_UNIT (decl))); if (tree_int_cst_lt (DECL_SIZE_UNIT (decl), size)) { DECL_SIZE (decl) = TYPE_SIZE (union_type); DECL_SIZE_UNIT (decl) = size; DECL_MODE (decl) = TYPE_MODE (union_type); TREE_TYPE (decl) = union_type; layout_decl (decl, 0); } } /* If this common block has been declared in a previous program unit, and either it is already initialized or there is no new initialization for it, just return. */ if ((decl != NULL_TREE) && (!is_init || DECL_INITIAL (decl))) return decl; /* If there is no backend_decl for the common block, build it. */ if (decl == NULL_TREE) { decl = build_decl (input_location, VAR_DECL, get_identifier (com->name), union_type); gfc_set_decl_assembler_name (decl, gfc_sym_mangled_common_id (com)); TREE_PUBLIC (decl) = 1; TREE_STATIC (decl) = 1; DECL_IGNORED_P (decl) = 1; if (!com->is_bind_c) DECL_ALIGN (decl) = BIGGEST_ALIGNMENT; else { /* Do not set the alignment for bind(c) common blocks to BIGGEST_ALIGNMENT because that won't match what C does. Also, for common blocks with one element, the alignment must be that of the field within the common block in order to match what C will do. */ tree field = NULL_TREE; field = TYPE_FIELDS (TREE_TYPE (decl)); if (DECL_CHAIN (field) == NULL_TREE) DECL_ALIGN (decl) = TYPE_ALIGN (TREE_TYPE (field)); } DECL_USER_ALIGN (decl) = 0; GFC_DECL_COMMON_OR_EQUIV (decl) = 1; gfc_set_decl_location (decl, &com->where); if (com->threadprivate) DECL_TLS_MODEL (decl) = decl_default_tls_model (decl); /* Place the back end declaration for this common block in GLOBAL_BINDING_LEVEL. */ common_sym->backend_decl = pushdecl_top_level (decl); } /* Has no initial values. */ if (!is_init) { DECL_INITIAL (decl) = NULL_TREE; DECL_COMMON (decl) = 1; DECL_DEFER_OUTPUT (decl) = 1; } else { DECL_INITIAL (decl) = error_mark_node; DECL_COMMON (decl) = 0; DECL_DEFER_OUTPUT (decl) = 0; } return decl; }
void gimple_init_edge_profiler (void) { tree interval_profiler_fn_type; tree pow2_profiler_fn_type; tree one_value_profiler_fn_type; tree gcov_type_ptr; tree ic_profiler_fn_type; tree average_profiler_fn_type; tree time_profiler_fn_type; if (!gcov_type_node) { gcov_type_node = get_gcov_type (); gcov_type_ptr = build_pointer_type (gcov_type_node); /* void (*) (gcov_type *, gcov_type, int, unsigned) */ interval_profiler_fn_type = build_function_type_list (void_type_node, gcov_type_ptr, gcov_type_node, integer_type_node, unsigned_type_node, NULL_TREE); tree_interval_profiler_fn = build_fn_decl ("__gcov_interval_profiler", interval_profiler_fn_type); TREE_NOTHROW (tree_interval_profiler_fn) = 1; DECL_ATTRIBUTES (tree_interval_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, DECL_ATTRIBUTES (tree_interval_profiler_fn)); /* void (*) (gcov_type *, gcov_type) */ pow2_profiler_fn_type = build_function_type_list (void_type_node, gcov_type_ptr, gcov_type_node, NULL_TREE); tree_pow2_profiler_fn = build_fn_decl ("__gcov_pow2_profiler", pow2_profiler_fn_type); TREE_NOTHROW (tree_pow2_profiler_fn) = 1; DECL_ATTRIBUTES (tree_pow2_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, DECL_ATTRIBUTES (tree_pow2_profiler_fn)); /* void (*) (gcov_type *, gcov_type) */ one_value_profiler_fn_type = build_function_type_list (void_type_node, gcov_type_ptr, gcov_type_node, NULL_TREE); tree_one_value_profiler_fn = build_fn_decl ("__gcov_one_value_profiler", one_value_profiler_fn_type); TREE_NOTHROW (tree_one_value_profiler_fn) = 1; DECL_ATTRIBUTES (tree_one_value_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, DECL_ATTRIBUTES (tree_one_value_profiler_fn)); init_ic_make_global_vars (); /* void (*) (gcov_type, void *) */ ic_profiler_fn_type = build_function_type_list (void_type_node, gcov_type_node, ptr_void, NULL_TREE); tree_indirect_call_profiler_fn = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ? "__gcov_indirect_call_topn_profiler": "__gcov_indirect_call_profiler_v2"), ic_profiler_fn_type); TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1; DECL_ATTRIBUTES (tree_indirect_call_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)); /* void (*) (gcov_type *, gcov_type, void *) */ time_profiler_fn_type = build_function_type_list (void_type_node, gcov_type_ptr, NULL_TREE); tree_time_profiler_fn = build_fn_decl ("__gcov_time_profiler", time_profiler_fn_type); TREE_NOTHROW (tree_time_profiler_fn) = 1; DECL_ATTRIBUTES (tree_time_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, DECL_ATTRIBUTES (tree_time_profiler_fn)); /* void (*) (gcov_type *, gcov_type) */ average_profiler_fn_type = build_function_type_list (void_type_node, gcov_type_ptr, gcov_type_node, NULL_TREE); tree_average_profiler_fn = build_fn_decl ("__gcov_average_profiler", average_profiler_fn_type); TREE_NOTHROW (tree_average_profiler_fn) = 1; DECL_ATTRIBUTES (tree_average_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, DECL_ATTRIBUTES (tree_average_profiler_fn)); tree_ior_profiler_fn = build_fn_decl ("__gcov_ior_profiler", average_profiler_fn_type); TREE_NOTHROW (tree_ior_profiler_fn) = 1; DECL_ATTRIBUTES (tree_ior_profiler_fn) = tree_cons (get_identifier ("leaf"), NULL, DECL_ATTRIBUTES (tree_ior_profiler_fn)); /* LTO streamer needs assembler names. Because we create these decls late, we need to initialize them by hand. */ DECL_ASSEMBLER_NAME (tree_interval_profiler_fn); DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn); DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn); DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn); DECL_ASSEMBLER_NAME (tree_time_profiler_fn); DECL_ASSEMBLER_NAME (tree_average_profiler_fn); DECL_ASSEMBLER_NAME (tree_ior_profiler_fn); } }