diff --git a/src/Makefile b/src/Makefile old mode 100755 new mode 100644 index f2a0a03..ec1516e --- a/src/Makefile +++ b/src/Makefile @@ -1,6 +1,42 @@ -$(HOSTLIBS)-$(CONFIG_PAX_RAP) += rap_plugin.so -always := $($(HOSTLIBS)-y) +GCC_PLUGINS_DIR := $(shell $(CC) -print-file-name=plugin) -rap_plugin-objs := $(patsubst $(srctree)/$(src)/%.c,%.o,$(wildcard $(srctree)/$(src)/*.c)) +ifeq ($(PLUGINCC),$(HOSTCC)) + HOSTLIBS := hostlibs + HOST_EXTRACFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src) + HOST_EXTRACFLAGS += -std=gnu99 -ggdb -fvisibility=hidden + HOST_EXTRACFLAGS += -Wall -W + export HOST_EXTRACFLAGS +else + HOSTLIBS := hostcxxlibs + HOST_EXTRACXXFLAGS += -I$(GCC_PLUGINS_DIR)/include -I$(src) + HOST_EXTRACXXFLAGS += -std=gnu++98 -ggdb -fvisibility=hidden + HOST_EXTRACXXFLAGS += -fno-rtti -fno-exceptions -fasynchronous-unwind-tables + HOST_EXTRACXXFLAGS += -Wall -W + HOST_EXTRACXXFLAGS += -Wno-unused-parameter -Wno-narrowing -Wno-unused-variable + export HOST_EXTRACXXFLAGS +endif + +ifneq ($(CFLAGS_KCOV), $(SANCOV_PLUGIN)) + GCC_PLUGIN := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGIN)) +endif + +export HOSTLIBS + +$(HOSTLIBS)-y := $(foreach p,$(GCC_PLUGIN),$(if $(findstring /,$(p)),,$(p))) +always := $($(HOSTLIBS)-y) +$(foreach p,$($(HOSTLIBS)-y:%.so=%),$(eval $(p)-objs := $(p).o)) + +$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h + +quiet_cmd_create_randomize_layout_seed = GENSEED $@ + cmd_create_randomize_layout_seed = \ + $(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h +$(objtree)/$(obj)/randomize_layout_seed.h: FORCE + $(call if_changed,create_randomize_layout_seed) + +targets += randomize_layout_seed.h randomize_layout_hash.h + +subdir-y := $(GCC_PLUGIN_SUBDIR) +subdir- += $(GCC_PLUGIN_SUBDIR) clean-files += *.so diff --git a/src/checker_plugin.c b/src/checker_plugin.c new file mode 100644 index 0000000..c16753c --- /dev/null +++ b/src/checker_plugin.c @@ -0,0 +1,491 @@ +/* + * Copyright 2011-2017 by the PaX Team + * Licensed under the GPL v2 + * + * Note: the choice of the license means that the compilation process is + * NOT 'eligible' as defined by gcc's library exception to the GPL v3, + * but for the kernel it doesn't matter since it doesn't link against + * any of the gcc libraries + * + * gcc plugin to implement various sparse (source code checker) features + * + * TODO: + * - define separate __iomem, __percpu and __rcu address spaces (lots of code to patch) + * + * BUGS: + * - none known + */ + +#include "gcc-common.h" + +extern void c_register_addr_space (const char *str, addr_space_t as); +extern enum machine_mode default_addr_space_pointer_mode (addr_space_t); +extern enum machine_mode default_addr_space_address_mode (addr_space_t); +extern bool default_addr_space_valid_pointer_mode(enum machine_mode mode, addr_space_t as); +extern bool default_addr_space_legitimate_address_p(enum machine_mode mode, rtx mem, bool strict, addr_space_t as); +extern rtx default_addr_space_legitimize_address(rtx x, rtx oldx, enum machine_mode mode, addr_space_t as); + +__visible int plugin_is_GPL_compatible; + +static struct plugin_info checker_plugin_info = { + .version = "201602181345", + .help = "user\tturn on user/kernel address space checking\n" + "context\tturn on locking context checking\n" +}; + +#define ADDR_SPACE_KERNEL 0 +#define ADDR_SPACE_FORCE_KERNEL 1 +#define ADDR_SPACE_USER 2 +#define ADDR_SPACE_FORCE_USER 3 +#define ADDR_SPACE_IOMEM 0 +#define ADDR_SPACE_FORCE_IOMEM 0 +#define ADDR_SPACE_PERCPU 0 +#define ADDR_SPACE_FORCE_PERCPU 0 +#define ADDR_SPACE_RCU 0 +#define ADDR_SPACE_FORCE_RCU 0 + +static enum machine_mode checker_addr_space_pointer_mode(addr_space_t addrspace) +{ + return default_addr_space_pointer_mode(ADDR_SPACE_GENERIC); +} + +static enum machine_mode checker_addr_space_address_mode(addr_space_t addrspace) +{ + return default_addr_space_address_mode(ADDR_SPACE_GENERIC); +} + +static bool checker_addr_space_valid_pointer_mode(enum machine_mode mode, addr_space_t as) +{ + return default_addr_space_valid_pointer_mode(mode, as); +} + +static bool checker_addr_space_legitimate_address_p(enum machine_mode mode, rtx mem, bool strict, addr_space_t as) +{ + return default_addr_space_legitimate_address_p(mode, mem, strict, ADDR_SPACE_GENERIC); +} + +static rtx checker_addr_space_legitimize_address(rtx x, rtx oldx, enum machine_mode mode, addr_space_t as) +{ + return default_addr_space_legitimize_address(x, oldx, mode, as); +} + +static bool checker_addr_space_subset_p(addr_space_t subset, addr_space_t superset) +{ + if (subset == ADDR_SPACE_FORCE_KERNEL && superset == ADDR_SPACE_KERNEL) + return true; + + if (subset == ADDR_SPACE_FORCE_USER && superset == ADDR_SPACE_USER) + return true; + + if (subset == ADDR_SPACE_FORCE_IOMEM && superset == ADDR_SPACE_IOMEM) + return true; + + if (subset == ADDR_SPACE_KERNEL && superset == ADDR_SPACE_FORCE_USER) + return true; + + if (subset == ADDR_SPACE_KERNEL && superset == ADDR_SPACE_FORCE_IOMEM) + return true; + + if (subset == ADDR_SPACE_USER && superset == ADDR_SPACE_FORCE_KERNEL) + return true; + + if (subset == ADDR_SPACE_IOMEM && superset == ADDR_SPACE_FORCE_KERNEL) + return true; + + return subset == superset; +} + +static rtx checker_addr_space_convert(rtx op, tree from_type, tree to_type) +{ +// addr_space_t from_as = TYPE_ADDR_SPACE(TREE_TYPE(from_type)); +// addr_space_t to_as = TYPE_ADDR_SPACE(TREE_TYPE(to_type)); + + return op; +} + +static void register_checker_address_spaces(void *event_data, void *data) +{ + c_register_addr_space("__kernel", ADDR_SPACE_KERNEL); + c_register_addr_space("__force_kernel", ADDR_SPACE_FORCE_KERNEL); + c_register_addr_space("__user", ADDR_SPACE_USER); + c_register_addr_space("__force_user", ADDR_SPACE_FORCE_USER); +// c_register_addr_space("__iomem", ADDR_SPACE_IOMEM); +// c_register_addr_space("__force_iomem", ADDR_SPACE_FORCE_IOMEM); +// c_register_addr_space("__percpu", ADDR_SPACE_PERCPU); +// c_register_addr_space("__force_percpu", ADDR_SPACE_FORCE_PERCPU); +// c_register_addr_space("__rcu", ADDR_SPACE_RCU); +// c_register_addr_space("__force_rcu", ADDR_SPACE_FORCE_RCU); + + targetm.addr_space.pointer_mode = checker_addr_space_pointer_mode; + targetm.addr_space.address_mode = checker_addr_space_address_mode; + targetm.addr_space.valid_pointer_mode = checker_addr_space_valid_pointer_mode; + targetm.addr_space.legitimate_address_p = checker_addr_space_legitimate_address_p; +// targetm.addr_space.legitimize_address = checker_addr_space_legitimize_address; + targetm.addr_space.subset_p = checker_addr_space_subset_p; + targetm.addr_space.convert = checker_addr_space_convert; +} + +static bool split_context_attribute(tree args, tree *lock, tree *in, tree *out) +{ + *in = TREE_VALUE(args); + + if (TREE_CODE(*in) != INTEGER_CST) { + *lock = *in; + args = TREE_CHAIN(args); + *in = TREE_VALUE(args); + } else + *lock = NULL_TREE; + + args = TREE_CHAIN(args); + if (*lock && !args) + return false; + + *out = TREE_VALUE(args); + return true; +} + +static tree handle_context_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) +{ + *no_add_attrs = true; + tree lock, in, out; + + if (TREE_CODE(*node) != FUNCTION_DECL) { + error("%qE attribute applies to functions only (%qD)", name, *node); + return NULL_TREE; + } + + if (!split_context_attribute(args, &lock, &in, &out)) { + error("%qE attribute needs two integers after the lock expression", name); + return NULL_TREE; + } + + if (TREE_CODE(in) != INTEGER_CST) { + error("the 'in' argument of the %qE attribute must be an integer (%qE)", name, in); + return NULL_TREE; + } + + if (TREE_CODE(out) != INTEGER_CST) { + error("the 'out' argument of the %qE attribute must be an integer (%qE)", name, out); + return NULL_TREE; + } + + *no_add_attrs = false; + return NULL_TREE; +} + +static struct attribute_spec context_attr = { + .name = "context", + .min_length = 2, + .max_length = 3, + .decl_required = true, + .type_required = false, + .function_type_required = false, + .handler = handle_context_attribute, +#if BUILDING_GCC_VERSION >= 4007 + .affects_type_identity = true +#endif +}; + +static void register_attributes(void *event_data, void *data) +{ + register_attribute(&context_attr); +} + +static const char context_function[] = "__context__"; +static GTY(()) tree context_function_decl; + +static const char context_error[] = "__context_error__"; +static GTY(()) tree context_error_decl; + +static void context_start_unit(void __unused *gcc_data, void __unused *user_data) +{ + tree fntype, attr; + + // void __context__(void *, int); + fntype = build_function_type_list(void_type_node, ptr_type_node, integer_type_node, NULL_TREE); + context_function_decl = build_fn_decl(context_function, fntype); + + TREE_PUBLIC(context_function_decl) = 1; + TREE_USED(context_function_decl) = 1; + DECL_EXTERNAL(context_function_decl) = 1; + DECL_ARTIFICIAL(context_function_decl) = 1; + DECL_PRESERVE_P(context_function_decl) = 1; +// TREE_NOTHROW(context_function_decl) = 1; +// DECL_UNINLINABLE(context_function_decl) = 1; + DECL_ASSEMBLER_NAME(context_function_decl); // for LTO + lang_hooks.decls.pushdecl(context_function_decl); + + // void __context_error__(const void *, int) __attribute__((error("context error"))); + fntype = build_function_type_list(void_type_node, const_ptr_type_node, integer_type_node, NULL_TREE); + context_error_decl = build_fn_decl(context_error, fntype); + + TREE_PUBLIC(context_error_decl) = 1; + TREE_USED(context_error_decl) = 1; + DECL_EXTERNAL(context_error_decl) = 1; + DECL_ARTIFICIAL(context_error_decl) = 1; + DECL_PRESERVE_P(context_error_decl) = 1; +// TREE_NOTHROW(context_error_decl) = 1; +// DECL_UNINLINABLE(context_error_decl) = 1; + TREE_THIS_VOLATILE(context_error_decl) = 1; + DECL_ASSEMBLER_NAME(context_error_decl); + + attr = tree_cons(NULL, build_const_char_string(14, "context error"), NULL); + attr = tree_cons(get_identifier("error"), attr, NULL); + decl_attributes(&context_error_decl, attr, 0); +} + +static bool context_gate(void) +{ + tree context_attr; + +return true; + + context_attr = lookup_attribute("context", DECL_ATTRIBUTES(current_function_decl)); + return context_attr != NULL_TREE; +} + +static basic_block verify_context_before(gimple_stmt_iterator *gsi, tree context, tree inout, tree error) +{ + gimple stmt; + basic_block cond_bb, join_bb, true_bb; + edge e; + location_t loc; + const char *file; + int line; + size_t len; + tree filename; + + stmt = gsi_stmt(*gsi); + if (gimple_has_location(stmt)) { + loc = gimple_location(stmt); + file = gimple_filename(stmt); + line = gimple_lineno(stmt); + } else { + loc = DECL_SOURCE_LOCATION(current_function_decl); + file = DECL_SOURCE_FILE(current_function_decl); + line = DECL_SOURCE_LINE(current_function_decl); + } + gcc_assert(file); + + // if (context != count) __context_error__(__FILE__, __LINE__); + stmt = gimple_build_cond(NE_EXPR, context, inout, NULL_TREE, NULL_TREE); + gimple_set_location(stmt, loc); + gsi_insert_before(gsi, stmt, GSI_NEW_STMT); + + cond_bb = gsi_bb(*gsi); + gcc_assert(!gsi_end_p(*gsi)); + gcc_assert(stmt == gsi_stmt(*gsi)); + + e = split_block(cond_bb, gsi_stmt(*gsi)); + cond_bb = e->src; + join_bb = e->dest; + e->flags = EDGE_FALSE_VALUE; + e->probability = REG_BR_PROB_BASE; + + true_bb = create_empty_bb(EXIT_BLOCK_PTR_FOR_FN(cfun)->prev_bb); + make_edge(cond_bb, true_bb, EDGE_TRUE_VALUE); + make_edge(true_bb, join_bb, EDGE_FALLTHRU); + + set_immediate_dominator(CDI_DOMINATORS, true_bb, cond_bb); + set_immediate_dominator(CDI_DOMINATORS, join_bb, cond_bb); + + gcc_assert(cond_bb->loop_father == join_bb->loop_father); + add_bb_to_loop(true_bb, cond_bb->loop_father); + + // insert call to builtin_trap or __context_error__ + *gsi = gsi_start_bb(true_bb); + +// stmt = gimple_build_call(builtin_decl_implicit(BUILT_IN_TRAP), 0); + len = strlen(file) + 1; + filename = build_const_char_string(len, file); + filename = build1(ADDR_EXPR, const_ptr_type_node, filename); + stmt = gimple_build_call(error, 2, filename, build_int_cst(NULL_TREE, line)); + gimple_set_location(stmt, loc); + gsi_insert_after(gsi, stmt, GSI_CONTINUE_LINKING); + + *gsi = gsi_start_nondebug_bb(join_bb); + return join_bb; +} + +static void update_context(gimple_stmt_iterator *gsi, tree context, int diff) +{ + gimple assign; + tree op; + + op = fold_build2_loc(UNKNOWN_LOCATION, PLUS_EXPR, integer_type_node, context, build_int_cst(integer_type_node, diff)); + assign = gimple_build_assign(context, op); + gsi_insert_after(gsi, assign, GSI_NEW_STMT); + update_stmt(assign); +} + +static basic_block track_context(basic_block bb, tree context) +{ + gimple_stmt_iterator gsi; + gimple assign; + + // adjust context according to the context information on any call stmt + for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { + gimple stmt = gsi_stmt(gsi); + tree fndecl, context_attr; + tree lock, in, out; + int incount, outcount; + + if (!is_gimple_call(stmt)) + continue; + + fndecl = gimple_call_fndecl(stmt); + if (!fndecl) + continue; + + if (fndecl == context_function_decl) { + unsigned int num_ops = gimple_num_ops(stmt); + int diff = tree_to_shwi(gimple_op(stmt, num_ops - 1)); + + gcc_assert(diff); + update_context(&gsi, context, diff); + continue; + } + + context_attr = lookup_attribute("context", DECL_ATTRIBUTES(fndecl)); + if (!context_attr) + continue; + + gcc_assert(split_context_attribute(TREE_VALUE(context_attr), &lock, &in, &out)); + incount = tree_to_shwi(in); + outcount = tree_to_shwi(out); + bb = verify_context_before(&gsi, context, in, context_error_decl); + update_context(&gsi, context, outcount - incount); + } + + return bb; +} + +static bool bb_any_loop(basic_block bb) +{ + return bb_loop_depth(bb) || (bb->flags & BB_IRREDUCIBLE_LOOP); +} + +static unsigned int context_execute(void) +{ + basic_block bb; + gimple assign; + gimple_stmt_iterator gsi; + tree context_attr, context; + tree lock, in, out; + + loop_optimizer_init(LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS); + gcc_assert(current_loops); + + calculate_dominance_info(CDI_DOMINATORS); + calculate_dominance_info(CDI_POST_DOMINATORS); + + context_attr = lookup_attribute("context", DECL_ATTRIBUTES(current_function_decl)); + if (context_attr) { + gcc_assert(split_context_attribute(TREE_VALUE(context_attr), &lock, &in, &out)); + } else { + in = out = integer_zero_node; + } + + // 1. create local context variable + context = create_tmp_var(integer_type_node, "context"); + add_referenced_var(context); + mark_sym_for_renaming(context); + + // 2. initialize local context variable + gcc_assert(single_succ_p(ENTRY_BLOCK_PTR_FOR_FN(cfun))); + bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); + if (!single_pred_p(bb)) { + gcc_assert(bb_any_loop(bb)); + split_edge(single_succ_edge(ENTRY_BLOCK_PTR_FOR_FN(cfun))); + bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun)); + } + gsi = gsi_start_bb(bb); + assign = gimple_build_assign(context, in); + gsi_insert_before(&gsi, assign, GSI_NEW_STMT); + update_stmt(assign); + + // 3. instrument each BB to track the local context variable + FOR_EACH_BB_FN(bb, cfun) { + bb = track_context(bb, context); + } + + // 4. verify the local context variable against the expected state + if (EDGE_COUNT(EXIT_BLOCK_PTR_FOR_FN(cfun)->preds)) { + gcc_assert(single_pred_p(EXIT_BLOCK_PTR_FOR_FN(cfun))); + gsi = gsi_last_nondebug_bb(single_pred(EXIT_BLOCK_PTR_FOR_FN(cfun))); + verify_context_before(&gsi, context, out, context_error_decl); + } + + free_dominance_info(CDI_DOMINATORS); + free_dominance_info(CDI_POST_DOMINATORS); + loop_optimizer_finalize(); + return 0; +} + +#define PASS_NAME context +#define PROPERTIES_REQUIRED PROP_gimple_leh | PROP_cfg +//#define TODO_FLAGS_START TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts +#define TODO_FLAGS_FINISH TODO_verify_ssa | TODO_verify_stmts | TODO_dump_func | TODO_verify_flow | TODO_update_ssa +#include "gcc-generate-gimple-pass.h" + +__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) +{ + const char * const plugin_name = plugin_info->base_name; + const int argc = plugin_info->argc; + const struct plugin_argument * const argv = plugin_info->argv; + int i; + bool enable_user, enable_context; + + static const struct ggc_root_tab gt_ggc_r_gt_checker[] = { + { + .base = &context_function_decl, + .nelt = 1, + .stride = sizeof(context_function_decl), + .cb = >_ggc_mx_tree_node, + .pchw = >_pch_nx_tree_node + }, + { + .base = &context_error_decl, + .nelt = 1, + .stride = sizeof(context_error_decl), + .cb = >_ggc_mx_tree_node, + .pchw = >_pch_nx_tree_node + }, + LAST_GGC_ROOT_TAB + }; + +// PASS_INFO(context, "ssa", 1, PASS_POS_INSERT_AFTER); + PASS_INFO(context, "phiprop", 1, PASS_POS_INSERT_AFTER); + + if (!plugin_default_version_check(version, &gcc_version)) { + error_gcc_version(version); + return 1; + } + + register_callback(plugin_name, PLUGIN_INFO, NULL, &checker_plugin_info); + + enable_user = false; + enable_context = false; + for (i = 0; i < argc; ++i) { + if (!strcmp(argv[i].key, "user")) { + enable_user = true; + continue; + } + if (!strcmp(argv[i].key, "context")) { + enable_context = true; + continue; + } + error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); + } + + if (enable_user) + register_callback(plugin_name, PLUGIN_PRAGMAS, register_checker_address_spaces, NULL); + if (enable_context) { + register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); + register_callback(plugin_name, PLUGIN_START_UNIT, context_start_unit, NULL); + register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)>_ggc_r_gt_checker); + register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &context_pass_info); + } + + return 0; +} diff --git a/src/colorize_plugin.c b/src/colorize_plugin.c new file mode 100644 index 0000000..c8c62e9 --- /dev/null +++ b/src/colorize_plugin.c @@ -0,0 +1,158 @@ +/* + * Copyright 2012-2017 by PaX Team + * Licensed under the GPL v2 + * + * Note: the choice of the license means that the compilation process is + * NOT 'eligible' as defined by gcc's library exception to the GPL v3, + * but for the kernel it doesn't matter since it doesn't link against + * any of the gcc libraries + * + * gcc plugin to colorize diagnostic output + * + */ + +#include "gcc-common.h" + +__visible int plugin_is_GPL_compatible; + +static struct plugin_info colorize_plugin_info = { + .version = "201602181345", + .help = "color=[never|always|auto]\tdetermine when to colorize\n", +}; + +#define GREEN "\033[32m\033[K" +#define LIGHTGREEN "\033[1;32m\033[K" +#define YELLOW "\033[33m\033[K" +#define LIGHTYELLOW "\033[1;33m\033[K" +#define RED "\033[31m\033[K" +#define LIGHTRED "\033[1;31m\033[K" +#define BLUE "\033[34m\033[K" +#define LIGHTBLUE "\033[1;34m\033[K" +#define BRIGHT "\033[1;m\033[K" +#define NORMAL "\033[m\033[K" + +static diagnostic_starter_fn old_starter; +static diagnostic_finalizer_fn old_finalizer; + +static void start_colorize(diagnostic_context *context, diagnostic_info *diagnostic) +{ + const char *color; + char *newprefix; + + switch (diagnostic->kind) { + case DK_NOTE: + color = LIGHTBLUE; + break; + + case DK_PEDWARN: + case DK_WARNING: + color = LIGHTYELLOW; + break; + + case DK_ERROR: + case DK_FATAL: + case DK_ICE: + case DK_PERMERROR: + case DK_SORRY: + color = LIGHTRED; + break; + + default: + color = NORMAL; + } + + old_starter(context, diagnostic); + if (-1 == asprintf(&newprefix, "%s%s" NORMAL, color, context->printer->prefix)) + return; + pp_destroy_prefix(context->printer); + pp_set_prefix(context->printer, newprefix); +} + +static void finalize_colorize(diagnostic_context *context, diagnostic_info *diagnostic) +{ + old_finalizer(context, diagnostic); +} + +static void colorize_arm(void) +{ + old_starter = diagnostic_starter(global_dc); + old_finalizer = diagnostic_finalizer(global_dc); + + diagnostic_starter(global_dc) = start_colorize; + diagnostic_finalizer(global_dc) = finalize_colorize; +} + +static unsigned int colorize_rearm_execute(void) +{ + if (diagnostic_starter(global_dc) == start_colorize) + return 0; + + colorize_arm(); + return 0; +} + +#define PASS_NAME colorize_rearm +#define NO_GATE +#include "gcc-generate-simple_ipa-pass.h" + +static void colorize_start_unit(void *gcc_data __unused, void *user_data __unused) +{ + colorize_arm(); +} + +static bool should_colorize(void) +{ +#if BUILDING_GCC_VERSION >= 4009 + return false; +#else + char const *t = getenv("TERM"); + + return t && strcmp(t, "dumb") && isatty(STDERR_FILENO); +#endif +} + +__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) +{ + const char * const plugin_name = plugin_info->base_name; + const int argc = plugin_info->argc; + const struct plugin_argument * const argv = plugin_info->argv; + int i; + bool colorize; + + PASS_INFO(colorize_rearm, "*free_lang_data", 1, PASS_POS_INSERT_AFTER); + + if (!plugin_default_version_check(version, &gcc_version)) { + error_gcc_version(version); + return 1; + } + + register_callback(plugin_name, PLUGIN_INFO, NULL, &colorize_plugin_info); + + colorize = getenv("GCC_COLORS") ? should_colorize() : false; + + for (i = 0; i < argc; ++i) { + if (!strcmp(argv[i].key, "color")) { + if (!argv[i].value) { + error(G_("no value supplied for option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); + continue; + } + if (!strcmp(argv[i].value, "always")) + colorize = true; + else if (!strcmp(argv[i].value, "never")) + colorize = false; + else if (!strcmp(argv[i].value, "auto")) + colorize = should_colorize(); + else + error(G_("invalid option argument '-fplugin-arg-%s-%s=%s'"), plugin_name, argv[i].key, argv[i].value); + continue; + } + error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); + } + + if (colorize) { + // TODO: parse GCC_COLORS as used by gcc 4.9+ + register_callback(plugin_name, PLUGIN_START_UNIT, &colorize_start_unit, NULL); + register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &colorize_rearm_pass_info); + } + return 0; +} diff --git a/src/constify_plugin.c b/src/constify_plugin.c new file mode 100644 index 0000000..42f2209 --- /dev/null +++ b/src/constify_plugin.c @@ -0,0 +1,577 @@ +/* + * Copyright 2011 by Emese Revfy + * Copyright 2011-2017 by PaX Team + * Licensed under the GPL v2, or (at your option) v3 + * + * This gcc plugin constifies all structures which contain only function pointers or are explicitly marked for constification. + * + * Homepage: + * http://www.grsecurity.net/~ephox/const_plugin/ + * + * Usage: + * $ gcc -I`gcc -print-file-name=plugin`/include -fPIC -shared -O2 -o constify_plugin.so constify_plugin.c + * $ gcc -fplugin=constify_plugin.so test.c -O2 + */ + +#include "gcc-common.h" + +// unused C type flag in all versions 4.5-6 +#define TYPE_CONSTIFY_VISITED(TYPE) TYPE_LANG_FLAG_4(TYPE) + +__visible int plugin_is_GPL_compatible; + +static bool enabled = true; + +static struct plugin_info const_plugin_info = { + .version = "201607241840", + .help = "disable\tturn off constification\n", +}; + +static struct { + const char *name; + const char *asm_op; +} const_sections[] = { + {".init.rodata", "\t.section\t.init.rodata,\"a\""}, + {".ref.rodata", "\t.section\t.ref.rodata,\"a\""}, + {".devinit.rodata", "\t.section\t.devinit.rodata,\"a\""}, + {".devexit.rodata", "\t.section\t.devexit.rodata,\"a\""}, + {".cpuinit.rodata", "\t.section\t.cpuinit.rodata,\"a\""}, + {".cpuexit.rodata", "\t.section\t.cpuexit.rodata,\"a\""}, + {".meminit.rodata", "\t.section\t.meminit.rodata,\"a\""}, + {".memexit.rodata", "\t.section\t.memexit.rodata,\"a\""}, + {".data..read_only", "\t.section\t.data..read_only,\"a\""}, +}; + +typedef struct { + bool has_fptr_field; + bool has_writable_field; + bool has_do_const_field; + bool has_no_const_field; +} constify_info; + +static const_tree get_field_type(const_tree field) +{ + return strip_array_types(TREE_TYPE(field)); +} + +static bool is_fptr(const_tree field) +{ + const_tree ptr = get_field_type(field); + + if (TREE_CODE(ptr) != POINTER_TYPE) + return false; + + return TREE_CODE(TREE_TYPE(ptr)) == FUNCTION_TYPE; +} + +/* + * determine whether the given structure type meets the requirements for automatic constification, + * including the constification attributes on nested structure types + */ +static void constifiable(const_tree node, constify_info *cinfo) +{ + const_tree field; + + gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); + + // e.g., pointer to structure fields while still constructing the structure type + if (TYPE_FIELDS(node) == NULL_TREE) + return; + + for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) { + const_tree type = get_field_type(field); + enum tree_code code = TREE_CODE(type); + + if (node == type) + continue; + + if (is_fptr(field)) + cinfo->has_fptr_field = true; + else if (code == RECORD_TYPE || code == UNION_TYPE) { + if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) + cinfo->has_do_const_field = true; + else if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type))) + cinfo->has_no_const_field = true; + else + constifiable(type, cinfo); + } else if (!TREE_READONLY(field)) + cinfo->has_writable_field = true; + } +} + +static bool constified(const_tree node) +{ + constify_info cinfo = { + .has_fptr_field = false, + .has_writable_field = false, + .has_do_const_field = false, + .has_no_const_field = false + }; + + gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); + + if (lookup_attribute("no_const", TYPE_ATTRIBUTES(node))) { +// gcc_assert(!TYPE_READONLY(node)); + return false; + } + + if (lookup_attribute("do_const", TYPE_ATTRIBUTES(node))) { + gcc_assert(TYPE_READONLY(node)); + return true; + } + + constifiable(node, &cinfo); + if ((!cinfo.has_fptr_field || cinfo.has_writable_field || cinfo.has_no_const_field) && !cinfo.has_do_const_field) + return false; + + return TYPE_READONLY(node); +} + +static void deconstify_tree(tree node); + +static void deconstify_type(tree type) +{ + tree field; + + gcc_assert(TREE_CODE(type) == RECORD_TYPE || TREE_CODE(type) == UNION_TYPE); + + for (field = TYPE_FIELDS(type); field; field = TREE_CHAIN(field)) { + const_tree fieldtype = get_field_type(field); + + // special case handling of simple ptr-to-same-array-type members + if (TREE_CODE(TREE_TYPE(field)) == POINTER_TYPE) { + tree ptrtype = TREE_TYPE(TREE_TYPE(field)); + + if (TREE_TYPE(TREE_TYPE(field)) == type) + continue; + if (TREE_CODE(ptrtype) != RECORD_TYPE && TREE_CODE(ptrtype) != UNION_TYPE) + continue; + if (!constified(ptrtype)) + continue; + if (TYPE_MAIN_VARIANT(ptrtype) == TYPE_MAIN_VARIANT(type)) + TREE_TYPE(field) = build_pointer_type(build_qualified_type(type, TYPE_QUALS(ptrtype) & ~TYPE_QUAL_CONST)); + continue; + } + if (TREE_CODE(fieldtype) != RECORD_TYPE && TREE_CODE(fieldtype) != UNION_TYPE) + continue; + if (!constified(fieldtype)) + continue; + + deconstify_tree(field); + TREE_READONLY(field) = 0; + } + TYPE_READONLY(type) = 0; + C_TYPE_FIELDS_READONLY(type) = 0; + if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { + TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type)); + TYPE_ATTRIBUTES(type) = remove_attribute("do_const", TYPE_ATTRIBUTES(type)); + } +} + +static void deconstify_tree(tree node) +{ + tree old_type, new_type, field; + + old_type = TREE_TYPE(node); + while (TREE_CODE(old_type) == ARRAY_TYPE && TREE_CODE(TREE_TYPE(old_type)) != ARRAY_TYPE) { + node = TREE_TYPE(node) = copy_node(old_type); + old_type = TREE_TYPE(old_type); + } + + gcc_assert(TREE_CODE(old_type) == RECORD_TYPE || TREE_CODE(old_type) == UNION_TYPE); + gcc_assert(TYPE_READONLY(old_type) && (TYPE_QUALS(old_type) & TYPE_QUAL_CONST)); + + new_type = build_qualified_type(old_type, TYPE_QUALS(old_type) & ~TYPE_QUAL_CONST); + TYPE_FIELDS(new_type) = copy_list(TYPE_FIELDS(new_type)); + for (field = TYPE_FIELDS(new_type); field; field = TREE_CHAIN(field)) + DECL_FIELD_CONTEXT(field) = new_type; + + deconstify_type(new_type); + + TREE_TYPE(node) = new_type; +} + +static tree handle_no_const_attribute(tree *node, tree name, tree args __unused, int flags __unused, bool *no_add_attrs) +{ + tree type; + constify_info cinfo = { + .has_fptr_field = false, + .has_writable_field = false, + .has_do_const_field = false, + .has_no_const_field = false + }; + + *no_add_attrs = true; + if (TREE_CODE(*node) == FUNCTION_DECL) { + error("%qE attribute does not apply to functions (%qF)", name, *node); + return NULL_TREE; + } + + if (TREE_CODE(*node) == PARM_DECL) { + error("%qE attribute does not apply to function parameters (%qD)", name, *node); + return NULL_TREE; + } + + if (TREE_CODE(*node) == VAR_DECL) { + error("%qE attribute does not apply to variables (%qD)", name, *node); + return NULL_TREE; + } + + if (TYPE_P(*node)) { + type = *node; + } else { + if (TREE_CODE(*node) != TYPE_DECL) { + error("%qE attribute does not apply to %qD (%qT)", name, *node, TREE_TYPE(*node)); + return NULL_TREE; + } + type = TREE_TYPE(*node); + } + + if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) { + error("%qE attribute used on %qT applies to struct and union types only", name, type); + return NULL_TREE; + } + + if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(type))) { + error("%qE attribute is already applied to the type %qT", name, type); + return NULL_TREE; + } + + if (TYPE_P(*node)) { + if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) + error("%qE attribute used on type %qT is incompatible with 'do_const'", name, type); + else + *no_add_attrs = false; + return NULL_TREE; + } + + constifiable(type, &cinfo); + if ((cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) || lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { + if (enabled) { + if TYPE_P(*node) + deconstify_type(*node); + else + deconstify_tree(*node); + } + if (TYPE_P(*node)) + TYPE_CONSTIFY_VISITED(*node) = 1; + else + TYPE_CONSTIFY_VISITED(TREE_TYPE(*node)) = 1; + return NULL_TREE; + } + + if (enabled && TYPE_FIELDS(type)) + error("%qE attribute used on type %qT that is not constified", name, type); + return NULL_TREE; +} + +static void constify_type(tree type) +{ + gcc_assert(type == TYPE_MAIN_VARIANT(type)); + TYPE_READONLY(type) = 1; + C_TYPE_FIELDS_READONLY(type) = 1; + TYPE_CONSTIFY_VISITED(type) = 1; +} + +static tree handle_do_const_attribute(tree *node, tree name, tree args __unused, int flags __unused, bool *no_add_attrs) +{ + *no_add_attrs = true; + if (!TYPE_P(*node)) { + error("%qE attribute applies to types only (%qD)", name, *node); + return NULL_TREE; + } + + if (TREE_CODE(*node) != RECORD_TYPE && TREE_CODE(*node) != UNION_TYPE) { + error("%qE attribute used on %qT applies to struct and union types only", name, *node); + return NULL_TREE; + } + + if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(*node))) { + error("%qE attribute used on %qT is already applied to the type", name, *node); + return NULL_TREE; + } + + if (lookup_attribute("no_const", TYPE_ATTRIBUTES(*node))) { + error("%qE attribute used on %qT is incompatible with 'no_const'", name, *node); + return NULL_TREE; + } + + *no_add_attrs = false; + return NULL_TREE; +} + +static struct attribute_spec no_const_attr = { + .name = "no_const", + .min_length = 0, + .max_length = 0, + .decl_required = false, + .type_required = false, + .function_type_required = false, + .handler = handle_no_const_attribute, +#if BUILDING_GCC_VERSION >= 4007 + .affects_type_identity = true +#endif +}; + +static struct attribute_spec do_const_attr = { + .name = "do_const", + .min_length = 0, + .max_length = 0, + .decl_required = false, + .type_required = false, + .function_type_required = false, + .handler = handle_do_const_attribute, +#if BUILDING_GCC_VERSION >= 4007 + .affects_type_identity = true +#endif +}; + +static void register_attributes(void *event_data, void *data) +{ + register_attribute(&no_const_attr); + register_attribute(&do_const_attr); +} + +static void finish_type(void *event_data, void *data __unused) +{ + tree type = (tree)event_data; + constify_info cinfo = { + .has_fptr_field = false, + .has_writable_field = false, + .has_do_const_field = false, + .has_no_const_field = false + }; + + if (type == NULL_TREE || type == error_mark_node) + return; + +#if BUILDING_GCC_VERSION >= 5000 + if (TREE_CODE(type) == ENUMERAL_TYPE) + return; +#endif + + if (TYPE_FIELDS(type) == NULL_TREE || TYPE_CONSTIFY_VISITED(type)) + return; + + constifiable(type, &cinfo); + + if (lookup_attribute("no_const", TYPE_ATTRIBUTES(type))) { + if ((cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) || cinfo.has_do_const_field) { + deconstify_type(type); + TYPE_CONSTIFY_VISITED(type) = 1; + } else + error("'no_const' attribute used on type %qT that is not constified", type); + return; + } + + if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { + if (!cinfo.has_writable_field && !cinfo.has_no_const_field) { + error("'do_const' attribute used on type %qT that is%sconstified", type, cinfo.has_fptr_field ? " " : " not "); + return; + } + constify_type(type); + return; + } + + if (cinfo.has_fptr_field && !cinfo.has_writable_field && !cinfo.has_no_const_field) { + if (lookup_attribute("do_const", TYPE_ATTRIBUTES(type))) { + error("'do_const' attribute used on type %qT that is constified", type); + return; + } + constify_type(type); +// TYPE_ATTRIBUTES(type) = copy_list(TYPE_ATTRIBUTES(type)); +// TYPE_ATTRIBUTES(type) = tree_cons(get_identifier("do_const"), NULL_TREE, TYPE_ATTRIBUTES(type)); + return; + } + + deconstify_type(type); + TYPE_CONSTIFY_VISITED(type) = 1; +} + +static bool is_constified_var(varpool_node_ptr node) +{ + tree var = NODE_DECL(node); + tree type = TREE_TYPE(var); + + if (node->alias) + return false; + + if (DECL_EXTERNAL(var)) + return false; + + // XXX handle more complex nesting of arrays/structs + if (TREE_CODE(type) == ARRAY_TYPE) + type = TREE_TYPE(type); + + if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) + return false; + + if (!TYPE_READONLY(type) || !C_TYPE_FIELDS_READONLY(type)) + return false; + + if (!TYPE_CONSTIFY_VISITED(type)) + return false; + + return true; +} + +static void check_section_mismatch(varpool_node_ptr node) +{ + tree var, section; + size_t i; + const char *name; + + var = NODE_DECL(node); + name = get_decl_section_name(var); + section = lookup_attribute("section", DECL_ATTRIBUTES(var)); + if (!section) { + if (name) { + fprintf(stderr, "DECL_SECTION [%s] ", name); + dump_varpool_node(stderr, node); + gcc_unreachable(); + } + return; + } else + gcc_assert(name); + +//fprintf(stderr, "SECTIONAME: [%s] ", get_decl_section_name(var)); +//debug_tree(var); + + gcc_assert(!TREE_CHAIN(section)); + gcc_assert(TREE_VALUE(section)); + + section = TREE_VALUE(TREE_VALUE(section)); + gcc_assert(!strcmp(TREE_STRING_POINTER(section), name)); +//debug_tree(section); + + for (i = 0; i < ARRAY_SIZE(const_sections); i++) + if (!strcmp(const_sections[i].name, name)) + return; + + error_at(DECL_SOURCE_LOCATION(var), "constified variable %qD placed into writable section %E", var, section); +} + +// this works around a gcc bug/feature where uninitialized globals +// are moved into the .bss section regardless of any constification +// see gcc/varasm.c:bss_initializer_p() +static void fix_initializer(varpool_node_ptr node) +{ + tree var = NODE_DECL(node); + tree type = TREE_TYPE(var); + + if (DECL_INITIAL(var)) + return; + + DECL_INITIAL(var) = build_constructor(type, NULL); +// inform(DECL_SOURCE_LOCATION(var), "constified variable %qE moved into .rodata", var); +} + +static void check_global_variables(void *event_data __unused, void *data __unused) +{ + varpool_node_ptr node; + + FOR_EACH_VARIABLE(node) { + if (!is_constified_var(node)) + continue; + + check_section_mismatch(node); + fix_initializer(node); + } +} + +static unsigned int check_local_variables_execute(void) +{ + unsigned int ret = 0; + tree var; + + unsigned int i; + + FOR_EACH_LOCAL_DECL(cfun, i, var) { + tree type = TREE_TYPE(var); + + gcc_assert(DECL_P(var)); + if (is_global_var(var)) + continue; + + if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE) + continue; + + if (!TYPE_READONLY(type) || !C_TYPE_FIELDS_READONLY(type)) + continue; + + if (!TYPE_CONSTIFY_VISITED(type)) + continue; + + error_at(DECL_SOURCE_LOCATION(var), "constified variable %qE cannot be local", var); + ret = 1; + } + return ret; +} + +#define PASS_NAME check_local_variables +#define NO_GATE +#include "gcc-generate-gimple-pass.h" + +static unsigned int (*old_section_type_flags)(tree decl, const char *name, int reloc); + +static unsigned int constify_section_type_flags(tree decl, const char *name, int reloc) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(const_sections); i++) + if (!strcmp(const_sections[i].name, name)) + return 0; + + return old_section_type_flags(decl, name, reloc); +} + +static void constify_start_unit(void *gcc_data __unused, void *user_data __unused) +{ +// size_t i; + +// for (i = 0; i < ARRAY_SIZE(const_sections); i++) +// const_sections[i].section = get_unnamed_section(0, output_section_asm_op, const_sections[i].asm_op); +// const_sections[i].section = get_section(const_sections[i].name, 0, NULL); + + old_section_type_flags = targetm.section_type_flags; + targetm.section_type_flags = constify_section_type_flags; +} + +__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) +{ + const char * const plugin_name = plugin_info->base_name; + const int argc = plugin_info->argc; + const struct plugin_argument * const argv = plugin_info->argv; + int i; + + PASS_INFO(check_local_variables, "ssa", 1, PASS_POS_INSERT_BEFORE); + + if (!plugin_default_version_check(version, &gcc_version)) { + error_gcc_version(version); + return 1; + } + + for (i = 0; i < argc; ++i) { + if (!(strcmp(argv[i].key, "disable"))) { + enabled = false; + continue; + } + error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); + } + + if (strncmp(lang_hooks.name, "GNU C", 5) && !strncmp(lang_hooks.name, "GNU C+", 6)) { + inform(UNKNOWN_LOCATION, G_("%s supports C only, not %s"), plugin_name, lang_hooks.name); + enabled = false; + } + + register_callback(plugin_name, PLUGIN_INFO, NULL, &const_plugin_info); + if (enabled) { + register_callback(plugin_name, PLUGIN_ALL_IPA_PASSES_START, check_global_variables, NULL); + register_callback(plugin_name, PLUGIN_FINISH_TYPE, finish_type, NULL); + register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &check_local_variables_pass_info); + register_callback(plugin_name, PLUGIN_START_UNIT, constify_start_unit, NULL); + } + register_callback(plugin_name, PLUGIN_ATTRIBUTES, register_attributes, NULL); + + return 0; +} diff --git a/src/cyc_complexity_plugin.c b/src/cyc_complexity_plugin.c new file mode 100644 index 0000000..f618028 --- /dev/null +++ b/src/cyc_complexity_plugin.c @@ -0,0 +1,69 @@ +/* + * Copyright 2011-2017 by Emese Revfy + * Licensed under the GPL v2, or (at your option) v3 + * + * Homepage: + * https://github.com/ephox-gcc-plugins/cyclomatic_complexity + * + * http://en.wikipedia.org/wiki/Cyclomatic_complexity + * The complexity M is then defined as: + * M = E - N + 2P + * where + * + * E = the number of edges of the graph + * N = the number of nodes of the graph + * P = the number of connected components (exit nodes). + * + * Usage (4.5 - 5): + * $ make clean; make run + */ + +#include "gcc-common.h" + +__visible int plugin_is_GPL_compatible; + +static struct plugin_info cyc_complexity_plugin_info = { + .version = "20160225", + .help = "Cyclomatic Complexity\n", +}; + +static unsigned int cyc_complexity_execute(void) +{ + int complexity; + expanded_location xloc; + + /* M = E - N + 2P */ + complexity = n_edges_for_fn(cfun) - n_basic_blocks_for_fn(cfun) + 2; + + xloc = expand_location(DECL_SOURCE_LOCATION(current_function_decl)); + fprintf(stderr, "Cyclomatic Complexity %d %s:%s\n", complexity, + xloc.file, DECL_NAME_POINTER(current_function_decl)); + + return 0; +} + +#define PASS_NAME cyc_complexity + +#define NO_GATE +#define TODO_FLAGS_FINISH TODO_dump_func + +#include "gcc-generate-gimple-pass.h" + +__visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) +{ + const char * const plugin_name = plugin_info->base_name; + + PASS_INFO(cyc_complexity, "ssa", 1, PASS_POS_INSERT_AFTER); + + if (!plugin_default_version_check(version, &gcc_version)) { + error_gcc_version(version); + return 1; + } + + register_callback(plugin_name, PLUGIN_INFO, NULL, + &cyc_complexity_plugin_info); + register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, + &cyc_complexity_pass_info); + + return 0; +} diff --git a/src/gcc-common.h b/src/gcc-common.h old mode 100755 new mode 100644 index 12262c0..8099dd1 --- a/src/gcc-common.h +++ b/src/gcc-common.h @@ -21,14 +21,22 @@ #include "rtl.h" #include "tm_p.h" #include "flags.h" +//#include "insn-attr.h" +//#include "insn-config.h" +//#include "insn-flags.h" #include "hard-reg-set.h" +//#include "recog.h" #include "output.h" #include "except.h" #include "function.h" #include "toplev.h" +#if BUILDING_GCC_VERSION >= 5000 +#include "expr.h" +#endif #include "basic-block.h" #include "intl.h" #include "ggc.h" +//#include "regs.h" #include "timevar.h" #include "params.h" @@ -43,12 +51,18 @@ #include "memmodel.h" #endif #include "emit-rtl.h" +//#include "reload.h" +//#include "ira.h" +//#include "dwarf2asm.h" #include "debug.h" #include "target.h" #include "langhooks.h" #include "cfgloop.h" +//#include "hosthooks.h" #include "cgraph.h" #include "opts.h" +//#include "coverage.h" +//#include "value-prof.h" #if BUILDING_GCC_VERSION == 4005 #include @@ -60,6 +74,8 @@ #endif #if BUILDING_GCC_VERSION >= 4006 +//#include "c-tree.h" +//#include "cp/cp-tree.h" #include "c-family/c-common.h" #else #include "c-common.h" @@ -78,8 +94,13 @@ #endif #include "diagnostic.h" +//#include "tree-diagnostic.h" #include "tree-dump.h" #include "tree-pass.h" +#if BUILDING_GCC_VERSION >= 4009 +#include "pass_manager.h" +#endif +//#include "df.h" #include "predict.h" #include "ipa-utils.h" @@ -90,6 +111,7 @@ #include "internal-fn.h" #include "gimple-expr.h" #include "gimple-fold.h" +//#include "diagnostic-color.h" #include "context.h" #include "tree-ssa-alias.h" #include "tree-ssa.h" @@ -115,28 +137,34 @@ #include "ssa-iterators.h" #endif +//#include "lto/lto.h" +#if BUILDING_GCC_VERSION >= 4007 +//#include "data-streamer.h" +#else +//#include "lto-streamer.h" +#endif +//#include "lto-compress.h" #if BUILDING_GCC_VERSION >= 5000 +//#include "lto-section-names.h" #include "builtins.h" #endif -/* #include "expr.h" where are you... */ -extern rtx emit_move_insn(rtx x, rtx y); - /* missing from basic_block.h... */ -extern void debug_dominance_info(enum cdi_direction dir); -extern void debug_dominance_tree(enum cdi_direction dir, basic_block root); +void debug_dominance_info(enum cdi_direction dir); +void debug_dominance_tree(enum cdi_direction dir, basic_block root); #if BUILDING_GCC_VERSION == 4006 -extern void debug_gimple_stmt(gimple); -extern void debug_gimple_seq(gimple_seq); -extern void print_gimple_seq(FILE *, gimple_seq, int, int); -extern void print_gimple_stmt(FILE *, gimple, int, int); -extern void print_gimple_expr(FILE *, gimple, int, int); -extern void dump_gimple_stmt(pretty_printer *, gimple, int, int); +void debug_gimple_stmt(gimple); +void debug_gimple_seq(gimple_seq); +void print_gimple_seq(FILE *, gimple_seq, int, int); +void print_gimple_stmt(FILE *, gimple, int, int); +void print_gimple_expr(FILE *, gimple, int, int); +void dump_gimple_stmt(pretty_printer *, gimple, int, int); #endif -#define __unused __attribute__((__unused__)) +#define __unused __attribute__((unused)) #define __visible __attribute__((visibility("default"))) +#define __weak __attribute__((weak)) #define DECL_NAME_POINTER(node) IDENTIFIER_POINTER(DECL_NAME(node)) #define DECL_NAME_LENGTH(node) IDENTIFIER_LENGTH(DECL_NAME(node)) @@ -146,6 +174,36 @@ extern void dump_gimple_stmt(pretty_printer *, gimple, int, int); /* should come from c-tree.h if only it were installed for gcc 4.5... */ #define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1(TYPE) +static inline tree build_const_char_string(int len, const char *str) +{ + tree cstr, elem, index, type; + + cstr = build_string(len, str); + elem = build_type_variant(char_type_node, 1, 0); + index = build_index_type(size_int(len - 1)); + type = build_array_type(elem, index); + TREE_TYPE(cstr) = type; + TREE_CONSTANT(cstr) = 1; + TREE_READONLY(cstr) = 1; + TREE_STATIC(cstr) = 1; + return cstr; +} + +static inline void error_gcc_version(struct plugin_gcc_version *version) +{ + error(G_("incompatible gcc/plugin versions: need %s %s %s %s but have %s %s %s %s"), + gcc_version.basever, gcc_version.datestamp, gcc_version.devphase, gcc_version.revision, + version->basever, version->datestamp, version->devphase, version->revision); +} + +#define PASS_INFO(NAME, REF, ID, POS) \ +struct register_pass_info NAME##_pass_info = { \ + .pass = make_##NAME##_pass(), \ + .reference_pass_name = REF, \ + .ref_pass_instance_number = ID, \ + .pos_op = POS, \ +} + #if BUILDING_GCC_VERSION == 4005 #define FOR_EACH_LOCAL_DECL(FUN, I, D) \ for (tree vars = (FUN)->local_decls, (I) = 0; \ @@ -172,6 +230,7 @@ static inline bool gimple_call_builtin_p(gimple stmt, enum built_in_function cod fndecl = gimple_call_fndecl(stmt); if (!fndecl || DECL_BUILT_IN_CLASS(fndecl) != BUILT_IN_NORMAL) return false; +// print_node(stderr, "pax", fndecl, 4); return DECL_FUNCTION_CODE(fndecl) == code; } @@ -345,6 +404,23 @@ static inline bool gimple_store_p(gimple gs) static inline void gimple_init_singleton(gimple g __unused) { } + +enum expand_modifier { + EXPAND_NORMAL = 0, + EXPAND_STACK_PARM, + EXPAND_SUM, + EXPAND_CONST_ADDRESS, + EXPAND_INITIALIZER, + EXPAND_WRITE, + EXPAND_MEMORY +}; + +rtx expand_expr_real(tree, rtx, enum machine_mode, enum expand_modifier, rtx *); + +static inline rtx expand_expr(tree exp, rtx target, enum machine_mode mode, enum expand_modifier modifier) +{ + return expand_expr_real(exp, target, mode, modifier, NULL); +} #endif #if BUILDING_GCC_VERSION == 4007 || BUILDING_GCC_VERSION == 4008 @@ -518,6 +594,28 @@ static inline const greturn *as_a_const_greturn(const_gimple stmt) #define create_var_ann(var) #define TODO_dump_func 0 #define TODO_dump_cgraph 0 + +#define VEC(T, A) vec +#define VEC_safe_push(T, A, V, O) vec_safe_push((V), (O)); +#endif + +#if BUILDING_GCC_VERSION == 4008 || BUILDING_GCC_VERSION == 4009 +enum expand_modifier { + EXPAND_NORMAL = 0, + EXPAND_STACK_PARM, + EXPAND_SUM, + EXPAND_CONST_ADDRESS, + EXPAND_INITIALIZER, + EXPAND_WRITE, + EXPAND_MEMORY +}; + +rtx expand_expr_real(tree, rtx, enum machine_mode, enum expand_modifier, rtx *, bool); + +static inline rtx expand_expr(tree exp, rtx target, enum machine_mode mode, enum expand_modifier modifier) +{ + return expand_expr_real(exp, target, mode, modifier, NULL, false); +} #endif #if BUILDING_GCC_VERSION <= 4009 @@ -527,6 +625,8 @@ static inline const greturn *as_a_const_greturn(const_gimple stmt) #define section_name_prefix LTO_SECTION_NAME_PREFIX #define fatal_error(loc, gmsgid, ...) fatal_error((gmsgid), __VA_ARGS__) +rtx emit_move_insn(rtx x, rtx y); + typedef struct rtx_def rtx_insn; static inline const char *get_decl_section_name(const_tree decl) @@ -643,6 +743,11 @@ static inline const greturn *as_a_const_greturn(const_gimple stmt) #define NODE_DECL(node) (node)->decl #define cgraph_node_name(node) (node)->name() #define NODE_IMPLICIT_ALIAS(node) (node)->cpp_implicit_alias + +static inline opt_pass *get_pass_for_id(int id) +{ + return g->get_passes()->get_pass_for_id(id); +} #endif #if BUILDING_GCC_VERSION >= 5000 && BUILDING_GCC_VERSION < 6000 @@ -661,6 +766,8 @@ inline bool is_a_helper::test(const_gimple gs) #define TODO_verify_stmts TODO_verify_il #define TODO_verify_rtl_sharing TODO_verify_il +//#define TREE_INT_CST_HIGH(NODE) ({ TREE_INT_CST_EXT_NUNITS(NODE) > 1 ? (unsigned HOST_WIDE_INT)TREE_INT_CST_ELT(NODE, 1) : 0; }) + #define INSN_DELETED_P(insn) (insn)->deleted() static inline const char *get_decl_section_name(const_tree decl) @@ -908,6 +1015,11 @@ static inline void debug_gimple_stmt(const_gimple s) #define debug_gimple_stmt(s) debug_gimple_stmt(CONST_CAST_GIMPLE(s)) #endif +#if BUILDING_GCC_VERSION < 7001 +#define SET_DECL_ALIGN(n, a) ({ DECL_ALIGN(n) = (a); }) +#define SET_DECL_MODE(n, m) ({ DECL_MODE(n) = (m); }) +#endif + #if BUILDING_GCC_VERSION >= 7000 #define get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep, keep_aligning) \ get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep) diff --git a/src/gcc-generate-gimple-pass.h b/src/gcc-generate-gimple-pass.h old mode 100755 new mode 100644 index 526c3c7..831300b --- a/src/gcc-generate-gimple-pass.h +++ b/src/gcc-generate-gimple-pass.h @@ -119,7 +119,7 @@ public: #endif #endif - virtual opt_pass * clone () { return new _PASS_NAME_PASS(); } + virtual opt_pass *clone() { return new _PASS_NAME_PASS(); } #ifndef NO_EXECUTE #if BUILDING_GCC_VERSION >= 5000 @@ -136,6 +136,7 @@ opt_pass *_MAKE_PASS_NAME_PASS(void) return new _PASS_NAME_PASS(); } #else +struct opt_pass *_MAKE_PASS_NAME_PASS(void); struct opt_pass *_MAKE_PASS_NAME_PASS(void) { return &_PASS_NAME_PASS.pass; diff --git a/src/gcc-generate-ipa-pass.h b/src/gcc-generate-ipa-pass.h old mode 100755 new mode 100644 index 9bd926e..93d8743 --- a/src/gcc-generate-ipa-pass.h +++ b/src/gcc-generate-ipa-pass.h @@ -225,6 +225,7 @@ opt_pass *_MAKE_PASS_NAME_PASS(void) return new _PASS_NAME_PASS(); } #else +struct opt_pass *_MAKE_PASS_NAME_PASS(void); struct opt_pass *_MAKE_PASS_NAME_PASS(void) { return &_PASS_NAME_PASS.pass; diff --git a/src/gcc-generate-rtl-pass.h b/src/gcc-generate-rtl-pass.h old mode 100755 new mode 100644 index 1dc67a5..e858d67 --- a/src/gcc-generate-rtl-pass.h +++ b/src/gcc-generate-rtl-pass.h @@ -136,6 +136,7 @@ opt_pass *_MAKE_PASS_NAME_PASS(void) return new _PASS_NAME_PASS(); } #else +struct opt_pass *_MAKE_PASS_NAME_PASS(void); struct opt_pass *_MAKE_PASS_NAME_PASS(void) { return &_PASS_NAME_PASS.pass; diff --git a/src/gcc-generate-simple_ipa-pass.h b/src/gcc-generate-simple_ipa-pass.h old mode 100755 new mode 100644 index a27e2b3..d5ed4e2 --- a/src/gcc-generate-simple_ipa-pass.h +++ b/src/gcc-generate-simple_ipa-pass.h @@ -136,6 +136,7 @@ opt_pass *_MAKE_PASS_NAME_PASS(void) return new _PASS_NAME_PASS(); } #else +struct opt_pass *_MAKE_PASS_NAME_PASS(void); struct opt_pass *_MAKE_PASS_NAME_PASS(void) { return &_PASS_NAME_PASS.pass; diff --git a/src/gen-random-seed.sh b/src/gen-random-seed.sh new file mode 100644 index 0000000..7514850 --- /dev/null +++ b/src/gen-random-seed.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ ! -f "$1" ]; then + SEED=`od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n'` + echo "const char *randstruct_seed = \"$SEED\";" > "$1" + HASH=`echo -n "$SEED" | sha256sum | cut -d" " -f1 | tr -d ' \n'` + echo "#define RANDSTRUCT_HASHED_SEED \"$HASH\"" > "$2" +fi diff --git a/src/include/ada/gcc-interface/ada-tree.def b/src/include/ada/gcc-interface/ada-tree.def new file mode 100644 index 0000000..93967b5 --- /dev/null +++ b/src/include/ada/gcc-interface/ada-tree.def @@ -0,0 +1,74 @@ +/**************************************************************************** + * * + * GNAT COMPILER COMPONENTS * + * * + * GNAT-SPECIFIC GCC TREE CODES * + * * + * Specification * + * * + * Copyright (C) 1992-2009, Free Software Foundation, Inc. * + * * + * GNAT is free software; you can redistribute it and/or modify it under * + * terms of the GNU General Public License as published by the Free Soft- * + * ware Foundation; either version 3, or (at your option) any later ver- * + * sion. GNAT is distributed in the hope that it will be useful, but WITH- * + * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * + * for more details. You should have received a copy of the GNU General * + * Public License along with GCC; see the file COPYING3. If not see * + * . * + * * + * GNAT was originally developed by the GNAT team at New York University. * + * Extensive contributions were provided by Ada Core Technologies Inc. * + * * + ****************************************************************************/ + +/* A type that is an unconstrained array. This node is never passed to GCC. + TREE_TYPE is the type of the fat pointer and TYPE_OBJECT_RECORD_TYPE is + the type of a record containing the template and data. */ +DEFTREECODE (UNCONSTRAINED_ARRAY_TYPE, "unconstrained_array_type", tcc_type, 0) + +/* A reference to an unconstrained array. This node only exists as an + intermediate node during the translation of a GNAT tree to a GCC tree; + it is never passed to GCC. The only field used is operand 0, which + is the fat pointer object. */ +DEFTREECODE (UNCONSTRAINED_ARRAY_REF, "unconstrained_array_ref", + tcc_reference, 1) + +/* An expression that returns an RTL suitable for its type. Operand 0 + is an expression to be evaluated for side effects only. */ +DEFTREECODE (NULL_EXPR, "null_expr", tcc_expression, 1) + +/* Same as PLUS_EXPR, except that no modulo reduction is applied. + This is used for loops and never shows up in the tree. */ +DEFTREECODE (PLUS_NOMOD_EXPR, "plus_nomod_expr", tcc_binary, 2) + +/* Same as MINUS_EXPR, except that no modulo reduction is applied. + This is used for loops and never shows up in the tree. */ +DEFTREECODE (MINUS_NOMOD_EXPR, "minus_nomod_expr", tcc_binary, 2) + +/* Same as ADDR_EXPR, except that if the operand represents a bit field, + return the address of the byte containing the bit. This is used + for the Address attribute and never shows up in the tree. */ +DEFTREECODE (ATTR_ADDR_EXPR, "attr_addr_expr", tcc_reference, 1) + +/* Here are the tree codes for the statement types known to Ada. These + must be at the end of this file to allow IS_ADA_STMT to work. */ + +/* This is how record_code_position and insert_code_for work. The former + makes this tree node, whose operand is a statement. The latter inserts + the actual statements into this node. Gimplification consists of + just returning the inner statement. */ +DEFTREECODE (STMT_STMT, "stmt_stmt", tcc_statement, 1) + +/* A loop. LOOP_STMT_COND is the test to exit the loop. LOOP_STMT_UPDATE + is the statement to update the loop iteration variable at the continue + point. LOOP_STMT_BODY are the statements in the body of the loop. And + LOOP_STMT_LABEL points to the LABEL_DECL of the end label of the loop. */ +DEFTREECODE (LOOP_STMT, "loop_stmt", tcc_statement, 4) + +/* Conditionally exit a loop. EXIT_STMT_COND is the condition, which, if + true, will cause the loop to be exited. If no condition is specified, + the loop is unconditionally exited. EXIT_STMT_LABEL is the end label + corresponding to the loop to exit. */ +DEFTREECODE (EXIT_STMT, "exit_stmt", tcc_statement, 2) diff --git a/src/include/alias.h b/src/include/alias.h new file mode 100644 index 0000000..af739a8 --- /dev/null +++ b/src/include/alias.h @@ -0,0 +1,51 @@ +/* Exported functions from alias.c + Copyright (C) 2004-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_ALIAS_H +#define GCC_ALIAS_H + +/* The type of an alias set. Code currently assumes that variables of + this type can take the values 0 (the alias set which aliases + everything) and -1 (sometimes indicating that the alias set is + unknown, sometimes indicating a memory barrier) and -2 (indicating + that the alias set should be set to a unique value but has not been + set yet). */ +typedef int alias_set_type; + +extern alias_set_type new_alias_set (void); +extern alias_set_type get_alias_set (tree); +extern alias_set_type get_deref_alias_set (tree); +extern alias_set_type get_varargs_alias_set (void); +extern alias_set_type get_frame_alias_set (void); +extern bool component_uses_parent_alias_set (const_tree); +extern bool alias_set_subset_of (alias_set_type, alias_set_type); +extern void record_alias_subset (alias_set_type, alias_set_type); +extern void record_component_aliases (tree); +extern int alias_sets_conflict_p (alias_set_type, alias_set_type); +extern int alias_sets_must_conflict_p (alias_set_type, alias_set_type); +extern int objects_must_conflict_p (tree, tree); +extern int nonoverlapping_memrefs_p (const_rtx, const_rtx, bool); + +/* This alias set can be used to force a memory to conflict with all + other memories, creating a barrier across which no memory reference + can move. Note that there are other legacy ways to create such + memory barriers, including an address of SCRATCH. */ +#define ALIAS_SET_MEMORY_BARRIER ((alias_set_type) -1) + +#endif /* GCC_ALIAS_H */ diff --git a/src/include/all-tree.def b/src/include/all-tree.def new file mode 100644 index 0000000..8a2da69 --- /dev/null +++ b/src/include/all-tree.def @@ -0,0 +1,7 @@ +#include "tree.def" +END_OF_BASE_TREE_CODES +#include "c-family/c-common.def" +#include "ada/gcc-interface/ada-tree.def" +#include "cp/cp-tree.def" +#include "java/java-tree.def" +#include "objc/objc-tree.def" diff --git a/src/include/alloc-pool.h b/src/include/alloc-pool.h new file mode 100644 index 0000000..1946125 --- /dev/null +++ b/src/include/alloc-pool.h @@ -0,0 +1,66 @@ +/* Functions to support a pool of allocatable objects + Copyright (C) 1997-2013 Free Software Foundation, Inc. + Contributed by Daniel Berlin + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ +#ifndef ALLOC_POOL_H +#define ALLOC_POOL_H + +typedef unsigned long ALLOC_POOL_ID_TYPE; + +typedef struct alloc_pool_list_def +{ + struct alloc_pool_list_def *next; +} + *alloc_pool_list; + +typedef struct alloc_pool_def +{ + const char *name; +#ifdef ENABLE_CHECKING + ALLOC_POOL_ID_TYPE id; +#endif + size_t elts_per_block; + + /* These are the elements that have been allocated at least once and freed. */ + alloc_pool_list returned_free_list; + + /* These are the elements that have not yet been allocated out of + the last block obtained from XNEWVEC. */ + char* virgin_free_list; + + /* The number of elements in the virgin_free_list that can be + allocated before needing another block. */ + size_t virgin_elts_remaining; + + size_t elts_allocated; + size_t elts_free; + size_t blocks_allocated; + alloc_pool_list block_list; + size_t block_size; + size_t elt_size; +} + *alloc_pool; + +extern alloc_pool create_alloc_pool (const char *, size_t, size_t); +extern void free_alloc_pool (alloc_pool); +extern void empty_alloc_pool (alloc_pool); +extern void free_alloc_pool_if_empty (alloc_pool *); +extern void *pool_alloc (alloc_pool) ATTRIBUTE_MALLOC; +extern void pool_free (alloc_pool, void *); +extern void dump_alloc_pool_statistics (void); +#endif diff --git a/src/include/ansidecl.h b/src/include/ansidecl.h new file mode 100644 index 0000000..40f4a5f --- /dev/null +++ b/src/include/ansidecl.h @@ -0,0 +1,441 @@ +/* ANSI and traditional C compatability macros + Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, + 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* ANSI and traditional C compatibility macros + + ANSI C is assumed if __STDC__ is #defined. + + Macro ANSI C definition Traditional C definition + ----- ---- - ---------- ----------- - ---------- + ANSI_PROTOTYPES 1 not defined + PTR `void *' `char *' + PTRCONST `void *const' `char *' + LONG_DOUBLE `long double' `double' + const not defined `' + volatile not defined `' + signed not defined `' + VA_START(ap, var) va_start(ap, var) va_start(ap) + + Note that it is safe to write "void foo();" indicating a function + with no return value, in all K+R compilers we have been able to test. + + For declaring functions with prototypes, we also provide these: + + PARAMS ((prototype)) + -- for functions which take a fixed number of arguments. Use this + when declaring the function. When defining the function, write a + K+R style argument list. For example: + + char *strcpy PARAMS ((char *dest, char *source)); + ... + char * + strcpy (dest, source) + char *dest; + char *source; + { ... } + + + VPARAMS ((prototype, ...)) + -- for functions which take a variable number of arguments. Use + PARAMS to declare the function, VPARAMS to define it. For example: + + int printf PARAMS ((const char *format, ...)); + ... + int + printf VPARAMS ((const char *format, ...)) + { + ... + } + + For writing functions which take variable numbers of arguments, we + also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These + hide the differences between K+R and C89 more + thoroughly than the simple VA_START() macro mentioned above. + + VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end. + Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls + corresponding to the list of fixed arguments. Then use va_arg + normally to get the variable arguments, or pass your va_list object + around. You do not declare the va_list yourself; VA_OPEN does it + for you. + + Here is a complete example: + + int + printf VPARAMS ((const char *format, ...)) + { + int result; + + VA_OPEN (ap, format); + VA_FIXEDARG (ap, const char *, format); + + result = vfprintf (stdout, format, ap); + VA_CLOSE (ap); + + return result; + } + + + You can declare variables either before or after the VA_OPEN, + VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning + and end of a block. They must appear at the same nesting level, + and any variables declared after VA_OPEN go out of scope at + VA_CLOSE. Unfortunately, with a K+R compiler, that includes the + argument list. You can have multiple instances of VA_OPEN/VA_CLOSE + pairs in a single function in case you need to traverse the + argument list more than once. + + For ease of writing code which uses GCC extensions but needs to be + portable to other compilers, we provide the GCC_VERSION macro that + simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various + wrappers around __attribute__. Also, __extension__ will be #defined + to nothing if it doesn't work. See below. + + This header also defines a lot of obsolete macros: + CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID, + AND, DOTS, NOARGS. Don't use them. */ + +#ifndef _ANSIDECL_H +#define _ANSIDECL_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Every source file includes this file, + so they will all get the switch for lint. */ +/* LINTLIBRARY */ + +/* Using MACRO(x,y) in cpp #if conditionals does not work with some + older preprocessors. Thus we can't define something like this: + +#define HAVE_GCC_VERSION(MAJOR, MINOR) \ + (__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR))) + +and then test "#if HAVE_GCC_VERSION(2,7)". + +So instead we use the macro below and test it against specific values. */ + +/* This macro simplifies testing whether we are using gcc, and if it + is of a particular minimum version. (Both major & minor numbers are + significant.) This macro will evaluate to 0 if we are not using + gcc at all. */ +#ifndef GCC_VERSION +#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__) +#endif /* GCC_VERSION */ + +#if defined (__STDC__) || defined(__cplusplus) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32) +/* All known AIX compilers implement these things (but don't always + define __STDC__). The RISC/OS MIPS compiler defines these things + in SVR4 mode, but does not define __STDC__. */ +/* eraxxon@alumni.rice.edu: The Compaq C++ compiler, unlike many other + C++ compilers, does not define __STDC__, though it acts as if this + was so. (Verified versions: 5.7, 6.2, 6.3, 6.5) */ + +#define ANSI_PROTOTYPES 1 +#define PTR void * +#define PTRCONST void *const +#define LONG_DOUBLE long double + +/* PARAMS is often defined elsewhere (e.g. by libintl.h), so wrap it in + a #ifndef. */ +#ifndef PARAMS +#define PARAMS(ARGS) ARGS +#endif + +#define VPARAMS(ARGS) ARGS +#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR) + +/* variadic function helper macros */ +/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's + use without inhibiting further decls and without declaring an + actual variable. */ +#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy +#define VA_CLOSE(AP) } va_end(AP); } +#define VA_FIXEDARG(AP, T, N) struct Qdmy + +#undef const +#undef volatile +#undef signed + +/* inline requires special treatment; it's in C99, and GCC >=2.7 supports + it too, but it's not in C89. */ +#undef inline +#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) || (defined(__SUNPRO_C) && defined(__C99FEATURES__)) +/* it's a keyword */ +#else +# if GCC_VERSION >= 2007 +# define inline __inline__ /* __inline__ prevents -pedantic warnings */ +# else +# define inline /* nothing */ +# endif +#endif + +/* These are obsolete. Do not use. */ +#ifndef IN_GCC +#define CONST const +#define VOLATILE volatile +#define SIGNED signed + +#define PROTO(type, name, arglist) type name arglist +#define EXFUN(name, proto) name proto +#define DEFUN(name, arglist, args) name(args) +#define DEFUN_VOID(name) name(void) +#define AND , +#define DOTS , ... +#define NOARGS void +#endif /* ! IN_GCC */ + +#else /* Not ANSI C. */ + +#undef ANSI_PROTOTYPES +#define PTR char * +#define PTRCONST PTR +#define LONG_DOUBLE double + +#define PARAMS(args) () +#define VPARAMS(args) (va_alist) va_dcl +#define VA_START(va_list, var) va_start(va_list) + +#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy +#define VA_CLOSE(AP) } va_end(AP); } +#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE) + +/* some systems define these in header files for non-ansi mode */ +#undef const +#undef volatile +#undef signed +#undef inline +#define const +#define volatile +#define signed +#define inline + +#ifndef IN_GCC +#define CONST +#define VOLATILE +#define SIGNED + +#define PROTO(type, name, arglist) type name () +#define EXFUN(name, proto) name() +#define DEFUN(name, arglist, args) name arglist args; +#define DEFUN_VOID(name) name() +#define AND ; +#define DOTS +#define NOARGS +#endif /* ! IN_GCC */ + +#endif /* ANSI C. */ + +/* Define macros for some gcc attributes. This permits us to use the + macros freely, and know that they will come into play for the + version of gcc in which they are supported. */ + +#if (GCC_VERSION < 2007) +# define __attribute__(x) +#endif + +/* Attribute __malloc__ on functions was valid as of gcc 2.96. */ +#ifndef ATTRIBUTE_MALLOC +# if (GCC_VERSION >= 2096) +# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__)) +# else +# define ATTRIBUTE_MALLOC +# endif /* GNUC >= 2.96 */ +#endif /* ATTRIBUTE_MALLOC */ + +/* Attributes on labels were valid as of gcc 2.93 and g++ 4.5. For + g++ an attribute on a label must be followed by a semicolon. */ +#ifndef ATTRIBUTE_UNUSED_LABEL +# ifndef __cplusplus +# if GCC_VERSION >= 2093 +# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED +# else +# define ATTRIBUTE_UNUSED_LABEL +# endif +# else +# if GCC_VERSION >= 4005 +# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED ; +# else +# define ATTRIBUTE_UNUSED_LABEL +# endif +# endif +#endif + +/* Similarly to ARG_UNUSED below. Prior to GCC 3.4, the C++ frontend + couldn't parse attributes placed after the identifier name, and now + the entire compiler is built with C++. */ +#ifndef ATTRIBUTE_UNUSED +#if GCC_VERSION >= 3004 +# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +#else +#define ATTRIBUTE_UNUSED +#endif +#endif /* ATTRIBUTE_UNUSED */ + +/* Before GCC 3.4, the C++ frontend couldn't parse attributes placed after the + identifier name. */ +#if ! defined(__cplusplus) || (GCC_VERSION >= 3004) +# define ARG_UNUSED(NAME) NAME ATTRIBUTE_UNUSED +#else /* !__cplusplus || GNUC >= 3.4 */ +# define ARG_UNUSED(NAME) NAME +#endif /* !__cplusplus || GNUC >= 3.4 */ + +#ifndef ATTRIBUTE_NORETURN +#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__)) +#endif /* ATTRIBUTE_NORETURN */ + +/* Attribute `nonnull' was valid as of gcc 3.3. */ +#ifndef ATTRIBUTE_NONNULL +# if (GCC_VERSION >= 3003) +# define ATTRIBUTE_NONNULL(m) __attribute__ ((__nonnull__ (m))) +# else +# define ATTRIBUTE_NONNULL(m) +# endif /* GNUC >= 3.3 */ +#endif /* ATTRIBUTE_NONNULL */ + +/* Attribute `pure' was valid as of gcc 3.0. */ +#ifndef ATTRIBUTE_PURE +# if (GCC_VERSION >= 3000) +# define ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define ATTRIBUTE_PURE +# endif /* GNUC >= 3.0 */ +#endif /* ATTRIBUTE_PURE */ + +/* Use ATTRIBUTE_PRINTF when the format specifier must not be NULL. + This was the case for the `printf' format attribute by itself + before GCC 3.3, but as of 3.3 we need to add the `nonnull' + attribute to retain this behavior. */ +#ifndef ATTRIBUTE_PRINTF +#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) ATTRIBUTE_NONNULL(m) +#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2) +#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3) +#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4) +#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5) +#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6) +#endif /* ATTRIBUTE_PRINTF */ + +/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on + a function pointer. Format attributes were allowed on function + pointers as of gcc 3.1. */ +#ifndef ATTRIBUTE_FPTR_PRINTF +# if (GCC_VERSION >= 3001) +# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n) +# else +# define ATTRIBUTE_FPTR_PRINTF(m, n) +# endif /* GNUC >= 3.1 */ +# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2) +# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3) +# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4) +# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5) +# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6) +#endif /* ATTRIBUTE_FPTR_PRINTF */ + +/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A + NULL format specifier was allowed as of gcc 3.3. */ +#ifndef ATTRIBUTE_NULL_PRINTF +# if (GCC_VERSION >= 3003) +# define ATTRIBUTE_NULL_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n))) +# else +# define ATTRIBUTE_NULL_PRINTF(m, n) +# endif /* GNUC >= 3.3 */ +# define ATTRIBUTE_NULL_PRINTF_1 ATTRIBUTE_NULL_PRINTF(1, 2) +# define ATTRIBUTE_NULL_PRINTF_2 ATTRIBUTE_NULL_PRINTF(2, 3) +# define ATTRIBUTE_NULL_PRINTF_3 ATTRIBUTE_NULL_PRINTF(3, 4) +# define ATTRIBUTE_NULL_PRINTF_4 ATTRIBUTE_NULL_PRINTF(4, 5) +# define ATTRIBUTE_NULL_PRINTF_5 ATTRIBUTE_NULL_PRINTF(5, 6) +#endif /* ATTRIBUTE_NULL_PRINTF */ + +/* Attribute `sentinel' was valid as of gcc 3.5. */ +#ifndef ATTRIBUTE_SENTINEL +# if (GCC_VERSION >= 3005) +# define ATTRIBUTE_SENTINEL __attribute__ ((__sentinel__)) +# else +# define ATTRIBUTE_SENTINEL +# endif /* GNUC >= 3.5 */ +#endif /* ATTRIBUTE_SENTINEL */ + + +#ifndef ATTRIBUTE_ALIGNED_ALIGNOF +# if (GCC_VERSION >= 3000) +# define ATTRIBUTE_ALIGNED_ALIGNOF(m) __attribute__ ((__aligned__ (__alignof__ (m)))) +# else +# define ATTRIBUTE_ALIGNED_ALIGNOF(m) +# endif /* GNUC >= 3.0 */ +#endif /* ATTRIBUTE_ALIGNED_ALIGNOF */ + +/* Useful for structures whose layout must much some binary specification + regardless of the alignment and padding qualities of the compiler. */ +#ifndef ATTRIBUTE_PACKED +# define ATTRIBUTE_PACKED __attribute__ ((packed)) +#endif + +/* Attribute `hot' and `cold' was valid as of gcc 4.3. */ +#ifndef ATTRIBUTE_COLD +# if (GCC_VERSION >= 4003) +# define ATTRIBUTE_COLD __attribute__ ((__cold__)) +# else +# define ATTRIBUTE_COLD +# endif /* GNUC >= 4.3 */ +#endif /* ATTRIBUTE_COLD */ +#ifndef ATTRIBUTE_HOT +# if (GCC_VERSION >= 4003) +# define ATTRIBUTE_HOT __attribute__ ((__hot__)) +# else +# define ATTRIBUTE_HOT +# endif /* GNUC >= 4.3 */ +#endif /* ATTRIBUTE_HOT */ + +/* We use __extension__ in some places to suppress -pedantic warnings + about GCC extensions. This feature didn't work properly before + gcc 2.8. */ +#if GCC_VERSION < 2008 +#define __extension__ +#endif + +/* This is used to declare a const variable which should be visible + outside of the current compilation unit. Use it as + EXPORTED_CONST int i = 1; + This is because the semantics of const are different in C and C++. + "extern const" is permitted in C but it looks strange, and gcc + warns about it when -Wc++-compat is not used. */ +#ifdef __cplusplus +#define EXPORTED_CONST extern const +#else +#define EXPORTED_CONST const +#endif + +/* Be conservative and only use enum bitfields with C++ or GCC. + FIXME: provide a complete autoconf test for buggy enum bitfields. */ + +#ifdef __cplusplus +#define ENUM_BITFIELD(TYPE) enum TYPE +#elif (GCC_VERSION > 2000) +#define ENUM_BITFIELD(TYPE) __extension__ enum TYPE +#else +#define ENUM_BITFIELD(TYPE) unsigned int +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ansidecl.h */ diff --git a/src/include/auto-host.h b/src/include/auto-host.h new file mode 100644 index 0000000..180f915 --- /dev/null +++ b/src/include/auto-host.h @@ -0,0 +1,2062 @@ +/* auto-host.h. Generated from config.in by configure. */ +/* config.in. Generated from configure.ac by autoheader. */ + +/* Define if building universal (internal helper macro) */ +#ifndef USED_FOR_TARGET +/* #undef AC_APPLE_UNIVERSAL_BUILD */ +#endif + + +/* Define as the number of bits in a byte, if `limits.h' doesn't. */ +#ifndef USED_FOR_TARGET +/* #undef CHAR_BIT */ +#endif + + +/* Define 0/1 to force the choice for exception handling model. */ +#ifndef USED_FOR_TARGET +/* #undef CONFIG_SJLJ_EXCEPTIONS */ +#endif + + +/* Define to enable the use of a default assembler. */ +#ifndef USED_FOR_TARGET +/* #undef DEFAULT_ASSEMBLER */ +#endif + + +/* Define to enable the use of a default linker. */ +#ifndef USED_FOR_TARGET +/* #undef DEFAULT_LINKER */ +#endif + + +/* Define if you want to use __cxa_atexit, rather than atexit, to register C++ + destructors for local statics and global objects. This is essential for + fully standards-compliant handling of destructors, but requires + __cxa_atexit in libc. */ +#ifndef USED_FOR_TARGET +#define DEFAULT_USE_CXA_ATEXIT 2 +#endif + + +/* Define if you want assertions enabled. This is a cheap check. */ +#ifndef USED_FOR_TARGET +#define ENABLE_ASSERT_CHECKING 1 +#endif + + +/* Define if you want more run-time sanity checks. This one gets a grab bag of + miscellaneous but relatively cheap checks. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_CHECKING */ +#endif + + +/* Define to 1 to specify that we are using the BID decimal floating point + format instead of DPD */ +#ifndef USED_FOR_TARGET +#define ENABLE_DECIMAL_BID_FORMAT 1 +#endif + + +/* Define to 1 to enable decimal float extension to C. */ +#ifndef USED_FOR_TARGET +#define ENABLE_DECIMAL_FLOAT 1 +#endif + + +/* Define if you want more run-time sanity checks for dataflow. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_DF_CHECKING */ +#endif + + +/* Define to 1 to enable fixed-point arithmetic extension to C. */ +#ifndef USED_FOR_TARGET +#define ENABLE_FIXED_POINT 0 +#endif + + +/* Define if you want fold checked that it never destructs its argument. This + is quite expensive. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_FOLD_CHECKING */ +#endif + + +/* Define if you want the garbage collector to operate in maximally paranoid + mode, validating the entire heap and collecting garbage at every + opportunity. This is extremely expensive. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_GC_ALWAYS_COLLECT */ +#endif + + +/* Define if you want the garbage collector to do object poisoning and other + memory allocation checks. This is quite expensive. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_GC_CHECKING */ +#endif + + +/* Define if you want operations on GIMPLE (the basic data structure of the + high-level optimizers) to be checked for dynamic type safety at runtime. + This is moderately expensive. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_GIMPLE_CHECKING */ +#endif + + +/* Define if gcc should always pass --build-id to linker. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_LD_BUILDID */ +#endif + + +/* Define to 1 to enable libquadmath support */ +#ifndef USED_FOR_TARGET +#define ENABLE_LIBQUADMATH_SUPPORT 1 +#endif + + +/* Define to enable LTO support. */ +#ifndef USED_FOR_TARGET +#define ENABLE_LTO 1 +#endif + + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#ifndef USED_FOR_TARGET +#define ENABLE_NLS 1 +#endif + + +/* Define to enable plugin support. */ +#ifndef USED_FOR_TARGET +#define ENABLE_PLUGIN 1 +#endif + + +/* Define if you want all operations on RTL (the basic data structure of the + optimizer and back end) to be checked for dynamic type safety at runtime. + This is quite expensive. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_RTL_CHECKING */ +#endif + + +/* Define if you want RTL flag accesses to be checked against the RTL codes + that are supported for each access macro. This is relatively cheap. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_RTL_FLAG_CHECKING */ +#endif + + +/* Define if you want runtime assertions enabled. This is a cheap check. */ +#define ENABLE_RUNTIME_CHECKING 1 + +/* Define if you want all operations on trees (the basic data structure of the + front ends) to be checked for dynamic type safety at runtime. This is + moderately expensive. The tree browser debugging routines will also be + enabled by this option. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_TREE_CHECKING */ +#endif + + +/* Define if you want all gimple types to be verified after gimplifiation. + This is cheap. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_TYPES_CHECKING */ +#endif + + +/* Define if you want to run subprograms and generated programs through + valgrind (a memory checker). This is extremely expensive. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_VALGRIND_CHECKING */ +#endif + + +/* Define to 1 if installation paths should be looked up in the Windows + Registry. Ignored on non-Windows hosts. */ +#ifndef USED_FOR_TARGET +/* #undef ENABLE_WIN32_REGISTRY */ +#endif + + +/* Define to the name of a file containing a list of extra machine modes for + this architecture. */ +#ifndef USED_FOR_TARGET +#define EXTRA_MODES_FILE "config/i386/i386-modes.def" +#endif + + +/* Define to enable detailed memory allocation stats gathering. */ +#ifndef USED_FOR_TARGET +#define GATHER_STATISTICS 0 +#endif + + +/* mcontext_t fields start with __ */ +#ifndef USED_FOR_TARGET +/* #undef HAS_MCONTEXT_T_UNDERSCORES */ +#endif + + +/* Define if your assembler supports cmpb. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_CMPB */ +#endif + + +/* Define if your assembler supports the DCI/ICI instructions. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_DCI */ +#endif + + +/* Define if your assembler supports the --debug-prefix-map option. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_DEBUG_PREFIX_MAP 1 +#endif + + +/* Define if your assembler supports DFP instructions. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_DFP */ +#endif + + +/* Define if your assembler supports DSPR1 mult. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_DSPR1_MULT */ +#endif + + +/* Define if your assembler supports .dtprelword. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_DTPRELWORD */ +#endif + + +/* Define if your assembler supports dwarf2 .file/.loc directives, and + preserves file table indices exactly as given. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_DWARF2_DEBUG_LINE 1 +#endif + + +/* Define if your assembler supports explicit relocations. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_EXPLICIT_RELOCS */ +#endif + + +/* Define if your assembler supports FMAF, HPC, and VIS 3.0 instructions. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_FMAF_HPC_VIS3 */ +#endif + + +/* Define if your assembler supports fprnd. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_FPRND */ +#endif + + +/* Define if your assembler supports the --gdwarf2 option. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_GDWARF2_DEBUG_FLAG 1 +#endif + + +/* Define if your assembler supports .gnu_attribute. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_GNU_ATTRIBUTE */ +#endif + + +/* Define true if the assembler supports '.long foo@GOTOFF'. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_GOTOFF_IN_DATA 1 +#endif + + +/* Define if your assembler supports the --gstabs option. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_GSTABS_DEBUG_FLAG 1 +#endif + + +/* Define if your assembler supports the Sun syntax for cmov. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_IX86_CMOV_SUN_SYNTAX */ +#endif + + +/* Define if your assembler supports the subtraction of symbols in different + sections. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_IX86_DIFF_SECT_DELTA 1 +#endif + + +/* Define if your assembler supports the ffreep mnemonic. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_IX86_FFREEP 1 +#endif + + +/* Define if your assembler uses fildq and fistq mnemonics. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_IX86_FILDQ 1 +#endif + + +/* Define if your assembler uses filds and fists mnemonics. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_IX86_FILDS 1 +#endif + + +/* Define if your assembler supports HLE prefixes. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_IX86_HLE 1 +#endif + + +/* Define if your assembler supports the .quad directive. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_IX86_QUAD 1 +#endif + + +/* Define if the assembler supports 'rep , lock '. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_IX86_REP_LOCK_PREFIX 1 +#endif + + +/* Define if your assembler supports the sahf mnemonic in 64bit mode. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_IX86_SAHF 1 +#endif + + +/* Define if your assembler supports the swap suffix. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_IX86_SWAP 1 +#endif + + +/* Define if your assembler and linker support @tlsgdplt. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_IX86_TLSGDPLT */ +#endif + + +/* Define if your assembler and linker support @tlsldmplt. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_IX86_TLSLDMPLT */ +#endif + + +/* Define if your assembler supports the 'ud2' mnemonic. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_IX86_UD2 1 +#endif + + +/* Define if your assembler supports the lituse_jsrdirect relocation. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_JSRDIRECT_RELOCS */ +#endif + + +/* Define if your assembler supports .sleb128 and .uleb128. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_LEB128 1 +#endif + + +/* Define if your assembler supports LEON instructions. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_LEON */ +#endif + + +/* Define if the assembler won't complain about a line such as # 0 "" 2. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_LINE_ZERO 1 +#endif + + +/* Define if your assembler supports ltoffx and ldxmov relocations. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_LTOFFX_LDXMOV_RELOCS */ +#endif + + +/* Define if your assembler supports LWSYNC instructions. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_LWSYNC */ +#endif + + +/* Define if your assembler supports mfcr field. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_MFCRF */ +#endif + + +/* Define if your assembler supports mffgpr and mftgpr. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_MFPGPR */ +#endif + + +/* Define if your assembler supports the -no-mul-bug-abort option. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_NO_MUL_BUG_ABORT_OPTION */ +#endif + + +/* Define if the assembler understands -mno-shared. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_NO_SHARED */ +#endif + + +/* Define if your assembler supports offsetable %lo(). */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_OFFSETABLE_LO10 */ +#endif + + +/* Define if your assembler supports popcntb field. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_POPCNTB */ +#endif + + +/* Define if your assembler supports POPCNTD instructions. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_POPCNTD */ +#endif + + +/* Define if your assembler supports POWER8 instructions. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_POWER8 */ +#endif + + +/* Define if your assembler supports .ref */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_REF */ +#endif + + +/* Define if your assembler supports .register. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_REGISTER_PSEUDO_OP */ +#endif + + +/* Define if your assembler supports R_PPC_REL16 relocs. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_REL16 */ +#endif + + +/* Define if your assembler supports -relax option. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_RELAX_OPTION */ +#endif + + +/* Define if your assembler supports SPARC4 instructions. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_SPARC4 */ +#endif + + +/* Define if your assembler and linker support GOTDATA_OP relocs. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_SPARC_GOTDATA_OP */ +#endif + + +/* Define to 1 if your assembler supports #nobits, 0 otherwise. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_SPARC_NOBITS */ +#endif + + +/* Define if your assembler and linker support unaligned PC relative relocs. + */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_SPARC_UA_PCREL */ +#endif + + +/* Define if your assembler and linker support unaligned PC relative relocs + against hidden symbols. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_SPARC_UA_PCREL_HIDDEN */ +#endif + + +/* Define if your assembler and linker support thread-local storage. */ +#ifndef USED_FOR_TARGET +#define HAVE_AS_TLS 1 +#endif + + +/* Define if your assembler supports arg info for __tls_get_addr. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_TLS_MARKERS */ +#endif + + +/* Define if your assembler supports VSX instructions. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_AS_VSX */ +#endif + + +/* Define to 1 if you have the `atoll' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_ATOLL 1 +#endif + + +/* Define to 1 if you have the `atoq' function. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_ATOQ */ +#endif + + +/* Define to 1 if you have the `clearerr_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_CLEARERR_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `clock' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_CLOCK 1 +#endif + + +/* Define if defines clock_t. */ +#ifndef USED_FOR_TARGET +#define HAVE_CLOCK_T 1 +#endif + + +/* Define 0/1 if your assembler and linker support COMDAT groups. */ +#ifndef USED_FOR_TARGET +#define HAVE_COMDAT_GROUP 1 +#endif + + +/* Define to 1 if we found a declaration for 'abort', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_ABORT 1 +#endif + + +/* Define to 1 if we found a declaration for 'asprintf', otherwise define to + 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_ASPRINTF 1 +#endif + + +/* Define to 1 if we found a declaration for 'atof', otherwise define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_ATOF 1 +#endif + + +/* Define to 1 if we found a declaration for 'atol', otherwise define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_ATOL 1 +#endif + + +/* Define to 1 if we found a declaration for 'basename', otherwise define to + 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_BASENAME 1 +#endif + + +/* Define to 1 if we found a declaration for 'calloc', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_CALLOC 1 +#endif + + +/* Define to 1 if we found a declaration for 'clearerr_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_CLEARERR_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'clock', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_CLOCK 1 +#endif + + +/* Define to 1 if we found a declaration for 'errno', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_ERRNO 1 +#endif + + +/* Define to 1 if we found a declaration for 'feof_unlocked', otherwise define + to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FEOF_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'ferror_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FERROR_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'fflush_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FFLUSH_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'ffs', otherwise define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FFS 1 +#endif + + +/* Define to 1 if we found a declaration for 'fgetc_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FGETC_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'fgets_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FGETS_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'fileno_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FILENO_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'fprintf_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FPRINTF_UNLOCKED 0 +#endif + + +/* Define to 1 if we found a declaration for 'fputc_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FPUTC_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'fputs_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FPUTS_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'fread_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FREAD_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'free', otherwise define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FREE 1 +#endif + + +/* Define to 1 if we found a declaration for 'fwrite_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_FWRITE_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'getchar_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_GETCHAR_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'getcwd', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_GETCWD 1 +#endif + + +/* Define to 1 if we found a declaration for 'getc_unlocked', otherwise define + to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_GETC_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'getenv', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_GETENV 1 +#endif + + +/* Define to 1 if we found a declaration for 'getopt', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_GETOPT 0 +#endif + + +/* Define to 1 if we found a declaration for 'getpagesize', otherwise define + to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_GETPAGESIZE 1 +#endif + + +/* Define to 1 if we found a declaration for 'getrlimit', otherwise define to + 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_GETRLIMIT 1 +#endif + + +/* Define to 1 if we found a declaration for 'getrusage', otherwise define to + 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_GETRUSAGE 1 +#endif + + +/* Define to 1 if we found a declaration for 'getwd', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_GETWD 1 +#endif + + +/* Define to 1 if we found a declaration for 'ldgetname', otherwise define to + 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_LDGETNAME 0 +#endif + + +/* Define to 1 if we found a declaration for 'madvise', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_MADVISE 1 +#endif + + +/* Define to 1 if we found a declaration for 'malloc', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_MALLOC 1 +#endif + + +/* Define to 1 if we found a declaration for 'putchar_unlocked', otherwise + define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_PUTCHAR_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'putc_unlocked', otherwise define + to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_PUTC_UNLOCKED 1 +#endif + + +/* Define to 1 if we found a declaration for 'realloc', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_REALLOC 1 +#endif + + +/* Define to 1 if we found a declaration for 'sbrk', otherwise define to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_SBRK 1 +#endif + + +/* Define to 1 if we found a declaration for 'setrlimit', otherwise define to + 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_SETRLIMIT 1 +#endif + + +/* Define to 1 if we found a declaration for 'sigaltstack', otherwise define + to 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_SIGALTSTACK 1 +#endif + + +/* Define to 1 if we found a declaration for 'snprintf', otherwise define to + 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_SNPRINTF 1 +#endif + + +/* Define to 1 if we found a declaration for 'stpcpy', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_STPCPY 1 +#endif + + +/* Define to 1 if we found a declaration for 'strsignal', otherwise define to + 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_STRSIGNAL 1 +#endif + + +/* Define to 1 if we found a declaration for 'strstr', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_STRSTR 1 +#endif + + +/* Define to 1 if we found a declaration for 'strverscmp', otherwise define to + 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_STRVERSCMP 1 +#endif + + +/* Define to 1 if we found a declaration for 'times', otherwise define to 0. + */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_TIMES 1 +#endif + + +/* Define to 1 if we found a declaration for 'vasprintf', otherwise define to + 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_VASPRINTF 1 +#endif + + +/* Define to 1 if we found a declaration for 'vsnprintf', otherwise define to + 0. */ +#ifndef USED_FOR_TARGET +#define HAVE_DECL_VSNPRINTF 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_DIRECT_H */ +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_DLFCN_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_EXT_HASH_MAP 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_FCNTL_H 1 +#endif + + +/* Define to 1 if you have the `feof_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_FEOF_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `ferror_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_FERROR_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `fflush_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_FFLUSH_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `fgetc_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_FGETC_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `fgets_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_FGETS_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `fileno_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_FILENO_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `fork' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_FORK 1 +#endif + + +/* Define to 1 if you have the `fprintf_unlocked' function. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_FPRINTF_UNLOCKED */ +#endif + + +/* Define to 1 if you have the `fputc_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_FPUTC_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `fputs_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_FPUTS_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `fread_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_FREAD_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `fwrite_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_FWRITE_UNLOCKED 1 +#endif + + +/* Define if your assembler supports specifying the alignment of objects + allocated using the GAS .comm command. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_GAS_ALIGNED_COMM */ +#endif + + +/* Define if your assembler supports .balign and .p2align. */ +#ifndef USED_FOR_TARGET +#define HAVE_GAS_BALIGN_AND_P2ALIGN 1 +#endif + + +/* Define 0/1 if your assembler supports CFI directives. */ +#define HAVE_GAS_CFI_DIRECTIVE 1 + +/* Define 0/1 if your assembler supports .cfi_personality. */ +#define HAVE_GAS_CFI_PERSONALITY_DIRECTIVE 1 + +/* Define 0/1 if your assembler supports .cfi_sections. */ +#define HAVE_GAS_CFI_SECTIONS_DIRECTIVE 1 + +/* Define if your assembler supports the .loc discriminator sub-directive. */ +#ifndef USED_FOR_TARGET +#define HAVE_GAS_DISCRIMINATOR 1 +#endif + + +/* Define if your assembler supports @gnu_unique_object. */ +#ifndef USED_FOR_TARGET +#define HAVE_GAS_GNU_UNIQUE_OBJECT 1 +#endif + + +/* Define if your assembler and linker support .hidden. */ +#define HAVE_GAS_HIDDEN 1 + +/* Define if your assembler supports .lcomm with an alignment field. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_GAS_LCOMM_WITH_ALIGNMENT */ +#endif + + +/* Define if your assembler supports .literal16. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_GAS_LITERAL16 */ +#endif + + +/* Define if your assembler supports specifying the maximum number of bytes to + skip when using the GAS .p2align command. */ +#ifndef USED_FOR_TARGET +#define HAVE_GAS_MAX_SKIP_P2ALIGN 1 +#endif + + +/* Define if your assembler supports .nsubspa comdat option. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_GAS_NSUBSPA_COMDAT */ +#endif + + +/* Define if your assembler and linker support 32-bit section relative relocs + via '.secrel32 label'. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_GAS_PE_SECREL32_RELOC */ +#endif + + +/* Define if your assembler supports specifying the section flag e. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_GAS_SECTION_EXCLUDE */ +#endif + + +/* Define 0/1 if your assembler supports marking sections with SHF_MERGE flag. + */ +#ifndef USED_FOR_TARGET +#define HAVE_GAS_SHF_MERGE 1 +#endif + + +/* Define if your assembler supports .subsection and .subsection -1 starts + emitting at the beginning of your section. */ +#ifndef USED_FOR_TARGET +#define HAVE_GAS_SUBSECTION_ORDERING 1 +#endif + + +/* Define if your assembler supports .weak. */ +#ifndef USED_FOR_TARGET +#define HAVE_GAS_WEAK 1 +#endif + + +/* Define if your assembler supports .weakref. */ +#ifndef USED_FOR_TARGET +#define HAVE_GAS_WEAKREF 1 +#endif + + +/* Define to 1 if you have the `getchar_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_GETCHAR_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `getc_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_GETC_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `getrlimit' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_GETRLIMIT 1 +#endif + + +/* Define to 1 if you have the `getrusage' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_GETRUSAGE 1 +#endif + + +/* Define to 1 if you have the `gettimeofday' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_GETTIMEOFDAY 1 +#endif + + +/* Define to 1 if using GNU as. */ +#ifndef USED_FOR_TARGET +#define HAVE_GNU_AS 1 +#endif + + +/* Define if your system supports gnu indirect functions. */ +#ifndef USED_FOR_TARGET +#define HAVE_GNU_INDIRECT_FUNCTION 1 +#endif + + +/* Define to 1 if using GNU ld. */ +#ifndef USED_FOR_TARGET +#define HAVE_GNU_LD 1 +#endif + + +/* Define if you have the iconv() function. */ +#ifndef USED_FOR_TARGET +#define HAVE_ICONV 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_ICONV_H 1 +#endif + + +/* Define .init_array/.fini_array sections are available and working. */ +#ifndef USED_FOR_TARGET +#define HAVE_INITFINI_ARRAY_SUPPORT 1 +#endif + + +/* Define to 1 if the system has the type `intmax_t'. */ +#ifndef USED_FOR_TARGET +#define HAVE_INTMAX_T 1 +#endif + + +/* Define to 1 if the system has the type `intptr_t'. */ +#ifndef USED_FOR_TARGET +#define HAVE_INTPTR_T 1 +#endif + + +/* Define if you have a working header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_INTTYPES_H 1 +#endif + + +/* Define if isl_schedule_constraints_compute_schedule exists. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE */ +#endif + + +/* Define to 1 if you have the `kill' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_KILL 1 +#endif + + +/* Define if you have and nl_langinfo(CODESET). */ +#ifndef USED_FOR_TARGET +#define HAVE_LANGINFO_CODESET 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_LANGINFO_H 1 +#endif + + +/* Define if your file defines LC_MESSAGES. */ +#ifndef USED_FOR_TARGET +#define HAVE_LC_MESSAGES 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_LDFCN_H */ +#endif + + +/* Define if your linker supports --as-needed and --no-as-needed options. */ +#ifndef USED_FOR_TARGET +#define HAVE_LD_AS_NEEDED 1 +#endif + + +/* Define if your linker supports --build-id. */ +#ifndef USED_FOR_TARGET +#define HAVE_LD_BUILDID 1 +#endif + + +/* Define if your linker supports --demangle option. */ +#ifndef USED_FOR_TARGET +#define HAVE_LD_DEMANGLE 1 +#endif + + +/* Define if your linker supports .eh_frame_hdr. */ +#define HAVE_LD_EH_FRAME_HDR 1 + +/* Define if your linker supports garbage collection of sections in presence + of EH frames. */ +#ifndef USED_FOR_TARGET +#define HAVE_LD_EH_GC_SECTIONS 1 +#endif + + +/* Define if your linker has buggy garbage collection of sections support when + .text.startup.foo like sections are used. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_LD_EH_GC_SECTIONS_BUG */ +#endif + + +/* Define if your PowerPC64 linker supports a large TOC. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_LD_LARGE_TOC */ +#endif + + +/* Define if your PowerPC64 linker only needs function descriptor syms. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_LD_NO_DOT_SYMS */ +#endif + + +/* Define if your linker can relax absolute .eh_frame personality pointers + into PC-relative form. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_LD_PERSONALITY_RELAXATION */ +#endif + + +/* Define if your linker supports -pie option. */ +#ifndef USED_FOR_TARGET +#define HAVE_LD_PIE 1 +#endif + + +/* Define if your linker links a mix of read-only and read-write sections into + a read-write section. */ +#ifndef USED_FOR_TARGET +#define HAVE_LD_RO_RW_SECTION_MIXING 1 +#endif + + +/* Define if your linker supports the *_sol2 emulations. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_LD_SOL2_EMULATION */ +#endif + + +/* Define if your linker supports -Bstatic/-Bdynamic or equivalent options. */ +#ifndef USED_FOR_TARGET +#define HAVE_LD_STATIC_DYNAMIC 1 +#endif + + +/* Define if your linker supports --sysroot. */ +#ifndef USED_FOR_TARGET +#define HAVE_LD_SYSROOT 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_LIMITS_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_LOCALE_H 1 +#endif + + +/* Define to 1 if the system has the type `long long'. */ +#ifndef USED_FOR_TARGET +#define HAVE_LONG_LONG 1 +#endif + + +/* Define to 1 if the system has the type `long long int'. */ +#ifndef USED_FOR_TARGET +#define HAVE_LONG_LONG_INT 1 +#endif + + +/* Define to the level of your linker's plugin support. */ +#ifndef USED_FOR_TARGET +#define HAVE_LTO_PLUGIN 2 +#endif + + +/* Define to 1 if you have the `madvise' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_MADVISE 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_MALLOC_H 1 +#endif + + +/* Define to 1 if you have the `mbstowcs' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_MBSTOWCS 1 +#endif + + +/* Define if valgrind's memcheck.h header is installed. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_MEMCHECK_H */ +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_MEMORY_H 1 +#endif + + +/* Define to 1 if you have the `mmap' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_MMAP 1 +#endif + + +/* Define if mmap with MAP_ANON(YMOUS) works. */ +#ifndef USED_FOR_TARGET +#define HAVE_MMAP_ANON 1 +#endif + + +/* Define if mmap of /dev/zero works. */ +#ifndef USED_FOR_TARGET +#define HAVE_MMAP_DEV_ZERO 1 +#endif + + +/* Define if read-only mmap of a plain file works. */ +#ifndef USED_FOR_TARGET +#define HAVE_MMAP_FILE 1 +#endif + + +/* Define to 1 if you have the `nl_langinfo' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_NL_LANGINFO 1 +#endif + + +/* Define to 1 if you have the `putchar_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_PUTCHAR_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `putc_unlocked' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_PUTC_UNLOCKED 1 +#endif + + +/* Define to 1 if you have the `setlocale' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_SETLOCALE 1 +#endif + + +/* Define to 1 if you have the `setrlimit' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_SETRLIMIT 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_STDDEF_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_STDINT_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_STDLIB_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_STRINGS_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_STRING_H 1 +#endif + + +/* Define to 1 if you have the `strsignal' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_STRSIGNAL 1 +#endif + + +/* Define if defines struct tms. */ +#ifndef USED_FOR_TARGET +#define HAVE_STRUCT_TMS 1 +#endif + + +/* Define to 1 if you have the `sysconf' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_SYSCONF 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_SYS_FILE_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_SYS_MMAN_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_SYS_PARAM_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_SYS_RESOURCE_H 1 +#endif + + +/* Define if your target C library provides sys/sdt.h */ +/* #undef HAVE_SYS_SDT_H */ + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_SYS_STAT_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_SYS_TIMES_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_SYS_TIME_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_SYS_TYPES_H 1 +#endif + + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#ifndef USED_FOR_TARGET +#define HAVE_SYS_WAIT_H 1 +#endif + + +/* Define to 1 if you have the `times' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_TIMES 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_TIME_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_TR1_UNORDERED_MAP 1 +#endif + + +/* Define to 1 if the system has the type `uintmax_t'. */ +#ifndef USED_FOR_TARGET +#define HAVE_UINTMAX_T 1 +#endif + + +/* Define to 1 if the system has the type `uintptr_t'. */ +#ifndef USED_FOR_TARGET +#define HAVE_UINTPTR_T 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_UNISTD_H 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_UNORDERED_MAP */ +#endif + + +/* Define to 1 if the system has the type `unsigned long long int'. */ +#ifndef USED_FOR_TARGET +#define HAVE_UNSIGNED_LONG_LONG_INT 1 +#endif + + +/* Define if valgrind's valgrind/memcheck.h header is installed. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_VALGRIND_MEMCHECK_H */ +#endif + + +/* Define to 1 if you have the `vfork' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_VFORK 1 +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_VFORK_H */ +#endif + + +/* Define to 1 if you have the header file. */ +#ifndef USED_FOR_TARGET +#define HAVE_WCHAR_H 1 +#endif + + +/* Define to 1 if you have the `wcswidth' function. */ +#ifndef USED_FOR_TARGET +#define HAVE_WCSWIDTH 1 +#endif + + +/* Define to 1 if `fork' works. */ +#ifndef USED_FOR_TARGET +#define HAVE_WORKING_FORK 1 +#endif + + +/* Define this macro if mbstowcs does not crash when its first argument is + NULL. */ +#ifndef USED_FOR_TARGET +#define HAVE_WORKING_MBSTOWCS 1 +#endif + + +/* Define to 1 if `vfork' works. */ +#ifndef USED_FOR_TARGET +#define HAVE_WORKING_VFORK 1 +#endif + + +/* Define to 1 if the system has the type `__int64'. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE___INT64 */ +#endif + + +/* Define if cloog is in use. */ +#ifndef USED_FOR_TARGET +/* #undef HAVE_cloog */ +#endif + + +/* Define if F_SETLKW supported by fcntl. */ +#ifndef USED_FOR_TARGET +#define HOST_HAS_F_SETLKW 1 +#endif + + +/* Define as const if the declaration of iconv() needs const. */ +#ifndef USED_FOR_TARGET +#define ICONV_CONST +#endif + + +/* Define to the linker option to enable use of shared objects. */ +#ifndef USED_FOR_TARGET +#define LD_DYNAMIC_OPTION "-Bdynamic" +#endif + + +/* Define to the linker option to disable use of shared objects. */ +#ifndef USED_FOR_TARGET +#define LD_STATIC_OPTION "-Bstatic" +#endif + + +/* Define to the library containing __tls_get_addr/___tls_get_addr. */ +#ifndef USED_FOR_TARGET +/* #undef LIB_TLS_SPEC */ +#endif + + +/* The linker hash style */ +#ifndef USED_FOR_TARGET +/* #undef LINKER_HASH_STYLE */ +#endif + + +/* Define to the name of the LTO plugin DSO that must be passed to the + linker's -plugin=LIB option. */ +#ifndef USED_FOR_TARGET +#define LTOPLUGINSONAME "liblto_plugin.so" +#endif + + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#ifndef USED_FOR_TARGET +#define LT_OBJDIR ".libs/" +#endif + + +/* Define if host mkdir takes a single argument. */ +#ifndef USED_FOR_TARGET +/* #undef MKDIR_TAKES_ONE_ARG */ +#endif + + +/* Define to 1 if HOST_WIDE_INT must be 64 bits wide (see hwint.h). */ +#ifndef USED_FOR_TARGET +#define NEED_64BIT_HOST_WIDE_INT 1 +#endif + + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#ifndef USED_FOR_TARGET +/* #undef NO_MINUS_C_MINUS_O */ +#endif + + +/* Define to the address where bug reports for this package should be sent. */ +#ifndef USED_FOR_TARGET +#define PACKAGE_BUGREPORT "" +#endif + + +/* Define to the full name of this package. */ +#ifndef USED_FOR_TARGET +#define PACKAGE_NAME "" +#endif + + +/* Define to the full name and version of this package. */ +#ifndef USED_FOR_TARGET +#define PACKAGE_STRING "" +#endif + + +/* Define to the one symbol short name of this package. */ +#ifndef USED_FOR_TARGET +#define PACKAGE_TARNAME "" +#endif + + +/* Define to the home page for this package. */ +#ifndef USED_FOR_TARGET +#define PACKAGE_URL "" +#endif + + +/* Define to the version of this package. */ +#ifndef USED_FOR_TARGET +#define PACKAGE_VERSION "" +#endif + + +/* Specify plugin linker */ +#ifndef USED_FOR_TARGET +#define PLUGIN_LD_SUFFIX "ld" +#endif + + +/* Define to PREFIX/include if cpp should also search that directory. */ +#ifndef USED_FOR_TARGET +#define PREFIX_INCLUDE_DIR "/home/zet/bin/gcc-48/include" +#endif + + +/* The size of `int', as computed by sizeof. */ +#ifndef USED_FOR_TARGET +#define SIZEOF_INT 4 +#endif + + +/* The size of `long', as computed by sizeof. */ +#ifndef USED_FOR_TARGET +#define SIZEOF_LONG 8 +#endif + + +/* The size of `long long', as computed by sizeof. */ +#ifndef USED_FOR_TARGET +#define SIZEOF_LONG_LONG 8 +#endif + + +/* The size of `short', as computed by sizeof. */ +#ifndef USED_FOR_TARGET +#define SIZEOF_SHORT 2 +#endif + + +/* The size of `void *', as computed by sizeof. */ +#ifndef USED_FOR_TARGET +#define SIZEOF_VOID_P 8 +#endif + + +/* The size of `__int64', as computed by sizeof. */ +#ifndef USED_FOR_TARGET +/* #undef SIZEOF___INT64 */ +#endif + + +/* Define to 1 if you have the ANSI C header files. */ +#ifndef USED_FOR_TARGET +#define STDC_HEADERS 1 +#endif + + +/* Define if you can safely include both and . */ +#ifndef USED_FOR_TARGET +#define STRING_WITH_STRINGS 1 +#endif + + +/* Define if TFmode long double should be the default */ +#ifndef USED_FOR_TARGET +/* #undef TARGET_DEFAULT_LONG_DOUBLE_128 */ +#endif + + +/* Define if your target C library provides the `dl_iterate_phdr' function. */ +/* #undef TARGET_DL_ITERATE_PHDR */ + +/* Define if your target C library provides stack protector support */ +#ifndef USED_FOR_TARGET +#define TARGET_LIBC_PROVIDES_SSP 1 +#endif + + +/* Define to 1 if you can safely include both and . */ +#ifndef USED_FOR_TARGET +#define TIME_WITH_SYS_TIME 1 +#endif + + +/* Define to the flag used to mark TLS sections if the default (`T') doesn't + work. */ +#ifndef USED_FOR_TARGET +/* #undef TLS_SECTION_ASM_FLAG */ +#endif + + +/* Define if your assembler mis-optimizes .eh_frame data. */ +#ifndef USED_FOR_TARGET +/* #undef USE_AS_TRADITIONAL_FORMAT */ +#endif + + +/* Define if you want to generate code by default that assumes that the Cygwin + DLL exports wrappers to support libstdc++ function replacement. */ +#ifndef USED_FOR_TARGET +/* #undef USE_CYGWIN_LIBSTDCXX_WRAPPERS */ +#endif + + +/* Define to 1 if the 'long long' (or '__int64') is wider than 'long' but + still efficiently supported by the host hardware. */ +#ifndef USED_FOR_TARGET +/* #undef USE_LONG_LONG_FOR_WIDEST_FAST_INT */ +#endif + + +/* Define if we should use leading underscore on 64 bit mingw targets */ +#ifndef USED_FOR_TARGET +/* #undef USE_MINGW64_LEADING_UNDERSCORES */ +#endif + + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# define _ALL_SOURCE 1 +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# define _TANDEM_SOURCE 1 +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ 1 +#endif + + +/* Define to be the last component of the Windows registry key under which to + look for installation paths. The full key used will be + HKEY_LOCAL_MACHINE/SOFTWARE/Free Software Foundation/{WIN32_REGISTRY_KEY}. + The default is the GCC version number. */ +#ifndef USED_FOR_TARGET +/* #undef WIN32_REGISTRY_KEY */ +#endif + + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#ifndef USED_FOR_TARGET +/* #undef _FILE_OFFSET_BITS */ +#endif + + +/* Define for large files, on AIX-style hosts. */ +#ifndef USED_FOR_TARGET +/* #undef _LARGE_FILES */ +#endif + + +/* Define to 1 if on MINIX. */ +#ifndef USED_FOR_TARGET +/* #undef _MINIX */ +#endif + + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#ifndef USED_FOR_TARGET +/* #undef _POSIX_1_SOURCE */ +#endif + + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#ifndef USED_FOR_TARGET +/* #undef _POSIX_SOURCE */ +#endif + + +/* Define for Solaris 2.5.1 so the uint32_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#ifndef USED_FOR_TARGET +/* #undef _UINT32_T */ +#endif + + +/* Define for Solaris 2.5.1 so the uint64_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#ifndef USED_FOR_TARGET +/* #undef _UINT64_T */ +#endif + + +/* Define for Solaris 2.5.1 so the uint8_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#ifndef USED_FOR_TARGET +/* #undef _UINT8_T */ +#endif + + +/* Define to `char *' if does not define. */ +#ifndef USED_FOR_TARGET +/* #undef caddr_t */ +#endif + + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to the type of a signed integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#ifndef USED_FOR_TARGET +/* #undef int16_t */ +#endif + + +/* Define to the type of a signed integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#ifndef USED_FOR_TARGET +/* #undef int32_t */ +#endif + + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#ifndef USED_FOR_TARGET +/* #undef int64_t */ +#endif + + +/* Define to the type of a signed integer type of width exactly 8 bits if such + a type exists and the standard includes do not define it. */ +#ifndef USED_FOR_TARGET +/* #undef int8_t */ +#endif + + +/* Define to the widest signed integer type if and do + not define. */ +#ifndef USED_FOR_TARGET +/* #undef intmax_t */ +#endif + + +/* Define to the type of a signed integer type wide enough to hold a pointer, + if such a type exists, and if the system does not define it. */ +#ifndef USED_FOR_TARGET +/* #undef intptr_t */ +#endif + + +/* Define to `int' if does not define. */ +#ifndef USED_FOR_TARGET +/* #undef pid_t */ +#endif + + +/* Define to `long' if doesn't define. */ +#ifndef USED_FOR_TARGET +/* #undef rlim_t */ +#endif + + +/* Define to `int' if does not define. */ +#ifndef USED_FOR_TARGET +/* #undef ssize_t */ +#endif + + +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#ifndef USED_FOR_TARGET +/* #undef uint16_t */ +#endif + + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#ifndef USED_FOR_TARGET +/* #undef uint32_t */ +#endif + + +/* Define to the type of an unsigned integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#ifndef USED_FOR_TARGET +/* #undef uint64_t */ +#endif + + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ +#ifndef USED_FOR_TARGET +/* #undef uint8_t */ +#endif + + +/* Define to the widest unsigned integer type if and + do not define. */ +#ifndef USED_FOR_TARGET +/* #undef uintmax_t */ +#endif + + +/* Define to the type of an unsigned integer type wide enough to hold a + pointer, if such a type exists, and if the system does not define it. */ +#ifndef USED_FOR_TARGET +/* #undef uintptr_t */ +#endif + + +/* Define as `fork' if `vfork' does not work. */ +#ifndef USED_FOR_TARGET +/* #undef vfork */ +#endif + diff --git a/src/include/b-header-vars b/src/include/b-header-vars new file mode 100644 index 0000000..6cdd670 --- /dev/null +++ b/src/include/b-header-vars @@ -0,0 +1,121 @@ +USER_H=xsaveoptintrin.h mm_malloc.h +HASHTAB_H=hashtab.h +OBSTACK_H=obstack.h +SPLAY_TREE_H=splay-tree.h +FIBHEAP_H=fibheap.h +PARTITION_H=partition.h +DWARF2_H=dwarf2.def +XREGEX_H=xregex.h +FNMATCH_H=fnmatch.h +LINKER_PLUGIN_API_H=plugin-api.h +LTO_SYMTAB_H=lto-symtab.h +BCONFIG_H=bconfig.h auto-host.h ansidecl.h +CONFIG_H=config.h auto-host.h ansidecl.h +TCONFIG_H=tconfig.h auto-host.h ansidecl.h +TM_P_H=tm_p.h config/i386/i386-protos.h tm-preds.h +GTM_H=tm.h options.h config/vxworks-dummy.h defaults.h insn-constants.h +TM_H=tm.h options.h config/vxworks-dummy.h i386-opts.h +VEC_H=vec.h statistics.h ggc.h gtype-desc.h statistics.h +HASH_TABLE_H=hashtab.h hash-table.h +EXCEPT_H=except.h hashtab.h +TARGET_H=tm.h options.h config/vxworks-dummy.h i386-opts.h target.h target.def target-hooks-macros.h insn-modes.h +C_TARGET_H=c-family/c-target.h c-family/c-target.def target-hooks-macros.h +COMMON_TARGET_H=common/common-target.h common-target.def target-hooks-macros.h +MACHMODE_H=machmode.h mode-classes.def insn-modes.h +HOOKS_H=hooks.h machmode.h mode-classes.def insn-modes.h +HOSTHOOKS_DEF_H=hosthooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h +LANGHOOKS_DEF_H=langhooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h +TARGET_DEF_H=target-def.h target-hooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h targhooks.h +C_TARGET_DEF_H=c-family/c-target-def.h c-family/c-target-hooks-def.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def common-targhooks.h +COMMON_TARGET_DEF_H=common/common-target-def.h common/common-target-hooks-def.h hooks.h machmode.h mode-classes.def insn-modes.h +RTL_BASE_H=coretypes.h rtl.h rtl.def machmode.h mode-classes.def insn-modes.h reg-notes.def insn-notes.def hashtab.h +FIXED_VALUE_H=fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h +RTL_H=coretypes.h rtl.h rtl.def machmode.h mode-classes.def insn-modes.h reg-notes.def insn-notes.def i386-opts.h genrtl.h +RTL_ERROR_H=rtl-error.h coretypes.h rtl.h rtl.def machmode.h mode-classes.def insn-modes.h reg-notes.def insn-notes.def line-map.h input.h bversion.h diagnostic.def +READ_MD_H=hashtab.h read-md.h +PARAMS_H=params.h params.def +INTERNAL_FN_H=internal-fn.h internal-fn.def +TREE_H=coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h +REGSET_H=regset.h bitmap.h hashtab.h statistics.h hard-reg-set.h +BASIC_BLOCK_H=basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h +GIMPLE_H=gimple.h gimple.def gsstruct.def pointer-set.h vec.h statistics.h ggc.h gtype-desc.h statistics.h ggc.h gtype-desc.h statistics.h basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-operands.h tree-ssa-alias.h internal-fn.h internal-fn.def +TRANS_MEM_H=trans-mem.h +GCOV_IO_H=gcov-io.h gcov-iov.h auto-host.h +COVERAGE_H=coverage.h gcov-io.h gcov-iov.h auto-host.h +DEMANGLE_H=demangle.h +RECOG_H=recog.h +ALIAS_H=alias.h +EMIT_RTL_H=emit-rtl.h +FLAGS_H=flags.h flag-types.h options.h flag-types.h config/i386/i386-opts.h +OPTIONS_H=options.h flag-types.h config/i386/i386-opts.h +FUNCTION_H=function.h line-map.h input.h machmode.h mode-classes.def insn-modes.h +EXPR_H=expr.h insn-config.h function.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h machmode.h mode-classes.def insn-modes.h emit-rtl.h +OPTABS_H=optabs.h insn-codes.h insn-opinit.h +REGS_H=regs.h machmode.h mode-classes.def insn-modes.h hard-reg-set.h +SCHED_INT_H=sched-int.h insn-attr.h insn-attr-common.h hashtab.h statistics.h hard-reg-set.h +SEL_SCHED_IR_H=sel-sched-ir.h insn-attr.h insn-attr-common.h hashtab.h statistics.h hard-reg-set.h +SEL_SCHED_DUMP_H=sel-sched-dump.h sel-sched-ir.h insn-attr.h insn-attr-common.h hashtab.h statistics.h hard-reg-set.h +CFGLOOP_H=cfgloop.h basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h hashtab.h statistics.h sbitmap.h +IPA_UTILS_H=ipa-utils.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def plugin-api.h is-a.h +IPA_REFERENCE_H=ipa-reference.h bitmap.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h +CGRAPH_H=cgraph.h vec.h statistics.h ggc.h gtype-desc.h statistics.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def plugin-api.h is-a.h +DF_H=df.h bitmap.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h alloc-pool.h timevar.h timevar.def +VALTRACK_H=valtrack.h bitmap.h hashtab.h hash-table.h +RESOURCE_H=resource.h hard-reg-set.h df.h bitmap.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h alloc-pool.h timevar.h timevar.def +DDG_H=ddg.h sbitmap.h df.h bitmap.h line-map.h input.h machmode.h mode-classes.def insn-modes.h cfg-flags.def cfghooks.h alloc-pool.h timevar.h timevar.def +GCC_H=gcc.h version.h diagnostic-core.h line-map.h input.h bversion.h diagnostic.def +GGC_H=ggc.h gtype-desc.h statistics.h +GGC_INTERNAL_H=ggc-internal.h ggc.h gtype-desc.h statistics.h +TIMEVAR_H=timevar.h timevar.def +INSN_ATTR_H=insn-attr.h insn-attr-common.h insn-addr.h +INSN_ADDR_H=insn-addr.h +C_COMMON_H=c-family/c-common.h c-family/c-common.def coretypes.h tree.h all-tree.def tree.def c-family/c-common.def line-map.h input.h bversion.h diagnostic.def +C_PRAGMA_H=c-family/c-pragma.h cpplib.h +C_TREE_H=c/c-tree.h c-family/c-common.h c-family/c-common.def coretypes.h tree.h all-tree.def tree.def c-family/c-common.def obstack.h +SYSTEM_H=system.h hwint.h filenames.h +PREDICT_H=predict.h predict.def +CPPLIB_H=cpplib.h +INPUT_H=line-map.h input.h +OPTS_H=obstack.h +DECNUM_H=decimal128Local.h +BACKTRACE_H=backtrace.h +MKDEPS_H=mkdeps.h +SYMTAB_H=obstack.h +CPP_ID_DATA_H=cpp-id-data.h +CPP_INTERNAL_H=cpp-id-data.h +TREE_DUMP_H=tree-dump.h splay-tree.h dumpfile.h +TREE_PASS_H=tree-pass.h timevar.h timevar.def dumpfile.h +TREE_FLOW_H=tree-flow.h tree-flow-inline.h tree-ssa-operands.h bitmap.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-alias.h +TREE_SSA_LIVE_H=tree-ssa-live.h partition.h +SSAEXPAND_H=ssaexpand.h tree-ssa-live.h partition.h +PRETTY_PRINT_H=pretty-print.h obstack.h +TREE_PRETTY_PRINT_H=tree-pretty-print.h pretty-print.h obstack.h +GIMPLE_PRETTY_PRINT_H=gimple-pretty-print.h tree-pretty-print.h pretty-print.h obstack.h +DIAGNOSTIC_CORE_H=diagnostic-core.h line-map.h input.h bversion.h diagnostic.def +DIAGNOSTIC_H=diagnostic.h diagnostic-core.h obstack.h +DWARF2OUT_H=dwarf2out.h dwarf2.def +C_PRETTY_PRINT_H=c-family/c-pretty-print.h pretty-print.h i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h +SCEV_H=tree-scalar-evolution.h ggc.h gtype-desc.h statistics.h tree-chrec.h params.h params.def +OMEGA_H=omega.h params.h params.def +TREE_DATA_REF_H=tree-data-ref.h omega.h params.h params.def graphds.h tree-scalar-evolution.h ggc.h gtype-desc.h statistics.h tree-chrec.h params.h params.def +TREE_INLINE_H=tree-inline.h +REAL_H=real.h machmode.h mode-classes.def insn-modes.h +IRA_INT_H=ira.h ira-int.h cfgloop.h basic-block.h predict.h predict.def vec.h statistics.h ggc.h gtype-desc.h statistics.h function.h hashtab.h statistics.h sbitmap.h alloc-pool.h +LRA_INT_H=lra.h bitmap.h insn-addr.h insn-codes.h lra-int.h +DBGCNT_H=dbgcnt.h dbgcnt.def +LTO_STREAMER_H=lto-streamer.h obstack.h alloc-pool.h +DATA_STREAMER_H=data-streamer.h vec.h statistics.h ggc.h gtype-desc.h statistics.h lto-streamer.h obstack.h alloc-pool.h +GIMPLE_STREAMER_H=gimple-streamer.h lto-streamer.h line-map.h input.h machmode.h mode-classes.def insn-modes.h +TREE_STREAMER_H=tree-streamer.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h +STREAMER_HOOKS_H=streamer-hooks.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h +TREE_VECTORIZER_H=tree-vectorizer.h tree-data-ref.h omega.h params.h params.def graphds.h tree-scalar-evolution.h ggc.h gtype-desc.h statistics.h tree-chrec.h params.h params.def tm.h options.h config/vxworks-dummy.h i386-opts.h target.h target.def target-hooks-macros.h insn-modes.h +IPA_PROP_H=ipa-prop.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-operands.h tree-ssa-alias.h internal-fn.h internal-fn.def alloc-pool.h +IPA_INLINE_H=ipa-inline.h ipa-prop.h coretypes.h tree.h all-tree.def tree.def c-family/c-common.def i386-opts.h real.h machmode.h mode-classes.def insn-modes.h fixed-value.h machmode.h mode-classes.def insn-modes.h double-int.h tree-ssa-operands.h tree-ssa-alias.h internal-fn.h internal-fn.def alloc-pool.h +GSTAB_H=gstab.h stab.def +BITMAP_H=bitmap.h hashtab.h statistics.h +GCC_PLUGIN_H=gcc-plugin.h highlev-plugin-common.h plugin.def config.h auto-host.h hashtab.h +PLUGIN_H=plugin.h gcc-plugin.h highlev-plugin-common.h plugin.def config.h auto-host.h hashtab.h +PLUGIN_VERSION_H=plugin-version.h configargs.h +LIBFUNCS_H=libfuncs.h hashtab.h +GTFILES_H=gt-coverage.h gt-caller-save.h gt-symtab.h gt-alias.h gt-bitmap.h gt-cselib.h gt-cgraph.h gt-ipa-prop.h gt-ipa-cp.h gt-dbxout.h gt-dwarf2asm.h gt-dwarf2cfi.h gt-dwarf2out.h gt-tree-vect-generic.h gt-dojump.h gt-emit-rtl.h gt-explow.h gt-expr.h gt-function.h gt-except.h gt-gcse.h gt-godump.h gt-lists.h gt-optabs.h gt-profile.h gt-mcf.h gt-reg-stack.h gt-cfgrtl.h gt-sdbout.h gt-stor-layout.h gt-stringpool.h gt-tree.h gt-varasm.h gt-gimple.h gt-tree-mudflap.h gt-tree-ssanames.h gt-tree-eh.h gt-tree-ssa-address.h gt-tree-cfg.h gt-tree-dfa.h gt-tree-iterator.h gt-gimplify.h gt-tree-scalar-evolution.h gt-tree-profile.h gt-tree-nested.h gt-tree-parloops.h gt-omp-low.h gt-targhooks.h gt-i386.h gt-passes.h gt-cgraphunit.h gt-cgraphclones.h gt-tree-ssa-propagate.h gt-tree-phinodes.h gt-lto-symtab.h gt-trans-mem.h gt-asan.h gt-tsan.h gt-ada-decl.h gt-ada-trans.h gt-ada-utils.h gt-ada-misc.h gt-c-c-lang.h gt-c-c-decl.h gt-c-family-c-common.h gt-c-family-c-cppbuiltin.h gt-c-family-c-pragma.h gt-c-c-objc-common.h gt-c-c-parser.h gt-cp-rtti.h gt-cp-mangle.h gt-cp-name-lookup.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h gt-cp-pt.h gt-cp-repo.h gt-cp-semantics.h gt-cp-tree.h gt-cp-parser.h gt-cp-method.h gt-cp-typeck2.h gt-c-family-c-common.h gt-c-family-c-lex.h gt-c-family-c-pragma.h gt-cp-class.h gt-cp-cp-objcp-common.h gt-cp-cp-lang.h gt-cp-except.h gt-fortran-f95-lang.h gt-fortran-trans-decl.h gt-fortran-trans-intrinsic.h gt-fortran-trans-io.h gt-fortran-trans-stmt.h gt-fortran-trans-types.h gt-go-go-lang.h gt-java-builtins.h gt-java-class.h gt-java-constants.h gt-java-decl.h gt-java-expr.h gt-java-jcf-parse.h gt-java-lang.h gt-java-mangle.h gt-java-resource.h gt-lto-lto-lang.h gt-lto-lto.h gt-objc-objc-act.h gt-objc-objc-runtime-shared-support.h gt-objc-objc-gnu-runtime-abi-01.h gt-objc-objc-next-runtime-abi-01.h gt-objc-objc-next-runtime-abi-02.h gt-c-c-parser.h gt-c-c-decl.h gt-c-c-objc-common.h gt-c-family-c-common.h gt-c-family-c-cppbuiltin.h gt-c-family-c-pragma.h gt-cp-rtti.h gt-cp-mangle.h gt-cp-name-lookup.h gt-cp-call.h gt-cp-decl.h gt-cp-decl2.h gt-cp-pt.h gt-cp-repo.h gt-cp-semantics.h gt-cp-tree.h gt-cp-parser.h gt-cp-method.h gt-cp-typeck2.h gt-c-family-c-common.h gt-c-family-c-lex.h gt-c-family-c-pragma.h gt-cp-class.h gt-cp-cp-objcp-common.h gt-objc-objc-act.h gt-objc-objc-runtime-shared-support.h gt-objc-objc-gnu-runtime-abi-01.h gt-objc-objc-next-runtime-abi-01.h gt-objc-objc-next-runtime-abi-02.h gt-c-family-c-cppbuiltin.h +GTFILES_LANG_H=gtype-ada.h gtype-c.h gtype-cp.h gtype-fortran.h gtype-go.h gtype-java.h gtype-lto.h gtype-objc.h gtype-objcp.h diff --git a/src/include/basic-block.h b/src/include/basic-block.h new file mode 100644 index 0000000..90eb57b --- /dev/null +++ b/src/include/basic-block.h @@ -0,0 +1,974 @@ +/* Define control flow data structures for the CFG. + Copyright (C) 1987-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_BASIC_BLOCK_H +#define GCC_BASIC_BLOCK_H + +#include "predict.h" +#include "vec.h" +#include "function.h" + +/* Type we use to hold basic block counters. Should be at least + 64bit. Although a counter cannot be negative, we use a signed + type, because erroneous negative counts can be generated when the + flow graph is manipulated by various optimizations. A signed type + makes those easy to detect. */ +typedef HOST_WIDEST_INT gcov_type; +typedef unsigned HOST_WIDEST_INT gcov_type_unsigned; + +/* Control flow edge information. */ +struct GTY((user)) edge_def { + /* The two blocks at the ends of the edge. */ + basic_block src; + basic_block dest; + + /* Instructions queued on the edge. */ + union edge_def_insns { + gimple_seq g; + rtx r; + } insns; + + /* Auxiliary info specific to a pass. */ + PTR aux; + + /* Location of any goto implicit in the edge. */ + location_t goto_locus; + + /* The index number corresponding to this edge in the edge vector + dest->preds. */ + unsigned int dest_idx; + + int flags; /* see cfg-flags.def */ + int probability; /* biased by REG_BR_PROB_BASE */ + gcov_type count; /* Expected number of executions calculated + in profile.c */ +}; + + +/* Garbage collection and PCH support for edge_def. */ +extern void gt_ggc_mx (edge_def *e); +extern void gt_pch_nx (edge_def *e); +extern void gt_pch_nx (edge_def *e, gt_pointer_operator, void *); + +/* Masks for edge.flags. */ +#define DEF_EDGE_FLAG(NAME,IDX) EDGE_##NAME = 1 << IDX , +enum cfg_edge_flags { +#include "cfg-flags.def" + LAST_CFG_EDGE_FLAG /* this is only used for EDGE_ALL_FLAGS */ +}; +#undef DEF_EDGE_FLAG + +/* Bit mask for all edge flags. */ +#define EDGE_ALL_FLAGS ((LAST_CFG_EDGE_FLAG - 1) * 2 - 1) + +/* The following four flags all indicate something special about an edge. + Test the edge flags on EDGE_COMPLEX to detect all forms of "strange" + control flow transfers. */ +#define EDGE_COMPLEX \ + (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL | EDGE_EH | EDGE_PRESERVE) + +/* Counter summary from the last set of coverage counts read by + profile.c. */ +extern const struct gcov_ctr_summary *profile_info; + +/* Working set size statistics for a given percentage of the entire + profile (sum_all from the counter summary). */ +typedef struct gcov_working_set_info +{ + /* Number of hot counters included in this working set. */ + unsigned num_counters; + /* Smallest counter included in this working set. */ + gcov_type min_counter; +} gcov_working_set_t; + +/* Structure to gather statistic about profile consistency, per pass. + An array of this structure, indexed by pass static number, is allocated + in passes.c. The structure is defined here so that different CFG modes + can do their book-keeping via CFG hooks. + + For every field[2], field[0] is the count before the pass runs, and + field[1] is the post-pass count. This allows us to monitor the effect + of each individual pass on the profile consistency. + + This structure is not supposed to be used by anything other than passes.c + and one CFG hook per CFG mode. */ +struct profile_record +{ + /* The number of basic blocks where sum(freq) of the block's predecessors + doesn't match reasonably well with the incoming frequency. */ + int num_mismatched_freq_in[2]; + /* Likewise for a basic block's successors. */ + int num_mismatched_freq_out[2]; + /* The number of basic blocks where sum(count) of the block's predecessors + doesn't match reasonably well with the incoming frequency. */ + int num_mismatched_count_in[2]; + /* Likewise for a basic block's successors. */ + int num_mismatched_count_out[2]; + /* A weighted cost of the run-time of the function body. */ + gcov_type time[2]; + /* A weighted cost of the size of the function body. */ + int size[2]; + /* True iff this pass actually was run. */ + bool run; +}; + +/* Declared in cfgloop.h. */ +struct loop; + +struct GTY(()) rtl_bb_info { + /* The first insn of the block is embedded into bb->il.x. */ + /* The last insn of the block. */ + rtx end_; + + /* In CFGlayout mode points to insn notes/jumptables to be placed just before + and after the block. */ + rtx header_; + rtx footer_; +}; + +struct GTY(()) gimple_bb_info { + /* Sequence of statements in this block. */ + gimple_seq seq; + + /* PHI nodes for this block. */ + gimple_seq phi_nodes; +}; + +/* A basic block is a sequence of instructions with only one entry and + only one exit. If any one of the instructions are executed, they + will all be executed, and in sequence from first to last. + + There may be COND_EXEC instructions in the basic block. The + COND_EXEC *instructions* will be executed -- but if the condition + is false the conditionally executed *expressions* will of course + not be executed. We don't consider the conditionally executed + expression (which might have side-effects) to be in a separate + basic block because the program counter will always be at the same + location after the COND_EXEC instruction, regardless of whether the + condition is true or not. + + Basic blocks need not start with a label nor end with a jump insn. + For example, a previous basic block may just "conditionally fall" + into the succeeding basic block, and the last basic block need not + end with a jump insn. Block 0 is a descendant of the entry block. + + A basic block beginning with two labels cannot have notes between + the labels. + + Data for jump tables are stored in jump_insns that occur in no + basic block even though these insns can follow or precede insns in + basic blocks. */ + +/* Basic block information indexed by block number. */ +struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_def { + /* The edges into and out of the block. */ + vec *preds; + vec *succs; + + /* Auxiliary info specific to a pass. */ + PTR GTY ((skip (""))) aux; + + /* Innermost loop containing the block. */ + struct loop *loop_father; + + /* The dominance and postdominance information node. */ + struct et_node * GTY ((skip (""))) dom[2]; + + /* Previous and next blocks in the chain. */ + basic_block prev_bb; + basic_block next_bb; + + union basic_block_il_dependent { + struct gimple_bb_info GTY ((tag ("0"))) gimple; + struct { + rtx head_; + struct rtl_bb_info * rtl; + } GTY ((tag ("1"))) x; + } GTY ((desc ("((%1.flags & BB_RTL) != 0)"))) il; + + /* Various flags. See cfg-flags.def. */ + int flags; + + /* The index of this block. */ + int index; + + /* Expected number of executions: calculated in profile.c. */ + gcov_type count; + + /* Expected frequency. Normalized to be in range 0 to BB_FREQ_MAX. */ + int frequency; + + /* The discriminator for this block. The discriminator distinguishes + among several basic blocks that share a common locus, allowing for + more accurate sample-based profiling. */ + int discriminator; +}; + +/* This ensures that struct gimple_bb_info is smaller than + struct rtl_bb_info, so that inlining the former into basic_block_def + is the better choice. */ +typedef int __assert_gimple_bb_smaller_rtl_bb + [(int)sizeof(struct rtl_bb_info) + - (int)sizeof (struct gimple_bb_info)]; + + +#define BB_FREQ_MAX 10000 + +/* Masks for basic_block.flags. */ +#define DEF_BASIC_BLOCK_FLAG(NAME,IDX) BB_##NAME = 1 << IDX , +enum cfg_bb_flags +{ +#include "cfg-flags.def" + LAST_CFG_BB_FLAG /* this is only used for BB_ALL_FLAGS */ +}; +#undef DEF_BASIC_BLOCK_FLAG + +/* Bit mask for all basic block flags. */ +#define BB_ALL_FLAGS ((LAST_CFG_BB_FLAG - 1) * 2 - 1) + +/* Bit mask for all basic block flags that must be preserved. These are + the bit masks that are *not* cleared by clear_bb_flags. */ +#define BB_FLAGS_TO_PRESERVE \ + (BB_DISABLE_SCHEDULE | BB_RTL | BB_NON_LOCAL_GOTO_TARGET \ + | BB_HOT_PARTITION | BB_COLD_PARTITION) + +/* Dummy bitmask for convenience in the hot/cold partitioning code. */ +#define BB_UNPARTITIONED 0 + +/* Partitions, to be used when partitioning hot and cold basic blocks into + separate sections. */ +#define BB_PARTITION(bb) ((bb)->flags & (BB_HOT_PARTITION|BB_COLD_PARTITION)) +#define BB_SET_PARTITION(bb, part) do { \ + basic_block bb_ = (bb); \ + bb_->flags = ((bb_->flags & ~(BB_HOT_PARTITION|BB_COLD_PARTITION)) \ + | (part)); \ +} while (0) + +#define BB_COPY_PARTITION(dstbb, srcbb) \ + BB_SET_PARTITION (dstbb, BB_PARTITION (srcbb)) + +/* State of dominance information. */ + +enum dom_state +{ + DOM_NONE, /* Not computed at all. */ + DOM_NO_FAST_QUERY, /* The data is OK, but the fast query data are not usable. */ + DOM_OK /* Everything is ok. */ +}; + +/* What sort of profiling information we have. */ +enum profile_status_d +{ + PROFILE_ABSENT, + PROFILE_GUESSED, + PROFILE_READ, + PROFILE_LAST /* Last value, used by profile streaming. */ +}; + +/* A structure to group all the per-function control flow graph data. + The x_* prefixing is necessary because otherwise references to the + fields of this struct are interpreted as the defines for backward + source compatibility following the definition of this struct. */ +struct GTY(()) control_flow_graph { + /* Block pointers for the exit and entry of a function. + These are always the head and tail of the basic block list. */ + basic_block x_entry_block_ptr; + basic_block x_exit_block_ptr; + + /* Index by basic block number, get basic block struct info. */ + vec *x_basic_block_info; + + /* Number of basic blocks in this flow graph. */ + int x_n_basic_blocks; + + /* Number of edges in this flow graph. */ + int x_n_edges; + + /* The first free basic block number. */ + int x_last_basic_block; + + /* UIDs for LABEL_DECLs. */ + int last_label_uid; + + /* Mapping of labels to their associated blocks. At present + only used for the gimple CFG. */ + vec *x_label_to_block_map; + + enum profile_status_d x_profile_status; + + /* Whether the dominators and the postdominators are available. */ + enum dom_state x_dom_computed[2]; + + /* Number of basic blocks in the dominance tree. */ + unsigned x_n_bbs_in_dom_tree[2]; + + /* Maximal number of entities in the single jumptable. Used to estimate + final flowgraph size. */ + int max_jumptable_ents; +}; + +/* Defines for accessing the fields of the CFG structure for function FN. */ +#define ENTRY_BLOCK_PTR_FOR_FUNCTION(FN) ((FN)->cfg->x_entry_block_ptr) +#define EXIT_BLOCK_PTR_FOR_FUNCTION(FN) ((FN)->cfg->x_exit_block_ptr) +#define basic_block_info_for_function(FN) ((FN)->cfg->x_basic_block_info) +#define n_basic_blocks_for_function(FN) ((FN)->cfg->x_n_basic_blocks) +#define n_edges_for_function(FN) ((FN)->cfg->x_n_edges) +#define last_basic_block_for_function(FN) ((FN)->cfg->x_last_basic_block) +#define label_to_block_map_for_function(FN) ((FN)->cfg->x_label_to_block_map) +#define profile_status_for_function(FN) ((FN)->cfg->x_profile_status) + +#define BASIC_BLOCK_FOR_FUNCTION(FN,N) \ + ((*basic_block_info_for_function(FN))[(N)]) +#define SET_BASIC_BLOCK_FOR_FUNCTION(FN,N,BB) \ + ((*basic_block_info_for_function(FN))[(N)] = (BB)) + +/* Defines for textual backward source compatibility. */ +#define ENTRY_BLOCK_PTR (cfun->cfg->x_entry_block_ptr) +#define EXIT_BLOCK_PTR (cfun->cfg->x_exit_block_ptr) +#define basic_block_info (cfun->cfg->x_basic_block_info) +#define n_basic_blocks (cfun->cfg->x_n_basic_blocks) +#define n_edges (cfun->cfg->x_n_edges) +#define last_basic_block (cfun->cfg->x_last_basic_block) +#define label_to_block_map (cfun->cfg->x_label_to_block_map) +#define profile_status (cfun->cfg->x_profile_status) + +#define BASIC_BLOCK(N) ((*basic_block_info)[(N)]) +#define SET_BASIC_BLOCK(N,BB) ((*basic_block_info)[(N)] = (BB)) + +/* For iterating over basic blocks. */ +#define FOR_BB_BETWEEN(BB, FROM, TO, DIR) \ + for (BB = FROM; BB != TO; BB = BB->DIR) + +#define FOR_EACH_BB_FN(BB, FN) \ + FOR_BB_BETWEEN (BB, (FN)->cfg->x_entry_block_ptr->next_bb, (FN)->cfg->x_exit_block_ptr, next_bb) + +#define FOR_EACH_BB(BB) FOR_EACH_BB_FN (BB, cfun) + +#define FOR_EACH_BB_REVERSE_FN(BB, FN) \ + FOR_BB_BETWEEN (BB, (FN)->cfg->x_exit_block_ptr->prev_bb, (FN)->cfg->x_entry_block_ptr, prev_bb) + +#define FOR_EACH_BB_REVERSE(BB) FOR_EACH_BB_REVERSE_FN(BB, cfun) + +/* For iterating over insns in basic block. */ +#define FOR_BB_INSNS(BB, INSN) \ + for ((INSN) = BB_HEAD (BB); \ + (INSN) && (INSN) != NEXT_INSN (BB_END (BB)); \ + (INSN) = NEXT_INSN (INSN)) + +/* For iterating over insns in basic block when we might remove the + current insn. */ +#define FOR_BB_INSNS_SAFE(BB, INSN, CURR) \ + for ((INSN) = BB_HEAD (BB), (CURR) = (INSN) ? NEXT_INSN ((INSN)): NULL; \ + (INSN) && (INSN) != NEXT_INSN (BB_END (BB)); \ + (INSN) = (CURR), (CURR) = (INSN) ? NEXT_INSN ((INSN)) : NULL) + +#define FOR_BB_INSNS_REVERSE(BB, INSN) \ + for ((INSN) = BB_END (BB); \ + (INSN) && (INSN) != PREV_INSN (BB_HEAD (BB)); \ + (INSN) = PREV_INSN (INSN)) + +#define FOR_BB_INSNS_REVERSE_SAFE(BB, INSN, CURR) \ + for ((INSN) = BB_END (BB),(CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL; \ + (INSN) && (INSN) != PREV_INSN (BB_HEAD (BB)); \ + (INSN) = (CURR), (CURR) = (INSN) ? PREV_INSN ((INSN)) : NULL) + +/* Cycles through _all_ basic blocks, even the fake ones (entry and + exit block). */ + +#define FOR_ALL_BB(BB) \ + for (BB = ENTRY_BLOCK_PTR; BB; BB = BB->next_bb) + +#define FOR_ALL_BB_FN(BB, FN) \ + for (BB = ENTRY_BLOCK_PTR_FOR_FUNCTION (FN); BB; BB = BB->next_bb) + + +/* Stuff for recording basic block info. */ + +#define BB_HEAD(B) (B)->il.x.head_ +#define BB_END(B) (B)->il.x.rtl->end_ +#define BB_HEADER(B) (B)->il.x.rtl->header_ +#define BB_FOOTER(B) (B)->il.x.rtl->footer_ + +/* Special block numbers [markers] for entry and exit. + Neither of them is supposed to hold actual statements. */ +#define ENTRY_BLOCK (0) +#define EXIT_BLOCK (1) + +/* The two blocks that are always in the cfg. */ +#define NUM_FIXED_BLOCKS (2) + +#define set_block_for_insn(INSN, BB) (BLOCK_FOR_INSN (INSN) = BB) + +extern void compute_bb_for_insn (void); +extern unsigned int free_bb_for_insn (void); +extern void update_bb_for_insn (basic_block); + +extern void insert_insn_on_edge (rtx, edge); +basic_block split_edge_and_insert (edge, rtx); + +extern void commit_one_edge_insertion (edge e); +extern void commit_edge_insertions (void); + +extern edge unchecked_make_edge (basic_block, basic_block, int); +extern edge cached_make_edge (sbitmap, basic_block, basic_block, int); +extern edge make_edge (basic_block, basic_block, int); +extern edge make_single_succ_edge (basic_block, basic_block, int); +extern void remove_edge_raw (edge); +extern void redirect_edge_succ (edge, basic_block); +extern edge redirect_edge_succ_nodup (edge, basic_block); +extern void redirect_edge_pred (edge, basic_block); +extern basic_block create_basic_block_structure (rtx, rtx, rtx, basic_block); +extern void clear_bb_flags (void); +extern void dump_bb_info (FILE *, basic_block, int, int, bool, bool); +extern void dump_edge_info (FILE *, edge, int, int); +extern void brief_dump_cfg (FILE *, int); +extern void clear_edges (void); +extern void scale_bbs_frequencies_int (basic_block *, int, int, int); +extern void scale_bbs_frequencies_gcov_type (basic_block *, int, gcov_type, + gcov_type); + +/* Structure to group all of the information to process IF-THEN and + IF-THEN-ELSE blocks for the conditional execution support. This + needs to be in a public file in case the IFCVT macros call + functions passing the ce_if_block data structure. */ + +typedef struct ce_if_block +{ + basic_block test_bb; /* First test block. */ + basic_block then_bb; /* THEN block. */ + basic_block else_bb; /* ELSE block or NULL. */ + basic_block join_bb; /* Join THEN/ELSE blocks. */ + basic_block last_test_bb; /* Last bb to hold && or || tests. */ + int num_multiple_test_blocks; /* # of && and || basic blocks. */ + int num_and_and_blocks; /* # of && blocks. */ + int num_or_or_blocks; /* # of || blocks. */ + int num_multiple_test_insns; /* # of insns in && and || blocks. */ + int and_and_p; /* Complex test is &&. */ + int num_then_insns; /* # of insns in THEN block. */ + int num_else_insns; /* # of insns in ELSE block. */ + int pass; /* Pass number. */ +} ce_if_block_t; + +/* This structure maintains an edge list vector. */ +/* FIXME: Make this a vec. */ +struct edge_list +{ + int num_edges; + edge *index_to_edge; +}; + +/* The base value for branch probability notes and edge probabilities. */ +#define REG_BR_PROB_BASE 10000 + +/* This is the value which indicates no edge is present. */ +#define EDGE_INDEX_NO_EDGE -1 + +/* EDGE_INDEX returns an integer index for an edge, or EDGE_INDEX_NO_EDGE + if there is no edge between the 2 basic blocks. */ +#define EDGE_INDEX(el, pred, succ) (find_edge_index ((el), (pred), (succ))) + +/* INDEX_EDGE_PRED_BB and INDEX_EDGE_SUCC_BB return a pointer to the basic + block which is either the pred or succ end of the indexed edge. */ +#define INDEX_EDGE_PRED_BB(el, index) ((el)->index_to_edge[(index)]->src) +#define INDEX_EDGE_SUCC_BB(el, index) ((el)->index_to_edge[(index)]->dest) + +/* INDEX_EDGE returns a pointer to the edge. */ +#define INDEX_EDGE(el, index) ((el)->index_to_edge[(index)]) + +/* Number of edges in the compressed edge list. */ +#define NUM_EDGES(el) ((el)->num_edges) + +/* BB is assumed to contain conditional jump. Return the fallthru edge. */ +#define FALLTHRU_EDGE(bb) (EDGE_SUCC ((bb), 0)->flags & EDGE_FALLTHRU \ + ? EDGE_SUCC ((bb), 0) : EDGE_SUCC ((bb), 1)) + +/* BB is assumed to contain conditional jump. Return the branch edge. */ +#define BRANCH_EDGE(bb) (EDGE_SUCC ((bb), 0)->flags & EDGE_FALLTHRU \ + ? EDGE_SUCC ((bb), 1) : EDGE_SUCC ((bb), 0)) + +#define RDIV(X,Y) (((X) + (Y) / 2) / (Y)) +/* Return expected execution frequency of the edge E. */ +#define EDGE_FREQUENCY(e) RDIV ((e)->src->frequency * (e)->probability, \ + REG_BR_PROB_BASE) + +/* Return nonzero if edge is critical. */ +#define EDGE_CRITICAL_P(e) (EDGE_COUNT ((e)->src->succs) >= 2 \ + && EDGE_COUNT ((e)->dest->preds) >= 2) + +#define EDGE_COUNT(ev) vec_safe_length (ev) +#define EDGE_I(ev,i) (*ev)[(i)] +#define EDGE_PRED(bb,i) (*(bb)->preds)[(i)] +#define EDGE_SUCC(bb,i) (*(bb)->succs)[(i)] + +/* Returns true if BB has precisely one successor. */ + +static inline bool +single_succ_p (const_basic_block bb) +{ + return EDGE_COUNT (bb->succs) == 1; +} + +/* Returns true if BB has precisely one predecessor. */ + +static inline bool +single_pred_p (const_basic_block bb) +{ + return EDGE_COUNT (bb->preds) == 1; +} + +/* Returns the single successor edge of basic block BB. Aborts if + BB does not have exactly one successor. */ + +static inline edge +single_succ_edge (const_basic_block bb) +{ + gcc_checking_assert (single_succ_p (bb)); + return EDGE_SUCC (bb, 0); +} + +/* Returns the single predecessor edge of basic block BB. Aborts + if BB does not have exactly one predecessor. */ + +static inline edge +single_pred_edge (const_basic_block bb) +{ + gcc_checking_assert (single_pred_p (bb)); + return EDGE_PRED (bb, 0); +} + +/* Returns the single successor block of basic block BB. Aborts + if BB does not have exactly one successor. */ + +static inline basic_block +single_succ (const_basic_block bb) +{ + return single_succ_edge (bb)->dest; +} + +/* Returns the single predecessor block of basic block BB. Aborts + if BB does not have exactly one predecessor.*/ + +static inline basic_block +single_pred (const_basic_block bb) +{ + return single_pred_edge (bb)->src; +} + +/* Iterator object for edges. */ + +typedef struct { + unsigned index; + vec **container; +} edge_iterator; + +static inline vec * +ei_container (edge_iterator i) +{ + gcc_checking_assert (i.container); + return *i.container; +} + +#define ei_start(iter) ei_start_1 (&(iter)) +#define ei_last(iter) ei_last_1 (&(iter)) + +/* Return an iterator pointing to the start of an edge vector. */ +static inline edge_iterator +ei_start_1 (vec **ev) +{ + edge_iterator i; + + i.index = 0; + i.container = ev; + + return i; +} + +/* Return an iterator pointing to the last element of an edge + vector. */ +static inline edge_iterator +ei_last_1 (vec **ev) +{ + edge_iterator i; + + i.index = EDGE_COUNT (*ev) - 1; + i.container = ev; + + return i; +} + +/* Is the iterator `i' at the end of the sequence? */ +static inline bool +ei_end_p (edge_iterator i) +{ + return (i.index == EDGE_COUNT (ei_container (i))); +} + +/* Is the iterator `i' at one position before the end of the + sequence? */ +static inline bool +ei_one_before_end_p (edge_iterator i) +{ + return (i.index + 1 == EDGE_COUNT (ei_container (i))); +} + +/* Advance the iterator to the next element. */ +static inline void +ei_next (edge_iterator *i) +{ + gcc_checking_assert (i->index < EDGE_COUNT (ei_container (*i))); + i->index++; +} + +/* Move the iterator to the previous element. */ +static inline void +ei_prev (edge_iterator *i) +{ + gcc_checking_assert (i->index > 0); + i->index--; +} + +/* Return the edge pointed to by the iterator `i'. */ +static inline edge +ei_edge (edge_iterator i) +{ + return EDGE_I (ei_container (i), i.index); +} + +/* Return an edge pointed to by the iterator. Do it safely so that + NULL is returned when the iterator is pointing at the end of the + sequence. */ +static inline edge +ei_safe_edge (edge_iterator i) +{ + return !ei_end_p (i) ? ei_edge (i) : NULL; +} + +/* Return 1 if we should continue to iterate. Return 0 otherwise. + *Edge P is set to the next edge if we are to continue to iterate + and NULL otherwise. */ + +static inline bool +ei_cond (edge_iterator ei, edge *p) +{ + if (!ei_end_p (ei)) + { + *p = ei_edge (ei); + return 1; + } + else + { + *p = NULL; + return 0; + } +} + +/* This macro serves as a convenient way to iterate each edge in a + vector of predecessor or successor edges. It must not be used when + an element might be removed during the traversal, otherwise + elements will be missed. Instead, use a for-loop like that shown + in the following pseudo-code: + + FOR (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) + { + IF (e != taken_edge) + remove_edge (e); + ELSE + ei_next (&ei); + } +*/ + +#define FOR_EACH_EDGE(EDGE,ITER,EDGE_VEC) \ + for ((ITER) = ei_start ((EDGE_VEC)); \ + ei_cond ((ITER), &(EDGE)); \ + ei_next (&(ITER))) + +#define CLEANUP_EXPENSIVE 1 /* Do relatively expensive optimizations + except for edge forwarding */ +#define CLEANUP_CROSSJUMP 2 /* Do crossjumping. */ +#define CLEANUP_POST_REGSTACK 4 /* We run after reg-stack and need + to care REG_DEAD notes. */ +#define CLEANUP_THREADING 8 /* Do jump threading. */ +#define CLEANUP_NO_INSN_DEL 16 /* Do not try to delete trivially dead + insns. */ +#define CLEANUP_CFGLAYOUT 32 /* Do cleanup in cfglayout mode. */ +#define CLEANUP_CFG_CHANGED 64 /* The caller changed the CFG. */ + +/* In cfganal.c */ +extern void bitmap_intersection_of_succs (sbitmap, sbitmap *, basic_block); +extern void bitmap_intersection_of_preds (sbitmap, sbitmap *, basic_block); +extern void bitmap_union_of_succs (sbitmap, sbitmap *, basic_block); +extern void bitmap_union_of_preds (sbitmap, sbitmap *, basic_block); + +/* In lcm.c */ +extern struct edge_list *pre_edge_lcm (int, sbitmap *, sbitmap *, + sbitmap *, sbitmap *, sbitmap **, + sbitmap **); +extern struct edge_list *pre_edge_rev_lcm (int, sbitmap *, + sbitmap *, sbitmap *, + sbitmap *, sbitmap **, + sbitmap **); +extern void compute_available (sbitmap *, sbitmap *, sbitmap *, sbitmap *); + +/* In predict.c */ +extern bool maybe_hot_bb_p (struct function *, const_basic_block); +extern bool maybe_hot_edge_p (edge); +extern bool probably_never_executed_bb_p (struct function *, const_basic_block); +extern bool optimize_bb_for_size_p (const_basic_block); +extern bool optimize_bb_for_speed_p (const_basic_block); +extern bool optimize_edge_for_size_p (edge); +extern bool optimize_edge_for_speed_p (edge); +extern bool optimize_loop_for_size_p (struct loop *); +extern bool optimize_loop_for_speed_p (struct loop *); +extern bool optimize_loop_nest_for_size_p (struct loop *); +extern bool optimize_loop_nest_for_speed_p (struct loop *); +extern bool gimple_predicted_by_p (const_basic_block, enum br_predictor); +extern bool rtl_predicted_by_p (const_basic_block, enum br_predictor); +extern void gimple_predict_edge (edge, enum br_predictor, int); +extern void rtl_predict_edge (edge, enum br_predictor, int); +extern void predict_edge_def (edge, enum br_predictor, enum prediction); +extern void guess_outgoing_edge_probabilities (basic_block); +extern void remove_predictions_associated_with_edge (edge); +extern bool edge_probability_reliable_p (const_edge); +extern bool br_prob_note_reliable_p (const_rtx); +extern bool predictable_edge_p (edge); + +/* In cfg.c */ +extern void init_flow (struct function *); +extern void debug_bb (basic_block); +extern basic_block debug_bb_n (int); +extern void dump_flow_info (FILE *, int); +extern void expunge_block (basic_block); +extern void link_block (basic_block, basic_block); +extern void unlink_block (basic_block); +extern void compact_blocks (void); +extern basic_block alloc_block (void); +extern void alloc_aux_for_blocks (int); +extern void clear_aux_for_blocks (void); +extern void free_aux_for_blocks (void); +extern void alloc_aux_for_edge (edge, int); +extern void alloc_aux_for_edges (int); +extern void clear_aux_for_edges (void); +extern void free_aux_for_edges (void); + +/* In cfganal.c */ +extern void find_unreachable_blocks (void); +extern bool mark_dfs_back_edges (void); +struct edge_list * create_edge_list (void); +void free_edge_list (struct edge_list *); +void print_edge_list (FILE *, struct edge_list *); +void verify_edge_list (FILE *, struct edge_list *); +int find_edge_index (struct edge_list *, basic_block, basic_block); +edge find_edge (basic_block, basic_block); +extern void remove_fake_edges (void); +extern void remove_fake_exit_edges (void); +extern void add_noreturn_fake_exit_edges (void); +extern void connect_infinite_loops_to_exit (void); +extern int post_order_compute (int *, bool, bool); +extern basic_block dfs_find_deadend (basic_block); +extern int inverted_post_order_compute (int *); +extern int pre_and_rev_post_order_compute (int *, int *, bool); +extern int dfs_enumerate_from (basic_block, int, + bool (*)(const_basic_block, const void *), + basic_block *, int, const void *); +extern void compute_dominance_frontiers (struct bitmap_head_def *); +extern bitmap compute_idf (bitmap, struct bitmap_head_def *); + +/* In cfgrtl.c */ +extern rtx block_label (basic_block); +extern rtx bb_note (basic_block); +extern bool purge_all_dead_edges (void); +extern bool purge_dead_edges (basic_block); +extern bool fixup_abnormal_edges (void); +extern basic_block force_nonfallthru_and_redirect (edge, basic_block, rtx); +extern bool contains_no_active_insn_p (const_basic_block); +extern bool forwarder_block_p (const_basic_block); +extern bool can_fallthru (basic_block, basic_block); + +/* In cfgbuild.c. */ +extern void find_many_sub_basic_blocks (sbitmap); +extern void rtl_make_eh_edge (sbitmap, basic_block, rtx); + +enum replace_direction { dir_none, dir_forward, dir_backward, dir_both }; + +/* In cfgcleanup.c. */ +extern bool cleanup_cfg (int); +extern int flow_find_cross_jump (basic_block, basic_block, rtx *, rtx *, + enum replace_direction*); +extern int flow_find_head_matching_sequence (basic_block, basic_block, + rtx *, rtx *, int); + +extern bool delete_unreachable_blocks (void); + +extern void update_br_prob_note (basic_block); +extern bool inside_basic_block_p (const_rtx); +extern bool control_flow_insn_p (const_rtx); +extern rtx get_last_bb_insn (basic_block); + +/* In dominance.c */ + +enum cdi_direction +{ + CDI_DOMINATORS = 1, + CDI_POST_DOMINATORS = 2 +}; + +extern enum dom_state dom_info_state (enum cdi_direction); +extern void set_dom_info_availability (enum cdi_direction, enum dom_state); +extern bool dom_info_available_p (enum cdi_direction); +extern void calculate_dominance_info (enum cdi_direction); +extern void free_dominance_info (enum cdi_direction); +extern basic_block nearest_common_dominator (enum cdi_direction, + basic_block, basic_block); +extern basic_block nearest_common_dominator_for_set (enum cdi_direction, + bitmap); +extern void set_immediate_dominator (enum cdi_direction, basic_block, + basic_block); +extern basic_block get_immediate_dominator (enum cdi_direction, basic_block); +extern bool dominated_by_p (enum cdi_direction, const_basic_block, const_basic_block); +extern vec get_dominated_by (enum cdi_direction, basic_block); +extern vec get_dominated_by_region (enum cdi_direction, + basic_block *, + unsigned); +extern vec get_dominated_to_depth (enum cdi_direction, + basic_block, int); +extern vec get_all_dominated_blocks (enum cdi_direction, + basic_block); +extern void add_to_dominance_info (enum cdi_direction, basic_block); +extern void delete_from_dominance_info (enum cdi_direction, basic_block); +basic_block recompute_dominator (enum cdi_direction, basic_block); +extern void redirect_immediate_dominators (enum cdi_direction, basic_block, + basic_block); +extern void iterate_fix_dominators (enum cdi_direction, + vec , bool); +extern void verify_dominators (enum cdi_direction); +extern basic_block first_dom_son (enum cdi_direction, basic_block); +extern basic_block next_dom_son (enum cdi_direction, basic_block); +unsigned bb_dom_dfs_in (enum cdi_direction, basic_block); +unsigned bb_dom_dfs_out (enum cdi_direction, basic_block); + +extern edge try_redirect_by_replacing_jump (edge, basic_block, bool); +extern void break_superblocks (void); +extern void relink_block_chain (bool); +extern void update_bb_profile_for_threading (basic_block, int, gcov_type, edge); +extern void init_rtl_bb_info (basic_block); + +extern void initialize_original_copy_tables (void); +extern void free_original_copy_tables (void); +extern void set_bb_original (basic_block, basic_block); +extern basic_block get_bb_original (basic_block); +extern void set_bb_copy (basic_block, basic_block); +extern basic_block get_bb_copy (basic_block); +void set_loop_copy (struct loop *, struct loop *); +struct loop *get_loop_copy (struct loop *); + +#include "cfghooks.h" + +/* Return true when one of the predecessor edges of BB is marked with EDGE_EH. */ +static inline bool +bb_has_eh_pred (basic_block bb) +{ + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, bb->preds) + { + if (e->flags & EDGE_EH) + return true; + } + return false; +} + +/* Return true when one of the predecessor edges of BB is marked with EDGE_ABNORMAL. */ +static inline bool +bb_has_abnormal_pred (basic_block bb) +{ + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, bb->preds) + { + if (e->flags & EDGE_ABNORMAL) + return true; + } + return false; +} + +/* Return the fallthru edge in EDGES if it exists, NULL otherwise. */ +static inline edge +find_fallthru_edge (vec *edges) +{ + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, edges) + if (e->flags & EDGE_FALLTHRU) + break; + + return e; +} + +/* In cfgloopmanip.c. */ +extern edge mfb_kj_edge; +extern bool mfb_keep_just (edge); + +/* In cfgexpand.c. */ +extern void rtl_profile_for_bb (basic_block); +extern void rtl_profile_for_edge (edge); +extern void default_rtl_profile (void); + +/* In profile.c. */ +extern gcov_working_set_t *find_working_set(unsigned pct_times_10); + +/* Check tha probability is sane. */ + +static inline void +check_probability (int prob) +{ + gcc_checking_assert (prob >= 0 && prob <= REG_BR_PROB_BASE); +} + +/* Given PROB1 and PROB2, return PROB1*PROB2/REG_BR_PROB_BASE. + Used to combine BB probabilities. */ + +static inline int +combine_probabilities (int prob1, int prob2) +{ + check_probability (prob1); + check_probability (prob2); + return RDIV (prob1 * prob2, REG_BR_PROB_BASE); +} + +/* Apply probability PROB on frequency or count FREQ. */ + +static inline gcov_type +apply_probability (gcov_type freq, int prob) +{ + check_probability (prob); + return RDIV (freq * prob, REG_BR_PROB_BASE); +} + +/* Return inverse probability for PROB. */ + +static inline int +inverse_probability (int prob1) +{ + check_probability (prob1); + return REG_BR_PROB_BASE - prob1; +} +#endif /* GCC_BASIC_BLOCK_H */ diff --git a/src/include/bitmap.h b/src/include/bitmap.h new file mode 100644 index 0000000..3d9738c --- /dev/null +++ b/src/include/bitmap.h @@ -0,0 +1,713 @@ +/* Functions to support general ended bitmaps. + Copyright (C) 1997-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_BITMAP_H +#define GCC_BITMAP_H + +/* Implementation of sparse integer sets as a linked list. + + This sparse set representation is suitable for sparse sets with an + unknown (a priori) universe. The set is represented as a double-linked + list of container nodes (struct bitmap_element_def). Each node consists + of an index for the first member that could be held in the container, + a small array of integers that represent the members in the container, + and pointers to the next and previous element in the linked list. The + elements in the list are sorted in ascending order, i.e. the head of + the list holds the element with the smallest member of the set. + + For a given member I in the set: + - the element for I will have index is I / (bits per element) + - the position for I within element is I % (bits per element) + + This representation is very space-efficient for large sparse sets, and + the size of the set can be changed dynamically without much overhead. + An important parameter is the number of bits per element. In this + implementation, there are 128 bits per element. This results in a + high storage overhead *per element*, but a small overall overhead if + the set is very sparse. + + The downside is that many operations are relatively slow because the + linked list has to be traversed to test membership (i.e. member_p/ + add_member/remove_member). To improve the performance of this set + representation, the last accessed element and its index are cached. + For membership tests on members close to recently accessed members, + the cached last element improves membership test to a constant-time + operation. + + The following operations can always be performed in O(1) time: + + * clear : bitmap_clear + * choose_one : (not implemented, but could be + implemented in constant time) + + The following operations can be performed in O(E) time worst-case (with + E the number of elements in the linked list), but in O(1) time with a + suitable access patterns: + + * member_p : bitmap_bit_p + * add_member : bitmap_set_bit + * remove_member : bitmap_clear_bit + + The following operations can be performed in O(E) time: + + * cardinality : bitmap_count_bits + * set_size : bitmap_last_set_bit (but this could + in constant time with a pointer to + the last element in the chain) + + Additionally, the linked-list sparse set representation supports + enumeration of the members in O(E) time: + + * forall : EXECUTE_IF_SET_IN_BITMAP + * set_copy : bitmap_copy + * set_intersection : bitmap_intersect_p / + bitmap_and / bitmap_and_into / + EXECUTE_IF_AND_IN_BITMAP + * set_union : bitmap_ior / bitmap_ior_into + * set_difference : bitmap_intersect_compl_p / + bitmap_and_comp / bitmap_and_comp_into / + EXECUTE_IF_AND_COMPL_IN_BITMAP + * set_disjuction : bitmap_xor_comp / bitmap_xor_comp_into + * set_compare : bitmap_equal_p + + Some operations on 3 sets that occur frequently in in data flow problems + are also implemented: + + * A | (B & C) : bitmap_ior_and_into + * A | (B & ~C) : bitmap_ior_and_compl / + bitmap_ior_and_compl_into + + The storage requirements for linked-list sparse sets are O(E), with E->N + in the worst case (a sparse set with large distances between the values + of the set members). + + The linked-list set representation works well for problems involving very + sparse sets. The canonical example in GCC is, of course, the "set of + sets" for some CFG-based data flow problems (liveness analysis, dominance + frontiers, etc.). + + This representation also works well for data flow problems where the size + of the set may grow dynamically, but care must be taken that the member_p, + add_member, and remove_member operations occur with a suitable access + pattern. + + For random-access sets with a known, relatively small universe size, the + SparseSet or simple bitmap representations may be more efficient than a + linked-list set. For random-access sets of unknown universe, a hash table + or a balanced binary tree representation is likely to be a more suitable + choice. + + Traversing linked lists is usually cache-unfriendly, even with the last + accessed element cached. + + Cache performance can be improved by keeping the elements in the set + grouped together in memory, using a dedicated obstack for a set (or group + of related sets). Elements allocated on obstacks are released to a + free-list and taken off the free list. If multiple sets are allocated on + the same obstack, elements freed from one set may be re-used for one of + the other sets. This usually helps avoid cache misses. + + A single free-list is used for all sets allocated in GGC space. This is + bad for persistent sets, so persistent sets should be allocated on an + obstack whenever possible. */ + +#include "hashtab.h" +#include "statistics.h" +#include "obstack.h" + +/* Fundamental storage type for bitmap. */ + +typedef unsigned long BITMAP_WORD; +/* BITMAP_WORD_BITS needs to be unsigned, but cannot contain casts as + it is used in preprocessor directives -- hence the 1u. */ +#define BITMAP_WORD_BITS (CHAR_BIT * SIZEOF_LONG * 1u) + +/* Number of words to use for each element in the linked list. */ + +#ifndef BITMAP_ELEMENT_WORDS +#define BITMAP_ELEMENT_WORDS ((128 + BITMAP_WORD_BITS - 1) / BITMAP_WORD_BITS) +#endif + +/* Number of bits in each actual element of a bitmap. */ + +#define BITMAP_ELEMENT_ALL_BITS (BITMAP_ELEMENT_WORDS * BITMAP_WORD_BITS) + +/* Obstack for allocating bitmaps and elements from. */ +typedef struct GTY (()) bitmap_obstack { + struct bitmap_element_def *elements; + struct bitmap_head_def *heads; + struct obstack GTY ((skip)) obstack; +} bitmap_obstack; + +/* Bitmap set element. We use a linked list to hold only the bits that + are set. This allows for use to grow the bitset dynamically without + having to realloc and copy a giant bit array. + + The free list is implemented as a list of lists. There is one + outer list connected together by prev fields. Each element of that + outer is an inner list (that may consist only of the outer list + element) that are connected by the next fields. The prev pointer + is undefined for interior elements. This allows + bitmap_elt_clear_from to be implemented in unit time rather than + linear in the number of elements to be freed. */ + +typedef struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) bitmap_element_def { + struct bitmap_element_def *next; /* Next element. */ + struct bitmap_element_def *prev; /* Previous element. */ + unsigned int indx; /* regno/BITMAP_ELEMENT_ALL_BITS. */ + BITMAP_WORD bits[BITMAP_ELEMENT_WORDS]; /* Bits that are set. */ +} bitmap_element; + +/* Head of bitmap linked list. The 'current' member points to something + already pointed to by the chain started by first, so GTY((skip)) it. */ + +typedef struct GTY(()) bitmap_head_def { + unsigned int indx; /* Index of last element looked at. */ + unsigned int descriptor_id; /* Unique identifier for the allocation + site of this bitmap, for detailed + statistics gathering. */ + bitmap_element *first; /* First element in linked list. */ + bitmap_element * GTY((skip(""))) current; /* Last element looked at. */ + bitmap_obstack *obstack; /* Obstack to allocate elements from. + If NULL, then use GGC allocation. */ +} bitmap_head; + +/* Global data */ +extern bitmap_element bitmap_zero_bits; /* Zero bitmap element */ +extern bitmap_obstack bitmap_default_obstack; /* Default bitmap obstack */ + +/* Clear a bitmap by freeing up the linked list. */ +extern void bitmap_clear (bitmap); + +/* Copy a bitmap to another bitmap. */ +extern void bitmap_copy (bitmap, const_bitmap); + +/* True if two bitmaps are identical. */ +extern bool bitmap_equal_p (const_bitmap, const_bitmap); + +/* True if the bitmaps intersect (their AND is non-empty). */ +extern bool bitmap_intersect_p (const_bitmap, const_bitmap); + +/* True if the complement of the second intersects the first (their + AND_COMPL is non-empty). */ +extern bool bitmap_intersect_compl_p (const_bitmap, const_bitmap); + +/* True if MAP is an empty bitmap. */ +inline bool bitmap_empty_p (const_bitmap map) +{ + return !map->first; +} + +/* True if the bitmap has only a single bit set. */ +extern bool bitmap_single_bit_set_p (const_bitmap); + +/* Count the number of bits set in the bitmap. */ +extern unsigned long bitmap_count_bits (const_bitmap); + +/* Boolean operations on bitmaps. The _into variants are two operand + versions that modify the first source operand. The other variants + are three operand versions that to not destroy the source bitmaps. + The operations supported are &, & ~, |, ^. */ +extern void bitmap_and (bitmap, const_bitmap, const_bitmap); +extern bool bitmap_and_into (bitmap, const_bitmap); +extern bool bitmap_and_compl (bitmap, const_bitmap, const_bitmap); +extern bool bitmap_and_compl_into (bitmap, const_bitmap); +#define bitmap_compl_and(DST, A, B) bitmap_and_compl (DST, B, A) +extern void bitmap_compl_and_into (bitmap, const_bitmap); +extern void bitmap_clear_range (bitmap, unsigned int, unsigned int); +extern void bitmap_set_range (bitmap, unsigned int, unsigned int); +extern bool bitmap_ior (bitmap, const_bitmap, const_bitmap); +extern bool bitmap_ior_into (bitmap, const_bitmap); +extern void bitmap_xor (bitmap, const_bitmap, const_bitmap); +extern void bitmap_xor_into (bitmap, const_bitmap); + +/* DST = A | (B & C). Return true if DST changes. */ +extern bool bitmap_ior_and_into (bitmap DST, const_bitmap B, const_bitmap C); +/* DST = A | (B & ~C). Return true if DST changes. */ +extern bool bitmap_ior_and_compl (bitmap DST, const_bitmap A, + const_bitmap B, const_bitmap C); +/* A |= (B & ~C). Return true if A changes. */ +extern bool bitmap_ior_and_compl_into (bitmap A, + const_bitmap B, const_bitmap C); + +/* Clear a single bit in a bitmap. Return true if the bit changed. */ +extern bool bitmap_clear_bit (bitmap, int); + +/* Set a single bit in a bitmap. Return true if the bit changed. */ +extern bool bitmap_set_bit (bitmap, int); + +/* Return true if a register is set in a register set. */ +extern int bitmap_bit_p (bitmap, int); + +/* Debug functions to print a bitmap linked list. */ +extern void debug_bitmap (const_bitmap); +extern void debug_bitmap_file (FILE *, const_bitmap); + +/* Print a bitmap. */ +extern void bitmap_print (FILE *, const_bitmap, const char *, const char *); + +/* Initialize and release a bitmap obstack. */ +extern void bitmap_obstack_initialize (bitmap_obstack *); +extern void bitmap_obstack_release (bitmap_obstack *); +extern void bitmap_register (bitmap MEM_STAT_DECL); +extern void dump_bitmap_statistics (void); + +/* Initialize a bitmap header. OBSTACK indicates the bitmap obstack + to allocate from, NULL for GC'd bitmap. */ + +static inline void +bitmap_initialize_stat (bitmap head, bitmap_obstack *obstack MEM_STAT_DECL) +{ + head->first = head->current = NULL; + head->obstack = obstack; + if (GATHER_STATISTICS) + bitmap_register (head PASS_MEM_STAT); +} +#define bitmap_initialize(h,o) bitmap_initialize_stat (h,o MEM_STAT_INFO) + +/* Allocate and free bitmaps from obstack, malloc and gc'd memory. */ +extern bitmap bitmap_obstack_alloc_stat (bitmap_obstack *obstack MEM_STAT_DECL); +#define bitmap_obstack_alloc(t) bitmap_obstack_alloc_stat (t MEM_STAT_INFO) +extern bitmap bitmap_gc_alloc_stat (ALONE_MEM_STAT_DECL); +#define bitmap_gc_alloc() bitmap_gc_alloc_stat (ALONE_MEM_STAT_INFO) +extern void bitmap_obstack_free (bitmap); + +/* A few compatibility/functions macros for compatibility with sbitmaps */ +inline void dump_bitmap (FILE *file, const_bitmap map) +{ + bitmap_print (file, map, "", "\n"); +} + +extern unsigned bitmap_first_set_bit (const_bitmap); +extern unsigned bitmap_last_set_bit (const_bitmap); + +/* Compute bitmap hash (for purposes of hashing etc.) */ +extern hashval_t bitmap_hash(const_bitmap); + +/* Allocate a bitmap from a bit obstack. */ +#define BITMAP_ALLOC(OBSTACK) bitmap_obstack_alloc (OBSTACK) + +/* Allocate a gc'd bitmap. */ +#define BITMAP_GGC_ALLOC() bitmap_gc_alloc () + +/* Do any cleanup needed on a bitmap when it is no longer used. */ +#define BITMAP_FREE(BITMAP) \ + ((void) (bitmap_obstack_free ((bitmap) BITMAP), (BITMAP) = (bitmap) NULL)) + +/* Iterator for bitmaps. */ + +typedef struct +{ + /* Pointer to the current bitmap element. */ + bitmap_element *elt1; + + /* Pointer to 2nd bitmap element when two are involved. */ + bitmap_element *elt2; + + /* Word within the current element. */ + unsigned word_no; + + /* Contents of the actually processed word. When finding next bit + it is shifted right, so that the actual bit is always the least + significant bit of ACTUAL. */ + BITMAP_WORD bits; +} bitmap_iterator; + +/* Initialize a single bitmap iterator. START_BIT is the first bit to + iterate from. */ + +static inline void +bmp_iter_set_init (bitmap_iterator *bi, const_bitmap map, + unsigned start_bit, unsigned *bit_no) +{ + bi->elt1 = map->first; + bi->elt2 = NULL; + + /* Advance elt1 until it is not before the block containing start_bit. */ + while (1) + { + if (!bi->elt1) + { + bi->elt1 = &bitmap_zero_bits; + break; + } + + if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS) + break; + bi->elt1 = bi->elt1->next; + } + + /* We might have gone past the start bit, so reinitialize it. */ + if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS) + start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS; + + /* Initialize for what is now start_bit. */ + bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS; + bi->bits = bi->elt1->bits[bi->word_no]; + bi->bits >>= start_bit % BITMAP_WORD_BITS; + + /* If this word is zero, we must make sure we're not pointing at the + first bit, otherwise our incrementing to the next word boundary + will fail. It won't matter if this increment moves us into the + next word. */ + start_bit += !bi->bits; + + *bit_no = start_bit; +} + +/* Initialize an iterator to iterate over the intersection of two + bitmaps. START_BIT is the bit to commence from. */ + +static inline void +bmp_iter_and_init (bitmap_iterator *bi, const_bitmap map1, const_bitmap map2, + unsigned start_bit, unsigned *bit_no) +{ + bi->elt1 = map1->first; + bi->elt2 = map2->first; + + /* Advance elt1 until it is not before the block containing + start_bit. */ + while (1) + { + if (!bi->elt1) + { + bi->elt2 = NULL; + break; + } + + if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS) + break; + bi->elt1 = bi->elt1->next; + } + + /* Advance elt2 until it is not before elt1. */ + while (1) + { + if (!bi->elt2) + { + bi->elt1 = bi->elt2 = &bitmap_zero_bits; + break; + } + + if (bi->elt2->indx >= bi->elt1->indx) + break; + bi->elt2 = bi->elt2->next; + } + + /* If we're at the same index, then we have some intersecting bits. */ + if (bi->elt1->indx == bi->elt2->indx) + { + /* We might have advanced beyond the start_bit, so reinitialize + for that. */ + if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS) + start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS; + + bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS; + bi->bits = bi->elt1->bits[bi->word_no] & bi->elt2->bits[bi->word_no]; + bi->bits >>= start_bit % BITMAP_WORD_BITS; + } + else + { + /* Otherwise we must immediately advance elt1, so initialize for + that. */ + bi->word_no = BITMAP_ELEMENT_WORDS - 1; + bi->bits = 0; + } + + /* If this word is zero, we must make sure we're not pointing at the + first bit, otherwise our incrementing to the next word boundary + will fail. It won't matter if this increment moves us into the + next word. */ + start_bit += !bi->bits; + + *bit_no = start_bit; +} + +/* Initialize an iterator to iterate over the bits in MAP1 & ~MAP2. + */ + +static inline void +bmp_iter_and_compl_init (bitmap_iterator *bi, + const_bitmap map1, const_bitmap map2, + unsigned start_bit, unsigned *bit_no) +{ + bi->elt1 = map1->first; + bi->elt2 = map2->first; + + /* Advance elt1 until it is not before the block containing start_bit. */ + while (1) + { + if (!bi->elt1) + { + bi->elt1 = &bitmap_zero_bits; + break; + } + + if (bi->elt1->indx >= start_bit / BITMAP_ELEMENT_ALL_BITS) + break; + bi->elt1 = bi->elt1->next; + } + + /* Advance elt2 until it is not before elt1. */ + while (bi->elt2 && bi->elt2->indx < bi->elt1->indx) + bi->elt2 = bi->elt2->next; + + /* We might have advanced beyond the start_bit, so reinitialize for + that. */ + if (bi->elt1->indx != start_bit / BITMAP_ELEMENT_ALL_BITS) + start_bit = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS; + + bi->word_no = start_bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS; + bi->bits = bi->elt1->bits[bi->word_no]; + if (bi->elt2 && bi->elt1->indx == bi->elt2->indx) + bi->bits &= ~bi->elt2->bits[bi->word_no]; + bi->bits >>= start_bit % BITMAP_WORD_BITS; + + /* If this word is zero, we must make sure we're not pointing at the + first bit, otherwise our incrementing to the next word boundary + will fail. It won't matter if this increment moves us into the + next word. */ + start_bit += !bi->bits; + + *bit_no = start_bit; +} + +/* Advance to the next bit in BI. We don't advance to the next + nonzero bit yet. */ + +static inline void +bmp_iter_next (bitmap_iterator *bi, unsigned *bit_no) +{ + bi->bits >>= 1; + *bit_no += 1; +} + +/* Advance to first set bit in BI. */ + +static inline void +bmp_iter_next_bit (bitmap_iterator * bi, unsigned *bit_no) +{ +#if (GCC_VERSION >= 3004) + { + unsigned int n = __builtin_ctzl (bi->bits); + gcc_assert (sizeof (unsigned long) == sizeof (BITMAP_WORD)); + bi->bits >>= n; + *bit_no += n; + } +#else + while (!(bi->bits & 1)) + { + bi->bits >>= 1; + *bit_no += 1; + } +#endif +} + +/* Advance to the next nonzero bit of a single bitmap, we will have + already advanced past the just iterated bit. Return true if there + is a bit to iterate. */ + +static inline bool +bmp_iter_set (bitmap_iterator *bi, unsigned *bit_no) +{ + /* If our current word is nonzero, it contains the bit we want. */ + if (bi->bits) + { + next_bit: + bmp_iter_next_bit (bi, bit_no); + return true; + } + + /* Round up to the word boundary. We might have just iterated past + the end of the last word, hence the -1. It is not possible for + bit_no to point at the beginning of the now last word. */ + *bit_no = ((*bit_no + BITMAP_WORD_BITS - 1) + / BITMAP_WORD_BITS * BITMAP_WORD_BITS); + bi->word_no++; + + while (1) + { + /* Find the next nonzero word in this elt. */ + while (bi->word_no != BITMAP_ELEMENT_WORDS) + { + bi->bits = bi->elt1->bits[bi->word_no]; + if (bi->bits) + goto next_bit; + *bit_no += BITMAP_WORD_BITS; + bi->word_no++; + } + + /* Advance to the next element. */ + bi->elt1 = bi->elt1->next; + if (!bi->elt1) + return false; + *bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS; + bi->word_no = 0; + } +} + +/* Advance to the next nonzero bit of an intersecting pair of + bitmaps. We will have already advanced past the just iterated bit. + Return true if there is a bit to iterate. */ + +static inline bool +bmp_iter_and (bitmap_iterator *bi, unsigned *bit_no) +{ + /* If our current word is nonzero, it contains the bit we want. */ + if (bi->bits) + { + next_bit: + bmp_iter_next_bit (bi, bit_no); + return true; + } + + /* Round up to the word boundary. We might have just iterated past + the end of the last word, hence the -1. It is not possible for + bit_no to point at the beginning of the now last word. */ + *bit_no = ((*bit_no + BITMAP_WORD_BITS - 1) + / BITMAP_WORD_BITS * BITMAP_WORD_BITS); + bi->word_no++; + + while (1) + { + /* Find the next nonzero word in this elt. */ + while (bi->word_no != BITMAP_ELEMENT_WORDS) + { + bi->bits = bi->elt1->bits[bi->word_no] & bi->elt2->bits[bi->word_no]; + if (bi->bits) + goto next_bit; + *bit_no += BITMAP_WORD_BITS; + bi->word_no++; + } + + /* Advance to the next identical element. */ + do + { + /* Advance elt1 while it is less than elt2. We always want + to advance one elt. */ + do + { + bi->elt1 = bi->elt1->next; + if (!bi->elt1) + return false; + } + while (bi->elt1->indx < bi->elt2->indx); + + /* Advance elt2 to be no less than elt1. This might not + advance. */ + while (bi->elt2->indx < bi->elt1->indx) + { + bi->elt2 = bi->elt2->next; + if (!bi->elt2) + return false; + } + } + while (bi->elt1->indx != bi->elt2->indx); + + *bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS; + bi->word_no = 0; + } +} + +/* Advance to the next nonzero bit in the intersection of + complemented bitmaps. We will have already advanced past the just + iterated bit. */ + +static inline bool +bmp_iter_and_compl (bitmap_iterator *bi, unsigned *bit_no) +{ + /* If our current word is nonzero, it contains the bit we want. */ + if (bi->bits) + { + next_bit: + bmp_iter_next_bit (bi, bit_no); + return true; + } + + /* Round up to the word boundary. We might have just iterated past + the end of the last word, hence the -1. It is not possible for + bit_no to point at the beginning of the now last word. */ + *bit_no = ((*bit_no + BITMAP_WORD_BITS - 1) + / BITMAP_WORD_BITS * BITMAP_WORD_BITS); + bi->word_no++; + + while (1) + { + /* Find the next nonzero word in this elt. */ + while (bi->word_no != BITMAP_ELEMENT_WORDS) + { + bi->bits = bi->elt1->bits[bi->word_no]; + if (bi->elt2 && bi->elt2->indx == bi->elt1->indx) + bi->bits &= ~bi->elt2->bits[bi->word_no]; + if (bi->bits) + goto next_bit; + *bit_no += BITMAP_WORD_BITS; + bi->word_no++; + } + + /* Advance to the next element of elt1. */ + bi->elt1 = bi->elt1->next; + if (!bi->elt1) + return false; + + /* Advance elt2 until it is no less than elt1. */ + while (bi->elt2 && bi->elt2->indx < bi->elt1->indx) + bi->elt2 = bi->elt2->next; + + *bit_no = bi->elt1->indx * BITMAP_ELEMENT_ALL_BITS; + bi->word_no = 0; + } +} + +/* Loop over all bits set in BITMAP, starting with MIN and setting + BITNUM to the bit number. ITER is a bitmap iterator. BITNUM + should be treated as a read-only variable as it contains loop + state. */ + +#ifndef EXECUTE_IF_SET_IN_BITMAP +/* See sbitmap.h for the other definition of EXECUTE_IF_SET_IN_BITMAP. */ +#define EXECUTE_IF_SET_IN_BITMAP(BITMAP, MIN, BITNUM, ITER) \ + for (bmp_iter_set_init (&(ITER), (BITMAP), (MIN), &(BITNUM)); \ + bmp_iter_set (&(ITER), &(BITNUM)); \ + bmp_iter_next (&(ITER), &(BITNUM))) +#endif + +/* Loop over all the bits set in BITMAP1 & BITMAP2, starting with MIN + and setting BITNUM to the bit number. ITER is a bitmap iterator. + BITNUM should be treated as a read-only variable as it contains + loop state. */ + +#define EXECUTE_IF_AND_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, ITER) \ + for (bmp_iter_and_init (&(ITER), (BITMAP1), (BITMAP2), (MIN), \ + &(BITNUM)); \ + bmp_iter_and (&(ITER), &(BITNUM)); \ + bmp_iter_next (&(ITER), &(BITNUM))) + +/* Loop over all the bits set in BITMAP1 & ~BITMAP2, starting with MIN + and setting BITNUM to the bit number. ITER is a bitmap iterator. + BITNUM should be treated as a read-only variable as it contains + loop state. */ + +#define EXECUTE_IF_AND_COMPL_IN_BITMAP(BITMAP1, BITMAP2, MIN, BITNUM, ITER) \ + for (bmp_iter_and_compl_init (&(ITER), (BITMAP1), (BITMAP2), (MIN), \ + &(BITNUM)); \ + bmp_iter_and_compl (&(ITER), &(BITNUM)); \ + bmp_iter_next (&(ITER), &(BITNUM))) + +#endif /* GCC_BITMAP_H */ diff --git a/src/include/builtins.def b/src/include/builtins.def new file mode 100644 index 0000000..d5afe0d --- /dev/null +++ b/src/include/builtins.def @@ -0,0 +1,842 @@ +/* This file contains the definitions and documentation for the + builtins used in the GNU compiler. + Copyright (C) 2000-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* Before including this file, you should define a macro: + + DEF_BUILTIN (ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, + FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT, COND) + + This macro will be called once for each builtin function. The + ENUM will be of type `enum built_in_function', and will indicate + which builtin function is being processed. The NAME of the builtin + function (which will always start with `__builtin_') is a string + literal. The CLASS is of type `enum built_in_class' and indicates + what kind of builtin is being processed. + + Some builtins are actually two separate functions. For example, + for `strcmp' there are two builtin functions; `__builtin_strcmp' + and `strcmp' itself. Both behave identically. Other builtins + define only the `__builtin' variant. If BOTH_P is TRUE, then this + builtin has both variants; otherwise, it is has only the first + variant. + + TYPE indicates the type of the function. The symbols correspond to + enumerals from builtin-types.def. If BOTH_P is true, then LIBTYPE + is the type of the non-`__builtin_' variant. Otherwise, LIBTYPE + should be ignored. + + If FALLBACK_P is true then, if for some reason, the compiler cannot + expand the builtin function directly, it will call the + corresponding library function (which does not have the + `__builtin_' prefix. + + If NONANSI_P is true, then the non-`__builtin_' variant is not an + ANSI/ISO library function, and so we should pretend it does not + exist when compiling in ANSI conformant mode. + + ATTRs is an attribute list as defined in builtin-attrs.def that + describes the attributes of this builtin function. + + IMPLICIT specifies condition when the builtin can be produced by + compiler. For instance C90 reserves floorf function, but does not + define it's meaning. When user uses floorf we may assume that the + floorf has the meaning we expect, but we can't produce floorf by + simplifying floor((double)float) since the runtime need not implement + it. + + The builtins is registered only if COND is true. */ + +/* A GCC builtin (like __builtin_saveregs) is provided by the + compiler, but does not correspond to a function in the standard + library. */ +#undef DEF_GCC_BUILTIN +#define DEF_GCC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \ + false, false, false, ATTRS, true, true) + +/* Like DEF_GCC_BUILTIN, except we don't prepend "__builtin_". */ +#undef DEF_SYNC_BUILTIN +#define DEF_SYNC_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, BT_LAST, \ + false, false, false, ATTRS, true, true) + +/* A library builtin (like __builtin_strchr) is a builtin equivalent + of an ANSI/ISO standard library function. In addition to the + `__builtin' version, we will create an ordinary version (e.g, + `strchr') as well. If we cannot compute the answer using the + builtin function, we will fall back to the standard library + version. */ +#undef DEF_LIB_BUILTIN +#define DEF_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ + true, true, false, ATTRS, true, true) + +/* Like DEF_LIB_BUILTIN, except that the function is not one that is + specified by ANSI/ISO C. So, when we're being fully conformant we + ignore the version of these builtins that does not begin with + __builtin. */ +#undef DEF_EXT_LIB_BUILTIN +#define DEF_EXT_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ + true, true, true, ATTRS, false, true) + +/* Like DEF_LIB_BUILTIN, except that the function is only a part of + the standard in C94 or above. */ +#undef DEF_C94_BUILTIN +#define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ + true, true, !flag_isoc94, ATTRS, TARGET_C99_FUNCTIONS, true) + +/* Like DEF_LIB_BUILTIN, except that the function is only a part of + the standard in C99 or above. */ +#undef DEF_C99_BUILTIN +#define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ + true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true) + +/* Builtin that is specified by C99 and C90 reserve the name for future use. + We can still recognize the builtin in C90 mode but we can't produce it + implicitly. */ +#undef DEF_C99_C90RES_BUILTIN +#define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ + true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true) + +/* Builtin that C99 reserve the name for future use. We can still recognize + the builtin in C99 mode but we can't produce it implicitly. */ +#undef DEF_EXT_C99RES_BUILTIN +#define DEF_EXT_C99RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ + true, true, true, ATTRS, false, true) + +/* Allocate the enum and the name for a builtin, but do not actually + define it here at all. */ +#undef DEF_BUILTIN_STUB +#define DEF_BUILTIN_STUB(ENUM, NAME) \ + DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, BT_LAST, BT_LAST, false, false, \ + false, ATTR_LAST, false, false) + +/* Builtin used by the implementation of GNU OpenMP. None of these are + actually implemented in the compiler; they're all in libgomp. */ +#undef DEF_GOMP_BUILTIN +#define DEF_GOMP_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ + false, true, true, ATTRS, false, \ + (flag_openmp || flag_tree_parallelize_loops)) + +/* Builtin used by the implementation of GNU TM. These + functions are mapped to the actual implementation of the STM library. */ +#undef DEF_TM_BUILTIN +#define DEF_TM_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ + true, true, true, ATTRS, false, flag_tm) + +/* Builtin used by the implementation of libsanitizer. These + functions are mapped to the actual implementation of the + libtsan library. */ +#undef DEF_SANITIZER_BUILTIN +#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ + true, true, true, ATTRS, true, \ + (flag_asan || flag_tsan)) + +/* Define an attribute list for math functions that are normally + "impure" because some of them may write into global memory for + `errno'. If !flag_errno_math they are instead "const". */ +#undef ATTR_MATHFN_ERRNO +#define ATTR_MATHFN_ERRNO (flag_errno_math ? \ + ATTR_NOTHROW_LEAF_LIST : ATTR_CONST_NOTHROW_LEAF_LIST) + +/* Define an attribute list for math functions that are normally + "const" but if flag_rounding_math is set they are instead "pure". + This distinction accounts for the fact that some math functions + check the rounding mode which is akin to examining global + memory. */ +#undef ATTR_MATHFN_FPROUNDING +#define ATTR_MATHFN_FPROUNDING (flag_rounding_math ? \ + ATTR_PURE_NOTHROW_LEAF_LIST : ATTR_CONST_NOTHROW_LEAF_LIST) + +/* Define an attribute list for math functions that are normally + "impure" because some of them may write into global memory for + `errno'. If !flag_errno_math, we can possibly use "pure" or + "const" depending on whether we care about FP rounding. */ +#undef ATTR_MATHFN_FPROUNDING_ERRNO +#define ATTR_MATHFN_FPROUNDING_ERRNO (flag_errno_math ? \ + ATTR_NOTHROW_LEAF_LIST : ATTR_MATHFN_FPROUNDING) + +/* Define an attribute list for math functions that need to mind FP + rounding, but because they store into memory they are never "const" + or "pure". Use of this macro is mainly for documentation and + maintenance purposes. */ +#undef ATTR_MATHFN_FPROUNDING_STORE +#define ATTR_MATHFN_FPROUNDING_STORE ATTR_NOTHROW_LEAF_LIST + +/* Make sure 0 is not a legitimate builtin. */ +DEF_BUILTIN_STUB(BUILT_IN_NONE, (const char *)0) + +/* Category: math builtins. */ +DEF_LIB_BUILTIN (BUILT_IN_ACOS, "acos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_ACOSF, "acosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ACOSH, "acosh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ACOSHF, "acoshf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ACOSHL, "acoshl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_ACOSL, "acosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_LIB_BUILTIN (BUILT_IN_ASIN, "asin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_ASINF, "asinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ASINH, "asinh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_ASINHF, "asinhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_ASINHL, "asinhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_C90RES_BUILTIN (BUILT_IN_ASINL, "asinl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_LIB_BUILTIN (BUILT_IN_ATAN, "atan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_LIB_BUILTIN (BUILT_IN_ATAN2, "atan2", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_ATAN2F, "atan2f", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_ATAN2L, "atan2l", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_ATANF, "atanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_ATANH, "atanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ATANHF, "atanhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ATANHL, "atanhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_ATANL, "atanl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CBRT, "cbrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CBRTF, "cbrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CBRTL, "cbrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_LIB_BUILTIN (BUILT_IN_CEIL, "ceil", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_C90RES_BUILTIN (BUILT_IN_CEILF, "ceilf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_C90RES_BUILTIN (BUILT_IN_CEILL, "ceill", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_COPYSIGN, "copysign", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_COPYSIGNF, "copysignf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_COPYSIGNL, "copysignl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_COS, "cos", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_C90RES_BUILTIN (BUILT_IN_COSF, "cosf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_LIB_BUILTIN (BUILT_IN_COSH, "cosh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_COSHF, "coshf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_COSHL, "coshl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_COSL, "cosl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_EXT_LIB_BUILTIN (BUILT_IN_DREM, "drem", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_DREMF, "dremf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_DREML, "dreml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ERF, "erf", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_ERFC, "erfc", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ERFCF, "erfcf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ERFCL, "erfcl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ERFF, "erff", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_ERFL, "erfl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_LIB_BUILTIN (BUILT_IN_EXP, "exp", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10, "exp10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10F, "exp10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_EXP10L, "exp10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_EXP2, "exp2", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_EXP2F, "exp2f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_EXP2L, "exp2l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_EXPF, "expf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_EXPL, "expl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_EXPM1, "expm1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_EXPM1F, "expm1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_EXPM1L, "expm1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_LIB_BUILTIN (BUILT_IN_FABS, "fabs", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSF, "fabsf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_FABSD32, "fabsd32", BT_FN_DFLOAT32_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_FABSD64, "fabsd64", BT_FN_DFLOAT64_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_FABSD128, "fabsd128", BT_FN_DFLOAT128_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_FDIM, "fdim", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_FDIMF, "fdimf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_FDIML, "fdiml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_LIB_BUILTIN (BUILT_IN_FLOOR, "floor", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORF, "floorf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_C90RES_BUILTIN (BUILT_IN_FLOORL, "floorl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_FMA, "fma", BT_FN_DOUBLE_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_FMAF, "fmaf", BT_FN_FLOAT_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_FMAL, "fmal", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_FMAX, "fmax", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_FMAXF, "fmaxf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_FMAXL, "fmaxl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_FMIN, "fmin", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_FMINF, "fminf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_FMINL, "fminl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_FMOD, "fmod", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODF, "fmodf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_FMODL, "fmodl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_LIB_BUILTIN (BUILT_IN_FREXP, "frexp", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_C99_C90RES_BUILTIN (BUILT_IN_FREXPF, "frexpf", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_C99_C90RES_BUILTIN (BUILT_IN_FREXPL, "frexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMA, "gamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAF, "gammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAL, "gammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMA_R, "gamma_r", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAF_R, "gammaf_r", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_GAMMAL_R, "gammal_r", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_GCC_BUILTIN (BUILT_IN_HUGE_VAL, "huge_val", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_HUGE_VALF, "huge_valf", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_HUGE_VALL, "huge_vall", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_HYPOT, "hypot", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_HYPOTF, "hypotf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_HYPOTL, "hypotl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_GCC_BUILTIN (BUILT_IN_ICEIL, "iceil", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_ICEILF, "iceilf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_ICEILL, "iceill", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_IFLOOR, "ifloor", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_IFLOORF, "ifloorf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_IFLOORL, "ifloorl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_ILOGB, "ilogb", BT_FN_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ILOGBF, "ilogbf", BT_FN_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ILOGBL, "ilogbl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_GCC_BUILTIN (BUILT_IN_INF, "inf", BT_FN_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_INFF, "inff", BT_FN_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_INFL, "infl", BT_FN_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_INFD32, "infd32", BT_FN_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_INFD64, "infd64", BT_FN_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_INFD128, "infd128", BT_FN_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_IRINT, "irint", BT_FN_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_GCC_BUILTIN (BUILT_IN_IRINTF, "irintf", BT_FN_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_GCC_BUILTIN (BUILT_IN_IRINTL, "irintl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_GCC_BUILTIN (BUILT_IN_IROUND, "iround", BT_FN_INT_DOUBLE, ATTR_MATHFN_ERRNO) +DEF_GCC_BUILTIN (BUILT_IN_IROUNDF, "iroundf", BT_FN_INT_FLOAT, ATTR_MATHFN_ERRNO) +DEF_GCC_BUILTIN (BUILT_IN_IROUNDL, "iroundl", BT_FN_INT_LONGDOUBLE, ATTR_MATHFN_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_J0, "j0", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_J0F, "j0f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_J0L, "j0l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_J1, "j1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_J1F, "j1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_J1L, "j1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_JN, "jn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_JNF, "jnf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_JNL, "jnl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_GCC_BUILTIN (BUILT_IN_LCEIL, "lceil", BT_FN_LONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_LCEILF, "lceilf", BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_LCEILL, "lceill", BT_FN_LONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_LDEXP, "ldexp", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPF, "ldexpf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_LDEXPL, "ldexpl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_GCC_BUILTIN (BUILT_IN_LFLOOR, "lfloor", BT_FN_LONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_LFLOORF, "lfloorf", BT_FN_LONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_LFLOORL, "lfloorl", BT_FN_LONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_LGAMMA, "lgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_STORE) +DEF_C99_BUILTIN (BUILT_IN_LGAMMAF, "lgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_STORE) +DEF_C99_BUILTIN (BUILT_IN_LGAMMAL, "lgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_LGAMMA_R, "lgamma_r", BT_FN_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_LGAMMAF_R, "lgammaf_r", BT_FN_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_LGAMMAL_R, "lgammal_r", BT_FN_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_GCC_BUILTIN (BUILT_IN_LLCEIL, "llceil", BT_FN_LONGLONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_LLCEILF, "llceilf", BT_FN_LONGLONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_LLCEILL, "llceill", BT_FN_LONGLONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_LLFLOOR, "llfloor", BT_FN_LONGLONG_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_LLFLOORF, "llfloorf", BT_FN_LONGLONG_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_LLFLOORL, "llfloorl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_LLRINT, "llrint", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LLRINTF, "llrintf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LLRINTL, "llrintl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LLROUND, "llround", BT_FN_LONGLONG_DOUBLE, ATTR_MATHFN_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LLROUNDF, "llroundf", BT_FN_LONGLONG_FLOAT, ATTR_MATHFN_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LLROUNDL, "llroundl", BT_FN_LONGLONG_LONGDOUBLE, ATTR_MATHFN_ERRNO) +DEF_LIB_BUILTIN (BUILT_IN_LOG, "log", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_LIB_BUILTIN (BUILT_IN_LOG10, "log10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_LOG10F, "log10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_LOG10L, "log10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LOG1P, "log1p", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LOG1PF, "log1pf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LOG1PL, "log1pl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LOG2, "log2", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LOG2F, "log2f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LOG2L, "log2l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LOGB, "logb", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LOGBF, "logbf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LOGBL, "logbl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_LOGF, "logf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_LOGL, "logl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LRINT, "lrint", BT_FN_LONG_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LRINTF, "lrintf", BT_FN_LONG_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LRINTL, "lrintl", BT_FN_LONG_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LROUND, "lround", BT_FN_LONG_DOUBLE, ATTR_MATHFN_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LROUNDF, "lroundf", BT_FN_LONG_FLOAT, ATTR_MATHFN_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_LROUNDL, "lroundl", BT_FN_LONG_LONGDOUBLE, ATTR_MATHFN_ERRNO) +DEF_LIB_BUILTIN (BUILT_IN_MODF, "modf", BT_FN_DOUBLE_DOUBLE_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFF, "modff", BT_FN_FLOAT_FLOAT_FLOATPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_C99_C90RES_BUILTIN (BUILT_IN_MODFL, "modfl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_C99_BUILTIN (BUILT_IN_NAN, "nan", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) +DEF_C99_BUILTIN (BUILT_IN_NANF, "nanf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) +DEF_C99_BUILTIN (BUILT_IN_NANL, "nanl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) +DEF_GCC_BUILTIN (BUILT_IN_NAND32, "nand32", BT_FN_DFLOAT32_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) +DEF_GCC_BUILTIN (BUILT_IN_NAND64, "nand64", BT_FN_DFLOAT64_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) +DEF_GCC_BUILTIN (BUILT_IN_NAND128, "nand128", BT_FN_DFLOAT128_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) +DEF_GCC_BUILTIN (BUILT_IN_NANS, "nans", BT_FN_DOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) +DEF_GCC_BUILTIN (BUILT_IN_NANSF, "nansf", BT_FN_FLOAT_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) +DEF_GCC_BUILTIN (BUILT_IN_NANSL, "nansl", BT_FN_LONGDOUBLE_CONST_STRING, ATTR_CONST_NOTHROW_NONNULL) +DEF_C99_BUILTIN (BUILT_IN_NEARBYINT, "nearbyint", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_NEARBYINTF, "nearbyintf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_NEARBYINTL, "nearbyintl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_NEXTAFTER, "nextafter", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_NEXTAFTERF, "nextafterf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_NEXTAFTERL, "nextafterl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARD, "nexttoward", BT_FN_DOUBLE_DOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARDF, "nexttowardf", BT_FN_FLOAT_FLOAT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_NEXTTOWARDL, "nexttowardl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_LIB_BUILTIN (BUILT_IN_POW, "pow", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10, "pow10", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10F, "pow10f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_POW10L, "pow10l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_POWF, "powf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_GCC_BUILTIN (BUILT_IN_POWI, "powi", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING) +DEF_GCC_BUILTIN (BUILT_IN_POWIF, "powif", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING) +DEF_GCC_BUILTIN (BUILT_IN_POWIL, "powil", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING) +DEF_C99_C90RES_BUILTIN (BUILT_IN_POWL, "powl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_REMAINDER, "remainder", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_REMAINDERF, "remainderf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_REMAINDERL, "remainderl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_REMQUO, "remquo", BT_FN_DOUBLE_DOUBLE_DOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_C99_BUILTIN (BUILT_IN_REMQUOF, "remquof", BT_FN_FLOAT_FLOAT_FLOAT_INTPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_C99_BUILTIN (BUILT_IN_REMQUOL, "remquol", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE_INTPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_C99_BUILTIN (BUILT_IN_RINT, "rint", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_RINTF, "rintf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_RINTL, "rintl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_ROUND, "round", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_ROUNDF, "roundf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_ROUNDL, "roundl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALB, "scalb", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALBF, "scalbf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SCALBL, "scalbl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_SCALBLN, "scalbln", BT_FN_DOUBLE_DOUBLE_LONG, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_SCALBLNF, "scalblnf", BT_FN_FLOAT_FLOAT_LONG, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_SCALBLNL, "scalblnl", BT_FN_LONGDOUBLE_LONGDOUBLE_LONG, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_SCALBN, "scalbn", BT_FN_DOUBLE_DOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_SCALBNF, "scalbnf", BT_FN_FLOAT_FLOAT_INT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_SCALBNL, "scalbnl", BT_FN_LONGDOUBLE_LONGDOUBLE_INT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBIT, "signbit", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITF, "signbitf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITL, "signbitl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD32, "signbitd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD64, "signbitd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNBITD128, "signbitd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICAND, "significand", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDF, "significandf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SIGNIFICANDL, "significandl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_LIB_BUILTIN (BUILT_IN_SIN, "sin", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOS, "sincos", BT_FN_VOID_DOUBLE_DOUBLEPTR_DOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSF, "sincosf", BT_FN_VOID_FLOAT_FLOATPTR_FLOATPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SINCOSL, "sincosl", BT_FN_VOID_LONGDOUBLE_LONGDOUBLEPTR_LONGDOUBLEPTR, ATTR_MATHFN_FPROUNDING_STORE) +DEF_C99_C90RES_BUILTIN (BUILT_IN_SINF, "sinf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_LIB_BUILTIN (BUILT_IN_SINH, "sinh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_SINHF, "sinhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_SINHL, "sinhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_SINL, "sinl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_LIB_BUILTIN (BUILT_IN_SQRT, "sqrt", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTF, "sqrtf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_C90RES_BUILTIN (BUILT_IN_SQRTL, "sqrtl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_LIB_BUILTIN (BUILT_IN_TAN, "tan", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_C90RES_BUILTIN (BUILT_IN_TANF, "tanf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_LIB_BUILTIN (BUILT_IN_TANH, "tanh", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_C90RES_BUILTIN (BUILT_IN_TANHF, "tanhf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_C90RES_BUILTIN (BUILT_IN_TANHL, "tanhl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_C90RES_BUILTIN (BUILT_IN_TANL, "tanl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_TGAMMA, "tgamma", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_TGAMMAF, "tgammaf", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_TGAMMAL, "tgammal", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_C99_BUILTIN (BUILT_IN_TRUNC, "trunc", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_TRUNCF, "truncf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_TRUNCL, "truncl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0, "y0", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0F, "y0f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_Y0L, "y0l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1, "y1", BT_FN_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1F, "y1f", BT_FN_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1L, "y1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_YN, "yn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) +DEF_EXT_LIB_BUILTIN (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) + +/* Category: _Complex math builtins. */ +DEF_C99_BUILTIN (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_GCC_BUILTIN (BUILT_IN_CEXPI, "cexpi", BT_FN_COMPLEX_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_GCC_BUILTIN (BUILT_IN_CEXPIF, "cexpif", BT_FN_COMPLEX_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_GCC_BUILTIN (BUILT_IN_CEXPIL, "cexpil", BT_FN_COMPLEX_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10, "clog10", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10F, "clog10f", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10L, "clog10l", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) +DEF_C99_BUILTIN (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING) + +/* Category: string/memory builtins. */ +/* bcmp, bcopy and bzero have traditionally accepted NULL pointers + when the length parameter is zero, so don't apply attribute "nonnull". */ +DEF_EXT_LIB_BUILTIN (BUILT_IN_BCMP, "bcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_BCOPY, "bcopy", BT_FN_VOID_CONST_PTR_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_BZERO, "bzero", BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_INDEX, "index", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_MEMCHR, "memchr", BT_FN_PTR_CONST_PTR_INT_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_RINDEX, "rindex", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY, "stpncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCASECMP, "strcasecmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRCHR, "strchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRCMP, "strcmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRCPY, "strcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_RET1_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRCSPN, "strcspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRDUP, "strdup", BT_FN_STRING_CONST_STRING, ATTR_MALLOC_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNDUP, "strndup", BT_FN_STRING_CONST_STRING_SIZE, ATTR_MALLOC_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRLEN, "strlen", BT_FN_SIZE_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCASECMP, "strncasecmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRNCMP, "strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRNCPY, "strncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRPBRK, "strpbrk", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRRCHR, "strrchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRSPN, "strspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_STRSTR, "strstr", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) + +/* Category: stdio builtins. */ +DEF_LIB_BUILTIN (BUILT_IN_FPRINTF, "fprintf", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_UNLOCKED, "fprintf_unlocked", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3) +DEF_LIB_BUILTIN (BUILT_IN_PUTC, "putc", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTC_UNLOCKED, "putc_unlocked", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST) +DEF_LIB_BUILTIN (BUILT_IN_FPUTC, "fputc", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTC_UNLOCKED, "fputc_unlocked", BT_FN_INT_INT_FILEPTR, ATTR_NONNULL_LIST) +DEF_LIB_BUILTIN (BUILT_IN_FPUTS, "fputs", BT_FN_INT_CONST_STRING_FILEPTR, ATTR_NONNULL_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FPUTS_UNLOCKED, "fputs_unlocked", BT_FN_INT_CONST_STRING_FILEPTR, ATTR_NONNULL_LIST) +DEF_LIB_BUILTIN (BUILT_IN_FSCANF, "fscanf", BT_FN_INT_FILEPTR_CONST_STRING_VAR, ATTR_FORMAT_SCANF_2_3) +DEF_LIB_BUILTIN (BUILT_IN_FWRITE, "fwrite", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FWRITE_UNLOCKED, "fwrite_unlocked", BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, ATTR_NONNULL_LIST) +DEF_LIB_BUILTIN (BUILT_IN_PRINTF, "printf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2) +DEF_EXT_LIB_BUILTIN (BUILT_IN_PRINTF_UNLOCKED, "printf_unlocked", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_1_2) +DEF_LIB_BUILTIN (BUILT_IN_PUTCHAR, "putchar", BT_FN_INT_INT, ATTR_NULL) +DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTCHAR_UNLOCKED, "putchar_unlocked", BT_FN_INT_INT, ATTR_NULL) +DEF_LIB_BUILTIN (BUILT_IN_PUTS, "puts", BT_FN_INT_CONST_STRING, ATTR_NONNULL_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_PUTS_UNLOCKED, "puts_unlocked", BT_FN_INT_CONST_STRING, ATTR_NONNULL_LIST) +DEF_LIB_BUILTIN (BUILT_IN_SCANF, "scanf", BT_FN_INT_CONST_STRING_VAR, ATTR_FORMAT_SCANF_1_2) +DEF_C99_BUILTIN (BUILT_IN_SNPRINTF, "snprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_3_4) +DEF_LIB_BUILTIN (BUILT_IN_SPRINTF, "sprintf", BT_FN_INT_STRING_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_2_3) +DEF_LIB_BUILTIN (BUILT_IN_SSCANF, "sscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_FORMAT_SCANF_NOTHROW_2_3) +DEF_LIB_BUILTIN (BUILT_IN_VFPRINTF, "vfprintf", BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0) +DEF_C99_BUILTIN (BUILT_IN_VFSCANF, "vfscanf", BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_2_0) +DEF_LIB_BUILTIN (BUILT_IN_VPRINTF, "vprintf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_1_0) +DEF_C99_BUILTIN (BUILT_IN_VSCANF, "vscanf", BT_FN_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_1_0) +DEF_C99_BUILTIN (BUILT_IN_VSNPRINTF, "vsnprintf", BT_FN_INT_STRING_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_3_0) +DEF_LIB_BUILTIN (BUILT_IN_VSPRINTF, "vsprintf", BT_FN_INT_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_2_0) +DEF_C99_BUILTIN (BUILT_IN_VSSCANF, "vsscanf", BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG, ATTR_FORMAT_SCANF_NOTHROW_2_0) + +/* Category: ctype builtins. */ +DEF_LIB_BUILTIN (BUILT_IN_ISALNUM, "isalnum", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_ISALPHA, "isalpha", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ISASCII, "isascii", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_ISBLANK, "isblank", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_ISCNTRL, "iscntrl", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_ISDIGIT, "isdigit", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_ISGRAPH, "isgraph", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_ISLOWER, "islower", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_ISPRINT, "isprint", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_ISPUNCT, "ispunct", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_ISSPACE, "isspace", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_ISUPPER, "isupper", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_ISXDIGIT, "isxdigit", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_TOASCII, "toascii", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_TOLOWER, "tolower", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_TOUPPER, "toupper", BT_FN_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST) + +/* Category: wctype builtins. */ +DEF_C94_BUILTIN (BUILT_IN_ISWALNUM, "iswalnum", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C94_BUILTIN (BUILT_IN_ISWALPHA, "iswalpha", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_ISWBLANK, "iswblank", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C94_BUILTIN (BUILT_IN_ISWCNTRL, "iswcntrl", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C94_BUILTIN (BUILT_IN_ISWDIGIT, "iswdigit", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C94_BUILTIN (BUILT_IN_ISWGRAPH, "iswgraph", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C94_BUILTIN (BUILT_IN_ISWLOWER, "iswlower", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C94_BUILTIN (BUILT_IN_ISWPRINT, "iswprint", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C94_BUILTIN (BUILT_IN_ISWPUNCT, "iswpunct", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C94_BUILTIN (BUILT_IN_ISWSPACE, "iswspace", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C94_BUILTIN (BUILT_IN_ISWUPPER, "iswupper", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C94_BUILTIN (BUILT_IN_ISWXDIGIT, "iswxdigit", BT_FN_INT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C94_BUILTIN (BUILT_IN_TOWLOWER, "towlower", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_C94_BUILTIN (BUILT_IN_TOWUPPER, "towupper", BT_FN_WINT_WINT, ATTR_PURE_NOTHROW_LEAF_LIST) + +/* Category: miscellaneous builtins. */ +DEF_LIB_BUILTIN (BUILT_IN_ABORT, "abort", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_ABS, "abs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_AGGREGATE_INCOMING_ADDRESS, "aggregate_incoming_address", BT_FN_PTR_VAR, ATTR_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ALLOCA, "alloca", BT_FN_PTR_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_APPLY, "apply", BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE, ATTR_NULL) +DEF_GCC_BUILTIN (BUILT_IN_APPLY_ARGS, "apply_args", BT_FN_PTR_VAR, ATTR_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_BSWAP16, "bswap16", BT_FN_UINT16_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_BSWAP32, "bswap32", BT_FN_UINT32_UINT32, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_BSWAP64, "bswap64", BT_FN_UINT64_UINT64, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_CLEAR_CACHE, "__clear_cache", BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LEAF_LIST) +/* [trans-mem]: Adjust BUILT_IN_TM_CALLOC if BUILT_IN_CALLOC is changed. */ +DEF_LIB_BUILTIN (BUILT_IN_CALLOC, "calloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CLASSIFY_TYPE, "classify_type", BT_FN_INT_VAR, ATTR_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CLZ, "clz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CLZIMAX, "clzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CLZL, "clzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CLZLL, "clzll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CONSTANT_P, "constant_p", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CTZ, "ctz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CTZIMAX, "ctzimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CTZL, "ctzl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CTZLL, "ctzll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CLRSB, "clrsb", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CLRSBIMAX, "clrsbimax", BT_FN_INT_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CLRSBL, "clrsbl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CLRSBLL, "clrsbll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_DCGETTEXT, "dcgettext", BT_FN_STRING_CONST_STRING_CONST_STRING_INT, ATTR_FORMAT_ARG_2) +DEF_EXT_LIB_BUILTIN (BUILT_IN_DGETTEXT, "dgettext", BT_FN_STRING_CONST_STRING_CONST_STRING, ATTR_FORMAT_ARG_2) +DEF_GCC_BUILTIN (BUILT_IN_DWARF_CFA, "dwarf_cfa", BT_FN_PTR, ATTR_NULL) +DEF_GCC_BUILTIN (BUILT_IN_DWARF_SP_COLUMN, "dwarf_sp_column", BT_FN_UINT, ATTR_NULL) +DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN, "eh_return", BT_FN_VOID_PTRMODE_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_EH_RETURN_DATA_REGNO, "eh_return_data_regno", BT_FN_INT_INT, ATTR_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECL, "execl", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_SENTINEL_NOTHROW_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECLP, "execlp", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_SENTINEL_NOTHROW_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECLE, "execle", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_NOTHROW_SENTINEL_1) +DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECV, "execv", BT_FN_INT_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVP, "execvp", BT_FN_INT_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVE, "execve", BT_FN_INT_CONST_STRING_PTR_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST) +DEF_LIB_BUILTIN (BUILT_IN_EXIT, "exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST) +DEF_GCC_BUILTIN (BUILT_IN_EXPECT, "expect", BT_FN_LONG_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_ASSUME_ALIGNED, "assume_aligned", BT_FN_PTR_CONST_PTR_SIZE_VAR, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_EXTEND_POINTER, "extend_pointer", BT_FN_UNWINDWORD_PTR, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_EXTRACT_RETURN_ADDR, "extract_return_addr", BT_FN_PTR_PTR, ATTR_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FFS, "ffs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSIMAX, "ffsimax", BT_FN_INT_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSL, "ffsl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSLL, "ffsll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FORK, "fork", BT_FN_PID, ATTR_NOTHROW_LIST) +DEF_GCC_BUILTIN (BUILT_IN_FRAME_ADDRESS, "frame_address", BT_FN_PTR_UINT, ATTR_NULL) +/* [trans-mem]: Adjust BUILT_IN_TM_FREE if BUILT_IN_FREE is changed. */ +DEF_LIB_BUILTIN (BUILT_IN_FREE, "free", BT_FN_VOID_PTR, ATTR_NOTHROW_LIST) +DEF_GCC_BUILTIN (BUILT_IN_FROB_RETURN_ADDR, "frob_return_addr", BT_FN_PTR_PTR, ATTR_NULL) +DEF_EXT_LIB_BUILTIN (BUILT_IN_GETTEXT, "gettext", BT_FN_STRING_CONST_STRING, ATTR_FORMAT_ARG_1) +DEF_C99_BUILTIN (BUILT_IN_IMAXABS, "imaxabs", BT_FN_INTMAX_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_INIT_DWARF_REG_SIZES, "init_dwarf_reg_size_table", BT_FN_VOID_PTR, ATTR_NULL) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITE, "finite", BT_FN_INT_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEF, "finitef", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITEL, "finitel", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED32, "finited32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED64, "finited64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FINITED128, "finited128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_FPCLASSIFY, "fpclassify", BT_FN_INT_INT_INT_INT_INT_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_ISFINITE, "isfinite", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_ISINF_SIGN, "isinf_sign", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_C99_C90RES_BUILTIN (BUILT_IN_ISINF, "isinf", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFF, "isinff", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFL, "isinfl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD32, "isinfd32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD64, "isinfd64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ISINFD128, "isinfd128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_C90RES_BUILTIN (BUILT_IN_ISNAN, "isnan", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANF, "isnanf", BT_FN_INT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNANL, "isnanl", BT_FN_INT_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND32, "isnand32", BT_FN_INT_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND64, "isnand64", BT_FN_INT_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_ISNAND128, "isnand128", BT_FN_INT_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_ISNORMAL, "isnormal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_ISGREATER, "isgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_ISGREATEREQUAL, "isgreaterequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_ISLESS, "isless", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_ISLESSEQUAL, "islessequal", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_ISLESSGREATER, "islessgreater", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_GCC_BUILTIN (BUILT_IN_ISUNORDERED, "isunordered", BT_FN_INT_VAR, ATTR_CONST_NOTHROW_TYPEGENERIC_LEAF) +DEF_LIB_BUILTIN (BUILT_IN_LABS, "labs", BT_FN_LONG_LONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN_LLABS, "llabs", BT_FN_LONGLONG_LONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_LONGJMP, "longjmp", BT_FN_VOID_PTR_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST) +/* [trans-mem]: Adjust BUILT_IN_TM_MALLOC if BUILT_IN_MALLOC is changed. */ +DEF_LIB_BUILTIN (BUILT_IN_MALLOC, "malloc", BT_FN_PTR_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_NEXT_ARG, "next_arg", BT_FN_PTR_VAR, ATTR_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_PARITY, "parity", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_PARITYIMAX, "parityimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_PARITYL, "parityl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_PARITYLL, "parityll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_POPCOUNT, "popcount", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTIMAX, "popcountimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTL, "popcountl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTLL, "popcountll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefetch", BT_FN_VOID_CONST_PTR_VAR, ATTR_NOVOPS_LEAF_LIST) +DEF_LIB_BUILTIN (BUILT_IN_REALLOC, "realloc", BT_FN_PTR_PTR_SIZE, ATTR_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL) +DEF_GCC_BUILTIN (BUILT_IN_SETJMP, "setjmp", BT_FN_INT_PTR, ATTR_NULL) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRFMON, "strfmon", BT_FN_SSIZE_STRING_SIZE_CONST_STRING_VAR, ATTR_FORMAT_STRFMON_NOTHROW_3_4) +DEF_LIB_BUILTIN (BUILT_IN_STRFTIME, "strftime", BT_FN_SIZE_STRING_SIZE_CONST_STRING_CONST_PTR, ATTR_FORMAT_STRFTIME_NOTHROW_3_0) +DEF_GCC_BUILTIN (BUILT_IN_TRAP, "trap", BT_FN_VOID, ATTR_NORETURN_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_UNREACHABLE, "unreachable", BT_FN_VOID, ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_UNWIND_INIT, "unwind_init", BT_FN_VOID, ATTR_NULL) +DEF_GCC_BUILTIN (BUILT_IN_UPDATE_SETJMP_BUF, "update_setjmp_buf", BT_FN_VOID_PTR_INT, ATTR_NULL) +DEF_GCC_BUILTIN (BUILT_IN_VA_COPY, "va_copy", BT_FN_VOID_VALIST_REF_VALIST_ARG, ATTR_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_VA_END, "va_end", BT_FN_VOID_VALIST_REF, ATTR_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_VA_START, "va_start", BT_FN_VOID_VALIST_REF_VAR, ATTR_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_VA_ARG_PACK, "va_arg_pack", BT_FN_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_VA_ARG_PACK_LEN, "va_arg_pack_len", BT_FN_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN__EXIT, "_exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST) +DEF_C99_BUILTIN (BUILT_IN__EXIT2, "_Exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LEAF_LIST) + +/* Implementing nested functions. */ +DEF_BUILTIN_STUB (BUILT_IN_INIT_TRAMPOLINE, "__builtin_init_trampoline") +DEF_BUILTIN_STUB (BUILT_IN_INIT_HEAP_TRAMPOLINE, "__builtin_init_heap_trampoline") +DEF_BUILTIN_STUB (BUILT_IN_ADJUST_TRAMPOLINE, "__builtin_adjust_trampoline") +DEF_BUILTIN_STUB (BUILT_IN_NONLOCAL_GOTO, "__builtin_nonlocal_goto") + +/* Implementing __builtin_setjmp. */ +DEF_BUILTIN_STUB (BUILT_IN_SETJMP_SETUP, "__builtin_setjmp_setup") +DEF_BUILTIN_STUB (BUILT_IN_SETJMP_DISPATCHER, "__builtin_setjmp_dispatcher") +DEF_BUILTIN_STUB (BUILT_IN_SETJMP_RECEIVER, "__builtin_setjmp_receiver") + +/* Implementing variable sized local variables. */ +DEF_BUILTIN_STUB (BUILT_IN_STACK_SAVE, "__builtin_stack_save") +DEF_BUILTIN_STUB (BUILT_IN_STACK_RESTORE, "__builtin_stack_restore") +DEF_BUILTIN_STUB (BUILT_IN_ALLOCA_WITH_ALIGN, "__builtin_alloca_with_align") + +/* Object size checking builtins. */ +DEF_GCC_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_PURE_NOTHROW_LEAF_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY_CHK, "__stpcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY_CHK, "__stpncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCAT_CHK, "__strcat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SNPRINTF_CHK, "__snprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_5_6) +DEF_EXT_LIB_BUILTIN (BUILT_IN_SPRINTF_CHK, "__sprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_4_5) +DEF_EXT_LIB_BUILTIN (BUILT_IN_VSNPRINTF_CHK, "__vsnprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_5_0) +DEF_EXT_LIB_BUILTIN (BUILT_IN_VSPRINTF_CHK, "__vsprintf_chk", BT_FN_INT_STRING_INT_SIZE_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_NOTHROW_4_0) +DEF_EXT_LIB_BUILTIN (BUILT_IN_FPRINTF_CHK, "__fprintf_chk", BT_FN_INT_FILEPTR_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_3_4) +DEF_EXT_LIB_BUILTIN (BUILT_IN_PRINTF_CHK, "__printf_chk", BT_FN_INT_INT_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_2_3) +DEF_EXT_LIB_BUILTIN (BUILT_IN_VFPRINTF_CHK, "__vfprintf_chk", BT_FN_INT_FILEPTR_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_3_0) +DEF_EXT_LIB_BUILTIN (BUILT_IN_VPRINTF_CHK, "__vprintf_chk", BT_FN_INT_INT_CONST_STRING_VALIST_ARG, ATTR_FORMAT_PRINTF_2_0) + +/* Profiling hooks. */ +DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_ENTER, "__cyg_profile_func_enter", BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST, + false, false, false, ATTR_NULL, true, true) +DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_EXIT, "__cyg_profile_func_exit", BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST, + false, false, false, ATTR_NULL, true, true) + +/* TLS thread pointer related builtins. */ +DEF_BUILTIN (BUILT_IN_THREAD_POINTER, "__builtin_thread_pointer", + BUILT_IN_NORMAL, BT_FN_PTR, BT_LAST, + false, false, true, ATTR_CONST_NOTHROW_LIST, true, + targetm.have_tls) + +DEF_BUILTIN (BUILT_IN_SET_THREAD_POINTER, "__builtin_set_thread_pointer", + BUILT_IN_NORMAL, BT_FN_VOID_PTR, BT_LAST, + false, false, true, ATTR_NOTHROW_LIST, true, + targetm.have_tls) + +/* TLS emulation. */ +DEF_BUILTIN (BUILT_IN_EMUTLS_GET_ADDRESS, targetm.emutls.get_address, + BUILT_IN_NORMAL, + BT_FN_PTR_PTR, BT_FN_PTR_PTR, + true, true, true, ATTR_CONST_NOTHROW_NONNULL_LEAF, false, + !targetm.have_tls) +DEF_BUILTIN (BUILT_IN_EMUTLS_REGISTER_COMMON, + targetm.emutls.register_common, BUILT_IN_NORMAL, + BT_FN_VOID_PTR_WORD_WORD_PTR, BT_FN_VOID_PTR_WORD_WORD_PTR, + true, true, true, ATTR_NOTHROW_LEAF_LIST, false, + !targetm.have_tls) + +/* Exception support. */ +DEF_BUILTIN_STUB (BUILT_IN_UNWIND_RESUME, "__builtin_unwind_resume") +DEF_BUILTIN_STUB (BUILT_IN_CXA_END_CLEANUP, "__builtin_cxa_end_cleanup") +DEF_BUILTIN_STUB (BUILT_IN_EH_POINTER, "__builtin_eh_pointer") +DEF_BUILTIN_STUB (BUILT_IN_EH_FILTER, "__builtin_eh_filter") +DEF_BUILTIN_STUB (BUILT_IN_EH_COPY_VALUES, "__builtin_eh_copy_values") + +/* __FILE__, __LINE__, __FUNCTION__ as builtins. */ +DEF_GCC_BUILTIN (BUILT_IN_FILE, "FILE", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_FUNCTION, "FUNCTION", BT_FN_CONST_STRING, ATTR_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST) + +/* Synchronization Primitives. */ +#include "sync-builtins.def" + +/* OpenMP builtins. */ +#include "omp-builtins.def" + +/* GTM builtins. */ +#include "gtm-builtins.def" + +/* Sanitizer builtins. */ +#include "sanitizer.def" + diff --git a/src/include/bversion.h b/src/include/bversion.h new file mode 100644 index 0000000..bc369fc --- /dev/null +++ b/src/include/bversion.h @@ -0,0 +1,4 @@ +#define BUILDING_GCC_MAJOR 4 +#define BUILDING_GCC_MINOR 8 +#define BUILDING_GCC_PATCHLEVEL 5 +#define BUILDING_GCC_VERSION (BUILDING_GCC_MAJOR * 1000 + BUILDING_GCC_MINOR) diff --git a/src/include/c-family/c-common.def b/src/include/c-family/c-common.def new file mode 100644 index 0000000..13113af --- /dev/null +++ b/src/include/c-family/c-common.def @@ -0,0 +1,62 @@ +/* This file contains the definitions and documentation for the + additional tree codes used in the GNU C compiler (see tree.def + for the standard codes). + Copyright (C) 1987-2013 Free Software Foundation, Inc. + Written by Benjamin Chelf + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* Tree nodes used in the C frontend. These are also shared with the + C++ and Objective C frontends. */ + +/* A C_MAYBE_CONST_EXPR, currently only used for C and Objective C, + tracks information about constancy of an expression and VLA type + sizes or VM expressions from typeof that need to be evaluated + before the main expression. It is used during parsing and removed + in c_fully_fold. C_MAYBE_CONST_EXPR_PRE is the expression to + evaluate first, if not NULL; C_MAYBE_CONST_EXPR_EXPR is the main + expression. If C_MAYBE_CONST_EXPR_INT_OPERANDS is set then the + expression may be used in an unevaluated part of an integer + constant expression, but not in an evaluated part. If + C_MAYBE_CONST_EXPR_NON_CONST is set then the expression contains + something that cannot occur in an evaluated part of a constant + expression (or outside of sizeof in C90 mode); otherwise it does + not. */ +DEFTREECODE (C_MAYBE_CONST_EXPR, "c_maybe_const_expr", tcc_expression, 2) + +/* An EXCESS_PRECISION_EXPR, currently only used for C and Objective + C, represents an expression evaluated in greater range or precision + than its type. The type of the EXCESS_PRECISION_EXPR is the + semantic type while the operand represents what is actually being + evaluated. */ +DEFTREECODE (EXCESS_PRECISION_EXPR, "excess_precision_expr", tcc_expression, 1) + +/* Used to represent a user-defined literal. + The operands are an IDENTIFIER for the suffix, the VALUE of the literal, + and for numeric literals the original string representation of the + number. */ +DEFTREECODE (USERDEF_LITERAL, "userdef_literal", tcc_exceptional, 3) + +/* Represents a 'sizeof' expression during C++ template expansion, + or for the purpose of -Wsizeof-pointer-memaccess warning. */ +DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", tcc_expression, 1) + +/* +Local variables: +mode:c +End: +*/ diff --git a/src/include/c-family/c-common.h b/src/include/c-family/c-common.h new file mode 100644 index 0000000..4014651 --- /dev/null +++ b/src/include/c-family/c-common.h @@ -0,0 +1,1136 @@ +/* Definitions for c-common.c. + Copyright (C) 1987-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_C_COMMON_H +#define GCC_C_COMMON_H + +#include "splay-tree.h" +#include "cpplib.h" +#include "ggc.h" +#include "tree.h" + +/* In order for the format checking to accept the C frontend + diagnostic framework extensions, you must include this file before + diagnostic-core.h, not after. The C front end formats are a subset of those + for C++, so they are the appropriate set to use in common code; + cp-tree.h overrides this for C++. */ +#if defined(GCC_DIAGNOSTIC_CORE_H) +#error \ +In order for the format checking to accept the C front end diagnostic \ +framework extensions, you must include this file before diagnostic-core.h \ +never after. +#endif +#ifndef GCC_DIAG_STYLE +#define GCC_DIAG_STYLE __gcc_cdiag__ +#endif +#include "diagnostic-core.h" + +/* Usage of TREE_LANG_FLAG_?: + 0: IDENTIFIER_MARKED (used by search routines). + C_MAYBE_CONST_EXPR_INT_OPERANDS (in C_MAYBE_CONST_EXPR, for C) + 1: C_DECLARED_LABEL_FLAG (in LABEL_DECL) + STATEMENT_LIST_STMT_EXPR (in STATEMENT_LIST) + C_MAYBE_CONST_EXPR_NON_CONST (in C_MAYBE_CONST_EXPR, for C) + 2: unused + 3: STATEMENT_LIST_HAS_LABEL (in STATEMENT_LIST) + 4: unused +*/ + +/* Reserved identifiers. This is the union of all the keywords for C, + C++, and Objective-C. All the type modifiers have to be in one + block at the beginning, because they are used as mask bits. There + are 28 type modifiers; if we add many more we will have to redesign + the mask mechanism. */ + +enum rid +{ + /* Modifiers: */ + /* C, in empirical order of frequency. */ + RID_STATIC = 0, + RID_UNSIGNED, RID_LONG, RID_CONST, RID_EXTERN, + RID_REGISTER, RID_TYPEDEF, RID_SHORT, RID_INLINE, + RID_VOLATILE, RID_SIGNED, RID_AUTO, RID_RESTRICT, + RID_NORETURN, + + /* C extensions */ + RID_COMPLEX, RID_THREAD, RID_SAT, + + /* C++ */ + RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE, + + /* ObjC ("PQ" reserved words - they do not appear after a '@' and + are keywords only in specific contexts) */ + RID_IN, RID_OUT, RID_INOUT, RID_BYCOPY, RID_BYREF, RID_ONEWAY, + + /* ObjC ("PATTR" reserved words - they do not appear after a '@' + and are keywords only as property attributes) */ + RID_GETTER, RID_SETTER, + RID_READONLY, RID_READWRITE, + RID_ASSIGN, RID_RETAIN, RID_COPY, + RID_NONATOMIC, + + /* C (reserved and imaginary types not implemented, so any use is a + syntax error) */ + RID_IMAGINARY, + + /* C */ + RID_INT, RID_CHAR, RID_FLOAT, RID_DOUBLE, RID_VOID, + RID_INT128, + RID_ENUM, RID_STRUCT, RID_UNION, RID_IF, RID_ELSE, + RID_WHILE, RID_DO, RID_FOR, RID_SWITCH, RID_CASE, + RID_DEFAULT, RID_BREAK, RID_CONTINUE, RID_RETURN, RID_GOTO, + RID_SIZEOF, + + /* C extensions */ + RID_ASM, RID_TYPEOF, RID_ALIGNOF, RID_ATTRIBUTE, RID_VA_ARG, + RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR, + RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE, + RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128, + RID_FRACT, RID_ACCUM, + + /* C11 */ + RID_ALIGNAS, + + /* This means to warn that this is a C++ keyword, and then treat it + as a normal identifier. */ + RID_CXX_COMPAT_WARN, + + /* GNU transactional memory extension */ + RID_TRANSACTION_ATOMIC, RID_TRANSACTION_RELAXED, RID_TRANSACTION_CANCEL, + + /* Too many ways of getting the name of a function as a string */ + RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME, + + /* C++ (some of these are keywords in Objective-C as well, but only + if they appear after a '@') */ + RID_BOOL, RID_WCHAR, RID_CLASS, + RID_PUBLIC, RID_PRIVATE, RID_PROTECTED, + RID_TEMPLATE, RID_NULL, RID_CATCH, + RID_DELETE, RID_FALSE, RID_NAMESPACE, + RID_NEW, RID_OFFSETOF, RID_OPERATOR, + RID_THIS, RID_THROW, RID_TRUE, + RID_TRY, RID_TYPENAME, RID_TYPEID, + RID_USING, RID_CHAR16, RID_CHAR32, + + /* casts */ + RID_CONSTCAST, RID_DYNCAST, RID_REINTCAST, RID_STATCAST, + + /* C++ extensions */ + RID_BASES, RID_DIRECT_BASES, + RID_HAS_NOTHROW_ASSIGN, RID_HAS_NOTHROW_CONSTRUCTOR, + RID_HAS_NOTHROW_COPY, RID_HAS_TRIVIAL_ASSIGN, + RID_HAS_TRIVIAL_CONSTRUCTOR, RID_HAS_TRIVIAL_COPY, + RID_HAS_TRIVIAL_DESTRUCTOR, RID_HAS_VIRTUAL_DESTRUCTOR, + RID_IS_ABSTRACT, RID_IS_BASE_OF, + RID_IS_CLASS, RID_IS_CONVERTIBLE_TO, + RID_IS_EMPTY, RID_IS_ENUM, + RID_IS_FINAL, RID_IS_LITERAL_TYPE, + RID_IS_POD, RID_IS_POLYMORPHIC, + RID_IS_STD_LAYOUT, RID_IS_TRIVIAL, + RID_IS_UNION, RID_UNDERLYING_TYPE, + + /* C++11 */ + RID_CONSTEXPR, RID_DECLTYPE, RID_NOEXCEPT, RID_NULLPTR, RID_STATIC_ASSERT, + + /* Objective-C ("AT" reserved words - they are only keywords when + they follow '@') */ + RID_AT_ENCODE, RID_AT_END, + RID_AT_CLASS, RID_AT_ALIAS, RID_AT_DEFS, + RID_AT_PRIVATE, RID_AT_PROTECTED, RID_AT_PUBLIC, RID_AT_PACKAGE, + RID_AT_PROTOCOL, RID_AT_SELECTOR, + RID_AT_THROW, RID_AT_TRY, RID_AT_CATCH, + RID_AT_FINALLY, RID_AT_SYNCHRONIZED, + RID_AT_OPTIONAL, RID_AT_REQUIRED, RID_AT_PROPERTY, + RID_AT_SYNTHESIZE, RID_AT_DYNAMIC, + RID_AT_INTERFACE, + RID_AT_IMPLEMENTATION, + + /* Named address support, mapping the keyword to a particular named address + number. Named address space 0 is reserved for the generic address. If + there are more than 254 named addresses, the addr_space_t type will need + to be grown from an unsigned char to unsigned short. */ + RID_ADDR_SPACE_0, /* generic address */ + RID_ADDR_SPACE_1, + RID_ADDR_SPACE_2, + RID_ADDR_SPACE_3, + RID_ADDR_SPACE_4, + RID_ADDR_SPACE_5, + RID_ADDR_SPACE_6, + RID_ADDR_SPACE_7, + RID_ADDR_SPACE_8, + RID_ADDR_SPACE_9, + RID_ADDR_SPACE_10, + RID_ADDR_SPACE_11, + RID_ADDR_SPACE_12, + RID_ADDR_SPACE_13, + RID_ADDR_SPACE_14, + RID_ADDR_SPACE_15, + + RID_FIRST_ADDR_SPACE = RID_ADDR_SPACE_0, + RID_LAST_ADDR_SPACE = RID_ADDR_SPACE_15, + + RID_MAX, + + RID_FIRST_MODIFIER = RID_STATIC, + RID_LAST_MODIFIER = RID_ONEWAY, + + RID_FIRST_CXX0X = RID_CONSTEXPR, + RID_LAST_CXX0X = RID_STATIC_ASSERT, + RID_FIRST_AT = RID_AT_ENCODE, + RID_LAST_AT = RID_AT_IMPLEMENTATION, + RID_FIRST_PQ = RID_IN, + RID_LAST_PQ = RID_ONEWAY, + RID_FIRST_PATTR = RID_GETTER, + RID_LAST_PATTR = RID_NONATOMIC +}; + +#define OBJC_IS_AT_KEYWORD(rid) \ + ((unsigned int) (rid) >= (unsigned int) RID_FIRST_AT && \ + (unsigned int) (rid) <= (unsigned int) RID_LAST_AT) + +#define OBJC_IS_PQ_KEYWORD(rid) \ + ((unsigned int) (rid) >= (unsigned int) RID_FIRST_PQ && \ + (unsigned int) (rid) <= (unsigned int) RID_LAST_PQ) + +#define OBJC_IS_PATTR_KEYWORD(rid) \ + ((unsigned int) (rid) >= (unsigned int) RID_FIRST_PATTR && \ + (unsigned int) (rid) <= (unsigned int) RID_LAST_PATTR) + +/* OBJC_IS_CXX_KEYWORD recognizes the 'CXX_OBJC' keywords (such as + 'class') which are shared in a subtle way between Objective-C and + C++. When the lexer is lexing in Objective-C/Objective-C++, if it + finds '@' followed by one of these identifiers (eg, '@class'), it + recognizes the whole as an Objective-C keyword. If the identifier + is found elsewhere, it follows the rules of the C/C++ language. + */ +#define OBJC_IS_CXX_KEYWORD(rid) \ + (rid == RID_CLASS \ + || rid == RID_PUBLIC || rid == RID_PROTECTED || rid == RID_PRIVATE \ + || rid == RID_TRY || rid == RID_THROW || rid == RID_CATCH) + +/* The elements of `ridpointers' are identifier nodes for the reserved + type names and storage classes. It is indexed by a RID_... value. */ +extern GTY ((length ("(int) RID_MAX"))) tree *ridpointers; + +/* Standard named or nameless data types of the C compiler. */ + +enum c_tree_index +{ + CTI_CHAR16_TYPE, + CTI_CHAR32_TYPE, + CTI_WCHAR_TYPE, + CTI_UNDERLYING_WCHAR_TYPE, + CTI_WINT_TYPE, + CTI_SIGNED_SIZE_TYPE, /* For format checking only. */ + CTI_UNSIGNED_PTRDIFF_TYPE, /* For format checking only. */ + CTI_INTMAX_TYPE, + CTI_UINTMAX_TYPE, + CTI_WIDEST_INT_LIT_TYPE, + CTI_WIDEST_UINT_LIT_TYPE, + + /* Types for , that may not be defined on all + targets. */ + CTI_SIG_ATOMIC_TYPE, + CTI_INT8_TYPE, + CTI_INT16_TYPE, + CTI_INT32_TYPE, + CTI_INT64_TYPE, + CTI_UINT8_TYPE, + CTI_UINT16_TYPE, + CTI_UINT32_TYPE, + CTI_UINT64_TYPE, + CTI_INT_LEAST8_TYPE, + CTI_INT_LEAST16_TYPE, + CTI_INT_LEAST32_TYPE, + CTI_INT_LEAST64_TYPE, + CTI_UINT_LEAST8_TYPE, + CTI_UINT_LEAST16_TYPE, + CTI_UINT_LEAST32_TYPE, + CTI_UINT_LEAST64_TYPE, + CTI_INT_FAST8_TYPE, + CTI_INT_FAST16_TYPE, + CTI_INT_FAST32_TYPE, + CTI_INT_FAST64_TYPE, + CTI_UINT_FAST8_TYPE, + CTI_UINT_FAST16_TYPE, + CTI_UINT_FAST32_TYPE, + CTI_UINT_FAST64_TYPE, + CTI_INTPTR_TYPE, + CTI_UINTPTR_TYPE, + + CTI_CHAR_ARRAY_TYPE, + CTI_CHAR16_ARRAY_TYPE, + CTI_CHAR32_ARRAY_TYPE, + CTI_WCHAR_ARRAY_TYPE, + CTI_INT_ARRAY_TYPE, + CTI_STRING_TYPE, + CTI_CONST_STRING_TYPE, + + /* Type for boolean expressions (bool in C++, int in C). */ + CTI_TRUTHVALUE_TYPE, + CTI_TRUTHVALUE_TRUE, + CTI_TRUTHVALUE_FALSE, + + CTI_DEFAULT_FUNCTION_TYPE, + + /* These are not types, but we have to look them up all the time. */ + CTI_FUNCTION_NAME_DECL, + CTI_PRETTY_FUNCTION_NAME_DECL, + CTI_C99_FUNCTION_NAME_DECL, + CTI_SAVED_FUNCTION_NAME_DECLS, + + CTI_VOID_ZERO, + + CTI_NULL, + + CTI_MAX +}; + +#define C_CPP_HASHNODE(id) \ + (&(((struct c_common_identifier *) (id))->node)) +#define C_RID_CODE(id) \ + ((enum rid) (((struct c_common_identifier *) (id))->node.rid_code)) +#define C_SET_RID_CODE(id, code) \ + (((struct c_common_identifier *) (id))->node.rid_code = (unsigned char) code) + +/* Identifier part common to the C front ends. Inherits from + tree_identifier, despite appearances. */ +struct GTY(()) c_common_identifier { + struct tree_common common; + struct cpp_hashnode node; +}; + +/* An entry in the reserved keyword table. */ + +struct c_common_resword +{ + const char *const word; + ENUM_BITFIELD(rid) const rid : 16; + const unsigned int disable : 16; +}; + +/* Extra cpp_ttype values for C++. */ + +/* A token type for keywords, as opposed to ordinary identifiers. */ +#define CPP_KEYWORD ((enum cpp_ttype) (N_TTYPES + 1)) + +/* A token type for template-ids. If a template-id is processed while + parsing tentatively, it is replaced with a CPP_TEMPLATE_ID token; + the value of the CPP_TEMPLATE_ID is whatever was returned by + cp_parser_template_id. */ +#define CPP_TEMPLATE_ID ((enum cpp_ttype) (CPP_KEYWORD + 1)) + +/* A token type for nested-name-specifiers. If a + nested-name-specifier is processed while parsing tentatively, it is + replaced with a CPP_NESTED_NAME_SPECIFIER token; the value of the + CPP_NESTED_NAME_SPECIFIER is whatever was returned by + cp_parser_nested_name_specifier_opt. */ +#define CPP_NESTED_NAME_SPECIFIER ((enum cpp_ttype) (CPP_TEMPLATE_ID + 1)) + +/* A token type for pre-parsed C++0x decltype. */ +#define CPP_DECLTYPE ((enum cpp_ttype) (CPP_NESTED_NAME_SPECIFIER + 1)) + +/* The number of token types, including C++-specific ones. */ +#define N_CP_TTYPES ((int) (CPP_DECLTYPE + 1)) + +/* Disable mask. Keywords are disabled if (reswords[i].disable & + mask) is _true_. Thus for keywords which are present in all + languages the disable field is zero. */ + +#define D_CONLY 0x001 /* C only (not in C++). */ +#define D_CXXONLY 0x002 /* C++ only (not in C). */ +#define D_C99 0x004 /* In C, C99 only. */ +#define D_CXX0X 0x008 /* In C++, C++0X only. */ +#define D_EXT 0x010 /* GCC extension. */ +#define D_EXT89 0x020 /* GCC extension incorporated in C99. */ +#define D_ASM 0x040 /* Disabled by -fno-asm. */ +#define D_OBJC 0x080 /* In Objective C and neither C nor C++. */ +#define D_CXX_OBJC 0x100 /* In Objective C, and C++, but not C. */ +#define D_CXXWARN 0x200 /* In C warn with -Wcxx-compat. */ + +/* The reserved keyword table. */ +extern const struct c_common_resword c_common_reswords[]; + +/* The number of items in the reserved keyword table. */ +extern const unsigned int num_c_common_reswords; + +#define char16_type_node c_global_trees[CTI_CHAR16_TYPE] +#define char32_type_node c_global_trees[CTI_CHAR32_TYPE] +#define wchar_type_node c_global_trees[CTI_WCHAR_TYPE] +#define underlying_wchar_type_node c_global_trees[CTI_UNDERLYING_WCHAR_TYPE] +#define wint_type_node c_global_trees[CTI_WINT_TYPE] +#define signed_size_type_node c_global_trees[CTI_SIGNED_SIZE_TYPE] +#define unsigned_ptrdiff_type_node c_global_trees[CTI_UNSIGNED_PTRDIFF_TYPE] +#define intmax_type_node c_global_trees[CTI_INTMAX_TYPE] +#define uintmax_type_node c_global_trees[CTI_UINTMAX_TYPE] +#define widest_integer_literal_type_node c_global_trees[CTI_WIDEST_INT_LIT_TYPE] +#define widest_unsigned_literal_type_node c_global_trees[CTI_WIDEST_UINT_LIT_TYPE] + +#define sig_atomic_type_node c_global_trees[CTI_SIG_ATOMIC_TYPE] +#define int8_type_node c_global_trees[CTI_INT8_TYPE] +#define int16_type_node c_global_trees[CTI_INT16_TYPE] +#define int32_type_node c_global_trees[CTI_INT32_TYPE] +#define int64_type_node c_global_trees[CTI_INT64_TYPE] +#define uint8_type_node c_global_trees[CTI_UINT8_TYPE] +#define c_uint16_type_node c_global_trees[CTI_UINT16_TYPE] +#define c_uint32_type_node c_global_trees[CTI_UINT32_TYPE] +#define c_uint64_type_node c_global_trees[CTI_UINT64_TYPE] +#define int_least8_type_node c_global_trees[CTI_INT_LEAST8_TYPE] +#define int_least16_type_node c_global_trees[CTI_INT_LEAST16_TYPE] +#define int_least32_type_node c_global_trees[CTI_INT_LEAST32_TYPE] +#define int_least64_type_node c_global_trees[CTI_INT_LEAST64_TYPE] +#define uint_least8_type_node c_global_trees[CTI_UINT_LEAST8_TYPE] +#define uint_least16_type_node c_global_trees[CTI_UINT_LEAST16_TYPE] +#define uint_least32_type_node c_global_trees[CTI_UINT_LEAST32_TYPE] +#define uint_least64_type_node c_global_trees[CTI_UINT_LEAST64_TYPE] +#define int_fast8_type_node c_global_trees[CTI_INT_FAST8_TYPE] +#define int_fast16_type_node c_global_trees[CTI_INT_FAST16_TYPE] +#define int_fast32_type_node c_global_trees[CTI_INT_FAST32_TYPE] +#define int_fast64_type_node c_global_trees[CTI_INT_FAST64_TYPE] +#define uint_fast8_type_node c_global_trees[CTI_UINT_FAST8_TYPE] +#define uint_fast16_type_node c_global_trees[CTI_UINT_FAST16_TYPE] +#define uint_fast32_type_node c_global_trees[CTI_UINT_FAST32_TYPE] +#define uint_fast64_type_node c_global_trees[CTI_UINT_FAST64_TYPE] +#define intptr_type_node c_global_trees[CTI_INTPTR_TYPE] +#define uintptr_type_node c_global_trees[CTI_UINTPTR_TYPE] + +#define truthvalue_type_node c_global_trees[CTI_TRUTHVALUE_TYPE] +#define truthvalue_true_node c_global_trees[CTI_TRUTHVALUE_TRUE] +#define truthvalue_false_node c_global_trees[CTI_TRUTHVALUE_FALSE] + +#define char_array_type_node c_global_trees[CTI_CHAR_ARRAY_TYPE] +#define char16_array_type_node c_global_trees[CTI_CHAR16_ARRAY_TYPE] +#define char32_array_type_node c_global_trees[CTI_CHAR32_ARRAY_TYPE] +#define wchar_array_type_node c_global_trees[CTI_WCHAR_ARRAY_TYPE] +#define int_array_type_node c_global_trees[CTI_INT_ARRAY_TYPE] +#define string_type_node c_global_trees[CTI_STRING_TYPE] +#define const_string_type_node c_global_trees[CTI_CONST_STRING_TYPE] + +#define default_function_type c_global_trees[CTI_DEFAULT_FUNCTION_TYPE] + +#define function_name_decl_node c_global_trees[CTI_FUNCTION_NAME_DECL] +#define pretty_function_name_decl_node c_global_trees[CTI_PRETTY_FUNCTION_NAME_DECL] +#define c99_function_name_decl_node c_global_trees[CTI_C99_FUNCTION_NAME_DECL] +#define saved_function_name_decls c_global_trees[CTI_SAVED_FUNCTION_NAME_DECLS] + +/* A node for `((void) 0)'. */ +#define void_zero_node c_global_trees[CTI_VOID_ZERO] + +/* The node for C++ `__null'. */ +#define null_node c_global_trees[CTI_NULL] + +extern GTY(()) tree c_global_trees[CTI_MAX]; + +/* In a RECORD_TYPE, a sorted array of the fields of the type, not a + tree for size reasons. */ +struct GTY((variable_size)) sorted_fields_type { + int len; + tree GTY((length ("%h.len"))) elts[1]; +}; + +/* Mark which labels are explicitly declared. + These may be shadowed, and may be referenced from nested functions. */ +#define C_DECLARED_LABEL_FLAG(label) TREE_LANG_FLAG_1 (label) + +typedef enum c_language_kind +{ + clk_c = 0, /* C90, C94 or C99 */ + clk_objc = 1, /* clk_c with ObjC features. */ + clk_cxx = 2, /* ANSI/ISO C++ */ + clk_objcxx = 3 /* clk_cxx with ObjC features. */ +} +c_language_kind; + +/* To test for a specific language use c_language, defined by each + front end. For "ObjC features" or "not C++" use the macros. */ +extern c_language_kind c_language; + +#define c_dialect_cxx() ((c_language & clk_cxx) != 0) +#define c_dialect_objc() ((c_language & clk_objc) != 0) + +/* The various name of operator that appears in error messages. */ +typedef enum ref_operator { + /* NULL */ + RO_NULL, + /* array indexing */ + RO_ARRAY_INDEXING, + /* unary * */ + RO_UNARY_STAR, + /* -> */ + RO_ARROW, + /* implicit conversion */ + RO_IMPLICIT_CONVERSION, + /* ->* */ + RO_ARROW_STAR +} ref_operator; + +/* Information about a statement tree. */ + +struct GTY(()) stmt_tree_s { + /* A stack of statement lists being collected. */ + vec *x_cur_stmt_list; + + /* In C++, Nonzero if we should treat statements as full + expressions. In particular, this variable is non-zero if at the + end of a statement we should destroy any temporaries created + during that statement. Similarly, if, at the end of a block, we + should destroy any local variables in this block. Normally, this + variable is nonzero, since those are the normal semantics of + C++. + + This flag has no effect in C. */ + int stmts_are_full_exprs_p; +}; + +typedef struct stmt_tree_s *stmt_tree; + +/* Global state pertinent to the current function. Some C dialects + extend this structure with additional fields. */ + +struct GTY(()) c_language_function { + /* While we are parsing the function, this contains information + about the statement-tree that we are building. */ + struct stmt_tree_s x_stmt_tree; + + /* Vector of locally defined typedefs, for + -Wunused-local-typedefs. */ + vec *local_typedefs; +}; + +#define stmt_list_stack (current_stmt_tree ()->x_cur_stmt_list) + +/* When building a statement-tree, this is the current statement list + being collected. */ +#define cur_stmt_list (stmt_list_stack->last ()) + +#define building_stmt_list_p() (stmt_list_stack && !stmt_list_stack->is_empty()) + +/* Language-specific hooks. */ + +/* If non-NULL, this function is called after a precompile header file + is loaded. */ +extern void (*lang_post_pch_load) (void); + +extern void push_file_scope (void); +extern void pop_file_scope (void); +extern stmt_tree current_stmt_tree (void); +extern tree push_stmt_list (void); +extern tree pop_stmt_list (tree); +extern tree add_stmt (tree); +extern void push_cleanup (tree, tree, bool); +extern tree pushdecl_top_level (tree); +extern tree pushdecl (tree); +extern tree build_modify_expr (location_t, tree, tree, enum tree_code, + location_t, tree, tree); +extern tree build_indirect_ref (location_t, tree, ref_operator); + +extern int field_decl_cmp (const void *, const void *); +extern void resort_sorted_fields (void *, void *, gt_pointer_operator, + void *); +extern bool has_c_linkage (const_tree decl); + +/* Switches common to the C front ends. */ + +/* Nonzero means don't output line number information. */ + +extern char flag_no_line_commands; + +/* Nonzero causes -E output not to be done, but directives such as + #define that have side effects are still obeyed. */ + +extern char flag_no_output; + +/* Nonzero means dump macros in some fashion; contains the 'D', 'M', + 'N' or 'U' of the command line switch. */ + +extern char flag_dump_macros; + +/* Nonzero means pass #include lines through to the output. */ + +extern char flag_dump_includes; + +/* Nonzero means process PCH files while preprocessing. */ + +extern bool flag_pch_preprocess; + +/* The file name to which we should write a precompiled header, or + NULL if no header will be written in this compile. */ + +extern const char *pch_file; + +/* Nonzero if an ISO standard was selected. It rejects macros in the + user's namespace. */ + +extern int flag_iso; + +/* C/ObjC language option variables. */ + + +/* Nonzero means allow type mismatches in conditional expressions; + just make their values `void'. */ + +extern int flag_cond_mismatch; + +/* Nonzero means enable C89 Amendment 1 features. */ + +extern int flag_isoc94; + +/* Nonzero means use the ISO C99 (or C11) dialect of C. */ + +extern int flag_isoc99; + +/* Nonzero means use the ISO C11 dialect of C. */ + +extern int flag_isoc11; + +/* Nonzero means that we have builtin functions, and main is an int. */ + +extern int flag_hosted; + +/* ObjC language option variables. */ + + +/* Tells the compiler that this is a special run. Do not perform any + compiling, instead we are to test some platform dependent features + and output a C header file with appropriate definitions. */ + +extern int print_struct_values; + +/* Tells the compiler what is the constant string class for ObjC. */ + +extern const char *constant_string_class_name; + + +/* C++ language option variables. */ + + +/* Nonzero means generate separate instantiation control files and + juggle them at link time. */ + +extern int flag_use_repository; + +/* The supported C++ dialects. */ + +enum cxx_dialect { + /* C++98 with TC1 */ + cxx98, + cxx03 = cxx98, + /* C++11 */ + cxx0x, + cxx11 = cxx0x, + /* C++1y (C++17?) */ + cxx1y +}; + +/* The C++ dialect being used. C++98 is the default. */ +extern enum cxx_dialect cxx_dialect; + +/* Maximum template instantiation depth. This limit is rather + arbitrary, but it exists to limit the time it takes to notice + excessively recursive template instantiations. */ + +extern int max_tinst_depth; + +/* Nonzero means that we should not issue warnings about problems that + occur when the code is executed, because the code being processed + is not expected to be executed. This is set during parsing. This + is used for cases like sizeof() and "0 ? a : b". This is a count, + not a bool, because unexecuted expressions can nest. */ + +extern int c_inhibit_evaluation_warnings; + +/* Whether lexing has been completed, so subsequent preprocessor + errors should use the compiler's input_location. */ + +extern bool done_lexing; + +/* C types are partitioned into three subsets: object, function, and + incomplete types. */ +#define C_TYPE_OBJECT_P(type) \ + (TREE_CODE (type) != FUNCTION_TYPE && TYPE_SIZE (type)) + +#define C_TYPE_INCOMPLETE_P(type) \ + (TREE_CODE (type) != FUNCTION_TYPE && TYPE_SIZE (type) == 0) + +#define C_TYPE_FUNCTION_P(type) \ + (TREE_CODE (type) == FUNCTION_TYPE) + +/* For convenience we define a single macro to identify the class of + object or incomplete types. */ +#define C_TYPE_OBJECT_OR_INCOMPLETE_P(type) \ + (!C_TYPE_FUNCTION_P (type)) + +struct visibility_flags +{ + unsigned inpragma : 1; /* True when in #pragma GCC visibility. */ + unsigned inlines_hidden : 1; /* True when -finlineshidden in effect. */ +}; + +/* Global visibility options. */ +extern struct visibility_flags visibility_options; + +/* Attribute table common to the C front ends. */ +extern const struct attribute_spec c_common_attribute_table[]; +extern const struct attribute_spec c_common_format_attribute_table[]; + +/* Pointer to function to lazily generate the VAR_DECL for __FUNCTION__ etc. + ID is the identifier to use, NAME is the string. + TYPE_DEP indicates whether it depends on type of the function or not + (i.e. __PRETTY_FUNCTION__). */ + +extern tree (*make_fname_decl) (location_t, tree, int); + +/* In c-decl.c and cp/tree.c. FIXME. */ +extern void c_register_addr_space (const char *str, addr_space_t as); + +/* In c-common.c. */ +extern bool in_late_binary_op; +extern const char *c_addr_space_name (addr_space_t as); +extern tree identifier_global_value (tree); +extern tree c_linkage_bindings (tree); +extern void record_builtin_type (enum rid, const char *, tree); +extern tree build_void_list_node (void); +extern void start_fname_decls (void); +extern void finish_fname_decls (void); +extern const char *fname_as_string (int); +extern tree fname_decl (location_t, unsigned, tree); + +extern int check_user_alignment (const_tree, bool); +extern void check_function_arguments (const_tree, int, tree *); +extern void check_function_arguments_recurse (void (*) + (void *, tree, + unsigned HOST_WIDE_INT), + void *, tree, + unsigned HOST_WIDE_INT); +extern bool check_builtin_function_arguments (tree, int, tree *); +extern void check_function_format (tree, int, tree *); +extern tree handle_format_attribute (tree *, tree, tree, int, bool *); +extern tree handle_format_arg_attribute (tree *, tree, tree, int, bool *); +extern bool attribute_takes_identifier_p (const_tree); +extern bool c_common_handle_option (size_t, const char *, int, int, location_t, + const struct cl_option_handlers *); +extern bool default_handle_c_option (size_t, const char *, int); +extern tree c_common_type_for_mode (enum machine_mode, int); +extern tree c_common_type_for_size (unsigned int, int); +extern tree c_common_fixed_point_type_for_size (unsigned int, unsigned int, + int, int); +extern tree c_common_unsigned_type (tree); +extern tree c_common_signed_type (tree); +extern tree c_common_signed_or_unsigned_type (int, tree); +extern void c_common_init_ts (void); +extern tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT, int); +extern bool unsafe_conversion_p (tree, tree, bool); +extern bool decl_with_nonnull_addr_p (const_tree); +extern tree c_fully_fold (tree, bool, bool *); +extern tree decl_constant_value_for_optimization (tree); +extern tree c_wrap_maybe_const (tree, bool); +extern tree c_save_expr (tree); +extern tree c_common_truthvalue_conversion (location_t, tree); +extern void c_apply_type_quals_to_decl (int, tree); +extern tree c_sizeof_or_alignof_type (location_t, tree, bool, int); +extern tree c_alignof_expr (location_t, tree); +/* Print an error message for invalid operands to arith operation CODE. + NOP_EXPR is used as a special case (see truthvalue_conversion). */ +extern void binary_op_error (location_t, enum tree_code, tree, tree); +extern tree fix_string_type (tree); +extern void constant_expression_warning (tree); +extern void constant_expression_error (tree); +extern bool strict_aliasing_warning (tree, tree, tree); +extern void sizeof_pointer_memaccess_warning (location_t *, tree, + vec *, tree *, + bool (*) (tree, tree)); +extern void warnings_for_convert_and_check (tree, tree, tree); +extern tree convert_and_check (tree, tree); +extern void overflow_warning (location_t, tree); +extern bool warn_if_unused_value (const_tree, location_t); +extern void warn_logical_operator (location_t, enum tree_code, tree, + enum tree_code, tree, enum tree_code, tree); +extern void check_main_parameter_types (tree decl); +extern bool c_determine_visibility (tree); +extern bool same_scalar_type_ignoring_signedness (tree, tree); +extern void mark_valid_location_for_stdc_pragma (bool); +extern bool valid_location_for_stdc_pragma_p (void); +extern void set_float_const_decimal64 (void); +extern void clear_float_const_decimal64 (void); +extern bool float_const_decimal64_p (void); + +extern bool keyword_begins_type_specifier (enum rid); +extern bool keyword_is_storage_class_specifier (enum rid); +extern bool keyword_is_type_qualifier (enum rid); +extern bool keyword_is_decl_specifier (enum rid); +extern bool cxx_fundamental_alignment_p (unsigned); + +#define c_sizeof(LOC, T) c_sizeof_or_alignof_type (LOC, T, true, 1) +#define c_alignof(LOC, T) c_sizeof_or_alignof_type (LOC, T, false, 1) + +/* Subroutine of build_binary_op, used for certain operations. */ +extern tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise); + +/* Subroutine of build_binary_op, used for comparison operations. + See if the operands have both been converted from subword integer types + and, if so, perhaps change them both back to their original type. */ +extern tree shorten_compare (tree *, tree *, tree *, enum tree_code *); + +extern tree pointer_int_sum (location_t, enum tree_code, tree, tree); + +/* Add qualifiers to a type, in the fashion for C. */ +extern tree c_build_qualified_type (tree, int); + +/* Build tree nodes and builtin functions common to both C and C++ language + frontends. */ +extern void c_common_nodes_and_builtins (void); + +extern void disable_builtin_function (const char *); + +extern void set_compound_literal_name (tree decl); + +extern tree build_va_arg (location_t, tree, tree); + +extern const unsigned int c_family_lang_mask; +extern unsigned int c_common_option_lang_mask (void); +extern void c_common_initialize_diagnostics (diagnostic_context *); +extern bool c_common_complain_wrong_lang_p (const struct cl_option *); +extern void c_common_init_options_struct (struct gcc_options *); +extern void c_common_init_options (unsigned int, struct cl_decoded_option *); +extern bool c_common_post_options (const char **); +extern bool c_common_init (void); +extern void c_common_finish (void); +extern void c_common_parse_file (void); +extern alias_set_type c_common_get_alias_set (tree); +extern void c_register_builtin_type (tree, const char*); +extern bool c_promoting_integer_type_p (const_tree); +extern int self_promoting_args_p (const_tree); +extern tree strip_pointer_operator (tree); +extern tree strip_pointer_or_array_types (tree); +extern HOST_WIDE_INT c_common_to_target_charset (HOST_WIDE_INT); + +/* This is the basic parsing function. */ +extern void c_parse_file (void); + +extern void warn_for_omitted_condop (location_t, tree); + +/* These macros provide convenient access to the various _STMT nodes. */ + +/* Nonzero if a given STATEMENT_LIST represents the outermost binding + if a statement expression. */ +#define STATEMENT_LIST_STMT_EXPR(NODE) \ + TREE_LANG_FLAG_1 (STATEMENT_LIST_CHECK (NODE)) + +/* Nonzero if a label has been added to the statement list. */ +#define STATEMENT_LIST_HAS_LABEL(NODE) \ + TREE_LANG_FLAG_3 (STATEMENT_LIST_CHECK (NODE)) + +/* C_MAYBE_CONST_EXPR accessors. */ +#define C_MAYBE_CONST_EXPR_PRE(NODE) \ + TREE_OPERAND (C_MAYBE_CONST_EXPR_CHECK (NODE), 0) +#define C_MAYBE_CONST_EXPR_EXPR(NODE) \ + TREE_OPERAND (C_MAYBE_CONST_EXPR_CHECK (NODE), 1) +#define C_MAYBE_CONST_EXPR_INT_OPERANDS(NODE) \ + TREE_LANG_FLAG_0 (C_MAYBE_CONST_EXPR_CHECK (NODE)) +#define C_MAYBE_CONST_EXPR_NON_CONST(NODE) \ + TREE_LANG_FLAG_1 (C_MAYBE_CONST_EXPR_CHECK (NODE)) +#define EXPR_INT_CONST_OPERANDS(EXPR) \ + (INTEGRAL_TYPE_P (TREE_TYPE (EXPR)) \ + && (TREE_CODE (EXPR) == INTEGER_CST \ + || (TREE_CODE (EXPR) == C_MAYBE_CONST_EXPR \ + && C_MAYBE_CONST_EXPR_INT_OPERANDS (EXPR)))) + +/* In a FIELD_DECL, nonzero if the decl was originally a bitfield. */ +#define DECL_C_BIT_FIELD(NODE) \ + (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) == 1) +#define SET_DECL_C_BIT_FIELD(NODE) \ + (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 1) +#define CLEAR_DECL_C_BIT_FIELD(NODE) \ + (DECL_LANG_FLAG_4 (FIELD_DECL_CHECK (NODE)) = 0) + +extern tree do_case (location_t, tree, tree); +extern tree build_stmt (location_t, enum tree_code, ...); +extern tree build_real_imag_expr (location_t, enum tree_code, tree); + +/* These functions must be defined by each front-end which implements + a variant of the C language. They are used in c-common.c. */ + +extern tree build_unary_op (location_t, enum tree_code, tree, int); +extern tree build_binary_op (location_t, enum tree_code, tree, tree, int); +extern tree perform_integral_promotions (tree); + +/* These functions must be defined by each front-end which implements + a variant of the C language. They are used by port files. */ + +extern tree default_conversion (tree); + +/* Given two integer or real types, return the type for their sum. + Given two compatible ANSI C types, returns the merged type. */ + +extern tree common_type (tree, tree); + +extern tree decl_constant_value (tree); + +/* Handle increment and decrement of boolean types. */ +extern tree boolean_increment (enum tree_code, tree); + +extern int case_compare (splay_tree_key, splay_tree_key); + +extern tree c_add_case_label (location_t, splay_tree, tree, tree, tree, tree); + +extern void c_do_switch_warnings (splay_tree, location_t, tree, tree); + +extern tree build_function_call (location_t, tree, tree); + +extern tree build_function_call_vec (location_t, tree, vec *, + vec *); + +extern tree resolve_overloaded_builtin (location_t, tree, vec *); + +extern tree finish_label_address_expr (tree, location_t); + +/* Same function prototype, but the C and C++ front ends have + different implementations. Used in c-common.c. */ +extern tree lookup_label (tree); +extern tree lookup_name (tree); +extern bool lvalue_p (const_tree); + +extern bool vector_targets_convertible_p (const_tree t1, const_tree t2); +extern bool vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note); +extern tree c_build_vec_perm_expr (location_t, tree, tree, tree); + +extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *); + +extern void init_c_lex (void); + +extern void c_cpp_builtins (cpp_reader *); +extern void c_cpp_builtins_optimize_pragma (cpp_reader *, tree, tree); +extern bool c_cpp_error (cpp_reader *, int, int, location_t, unsigned int, + const char *, va_list *) + ATTRIBUTE_GCC_DIAG(6,0); + +extern bool parse_optimize_options (tree, bool); + +/* Positive if an implicit `extern "C"' scope has just been entered; + negative if such a scope has just been exited. */ +extern GTY(()) int pending_lang_change; + +/* Information recorded about each file examined during compilation. */ + +struct c_fileinfo +{ + int time; /* Time spent in the file. */ + + /* Flags used only by C++. + INTERFACE_ONLY nonzero means that we are in an "interface" section + of the compiler. INTERFACE_UNKNOWN nonzero means we cannot trust + the value of INTERFACE_ONLY. If INTERFACE_UNKNOWN is zero and + INTERFACE_ONLY is zero, it means that we are responsible for + exporting definitions that others might need. */ + short interface_only; + short interface_unknown; +}; + +struct c_fileinfo *get_fileinfo (const char *); +extern void dump_time_statistics (void); + +extern bool c_dump_tree (void *, tree); + +extern void verify_sequence_points (tree); + +extern tree fold_offsetof_1 (tree); +extern tree fold_offsetof (tree); + +/* Places where an lvalue, or modifiable lvalue, may be required. + Used to select diagnostic messages in lvalue_error and + readonly_error. */ +enum lvalue_use { + lv_assign, + lv_increment, + lv_decrement, + lv_addressof, + lv_asm +}; + +extern void readonly_error (tree, enum lvalue_use); +extern void lvalue_error (location_t, enum lvalue_use); +extern void invalid_indirection_error (location_t, tree, ref_operator); + +extern int complete_array_type (tree *, tree, bool); + +extern tree builtin_type_for_size (int, bool); + +extern void c_common_mark_addressable_vec (tree); + +extern void warn_array_subscript_with_type_char (tree); +extern void warn_about_parentheses (location_t, + enum tree_code, + enum tree_code, tree, + enum tree_code, tree); +extern void warn_for_unused_label (tree label); +extern void warn_for_div_by_zero (location_t, tree divisor); +extern void warn_for_sign_compare (location_t, + tree orig_op0, tree orig_op1, + tree op0, tree op1, + tree result_type, + enum tree_code resultcode); +extern void do_warn_double_promotion (tree, tree, tree, const char *, + location_t); +extern void set_underlying_type (tree); +extern void record_locally_defined_typedef (tree); +extern void maybe_record_typedef_use (tree); +extern void maybe_warn_unused_local_typedefs (void); +extern vec *make_tree_vector (void); +extern void release_tree_vector (vec *); +extern vec *make_tree_vector_single (tree); +extern vec *make_tree_vector_from_list (tree); +extern vec *make_tree_vector_copy (const vec *); + +/* In c-gimplify.c */ +extern void c_genericize (tree); +extern int c_gimplify_expr (tree *, gimple_seq *, gimple_seq *); +extern tree c_build_bind_expr (location_t, tree, tree); + +/* In c-pch.c */ +extern void pch_init (void); +extern void pch_cpp_save_state (void); +extern int c_common_valid_pch (cpp_reader *pfile, const char *name, int fd); +extern void c_common_read_pch (cpp_reader *pfile, const char *name, int fd, + const char *orig); +extern void c_common_write_pch (void); +extern void c_common_no_more_pch (void); +extern void c_common_pch_pragma (cpp_reader *pfile, const char *); + +/* In *-checksum.c */ +extern const unsigned char executable_checksum[16]; + +/* In c-cppbuiltin.c */ +extern void builtin_define_std (const char *macro); +extern void builtin_define_with_value (const char *, const char *, int); +extern void c_stddef_cpp_builtins (void); +extern void fe_file_change (const struct line_map *); +extern void c_parse_error (const char *, enum cpp_ttype, tree, unsigned char); + +/* In c-ppoutput.c */ +extern void init_pp_output (FILE *); +extern void preprocess_file (cpp_reader *); +extern void pp_file_change (const struct line_map *); +extern void pp_dir_change (cpp_reader *, const char *); +extern bool check_missing_format_attribute (tree, tree); + +/* In c-omp.c */ +extern tree c_finish_omp_master (location_t, tree); +extern tree c_finish_omp_critical (location_t, tree, tree); +extern tree c_finish_omp_ordered (location_t, tree); +extern void c_finish_omp_barrier (location_t); +extern tree c_finish_omp_atomic (location_t, enum tree_code, enum tree_code, + tree, tree, tree, tree, tree); +extern void c_finish_omp_flush (location_t); +extern void c_finish_omp_taskwait (location_t); +extern void c_finish_omp_taskyield (location_t); +extern tree c_finish_omp_for (location_t, tree, tree, tree, tree, tree, tree); +extern void c_split_parallel_clauses (location_t, tree, tree *, tree *); +extern enum omp_clause_default_kind c_omp_predetermined_sharing (tree); + +/* Not in c-omp.c; provided by the front end. */ +extern bool c_omp_sharing_predetermined (tree); +extern tree c_omp_remap_decl (tree, bool); +extern void record_types_used_by_current_var_decl (tree); + +/* Return next tree in the chain for chain_next walking of tree nodes. */ +static inline tree +c_tree_chain_next (tree t) +{ + /* TREE_CHAIN of a type is TYPE_STUB_DECL, which is different + kind of object, never a long chain of nodes. Prefer + TYPE_NEXT_VARIANT for types. */ + if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPE_COMMON)) + return TYPE_NEXT_VARIANT (t); + /* Otherwise, if there is TREE_CHAIN, return it. */ + if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_COMMON)) + return TREE_CHAIN (t); + return NULL; +} + +/* Mask used by tm_stmt_attr. */ +#define TM_STMT_ATTR_OUTER 2 +#define TM_STMT_ATTR_ATOMIC 4 +#define TM_STMT_ATTR_RELAXED 8 + +extern int parse_tm_stmt_attr (tree, int); + +/* Mask used by tm_attr_to_mask and tm_mask_to_attr. Note that these + are ordered specifically such that more restrictive attributes are + at lower bit positions. This fact is known by the C++ tm attribute + inheritance code such that least bit extraction (mask & -mask) results + in the most restrictive attribute. */ +#define TM_ATTR_SAFE 1 +#define TM_ATTR_CALLABLE 2 +#define TM_ATTR_PURE 4 +#define TM_ATTR_IRREVOCABLE 8 +#define TM_ATTR_MAY_CANCEL_OUTER 16 + +extern int tm_attr_to_mask (tree); +extern tree tm_mask_to_attr (int); +extern tree find_tm_attribute (tree); + +/* A suffix-identifier value doublet that represents user-defined literals + for C++-0x. */ +enum overflow_type { + OT_UNDERFLOW = -1, + OT_NONE, + OT_OVERFLOW +}; + +struct GTY(()) tree_userdef_literal { + struct tree_base base; + tree suffix_id; + tree value; + tree num_string; + enum overflow_type overflow; +}; + +#define USERDEF_LITERAL_SUFFIX_ID(NODE) \ + (((struct tree_userdef_literal *)USERDEF_LITERAL_CHECK (NODE))->suffix_id) + +#define USERDEF_LITERAL_VALUE(NODE) \ + (((struct tree_userdef_literal *)USERDEF_LITERAL_CHECK (NODE))->value) + +#define USERDEF_LITERAL_OVERFLOW(NODE) \ + (((struct tree_userdef_literal *)USERDEF_LITERAL_CHECK (NODE))->overflow) + +#define USERDEF_LITERAL_NUM_STRING(NODE) \ + (((struct tree_userdef_literal *)USERDEF_LITERAL_CHECK (NODE))->num_string) + +#define USERDEF_LITERAL_TYPE(NODE) \ + (TREE_TYPE (USERDEF_LITERAL_VALUE (NODE))) + +extern tree build_userdef_literal (tree suffix_id, tree value, + enum overflow_type overflow, + tree num_string); + +extern void convert_vector_to_pointer_for_subscript (location_t, tree*, tree); + +/* Possibe cases of scalar_to_vector conversion. */ +enum stv_conv { + stv_error, /* Error occured. */ + stv_nothing, /* Nothing happened. */ + stv_firstarg, /* First argument must be expanded. */ + stv_secondarg /* Second argument must be expanded. */ +}; + +extern enum stv_conv scalar_to_vector (location_t loc, enum tree_code code, + tree op0, tree op1, bool); + +#endif /* ! GCC_C_COMMON_H */ diff --git a/src/include/c-family/c-objc.h b/src/include/c-family/c-objc.h new file mode 100644 index 0000000..bf4e3d5 --- /dev/null +++ b/src/include/c-family/c-objc.h @@ -0,0 +1,114 @@ +/* Definitions of Objective-C front-end entry points used for C and C++. + Copyright (C) 1987-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_C_COMMON_OBJC_H +#define GCC_C_COMMON_OBJC_H + +/* ObjC ivar visibility types. */ +typedef enum objc_ivar_visibility_kind { + OBJC_IVAR_VIS_PROTECTED = 0, + OBJC_IVAR_VIS_PUBLIC = 1, + OBJC_IVAR_VIS_PRIVATE = 2, + OBJC_IVAR_VIS_PACKAGE = 3 +} objc_ivar_visibility_kind; + +/* Objective-C / Objective-C++ entry points. */ + +/* The following ObjC/ObjC++ functions are called by the C and/or C++ + front-ends; they all must have corresponding stubs in stub-objc.c. */ +extern void objc_write_global_declarations (void); +extern tree objc_is_class_name (tree); +extern tree objc_is_object_ptr (tree); +extern void objc_check_decl (tree); +extern void objc_check_global_decl (tree); +extern tree objc_common_type (tree, tree); +extern bool objc_compare_types (tree, tree, int, tree); +extern bool objc_have_common_type (tree, tree, int, tree); +extern bool objc_diagnose_private_ivar (tree); +extern void objc_volatilize_decl (tree); +extern tree objc_rewrite_function_call (tree, tree); +extern tree objc_message_selector (void); +extern tree objc_lookup_ivar (tree, tree); +extern void objc_clear_super_receiver (void); +extern int objc_is_public (tree, tree); +extern tree objc_is_id (tree); +extern void objc_declare_alias (tree, tree); +extern void objc_declare_class (tree); +extern void objc_declare_protocol (tree, tree); +extern tree objc_build_message_expr (tree, tree); +extern tree objc_finish_message_expr (tree, tree, tree, tree*); +extern tree objc_build_selector_expr (location_t, tree); +extern tree objc_build_protocol_expr (tree); +extern tree objc_build_encode_expr (tree); +extern tree objc_build_string_object (tree); +extern tree objc_get_protocol_qualified_type (tree, tree); +extern tree objc_get_class_reference (tree); +extern tree objc_get_class_ivars (tree); +extern bool objc_detect_field_duplicates (bool); +extern void objc_start_class_interface (tree, tree, tree, tree); +extern void objc_start_category_interface (tree, tree, tree, tree); +extern void objc_start_protocol (tree, tree, tree); +extern void objc_continue_interface (void); +extern void objc_finish_interface (void); +extern void objc_start_class_implementation (tree, tree); +extern void objc_start_category_implementation (tree, tree); +extern void objc_continue_implementation (void); +extern void objc_finish_implementation (void); +extern void objc_set_visibility (objc_ivar_visibility_kind); +extern tree objc_build_method_signature (bool, tree, tree, tree, bool); +extern void objc_add_method_declaration (bool, tree, tree); +extern bool objc_start_method_definition (bool, tree, tree, tree); +extern void objc_finish_method_definition (tree); +extern void objc_add_instance_variable (tree); +extern tree objc_build_keyword_decl (tree, tree, tree, tree); +extern tree objc_build_throw_stmt (location_t, tree); +extern void objc_begin_try_stmt (location_t, tree); +extern tree objc_finish_try_stmt (void); +extern void objc_begin_catch_clause (tree); +extern void objc_finish_catch_clause (void); +extern void objc_build_finally_clause (location_t, tree); +extern tree objc_build_synchronized (location_t, tree, tree); +extern int objc_static_init_needed_p (void); +extern tree objc_generate_static_init_call (tree); +extern tree objc_generate_write_barrier (tree, enum tree_code, tree); +extern void objc_set_method_opt (bool); +extern void objc_finish_foreach_loop (location_t, tree, tree, tree, tree, tree); +extern bool objc_method_decl (enum tree_code); +extern void objc_add_property_declaration (location_t, tree, bool, bool, bool, + bool, bool, bool, tree, tree); +extern tree objc_maybe_build_component_ref (tree, tree); +extern tree objc_build_class_component_ref (tree, tree); +extern tree objc_maybe_build_modify_expr (tree, tree); +extern tree objc_build_incr_expr_for_property_ref (location_t, enum tree_code, + tree, tree); +extern void objc_add_synthesize_declaration (location_t, tree); +extern void objc_add_dynamic_declaration (location_t, tree); +extern const char * objc_maybe_printable_name (tree, int); +extern bool objc_is_property_ref (tree); +extern bool objc_string_ref_type_p (tree); +extern void objc_check_format_arg (tree, tree); +extern void objc_finish_function (void); +extern void objc_maybe_warn_exceptions (location_t); + +/* The following are provided by the C and C++ front-ends, and called by + ObjC/ObjC++. */ +extern void *objc_get_current_scope (void); +extern void objc_mark_locals_volatile (void *); + +#endif /* ! GCC_C_COMMON_OBJC_H */ diff --git a/src/include/c-family/c-pragma.h b/src/include/c-family/c-pragma.h new file mode 100644 index 0000000..41215db --- /dev/null +++ b/src/include/c-family/c-pragma.h @@ -0,0 +1,150 @@ +/* Pragma related interfaces. + Copyright (C) 1995-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_C_PRAGMA_H +#define GCC_C_PRAGMA_H + +#include "cpplib.h" /* For enum cpp_ttype. */ + +/* Pragma identifiers built in to the front end parsers. Identifiers + for ancillary handlers will follow these. */ +typedef enum pragma_kind { + PRAGMA_NONE = 0, + + PRAGMA_OMP_ATOMIC, + PRAGMA_OMP_BARRIER, + PRAGMA_OMP_CRITICAL, + PRAGMA_OMP_FLUSH, + PRAGMA_OMP_FOR, + PRAGMA_OMP_MASTER, + PRAGMA_OMP_ORDERED, + PRAGMA_OMP_PARALLEL, + PRAGMA_OMP_PARALLEL_FOR, + PRAGMA_OMP_PARALLEL_SECTIONS, + PRAGMA_OMP_SECTION, + PRAGMA_OMP_SECTIONS, + PRAGMA_OMP_SINGLE, + PRAGMA_OMP_TASK, + PRAGMA_OMP_TASKWAIT, + PRAGMA_OMP_TASKYIELD, + PRAGMA_OMP_THREADPRIVATE, + + PRAGMA_GCC_PCH_PREPROCESS, + + PRAGMA_FIRST_EXTERNAL +} pragma_kind; + + +/* All clauses defined by OpenMP 2.5 and 3.0. + Used internally by both C and C++ parsers. */ +typedef enum pragma_omp_clause { + PRAGMA_OMP_CLAUSE_NONE = 0, + + PRAGMA_OMP_CLAUSE_COLLAPSE, + PRAGMA_OMP_CLAUSE_COPYIN, + PRAGMA_OMP_CLAUSE_COPYPRIVATE, + PRAGMA_OMP_CLAUSE_DEFAULT, + PRAGMA_OMP_CLAUSE_FIRSTPRIVATE, + PRAGMA_OMP_CLAUSE_IF, + PRAGMA_OMP_CLAUSE_LASTPRIVATE, + PRAGMA_OMP_CLAUSE_NOWAIT, + PRAGMA_OMP_CLAUSE_NUM_THREADS, + PRAGMA_OMP_CLAUSE_ORDERED, + PRAGMA_OMP_CLAUSE_PRIVATE, + PRAGMA_OMP_CLAUSE_REDUCTION, + PRAGMA_OMP_CLAUSE_SCHEDULE, + PRAGMA_OMP_CLAUSE_SHARED, + PRAGMA_OMP_CLAUSE_UNTIED, + PRAGMA_OMP_CLAUSE_FINAL, + PRAGMA_OMP_CLAUSE_MERGEABLE +} pragma_omp_clause; + +extern struct cpp_reader* parse_in; + +/* It's safe to always leave visibility pragma enabled as if + visibility is not supported on the host OS platform the + statements are ignored. */ +extern void push_visibility (const char *, int); +extern bool pop_visibility (int); + +extern void init_pragma (void); + +/* Front-end wrappers for pragma registration. */ +typedef void (*pragma_handler_1arg)(struct cpp_reader *); +/* A second pragma handler, which adds a void * argument allowing to pass extra + data to the handler. */ +typedef void (*pragma_handler_2arg)(struct cpp_reader *, void *); + +/* This union allows to abstract the different handlers. */ +union gen_pragma_handler { + pragma_handler_1arg handler_1arg; + pragma_handler_2arg handler_2arg; +}; +/* Internally used to keep the data of the handler. */ +struct internal_pragma_handler_d { + union gen_pragma_handler handler; + /* Permits to know if handler is a pragma_handler_1arg (extra_data is false) + or a pragma_handler_2arg (extra_data is true). */ + bool extra_data; + /* A data field which can be used when extra_data is true. */ + void * data; +}; +typedef struct internal_pragma_handler_d internal_pragma_handler; + +extern void c_register_pragma (const char *space, const char *name, + pragma_handler_1arg handler); +extern void c_register_pragma_with_data (const char *space, const char *name, + pragma_handler_2arg handler, + void *data); + +extern void c_register_pragma_with_expansion (const char *space, + const char *name, + pragma_handler_1arg handler); +extern void c_register_pragma_with_expansion_and_data (const char *space, + const char *name, + pragma_handler_2arg handler, + void *data); +extern void c_invoke_pragma_handler (unsigned int); + +extern void maybe_apply_pragma_weak (tree); +extern void maybe_apply_pending_pragma_weaks (void); +extern tree maybe_apply_renaming_pragma (tree, tree); +extern void add_to_renaming_pragma_list (tree, tree); + +extern enum cpp_ttype pragma_lex (tree *); + +/* Flags for use with c_lex_with_flags. The values here were picked + so that 0 means to translate and join strings. */ +#define C_LEX_STRING_NO_TRANSLATE 1 /* Do not lex strings into + execution character set. */ +#define C_LEX_STRING_NO_JOIN 2 /* Do not concatenate strings + nor translate them into execution + character set. */ + +/* This is not actually available to pragma parsers. It's merely a + convenient location to declare this function for c-lex, after + having enum cpp_ttype declared. */ +extern enum cpp_ttype c_lex_with_flags (tree *, location_t *, unsigned char *, + int); + +extern void c_pp_lookup_pragma (unsigned int, const char **, const char **); + +extern GTY(()) tree pragma_extern_prefix; + +#endif /* GCC_C_PRAGMA_H */ diff --git a/src/include/c-family/c-pretty-print.h b/src/include/c-family/c-pretty-print.h new file mode 100644 index 0000000..04b72c4 --- /dev/null +++ b/src/include/c-family/c-pretty-print.h @@ -0,0 +1,215 @@ +/* Various declarations for the C and C++ pretty-printers. + Copyright (C) 2002-2013 Free Software Foundation, Inc. + Contributed by Gabriel Dos Reis + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_C_PRETTY_PRINTER +#define GCC_C_PRETTY_PRINTER + +#include "tree.h" +#include "c-family/c-common.h" +#include "pretty-print.h" + + +typedef enum + { + pp_c_flag_abstract = 1 << 1, + pp_c_flag_gnu_v3 = 1 << 2, + pp_c_flag_last_bit = 3 + } pp_c_pretty_print_flags; + + +/* The data type used to bundle information necessary for pretty-printing + a C or C++ entity. */ +typedef struct c_pretty_print_info c_pretty_printer; + +/* The type of a C pretty-printer 'member' function. */ +typedef void (*c_pretty_print_fn) (c_pretty_printer *, tree); + +/* The datatype that contains information necessary for pretty-printing + a tree that represents a C construct. Any pretty-printer for a + language using C/c++ syntax can derive from this datatype and reuse + facilities provided here. It can do so by having a subobject of type + c_pretty_printer and override the macro pp_c_base to return a pointer + to that subobject. Such a pretty-printer has the responsibility to + initialize the pp_base() part, then call pp_c_pretty_printer_init + to set up the components that are specific to the C pretty-printer. + A derived pretty-printer can override any function listed in the + vtable below. See cp/cxx-pretty-print.h and cp/cxx-pretty-print.c + for an example of derivation. */ +struct c_pretty_print_info +{ + pretty_printer base; + /* Points to the first element of an array of offset-list. + Not used yet. */ + int *offset_list; + + pp_flags flags; + + /* These must be overridden by each of the C and C++ front-end to + reflect their understanding of syntactic productions when they differ. */ + c_pretty_print_fn declaration; + c_pretty_print_fn declaration_specifiers; + c_pretty_print_fn declarator; + c_pretty_print_fn abstract_declarator; + c_pretty_print_fn direct_abstract_declarator; + c_pretty_print_fn type_specifier_seq; + c_pretty_print_fn direct_declarator; + c_pretty_print_fn ptr_operator; + c_pretty_print_fn parameter_list; + c_pretty_print_fn type_id; + c_pretty_print_fn simple_type_specifier; + c_pretty_print_fn function_specifier; + c_pretty_print_fn storage_class_specifier; + c_pretty_print_fn initializer; + + c_pretty_print_fn statement; + + c_pretty_print_fn constant; + c_pretty_print_fn id_expression; + c_pretty_print_fn primary_expression; + c_pretty_print_fn postfix_expression; + c_pretty_print_fn unary_expression; + c_pretty_print_fn multiplicative_expression; + c_pretty_print_fn conditional_expression; + c_pretty_print_fn assignment_expression; + c_pretty_print_fn expression; +}; + +/* Override the pp_base macro. Derived pretty-printers should not + touch this macro. Instead they should override pp_c_base instead. */ +#undef pp_base +#define pp_base(PP) (&pp_c_base (PP)->base) + + +#define pp_c_tree_identifier(PPI, ID) \ + pp_c_identifier (PPI, IDENTIFIER_POINTER (ID)) + +#define pp_declaration(PPI, T) \ + pp_c_base (PPI)->declaration (pp_c_base (PPI), T) +#define pp_declaration_specifiers(PPI, D) \ + pp_c_base (PPI)->declaration_specifiers (pp_c_base (PPI), D) +#define pp_abstract_declarator(PP, D) \ + pp_c_base (PP)->abstract_declarator (pp_c_base (PP), D) +#define pp_type_specifier_seq(PPI, D) \ + pp_c_base (PPI)->type_specifier_seq (pp_c_base (PPI), D) +#define pp_declarator(PPI, D) \ + pp_c_base (PPI)->declarator (pp_c_base (PPI), D) +#define pp_direct_declarator(PPI, D) \ + pp_c_base (PPI)->direct_declarator (pp_c_base (PPI), D) +#define pp_direct_abstract_declarator(PP, D) \ + pp_c_base (PP)->direct_abstract_declarator (pp_c_base (PP), D) +#define pp_ptr_operator(PP, D) \ + pp_c_base (PP)->ptr_operator (pp_c_base (PP), D) +#define pp_parameter_list(PPI, T) \ + pp_c_base (PPI)->parameter_list (pp_c_base (PPI), T) +#define pp_type_id(PPI, D) \ + pp_c_base (PPI)->type_id (pp_c_base (PPI), D) +#define pp_simple_type_specifier(PP, T) \ + pp_c_base (PP)->simple_type_specifier (pp_c_base (PP), T) +#define pp_function_specifier(PP, D) \ + pp_c_base (PP)->function_specifier (pp_c_base (PP), D) +#define pp_storage_class_specifier(PP, D) \ + pp_c_base (PP)->storage_class_specifier (pp_c_base (PP), D); + +#define pp_statement(PPI, S) \ + pp_c_base (PPI)->statement (pp_c_base (PPI), S) + +#define pp_constant(PP, E) \ + pp_c_base (PP)->constant (pp_c_base (PP), E) +#define pp_id_expression(PP, E) \ + pp_c_base (PP)->id_expression (pp_c_base (PP), E) +#define pp_primary_expression(PPI, E) \ + pp_c_base (PPI)->primary_expression (pp_c_base (PPI), E) +#define pp_postfix_expression(PPI, E) \ + pp_c_base (PPI)->postfix_expression (pp_c_base (PPI), E) +#define pp_unary_expression(PPI, E) \ + pp_c_base (PPI)->unary_expression (pp_c_base (PPI), E) +#define pp_initializer(PPI, E) \ + pp_c_base (PPI)->initializer (pp_c_base (PPI), E) +#define pp_multiplicative_expression(PPI, E) \ + pp_c_base (PPI)->multiplicative_expression (pp_c_base (PPI), E) +#define pp_conditional_expression(PPI, E) \ + pp_c_base (PPI)->conditional_expression (pp_c_base (PPI), E) +#define pp_assignment_expression(PPI, E) \ + pp_c_base (PPI)->assignment_expression (pp_c_base (PPI), E) +#define pp_expression(PP, E) \ + pp_c_base (PP)->expression (pp_c_base (PP), E) + + +/* Returns the c_pretty_printer base object of PRETTY-PRINTER. This + macro must be overridden by any subclass of c_pretty_print_info. */ +#define pp_c_base(PP) (PP) + +extern void pp_c_pretty_printer_init (c_pretty_printer *); +void pp_c_whitespace (c_pretty_printer *); +void pp_c_left_paren (c_pretty_printer *); +void pp_c_right_paren (c_pretty_printer *); +void pp_c_left_brace (c_pretty_printer *); +void pp_c_right_brace (c_pretty_printer *); +void pp_c_left_bracket (c_pretty_printer *); +void pp_c_right_bracket (c_pretty_printer *); +void pp_c_dot (c_pretty_printer *); +void pp_c_ampersand (c_pretty_printer *); +void pp_c_star (c_pretty_printer *); +void pp_c_arrow (c_pretty_printer *); +void pp_c_semicolon (c_pretty_printer *); +void pp_c_complement (c_pretty_printer *); +void pp_c_exclamation (c_pretty_printer *); +void pp_c_space_for_pointer_operator (c_pretty_printer *, tree); + +/* Declarations. */ +void pp_c_tree_decl_identifier (c_pretty_printer *, tree); +void pp_c_function_definition (c_pretty_printer *, tree); +void pp_c_attributes (c_pretty_printer *, tree); +void pp_c_attributes_display (c_pretty_printer *, tree); +void pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type); +void pp_c_type_qualifier_list (c_pretty_printer *, tree); +void pp_c_parameter_type_list (c_pretty_printer *, tree); +void pp_c_declaration (c_pretty_printer *, tree); +void pp_c_declaration_specifiers (c_pretty_printer *, tree); +void pp_c_declarator (c_pretty_printer *, tree); +void pp_c_direct_declarator (c_pretty_printer *, tree); +void pp_c_specifier_qualifier_list (c_pretty_printer *, tree); +void pp_c_function_specifier (c_pretty_printer *, tree); +void pp_c_type_id (c_pretty_printer *, tree); +void pp_c_direct_abstract_declarator (c_pretty_printer *, tree); +void pp_c_type_specifier (c_pretty_printer *, tree); +void pp_c_storage_class_specifier (c_pretty_printer *, tree); +/* Statements. */ +void pp_c_statement (c_pretty_printer *, tree); +/* Expressions. */ +void pp_c_expression (c_pretty_printer *, tree); +void pp_c_logical_or_expression (c_pretty_printer *, tree); +void pp_c_expression_list (c_pretty_printer *, tree); +void pp_c_constructor_elts (c_pretty_printer *, vec *); +void pp_c_call_argument_list (c_pretty_printer *, tree); +void pp_c_unary_expression (c_pretty_printer *, tree); +void pp_c_cast_expression (c_pretty_printer *, tree); +void pp_c_postfix_expression (c_pretty_printer *, tree); +void pp_c_primary_expression (c_pretty_printer *, tree); +void pp_c_init_declarator (c_pretty_printer *, tree); +void pp_c_constant (c_pretty_printer *, tree); +void pp_c_id_expression (c_pretty_printer *, tree); +void pp_c_ws_string (c_pretty_printer *, const char *); +void pp_c_identifier (c_pretty_printer *, const char *); +void pp_c_string_literal (c_pretty_printer *, tree); + +void print_c_tree (FILE *file, tree t); + +#endif /* GCC_C_PRETTY_PRINTER */ diff --git a/src/include/c-tree.h b/src/include/c-tree.h new file mode 100644 index 0000000..1e6e68a --- /dev/null +++ b/src/include/c-tree.h @@ -0,0 +1,673 @@ +/* Definitions for C parsing and type checking. + Copyright (C) 1987-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_C_TREE_H +#define GCC_C_TREE_H + +#include "c-family/c-common.h" +#include "diagnostic.h" + +/* struct lang_identifier is private to c-decl.c, but langhooks.c needs to + know how big it is. This is sanity-checked in c-decl.c. */ +#define C_SIZEOF_STRUCT_LANG_IDENTIFIER \ + (sizeof (struct c_common_identifier) + 3 * sizeof (void *)) + +/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */ +#define C_TYPE_FIELDS_READONLY(TYPE) TREE_LANG_FLAG_1 (TYPE) + +/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is volatile. */ +#define C_TYPE_FIELDS_VOLATILE(TYPE) TREE_LANG_FLAG_2 (TYPE) + +/* In a RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE + nonzero if the definition of the type has already started. */ +#define C_TYPE_BEING_DEFINED(TYPE) TYPE_LANG_FLAG_0 (TYPE) + +/* In an incomplete RECORD_TYPE or UNION_TYPE, a list of variable + declarations whose type would be completed by completing that type. */ +#define C_TYPE_INCOMPLETE_VARS(TYPE) TYPE_VFIELD (TYPE) + +/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a + keyword. C_RID_CODE (node) is then the RID_* value of the keyword, + and C_RID_YYCODE is the token number wanted by Yacc. */ +#define C_IS_RESERVED_WORD(ID) TREE_LANG_FLAG_0 (ID) + +/* Record whether a type or decl was written with nonconstant size. + Note that TYPE_SIZE may have simplified to a constant. */ +#define C_TYPE_VARIABLE_SIZE(TYPE) TYPE_LANG_FLAG_1 (TYPE) +#define C_DECL_VARIABLE_SIZE(TYPE) DECL_LANG_FLAG_0 (TYPE) + +/* Record whether a type is defined inside a struct or union type. + This is used for -Wc++-compat. */ +#define C_TYPE_DEFINED_IN_STRUCT(TYPE) TYPE_LANG_FLAG_2 (TYPE) + +/* Record whether a typedef for type `int' was actually `signed int'. */ +#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP) + +/* For a FUNCTION_DECL, nonzero if it was defined without an explicit + return type. */ +#define C_FUNCTION_IMPLICIT_INT(EXP) DECL_LANG_FLAG_1 (EXP) + +/* For a FUNCTION_DECL, nonzero if it was an implicit declaration. */ +#define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP) + +/* For FUNCTION_DECLs, evaluates true if the decl is built-in but has + been declared. */ +#define C_DECL_DECLARED_BUILTIN(EXP) \ + DECL_LANG_FLAG_3 (FUNCTION_DECL_CHECK (EXP)) + +/* For FUNCTION_DECLs, evaluates true if the decl is built-in, has a + built-in prototype and does not have a non-built-in prototype. */ +#define C_DECL_BUILTIN_PROTOTYPE(EXP) \ + DECL_LANG_FLAG_6 (FUNCTION_DECL_CHECK (EXP)) + +/* Record whether a decl was declared register. This is strictly a + front-end flag, whereas DECL_REGISTER is used for code generation; + they may differ for structures with volatile fields. */ +#define C_DECL_REGISTER(EXP) DECL_LANG_FLAG_4 (EXP) + +/* Record whether a decl was used in an expression anywhere except an + unevaluated operand of sizeof / typeof / alignof. This is only + used for functions declared static but not defined, though outside + sizeof and typeof it is set for other function decls as well. */ +#define C_DECL_USED(EXP) DECL_LANG_FLAG_5 (FUNCTION_DECL_CHECK (EXP)) + +/* Record whether a variable has been declared threadprivate by + #pragma omp threadprivate. */ +#define C_DECL_THREADPRIVATE_P(DECL) DECL_LANG_FLAG_3 (VAR_DECL_CHECK (DECL)) + +/* Nonzero for a decl which either doesn't exist or isn't a prototype. + N.B. Could be simplified if all built-in decls had complete prototypes + (but this is presently difficult because some of them need FILE*). */ +#define C_DECL_ISNT_PROTOTYPE(EXP) \ + (EXP == 0 \ + || (!prototype_p (TREE_TYPE (EXP)) \ + && !DECL_BUILT_IN (EXP))) + +/* For FUNCTION_TYPE, a hidden list of types of arguments. The same as + TYPE_ARG_TYPES for functions with prototypes, but created for functions + without prototypes. */ +#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_LANG_SLOT_1 (NODE) + +/* For a CONSTRUCTOR, whether some initializer contains a + subexpression meaning it is not a constant expression. */ +#define CONSTRUCTOR_NON_CONST(EXPR) TREE_LANG_FLAG_1 (CONSTRUCTOR_CHECK (EXPR)) + +/* Record parser information about an expression that is irrelevant + for code generation alongside a tree representing its value. */ +struct c_expr +{ + /* The value of the expression. */ + tree value; + /* Record the original unary/binary operator of an expression, which may + have been changed by fold, STRING_CST for unparenthesized string + constants, C_MAYBE_CONST_EXPR for __builtin_constant_p calls + (even if parenthesized), for subexpressions, and for non-constant + initializers, or ERROR_MARK for other expressions (including + parenthesized expressions). */ + enum tree_code original_code; + /* If not NULL, the original type of an expression. This will + differ from the type of the value field for an enum constant. + The type of an enum constant is a plain integer type, but this + field will be the enum type. */ + tree original_type; +}; + +/* Type alias for struct c_expr. This allows to use the structure + inside the VEC types. */ +typedef struct c_expr c_expr_t; + +/* A varray of c_expr_t. */ + +/* Append a new c_expr_t element to V. */ +#define C_EXPR_APPEND(V, ELEM) \ + do { \ + c_expr_t __elem = (ELEM); \ + vec_safe_push (V, __elem); \ + } while (0) + +/* A kind of type specifier. Note that this information is currently + only used to distinguish tag definitions, tag references and typeof + uses. */ +enum c_typespec_kind { + /* No typespec. This appears only in struct c_declspec. */ + ctsk_none, + /* A reserved keyword type specifier. */ + ctsk_resword, + /* A reference to a tag, previously declared, such as "struct foo". + This includes where the previous declaration was as a different + kind of tag, in which case this is only valid if shadowing that + tag in an inner scope. */ + ctsk_tagref, + /* A reference to a tag, not previously declared in a visible + scope. */ + ctsk_tagfirstref, + /* A definition of a tag such as "struct foo { int a; }". */ + ctsk_tagdef, + /* A typedef name. */ + ctsk_typedef, + /* An ObjC-specific kind of type specifier. */ + ctsk_objc, + /* A typeof specifier. */ + ctsk_typeof +}; + +/* A type specifier: this structure is created in the parser and + passed to declspecs_add_type only. */ +struct c_typespec { + /* What kind of type specifier this is. */ + enum c_typespec_kind kind; + /* Whether the expression has operands suitable for use in constant + expressions. */ + bool expr_const_operands; + /* The specifier itself. */ + tree spec; + /* An expression to be evaluated before the type specifier, in the + case of typeof specifiers, or NULL otherwise or if no such + expression is required for a particular typeof specifier. In + particular, when typeof is applied to an expression of variably + modified type, that expression must be evaluated in order to + determine array sizes that form part of the type, but the + expression itself (as opposed to the array sizes) forms no part + of the type and so needs to be recorded separately. */ + tree expr; +}; + +/* A storage class specifier. */ +enum c_storage_class { + csc_none, + csc_auto, + csc_extern, + csc_register, + csc_static, + csc_typedef +}; + +/* A type specifier keyword "void", "_Bool", "char", "int", "float", + "double", "_Decimal32", "_Decimal64", "_Decimal128", "_Fract", "_Accum", + or none of these. */ +enum c_typespec_keyword { + cts_none, + cts_void, + cts_bool, + cts_char, + cts_int, + cts_float, + cts_int128, + cts_double, + cts_dfloat32, + cts_dfloat64, + cts_dfloat128, + cts_fract, + cts_accum +}; + +/* This enum lists all the possible declarator specifiers, storage + class or attribute that a user can write. There is at least one + enumerator per possible declarator specifier in the struct + c_declspecs below. + + It is used to index the array of declspec locations in struct + c_declspecs. */ +enum c_declspec_word { + cdw_typespec /* A catch-all for a typespec. */, + cdw_storage_class /* A catch-all for a storage class */, + cdw_attributes, + cdw_typedef, + cdw_explicit_signed, + cdw_deprecated, + cdw_default_int, + cdw_long, + cdw_long_long, + cdw_short, + cdw_signed, + cdw_unsigned, + cdw_complex, + cdw_inline, + cdw_noreturn, + cdw_thread, + cdw_const, + cdw_volatile, + cdw_restrict, + cdw_saturating, + cdw_alignas, + cdw_address_space, + cdw_number_of_elements /* This one must always be the last + enumerator. */ +}; + +/* A sequence of declaration specifiers in C. When a new declaration + specifier is added, please update the enum c_declspec_word above + accordingly. */ +struct c_declspecs { + source_location locations[cdw_number_of_elements]; + /* The type specified, if a single type specifier such as a struct, + union or enum specifier, typedef name or typeof specifies the + whole type, or NULL_TREE if none or a keyword such as "void" or + "char" is used. Does not include qualifiers. */ + tree type; + /* Any expression to be evaluated before the type, from a typeof + specifier. */ + tree expr; + /* The attributes from a typedef decl. */ + tree decl_attr; + /* When parsing, the attributes. Outside the parser, this will be + NULL; attributes (possibly from multiple lists) will be passed + separately. */ + tree attrs; + /* The base-2 log of the greatest alignment required by an _Alignas + specifier, in bytes, or -1 if no such specifiers with nonzero + alignment. */ + int align_log; + /* The storage class specifier, or csc_none if none. */ + enum c_storage_class storage_class; + /* Any type specifier keyword used such as "int", not reflecting + modifiers such as "short", or cts_none if none. */ + ENUM_BITFIELD (c_typespec_keyword) typespec_word : 8; + /* The kind of type specifier if one has been seen, ctsk_none + otherwise. */ + ENUM_BITFIELD (c_typespec_kind) typespec_kind : 3; + /* Whether any expressions in typeof specifiers may appear in + constant expressions. */ + BOOL_BITFIELD expr_const_operands : 1; + /* Whether any declaration specifiers have been seen at all. */ + BOOL_BITFIELD declspecs_seen_p : 1; + /* Whether something other than a storage class specifier or + attribute has been seen. This is used to warn for the + obsolescent usage of storage class specifiers other than at the + start of the list. (Doing this properly would require function + specifiers to be handled separately from storage class + specifiers.) */ + BOOL_BITFIELD non_sc_seen_p : 1; + /* Whether the type is specified by a typedef or typeof name. */ + BOOL_BITFIELD typedef_p : 1; + /* Whether the type is explicitly "signed" or specified by a typedef + whose type is explicitly "signed". */ + BOOL_BITFIELD explicit_signed_p : 1; + /* Whether the specifiers include a deprecated typedef. */ + BOOL_BITFIELD deprecated_p : 1; + /* Whether the type defaulted to "int" because there were no type + specifiers. */ + BOOL_BITFIELD default_int_p : 1; + /* Whether "long" was specified. */ + BOOL_BITFIELD long_p : 1; + /* Whether "long" was specified more than once. */ + BOOL_BITFIELD long_long_p : 1; + /* Whether "short" was specified. */ + BOOL_BITFIELD short_p : 1; + /* Whether "signed" was specified. */ + BOOL_BITFIELD signed_p : 1; + /* Whether "unsigned" was specified. */ + BOOL_BITFIELD unsigned_p : 1; + /* Whether "complex" was specified. */ + BOOL_BITFIELD complex_p : 1; + /* Whether "inline" was specified. */ + BOOL_BITFIELD inline_p : 1; + /* Whether "_Noreturn" was speciied. */ + BOOL_BITFIELD noreturn_p : 1; + /* Whether "__thread" was specified. */ + BOOL_BITFIELD thread_p : 1; + /* Whether "const" was specified. */ + BOOL_BITFIELD const_p : 1; + /* Whether "volatile" was specified. */ + BOOL_BITFIELD volatile_p : 1; + /* Whether "restrict" was specified. */ + BOOL_BITFIELD restrict_p : 1; + /* Whether "_Sat" was specified. */ + BOOL_BITFIELD saturating_p : 1; + /* Whether any alignment specifier (even with zero alignment) was + specified. */ + BOOL_BITFIELD alignas_p : 1; + /* The address space that the declaration belongs to. */ + addr_space_t address_space; +}; + +/* The various kinds of declarators in C. */ +enum c_declarator_kind { + /* An identifier. */ + cdk_id, + /* A function. */ + cdk_function, + /* An array. */ + cdk_array, + /* A pointer. */ + cdk_pointer, + /* Parenthesized declarator with nested attributes. */ + cdk_attrs +}; + +typedef struct c_arg_tag_d { + /* The argument name. */ + tree id; + /* The type of the argument. */ + tree type; +} c_arg_tag; + + +/* Information about the parameters in a function declarator. */ +struct c_arg_info { + /* A list of parameter decls. */ + tree parms; + /* A list of structure, union and enum tags defined. */ + vec *tags; + /* A list of argument types to go in the FUNCTION_TYPE. */ + tree types; + /* A list of non-parameter decls (notably enumeration constants) + defined with the parameters. */ + tree others; + /* A compound expression of VLA sizes from the parameters, or NULL. + In a function definition, these are used to ensure that + side-effects in sizes of arrays converted to pointers (such as a + parameter int i[n++]) take place; otherwise, they are + ignored. */ + tree pending_sizes; + /* True when these arguments had [*]. */ + BOOL_BITFIELD had_vla_unspec : 1; +}; + +/* A declarator. */ +struct c_declarator { + /* The kind of declarator. */ + enum c_declarator_kind kind; + location_t id_loc; /* Currently only set for cdk_id, cdk_array. */ + /* Except for cdk_id, the contained declarator. For cdk_id, NULL. */ + struct c_declarator *declarator; + union { + /* For identifiers, an IDENTIFIER_NODE or NULL_TREE if an abstract + declarator. */ + tree id; + /* For functions. */ + struct c_arg_info *arg_info; + /* For arrays. */ + struct { + /* The array dimension, or NULL for [] and [*]. */ + tree dimen; + /* The qualifiers inside []. */ + int quals; + /* The attributes (currently ignored) inside []. */ + tree attrs; + /* Whether [static] was used. */ + BOOL_BITFIELD static_p : 1; + /* Whether [*] was used. */ + BOOL_BITFIELD vla_unspec_p : 1; + } array; + /* For pointers, the qualifiers on the pointer type. */ + int pointer_quals; + /* For attributes. */ + tree attrs; + } u; +}; + +/* A type name. */ +struct c_type_name { + /* The declaration specifiers. */ + struct c_declspecs *specs; + /* The declarator. */ + struct c_declarator *declarator; +}; + +/* A parameter. */ +struct c_parm { + /* The declaration specifiers, minus any prefix attributes. */ + struct c_declspecs *specs; + /* The attributes. */ + tree attrs; + /* The declarator. */ + struct c_declarator *declarator; +}; + +/* Used when parsing an enum. Initialized by start_enum. */ +struct c_enum_contents +{ + /* While defining an enum type, this is 1 plus the last enumerator + constant value. */ + tree enum_next_value; + + /* Nonzero means that there was overflow computing enum_next_value. */ + int enum_overflow; +}; + +/* A type of reference to a static identifier in an inline + function. */ +enum c_inline_static_type { + /* Identifier with internal linkage used in function that may be an + inline definition (i.e., file-scope static). */ + csi_internal, + /* Modifiable object with static storage duration defined in + function that may be an inline definition (i.e., local + static). */ + csi_modifiable +}; + + +/* in c-parser.c */ +extern void c_parse_init (void); + +/* in c-aux-info.c */ +extern void gen_aux_info_record (tree, int, int, int); + +/* in c-decl.c */ +struct c_spot_bindings; +struct c_struct_parse_info; +extern struct obstack parser_obstack; +extern tree c_break_label; +extern tree c_cont_label; + +extern bool global_bindings_p (void); +extern void push_scope (void); +extern tree pop_scope (void); +extern void c_bindings_start_stmt_expr (struct c_spot_bindings *); +extern void c_bindings_end_stmt_expr (struct c_spot_bindings *); + +extern void record_inline_static (location_t, tree, tree, + enum c_inline_static_type); +extern void c_init_decl_processing (void); +extern void c_print_identifier (FILE *, tree, int); +extern int quals_from_declspecs (const struct c_declspecs *); +extern struct c_declarator *build_array_declarator (location_t, tree, + struct c_declspecs *, + bool, bool); +extern tree build_enumerator (location_t, location_t, struct c_enum_contents *, + tree, tree); +extern tree check_for_loop_decls (location_t, bool); +extern void mark_forward_parm_decls (void); +extern void declare_parm_level (void); +extern void undeclared_variable (location_t, tree); +extern tree lookup_label_for_goto (location_t, tree); +extern tree declare_label (tree); +extern tree define_label (location_t, tree); +extern struct c_spot_bindings *c_get_switch_bindings (void); +extern void c_release_switch_bindings (struct c_spot_bindings *); +extern bool c_check_switch_jump_warnings (struct c_spot_bindings *, + location_t, location_t); +extern void finish_decl (tree, location_t, tree, tree, tree); +extern tree finish_enum (tree, tree, tree); +extern void finish_function (void); +extern tree finish_struct (location_t, tree, tree, tree, + struct c_struct_parse_info *); +extern struct c_arg_info *build_arg_info (void); +extern struct c_arg_info *get_parm_info (bool, tree); +extern tree grokfield (location_t, struct c_declarator *, + struct c_declspecs *, tree, tree *); +extern tree groktypename (struct c_type_name *, tree *, bool *); +extern tree grokparm (const struct c_parm *, tree *); +extern tree implicitly_declare (location_t, tree); +extern void keep_next_level (void); +extern void pending_xref_error (void); +extern void c_push_function_context (void); +extern void c_pop_function_context (void); +extern void push_parm_decl (const struct c_parm *, tree *); +extern struct c_declarator *set_array_declarator_inner (struct c_declarator *, + struct c_declarator *); +extern tree c_builtin_function (tree); +extern tree c_builtin_function_ext_scope (tree); +extern void shadow_tag (const struct c_declspecs *); +extern void shadow_tag_warned (const struct c_declspecs *, int); +extern tree start_enum (location_t, struct c_enum_contents *, tree); +extern int start_function (struct c_declspecs *, struct c_declarator *, tree); +extern tree start_decl (struct c_declarator *, struct c_declspecs *, bool, + tree); +extern tree start_struct (location_t, enum tree_code, tree, + struct c_struct_parse_info **); +extern void store_parm_decls (void); +extern void store_parm_decls_from (struct c_arg_info *); +extern tree xref_tag (enum tree_code, tree); +extern struct c_typespec parser_xref_tag (location_t, enum tree_code, tree); +extern struct c_parm *build_c_parm (struct c_declspecs *, tree, + struct c_declarator *); +extern struct c_declarator *build_attrs_declarator (tree, + struct c_declarator *); +extern struct c_declarator *build_function_declarator (struct c_arg_info *, + struct c_declarator *); +extern struct c_declarator *build_id_declarator (tree); +extern struct c_declarator *make_pointer_declarator (struct c_declspecs *, + struct c_declarator *); +extern struct c_declspecs *build_null_declspecs (void); +extern struct c_declspecs *declspecs_add_qual (source_location, + struct c_declspecs *, tree); +extern struct c_declspecs *declspecs_add_type (location_t, + struct c_declspecs *, + struct c_typespec); +extern struct c_declspecs *declspecs_add_scspec (source_location, + struct c_declspecs *, tree); +extern struct c_declspecs *declspecs_add_attrs (source_location, + struct c_declspecs *, tree); +extern struct c_declspecs *declspecs_add_addrspace (source_location, + struct c_declspecs *, + addr_space_t); +extern struct c_declspecs *declspecs_add_alignas (source_location, + struct c_declspecs *, tree); +extern struct c_declspecs *finish_declspecs (struct c_declspecs *); + +/* in c-objc-common.c */ +extern bool c_objc_common_init (void); +extern bool c_missing_noreturn_ok_p (tree); +extern bool c_warn_unused_global_decl (const_tree); +extern void c_initialize_diagnostics (diagnostic_context *); +extern bool c_vla_unspec_p (tree x, tree fn); + +/* in c-typeck.c */ +extern int in_alignof; +extern int in_sizeof; +extern int in_typeof; + +extern tree c_last_sizeof_arg; + +extern struct c_switch *c_switch_stack; + +extern tree c_objc_common_truthvalue_conversion (location_t, tree); +extern tree require_complete_type (tree); +extern int same_translation_unit_p (const_tree, const_tree); +extern int comptypes (tree, tree); +extern int comptypes_check_different_types (tree, tree, bool *); +extern bool c_vla_type_p (const_tree); +extern bool c_mark_addressable (tree); +extern void c_incomplete_type_error (const_tree, const_tree); +extern tree c_type_promotes_to (tree); +extern struct c_expr default_function_array_conversion (location_t, + struct c_expr); +extern struct c_expr default_function_array_read_conversion (location_t, + struct c_expr); +extern void mark_exp_read (tree); +extern tree composite_type (tree, tree); +extern tree build_component_ref (location_t, tree, tree); +extern tree build_array_ref (location_t, tree, tree); +extern tree build_external_ref (location_t, tree, int, tree *); +extern void pop_maybe_used (bool); +extern struct c_expr c_expr_sizeof_expr (location_t, struct c_expr); +extern struct c_expr c_expr_sizeof_type (location_t, struct c_type_name *); +extern struct c_expr parser_build_unary_op (location_t, enum tree_code, + struct c_expr); +extern struct c_expr parser_build_binary_op (location_t, + enum tree_code, struct c_expr, + struct c_expr); +extern tree build_conditional_expr (location_t, tree, bool, tree, tree, + tree, tree); +extern tree build_compound_expr (location_t, tree, tree); +extern tree c_cast_expr (location_t, struct c_type_name *, tree); +extern tree build_c_cast (location_t, tree, tree); +extern void store_init_value (location_t, tree, tree, tree); +extern void error_init (const char *); +extern void pedwarn_init (location_t, int opt, const char *); +extern void maybe_warn_string_init (tree, struct c_expr); +extern void start_init (tree, tree, int); +extern void finish_init (void); +extern void really_start_incremental_init (tree); +extern void push_init_level (int, struct obstack *); +extern struct c_expr pop_init_level (int, struct obstack *); +extern void set_init_index (tree, tree, struct obstack *); +extern void set_init_label (tree, struct obstack *); +extern void process_init_element (struct c_expr, bool, struct obstack *); +extern tree build_compound_literal (location_t, tree, tree, bool); +extern void check_compound_literal_type (location_t, struct c_type_name *); +extern tree c_start_case (location_t, location_t, tree); +extern void c_finish_case (tree); +extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool); +extern tree build_asm_stmt (tree, tree); +extern int c_types_compatible_p (tree, tree); +extern tree c_begin_compound_stmt (bool); +extern tree c_end_compound_stmt (location_t, tree, bool); +extern void c_finish_if_stmt (location_t, tree, tree, tree, bool); +extern void c_finish_loop (location_t, tree, tree, tree, tree, tree, bool); +extern tree c_begin_stmt_expr (void); +extern tree c_finish_stmt_expr (location_t, tree); +extern tree c_process_expr_stmt (location_t, tree); +extern tree c_finish_expr_stmt (location_t, tree); +extern tree c_finish_return (location_t, tree, tree); +extern tree c_finish_bc_stmt (location_t, tree *, bool); +extern tree c_finish_goto_label (location_t, tree); +extern tree c_finish_goto_ptr (location_t, tree); +extern tree c_expr_to_decl (tree, bool *, bool *); +extern tree c_begin_omp_parallel (void); +extern tree c_finish_omp_parallel (location_t, tree, tree); +extern tree c_begin_omp_task (void); +extern tree c_finish_omp_task (location_t, tree, tree); +extern tree c_finish_omp_clauses (tree); +extern tree c_build_va_arg (location_t, tree, tree); +extern tree c_finish_transaction (location_t, tree, int); +extern tree c_build_function_call_vec (location_t, tree, vec *, + vec *); + +/* Set to 0 at beginning of a function definition, set to 1 if + a return statement that specifies a return value is seen. */ + +extern int current_function_returns_value; + +/* Set to 0 at beginning of a function definition, set to 1 if + a return statement with no argument is seen. */ + +extern int current_function_returns_null; + +/* Set to 0 at beginning of a function definition, set to 1 if + a call to a noreturn function is seen. */ + +extern int current_function_returns_abnormally; + +/* Mode used to build pointers (VOIDmode means ptr_mode). */ + +extern enum machine_mode c_default_pointer_mode; + +/* In c-decl.c */ +extern void c_finish_incomplete_decl (tree); +extern void c_write_global_declarations (void); + +/* In c-errors.c */ +extern void pedwarn_c90 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); +extern void pedwarn_c99 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); + +#endif /* ! GCC_C_TREE_H */ diff --git a/src/include/cfg-flags.def b/src/include/cfg-flags.def new file mode 100644 index 0000000..de127d6 --- /dev/null +++ b/src/include/cfg-flags.def @@ -0,0 +1,186 @@ +/* Flags on basic blocks and edges. + Copyright (C) 2012-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* This file defines flags that may appear on basic blocks or on + edges. Source files define DEF_BASIC_BLOCK_FLAG or DEF_EDGE_FLAG + appropriately before including this file. */ + +#if !defined(DEF_BASIC_BLOCK_FLAG) && !defined(DEF_EDGE_FLAG) +#error "You must define DEF_BASIC_BLOCK_FLAG or DEF_EDGE_FLAG" +#endif + +#ifdef DEF_BASIC_BLOCK_FLAG + +/* Masks for basic_block.flags. + + The format of this file is: DEF_BASIC_BLOCK_FLAG(NAME, IDX). + NAME is the name of the basic block flag. A flag BB_#NAME will be + created and the name is used in dump_edge_info. + IDX is a sequence number that is used to determine the value + of the flag, which is 1 << IDX). + + BB_HOT_PARTITION and BB_COLD_PARTITION should be preserved throughout + the compilation, so they are never cleared. + + All other flags may be cleared by clear_bb_flags(). It is generally + a bad idea to rely on any flags being up-to-date. */ + +/* Only set on blocks that have just been created by create_bb. */ +DEF_BASIC_BLOCK_FLAG(NEW, 0) + +/* Set by find_unreachable_blocks. Do not rely on this being set in any + pass. */ +DEF_BASIC_BLOCK_FLAG(REACHABLE, 1) + +/* Set for blocks in an irreducible loop by loop analysis. */ +DEF_BASIC_BLOCK_FLAG(IRREDUCIBLE_LOOP, 2) + +/* Set on blocks that may actually not be single-entry single-exit block. */ +DEF_BASIC_BLOCK_FLAG(SUPERBLOCK, 3) + +/* Set on basic blocks that the scheduler should not touch. This is used + by SMS to prevent other schedulers from messing with the loop schedule. */ +DEF_BASIC_BLOCK_FLAG(DISABLE_SCHEDULE, 4) + +/* Set on blocks that should be put in a hot section. */ +DEF_BASIC_BLOCK_FLAG(HOT_PARTITION, 5) + +/* Set on blocks that should be put in a cold section. */ +DEF_BASIC_BLOCK_FLAG(COLD_PARTITION, 6) + +/* Set on block that was duplicated. */ +DEF_BASIC_BLOCK_FLAG(DUPLICATED, 7) + +/* Set if the label at the top of this block is the target of a non-local goto. */ +DEF_BASIC_BLOCK_FLAG(NON_LOCAL_GOTO_TARGET, 8) + +/* Set on blocks that are in RTL format. */ +DEF_BASIC_BLOCK_FLAG(RTL, 9) + +/* Set on blocks that are forwarder blocks. + Only used in cfgcleanup.c. */ +DEF_BASIC_BLOCK_FLAG(FORWARDER_BLOCK, 10) + +/* Set on blocks that cannot be threaded through. + Only used in cfgcleanup.c. */ +DEF_BASIC_BLOCK_FLAG(NONTHREADABLE_BLOCK, 11) + +/* Set on blocks that were modified in some way. This bit is set in + df_set_bb_dirty, but not cleared by df_analyze, so it can be used + to test whether a block has been modified prior to a df_analyze call. */ +DEF_BASIC_BLOCK_FLAG(MODIFIED, 12) + +/* A general visited flag for passes to use. */ +DEF_BASIC_BLOCK_FLAG(VISITED, 13) + +/* Set on blocks that are in a transaction. This is calculated on + demand, and is available after calling compute_transaction_bits(). */ +DEF_BASIC_BLOCK_FLAG(IN_TRANSACTION, 14) + +#endif + +#ifdef DEF_EDGE_FLAG + +/* Masks for edge.flags. + + The format of this file is: DEF_EDGE_FLAG(NAME, IDX, STRING). + NAME is the name of the edge flag. A flag EDGE_#NAME will be + created and the name is used in dump_edge_info. + IDX is a sequence number that is used to determine the value + of the flag, which is 1 << IDX). */ + +/* 'Straight line' flow. In GIMPLE and in cfglayout mode, all normal + edges are fallthru edges. In cfgrtl mode, this flag really means + that control flow falls through to the next basic block in the line. */ +DEF_EDGE_FLAG(FALLTHRU, 0) + +/* Strange flow, like a computed jump or exception handling. Usually + this means that the edge cannot be split. */ +DEF_EDGE_FLAG(ABNORMAL, 1) + +/* Edge out of a basic block that ends with a CALL_INSN with abnormal + exit, like an exception or a non-local goto. + ABNORMAL_CALL edges also have ABNORMAL set. + This flag is only used for the RTL CFG. */ +DEF_EDGE_FLAG(ABNORMAL_CALL, 2) + +/* Exception edge. Exception handling edges represent possible control + transfers from a trapping instruction to an exception handler. + EH edges also have ABNORMAL set for the RTL CFG. */ +DEF_EDGE_FLAG(EH, 3) + +/* Never merge blocks via this edge. This is used for exception handling, + to prevent merging away edges to the post-landing-pad basic block. + This flag is only used for the RTL CFG. */ +DEF_EDGE_FLAG(PRESERVE, 4) + +/* Not a real edge. This is used to connect parts of the CFG that do + not halt, such as infinite loops and noreturn functions, to the + EXIT_BLOCK, so that traversing of the reverse CFG is possible. */ +DEF_EDGE_FLAG(FAKE, 5) + +/* A back edge, marked in a depth-first search of the CFG. Back edges + are hints that this edge may be part of a loop in the CFG. */ +DEF_EDGE_FLAG(DFS_BACK, 6) + +/* Edge in a part of the CFG that is an irreducible loop. */ +DEF_EDGE_FLAG(IRREDUCIBLE_LOOP, 7) + +/* Edge taken when controlling predicate is nonzero. + This is only used for the GIMPLE CFG. */ +DEF_EDGE_FLAG(TRUE_VALUE, 8) + +/* Edge taken when controlling predicate is zero. + This is only used for the GIMPLE CFG. */ +DEF_EDGE_FLAG(FALSE_VALUE, 9) + +/* Edge is executable. This is only used in GIMPLE SSA-CCP and VRP. + This is only used for the GIMPLE CFG. */ +DEF_EDGE_FLAG(EXECUTABLE, 10) + +/* Edge crosses between hot and cold sections, when we do partitioning. + This flag is only used for the RTL CFG. */ +DEF_EDGE_FLAG(CROSSING, 11) + +/* Edge from a sibcall CALL_INSN to exit. + SIBCALL edges also have ABNORMAL set. + This flag is only used for the RTL CFG. */ +DEF_EDGE_FLAG(SIBCALL, 12) + +/* Candidate for straight line flow. Only used in bb-reorder.c. + This flag is only used for the RTL CFG. */ +DEF_EDGE_FLAG(CAN_FALLTHRU, 13) + +/* Exit of a loop. This is only used in ifcvt.c. + This flag is only used for the RTL CFG. */ +DEF_EDGE_FLAG(LOOP_EXIT, 14) + +/* Uninstrumented edge out of a GIMPLE_TRANSACTION statement. */ +DEF_EDGE_FLAG(TM_UNINSTRUMENTED, 15) + +/* Abort (over) edge out of a GIMPLE_TRANSACTION statement. */ +DEF_EDGE_FLAG(TM_ABORT, 16) + +#endif + +/* +Local variables: +mode:c +End: +*/ diff --git a/src/include/cfghooks.h b/src/include/cfghooks.h new file mode 100644 index 0000000..bff0a0c --- /dev/null +++ b/src/include/cfghooks.h @@ -0,0 +1,223 @@ +/* Hooks for cfg representation specific functions. + Copyright (C) 2003-2013 Free Software Foundation, Inc. + Contributed by Sebastian Pop + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* Only basic-block.h includes this. */ + +struct cfg_hooks +{ + /* Name of the corresponding ir. */ + const char *name; + + /* Debugging. */ + int (*verify_flow_info) (void); + void (*dump_bb) (FILE *, basic_block, int, int); + void (*dump_bb_for_graph) (pretty_printer *, basic_block); + + /* Basic CFG manipulation. */ + + /* Return new basic block. */ + basic_block (*create_basic_block) (void *head, void *end, basic_block after); + + /* Redirect edge E to the given basic block B and update underlying program + representation. Returns edge representing redirected branch (that may not + be equivalent to E in the case of duplicate edges being removed) or NULL + if edge is not easily redirectable for whatever reason. */ + edge (*redirect_edge_and_branch) (edge e, basic_block b); + + /* Same as the above but allows redirecting of fallthru edges. In that case + newly created forwarder basic block is returned. The edge must + not be abnormal. */ + basic_block (*redirect_edge_and_branch_force) (edge, basic_block); + + /* Returns true if it is possible to remove the edge by redirecting it + to the destination of the other edge going from its source. */ + bool (*can_remove_branch_p) (const_edge); + + /* Remove statements corresponding to a given basic block. */ + void (*delete_basic_block) (basic_block); + + /* Creates a new basic block just after basic block B by splitting + everything after specified instruction I. */ + basic_block (*split_block) (basic_block b, void * i); + + /* Move block B immediately after block A. */ + bool (*move_block_after) (basic_block b, basic_block a); + + /* Return true when blocks A and B can be merged into single basic block. */ + bool (*can_merge_blocks_p) (basic_block a, basic_block b); + + /* Merge blocks A and B. */ + void (*merge_blocks) (basic_block a, basic_block b); + + /* Predict edge E using PREDICTOR to given PROBABILITY. */ + void (*predict_edge) (edge e, enum br_predictor predictor, int probability); + + /* Return true if the one of outgoing edges is already predicted by + PREDICTOR. */ + bool (*predicted_by_p) (const_basic_block bb, enum br_predictor predictor); + + /* Return true when block A can be duplicated. */ + bool (*can_duplicate_block_p) (const_basic_block a); + + /* Duplicate block A. */ + basic_block (*duplicate_block) (basic_block a); + + /* Higher level functions representable by primitive operations above if + we didn't have some oddities in RTL and Tree representations. */ + basic_block (*split_edge) (edge); + void (*make_forwarder_block) (edge); + + /* Try to make the edge fallthru. */ + void (*tidy_fallthru_edge) (edge); + + /* Make the edge non-fallthru. */ + basic_block (*force_nonfallthru) (edge); + + /* Say whether a block ends with a call, possibly followed by some + other code that must stay with the call. */ + bool (*block_ends_with_call_p) (basic_block); + + /* Say whether a block ends with a conditional branch. Switches + and unconditional branches do not qualify. */ + bool (*block_ends_with_condjump_p) (const_basic_block); + + /* Add fake edges to the function exit for any non constant and non noreturn + calls, volatile inline assembly in the bitmap of blocks specified by + BLOCKS or to the whole CFG if BLOCKS is zero. Return the number of blocks + that were split. + + The goal is to expose cases in which entering a basic block does not imply + that all subsequent instructions must be executed. */ + int (*flow_call_edges_add) (sbitmap); + + /* This function is called immediately after edge E is added to the + edge vector E->dest->preds. */ + void (*execute_on_growing_pred) (edge); + + /* This function is called immediately before edge E is removed from + the edge vector E->dest->preds. */ + void (*execute_on_shrinking_pred) (edge); + + /* A hook for duplicating loop in CFG, currently this is used + in loop versioning. */ + bool (*cfg_hook_duplicate_loop_to_header_edge) (struct loop *, edge, + unsigned, sbitmap, + edge, vec *, + int); + + /* Add condition to new basic block and update CFG used in loop + versioning. */ + void (*lv_add_condition_to_bb) (basic_block, basic_block, basic_block, + void *); + /* Update the PHI nodes in case of loop versioning. */ + void (*lv_adjust_loop_header_phi) (basic_block, basic_block, + basic_block, edge); + + /* Given a condition BB extract the true/false taken/not taken edges + (depending if we are on tree's or RTL). */ + void (*extract_cond_bb_edges) (basic_block, edge *, edge *); + + + /* Add PHI arguments queued in PENDINT_STMT list on edge E to edge + E->dest (only in tree-ssa loop versioning. */ + void (*flush_pending_stmts) (edge); + + /* True if a block contains no executable instructions. */ + bool (*empty_block_p) (basic_block); + + /* Split a basic block if it ends with a conditional branch and if + the other part of the block is not empty. */ + basic_block (*split_block_before_cond_jump) (basic_block); + + /* Do book-keeping of a basic block for the profile consistency checker. */ + void (*account_profile_record) (basic_block, int, struct profile_record *); +}; + +extern void verify_flow_info (void); +extern void dump_bb (FILE *, basic_block, int, int); +extern void dump_bb_for_graph (pretty_printer *, basic_block); + +extern edge redirect_edge_and_branch (edge, basic_block); +extern basic_block redirect_edge_and_branch_force (edge, basic_block); +extern bool can_remove_branch_p (const_edge); +extern void remove_branch (edge); +extern void remove_edge (edge); +extern edge split_block (basic_block, void *); +extern edge split_block_after_labels (basic_block); +extern bool move_block_after (basic_block, basic_block); +extern void delete_basic_block (basic_block); +extern basic_block split_edge (edge); +extern basic_block create_basic_block (void *, void *, basic_block); +extern basic_block create_empty_bb (basic_block); +extern bool can_merge_blocks_p (basic_block, basic_block); +extern void merge_blocks (basic_block, basic_block); +extern edge make_forwarder_block (basic_block, bool (*)(edge), + void (*) (basic_block)); +extern basic_block force_nonfallthru (edge); +extern void tidy_fallthru_edge (edge); +extern void tidy_fallthru_edges (void); +extern void predict_edge (edge e, enum br_predictor predictor, int probability); +extern bool predicted_by_p (const_basic_block bb, enum br_predictor predictor); +extern bool can_duplicate_block_p (const_basic_block); +extern basic_block duplicate_block (basic_block, edge, basic_block); +extern bool block_ends_with_call_p (basic_block bb); +extern bool empty_block_p (basic_block); +extern basic_block split_block_before_cond_jump (basic_block); +extern bool block_ends_with_condjump_p (const_basic_block bb); +extern int flow_call_edges_add (sbitmap); +extern void execute_on_growing_pred (edge); +extern void execute_on_shrinking_pred (edge); +extern bool cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge, + unsigned int ndupl, + sbitmap wont_exit, + edge orig, + vec *to_remove, + int flags); + +extern void lv_flush_pending_stmts (edge); +extern void extract_cond_bb_edges (basic_block, edge *, edge*); +extern void lv_adjust_loop_header_phi (basic_block, basic_block, basic_block, + edge); +extern void lv_add_condition_to_bb (basic_block, basic_block, basic_block, + void *); + +extern bool can_copy_bbs_p (basic_block *, unsigned); +extern void copy_bbs (basic_block *, unsigned, basic_block *, + edge *, unsigned, edge *, struct loop *, + basic_block); + +void account_profile_record (struct profile_record *, int); + +extern void cfg_layout_initialize (unsigned int); +extern void cfg_layout_finalize (void); + +/* Hooks containers. */ +extern struct cfg_hooks gimple_cfg_hooks; +extern struct cfg_hooks rtl_cfg_hooks; +extern struct cfg_hooks cfg_layout_rtl_cfg_hooks; + +/* Declarations. */ +extern enum ir_type current_ir_type (void); +extern void rtl_register_cfg_hooks (void); +extern void cfg_layout_rtl_register_cfg_hooks (void); +extern void gimple_register_cfg_hooks (void); +extern struct cfg_hooks get_cfg_hooks (void); +extern void set_cfg_hooks (struct cfg_hooks); + diff --git a/src/include/cfgloop.h b/src/include/cfgloop.h new file mode 100644 index 0000000..01cef51 --- /dev/null +++ b/src/include/cfgloop.h @@ -0,0 +1,733 @@ +/* Natural loop functions + Copyright (C) 1987-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_CFGLOOP_H +#define GCC_CFGLOOP_H + +#include "basic-block.h" +#include "double-int.h" + +#include "bitmap.h" +#include "sbitmap.h" + +/* Structure to hold decision about unrolling/peeling. */ +enum lpt_dec +{ + LPT_NONE, + LPT_PEEL_COMPLETELY, + LPT_PEEL_SIMPLE, + LPT_UNROLL_CONSTANT, + LPT_UNROLL_RUNTIME, + LPT_UNROLL_STUPID +}; + +struct GTY (()) lpt_decision { + enum lpt_dec decision; + unsigned times; +}; + +/* The type of extend applied to an IV. */ +enum iv_extend_code +{ + IV_SIGN_EXTEND, + IV_ZERO_EXTEND, + IV_UNKNOWN_EXTEND +}; + +/* The structure describing a bound on number of iterations of a loop. */ + +struct GTY ((chain_next ("%h.next"))) nb_iter_bound { + /* The statement STMT is executed at most ... */ + gimple stmt; + + /* ... BOUND + 1 times (BOUND must be an unsigned constant). + The + 1 is added for the following reasons: + + a) 0 would otherwise be unused, while we would need to care more about + overflows (as MAX + 1 is sometimes produced as the estimate on number + of executions of STMT). + b) it is consistent with the result of number_of_iterations_exit. */ + double_int bound; + + /* True if the statement will cause the loop to be leaved the (at most) + BOUND + 1-st time it is executed, that is, all the statements after it + are executed at most BOUND times. */ + bool is_exit; + + /* The next bound in the list. */ + struct nb_iter_bound *next; +}; + +/* Description of the loop exit. */ + +struct GTY (()) loop_exit { + /* The exit edge. */ + edge e; + + /* Previous and next exit in the list of the exits of the loop. */ + struct loop_exit *prev; + struct loop_exit *next; + + /* Next element in the list of loops from that E exits. */ + struct loop_exit *next_e; +}; + +typedef struct loop *loop_p; + +/* An integer estimation of the number of iterations. Estimate_state + describes what is the state of the estimation. */ +enum loop_estimation +{ + /* Estimate was not computed yet. */ + EST_NOT_COMPUTED, + /* Estimate is ready. */ + EST_AVAILABLE +}; + +/* Structure to hold information for each natural loop. */ +struct GTY ((chain_next ("%h.next"))) loop { + /* Index into loops array. */ + int num; + + /* Number of loop insns. */ + unsigned ninsns; + + /* Basic block of loop header. */ + basic_block header; + + /* Basic block of loop latch. */ + basic_block latch; + + /* For loop unrolling/peeling decision. */ + struct lpt_decision lpt_decision; + + /* Average number of executed insns per iteration. */ + unsigned av_ninsns; + + /* Number of blocks contained within the loop. */ + unsigned num_nodes; + + /* Superloops of the loop, starting with the outermost loop. */ + vec *superloops; + + /* The first inner (child) loop or NULL if innermost loop. */ + struct loop *inner; + + /* Link to the next (sibling) loop. */ + struct loop *next; + + /* Auxiliary info specific to a pass. */ + PTR GTY ((skip (""))) aux; + + /* The number of times the latch of the loop is executed. This can be an + INTEGER_CST, or a symbolic expression representing the number of + iterations like "N - 1", or a COND_EXPR containing the runtime + conditions under which the number of iterations is non zero. + + Don't access this field directly: number_of_latch_executions + computes and caches the computed information in this field. */ + tree nb_iterations; + + /* An integer guaranteed to be greater or equal to nb_iterations. Only + valid if any_upper_bound is true. */ + double_int nb_iterations_upper_bound; + + /* An integer giving an estimate on nb_iterations. Unlike + nb_iterations_upper_bound, there is no guarantee that it is at least + nb_iterations. */ + double_int nb_iterations_estimate; + + bool any_upper_bound; + bool any_estimate; + + /* True if the loop can be parallel. */ + bool can_be_parallel; + + /* True if -Waggressive-loop-optimizations warned about this loop + already. */ + bool warned_aggressive_loop_optimizations; + + /* An integer estimation of the number of iterations. Estimate_state + describes what is the state of the estimation. */ + enum loop_estimation estimate_state; + + /* Upper bound on number of iterations of a loop. */ + struct nb_iter_bound *bounds; + + /* Head of the cyclic list of the exits of the loop. */ + struct loop_exit *exits; +}; + +/* Flags for state of loop structure. */ +enum +{ + LOOPS_HAVE_PREHEADERS = 1, + LOOPS_HAVE_SIMPLE_LATCHES = 2, + LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS = 4, + LOOPS_HAVE_RECORDED_EXITS = 8, + LOOPS_MAY_HAVE_MULTIPLE_LATCHES = 16, + LOOP_CLOSED_SSA = 32, + LOOPS_NEED_FIXUP = 64, + LOOPS_HAVE_FALLTHRU_PREHEADERS = 128 +}; + +#define LOOPS_NORMAL (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES \ + | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS) +#define AVOID_CFG_MODIFICATIONS (LOOPS_MAY_HAVE_MULTIPLE_LATCHES) + +/* Structure to hold CFG information about natural loops within a function. */ +struct GTY (()) loops { + /* State of loops. */ + int state; + + /* Array of the loops. */ + vec *larray; + + /* Maps edges to the list of their descriptions as loop exits. Edges + whose sources or destinations have loop_father == NULL (which may + happen during the cfg manipulations) should not appear in EXITS. */ + htab_t GTY((param_is (struct loop_exit))) exits; + + /* Pointer to root of loop hierarchy tree. */ + struct loop *tree_root; +}; + +/* Loop recognition. */ +bool bb_loop_header_p (basic_block); +extern struct loops *flow_loops_find (struct loops *); +extern void disambiguate_loops_with_multiple_latches (void); +extern void flow_loops_free (struct loops *); +extern void flow_loops_dump (FILE *, + void (*)(const struct loop *, FILE *, int), int); +extern void flow_loop_dump (const struct loop *, FILE *, + void (*)(const struct loop *, FILE *, int), int); +struct loop *alloc_loop (void); +extern void flow_loop_free (struct loop *); +int flow_loop_nodes_find (basic_block, struct loop *); +unsigned fix_loop_structure (bitmap changed_bbs); +bool mark_irreducible_loops (void); +void release_recorded_exits (void); +void record_loop_exits (void); +void rescan_loop_exit (edge, bool, bool); + +/* Loop data structure manipulation/querying. */ +extern void flow_loop_tree_node_add (struct loop *, struct loop *); +extern void flow_loop_tree_node_remove (struct loop *); +extern void add_loop (struct loop *, struct loop *); +extern bool flow_loop_nested_p (const struct loop *, const struct loop *); +extern bool flow_bb_inside_loop_p (const struct loop *, const_basic_block); +extern struct loop * find_common_loop (struct loop *, struct loop *); +struct loop *superloop_at_depth (struct loop *, unsigned); +struct eni_weights_d; +extern unsigned tree_num_loop_insns (struct loop *, struct eni_weights_d *); +extern int num_loop_insns (const struct loop *); +extern int average_num_loop_insns (const struct loop *); +extern unsigned get_loop_level (const struct loop *); +extern bool loop_exit_edge_p (const struct loop *, const_edge); +extern bool loop_exits_to_bb_p (struct loop *, basic_block); +extern bool loop_exits_from_bb_p (struct loop *, basic_block); +extern void mark_loop_exit_edges (void); +extern location_t get_loop_location (struct loop *loop); + +/* Loops & cfg manipulation. */ +extern basic_block *get_loop_body (const struct loop *); +extern unsigned get_loop_body_with_size (const struct loop *, basic_block *, + unsigned); +extern basic_block *get_loop_body_in_dom_order (const struct loop *); +extern basic_block *get_loop_body_in_bfs_order (const struct loop *); +extern basic_block *get_loop_body_in_custom_order (const struct loop *, + int (*) (const void *, const void *)); + +extern vec get_loop_exit_edges (const struct loop *); +extern edge single_exit (const struct loop *); +extern edge single_likely_exit (struct loop *loop); +extern unsigned num_loop_branches (const struct loop *); + +extern edge loop_preheader_edge (const struct loop *); +extern edge loop_latch_edge (const struct loop *); + +extern void add_bb_to_loop (basic_block, struct loop *); +extern void remove_bb_from_loops (basic_block); + +extern void cancel_loop_tree (struct loop *); +extern void delete_loop (struct loop *); + +enum +{ + CP_SIMPLE_PREHEADERS = 1, + CP_FALLTHRU_PREHEADERS = 2 +}; + +basic_block create_preheader (struct loop *, int); +extern void create_preheaders (int); +extern void force_single_succ_latches (void); + +extern void verify_loop_structure (void); + +/* Loop analysis. */ +extern bool just_once_each_iteration_p (const struct loop *, const_basic_block); +gcov_type expected_loop_iterations_unbounded (const struct loop *); +extern unsigned expected_loop_iterations (const struct loop *); +extern rtx doloop_condition_get (rtx); + +void estimate_numbers_of_iterations_loop (struct loop *); +void record_niter_bound (struct loop *, double_int, bool, bool); +bool estimated_loop_iterations (struct loop *, double_int *); +bool max_loop_iterations (struct loop *, double_int *); +HOST_WIDE_INT estimated_loop_iterations_int (struct loop *); +HOST_WIDE_INT max_loop_iterations_int (struct loop *); +bool max_stmt_executions (struct loop *, double_int *); +bool estimated_stmt_executions (struct loop *, double_int *); +HOST_WIDE_INT max_stmt_executions_int (struct loop *); +HOST_WIDE_INT estimated_stmt_executions_int (struct loop *); + +/* Loop manipulation. */ +extern bool can_duplicate_loop_p (const struct loop *loop); + +#define DLTHE_FLAG_UPDATE_FREQ 1 /* Update frequencies in + duplicate_loop_to_header_edge. */ +#define DLTHE_RECORD_COPY_NUMBER 2 /* Record copy number in the aux + field of newly create BB. */ +#define DLTHE_FLAG_COMPLETTE_PEEL 4 /* Update frequencies expecting + a complete peeling. */ + +extern edge create_empty_if_region_on_edge (edge, tree); +extern struct loop *create_empty_loop_on_edge (edge, tree, tree, tree, tree, + tree *, tree *, struct loop *); +extern struct loop * duplicate_loop (struct loop *, struct loop *); +extern void copy_loop_info (struct loop *loop, struct loop *target); +extern void duplicate_subloops (struct loop *, struct loop *); +extern bool duplicate_loop_to_header_edge (struct loop *, edge, + unsigned, sbitmap, edge, + vec *, int); +extern struct loop *loopify (edge, edge, + basic_block, edge, edge, bool, + unsigned, unsigned); +struct loop * loop_version (struct loop *, void *, + basic_block *, unsigned, unsigned, unsigned, bool); +extern bool remove_path (edge); +extern void unloop (struct loop *, bool *, bitmap); +extern void scale_loop_frequencies (struct loop *, int, int); + +/* Induction variable analysis. */ + +/* The description of induction variable. The things are a bit complicated + due to need to handle subregs and extends. The value of the object described + by it can be obtained as follows (all computations are done in extend_mode): + + Value in i-th iteration is + delta + mult * extend_{extend_mode} (subreg_{mode} (base + i * step)). + + If first_special is true, the value in the first iteration is + delta + mult * base + + If extend = UNKNOWN, first_special must be false, delta 0, mult 1 and value is + subreg_{mode} (base + i * step) + + The get_iv_value function can be used to obtain these expressions. + + ??? Add a third mode field that would specify the mode in that inner + computation is done, which would enable it to be different from the + outer one? */ + +struct rtx_iv +{ + /* Its base and step (mode of base and step is supposed to be extend_mode, + see the description above). */ + rtx base, step; + + /* The type of extend applied to it (IV_SIGN_EXTEND, IV_ZERO_EXTEND, + or IV_UNKNOWN_EXTEND). */ + enum iv_extend_code extend; + + /* Operations applied in the extended mode. */ + rtx delta, mult; + + /* The mode it is extended to. */ + enum machine_mode extend_mode; + + /* The mode the variable iterates in. */ + enum machine_mode mode; + + /* Whether the first iteration needs to be handled specially. */ + unsigned first_special : 1; +}; + +/* The description of an exit from the loop and of the number of iterations + till we take the exit. */ + +struct niter_desc +{ + /* The edge out of the loop. */ + edge out_edge; + + /* The other edge leading from the condition. */ + edge in_edge; + + /* True if we are able to say anything about number of iterations of the + loop. */ + bool simple_p; + + /* True if the loop iterates the constant number of times. */ + bool const_iter; + + /* Number of iterations if constant. */ + unsigned HOST_WIDEST_INT niter; + + /* Assumptions under that the rest of the information is valid. */ + rtx assumptions; + + /* Assumptions under that the loop ends before reaching the latch, + even if value of niter_expr says otherwise. */ + rtx noloop_assumptions; + + /* Condition under that the loop is infinite. */ + rtx infinite; + + /* Whether the comparison is signed. */ + bool signed_p; + + /* The mode in that niter_expr should be computed. */ + enum machine_mode mode; + + /* The number of iterations of the loop. */ + rtx niter_expr; +}; + +extern void iv_analysis_loop_init (struct loop *); +extern bool iv_analyze (rtx, rtx, struct rtx_iv *); +extern bool iv_analyze_result (rtx, rtx, struct rtx_iv *); +extern bool iv_analyze_expr (rtx, rtx, enum machine_mode, struct rtx_iv *); +extern rtx get_iv_value (struct rtx_iv *, rtx); +extern bool biv_p (rtx, rtx); +extern void find_simple_exit (struct loop *, struct niter_desc *); +extern void iv_analysis_done (void); + +extern struct niter_desc *get_simple_loop_desc (struct loop *loop); +extern void free_simple_loop_desc (struct loop *loop); + +static inline struct niter_desc * +simple_loop_desc (struct loop *loop) +{ + return (struct niter_desc *) loop->aux; +} + +/* Accessors for the loop structures. */ + +/* Returns the loop with index NUM from current_loops. */ + +static inline struct loop * +get_loop (unsigned num) +{ + return (*current_loops->larray)[num]; +} + +/* Returns the number of superloops of LOOP. */ + +static inline unsigned +loop_depth (const struct loop *loop) +{ + return vec_safe_length (loop->superloops); +} + +/* Returns the loop depth of the loop BB belongs to. */ + +static inline int +bb_loop_depth (const_basic_block bb) +{ + return bb->loop_father ? loop_depth (bb->loop_father) : 0; +} + +/* Returns the immediate superloop of LOOP, or NULL if LOOP is the outermost + loop. */ + +static inline struct loop * +loop_outer (const struct loop *loop) +{ + unsigned n = vec_safe_length (loop->superloops); + + if (n == 0) + return NULL; + + return (*loop->superloops)[n - 1]; +} + +/* Returns true if LOOP has at least one exit edge. */ + +static inline bool +loop_has_exit_edges (const struct loop *loop) +{ + return loop->exits->next->e != NULL; +} + +/* Returns the list of loops in current_loops. */ + +static inline vec * +get_loops (void) +{ + if (!current_loops) + return NULL; + + return current_loops->larray; +} + +/* Returns the number of loops in current_loops (including the removed + ones and the fake loop that forms the root of the loop tree). */ + +static inline unsigned +number_of_loops (void) +{ + if (!current_loops) + return 0; + + return vec_safe_length (current_loops->larray); +} + +/* Returns true if state of the loops satisfies all properties + described by FLAGS. */ + +static inline bool +loops_state_satisfies_p (unsigned flags) +{ + return (current_loops->state & flags) == flags; +} + +/* Sets FLAGS to the loops state. */ + +static inline void +loops_state_set (unsigned flags) +{ + current_loops->state |= flags; +} + +/* Clears FLAGS from the loops state. */ + +static inline void +loops_state_clear (unsigned flags) +{ + if (!current_loops) + return; + current_loops->state &= ~flags; +} + +/* Loop iterators. */ + +/* Flags for loop iteration. */ + +enum li_flags +{ + LI_INCLUDE_ROOT = 1, /* Include the fake root of the loop tree. */ + LI_FROM_INNERMOST = 2, /* Iterate over the loops in the reverse order, + starting from innermost ones. */ + LI_ONLY_INNERMOST = 4 /* Iterate only over innermost loops. */ +}; + +/* The iterator for loops. */ + +typedef struct +{ + /* The list of loops to visit. */ + vec to_visit; + + /* The index of the actual loop. */ + unsigned idx; +} loop_iterator; + +static inline void +fel_next (loop_iterator *li, loop_p *loop) +{ + int anum; + + while (li->to_visit.iterate (li->idx, &anum)) + { + li->idx++; + *loop = get_loop (anum); + if (*loop) + return; + } + + li->to_visit.release (); + *loop = NULL; +} + +static inline void +fel_init (loop_iterator *li, loop_p *loop, unsigned flags) +{ + struct loop *aloop; + unsigned i; + int mn; + + li->idx = 0; + if (!current_loops) + { + li->to_visit.create (0); + *loop = NULL; + return; + } + + li->to_visit.create (number_of_loops ()); + mn = (flags & LI_INCLUDE_ROOT) ? 0 : 1; + + if (flags & LI_ONLY_INNERMOST) + { + for (i = 0; vec_safe_iterate (current_loops->larray, i, &aloop); i++) + if (aloop != NULL + && aloop->inner == NULL + && aloop->num >= mn) + li->to_visit.quick_push (aloop->num); + } + else if (flags & LI_FROM_INNERMOST) + { + /* Push the loops to LI->TO_VISIT in postorder. */ + for (aloop = current_loops->tree_root; + aloop->inner != NULL; + aloop = aloop->inner) + continue; + + while (1) + { + if (aloop->num >= mn) + li->to_visit.quick_push (aloop->num); + + if (aloop->next) + { + for (aloop = aloop->next; + aloop->inner != NULL; + aloop = aloop->inner) + continue; + } + else if (!loop_outer (aloop)) + break; + else + aloop = loop_outer (aloop); + } + } + else + { + /* Push the loops to LI->TO_VISIT in preorder. */ + aloop = current_loops->tree_root; + while (1) + { + if (aloop->num >= mn) + li->to_visit.quick_push (aloop->num); + + if (aloop->inner != NULL) + aloop = aloop->inner; + else + { + while (aloop != NULL && aloop->next == NULL) + aloop = loop_outer (aloop); + if (aloop == NULL) + break; + aloop = aloop->next; + } + } + } + + fel_next (li, loop); +} + +#define FOR_EACH_LOOP(LI, LOOP, FLAGS) \ + for (fel_init (&(LI), &(LOOP), FLAGS); \ + (LOOP); \ + fel_next (&(LI), &(LOOP))) + +#define FOR_EACH_LOOP_BREAK(LI) \ + { \ + (LI).to_visit.release (); \ + break; \ + } + +/* The properties of the target. */ +struct target_cfgloop { + /* Number of available registers. */ + unsigned x_target_avail_regs; + + /* Number of available registers that are call-clobbered. */ + unsigned x_target_clobbered_regs; + + /* Number of registers reserved for temporary expressions. */ + unsigned x_target_res_regs; + + /* The cost for register when there still is some reserve, but we are + approaching the number of available registers. */ + unsigned x_target_reg_cost[2]; + + /* The cost for register when we need to spill. */ + unsigned x_target_spill_cost[2]; +}; + +extern struct target_cfgloop default_target_cfgloop; +#if SWITCHABLE_TARGET +extern struct target_cfgloop *this_target_cfgloop; +#else +#define this_target_cfgloop (&default_target_cfgloop) +#endif + +#define target_avail_regs \ + (this_target_cfgloop->x_target_avail_regs) +#define target_clobbered_regs \ + (this_target_cfgloop->x_target_clobbered_regs) +#define target_res_regs \ + (this_target_cfgloop->x_target_res_regs) +#define target_reg_cost \ + (this_target_cfgloop->x_target_reg_cost) +#define target_spill_cost \ + (this_target_cfgloop->x_target_spill_cost) + +/* Register pressure estimation for induction variable optimizations & loop + invariant motion. */ +extern unsigned estimate_reg_pressure_cost (unsigned, unsigned, bool, bool); +extern void init_set_costs (void); + +/* Loop optimizer initialization. */ +extern void loop_optimizer_init (unsigned); +extern void loop_optimizer_finalize (void); + +/* Optimization passes. */ +extern void unswitch_loops (void); + +enum +{ + UAP_PEEL = 1, /* Enables loop peeling. */ + UAP_UNROLL = 2, /* Enables unrolling of loops if it seems profitable. */ + UAP_UNROLL_ALL = 4 /* Enables unrolling of all loops. */ +}; + +extern void unroll_and_peel_loops (int); +extern void doloop_optimize_loops (void); +extern void move_loop_invariants (void); +extern bool finite_loop_p (struct loop *); +extern void scale_loop_profile (struct loop *loop, int scale, gcov_type iteration_bound); +extern vec get_loop_hot_path (const struct loop *loop); + +/* Returns the outermost loop of the loop nest that contains LOOP.*/ +static inline struct loop * +loop_outermost (struct loop *loop) +{ + unsigned n = vec_safe_length (loop->superloops); + + if (n <= 1) + return loop; + + return (*loop->superloops)[1]; +} + + +#endif /* GCC_CFGLOOP_H */ diff --git a/src/include/cgraph.h b/src/include/cgraph.h new file mode 100644 index 0000000..8ab7ae1 --- /dev/null +++ b/src/include/cgraph.h @@ -0,0 +1,1371 @@ +/* Callgraph handling code. + Copyright (C) 2003-2013 Free Software Foundation, Inc. + Contributed by Jan Hubicka + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_CGRAPH_H +#define GCC_CGRAPH_H + +#include "is-a.h" +#include "plugin-api.h" +#include "vec.h" +#include "tree.h" +#include "basic-block.h" +#include "function.h" +#include "ipa-ref.h" + +/* Symbol table consists of functions and variables. + TODO: add labels, constant pool and aliases. */ +enum symtab_type +{ + SYMTAB_SYMBOL, + SYMTAB_FUNCTION, + SYMTAB_VARIABLE +}; + +/* Base of all entries in the symbol table. + The symtab_node is inherited by cgraph and varpol nodes. */ +struct GTY(()) symtab_node_base +{ + /* Type of the symbol. */ + ENUM_BITFIELD (symtab_type) type : 8; + + /* The symbols resolution. */ + ENUM_BITFIELD (ld_plugin_symbol_resolution) resolution : 8; + + /* Set when function has address taken. + In current implementation it imply needed flag. */ + unsigned address_taken : 1; + /* Set when variable is used from other LTRANS partition. */ + unsigned used_from_other_partition : 1; + /* Set when function is available in the other LTRANS partition. + During WPA output it is used to mark nodes that are present in + multiple partitions. */ + unsigned in_other_partition : 1; + /* Set when function is visible by other units. */ + unsigned externally_visible : 1; + /* Needed variables might become dead by optimization. This flag + forces the variable to be output even if it appears dead otherwise. */ + unsigned force_output : 1; + + /* Ordering of all symtab entries. */ + int order; + + tree decl; + + /* Vectors of referring and referenced entities. */ + struct ipa_ref_list ref_list; + + /* Circular list of nodes in the same comdat group if non-NULL. */ + symtab_node same_comdat_group; + + /* File stream where this node is being written to. */ + struct lto_file_decl_data * lto_file_data; + + /* Linked list of symbol table entries starting with symtab_nodes. */ + symtab_node next; + symtab_node previous; + /* Linked list of symbols with the same asm name. There may be multiple + entries for single symbol name in the case of LTO resolutions, + existence of inline clones, or duplicated declaration. The last case + is a long standing bug frontends and builtin handling. */ + symtab_node next_sharing_asm_name; + symtab_node previous_sharing_asm_name; + + PTR GTY ((skip)) aux; +}; + +enum availability +{ + /* Not yet set by cgraph_function_body_availability. */ + AVAIL_UNSET, + /* Function body/variable initializer is unknown. */ + AVAIL_NOT_AVAILABLE, + /* Function body/variable initializer is known but might be replaced + by a different one from other compilation unit and thus needs to + be dealt with a care. Like AVAIL_NOT_AVAILABLE it can have + arbitrary side effects on escaping variables and functions, while + like AVAILABLE it might access static variables. */ + AVAIL_OVERWRITABLE, + /* Function body/variable initializer is known and will be used in final + program. */ + AVAIL_AVAILABLE, + /* Function body/variable initializer is known and all it's uses are explicitly + visible within current unit (ie it's address is never taken and it is not + exported to other units). + Currently used only for functions. */ + AVAIL_LOCAL +}; + +/* This is the information that is put into the cgraph local structure + to recover a function. */ +struct lto_file_decl_data; + +extern const char * const cgraph_availability_names[]; +extern const char * const ld_plugin_symbol_resolution_names[]; + +/* Information about thunk, used only for same body aliases. */ + +struct GTY(()) cgraph_thunk_info { + /* Information about the thunk. */ + HOST_WIDE_INT fixed_offset; + HOST_WIDE_INT virtual_value; + tree alias; + bool this_adjusting; + bool virtual_offset_p; + /* Set to true when alias node is thunk. */ + bool thunk_p; +}; + +/* Information about the function collected locally. + Available after function is analyzed. */ + +struct GTY(()) cgraph_local_info { + /* Set when function function is visible in current compilation unit only + and its address is never taken. */ + unsigned local : 1; + + /* Set once it has been finalized so we consider it to be output. */ + unsigned finalized : 1; + + /* False when there is something makes versioning impossible. */ + unsigned versionable : 1; + + /* False when function calling convention and signature can not be changed. + This is the case when __builtin_apply_args is used. */ + unsigned can_change_signature : 1; + + /* True when the function has been originally extern inline, but it is + redefined now. */ + unsigned redefined_extern_inline : 1; + + /* True if the function may enter serial irrevocable mode. */ + unsigned tm_may_enter_irr : 1; +}; + +/* Information about the function that needs to be computed globally + once compilation is finished. Available only with -funit-at-a-time. */ + +struct GTY(()) cgraph_global_info { + /* For inline clones this points to the function they will be + inlined into. */ + struct cgraph_node *inlined_to; +}; + +/* Information about the function that is propagated by the RTL backend. + Available only for functions that has been already assembled. */ + +struct GTY(()) cgraph_rtl_info { + unsigned int preferred_incoming_stack_boundary; +}; + +/* Represent which DECL tree (or reference to such tree) + will be replaced by another tree while versioning. */ +struct GTY(()) ipa_replace_map +{ + /* The tree that will be replaced. */ + tree old_tree; + /* The new (replacing) tree. */ + tree new_tree; + /* Parameter number to replace, when old_tree is NULL. */ + int parm_num; + /* True when a substitution should be done, false otherwise. */ + bool replace_p; + /* True when we replace a reference to old_tree. */ + bool ref_p; +}; +typedef struct ipa_replace_map *ipa_replace_map_p; + +struct GTY(()) cgraph_clone_info +{ + vec *tree_map; + bitmap args_to_skip; + bitmap combined_args_to_skip; +}; + + +/* The cgraph data structure. + Each function decl has assigned cgraph_node listing callees and callers. */ + +struct GTY(()) cgraph_node { + struct symtab_node_base symbol; + struct cgraph_edge *callees; + struct cgraph_edge *callers; + /* List of edges representing indirect calls with a yet undetermined + callee. */ + struct cgraph_edge *indirect_calls; + /* For nested functions points to function the node is nested in. */ + struct cgraph_node * + GTY ((nested_ptr (union symtab_node_def, "(struct cgraph_node *)(%h)", "(symtab_node)%h"))) + origin; + /* Points to first nested function, if any. */ + struct cgraph_node * + GTY ((nested_ptr (union symtab_node_def, "(struct cgraph_node *)(%h)", "(symtab_node)%h"))) + nested; + /* Pointer to the next function with same origin, if any. */ + struct cgraph_node * + GTY ((nested_ptr (union symtab_node_def, "(struct cgraph_node *)(%h)", "(symtab_node)%h"))) + next_nested; + /* Pointer to the next clone. */ + struct cgraph_node *next_sibling_clone; + struct cgraph_node *prev_sibling_clone; + struct cgraph_node *clones; + struct cgraph_node *clone_of; + /* For functions with many calls sites it holds map from call expression + to the edge to speed up cgraph_edge function. */ + htab_t GTY((param_is (struct cgraph_edge))) call_site_hash; + /* Declaration node used to be clone of. */ + tree former_clone_of; + + /* Interprocedural passes scheduled to have their transform functions + applied next time we execute local pass on them. We maintain it + per-function in order to allow IPA passes to introduce new functions. */ + vec GTY((skip)) ipa_transforms_to_apply; + + struct cgraph_local_info local; + struct cgraph_global_info global; + struct cgraph_rtl_info rtl; + struct cgraph_clone_info clone; + struct cgraph_thunk_info thunk; + + /* Expected number of executions: calculated in profile.c. */ + gcov_type count; + /* How to scale counts at materialization time; used to merge + LTO units with different number of profile runs. */ + int count_materialization_scale; + /* Unique id of the node. */ + int uid; + + /* Set when decl is an abstract function pointed to by the + ABSTRACT_DECL_ORIGIN of a reachable function. */ + unsigned abstract_and_needed : 1; + /* Set once the function is lowered (i.e. its CFG is built). */ + unsigned lowered : 1; + /* Set once the function has been instantiated and its callee + lists created. */ + unsigned analyzed : 1; + /* Set when function is scheduled to be processed by local passes. */ + unsigned process : 1; + /* Set for aliases once they got through assemble_alias. */ + unsigned alias : 1; + /* Set for aliases created as C++ same body aliases. */ + unsigned same_body_alias : 1; + /* How commonly executed the node is. Initialized during branch + probabilities pass. */ + ENUM_BITFIELD (node_frequency) frequency : 2; + /* True when function can only be called at startup (from static ctor). */ + unsigned only_called_at_startup : 1; + /* True when function can only be called at startup (from static dtor). */ + unsigned only_called_at_exit : 1; + /* True when function is the transactional clone of a function which + is called only from inside transactions. */ + /* ?? We should be able to remove this. We have enough bits in + cgraph to calculate it. */ + unsigned tm_clone : 1; + /* True if this decl is a dispatcher for function versions. */ + unsigned dispatcher_function : 1; +}; + + +typedef struct cgraph_node *cgraph_node_ptr; + + +/* Function Multiversioning info. */ +struct GTY(()) cgraph_function_version_info { + /* The cgraph_node for which the function version info is stored. */ + struct cgraph_node *this_node; + /* Chains all the semantically identical function versions. The + first function in this chain is the version_info node of the + default function. */ + struct cgraph_function_version_info *prev; + /* If this version node corresponds to a dispatcher for function + versions, this points to the version info node of the default + function, the first node in the chain. */ + struct cgraph_function_version_info *next; + /* If this node corresponds to a function version, this points + to the dispatcher function decl, which is the function that must + be called to execute the right function version at run-time. + + If this cgraph node is a dispatcher (if dispatcher_function is + true, in the cgraph_node struct) for function versions, this + points to resolver function, which holds the function body of the + dispatcher. The dispatcher decl is an alias to the resolver + function decl. */ + tree dispatcher_resolver; +}; + +/* Get the cgraph_function_version_info node corresponding to node. */ +struct cgraph_function_version_info * + get_cgraph_node_version (struct cgraph_node *node); + +/* Insert a new cgraph_function_version_info node into cgraph_fnver_htab + corresponding to cgraph_node NODE. */ +struct cgraph_function_version_info * + insert_new_cgraph_node_version (struct cgraph_node *node); + +/* Record that DECL1 and DECL2 are semantically identical function + versions. */ +void record_function_versions (tree decl1, tree decl2); + +/* Remove the cgraph_function_version_info and cgraph_node for DECL. This + DECL is a duplicate declaration. */ +void delete_function_version (tree decl); + +/* A cgraph node set is a collection of cgraph nodes. A cgraph node + can appear in multiple sets. */ +struct cgraph_node_set_def +{ + struct pointer_map_t *map; + vec nodes; +}; + +typedef struct varpool_node *varpool_node_ptr; + + +/* A varpool node set is a collection of varpool nodes. A varpool node + can appear in multiple sets. */ +struct varpool_node_set_def +{ + struct pointer_map_t * map; + vec nodes; +}; + +typedef struct cgraph_node_set_def *cgraph_node_set; + + +typedef struct varpool_node_set_def *varpool_node_set; + + +/* Iterator structure for cgraph node sets. */ +typedef struct +{ + cgraph_node_set set; + unsigned index; +} cgraph_node_set_iterator; + +/* Iterator structure for varpool node sets. */ +typedef struct +{ + varpool_node_set set; + unsigned index; +} varpool_node_set_iterator; + +#define DEFCIFCODE(code, string) CIF_ ## code, +/* Reasons for inlining failures. */ +typedef enum cgraph_inline_failed_enum { +#include "cif-code.def" + CIF_N_REASONS +} cgraph_inline_failed_t; + +/* Structure containing additional information about an indirect call. */ + +struct GTY(()) cgraph_indirect_call_info +{ + /* When polymorphic is set, this field contains offset where the object which + was actually used in the polymorphic resides within a larger structure. + If agg_contents is set, the field contains the offset within the aggregate + from which the address to call was loaded. */ + HOST_WIDE_INT offset; + /* OBJ_TYPE_REF_TOKEN of a polymorphic call (if polymorphic is set). */ + HOST_WIDE_INT otr_token; + /* Type of the object from OBJ_TYPE_REF_OBJECT. */ + tree otr_type; + /* Index of the parameter that is called. */ + int param_index; + /* ECF flags determined from the caller. */ + int ecf_flags; + + /* Set when the call is a virtual call with the parameter being the + associated object pointer rather than a simple direct call. */ + unsigned polymorphic : 1; + /* Set when the call is a call of a pointer loaded from contents of an + aggregate at offset. */ + unsigned agg_contents : 1; + /* When the previous bit is set, this one determines whether the destination + is loaded from a parameter passed by reference. */ + unsigned by_ref : 1; +}; + +struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgraph_edge { + /* Expected number of executions: calculated in profile.c. */ + gcov_type count; + struct cgraph_node *caller; + struct cgraph_node *callee; + struct cgraph_edge *prev_caller; + struct cgraph_edge *next_caller; + struct cgraph_edge *prev_callee; + struct cgraph_edge *next_callee; + gimple call_stmt; + /* Additional information about an indirect call. Not cleared when an edge + becomes direct. */ + struct cgraph_indirect_call_info *indirect_info; + PTR GTY ((skip (""))) aux; + /* When equal to CIF_OK, inline this call. Otherwise, points to the + explanation why function was not inlined. */ + cgraph_inline_failed_t inline_failed; + /* The stmt_uid of call_stmt. This is used by LTO to recover the call_stmt + when the function is serialized in. */ + unsigned int lto_stmt_uid; + /* Expected frequency of executions within the function. + When set to CGRAPH_FREQ_BASE, the edge is expected to be called once + per function call. The range is 0 to CGRAPH_FREQ_MAX. */ + int frequency; + /* Unique id of the edge. */ + int uid; + /* Whether this edge was made direct by indirect inlining. */ + unsigned int indirect_inlining_edge : 1; + /* Whether this edge describes an indirect call with an undetermined + callee. */ + unsigned int indirect_unknown_callee : 1; + /* Whether this edge is still a dangling */ + /* True if the corresponding CALL stmt cannot be inlined. */ + unsigned int call_stmt_cannot_inline_p : 1; + /* Can this call throw externally? */ + unsigned int can_throw_external : 1; +}; + +#define CGRAPH_FREQ_BASE 1000 +#define CGRAPH_FREQ_MAX 100000 + +typedef struct cgraph_edge *cgraph_edge_p; + + +/* The varpool data structure. + Each static variable decl has assigned varpool_node. */ + +struct GTY(()) varpool_node { + struct symtab_node_base symbol; + /* For aliases points to declaration DECL is alias of. */ + tree alias_of; + + /* Set once the variable has been instantiated and its callee + lists created. */ + unsigned analyzed : 1; + /* Set once it has been finalized so we consider it to be output. */ + unsigned finalized : 1; + /* Set when variable is scheduled to be assembled. */ + unsigned output : 1; + /* Set for aliases once they got through assemble_alias. Also set for + extra name aliases in varpool_extra_name_alias. */ + unsigned alias : 1; + unsigned extra_name_alias : 1; +}; + +/* Every top level asm statement is put into a asm_node. */ + +struct GTY(()) asm_node { + /* Next asm node. */ + struct asm_node *next; + /* String for this asm node. */ + tree asm_str; + /* Ordering of all cgraph nodes. */ + int order; +}; + +/* Symbol table entry. */ +union GTY((desc ("%h.symbol.type"), chain_next ("%h.symbol.next"), + chain_prev ("%h.symbol.previous"))) symtab_node_def { + struct symtab_node_base GTY ((tag ("SYMTAB_SYMBOL"))) symbol; + /* To access the following fields, + use the use dyn_cast or as_a to obtain the concrete type. */ + struct cgraph_node GTY ((tag ("SYMTAB_FUNCTION"))) x_function; + struct varpool_node GTY ((tag ("SYMTAB_VARIABLE"))) x_variable; +}; + +/* Report whether or not THIS symtab node is a function, aka cgraph_node. */ + +template <> +template <> +inline bool +is_a_helper ::test (symtab_node_def *p) +{ + return p->symbol.type == SYMTAB_FUNCTION; +} + +/* Report whether or not THIS symtab node is a vriable, aka varpool_node. */ + +template <> +template <> +inline bool +is_a_helper ::test (symtab_node_def *p) +{ + return p->symbol.type == SYMTAB_VARIABLE; +} + +extern GTY(()) symtab_node symtab_nodes; +extern GTY(()) int cgraph_n_nodes; +extern GTY(()) int cgraph_max_uid; +extern GTY(()) int cgraph_edge_max_uid; +extern bool cgraph_global_info_ready; +enum cgraph_state +{ + /* Frontend is parsing and finalizing functions. */ + CGRAPH_STATE_PARSING, + /* Callgraph is being constructed. It is safe to add new functions. */ + CGRAPH_STATE_CONSTRUCTION, + /* Callgraph is built and IPA passes are being run. */ + CGRAPH_STATE_IPA, + /* Callgraph is built and all functions are transformed to SSA form. */ + CGRAPH_STATE_IPA_SSA, + /* Functions are now ordered and being passed to RTL expanders. */ + CGRAPH_STATE_EXPANSION, + /* All cgraph expansion is done. */ + CGRAPH_STATE_FINISHED +}; +extern enum cgraph_state cgraph_state; +extern bool cgraph_function_flags_ready; +extern cgraph_node_set cgraph_new_nodes; + +extern GTY(()) struct asm_node *asm_nodes; +extern GTY(()) int symtab_order; +extern bool same_body_aliases_done; + +/* In symtab.c */ +void symtab_register_node (symtab_node); +void symtab_unregister_node (symtab_node); +void symtab_remove_node (symtab_node); +symtab_node symtab_get_node (const_tree); +symtab_node symtab_node_for_asm (const_tree asmname); +const char * symtab_node_asm_name (symtab_node); +const char * symtab_node_name (symtab_node); +void symtab_insert_node_to_hashtable (symtab_node); +void symtab_add_to_same_comdat_group (symtab_node, symtab_node); +void symtab_dissolve_same_comdat_group_list (symtab_node node); +void dump_symtab (FILE *); +void debug_symtab (void); +void dump_symtab_node (FILE *, symtab_node); +void debug_symtab_node (symtab_node); +void dump_symtab_base (FILE *, symtab_node); +void verify_symtab (void); +void verify_symtab_node (symtab_node); +bool verify_symtab_base (symtab_node); +bool symtab_used_from_object_file_p (symtab_node); +void symtab_make_decl_local (tree); + +/* In cgraph.c */ +void dump_cgraph (FILE *); +void debug_cgraph (void); +void dump_cgraph_node (FILE *, struct cgraph_node *); +void debug_cgraph_node (struct cgraph_node *); +void cgraph_remove_edge (struct cgraph_edge *); +void cgraph_remove_node (struct cgraph_node *); +void cgraph_release_function_body (struct cgraph_node *); +void cgraph_node_remove_callees (struct cgraph_node *node); +struct cgraph_edge *cgraph_create_edge (struct cgraph_node *, + struct cgraph_node *, + gimple, gcov_type, int); +struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple, + int, gcov_type, int); +struct cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void); +struct cgraph_node * cgraph_create_node (tree); +struct cgraph_node * cgraph_create_empty_node (void); +struct cgraph_node * cgraph_get_create_node (tree); +struct cgraph_node * cgraph_get_create_real_symbol_node (tree); +struct cgraph_node * cgraph_same_body_alias (struct cgraph_node *, tree, tree); +struct cgraph_node * cgraph_add_thunk (struct cgraph_node *, tree, tree, bool, HOST_WIDE_INT, + HOST_WIDE_INT, tree, tree); +struct cgraph_node *cgraph_node_for_asm (tree); +struct cgraph_edge *cgraph_edge (struct cgraph_node *, gimple); +void cgraph_set_call_stmt (struct cgraph_edge *, gimple); +void cgraph_update_edges_for_call_stmt (gimple, tree, gimple); +struct cgraph_local_info *cgraph_local_info (tree); +struct cgraph_global_info *cgraph_global_info (tree); +struct cgraph_rtl_info *cgraph_rtl_info (tree); +struct cgraph_node *cgraph_create_function_alias (tree, tree); +void cgraph_call_node_duplication_hooks (struct cgraph_node *, + struct cgraph_node *); +void cgraph_call_edge_duplication_hooks (struct cgraph_edge *, + struct cgraph_edge *); + +void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *); +void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *); +bool cgraph_only_called_directly_p (struct cgraph_node *); + +bool cgraph_function_possibly_inlined_p (tree); +void cgraph_unnest_node (struct cgraph_node *); + +enum availability cgraph_function_body_availability (struct cgraph_node *); +void cgraph_add_new_function (tree, bool); +const char* cgraph_inline_failed_string (cgraph_inline_failed_t); + +void cgraph_set_nothrow_flag (struct cgraph_node *, bool); +void cgraph_set_const_flag (struct cgraph_node *, bool, bool); +void cgraph_set_pure_flag (struct cgraph_node *, bool, bool); +bool cgraph_node_cannot_return (struct cgraph_node *); +bool cgraph_edge_cannot_lead_to_return (struct cgraph_edge *); +bool cgraph_will_be_removed_from_program_if_no_direct_calls + (struct cgraph_node *node); +bool cgraph_can_remove_if_no_direct_calls_and_refs_p + (struct cgraph_node *node); +bool cgraph_can_remove_if_no_direct_calls_p (struct cgraph_node *node); +bool resolution_used_from_other_file_p (enum ld_plugin_symbol_resolution); +bool cgraph_for_node_thunks_and_aliases (struct cgraph_node *, + bool (*) (struct cgraph_node *, void *), + void *, + bool); +bool cgraph_for_node_and_aliases (struct cgraph_node *, + bool (*) (struct cgraph_node *, void *), + void *, bool); +vec collect_callers_of_node (struct cgraph_node *node); +void verify_cgraph (void); +void verify_cgraph_node (struct cgraph_node *); +void cgraph_mark_address_taken_node (struct cgraph_node *); + +typedef void (*cgraph_edge_hook)(struct cgraph_edge *, void *); +typedef void (*cgraph_node_hook)(struct cgraph_node *, void *); +typedef void (*cgraph_2edge_hook)(struct cgraph_edge *, struct cgraph_edge *, + void *); +typedef void (*cgraph_2node_hook)(struct cgraph_node *, struct cgraph_node *, + void *); +struct cgraph_edge_hook_list; +struct cgraph_node_hook_list; +struct cgraph_2edge_hook_list; +struct cgraph_2node_hook_list; +struct cgraph_edge_hook_list *cgraph_add_edge_removal_hook (cgraph_edge_hook, void *); +void cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *); +struct cgraph_node_hook_list *cgraph_add_node_removal_hook (cgraph_node_hook, + void *); +void cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *); +struct cgraph_node_hook_list *cgraph_add_function_insertion_hook (cgraph_node_hook, + void *); +void cgraph_remove_function_insertion_hook (struct cgraph_node_hook_list *); +void cgraph_call_function_insertion_hooks (struct cgraph_node *node); +struct cgraph_2edge_hook_list *cgraph_add_edge_duplication_hook (cgraph_2edge_hook, void *); +void cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *); +struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_hook, void *); +void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *); +gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *); +bool cgraph_propagate_frequency (struct cgraph_node *node); + +/* In cgraphunit.c */ +struct asm_node *add_asm_node (tree); +extern FILE *cgraph_dump_file; +void cgraph_finalize_function (tree, bool); +void finalize_compilation_unit (void); +void compile (void); +void init_cgraph (void); +bool cgraph_process_new_functions (void); +void cgraph_process_same_body_aliases (void); +void fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias); +/* Initialize datastructures so DECL is a function in lowered gimple form. + IN_SSA is true if the gimple is in SSA. */ +basic_block init_lowered_empty_function (tree decl, bool in_ssa); + +/* In cgraphclones.c */ + +struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *, + struct cgraph_node *, gimple, + unsigned, gcov_type, int, bool); +struct cgraph_node * cgraph_clone_node (struct cgraph_node *, tree, gcov_type, + int, bool, vec, + bool); +tree clone_function_name (tree decl, const char *); +struct cgraph_node * cgraph_create_virtual_clone (struct cgraph_node *old_node, + vec, + vec *tree_map, + bitmap args_to_skip, + const char *clone_name); +struct cgraph_node *cgraph_find_replacement_node (struct cgraph_node *); +bool cgraph_remove_node_and_inline_clones (struct cgraph_node *, struct cgraph_node *); +void cgraph_set_call_stmt_including_clones (struct cgraph_node *, gimple, gimple); +void cgraph_create_edge_including_clones (struct cgraph_node *, + struct cgraph_node *, + gimple, gimple, gcov_type, int, + cgraph_inline_failed_t); +void cgraph_materialize_all_clones (void); +struct cgraph_node * cgraph_copy_node_for_versioning (struct cgraph_node *, + tree, vec, bitmap); +struct cgraph_node *cgraph_function_versioning (struct cgraph_node *, + vec, + vec *, + bitmap, bool, bitmap, + basic_block, const char *); +void tree_function_versioning (tree, tree, vec *, + bool, bitmap, bool, bitmap, basic_block); + +/* In cgraphbuild.c */ +unsigned int rebuild_cgraph_edges (void); +void cgraph_rebuild_references (void); +int compute_call_stmt_bb_frequency (tree, basic_block bb); +void record_references_in_initializer (tree, bool); + +/* In ipa.c */ +bool symtab_remove_unreachable_nodes (bool, FILE *); +cgraph_node_set cgraph_node_set_new (void); +cgraph_node_set_iterator cgraph_node_set_find (cgraph_node_set, + struct cgraph_node *); +void cgraph_node_set_add (cgraph_node_set, struct cgraph_node *); +void cgraph_node_set_remove (cgraph_node_set, struct cgraph_node *); +void dump_cgraph_node_set (FILE *, cgraph_node_set); +void debug_cgraph_node_set (cgraph_node_set); +void free_cgraph_node_set (cgraph_node_set); +void cgraph_build_static_cdtor (char which, tree body, int priority); + +varpool_node_set varpool_node_set_new (void); +varpool_node_set_iterator varpool_node_set_find (varpool_node_set, + struct varpool_node *); +void varpool_node_set_add (varpool_node_set, struct varpool_node *); +void varpool_node_set_remove (varpool_node_set, struct varpool_node *); +void dump_varpool_node_set (FILE *, varpool_node_set); +void debug_varpool_node_set (varpool_node_set); +void free_varpool_node_set (varpool_node_set); +void ipa_discover_readonly_nonaddressable_vars (void); +bool cgraph_comdat_can_be_unshared_p (struct cgraph_node *); +bool varpool_externally_visible_p (struct varpool_node *, bool); + +/* In predict.c */ +bool cgraph_maybe_hot_edge_p (struct cgraph_edge *e); +bool cgraph_optimize_for_size_p (struct cgraph_node *); + +/* In varpool.c */ +struct varpool_node *varpool_node_for_decl (tree); +struct varpool_node *varpool_node_for_asm (tree asmname); +void varpool_mark_needed_node (struct varpool_node *); +void debug_varpool (void); +void dump_varpool (FILE *); +void dump_varpool_node (FILE *, struct varpool_node *); + +void varpool_finalize_decl (tree); +bool decide_is_variable_needed (struct varpool_node *, tree); +enum availability cgraph_variable_initializer_availability (struct varpool_node *); +void cgraph_make_node_local (struct cgraph_node *); +bool cgraph_node_can_be_local_p (struct cgraph_node *); + + +void varpool_remove_node (struct varpool_node *node); +void varpool_finalize_named_section_flags (struct varpool_node *node); +bool varpool_output_variables (void); +bool varpool_assemble_decl (struct varpool_node *node); +void varpool_analyze_node (struct varpool_node *); +struct varpool_node * varpool_extra_name_alias (tree, tree); +struct varpool_node * varpool_create_variable_alias (tree, tree); +void varpool_reset_queue (void); +bool const_value_known_p (tree); +bool varpool_for_node_and_aliases (struct varpool_node *, + bool (*) (struct varpool_node *, void *), + void *, bool); +void varpool_add_new_variable (tree); +void symtab_initialize_asm_name_hash (void); +void symtab_prevail_in_asm_name_hash (symtab_node node); + + +/* Return callgraph node for given symbol and check it is a function. */ +static inline struct cgraph_node * +cgraph (symtab_node node) +{ + gcc_checking_assert (!node || node->symbol.type == SYMTAB_FUNCTION); + return (struct cgraph_node *)node; +} + +/* Return varpool node for given symbol and check it is a variable. */ +static inline struct varpool_node * +varpool (symtab_node node) +{ + gcc_checking_assert (!node || node->symbol.type == SYMTAB_VARIABLE); + return (struct varpool_node *)node; +} + +/* Return callgraph node for given symbol and check it is a function. */ +static inline struct cgraph_node * +cgraph_get_node (const_tree decl) +{ + gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL); + return cgraph (symtab_get_node (decl)); +} + +/* Return varpool node for given symbol and check it is a function. */ +static inline struct varpool_node * +varpool_get_node (const_tree decl) +{ + gcc_checking_assert (TREE_CODE (decl) == VAR_DECL); + return varpool (symtab_get_node (decl)); +} + +/* Return asm name of cgraph node. */ +static inline const char * +cgraph_node_asm_name(struct cgraph_node *node) +{ + return symtab_node_asm_name ((symtab_node)node); +} + +/* Return asm name of varpool node. */ +static inline const char * +varpool_node_asm_name(struct varpool_node *node) +{ + return symtab_node_asm_name ((symtab_node)node); +} + +/* Return name of cgraph node. */ +static inline const char * +cgraph_node_name(struct cgraph_node *node) +{ + return symtab_node_name ((symtab_node)node); +} + +/* Return name of varpool node. */ +static inline const char * +varpool_node_name(struct varpool_node *node) +{ + return symtab_node_name ((symtab_node)node); +} + +/* Walk all symbols. */ +#define FOR_EACH_SYMBOL(node) \ + for ((node) = symtab_nodes; (node); (node) = (node)->symbol.next) + + +/* Return first variable. */ +static inline struct varpool_node * +varpool_first_variable (void) +{ + symtab_node node; + for (node = symtab_nodes; node; node = node->symbol.next) + if (varpool_node *vnode = dyn_cast (node)) + return vnode; + return NULL; +} + +/* Return next variable after NODE. */ +static inline struct varpool_node * +varpool_next_variable (struct varpool_node *node) +{ + symtab_node node1 = (symtab_node) node->symbol.next; + for (; node1; node1 = node1->symbol.next) + if (varpool_node *vnode1 = dyn_cast (node1)) + return vnode1; + return NULL; +} +/* Walk all variables. */ +#define FOR_EACH_VARIABLE(node) \ + for ((node) = varpool_first_variable (); \ + (node); \ + (node) = varpool_next_variable ((node))) + +/* Return first reachable static variable with initializer. */ +static inline struct varpool_node * +varpool_first_static_initializer (void) +{ + symtab_node node; + for (node = symtab_nodes; node; node = node->symbol.next) + { + varpool_node *vnode = dyn_cast (node); + if (vnode && DECL_INITIAL (node->symbol.decl)) + return vnode; + } + return NULL; +} + +/* Return next reachable static variable with initializer after NODE. */ +static inline struct varpool_node * +varpool_next_static_initializer (struct varpool_node *node) +{ + symtab_node node1 = (symtab_node) node->symbol.next; + for (; node1; node1 = node1->symbol.next) + { + varpool_node *vnode1 = dyn_cast (node1); + if (vnode1 && DECL_INITIAL (node1->symbol.decl)) + return vnode1; + } + return NULL; +} + +/* Walk all static variables with initializer set. */ +#define FOR_EACH_STATIC_INITIALIZER(node) \ + for ((node) = varpool_first_static_initializer (); (node); \ + (node) = varpool_next_static_initializer (node)) + +/* Return first reachable static variable with initializer. */ +static inline struct varpool_node * +varpool_first_defined_variable (void) +{ + symtab_node node; + for (node = symtab_nodes; node; node = node->symbol.next) + { + varpool_node *vnode = dyn_cast (node); + if (vnode && vnode->analyzed) + return vnode; + } + return NULL; +} + +/* Return next reachable static variable with initializer after NODE. */ +static inline struct varpool_node * +varpool_next_defined_variable (struct varpool_node *node) +{ + symtab_node node1 = (symtab_node) node->symbol.next; + for (; node1; node1 = node1->symbol.next) + { + varpool_node *vnode1 = dyn_cast (node1); + if (vnode1 && vnode1->analyzed) + return vnode1; + } + return NULL; +} +/* Walk all variables with definitions in current unit. */ +#define FOR_EACH_DEFINED_VARIABLE(node) \ + for ((node) = varpool_first_defined_variable (); (node); \ + (node) = varpool_next_defined_variable (node)) + +/* Return first function with body defined. */ +static inline struct cgraph_node * +cgraph_first_defined_function (void) +{ + symtab_node node; + for (node = symtab_nodes; node; node = node->symbol.next) + { + cgraph_node *cn = dyn_cast (node); + if (cn && cn->analyzed) + return cn; + } + return NULL; +} + +/* Return next function with body defined after NODE. */ +static inline struct cgraph_node * +cgraph_next_defined_function (struct cgraph_node *node) +{ + symtab_node node1 = (symtab_node) node->symbol.next; + for (; node1; node1 = node1->symbol.next) + { + cgraph_node *cn1 = dyn_cast (node1); + if (cn1 && cn1->analyzed) + return cn1; + } + return NULL; +} + +/* Walk all functions with body defined. */ +#define FOR_EACH_DEFINED_FUNCTION(node) \ + for ((node) = cgraph_first_defined_function (); (node); \ + (node) = cgraph_next_defined_function ((node))) + +/* Return first function. */ +static inline struct cgraph_node * +cgraph_first_function (void) +{ + symtab_node node; + for (node = symtab_nodes; node; node = node->symbol.next) + if (cgraph_node *cn = dyn_cast (node)) + return cn; + return NULL; +} + +/* Return next function. */ +static inline struct cgraph_node * +cgraph_next_function (struct cgraph_node *node) +{ + symtab_node node1 = (symtab_node) node->symbol.next; + for (; node1; node1 = node1->symbol.next) + if (cgraph_node *cn1 = dyn_cast (node1)) + return cn1; + return NULL; +} +/* Walk all functions. */ +#define FOR_EACH_FUNCTION(node) \ + for ((node) = cgraph_first_function (); (node); \ + (node) = cgraph_next_function ((node))) + +/* Return true when NODE is a function with Gimple body defined + in current unit. Functions can also be define externally or they + can be thunks with no Gimple representation. + + Note that at WPA stage, the function body may not be present in memory. */ + +static inline bool +cgraph_function_with_gimple_body_p (struct cgraph_node *node) +{ + return node->analyzed && !node->thunk.thunk_p && !node->alias; +} + +/* Return first function with body defined. */ +static inline struct cgraph_node * +cgraph_first_function_with_gimple_body (void) +{ + symtab_node node; + for (node = symtab_nodes; node; node = node->symbol.next) + { + cgraph_node *cn = dyn_cast (node); + if (cn && cgraph_function_with_gimple_body_p (cn)) + return cn; + } + return NULL; +} + +/* Return next reachable static variable with initializer after NODE. */ +static inline struct cgraph_node * +cgraph_next_function_with_gimple_body (struct cgraph_node *node) +{ + symtab_node node1 = node->symbol.next; + for (; node1; node1 = node1->symbol.next) + { + cgraph_node *cn1 = dyn_cast (node1); + if (cn1 && cgraph_function_with_gimple_body_p (cn1)) + return cn1; + } + return NULL; +} + +/* Walk all functions with body defined. */ +#define FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) \ + for ((node) = cgraph_first_function_with_gimple_body (); (node); \ + (node) = cgraph_next_function_with_gimple_body (node)) + +/* Create a new static variable of type TYPE. */ +tree add_new_static_var (tree type); + +/* Return true if iterator CSI points to nothing. */ +static inline bool +csi_end_p (cgraph_node_set_iterator csi) +{ + return csi.index >= csi.set->nodes.length (); +} + +/* Advance iterator CSI. */ +static inline void +csi_next (cgraph_node_set_iterator *csi) +{ + csi->index++; +} + +/* Return the node pointed to by CSI. */ +static inline struct cgraph_node * +csi_node (cgraph_node_set_iterator csi) +{ + return csi.set->nodes[csi.index]; +} + +/* Return an iterator to the first node in SET. */ +static inline cgraph_node_set_iterator +csi_start (cgraph_node_set set) +{ + cgraph_node_set_iterator csi; + + csi.set = set; + csi.index = 0; + return csi; +} + +/* Return true if SET contains NODE. */ +static inline bool +cgraph_node_in_set_p (struct cgraph_node *node, cgraph_node_set set) +{ + cgraph_node_set_iterator csi; + csi = cgraph_node_set_find (set, node); + return !csi_end_p (csi); +} + +/* Return number of nodes in SET. */ +static inline size_t +cgraph_node_set_size (cgraph_node_set set) +{ + return set->nodes.length (); +} + +/* Return true if iterator VSI points to nothing. */ +static inline bool +vsi_end_p (varpool_node_set_iterator vsi) +{ + return vsi.index >= vsi.set->nodes.length (); +} + +/* Advance iterator VSI. */ +static inline void +vsi_next (varpool_node_set_iterator *vsi) +{ + vsi->index++; +} + +/* Return the node pointed to by VSI. */ +static inline struct varpool_node * +vsi_node (varpool_node_set_iterator vsi) +{ + return vsi.set->nodes[vsi.index]; +} + +/* Return an iterator to the first node in SET. */ +static inline varpool_node_set_iterator +vsi_start (varpool_node_set set) +{ + varpool_node_set_iterator vsi; + + vsi.set = set; + vsi.index = 0; + return vsi; +} + +/* Return true if SET contains NODE. */ +static inline bool +varpool_node_in_set_p (struct varpool_node *node, varpool_node_set set) +{ + varpool_node_set_iterator vsi; + vsi = varpool_node_set_find (set, node); + return !vsi_end_p (vsi); +} + +/* Return number of nodes in SET. */ +static inline size_t +varpool_node_set_size (varpool_node_set set) +{ + return set->nodes.length (); +} + +/* Uniquize all constants that appear in memory. + Each constant in memory thus far output is recorded + in `const_desc_table'. */ + +struct GTY(()) constant_descriptor_tree { + /* A MEM for the constant. */ + rtx rtl; + + /* The value of the constant. */ + tree value; + + /* Hash of value. Computing the hash from value each time + hashfn is called can't work properly, as that means recursive + use of the hash table during hash table expansion. */ + hashval_t hash; +}; + +/* Return true if set is nonempty. */ +static inline bool +cgraph_node_set_nonempty_p (cgraph_node_set set) +{ + return !set->nodes.is_empty (); +} + +/* Return true if set is nonempty. */ +static inline bool +varpool_node_set_nonempty_p (varpool_node_set set) +{ + return !set->nodes.is_empty (); +} + +/* Return true when function NODE is only called directly or it has alias. + i.e. it is not externally visible, address was not taken and + it is not used in any other non-standard way. */ + +static inline bool +cgraph_only_called_directly_or_aliased_p (struct cgraph_node *node) +{ + gcc_assert (!node->global.inlined_to); + return (!node->symbol.force_output && !node->symbol.address_taken + && !node->symbol.used_from_other_partition + && !DECL_VIRTUAL_P (node->symbol.decl) + && !DECL_STATIC_CONSTRUCTOR (node->symbol.decl) + && !DECL_STATIC_DESTRUCTOR (node->symbol.decl) + && !node->symbol.externally_visible); +} + +/* Return true when function NODE can be removed from callgraph + if all direct calls are eliminated. */ + +static inline bool +varpool_can_remove_if_no_refs (struct varpool_node *node) +{ + if (DECL_EXTERNAL (node->symbol.decl)) + return true; + return (!node->symbol.force_output && !node->symbol.used_from_other_partition + && ((DECL_COMDAT (node->symbol.decl) + && !symtab_used_from_object_file_p ((symtab_node) node)) + || !node->symbol.externally_visible + || DECL_HAS_VALUE_EXPR_P (node->symbol.decl))); +} + +/* Return true when all references to VNODE must be visible in ipa_ref_list. + i.e. if the variable is not externally visible or not used in some magic + way (asm statement or such). + The magic uses are all summarized in force_output flag. */ + +static inline bool +varpool_all_refs_explicit_p (struct varpool_node *vnode) +{ + return (vnode->analyzed + && !vnode->symbol.externally_visible + && !vnode->symbol.used_from_other_partition + && !vnode->symbol.force_output); +} + +/* Constant pool accessor function. */ +htab_t constant_pool_htab (void); + +/* FIXME: inappropriate dependency of cgraph on IPA. */ +#include "ipa-ref-inline.h" + +/* Return node that alias N is aliasing. */ + +static inline struct cgraph_node * +cgraph_alias_aliased_node (struct cgraph_node *n) +{ + struct ipa_ref *ref; + + ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref); + gcc_checking_assert (ref->use == IPA_REF_ALIAS); + if (is_a (ref->referred)) + return ipa_ref_node (ref); + return NULL; +} + +/* Return node that alias N is aliasing. */ + +static inline struct varpool_node * +varpool_alias_aliased_node (struct varpool_node *n) +{ + struct ipa_ref *ref; + + ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref); + gcc_checking_assert (ref->use == IPA_REF_ALIAS); + if (is_a (ref->referred)) + return ipa_ref_varpool_node (ref); + return NULL; +} + +/* Given NODE, walk the alias chain to return the function NODE is alias of. + Walk through thunk, too. + When AVAILABILITY is non-NULL, get minimal availability in the chain. */ + +static inline struct cgraph_node * +cgraph_function_node (struct cgraph_node *node, enum availability *availability) +{ + if (availability) + *availability = cgraph_function_body_availability (node); + while (node) + { + if (node->alias && node->analyzed) + node = cgraph_alias_aliased_node (node); + else if (node->thunk.thunk_p) + node = node->callees->callee; + else + return node; + if (node && availability) + { + enum availability a; + a = cgraph_function_body_availability (node); + if (a < *availability) + *availability = a; + } + } + if (availability) + *availability = AVAIL_NOT_AVAILABLE; + return NULL; +} + +/* Given NODE, walk the alias chain to return the function NODE is alias of. + Do not walk through thunks. + When AVAILABILITY is non-NULL, get minimal availability in the chain. */ + +static inline struct cgraph_node * +cgraph_function_or_thunk_node (struct cgraph_node *node, enum availability *availability) +{ + if (availability) + *availability = cgraph_function_body_availability (node); + while (node) + { + if (node->alias && node->analyzed) + node = cgraph_alias_aliased_node (node); + else + return node; + if (node && availability) + { + enum availability a; + a = cgraph_function_body_availability (node); + if (a < *availability) + *availability = a; + } + } + if (availability) + *availability = AVAIL_NOT_AVAILABLE; + return NULL; +} + +/* Given NODE, walk the alias chain to return the function NODE is alias of. + Do not walk through thunks. + When AVAILABILITY is non-NULL, get minimal availability in the chain. */ + +static inline struct varpool_node * +varpool_variable_node (struct varpool_node *node, enum availability *availability) +{ + if (availability) + *availability = cgraph_variable_initializer_availability (node); + while (node) + { + if (node->alias && node->analyzed) + node = varpool_alias_aliased_node (node); + else + return node; + if (node && availability) + { + enum availability a; + a = cgraph_variable_initializer_availability (node); + if (a < *availability) + *availability = a; + } + } + if (availability) + *availability = AVAIL_NOT_AVAILABLE; + return NULL; +} + +/* Return true when the edge E represents a direct recursion. */ +static inline bool +cgraph_edge_recursive_p (struct cgraph_edge *e) +{ + struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, NULL); + if (e->caller->global.inlined_to) + return e->caller->global.inlined_to->symbol.decl == callee->symbol.decl; + else + return e->caller->symbol.decl == callee->symbol.decl; +} + +/* Return true if the TM_CLONE bit is set for a given FNDECL. */ +static inline bool +decl_is_tm_clone (const_tree fndecl) +{ + struct cgraph_node *n = cgraph_get_node (fndecl); + if (n) + return n->tm_clone; + return false; +} + +/* Likewise indicate that a node is needed, i.e. reachable via some + external means. */ + +static inline void +cgraph_mark_force_output_node (struct cgraph_node *node) +{ + node->symbol.force_output = 1; + gcc_checking_assert (!node->global.inlined_to); +} + +/* Return true when the symbol is real symbol, i.e. it is not inline clone + or extern function kept around just for inlining. */ + +static inline bool +symtab_real_symbol_p (symtab_node node) +{ + struct cgraph_node *cnode; + + if (!is_a (node)) + return true; + cnode = cgraph (node); + if (cnode->global.inlined_to) + return false; + if (cnode->abstract_and_needed) + return false; + return true; +} +#endif /* GCC_CGRAPH_H */ diff --git a/src/include/cif-code.def b/src/include/cif-code.def new file mode 100644 index 0000000..55e0ef4 --- /dev/null +++ b/src/include/cif-code.def @@ -0,0 +1,105 @@ +/* This file contains the definitions of the cgraph_inline_failed_t + enums used in GCC. + + Copyright (C) 2008-2013 Free Software Foundation, Inc. + Contributed by Doug Kwan + +This file is part of GCC. + +GCC is free software you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC see the file COPYING3. If not see +. */ + +/* The format of this file is + DEFCIFCODE(code, string). + + Where symbol is the enumeration name without the ``''. + The argument STRING is a explain the failure. Except for OK, + which is a NULL pointer. */ + +/* Inlining successful. This must be the first code. */ +DEFCIFCODE(OK , NULL) + +/* Inlining failed for an unspecified reason. */ +DEFCIFCODE(UNSPECIFIED , "") + +/* Function has not be considered for inlining. This is the code for + functions that have not been rejected for inlining yet. */ +DEFCIFCODE(FUNCTION_NOT_CONSIDERED, N_("function not considered for inlining")) + +/* Inlining failed owing to unavailable function body. */ +DEFCIFCODE(BODY_NOT_AVAILABLE, N_("function body not available")) + +/* Extern inline function that has been redefined. */ +DEFCIFCODE(REDEFINED_EXTERN_INLINE, + N_("redefined extern inline functions are not considered for " + "inlining")) + +/* Function is not inlinable. */ +DEFCIFCODE(FUNCTION_NOT_INLINABLE, N_("function not inlinable")) + +/* Function is not overwritable. */ +DEFCIFCODE(OVERWRITABLE, N_("function body can be overwritten at link time")) + +/* Function is not an inlining candidate. */ +DEFCIFCODE(FUNCTION_NOT_INLINE_CANDIDATE, N_("function not inline candidate")) + +/* Inlining failed because of various limit parameters. */ +DEFCIFCODE(LARGE_FUNCTION_GROWTH_LIMIT, + N_("--param large-function-growth limit reached")) +DEFCIFCODE(LARGE_STACK_FRAME_GROWTH_LIMIT, + N_("--param large-stack-frame-growth limit reached")) +DEFCIFCODE(MAX_INLINE_INSNS_SINGLE_LIMIT, + N_("--param max-inline-insns-single limit reached")) +DEFCIFCODE(MAX_INLINE_INSNS_AUTO_LIMIT, + N_("--param max-inline-insns-auto limit reached")) +DEFCIFCODE(INLINE_UNIT_GROWTH_LIMIT, + N_("--param inline-unit-growth limit reached")) + +/* Recursive inlining. */ +DEFCIFCODE(RECURSIVE_INLINING, N_("recursive inlining")) + +/* Call is unlikely. */ +DEFCIFCODE(UNLIKELY_CALL, N_("call is unlikely and code size would grow")) + +/* Function is not declared as inline. */ +DEFCIFCODE(NOT_DECLARED_INLINED, + N_("function not declared inline and code size would grow")) + +/* Inlining suppressed due to size optimization. */ +DEFCIFCODE(OPTIMIZING_FOR_SIZE, + N_("optimizing for size and code size would grow")) + +/* Caller and callee disagree on the arguments. */ +DEFCIFCODE(MISMATCHED_ARGUMENTS, N_("mismatched arguments")) + +/* Call was originally indirect. */ +DEFCIFCODE(ORIGINALLY_INDIRECT_CALL, + N_("originally indirect function call not considered for inlining")) + +/* Ths edge represents an indirect edge with a yet-undetermined callee . */ +DEFCIFCODE(INDIRECT_UNKNOWN_CALL, + N_("indirect function call with a yet undetermined callee")) + +/* We can't inline different EH personalities together. */ +DEFCIFCODE(EH_PERSONALITY, N_("exception handling personality mismatch")) + +/* We can't inline if the callee can throw non-call exceptions but the + caller cannot. */ +DEFCIFCODE(NON_CALL_EXCEPTIONS, N_("non-call exception handling mismatch")) + +/* We can't inline because of mismatched target specific options. */ +DEFCIFCODE(TARGET_OPTION_MISMATCH, N_("target specific option mismatch")) + +/* We can't inline because of mismatched optimization levels. */ +DEFCIFCODE(OPTIMIZATION_MISMATCH, N_("optimization level attribute mismatch")) diff --git a/src/include/config.h b/src/include/config.h new file mode 100644 index 0000000..aa6dd6b --- /dev/null +++ b/src/include/config.h @@ -0,0 +1,10 @@ +#ifndef GCC_CONFIG_H +#define GCC_CONFIG_H +#ifdef GENERATOR_FILE +#error config.h is for the host, not build, machine. +#endif +#include "auto-host.h" +#ifdef IN_GCC +# include "ansidecl.h" +#endif +#endif /* GCC_CONFIG_H */ diff --git a/src/include/config/dbxelf.h b/src/include/config/dbxelf.h new file mode 100644 index 0000000..e45efc9 --- /dev/null +++ b/src/include/config/dbxelf.h @@ -0,0 +1,68 @@ +/* Definitions needed when using stabs embedded in ELF sections. + Copyright (C) 1999-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* This file may be included by any ELF target which wishes to + support -gstabs generating stabs in sections, as produced by gas + and understood by gdb. */ + +#ifndef GCC_DBX_ELF_H +#define GCC_DBX_ELF_H + +/* Output DBX (stabs) debugging information if doing -gstabs. */ + +#define DBX_DEBUGGING_INFO 1 + +/* Make LBRAC and RBRAC addresses relative to the start of the + function. The native Solaris stabs debugging format works this + way, gdb expects it, and it reduces the number of relocation + entries... */ + +#define DBX_BLOCKS_FUNCTION_RELATIVE 1 + +/* ... but, to make this work, functions must appear prior to line info. */ + +#define DBX_FUNCTION_FIRST + +/* When generating stabs debugging, use N_BINCL entries. */ + +#define DBX_USE_BINCL + +/* There is no limit to the length of stabs strings. */ + +#ifndef DBX_CONTIN_LENGTH +#define DBX_CONTIN_LENGTH 0 +#endif + +/* Like block addresses, stabs line numbers are relative to the + current function. */ + +#define DBX_LINES_FUNCTION_RELATIVE 1 + +/* Generate a blank trailing N_SO to mark the end of the .o file, since + we can't depend upon the linker to mark .o file boundaries with + embedded stabs. */ + +#define DBX_OUTPUT_NULL_N_SO_AT_MAIN_SOURCE_FILE_END + +#endif /* ! GCC_DBX_ELF_H */ diff --git a/src/include/config/elfos.h b/src/include/config/elfos.h new file mode 100644 index 0000000..43aab73 --- /dev/null +++ b/src/include/config/elfos.h @@ -0,0 +1,435 @@ +/* elfos.h -- operating system specific defines to be used when + targeting GCC for some generic ELF system + Copyright (C) 1991-2013 Free Software Foundation, Inc. + Based on svr4.h contributed by Ron Guilmette (rfg@netcom.com). + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#define TARGET_OBJFMT_CPP_BUILTINS() \ + do \ + { \ + builtin_define ("__ELF__"); \ + } \ + while (0) + +/* Define a symbol indicating that we are using elfos.h. + Some CPU specific configuration files use this. */ +#define USING_ELFOS_H + +/* The prefix to add to user-visible assembler symbols. + + For ELF systems the convention is *not* to prepend a leading + underscore onto user-level symbol names. */ + +#undef USER_LABEL_PREFIX +#define USER_LABEL_PREFIX "" + +/* The biggest alignment supported by ELF in bits. 32-bit ELF + supports section alignment up to (0x80000000 * 8), while + 64-bit ELF supports (0x8000000000000000 * 8). If this macro + is not defined, the default is the largest alignment supported + by 32-bit ELF and representable on a 32-bit host. Use this + macro to limit the alignment which can be specified using + the `__attribute__ ((aligned (N)))' construct. */ +#ifndef MAX_OFILE_ALIGNMENT +#define MAX_OFILE_ALIGNMENT (((unsigned int) 1 << 28) * 8) +#endif + +/* Use periods rather than dollar signs in special g++ assembler names. */ + +#define NO_DOLLAR_IN_LABEL + +/* Writing `int' for a bit-field forces int alignment for the structure. */ + +#ifndef PCC_BITFIELD_TYPE_MATTERS +#define PCC_BITFIELD_TYPE_MATTERS 1 +#endif + +/* All ELF targets can support DWARF-2. */ + +#define DWARF2_DEBUGGING_INFO 1 + +/* The GNU tools operate better with dwarf2, and it is required by some + psABI's. Since we don't have any native tools to be compatible with, + default to dwarf2. */ + +#ifndef PREFERRED_DEBUGGING_TYPE +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG +#endif + +/* All SVR4 targets use the ELF object file format. */ +#define OBJECT_FORMAT_ELF + + +/* Output #ident as a .ident. */ + +#undef TARGET_ASM_OUTPUT_IDENT +#define TARGET_ASM_OUTPUT_IDENT default_asm_output_ident_directive + +#undef SET_ASM_OP +#define SET_ASM_OP "\t.set\t" + +/* Most svr4 assemblers want a .file directive at the beginning of + their input file. */ +#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true + +/* This is how to allocate empty space in some section. The .zero + pseudo-op is used for this on most svr4 assemblers. */ + +#define SKIP_ASM_OP "\t.zero\t" + +#undef ASM_OUTPUT_SKIP +#define ASM_OUTPUT_SKIP(FILE, SIZE) \ + fprintf ((FILE), "%s"HOST_WIDE_INT_PRINT_UNSIGNED"\n",\ + SKIP_ASM_OP, (SIZE)) + +/* This is how to store into the string LABEL + the symbol_ref name of an internal numbered label where + PREFIX is the class of label and NUM is the number within the class. + This is suitable for output with `assemble_name'. + + For most svr4 systems, the convention is that any symbol which begins + with a period is not put into the linker symbol table by the assembler. */ + +#undef ASM_GENERATE_INTERNAL_LABEL +#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ + do \ + { \ + char *__p; \ + (LABEL)[0] = '*'; \ + (LABEL)[1] = '.'; \ + __p = stpcpy (&(LABEL)[2], PREFIX); \ + sprint_ul (__p, (unsigned long) (NUM)); \ + } \ + while (0) + +/* Output the label which precedes a jumptable. Note that for all svr4 + systems where we actually generate jumptables (which is to say every + svr4 target except i386, where we use casesi instead) we put the jump- + tables into the .rodata section and since other stuff could have been + put into the .rodata section prior to any given jumptable, we have to + make sure that the location counter for the .rodata section gets pro- + perly re-aligned prior to the actual beginning of the jump table. */ + +#undef ALIGN_ASM_OP +#define ALIGN_ASM_OP "\t.align\t" + +#ifndef ASM_OUTPUT_BEFORE_CASE_LABEL +#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \ + ASM_OUTPUT_ALIGN ((FILE), 2); +#endif + +#undef ASM_OUTPUT_CASE_LABEL +#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, JUMPTABLE) \ + do \ + { \ + ASM_OUTPUT_BEFORE_CASE_LABEL (FILE, PREFIX, NUM, JUMPTABLE) \ + (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM); \ + } \ + while (0) + +/* The standard SVR4 assembler seems to require that certain builtin + library routines (e.g. .udiv) be explicitly declared as .globl + in each assembly file where they are referenced. */ + +#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \ + (*targetm.asm_out.globalize_label) (FILE, XSTR (FUN, 0)) + +/* This says how to output assembler code to declare an + uninitialized external linkage data object. Under SVR4, + the linker seems to want the alignment of data objects + to depend on their types. We do exactly that here. */ + +#define COMMON_ASM_OP "\t.comm\t" + +#undef ASM_OUTPUT_ALIGNED_COMMON +#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \ + do \ + { \ + fprintf ((FILE), "%s", COMMON_ASM_OP); \ + assemble_name ((FILE), (NAME)); \ + fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \ + (SIZE), (ALIGN) / BITS_PER_UNIT); \ + } \ + while (0) + +/* This says how to output assembler code to declare an + uninitialized internal linkage data object. Under SVR4, + the linker seems to want the alignment of data objects + to depend on their types. We do exactly that here. */ + +#define LOCAL_ASM_OP "\t.local\t" + +#undef ASM_OUTPUT_ALIGNED_LOCAL +#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ + do \ + { \ + fprintf ((FILE), "%s", LOCAL_ASM_OP); \ + assemble_name ((FILE), (NAME)); \ + fprintf ((FILE), "\n"); \ + ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \ + } \ + while (0) + +/* This is the pseudo-op used to generate a contiguous sequence of byte + values from a double-quoted string WITHOUT HAVING A TERMINATING NUL + AUTOMATICALLY APPENDED. This is the same for most svr4 assemblers. */ + +#undef ASCII_DATA_ASM_OP +#define ASCII_DATA_ASM_OP "\t.ascii\t" + +/* Support a read-only data section. */ +#define READONLY_DATA_SECTION_ASM_OP "\t.section\t.rodata" + +/* On svr4, we *do* have support for the .init and .fini sections, and we + can put stuff in there to be executed before and after `main'. We let + crtstuff.c and other files know this by defining the following symbols. + The definitions say how to change sections to the .init and .fini + sections. This is the same for all known svr4 assemblers. */ + +#define INIT_SECTION_ASM_OP "\t.section\t.init" +#define FINI_SECTION_ASM_OP "\t.section\t.fini" + +/* Output assembly directive to move to the beginning of current section. */ +#ifdef HAVE_GAS_SUBSECTION_ORDERING +# define ASM_SECTION_START_OP "\t.subsection\t-1" +# define ASM_OUTPUT_SECTION_START(FILE) \ + fprintf ((FILE), "%s\n", ASM_SECTION_START_OP) +#endif + +#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1) + +/* Switch into a generic section. */ +#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section + +#undef TARGET_ASM_SELECT_RTX_SECTION +#define TARGET_ASM_SELECT_RTX_SECTION default_elf_select_rtx_section +#undef TARGET_ASM_SELECT_SECTION +#define TARGET_ASM_SELECT_SECTION default_elf_select_section +#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS +#define TARGET_HAVE_SWITCHABLE_BSS_SECTIONS true + +/* Define the strings used for the special svr4 .type and .size directives. + These strings generally do not vary from one system running svr4 to + another, but if a given system (e.g. m88k running svr) needs to use + different pseudo-op names for these, they may be overridden in the + file which includes this one. */ + +#define TYPE_ASM_OP "\t.type\t" +#define SIZE_ASM_OP "\t.size\t" + +/* This is how we tell the assembler that a symbol is weak. */ + +#define ASM_WEAKEN_LABEL(FILE, NAME) \ + do \ + { \ + fputs ("\t.weak\t", (FILE)); \ + assemble_name ((FILE), (NAME)); \ + fputc ('\n', (FILE)); \ + } \ + while (0) + +/* The following macro defines the format used to output the second + operand of the .type assembler directive. Different svr4 assemblers + expect various different forms for this operand. The one given here + is just a default. You may need to override it in your machine- + specific tm.h file (depending upon the particulars of your assembler). */ + +#define TYPE_OPERAND_FMT "@%s" + +/* Write the extra assembler code needed to declare a function's result. + Most svr4 assemblers don't require any special declaration of the + result value, but there are exceptions. */ + +#ifndef ASM_DECLARE_RESULT +#define ASM_DECLARE_RESULT(FILE, RESULT) +#endif + +/* These macros generate the special .type and .size directives which + are used to set the corresponding fields of the linker symbol table + entries in an ELF object file under SVR4. These macros also output + the starting labels for the relevant functions/objects. */ + +/* Write the extra assembler code needed to declare a function properly. + Some svr4 assemblers need to also have something extra said about the + function's return value. We allow for that here. */ + +#ifndef ASM_DECLARE_FUNCTION_NAME +#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ + do \ + { \ + ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \ + ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ + ASM_OUTPUT_FUNCTION_LABEL (FILE, NAME, DECL); \ + } \ + while (0) +#endif + +/* Write the extra assembler code needed to declare an object properly. */ + +#ifdef HAVE_GAS_GNU_UNIQUE_OBJECT +#define USE_GNU_UNIQUE_OBJECT flag_gnu_unique +#else +#define USE_GNU_UNIQUE_OBJECT 0 +#endif + +#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ + do \ + { \ + HOST_WIDE_INT size; \ + \ + /* For template static data member instantiations or \ + inline fn local statics and their guard variables, use \ + gnu_unique_object so that they will be combined even under \ + RTLD_LOCAL. Don't use gnu_unique_object for typeinfo, \ + vtables and other read-only artificial decls. */ \ + if (USE_GNU_UNIQUE_OBJECT && DECL_ONE_ONLY (DECL) \ + && (!DECL_ARTIFICIAL (DECL) || !TREE_READONLY (DECL))) \ + ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "gnu_unique_object"); \ + else \ + ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "object"); \ + \ + size_directive_output = 0; \ + if (!flag_inhibit_size_directive \ + && (DECL) && DECL_SIZE (DECL)) \ + { \ + size_directive_output = 1; \ + size = int_size_in_bytes (TREE_TYPE (DECL)); \ + ASM_OUTPUT_SIZE_DIRECTIVE (FILE, NAME, size); \ + } \ + \ + ASM_OUTPUT_LABEL (FILE, NAME); \ + } \ + while (0) + +/* Output the size directive for a decl in rest_of_decl_compilation + in the case where we did not do so before the initializer. + Once we find the error_mark_node, we know that the value of + size_directive_output was set + by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ + +#undef ASM_FINISH_DECLARE_OBJECT +#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END)\ + do \ + { \ + const char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ + HOST_WIDE_INT size; \ + \ + if (!flag_inhibit_size_directive \ + && DECL_SIZE (DECL) \ + && ! AT_END && TOP_LEVEL \ + && DECL_INITIAL (DECL) == error_mark_node \ + && !size_directive_output) \ + { \ + size_directive_output = 1; \ + size = int_size_in_bytes (TREE_TYPE (DECL)); \ + ASM_OUTPUT_SIZE_DIRECTIVE (FILE, name, size); \ + } \ + } \ + while (0) + +/* This is how to declare the size of a function. */ +#ifndef ASM_DECLARE_FUNCTION_SIZE +#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ + do \ + { \ + if (!flag_inhibit_size_directive) \ + ASM_OUTPUT_MEASURED_SIZE (FILE, FNAME); \ + } \ + while (0) +#endif + +/* A table of bytes codes used by the ASM_OUTPUT_ASCII and + ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table + corresponds to a particular byte value [0..255]. For any + given byte value, if the value in the corresponding table + position is zero, the given character can be output directly. + If the table value is 1, the byte must be output as a \ooo + octal escape. If the tables value is anything else, then the + byte value should be output as a \ followed by the value + in the table. Note that we can use standard UN*X escape + sequences for many control characters, but we don't use + \a to represent BEL because some svr4 assemblers (e.g. on + the i386) don't know about that. Also, we don't use \v + since some versions of gas, such as 2.2 did not accept it. */ + +#define ELF_ASCII_ESCAPES \ +"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ +\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\ +\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ +\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ +\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ +\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1" + +/* Some svr4 assemblers have a limit on the number of characters which + can appear in the operand of a .string directive. If your assembler + has such a limitation, you should define STRING_LIMIT to reflect that + limit. Note that at least some svr4 assemblers have a limit on the + actual number of bytes in the double-quoted string, and that they + count each character in an escape sequence as one byte. Thus, an + escape sequence like \377 would count as four bytes. + + If your target assembler doesn't support the .string directive, you + should define this to zero. +*/ + +#define ELF_STRING_LIMIT ((unsigned) 256) + +#define STRING_ASM_OP "\t.string\t" + +/* The routine used to output NUL terminated strings. We use a special + version of this for most svr4 targets because doing so makes the + generated assembly code more compact (and thus faster to assemble) + as well as more readable, especially for targets like the i386 + (where the only alternative is to output character sequences as + comma separated lists of numbers). */ + +#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \ + default_elf_asm_output_limited_string ((FILE), (STR)) + +/* The routine used to output sequences of byte values. We use a special + version of this for most svr4 targets because doing so makes the + generated assembly code more compact (and thus faster to assemble) + as well as more readable. Note that if we find subparts of the + character sequence which end with NUL (and which are shorter than + STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */ + +#undef ASM_OUTPUT_ASCII +#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \ + default_elf_asm_output_ascii ((FILE), (STR), (LENGTH)); + +/* Allow the use of the -frecord-gcc-switches switch via the + elf_record_gcc_switches function defined in varasm.c. */ +#undef TARGET_ASM_RECORD_GCC_SWITCHES +#define TARGET_ASM_RECORD_GCC_SWITCHES elf_record_gcc_switches + +/* A C statement (sans semicolon) to output to the stdio stream STREAM + any text necessary for declaring the name of an external symbol + named NAME which is referenced in this compilation but not defined. + It is needed to properly support non-default visibility. */ + +#ifndef ASM_OUTPUT_EXTERNAL +#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ + default_elf_asm_output_external (FILE, DECL, NAME) +#endif diff --git a/src/include/config/glibc-stdint.h b/src/include/config/glibc-stdint.h new file mode 100644 index 0000000..54bc630 --- /dev/null +++ b/src/include/config/glibc-stdint.h @@ -0,0 +1,55 @@ +/* Definitions for types on systems using GNU libc or uClibc. + Copyright (C) 2008-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#define SIG_ATOMIC_TYPE "int" + +#define INT8_TYPE "signed char" +#define INT16_TYPE "short int" +#define INT32_TYPE "int" +#define INT64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int") +#define UINT8_TYPE "unsigned char" +#define UINT16_TYPE "short unsigned int" +#define UINT32_TYPE "unsigned int" +#define UINT64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int") + +#define INT_LEAST8_TYPE "signed char" +#define INT_LEAST16_TYPE "short int" +#define INT_LEAST32_TYPE "int" +#define INT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int") +#define UINT_LEAST8_TYPE "unsigned char" +#define UINT_LEAST16_TYPE "short unsigned int" +#define UINT_LEAST32_TYPE "unsigned int" +#define UINT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int") + +#define INT_FAST8_TYPE "signed char" +#define INT_FAST16_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int") +#define INT_FAST32_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int") +#define INT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int") +#define UINT_FAST8_TYPE "unsigned char" +#define UINT_FAST16_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int") +#define UINT_FAST32_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int") +#define UINT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int") + +#define INTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int") +#define UINTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int") diff --git a/src/include/config/gnu-user.h b/src/include/config/gnu-user.h new file mode 100644 index 0000000..bcdf0e6 --- /dev/null +++ b/src/include/config/gnu-user.h @@ -0,0 +1,123 @@ +/* Definitions for systems using, at least optionally, a GNU + (glibc-based) userspace or other userspace with libc derived from + glibc (e.g. uClibc) or for which similar specs are appropriate. + Copyright (C) 1995-2013 Free Software Foundation, Inc. + Contributed by Eric Youngdale. + Modified for stabs-in-ELF by H.J. Lu (hjl@lucon.org). + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* Don't assume anything about the header files. */ +#define NO_IMPLICIT_EXTERN_C + +#undef ASM_APP_ON +#define ASM_APP_ON "#APP\n" + +#undef ASM_APP_OFF +#define ASM_APP_OFF "#NO_APP\n" + +/* Provide a STARTFILE_SPEC appropriate for GNU userspace. Here we add + the GNU userspace magical crtbegin.o file (see crtstuff.c) which + provides part of the support for getting C++ file-scope static + object constructed before entering `main'. */ + +#if defined HAVE_LD_PIE +#define GNU_USER_TARGET_STARTFILE_SPEC \ + "%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \ + crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}" +#else +#define GNU_USER_TARGET_STARTFILE_SPEC \ + "%{!shared: %{pg|p|profile:gcrt1.o%s;:crt1.o%s}} \ + crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}" +#endif +#undef STARTFILE_SPEC +#define STARTFILE_SPEC GNU_USER_TARGET_STARTFILE_SPEC + +/* Provide a ENDFILE_SPEC appropriate for GNU userspace. Here we tack on + the GNU userspace magical crtend.o file (see crtstuff.c) which + provides part of the support for getting C++ file-scope static + object constructed before entering `main', followed by a normal + GNU userspace "finalizer" file, `crtn.o'. */ + +#define GNU_USER_TARGET_ENDFILE_SPEC \ + "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s" +#undef ENDFILE_SPEC +#define ENDFILE_SPEC GNU_USER_TARGET_ENDFILE_SPEC + +/* This is for -profile to use -lc_p instead of -lc. */ +#define GNU_USER_TARGET_CC1_SPEC "%{profile:-p}" +#ifndef CC1_SPEC +#define CC1_SPEC GNU_USER_TARGET_CC1_SPEC +#endif + +/* The GNU C++ standard library requires that these macros be defined. */ +#undef CPLUSPLUS_CPP_SPEC +#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)" + +#define GNU_USER_TARGET_LIB_SPEC \ + "%{pthread:-lpthread} \ + %{shared:-lc} \ + %{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}" +#undef LIB_SPEC +#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC + +#if defined(HAVE_LD_EH_FRAME_HDR) +#define LINK_EH_SPEC "%{!static:--eh-frame-hdr} " +#endif + +#undef LINK_GCC_C_SEQUENCE_SPEC +#define LINK_GCC_C_SEQUENCE_SPEC \ + "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" + +/* Use --as-needed -lgcc_s for eh support. */ +#ifdef HAVE_LD_AS_NEEDED +#define USE_LD_AS_NEEDED 1 +#endif + +#define TARGET_POSIX_IO + +#define TARGET_C99_FUNCTIONS 1 +#define TARGET_HAS_SINCOS 1 + +/* Link -lasan early on the command line. For -static-libasan, don't link + it for -shared link, the executable should be compiled with -static-libasan + in that case, and for executable link link with --{,no-}whole-archive around + it to force everything into the executable. And similarly for -ltsan. */ +#if defined(HAVE_LD_STATIC_DYNAMIC) +#undef LIBASAN_EARLY_SPEC +#define LIBASAN_EARLY_SPEC "%{!shared:libasan_preinit%O%s} " \ + "%{static-libasan:%{!shared:" \ + LD_STATIC_OPTION " --whole-archive -lasan --no-whole-archive " \ + LD_DYNAMIC_OPTION "}}%{!static-libasan:-lasan}" +#undef LIBTSAN_EARLY_SPEC +#define LIBTSAN_EARLY_SPEC "%{static-libtsan:%{!shared:" \ + LD_STATIC_OPTION " --whole-archive -ltsan --no-whole-archive " \ + LD_DYNAMIC_OPTION "}}%{!static-libtsan:-ltsan}" +#endif + +/* Additional libraries needed by -static-libasan. */ +#undef STATIC_LIBASAN_LIBS +#define STATIC_LIBASAN_LIBS "-ldl -lpthread" + +/* Additional libraries needed by -static-libtsan. */ +#undef STATIC_LIBTSAN_LIBS +#define STATIC_LIBTSAN_LIBS "-ldl -lpthread" diff --git a/src/include/config/i386/att.h b/src/include/config/i386/att.h new file mode 100644 index 0000000..e194c5b --- /dev/null +++ b/src/include/config/i386/att.h @@ -0,0 +1,91 @@ +/* Definitions for AT&T assembler syntax for the Intel 80386. + Copyright (C) 1988-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + + +/* Define the syntax of instructions and addresses. */ + +/* Prefix for internally generated assembler labels. */ +#define LPREFIX ".L" + +/* Assembler pseudos to introduce constants of various size. */ + +#define ASM_BYTE "\t.byte\t" +#define ASM_SHORT "\t.value\t" +#define ASM_LONG "\t.long\t" +#define ASM_QUAD "\t.quad\t" /* Should not be used for 32bit compilation. */ + +/* How to output an ASCII string constant. */ + +#undef ASM_OUTPUT_ASCII +#define ASM_OUTPUT_ASCII(FILE, PTR, SIZE) \ +do \ +{ size_t i = 0, limit = (SIZE); \ + while (i < limit) \ + { if (i%10 == 0) { if (i!=0) putc ('\n', (FILE)); \ + fputs (ASM_BYTE, (FILE)); } \ + else putc (',', (FILE)); \ + fprintf ((FILE), "0x%x", ((PTR)[i++] & 0377)) ;} \ + putc ('\n', (FILE)); \ +} while (0) + +/* Output at beginning of assembler file. */ +#define TARGET_ASM_FILE_START_FILE_DIRECTIVE true + +/* This is how to output an assembler line + that says to advance the location counter + to a multiple of 2**LOG bytes. */ + +#define ASM_OUTPUT_ALIGN(FILE,LOG) \ + if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG)) + +/* This is how to output an assembler line + that says to advance the location counter by SIZE bytes. */ + +#undef ASM_OUTPUT_SKIP +#define ASM_OUTPUT_SKIP(FILE,SIZE) \ + fprintf ((FILE), "\t.set .,.+%u\n", (int)(SIZE)) + +/* Can't use ASM_OUTPUT_SKIP in text section; it doesn't leave 0s. */ + +#define ASM_NO_SKIP_IN_TEXT 1 + +/* Define the syntax of labels and symbol definitions/declarations. */ + +/* The prefix to add for compiler private assembler symbols. */ +#undef LOCAL_LABEL_PREFIX +#define LOCAL_LABEL_PREFIX "." + +/* This is how to store into the string BUF + the symbol_ref name of an internal numbered label where + PREFIX is the class of label and NUM is the number within the class. + This is suitable for output with `assemble_name'. */ + +#undef ASM_GENERATE_INTERNAL_LABEL +#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ + sprintf ((BUF), LOCAL_LABEL_PREFIX "%s%ld", (PREFIX), (long)(NUMBER)) + +/* The prefix to add to user-visible assembler symbols. */ + +#undef USER_LABEL_PREFIX +#define USER_LABEL_PREFIX "" diff --git a/src/include/config/i386/biarch64.h b/src/include/config/i386/biarch64.h new file mode 100644 index 0000000..5b5e86b --- /dev/null +++ b/src/include/config/i386/biarch64.h @@ -0,0 +1,29 @@ +/* Make configure files to produce biarch compiler defaulting to 64bit mode. + This file must be included very first, while the OS specific file later + to overwrite otherwise wrong defaults. + Copyright (C) 2001-2013 Free Software Foundation, Inc. + Contributed by Bo Thorsen . + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#define TARGET_64BIT_DEFAULT (OPTION_MASK_ISA_64BIT | OPTION_MASK_ABI_64) +#define TARGET_BI_ARCH 1 diff --git a/src/include/config/i386/gnu-user-common.h b/src/include/config/i386/gnu-user-common.h new file mode 100644 index 0000000..e28483d --- /dev/null +++ b/src/include/config/i386/gnu-user-common.h @@ -0,0 +1,72 @@ +/* Common definitions for Intel 386 and AMD x86-64 systems using + GNU userspace. Copyright (C) 2012-2013 Free Software Foundation, Inc. + Contributed by Ilya Enkovich. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* The svr4 ABI for the i386 says that records and unions are returned + in memory. In the 64bit compilation we will turn this flag off in + ix86_option_override_internal, as we never do pcc_struct_return + scheme on this target. */ +#undef DEFAULT_PCC_STRUCT_RETURN +#define DEFAULT_PCC_STRUCT_RETURN 1 + +/* We arrange for the whole %fs segment to map the tls area. */ +#undef TARGET_TLS_DIRECT_SEG_REFS_DEFAULT +#define TARGET_TLS_DIRECT_SEG_REFS_DEFAULT MASK_TLS_DIRECT_SEG_REFS + +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + GNU_USER_TARGET_OS_CPP_BUILTINS(); \ + } \ + while (0) + +#undef CPP_SPEC +#define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}" + +#undef GNU_USER_TARGET_CC1_SPEC +#define GNU_USER_TARGET_CC1_SPEC "%(cc1_cpu) %{profile:-p}" + +#undef CC1_SPEC +#define CC1_SPEC GNU_USER_TARGET_CC1_SPEC + +/* Similar to standard GNU userspace, but adding -ffast-math support. */ +#define GNU_USER_TARGET_MATHFILE_SPEC \ + "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \ + %{mpc32:crtprec32.o%s} \ + %{mpc64:crtprec64.o%s} \ + %{mpc80:crtprec80.o%s}" + +#undef ENDFILE_SPEC +#define ENDFILE_SPEC \ + GNU_USER_TARGET_MATHFILE_SPEC " " \ + GNU_USER_TARGET_ENDFILE_SPEC + +/* Put all *tf routines in libgcc. */ +#undef LIBGCC2_HAS_TF_MODE +#define LIBGCC2_HAS_TF_MODE 1 +#define LIBGCC2_TF_CEXT q +#define TF_SIZE 113 + +#define TARGET_ASM_FILE_END file_end_indicate_exec_stack + +/* The stack pointer needs to be moved while checking the stack. */ +#define STACK_CHECK_MOVING_SP 1 + +/* Static stack checking is supported by means of probes. */ +#define STACK_CHECK_STATIC_BUILTIN 1 diff --git a/src/include/config/i386/gnu-user64.h b/src/include/config/i386/gnu-user64.h new file mode 100644 index 0000000..952bb5b --- /dev/null +++ b/src/include/config/i386/gnu-user64.h @@ -0,0 +1,99 @@ +/* Definitions for AMD x86-64 using GNU userspace. + Copyright (C) 2001-2013 Free Software Foundation, Inc. + Contributed by Jan Hubicka , based on linux.h. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* Provide a LINK_SPEC. Here we provide support for the special GCC + options -static and -shared, which allow us to link things in one + of these three modes by applying the appropriate combinations of + options at link-time. + + When the -shared link option is used a final link is not being + done. */ + +#if TARGET_64BIT_DEFAULT +#define SPEC_32 "m32" +#if TARGET_BI_ARCH == 2 +#define SPEC_64 "m64" +#define SPEC_X32 "m32|m64:;" +#else +#define SPEC_64 "m32|mx32:;" +#define SPEC_X32 "mx32" +#endif +#else +#define SPEC_32 "m64|mx32:;" +#define SPEC_64 "m64" +#define SPEC_X32 "mx32" +#endif + +#undef ASM_SPEC +#define ASM_SPEC "%{" SPEC_32 ":--32} \ + %{" SPEC_64 ":--64} \ + %{" SPEC_X32 ":--x32} \ + %{!mno-sse2avx:%{mavx:-msse2avx}} %{msse2avx:%{!mavx:-msse2avx}}" + +#define GNU_USER_TARGET_LINK_SPEC \ + "%{" SPEC_64 ":-m " GNU_USER_LINK_EMULATION64 "} \ + %{" SPEC_32 ":-m " GNU_USER_LINK_EMULATION32 "} \ + %{" SPEC_X32 ":-m " GNU_USER_LINK_EMULATIONX32 "} \ + %{shared:-shared} \ + %{!shared: \ + %{!static: \ + %{rdynamic:-export-dynamic} \ + %{" SPEC_32 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "} \ + %{" SPEC_64 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "} \ + %{" SPEC_X32 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKERX32 "}} \ + %{static:-static}}" + +#undef LINK_SPEC +#define LINK_SPEC GNU_USER_TARGET_LINK_SPEC + +#if TARGET_64BIT_DEFAULT +#if TARGET_BI_ARCH == 2 +#define MULTILIB_DEFAULTS { "mx32" } +#else +#define MULTILIB_DEFAULTS { "m64" } +#endif +#else +#define MULTILIB_DEFAULTS { "m32" } +#endif + +#ifdef TARGET_LIBC_PROVIDES_SSP +/* i386 glibc provides __stack_chk_guard in %gs:0x14, + x32 glibc provides it in %fs:0x18. + x86_64 glibc provides it in %fs:0x28. */ +#define TARGET_THREAD_SSP_OFFSET \ + (TARGET_64BIT ? (TARGET_X32 ? 0x18 : 0x28) : 0x14) + +/* We only build the -fsplit-stack support in libgcc if the + assembler has full support for the CFI directives. */ +#if HAVE_GAS_CFI_PERSONALITY_DIRECTIVE +#define TARGET_CAN_SPLIT_STACK +#endif +/* We steal the last transactional memory word. */ +#define TARGET_THREAD_SPLIT_STACK_OFFSET \ + (TARGET_64BIT ? (TARGET_X32 ? 0x40 : 0x70) : 0x30) +#endif + +#undef WCHAR_TYPE +#define WCHAR_TYPE (TARGET_LP64 ? "int" : "long int") diff --git a/src/include/config/i386/i386-opts.h b/src/include/config/i386/i386-opts.h new file mode 100644 index 0000000..11c0845 --- /dev/null +++ b/src/include/config/i386/i386-opts.h @@ -0,0 +1,88 @@ +/* Definitions for option handling for IA-32. + Copyright (C) 1988-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#ifndef I386_OPTS_H +#define I386_OPTS_H + +/* Algorithm to expand string function with. */ +enum stringop_alg +{ + no_stringop, + libcall, + rep_prefix_1_byte, + rep_prefix_4_byte, + rep_prefix_8_byte, + loop_1_byte, + loop, + unrolled_loop +}; + +/* Available call abi. */ +enum calling_abi +{ + SYSV_ABI = 0, + MS_ABI = 1 +}; + +enum fpmath_unit +{ + FPMATH_387 = 1, + FPMATH_SSE = 2 +}; + +enum tls_dialect +{ + TLS_DIALECT_GNU, + TLS_DIALECT_GNU2, + TLS_DIALECT_SUN +}; + +enum cmodel { + CM_32, /* The traditional 32-bit ABI. */ + CM_SMALL, /* Assumes all code and data fits in the low 31 bits. */ + CM_KERNEL, /* Assumes all code and data fits in the high 31 bits. */ + CM_MEDIUM, /* Assumes code fits in the low 31 bits; data unlimited. */ + CM_LARGE, /* No assumptions. */ + CM_SMALL_PIC, /* Assumes code+data+got/plt fits in a 31 bit region. */ + CM_MEDIUM_PIC,/* Assumes code+got/plt fits in a 31 bit region. */ + CM_LARGE_PIC /* No assumptions. */ +}; + +enum pmode { + PMODE_SI, /* Pmode == SImode. */ + PMODE_DI /* Pmode == DImode. */ +}; + +enum asm_dialect { + ASM_ATT, + ASM_INTEL +}; + +enum ix86_veclibabi { + ix86_veclibabi_type_none, + ix86_veclibabi_type_svml, + ix86_veclibabi_type_acml +}; + +#endif diff --git a/src/include/config/i386/i386-protos.h b/src/include/config/i386/i386-protos.h new file mode 100644 index 0000000..602e6fc --- /dev/null +++ b/src/include/config/i386/i386-protos.h @@ -0,0 +1,326 @@ +/* Definitions of target machine for GCC for IA-32. + Copyright (C) 1988-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* In i386-common.c. */ +extern bool ix86_handle_option (struct gcc_options *opts, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc); + +/* Functions in i386.c */ +extern bool ix86_target_stack_probe (void); +extern bool ix86_can_use_return_insn_p (void); +extern void ix86_setup_frame_addresses (void); + +extern HOST_WIDE_INT ix86_initial_elimination_offset (int, int); +extern void ix86_expand_prologue (void); +extern void ix86_maybe_emit_epilogue_vzeroupper (void); +extern void ix86_expand_epilogue (int); +extern void ix86_expand_split_stack_prologue (void); + +extern void ix86_output_addr_vec_elt (FILE *, int); +extern void ix86_output_addr_diff_elt (FILE *, int, int); + +extern enum calling_abi ix86_cfun_abi (void); +extern enum calling_abi ix86_function_type_abi (const_tree); + +#ifdef RTX_CODE +extern int standard_80387_constant_p (rtx); +extern const char *standard_80387_constant_opcode (rtx); +extern rtx standard_80387_constant_rtx (int); +extern int standard_sse_constant_p (rtx); +extern const char *standard_sse_constant_opcode (rtx, rtx); +extern bool symbolic_reference_mentioned_p (rtx); +extern bool extended_reg_mentioned_p (rtx); +extern bool x86_extended_QIreg_mentioned_p (rtx); +extern bool x86_extended_reg_mentioned_p (rtx); +extern bool x86_maybe_negate_const_int (rtx *, enum machine_mode); +extern enum machine_mode ix86_cc_mode (enum rtx_code, rtx, rtx); + +extern int avx_vpermilp_parallel (rtx par, enum machine_mode mode); +extern int avx_vperm2f128_parallel (rtx par, enum machine_mode mode); + +extern bool ix86_expand_movmem (rtx, rtx, rtx, rtx, rtx, rtx); +extern bool ix86_expand_setmem (rtx, rtx, rtx, rtx, rtx, rtx); +extern bool ix86_expand_strlen (rtx, rtx, rtx, rtx); + +extern bool constant_address_p (rtx); +extern bool legitimate_pic_operand_p (rtx); +extern bool legitimate_pic_address_disp_p (rtx); +extern bool ix86_legitimize_reload_address (rtx, enum machine_mode, + int, int, int); +extern void print_reg (rtx, int, FILE*); +extern void ix86_print_operand (FILE *, rtx, int); + +extern void split_double_mode (enum machine_mode, rtx[], int, rtx[], rtx[]); + +extern const char *output_set_got (rtx, rtx); +extern const char *output_387_binary_op (rtx, rtx*); +extern const char *output_387_reg_move (rtx, rtx*); +extern const char *output_fix_trunc (rtx, rtx*, bool); +extern const char *output_fp_compare (rtx, rtx*, bool, bool); +extern const char *output_adjust_stack_and_probe (rtx); +extern const char *output_probe_stack_range (rtx, rtx); + +extern void ix86_expand_clear (rtx); +extern void ix86_expand_move (enum machine_mode, rtx[]); +extern void ix86_expand_vector_move (enum machine_mode, rtx[]); +extern void ix86_expand_vector_move_misalign (enum machine_mode, rtx[]); +extern void ix86_expand_push (enum machine_mode, rtx); +extern rtx ix86_fixup_binary_operands (enum rtx_code, + enum machine_mode, rtx[]); +extern void ix86_fixup_binary_operands_no_copy (enum rtx_code, + enum machine_mode, rtx[]); +extern void ix86_expand_binary_operator (enum rtx_code, + enum machine_mode, rtx[]); +extern void ix86_expand_vector_logical_operator (enum rtx_code, + enum machine_mode, rtx[]); +extern bool ix86_binary_operator_ok (enum rtx_code, enum machine_mode, rtx[]); +extern bool ix86_avoid_lea_for_add (rtx, rtx[]); +extern bool ix86_use_lea_for_mov (rtx, rtx[]); +extern bool ix86_avoid_lea_for_addr (rtx, rtx[]); +extern void ix86_split_lea_for_addr (rtx, rtx[], enum machine_mode); +extern bool ix86_lea_for_add_ok (rtx, rtx[]); +extern bool ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high); +extern bool ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn); +extern bool ix86_agi_dependent (rtx set_insn, rtx use_insn); +extern void ix86_expand_unary_operator (enum rtx_code, enum machine_mode, + rtx[]); +extern rtx ix86_build_const_vector (enum machine_mode, bool, rtx); +extern rtx ix86_build_signbit_mask (enum machine_mode, bool, bool); +extern void ix86_split_convert_uns_si_sse (rtx[]); +extern void ix86_expand_convert_uns_didf_sse (rtx, rtx); +extern void ix86_expand_convert_uns_sixf_sse (rtx, rtx); +extern void ix86_expand_convert_uns_sidf_sse (rtx, rtx); +extern void ix86_expand_convert_uns_sisf_sse (rtx, rtx); +extern void ix86_expand_convert_sign_didf_sse (rtx, rtx); +extern void ix86_expand_vector_convert_uns_vsivsf (rtx, rtx); +extern rtx ix86_expand_adjust_ufix_to_sfix_si (rtx, rtx *); +extern enum ix86_fpcmp_strategy ix86_fp_comparison_strategy (enum rtx_code); +extern void ix86_expand_fp_absneg_operator (enum rtx_code, enum machine_mode, + rtx[]); +extern void ix86_expand_copysign (rtx []); +extern void ix86_split_copysign_const (rtx []); +extern void ix86_split_copysign_var (rtx []); +extern bool ix86_unary_operator_ok (enum rtx_code, enum machine_mode, rtx[]); +extern bool ix86_match_ccmode (rtx, enum machine_mode); +extern void ix86_expand_branch (enum rtx_code, rtx, rtx, rtx); +extern void ix86_expand_setcc (rtx, enum rtx_code, rtx, rtx); +extern bool ix86_expand_int_movcc (rtx[]); +extern bool ix86_expand_fp_movcc (rtx[]); +extern bool ix86_expand_fp_vcond (rtx[]); +extern bool ix86_expand_int_vcond (rtx[]); +extern void ix86_expand_vec_perm (rtx[]); +extern bool ix86_expand_vec_perm_const (rtx[]); +extern void ix86_expand_sse_unpack (rtx, rtx, bool, bool); +extern bool ix86_expand_int_addcc (rtx[]); +extern rtx ix86_expand_call (rtx, rtx, rtx, rtx, rtx, bool); +extern void ix86_split_call_vzeroupper (rtx, rtx); +extern void x86_initialize_trampoline (rtx, rtx, rtx); +extern rtx ix86_zero_extend_to_Pmode (rtx); +extern void ix86_split_long_move (rtx[]); +extern void ix86_split_ashl (rtx *, rtx, enum machine_mode); +extern void ix86_split_ashr (rtx *, rtx, enum machine_mode); +extern void ix86_split_lshr (rtx *, rtx, enum machine_mode); +extern rtx ix86_find_base_term (rtx); +extern bool ix86_check_movabs (rtx, int); +extern void ix86_split_idivmod (enum machine_mode, rtx[], bool); + +extern rtx assign_386_stack_local (enum machine_mode, enum ix86_stack_slot); +extern int ix86_attr_length_immediate_default (rtx, bool); +extern int ix86_attr_length_address_default (rtx); +extern int ix86_attr_length_vex_default (rtx, bool, bool); + +extern enum machine_mode ix86_fp_compare_mode (enum rtx_code); + +extern rtx ix86_libcall_value (enum machine_mode); +extern bool ix86_function_arg_regno_p (int); +extern void ix86_asm_output_function_label (FILE *, const char *, tree); +extern rtx ix86_force_to_memory (enum machine_mode, rtx); +extern void ix86_free_from_memory (enum machine_mode); +extern void ix86_call_abi_override (const_tree); +extern int ix86_reg_parm_stack_space (const_tree); + +extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx, + rtx, rtx, rtx, rtx); +extern bool ix86_hard_regno_mode_ok (int, enum machine_mode); +extern bool ix86_modes_tieable_p (enum machine_mode, enum machine_mode); +extern bool ix86_secondary_memory_needed (enum reg_class, enum reg_class, + enum machine_mode, int); +extern bool ix86_cannot_change_mode_class (enum machine_mode, + enum machine_mode, enum reg_class); + +extern int ix86_mode_needed (int, rtx); +extern int ix86_mode_after (int, int, rtx); +extern int ix86_mode_entry (int); +extern int ix86_mode_exit (int); + +#ifdef HARD_CONST +extern void ix86_emit_mode_set (int, int, HARD_REG_SET); +#endif + +extern void x86_order_regs_for_local_alloc (void); +extern void x86_function_profiler (FILE *, int); +extern void x86_emit_floatuns (rtx [2]); +extern void ix86_emit_fp_unordered_jump (rtx); + +extern void ix86_emit_i387_log1p (rtx, rtx); +extern void ix86_emit_i387_round (rtx, rtx); +extern void ix86_emit_swdivsf (rtx, rtx, rtx, enum machine_mode); +extern void ix86_emit_swsqrtsf (rtx, rtx, enum machine_mode, bool); + +extern enum rtx_code ix86_reverse_condition (enum rtx_code, enum machine_mode); + +extern void ix86_expand_lround (rtx, rtx); +extern void ix86_expand_lfloorceil (rtx, rtx, bool); +extern void ix86_expand_rint (rtx, rtx); +extern void ix86_expand_floorceil (rtx, rtx, bool); +extern void ix86_expand_floorceildf_32 (rtx, rtx, bool); +extern void ix86_expand_round_sse4 (rtx, rtx); +extern void ix86_expand_round (rtx, rtx); +extern void ix86_expand_rounddf_32 (rtx, rtx); +extern void ix86_expand_trunc (rtx, rtx); +extern void ix86_expand_truncdf_32 (rtx, rtx); + +extern void ix86_expand_vecop_qihi (enum rtx_code, rtx, rtx, rtx); + +#ifdef TREE_CODE +extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int); +#endif /* TREE_CODE */ + +#endif /* RTX_CODE */ + +#ifdef TREE_CODE +extern int ix86_data_alignment (tree, int); +extern unsigned int ix86_local_alignment (tree, enum machine_mode, + unsigned int); +extern unsigned int ix86_minimum_alignment (tree, enum machine_mode, + unsigned int); +extern int ix86_constant_alignment (tree, int); +extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *); +extern tree ix86_handle_selectany_attribute (tree *, tree, tree, int, bool *); +extern int x86_field_alignment (tree, int); +extern tree ix86_valid_target_attribute_tree (tree); +extern unsigned int ix86_get_callcvt (const_tree); + +#endif + +extern rtx ix86_tls_module_base (void); + +extern void ix86_expand_vector_init (bool, rtx, rtx); +extern void ix86_expand_vector_set (bool, rtx, rtx, int); +extern void ix86_expand_vector_extract (bool, rtx, rtx, int); +extern void ix86_expand_reduc (rtx (*)(rtx, rtx, rtx), rtx, rtx); + +extern void ix86_expand_vec_extract_even_odd (rtx, rtx, rtx, unsigned); +extern bool ix86_expand_pinsr (rtx *); +extern void ix86_expand_mul_widen_evenodd (rtx, rtx, rtx, bool, bool); +extern void ix86_expand_mul_widen_hilo (rtx, rtx, rtx, bool, bool); +extern void ix86_expand_sse2_mulv4si3 (rtx, rtx, rtx); +extern void ix86_expand_sse2_mulvxdi3 (rtx, rtx, rtx); + +/* In i386-c.c */ +extern void ix86_target_macros (void); +extern void ix86_register_pragmas (void); + +/* In winnt.c */ +extern void i386_pe_unique_section (tree, int); +extern void i386_pe_declare_function_type (FILE *, const char *, int); +extern void i386_pe_record_external_function (tree, const char *); +extern void i386_pe_maybe_record_exported_symbol (tree, const char *, int); +extern void i386_pe_encode_section_info (tree, rtx, int); +extern bool i386_pe_binds_local_p (const_tree); +extern const char *i386_pe_strip_name_encoding_full (const char *); +extern bool i386_pe_valid_dllimport_attribute_p (const_tree); +extern unsigned int i386_pe_section_type_flags (tree, const char *, int); +extern void i386_pe_asm_named_section (const char *, unsigned int, tree); +extern void i386_pe_asm_output_aligned_decl_common (FILE *, tree, + const char *, + HOST_WIDE_INT, + HOST_WIDE_INT); +extern void i386_pe_file_end (void); +extern void i386_pe_start_function (FILE *, const char *, tree); +extern void i386_pe_end_function (FILE *, const char *, tree); +extern void i386_pe_assemble_visibility (tree, int); +extern tree i386_pe_mangle_decl_assembler_name (tree, tree); +extern tree i386_pe_mangle_assembler_name (const char *); + +extern void i386_pe_seh_init (FILE *); +extern void i386_pe_seh_end_prologue (FILE *); +extern void i386_pe_seh_unwind_emit (FILE *, rtx); +extern void i386_pe_seh_emit_except_personality (rtx); +extern void i386_pe_seh_init_sections (void); + +/* In winnt-cxx.c and winnt-stubs.c */ +extern void i386_pe_adjust_class_at_definition (tree); +extern bool i386_pe_type_dllimport_p (tree); +extern bool i386_pe_type_dllexport_p (tree); + +extern int i386_pe_reloc_rw_mask (void); + +extern rtx maybe_get_pool_constant (rtx); + +extern char internal_label_prefix[16]; +extern int internal_label_prefix_len; + +enum ix86_address_seg { SEG_DEFAULT, SEG_FS, SEG_GS }; +struct ix86_address +{ + rtx base, index, disp; + HOST_WIDE_INT scale; + enum ix86_address_seg seg; +}; + +extern int ix86_decompose_address (rtx, struct ix86_address *); +extern int memory_address_length (rtx, bool); +extern void x86_output_aligned_bss (FILE *, tree, const char *, + unsigned HOST_WIDE_INT, int); +extern void x86_elf_aligned_common (FILE *, const char *, + unsigned HOST_WIDE_INT, int); + +#ifdef RTX_CODE +extern void ix86_fp_comparison_codes (enum rtx_code code, enum rtx_code *, + enum rtx_code *, enum rtx_code *); +extern enum rtx_code ix86_fp_compare_code_to_integer (enum rtx_code); +#endif +extern int asm_preferred_eh_data_format (int, int); + +#ifdef HAVE_ATTR_cpu +extern enum attr_cpu ix86_schedule; +#endif + +extern const char * ix86_output_call_insn (rtx insn, rtx call_op); + +#ifdef RTX_CODE +/* Target data for multipass lookahead scheduling. + Currently used for Core 2/i7 tuning. */ +struct ix86_first_cycle_multipass_data_ +{ + /* The length (in bytes) of ifetch block in this solution. */ + int ifetch_block_len; + /* Number of instructions in ifetch block in this solution. */ + int ifetch_block_n_insns; + /* Bitmap to remember changes to ready_try for backtracking. */ + sbitmap ready_try_change; + /* Size of the bitmap. */ + int ready_try_change_size; +}; +# define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DATA_T \ + struct ix86_first_cycle_multipass_data_ +#endif /* RTX_CODE */ diff --git a/src/include/config/i386/i386.h b/src/include/config/i386/i386.h new file mode 100644 index 0000000..335cf61 --- /dev/null +++ b/src/include/config/i386/i386.h @@ -0,0 +1,2390 @@ +/* Definitions of target machine for GCC for IA-32. + Copyright (C) 1988-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* The purpose of this file is to define the characteristics of the i386, + independent of assembler syntax or operating system. + + Three other files build on this one to describe a specific assembler syntax: + bsd386.h, att386.h, and sun386.h. + + The actual tm.h file for a particular system should include + this file, and then the file for the appropriate assembler syntax. + + Many macros that specify assembler syntax are omitted entirely from + this file because they really belong in the files for particular + assemblers. These include RP, IP, LPREFIX, PUT_OP_SIZE, USE_STAR, + ADDR_BEG, ADDR_END, PRINT_IREG, PRINT_SCALE, PRINT_B_I_S, and many + that start with ASM_ or end in ASM_OP. */ + +/* Redefines for option macros. */ + +#define TARGET_64BIT TARGET_ISA_64BIT +#define TARGET_MMX TARGET_ISA_MMX +#define TARGET_3DNOW TARGET_ISA_3DNOW +#define TARGET_3DNOW_A TARGET_ISA_3DNOW_A +#define TARGET_SSE TARGET_ISA_SSE +#define TARGET_SSE2 TARGET_ISA_SSE2 +#define TARGET_SSE3 TARGET_ISA_SSE3 +#define TARGET_SSSE3 TARGET_ISA_SSSE3 +#define TARGET_SSE4_1 TARGET_ISA_SSE4_1 +#define TARGET_SSE4_2 TARGET_ISA_SSE4_2 +#define TARGET_AVX TARGET_ISA_AVX +#define TARGET_AVX2 TARGET_ISA_AVX2 +#define TARGET_FMA TARGET_ISA_FMA +#define TARGET_SSE4A TARGET_ISA_SSE4A +#define TARGET_FMA4 TARGET_ISA_FMA4 +#define TARGET_XOP TARGET_ISA_XOP +#define TARGET_LWP TARGET_ISA_LWP +#define TARGET_ROUND TARGET_ISA_ROUND +#define TARGET_ABM TARGET_ISA_ABM +#define TARGET_BMI TARGET_ISA_BMI +#define TARGET_BMI2 TARGET_ISA_BMI2 +#define TARGET_LZCNT TARGET_ISA_LZCNT +#define TARGET_TBM TARGET_ISA_TBM +#define TARGET_POPCNT TARGET_ISA_POPCNT +#define TARGET_SAHF TARGET_ISA_SAHF +#define TARGET_MOVBE TARGET_ISA_MOVBE +#define TARGET_CRC32 TARGET_ISA_CRC32 +#define TARGET_AES TARGET_ISA_AES +#define TARGET_PCLMUL TARGET_ISA_PCLMUL +#define TARGET_CMPXCHG16B TARGET_ISA_CX16 +#define TARGET_FSGSBASE TARGET_ISA_FSGSBASE +#define TARGET_RDRND TARGET_ISA_RDRND +#define TARGET_F16C TARGET_ISA_F16C +#define TARGET_RTM TARGET_ISA_RTM +#define TARGET_HLE TARGET_ISA_HLE +#define TARGET_RDSEED TARGET_ISA_RDSEED +#define TARGET_PRFCHW TARGET_ISA_PRFCHW +#define TARGET_ADX TARGET_ISA_ADX +#define TARGET_FXSR TARGET_ISA_FXSR +#define TARGET_XSAVE TARGET_ISA_XSAVE +#define TARGET_XSAVEOPT TARGET_ISA_XSAVEOPT + +#define TARGET_LP64 TARGET_ABI_64 +#define TARGET_X32 TARGET_ABI_X32 + +/* SSE4.1 defines round instructions */ +#define OPTION_MASK_ISA_ROUND OPTION_MASK_ISA_SSE4_1 +#define TARGET_ISA_ROUND ((ix86_isa_flags & OPTION_MASK_ISA_ROUND) != 0) + +#include "config/vxworks-dummy.h" + +#include "config/i386/i386-opts.h" + +#define MAX_STRINGOP_ALGS 4 + +/* Specify what algorithm to use for stringops on known size. + When size is unknown, the UNKNOWN_SIZE alg is used. When size is + known at compile time or estimated via feedback, the SIZE array + is walked in order until MAX is greater then the estimate (or -1 + means infinity). Corresponding ALG is used then. + When NOALIGN is true the code guaranting the alignment of the memory + block is skipped. + + For example initializer: + {{256, loop}, {-1, rep_prefix_4_byte}} + will use loop for blocks smaller or equal to 256 bytes, rep prefix will + be used otherwise. */ +struct stringop_algs +{ + const enum stringop_alg unknown_size; + const struct stringop_strategy { + const int max; + const enum stringop_alg alg; + int noalign; + } size [MAX_STRINGOP_ALGS]; +}; + +/* Define the specific costs for a given cpu */ + +struct processor_costs { + const int add; /* cost of an add instruction */ + const int lea; /* cost of a lea instruction */ + const int shift_var; /* variable shift costs */ + const int shift_const; /* constant shift costs */ + const int mult_init[5]; /* cost of starting a multiply + in QImode, HImode, SImode, DImode, TImode*/ + const int mult_bit; /* cost of multiply per each bit set */ + const int divide[5]; /* cost of a divide/mod + in QImode, HImode, SImode, DImode, TImode*/ + int movsx; /* The cost of movsx operation. */ + int movzx; /* The cost of movzx operation. */ + const int large_insn; /* insns larger than this cost more */ + const int move_ratio; /* The threshold of number of scalar + memory-to-memory move insns. */ + const int movzbl_load; /* cost of loading using movzbl */ + const int int_load[3]; /* cost of loading integer registers + in QImode, HImode and SImode relative + to reg-reg move (2). */ + const int int_store[3]; /* cost of storing integer register + in QImode, HImode and SImode */ + const int fp_move; /* cost of reg,reg fld/fst */ + const int fp_load[3]; /* cost of loading FP register + in SFmode, DFmode and XFmode */ + const int fp_store[3]; /* cost of storing FP register + in SFmode, DFmode and XFmode */ + const int mmx_move; /* cost of moving MMX register. */ + const int mmx_load[2]; /* cost of loading MMX register + in SImode and DImode */ + const int mmx_store[2]; /* cost of storing MMX register + in SImode and DImode */ + const int sse_move; /* cost of moving SSE register. */ + const int sse_load[3]; /* cost of loading SSE register + in SImode, DImode and TImode*/ + const int sse_store[3]; /* cost of storing SSE register + in SImode, DImode and TImode*/ + const int mmxsse_to_integer; /* cost of moving mmxsse register to + integer and vice versa. */ + const int l1_cache_size; /* size of l1 cache, in kilobytes. */ + const int l2_cache_size; /* size of l2 cache, in kilobytes. */ + const int prefetch_block; /* bytes moved to cache for prefetch. */ + const int simultaneous_prefetches; /* number of parallel prefetch + operations. */ + const int branch_cost; /* Default value for BRANCH_COST. */ + const int fadd; /* cost of FADD and FSUB instructions. */ + const int fmul; /* cost of FMUL instruction. */ + const int fdiv; /* cost of FDIV instruction. */ + const int fabs; /* cost of FABS instruction. */ + const int fchs; /* cost of FCHS instruction. */ + const int fsqrt; /* cost of FSQRT instruction. */ + /* Specify what algorithm + to use for stringops on unknown size. */ + struct stringop_algs memcpy[2], memset[2]; + const int scalar_stmt_cost; /* Cost of any scalar operation, excluding + load and store. */ + const int scalar_load_cost; /* Cost of scalar load. */ + const int scalar_store_cost; /* Cost of scalar store. */ + const int vec_stmt_cost; /* Cost of any vector operation, excluding + load, store, vector-to-scalar and + scalar-to-vector operation. */ + const int vec_to_scalar_cost; /* Cost of vect-to-scalar operation. */ + const int scalar_to_vec_cost; /* Cost of scalar-to-vector operation. */ + const int vec_align_load_cost; /* Cost of aligned vector load. */ + const int vec_unalign_load_cost; /* Cost of unaligned vector load. */ + const int vec_store_cost; /* Cost of vector store. */ + const int cond_taken_branch_cost; /* Cost of taken branch for vectorizer + cost model. */ + const int cond_not_taken_branch_cost;/* Cost of not taken branch for + vectorizer cost model. */ +}; + +extern const struct processor_costs *ix86_cost; +extern const struct processor_costs ix86_size_cost; + +#define ix86_cur_cost() \ + (optimize_insn_for_size_p () ? &ix86_size_cost: ix86_cost) + +/* Macros used in the machine description to test the flags. */ + +/* configure can arrange to change it. */ + +#ifndef TARGET_CPU_DEFAULT +#define TARGET_CPU_DEFAULT PROCESSOR_GENERIC32 +#endif + +#ifndef TARGET_FPMATH_DEFAULT +#define TARGET_FPMATH_DEFAULT \ + (TARGET_64BIT && TARGET_SSE ? FPMATH_SSE : FPMATH_387) +#endif + +#define TARGET_FLOAT_RETURNS_IN_80387 TARGET_FLOAT_RETURNS + +/* 64bit Sledgehammer mode. For libgcc2 we make sure this is a + compile-time constant. */ +#ifdef IN_LIBGCC2 +#undef TARGET_64BIT +#ifdef __x86_64__ +#define TARGET_64BIT 1 +#else +#define TARGET_64BIT 0 +#endif +#else +#ifndef TARGET_BI_ARCH +#undef TARGET_64BIT +#if TARGET_64BIT_DEFAULT +#define TARGET_64BIT 1 +#else +#define TARGET_64BIT 0 +#endif +#endif +#endif + +#define HAS_LONG_COND_BRANCH 1 +#define HAS_LONG_UNCOND_BRANCH 1 + +#define TARGET_386 (ix86_tune == PROCESSOR_I386) +#define TARGET_486 (ix86_tune == PROCESSOR_I486) +#define TARGET_PENTIUM (ix86_tune == PROCESSOR_PENTIUM) +#define TARGET_PENTIUMPRO (ix86_tune == PROCESSOR_PENTIUMPRO) +#define TARGET_GEODE (ix86_tune == PROCESSOR_GEODE) +#define TARGET_K6 (ix86_tune == PROCESSOR_K6) +#define TARGET_ATHLON (ix86_tune == PROCESSOR_ATHLON) +#define TARGET_PENTIUM4 (ix86_tune == PROCESSOR_PENTIUM4) +#define TARGET_K8 (ix86_tune == PROCESSOR_K8) +#define TARGET_ATHLON_K8 (TARGET_K8 || TARGET_ATHLON) +#define TARGET_NOCONA (ix86_tune == PROCESSOR_NOCONA) +#define TARGET_CORE2 (ix86_tune == PROCESSOR_CORE2) +#define TARGET_COREI7 (ix86_tune == PROCESSOR_COREI7) +#define TARGET_HASWELL (ix86_tune == PROCESSOR_HASWELL) +#define TARGET_GENERIC32 (ix86_tune == PROCESSOR_GENERIC32) +#define TARGET_GENERIC64 (ix86_tune == PROCESSOR_GENERIC64) +#define TARGET_GENERIC (TARGET_GENERIC32 || TARGET_GENERIC64) +#define TARGET_AMDFAM10 (ix86_tune == PROCESSOR_AMDFAM10) +#define TARGET_BDVER1 (ix86_tune == PROCESSOR_BDVER1) +#define TARGET_BDVER2 (ix86_tune == PROCESSOR_BDVER2) +#define TARGET_BDVER3 (ix86_tune == PROCESSOR_BDVER3) +#define TARGET_BTVER1 (ix86_tune == PROCESSOR_BTVER1) +#define TARGET_BTVER2 (ix86_tune == PROCESSOR_BTVER2) +#define TARGET_ATOM (ix86_tune == PROCESSOR_ATOM) + +/* Feature tests against the various tunings. */ +enum ix86_tune_indices { + X86_TUNE_USE_LEAVE, + X86_TUNE_PUSH_MEMORY, + X86_TUNE_ZERO_EXTEND_WITH_AND, + X86_TUNE_UNROLL_STRLEN, + X86_TUNE_BRANCH_PREDICTION_HINTS, + X86_TUNE_DOUBLE_WITH_ADD, + X86_TUNE_USE_SAHF, + X86_TUNE_MOVX, + X86_TUNE_PARTIAL_REG_STALL, + X86_TUNE_PARTIAL_FLAG_REG_STALL, + X86_TUNE_LCP_STALL, + X86_TUNE_USE_HIMODE_FIOP, + X86_TUNE_USE_SIMODE_FIOP, + X86_TUNE_USE_MOV0, + X86_TUNE_USE_CLTD, + X86_TUNE_USE_XCHGB, + X86_TUNE_SPLIT_LONG_MOVES, + X86_TUNE_READ_MODIFY_WRITE, + X86_TUNE_READ_MODIFY, + X86_TUNE_PROMOTE_QIMODE, + X86_TUNE_FAST_PREFIX, + X86_TUNE_SINGLE_STRINGOP, + X86_TUNE_QIMODE_MATH, + X86_TUNE_HIMODE_MATH, + X86_TUNE_PROMOTE_QI_REGS, + X86_TUNE_PROMOTE_HI_REGS, + X86_TUNE_SINGLE_POP, + X86_TUNE_DOUBLE_POP, + X86_TUNE_SINGLE_PUSH, + X86_TUNE_DOUBLE_PUSH, + X86_TUNE_INTEGER_DFMODE_MOVES, + X86_TUNE_PARTIAL_REG_DEPENDENCY, + X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY, + X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL, + X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL, + X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL, + X86_TUNE_SSE_SPLIT_REGS, + X86_TUNE_SSE_TYPELESS_STORES, + X86_TUNE_SSE_LOAD0_BY_PXOR, + X86_TUNE_MEMORY_MISMATCH_STALL, + X86_TUNE_PROLOGUE_USING_MOVE, + X86_TUNE_EPILOGUE_USING_MOVE, + X86_TUNE_SHIFT1, + X86_TUNE_USE_FFREEP, + X86_TUNE_INTER_UNIT_MOVES, + X86_TUNE_INTER_UNIT_CONVERSIONS, + X86_TUNE_FOUR_JUMP_LIMIT, + X86_TUNE_SCHEDULE, + X86_TUNE_USE_BT, + X86_TUNE_USE_INCDEC, + X86_TUNE_PAD_RETURNS, + X86_TUNE_PAD_SHORT_FUNCTION, + X86_TUNE_EXT_80387_CONSTANTS, + X86_TUNE_AVOID_VECTOR_DECODE, + X86_TUNE_PROMOTE_HIMODE_IMUL, + X86_TUNE_SLOW_IMUL_IMM32_MEM, + X86_TUNE_SLOW_IMUL_IMM8, + X86_TUNE_MOVE_M1_VIA_OR, + X86_TUNE_NOT_UNPAIRABLE, + X86_TUNE_NOT_VECTORMODE, + X86_TUNE_USE_VECTOR_FP_CONVERTS, + X86_TUNE_USE_VECTOR_CONVERTS, + X86_TUNE_FUSE_CMP_AND_BRANCH, + X86_TUNE_OPT_AGU, + X86_TUNE_VECTORIZE_DOUBLE, + X86_TUNE_SOFTWARE_PREFETCHING_BENEFICIAL, + X86_TUNE_AVX128_OPTIMAL, + X86_TUNE_REASSOC_INT_TO_PARALLEL, + X86_TUNE_REASSOC_FP_TO_PARALLEL, + X86_TUNE_GENERAL_REGS_SSE_SPILL, + X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE, + + X86_TUNE_LAST +}; + +extern unsigned char ix86_tune_features[X86_TUNE_LAST]; + +#define TARGET_USE_LEAVE ix86_tune_features[X86_TUNE_USE_LEAVE] +#define TARGET_PUSH_MEMORY ix86_tune_features[X86_TUNE_PUSH_MEMORY] +#define TARGET_ZERO_EXTEND_WITH_AND \ + ix86_tune_features[X86_TUNE_ZERO_EXTEND_WITH_AND] +#define TARGET_UNROLL_STRLEN ix86_tune_features[X86_TUNE_UNROLL_STRLEN] +#define TARGET_BRANCH_PREDICTION_HINTS \ + ix86_tune_features[X86_TUNE_BRANCH_PREDICTION_HINTS] +#define TARGET_DOUBLE_WITH_ADD ix86_tune_features[X86_TUNE_DOUBLE_WITH_ADD] +#define TARGET_USE_SAHF ix86_tune_features[X86_TUNE_USE_SAHF] +#define TARGET_MOVX ix86_tune_features[X86_TUNE_MOVX] +#define TARGET_PARTIAL_REG_STALL ix86_tune_features[X86_TUNE_PARTIAL_REG_STALL] +#define TARGET_PARTIAL_FLAG_REG_STALL \ + ix86_tune_features[X86_TUNE_PARTIAL_FLAG_REG_STALL] +#define TARGET_LCP_STALL \ + ix86_tune_features[X86_TUNE_LCP_STALL] +#define TARGET_USE_HIMODE_FIOP ix86_tune_features[X86_TUNE_USE_HIMODE_FIOP] +#define TARGET_USE_SIMODE_FIOP ix86_tune_features[X86_TUNE_USE_SIMODE_FIOP] +#define TARGET_USE_MOV0 ix86_tune_features[X86_TUNE_USE_MOV0] +#define TARGET_USE_CLTD ix86_tune_features[X86_TUNE_USE_CLTD] +#define TARGET_USE_XCHGB ix86_tune_features[X86_TUNE_USE_XCHGB] +#define TARGET_SPLIT_LONG_MOVES ix86_tune_features[X86_TUNE_SPLIT_LONG_MOVES] +#define TARGET_READ_MODIFY_WRITE ix86_tune_features[X86_TUNE_READ_MODIFY_WRITE] +#define TARGET_READ_MODIFY ix86_tune_features[X86_TUNE_READ_MODIFY] +#define TARGET_PROMOTE_QImode ix86_tune_features[X86_TUNE_PROMOTE_QIMODE] +#define TARGET_FAST_PREFIX ix86_tune_features[X86_TUNE_FAST_PREFIX] +#define TARGET_SINGLE_STRINGOP ix86_tune_features[X86_TUNE_SINGLE_STRINGOP] +#define TARGET_QIMODE_MATH ix86_tune_features[X86_TUNE_QIMODE_MATH] +#define TARGET_HIMODE_MATH ix86_tune_features[X86_TUNE_HIMODE_MATH] +#define TARGET_PROMOTE_QI_REGS ix86_tune_features[X86_TUNE_PROMOTE_QI_REGS] +#define TARGET_PROMOTE_HI_REGS ix86_tune_features[X86_TUNE_PROMOTE_HI_REGS] +#define TARGET_SINGLE_POP ix86_tune_features[X86_TUNE_SINGLE_POP] +#define TARGET_DOUBLE_POP ix86_tune_features[X86_TUNE_DOUBLE_POP] +#define TARGET_SINGLE_PUSH ix86_tune_features[X86_TUNE_SINGLE_PUSH] +#define TARGET_DOUBLE_PUSH ix86_tune_features[X86_TUNE_DOUBLE_PUSH] +#define TARGET_INTEGER_DFMODE_MOVES \ + ix86_tune_features[X86_TUNE_INTEGER_DFMODE_MOVES] +#define TARGET_PARTIAL_REG_DEPENDENCY \ + ix86_tune_features[X86_TUNE_PARTIAL_REG_DEPENDENCY] +#define TARGET_SSE_PARTIAL_REG_DEPENDENCY \ + ix86_tune_features[X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY] +#define TARGET_SSE_UNALIGNED_LOAD_OPTIMAL \ + ix86_tune_features[X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL] +#define TARGET_SSE_UNALIGNED_STORE_OPTIMAL \ + ix86_tune_features[X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL] +#define TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL \ + ix86_tune_features[X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL] +#define TARGET_SSE_SPLIT_REGS ix86_tune_features[X86_TUNE_SSE_SPLIT_REGS] +#define TARGET_SSE_TYPELESS_STORES \ + ix86_tune_features[X86_TUNE_SSE_TYPELESS_STORES] +#define TARGET_SSE_LOAD0_BY_PXOR ix86_tune_features[X86_TUNE_SSE_LOAD0_BY_PXOR] +#define TARGET_MEMORY_MISMATCH_STALL \ + ix86_tune_features[X86_TUNE_MEMORY_MISMATCH_STALL] +#define TARGET_PROLOGUE_USING_MOVE \ + ix86_tune_features[X86_TUNE_PROLOGUE_USING_MOVE] +#define TARGET_EPILOGUE_USING_MOVE \ + ix86_tune_features[X86_TUNE_EPILOGUE_USING_MOVE] +#define TARGET_SHIFT1 ix86_tune_features[X86_TUNE_SHIFT1] +#define TARGET_USE_FFREEP ix86_tune_features[X86_TUNE_USE_FFREEP] +#define TARGET_INTER_UNIT_MOVES ix86_tune_features[X86_TUNE_INTER_UNIT_MOVES] +#define TARGET_INTER_UNIT_CONVERSIONS\ + ix86_tune_features[X86_TUNE_INTER_UNIT_CONVERSIONS] +#define TARGET_FOUR_JUMP_LIMIT ix86_tune_features[X86_TUNE_FOUR_JUMP_LIMIT] +#define TARGET_SCHEDULE ix86_tune_features[X86_TUNE_SCHEDULE] +#define TARGET_USE_BT ix86_tune_features[X86_TUNE_USE_BT] +#define TARGET_USE_INCDEC ix86_tune_features[X86_TUNE_USE_INCDEC] +#define TARGET_PAD_RETURNS ix86_tune_features[X86_TUNE_PAD_RETURNS] +#define TARGET_PAD_SHORT_FUNCTION \ + ix86_tune_features[X86_TUNE_PAD_SHORT_FUNCTION] +#define TARGET_EXT_80387_CONSTANTS \ + ix86_tune_features[X86_TUNE_EXT_80387_CONSTANTS] +#define TARGET_AVOID_VECTOR_DECODE \ + ix86_tune_features[X86_TUNE_AVOID_VECTOR_DECODE] +#define TARGET_TUNE_PROMOTE_HIMODE_IMUL \ + ix86_tune_features[X86_TUNE_PROMOTE_HIMODE_IMUL] +#define TARGET_SLOW_IMUL_IMM32_MEM \ + ix86_tune_features[X86_TUNE_SLOW_IMUL_IMM32_MEM] +#define TARGET_SLOW_IMUL_IMM8 ix86_tune_features[X86_TUNE_SLOW_IMUL_IMM8] +#define TARGET_MOVE_M1_VIA_OR ix86_tune_features[X86_TUNE_MOVE_M1_VIA_OR] +#define TARGET_NOT_UNPAIRABLE ix86_tune_features[X86_TUNE_NOT_UNPAIRABLE] +#define TARGET_NOT_VECTORMODE ix86_tune_features[X86_TUNE_NOT_VECTORMODE] +#define TARGET_USE_VECTOR_FP_CONVERTS \ + ix86_tune_features[X86_TUNE_USE_VECTOR_FP_CONVERTS] +#define TARGET_USE_VECTOR_CONVERTS \ + ix86_tune_features[X86_TUNE_USE_VECTOR_CONVERTS] +#define TARGET_FUSE_CMP_AND_BRANCH \ + ix86_tune_features[X86_TUNE_FUSE_CMP_AND_BRANCH] +#define TARGET_OPT_AGU ix86_tune_features[X86_TUNE_OPT_AGU] +#define TARGET_VECTORIZE_DOUBLE \ + ix86_tune_features[X86_TUNE_VECTORIZE_DOUBLE] +#define TARGET_SOFTWARE_PREFETCHING_BENEFICIAL \ + ix86_tune_features[X86_TUNE_SOFTWARE_PREFETCHING_BENEFICIAL] +#define TARGET_AVX128_OPTIMAL \ + ix86_tune_features[X86_TUNE_AVX128_OPTIMAL] +#define TARGET_REASSOC_INT_TO_PARALLEL \ + ix86_tune_features[X86_TUNE_REASSOC_INT_TO_PARALLEL] +#define TARGET_REASSOC_FP_TO_PARALLEL \ + ix86_tune_features[X86_TUNE_REASSOC_FP_TO_PARALLEL] +#define TARGET_GENERAL_REGS_SSE_SPILL \ + ix86_tune_features[X86_TUNE_GENERAL_REGS_SSE_SPILL] +#define TARGET_AVOID_MEM_OPND_FOR_CMOVE \ + ix86_tune_features[X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE] + +/* Feature tests against the various architecture variations. */ +enum ix86_arch_indices { + X86_ARCH_CMOV, + X86_ARCH_CMPXCHG, + X86_ARCH_CMPXCHG8B, + X86_ARCH_XADD, + X86_ARCH_BSWAP, + + X86_ARCH_LAST +}; + +extern unsigned char ix86_arch_features[X86_ARCH_LAST]; + +#define TARGET_CMOV ix86_arch_features[X86_ARCH_CMOV] +#define TARGET_CMPXCHG ix86_arch_features[X86_ARCH_CMPXCHG] +#define TARGET_CMPXCHG8B ix86_arch_features[X86_ARCH_CMPXCHG8B] +#define TARGET_XADD ix86_arch_features[X86_ARCH_XADD] +#define TARGET_BSWAP ix86_arch_features[X86_ARCH_BSWAP] + +/* For sane SSE instruction set generation we need fcomi instruction. + It is safe to enable all CMOVE instructions. Also, RDRAND intrinsic + expands to a sequence that includes conditional move. */ +#define TARGET_CMOVE (TARGET_CMOV || TARGET_SSE || TARGET_RDRND) + +#define TARGET_FISTTP (TARGET_SSE3 && TARGET_80387) + +extern unsigned char x86_prefetch_sse; +#define TARGET_PREFETCH_SSE x86_prefetch_sse + +#define ASSEMBLER_DIALECT (ix86_asm_dialect) + +#define TARGET_SSE_MATH ((ix86_fpmath & FPMATH_SSE) != 0) +#define TARGET_MIX_SSE_I387 \ + ((ix86_fpmath & (FPMATH_SSE | FPMATH_387)) == (FPMATH_SSE | FPMATH_387)) + +#define TARGET_GNU_TLS (ix86_tls_dialect == TLS_DIALECT_GNU) +#define TARGET_GNU2_TLS (ix86_tls_dialect == TLS_DIALECT_GNU2) +#define TARGET_ANY_GNU_TLS (TARGET_GNU_TLS || TARGET_GNU2_TLS) +#define TARGET_SUN_TLS 0 + +#ifndef TARGET_64BIT_DEFAULT +#define TARGET_64BIT_DEFAULT 0 +#endif +#ifndef TARGET_TLS_DIRECT_SEG_REFS_DEFAULT +#define TARGET_TLS_DIRECT_SEG_REFS_DEFAULT 0 +#endif + +/* Fence to use after loop using storent. */ + +extern tree x86_mfence; +#define FENCE_FOLLOWING_MOVNT x86_mfence + +/* Once GDB has been enhanced to deal with functions without frame + pointers, we can change this to allow for elimination of + the frame pointer in leaf functions. */ +#define TARGET_DEFAULT 0 + +/* Extra bits to force. */ +#define TARGET_SUBTARGET_DEFAULT 0 +#define TARGET_SUBTARGET_ISA_DEFAULT 0 + +/* Extra bits to force on w/ 32-bit mode. */ +#define TARGET_SUBTARGET32_DEFAULT 0 +#define TARGET_SUBTARGET32_ISA_DEFAULT 0 + +/* Extra bits to force on w/ 64-bit mode. */ +#define TARGET_SUBTARGET64_DEFAULT 0 +#define TARGET_SUBTARGET64_ISA_DEFAULT 0 + +/* Replace MACH-O, ifdefs by in-line tests, where possible. + (a) Macros defined in config/i386/darwin.h */ +#define TARGET_MACHO 0 +#define TARGET_MACHO_BRANCH_ISLANDS 0 +#define MACHOPIC_ATT_STUB 0 +/* (b) Macros defined in config/darwin.h */ +#define MACHO_DYNAMIC_NO_PIC_P 0 +#define MACHOPIC_INDIRECT 0 +#define MACHOPIC_PURE 0 + +/* For the RDOS */ +#define TARGET_RDOS 0 + +/* For the Windows 64-bit ABI. */ +#define TARGET_64BIT_MS_ABI (TARGET_64BIT && ix86_cfun_abi () == MS_ABI) + +/* For the Windows 32-bit ABI. */ +#define TARGET_32BIT_MS_ABI (!TARGET_64BIT && ix86_cfun_abi () == MS_ABI) + +/* This is re-defined by cygming.h. */ +#define TARGET_SEH 0 + +/* The default abi used by target. */ +#define DEFAULT_ABI SYSV_ABI + +/* Subtargets may reset this to 1 in order to enable 96-bit long double + with the rounding mode forced to 53 bits. */ +#define TARGET_96_ROUND_53_LONG_DOUBLE 0 + +/* -march=native handling only makes sense with compiler running on + an x86 or x86_64 chip. If changing this condition, also change + the condition in driver-i386.c. */ +#if defined(__i386__) || defined(__x86_64__) +/* In driver-i386.c. */ +extern const char *host_detect_local_cpu (int argc, const char **argv); +#define EXTRA_SPEC_FUNCTIONS \ + { "local_cpu_detect", host_detect_local_cpu }, +#define HAVE_LOCAL_CPU_DETECT +#endif + +#if TARGET_64BIT_DEFAULT +#define OPT_ARCH64 "!m32" +#define OPT_ARCH32 "m32" +#else +#define OPT_ARCH64 "m64|mx32" +#define OPT_ARCH32 "m64|mx32:;" +#endif + +/* Support for configure-time defaults of some command line options. + The order here is important so that -march doesn't squash the + tune or cpu values. */ +#define OPTION_DEFAULT_SPECS \ + {"tune", "%{!mtune=*:%{!mcpu=*:%{!march=*:-mtune=%(VALUE)}}}" }, \ + {"tune_32", "%{" OPT_ARCH32 ":%{!mtune=*:%{!mcpu=*:%{!march=*:-mtune=%(VALUE)}}}}" }, \ + {"tune_64", "%{" OPT_ARCH64 ":%{!mtune=*:%{!mcpu=*:%{!march=*:-mtune=%(VALUE)}}}}" }, \ + {"cpu", "%{!mtune=*:%{!mcpu=*:%{!march=*:-mtune=%(VALUE)}}}" }, \ + {"cpu_32", "%{" OPT_ARCH32 ":%{!mtune=*:%{!mcpu=*:%{!march=*:-mtune=%(VALUE)}}}}" }, \ + {"cpu_64", "%{" OPT_ARCH64 ":%{!mtune=*:%{!mcpu=*:%{!march=*:-mtune=%(VALUE)}}}}" }, \ + {"arch", "%{!march=*:-march=%(VALUE)}"}, \ + {"arch_32", "%{" OPT_ARCH32 ":%{!march=*:-march=%(VALUE)}}"}, \ + {"arch_64", "%{" OPT_ARCH64 ":%{!march=*:-march=%(VALUE)}}"}, + +/* Specs for the compiler proper */ + +#ifndef CC1_CPU_SPEC +#define CC1_CPU_SPEC_1 "" + +#ifndef HAVE_LOCAL_CPU_DETECT +#define CC1_CPU_SPEC CC1_CPU_SPEC_1 +#else +#define CC1_CPU_SPEC CC1_CPU_SPEC_1 \ +"%{march=native:%>march=native %:local_cpu_detect(arch) \ + %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} \ +%{mtune=native:%>mtune=native %:local_cpu_detect(tune)}" +#endif +#endif + +/* Target CPU builtins. */ +#define TARGET_CPU_CPP_BUILTINS() ix86_target_macros () + +/* Target Pragmas. */ +#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas () + +#ifndef CC1_SPEC +#define CC1_SPEC "%(cc1_cpu) " +#endif + +/* This macro defines names of additional specifications to put in the + specs that can be used in various specifications like CC1_SPEC. Its + definition is an initializer with a subgrouping for each command option. + + Each subgrouping contains a string constant, that defines the + specification name, and a string constant that used by the GCC driver + program. + + Do not define this macro if it does not need to do anything. */ + +#ifndef SUBTARGET_EXTRA_SPECS +#define SUBTARGET_EXTRA_SPECS +#endif + +#define EXTRA_SPECS \ + { "cc1_cpu", CC1_CPU_SPEC }, \ + SUBTARGET_EXTRA_SPECS + + +/* Set the value of FLT_EVAL_METHOD in float.h. When using only the + FPU, assume that the fpcw is set to extended precision; when using + only SSE, rounding is correct; when using both SSE and the FPU, + the rounding precision is indeterminate, since either may be chosen + apparently at random. */ +#define TARGET_FLT_EVAL_METHOD \ + (TARGET_MIX_SSE_I387 ? -1 : TARGET_SSE_MATH ? 0 : 2) + +/* Whether to allow x87 floating-point arithmetic on MODE (one of + SFmode, DFmode and XFmode) in the current excess precision + configuration. */ +#define X87_ENABLE_ARITH(MODE) \ + (flag_excess_precision == EXCESS_PRECISION_FAST || (MODE) == XFmode) + +/* Likewise, whether to allow direct conversions from integer mode + IMODE (HImode, SImode or DImode) to MODE. */ +#define X87_ENABLE_FLOAT(MODE, IMODE) \ + (flag_excess_precision == EXCESS_PRECISION_FAST \ + || (MODE) == XFmode \ + || ((MODE) == DFmode && (IMODE) == SImode) \ + || (IMODE) == HImode) + +/* target machine storage layout */ + +#define SHORT_TYPE_SIZE 16 +#define INT_TYPE_SIZE 32 +#define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD) +#define POINTER_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD) +#define LONG_LONG_TYPE_SIZE 64 +#define FLOAT_TYPE_SIZE 32 +#define DOUBLE_TYPE_SIZE 64 +#define LONG_DOUBLE_TYPE_SIZE (TARGET_LONG_DOUBLE_64 ? 64 : 80) + +/* Define this to set long double type size to use in libgcc2.c, which can + not depend on target_flags. */ +#ifdef __LONG_DOUBLE_64__ +#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64 +#else +#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 80 +#endif + +#define WIDEST_HARDWARE_FP_SIZE 80 + +#if defined (TARGET_BI_ARCH) || TARGET_64BIT_DEFAULT +#define MAX_BITS_PER_WORD 64 +#else +#define MAX_BITS_PER_WORD 32 +#endif + +/* Define this if most significant byte of a word is the lowest numbered. */ +/* That is true on the 80386. */ + +#define BITS_BIG_ENDIAN 0 + +/* Define this if most significant byte of a word is the lowest numbered. */ +/* That is not true on the 80386. */ +#define BYTES_BIG_ENDIAN 0 + +/* Define this if most significant word of a multiword number is the lowest + numbered. */ +/* Not true for 80386 */ +#define WORDS_BIG_ENDIAN 0 + +/* Width of a word, in units (bytes). */ +#define UNITS_PER_WORD (TARGET_64BIT ? 8 : 4) + +#ifndef IN_LIBGCC2 +#define MIN_UNITS_PER_WORD 4 +#endif + +/* Allocation boundary (in *bits*) for storing arguments in argument list. */ +#define PARM_BOUNDARY BITS_PER_WORD + +/* Boundary (in *bits*) on which stack pointer should be aligned. */ +#define STACK_BOUNDARY \ + (TARGET_64BIT && ix86_abi == MS_ABI ? 128 : BITS_PER_WORD) + +/* Stack boundary of the main function guaranteed by OS. */ +#define MAIN_STACK_BOUNDARY (TARGET_64BIT ? 128 : 32) + +/* Minimum stack boundary. */ +#define MIN_STACK_BOUNDARY (TARGET_64BIT ? (TARGET_SSE ? 128 : 64) : 32) + +/* Boundary (in *bits*) on which the stack pointer prefers to be + aligned; the compiler cannot rely on having this alignment. */ +#define PREFERRED_STACK_BOUNDARY ix86_preferred_stack_boundary + +/* It should be MIN_STACK_BOUNDARY. But we set it to 128 bits for + both 32bit and 64bit, to support codes that need 128 bit stack + alignment for SSE instructions, but can't realign the stack. */ +#define PREFERRED_STACK_BOUNDARY_DEFAULT 128 + +/* 1 if -mstackrealign should be turned on by default. It will + generate an alternate prologue and epilogue that realigns the + runtime stack if nessary. This supports mixing codes that keep a + 4-byte aligned stack, as specified by i386 psABI, with codes that + need a 16-byte aligned stack, as required by SSE instructions. */ +#define STACK_REALIGN_DEFAULT 0 + +/* Boundary (in *bits*) on which the incoming stack is aligned. */ +#define INCOMING_STACK_BOUNDARY ix86_incoming_stack_boundary + +/* According to Windows x64 software convention, the maximum stack allocatable + in the prologue is 4G - 8 bytes. Furthermore, there is a limited set of + instructions allowed to adjust the stack pointer in the epilog, forcing the + use of frame pointer for frames larger than 2 GB. This theorical limit + is reduced by 256, an over-estimated upper bound for the stack use by the + prologue. + We define only one threshold for both the prolog and the epilog. When the + frame size is larger than this threshold, we allocate the area to save SSE + regs, then save them, and then allocate the remaining. There is no SEH + unwind info for this later allocation. */ +#define SEH_MAX_FRAME_SIZE ((2U << 30) - 256) + +/* Target OS keeps a vector-aligned (128-bit, 16-byte) stack. This is + mandatory for the 64-bit ABI, and may or may not be true for other + operating systems. */ +#define TARGET_KEEPS_VECTOR_ALIGNED_STACK TARGET_64BIT + +/* Minimum allocation boundary for the code of a function. */ +#define FUNCTION_BOUNDARY 8 + +/* C++ stores the virtual bit in the lowest bit of function pointers. */ +#define TARGET_PTRMEMFUNC_VBIT_LOCATION ptrmemfunc_vbit_in_pfn + +/* Minimum size in bits of the largest boundary to which any + and all fundamental data types supported by the hardware + might need to be aligned. No data type wants to be aligned + rounder than this. + + Pentium+ prefers DFmode values to be aligned to 64 bit boundary + and Pentium Pro XFmode values at 128 bit boundaries. */ + +#define BIGGEST_ALIGNMENT (TARGET_AVX ? 256 : 128) + +/* Maximum stack alignment. */ +#define MAX_STACK_ALIGNMENT MAX_OFILE_ALIGNMENT + +/* Alignment value for attribute ((aligned)). It is a constant since + it is the part of the ABI. We shouldn't change it with -mavx. */ +#define ATTRIBUTE_ALIGNED_VALUE 128 + +/* Decide whether a variable of mode MODE should be 128 bit aligned. */ +#define ALIGN_MODE_128(MODE) \ + ((MODE) == XFmode || SSE_REG_MODE_P (MODE)) + +/* The published ABIs say that doubles should be aligned on word + boundaries, so lower the alignment for structure fields unless + -malign-double is set. */ + +/* ??? Blah -- this macro is used directly by libobjc. Since it + supports no vector modes, cut out the complexity and fall back + on BIGGEST_FIELD_ALIGNMENT. */ +#ifdef IN_TARGET_LIBS +#ifdef __x86_64__ +#define BIGGEST_FIELD_ALIGNMENT 128 +#else +#define BIGGEST_FIELD_ALIGNMENT 32 +#endif +#else +#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \ + x86_field_alignment (FIELD, COMPUTED) +#endif + +/* If defined, a C expression to compute the alignment given to a + constant that is being placed in memory. EXP is the constant + and ALIGN is the alignment that the object would ordinarily have. + The value of this macro is used instead of that alignment to align + the object. + + If this macro is not defined, then ALIGN is used. + + The typical use of this macro is to increase alignment for string + constants to be word aligned so that `strcpy' calls that copy + constants can be done inline. */ + +#define CONSTANT_ALIGNMENT(EXP, ALIGN) ix86_constant_alignment ((EXP), (ALIGN)) + +/* If defined, a C expression to compute the alignment for a static + variable. TYPE is the data type, and ALIGN is the alignment that + the object would ordinarily have. The value of this macro is used + instead of that alignment to align the object. + + If this macro is not defined, then ALIGN is used. + + One use of this macro is to increase alignment of medium-size + data to make it all fit in fewer cache lines. Another is to + cause character arrays to be word-aligned so that `strcpy' calls + that copy constants to character arrays can be done inline. */ + +#define DATA_ALIGNMENT(TYPE, ALIGN) ix86_data_alignment ((TYPE), (ALIGN)) + +/* If defined, a C expression to compute the alignment for a local + variable. TYPE is the data type, and ALIGN is the alignment that + the object would ordinarily have. The value of this macro is used + instead of that alignment to align the object. + + If this macro is not defined, then ALIGN is used. + + One use of this macro is to increase alignment of medium-size + data to make it all fit in fewer cache lines. */ + +#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ + ix86_local_alignment ((TYPE), VOIDmode, (ALIGN)) + +/* If defined, a C expression to compute the alignment for stack slot. + TYPE is the data type, MODE is the widest mode available, and ALIGN + is the alignment that the slot would ordinarily have. The value of + this macro is used instead of that alignment to align the slot. + + If this macro is not defined, then ALIGN is used when TYPE is NULL, + Otherwise, LOCAL_ALIGNMENT will be used. + + One use of this macro is to set alignment of stack slot to the + maximum alignment of all possible modes which the slot may have. */ + +#define STACK_SLOT_ALIGNMENT(TYPE, MODE, ALIGN) \ + ix86_local_alignment ((TYPE), (MODE), (ALIGN)) + +/* If defined, a C expression to compute the alignment for a local + variable DECL. + + If this macro is not defined, then + LOCAL_ALIGNMENT (TREE_TYPE (DECL), DECL_ALIGN (DECL)) will be used. + + One use of this macro is to increase alignment of medium-size + data to make it all fit in fewer cache lines. */ + +#define LOCAL_DECL_ALIGNMENT(DECL) \ + ix86_local_alignment ((DECL), VOIDmode, DECL_ALIGN (DECL)) + +/* If defined, a C expression to compute the minimum required alignment + for dynamic stack realignment purposes for EXP (a TYPE or DECL), + MODE, assuming normal alignment ALIGN. + + If this macro is not defined, then (ALIGN) will be used. */ + +#define MINIMUM_ALIGNMENT(EXP, MODE, ALIGN) \ + ix86_minimum_alignment (EXP, MODE, ALIGN) + + +/* Set this nonzero if move instructions will actually fail to work + when given unaligned data. */ +#define STRICT_ALIGNMENT 0 + +/* If bit field type is int, don't let it cross an int, + and give entire struct the alignment of an int. */ +/* Required on the 386 since it doesn't have bit-field insns. */ +#define PCC_BITFIELD_TYPE_MATTERS 1 + +/* Standard register usage. */ + +/* This processor has special stack-like registers. See reg-stack.c + for details. */ + +#define STACK_REGS + +#define IS_STACK_MODE(MODE) \ + (((MODE) == SFmode && !(TARGET_SSE && TARGET_SSE_MATH)) \ + || ((MODE) == DFmode && !(TARGET_SSE2 && TARGET_SSE_MATH)) \ + || (MODE) == XFmode) + +/* Number of actual hardware registers. + The hardware registers are assigned numbers for the compiler + from 0 to just below FIRST_PSEUDO_REGISTER. + All registers that the compiler knows about must be given numbers, + even those that are not normally considered general registers. + + In the 80386 we give the 8 general purpose registers the numbers 0-7. + We number the floating point registers 8-15. + Note that registers 0-7 can be accessed as a short or int, + while only 0-3 may be used with byte `mov' instructions. + + Reg 16 does not correspond to any hardware register, but instead + appears in the RTL as an argument pointer prior to reload, and is + eliminated during reloading in favor of either the stack or frame + pointer. */ + +#define FIRST_PSEUDO_REGISTER 53 + +/* Number of hardware registers that go into the DWARF-2 unwind info. + If not defined, equals FIRST_PSEUDO_REGISTER. */ + +#define DWARF_FRAME_REGISTERS 17 + +/* 1 for registers that have pervasive standard uses + and are not available for the register allocator. + On the 80386, the stack pointer is such, as is the arg pointer. + + REX registers are disabled for 32bit targets in + TARGET_CONDITIONAL_REGISTER_USAGE. */ + +#define FIXED_REGISTERS \ +/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/ \ +{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, \ +/*arg,flags,fpsr,fpcr,frame*/ \ + 1, 1, 1, 1, 1, \ +/*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/ \ + 0, 0, 0, 0, 0, 0, 0, 0, \ +/* mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7*/ \ + 0, 0, 0, 0, 0, 0, 0, 0, \ +/* r8, r9, r10, r11, r12, r13, r14, r15*/ \ + 0, 0, 0, 0, 0, 0, 0, 0, \ +/*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/ \ + 0, 0, 0, 0, 0, 0, 0, 0 } + +/* 1 for registers not available across function calls. + These must include the FIXED_REGISTERS and also any + registers that can be used without being saved. + The latter must include the registers where values are returned + and the register where structure-value addresses are passed. + Aside from that, you can include as many other registers as you like. + + Value is set to 1 if the register is call used unconditionally. + Bit one is set if the register is call used on TARGET_32BIT ABI. + Bit two is set if the register is call used on TARGET_64BIT ABI. + Bit three is set if the register is call used on TARGET_64BIT_MS_ABI. + + Proper values are computed in TARGET_CONDITIONAL_REGISTER_USAGE. */ + +#define CALL_USED_REGISTERS \ +/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7*/ \ +{ 1, 1, 1, 0, 4, 4, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ +/*arg,flags,fpsr,fpcr,frame*/ \ + 1, 1, 1, 1, 1, \ +/*xmm0,xmm1,xmm2,xmm3,xmm4,xmm5,xmm6,xmm7*/ \ + 1, 1, 1, 1, 1, 1, 6, 6, \ +/* mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7*/ \ + 1, 1, 1, 1, 1, 1, 1, 1, \ +/* r8, r9, r10, r11, r12, r13, r14, r15*/ \ + 1, 1, 1, 1, 2, 2, 2, 2, \ +/*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/ \ + 6, 6, 6, 6, 6, 6, 6, 6 } + +/* Order in which to allocate registers. Each register must be + listed once, even those in FIXED_REGISTERS. List frame pointer + late and fixed registers last. Note that, in general, we prefer + registers listed in CALL_USED_REGISTERS, keeping the others + available for storage of persistent values. + + The ADJUST_REG_ALLOC_ORDER actually overwrite the order, + so this is just empty initializer for array. */ + +#define REG_ALLOC_ORDER \ +{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,\ + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, \ + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \ + 48, 49, 50, 51, 52 } + +/* ADJUST_REG_ALLOC_ORDER is a macro which permits reg_alloc_order + to be rearranged based on a particular function. When using sse math, + we want to allocate SSE before x87 registers and vice versa. */ + +#define ADJUST_REG_ALLOC_ORDER x86_order_regs_for_local_alloc () + + +#define OVERRIDE_ABI_FORMAT(FNDECL) ix86_call_abi_override (FNDECL) + +/* Return number of consecutive hard regs needed starting at reg REGNO + to hold something of mode MODE. + This is ordinarily the length in words of a value of mode MODE + but can be less for certain modes in special long registers. + + Actually there are no two word move instructions for consecutive + registers. And only registers 0-3 may have mov byte instructions + applied to them. */ + +#define HARD_REGNO_NREGS(REGNO, MODE) \ + (STACK_REGNO_P (REGNO) || SSE_REGNO_P (REGNO) || MMX_REGNO_P (REGNO) \ + ? (COMPLEX_MODE_P (MODE) ? 2 : 1) \ + : ((MODE) == XFmode \ + ? (TARGET_64BIT ? 2 : 3) \ + : (MODE) == XCmode \ + ? (TARGET_64BIT ? 4 : 6) \ + : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))) + +#define HARD_REGNO_NREGS_HAS_PADDING(REGNO, MODE) \ + ((TARGET_128BIT_LONG_DOUBLE && !TARGET_64BIT) \ + ? (STACK_REGNO_P (REGNO) || SSE_REGNO_P (REGNO) || MMX_REGNO_P (REGNO) \ + ? 0 \ + : ((MODE) == XFmode || (MODE) == XCmode)) \ + : 0) + +#define HARD_REGNO_NREGS_WITH_PADDING(REGNO, MODE) ((MODE) == XFmode ? 4 : 8) + +#define VALID_AVX256_REG_MODE(MODE) \ + ((MODE) == V32QImode || (MODE) == V16HImode || (MODE) == V8SImode \ + || (MODE) == V4DImode || (MODE) == V2TImode || (MODE) == V8SFmode \ + || (MODE) == V4DFmode) + +#define VALID_AVX256_REG_OR_OI_MODE(MODE) \ + (VALID_AVX256_REG_MODE (MODE) || (MODE) == OImode) + +#define VALID_SSE2_REG_MODE(MODE) \ + ((MODE) == V16QImode || (MODE) == V8HImode || (MODE) == V2DFmode \ + || (MODE) == V2DImode || (MODE) == DFmode) + +#define VALID_SSE_REG_MODE(MODE) \ + ((MODE) == V1TImode || (MODE) == TImode \ + || (MODE) == V4SFmode || (MODE) == V4SImode \ + || (MODE) == SFmode || (MODE) == TFmode) + +#define VALID_MMX_REG_MODE_3DNOW(MODE) \ + ((MODE) == V2SFmode || (MODE) == SFmode) + +#define VALID_MMX_REG_MODE(MODE) \ + ((MODE == V1DImode) || (MODE) == DImode \ + || (MODE) == V2SImode || (MODE) == SImode \ + || (MODE) == V4HImode || (MODE) == V8QImode) + +#define VALID_DFP_MODE_P(MODE) \ + ((MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode) + +#define VALID_FP_MODE_P(MODE) \ + ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode \ + || (MODE) == SCmode || (MODE) == DCmode || (MODE) == XCmode) \ + +#define VALID_INT_MODE_P(MODE) \ + ((MODE) == QImode || (MODE) == HImode || (MODE) == SImode \ + || (MODE) == DImode \ + || (MODE) == CQImode || (MODE) == CHImode || (MODE) == CSImode \ + || (MODE) == CDImode \ + || (TARGET_64BIT && ((MODE) == TImode || (MODE) == CTImode \ + || (MODE) == TFmode || (MODE) == TCmode))) + +/* Return true for modes passed in SSE registers. */ +#define SSE_REG_MODE_P(MODE) \ + ((MODE) == V1TImode || (MODE) == TImode || (MODE) == V16QImode \ + || (MODE) == TFmode || (MODE) == V8HImode || (MODE) == V2DFmode \ + || (MODE) == V2DImode || (MODE) == V4SFmode || (MODE) == V4SImode \ + || (MODE) == V32QImode || (MODE) == V16HImode || (MODE) == V8SImode \ + || (MODE) == V4DImode || (MODE) == V8SFmode || (MODE) == V4DFmode \ + || (MODE) == V2TImode) + +/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */ + +#define HARD_REGNO_MODE_OK(REGNO, MODE) \ + ix86_hard_regno_mode_ok ((REGNO), (MODE)) + +/* Value is 1 if it is a good idea to tie two pseudo registers + when one has mode MODE1 and one has mode MODE2. + If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, + for any hard reg, then this must be 0 for correct output. */ + +#define MODES_TIEABLE_P(MODE1, MODE2) ix86_modes_tieable_p (MODE1, MODE2) + +/* It is possible to write patterns to move flags; but until someone + does it, */ +#define AVOID_CCMODE_COPIES + +/* Specify the modes required to caller save a given hard regno. + We do this on i386 to prevent flags from being saved at all. + + Kill any attempts to combine saving of modes. */ + +#define HARD_REGNO_CALLER_SAVE_MODE(REGNO, NREGS, MODE) \ + (CC_REGNO_P (REGNO) ? VOIDmode \ + : (MODE) == VOIDmode && (NREGS) != 1 ? VOIDmode \ + : (MODE) == VOIDmode ? choose_hard_reg_mode ((REGNO), (NREGS), false) \ + : (MODE) == HImode && !TARGET_PARTIAL_REG_STALL ? SImode \ + : (MODE) == QImode && !(TARGET_64BIT || QI_REGNO_P (REGNO)) ? SImode \ + : (MODE)) + +/* The only ABI that saves SSE registers across calls is Win64 (thus no + need to check the current ABI here), and with AVX enabled Win64 only + guarantees that the low 16 bytes are saved. */ +#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ + (SSE_REGNO_P (REGNO) && GET_MODE_SIZE (MODE) > 16) + +/* Specify the registers used for certain standard purposes. + The values of these macros are register numbers. */ + +/* on the 386 the pc register is %eip, and is not usable as a general + register. The ordinary mov instructions won't work */ +/* #define PC_REGNUM */ + +/* Register to use for pushing function arguments. */ +#define STACK_POINTER_REGNUM 7 + +/* Base register for access to local variables of the function. */ +#define HARD_FRAME_POINTER_REGNUM 6 + +/* Base register for access to local variables of the function. */ +#define FRAME_POINTER_REGNUM 20 + +/* First floating point reg */ +#define FIRST_FLOAT_REG 8 + +/* First & last stack-like regs */ +#define FIRST_STACK_REG FIRST_FLOAT_REG +#define LAST_STACK_REG (FIRST_FLOAT_REG + 7) + +#define FIRST_SSE_REG (FRAME_POINTER_REGNUM + 1) +#define LAST_SSE_REG (FIRST_SSE_REG + 7) + +#define FIRST_MMX_REG (LAST_SSE_REG + 1) +#define LAST_MMX_REG (FIRST_MMX_REG + 7) + +#define FIRST_REX_INT_REG (LAST_MMX_REG + 1) +#define LAST_REX_INT_REG (FIRST_REX_INT_REG + 7) + +#define FIRST_REX_SSE_REG (LAST_REX_INT_REG + 1) +#define LAST_REX_SSE_REG (FIRST_REX_SSE_REG + 7) + +/* Override this in other tm.h files to cope with various OS lossage + requiring a frame pointer. */ +#ifndef SUBTARGET_FRAME_POINTER_REQUIRED +#define SUBTARGET_FRAME_POINTER_REQUIRED 0 +#endif + +/* Make sure we can access arbitrary call frames. */ +#define SETUP_FRAME_ADDRESSES() ix86_setup_frame_addresses () + +/* Base register for access to arguments of the function. */ +#define ARG_POINTER_REGNUM 16 + +/* Register to hold the addressing base for position independent + code access to data items. We don't use PIC pointer for 64bit + mode. Define the regnum to dummy value to prevent gcc from + pessimizing code dealing with EBX. + + To avoid clobbering a call-saved register unnecessarily, we renumber + the pic register when possible. The change is visible after the + prologue has been emitted. */ + +#define REAL_PIC_OFFSET_TABLE_REGNUM BX_REG + +#define PIC_OFFSET_TABLE_REGNUM \ + ((TARGET_64BIT && ix86_cmodel == CM_SMALL_PIC) \ + || !flag_pic ? INVALID_REGNUM \ + : reload_completed ? REGNO (pic_offset_table_rtx) \ + : REAL_PIC_OFFSET_TABLE_REGNUM) + +#define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_" + +/* This is overridden by . */ +#define MS_AGGREGATE_RETURN 0 + +#define KEEP_AGGREGATE_RETURN_POINTER 0 + +/* Define the classes of registers for register constraints in the + machine description. Also define ranges of constants. + + One of the classes must always be named ALL_REGS and include all hard regs. + If there is more than one class, another class must be named NO_REGS + and contain no registers. + + The name GENERAL_REGS must be the name of a class (or an alias for + another name such as ALL_REGS). This is the class of registers + that is allowed by "g" or "r" in a register constraint. + Also, registers outside this class are allocated only when + instructions express preferences for them. + + The classes must be numbered in nondecreasing order; that is, + a larger-numbered class must never be contained completely + in a smaller-numbered class. + + For any two classes, it is very desirable that there be another + class that represents their union. + + It might seem that class BREG is unnecessary, since no useful 386 + opcode needs reg %ebx. But some systems pass args to the OS in ebx, + and the "b" register constraint is useful in asms for syscalls. + + The flags, fpsr and fpcr registers are in no class. */ + +enum reg_class +{ + NO_REGS, + AREG, DREG, CREG, BREG, SIREG, DIREG, + AD_REGS, /* %eax/%edx for DImode */ + Q_REGS, /* %eax %ebx %ecx %edx */ + NON_Q_REGS, /* %esi %edi %ebp %esp */ + INDEX_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp */ + LEGACY_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp %esp */ + CLOBBERED_REGS, /* call-clobbered integer registers */ + GENERAL_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp %esp + %r8 %r9 %r10 %r11 %r12 %r13 %r14 %r15 */ + FP_TOP_REG, FP_SECOND_REG, /* %st(0) %st(1) */ + FLOAT_REGS, + SSE_FIRST_REG, + SSE_REGS, + MMX_REGS, + FP_TOP_SSE_REGS, + FP_SECOND_SSE_REGS, + FLOAT_SSE_REGS, + FLOAT_INT_REGS, + INT_SSE_REGS, + FLOAT_INT_SSE_REGS, + ALL_REGS, LIM_REG_CLASSES +}; + +#define N_REG_CLASSES ((int) LIM_REG_CLASSES) + +#define INTEGER_CLASS_P(CLASS) \ + reg_class_subset_p ((CLASS), GENERAL_REGS) +#define FLOAT_CLASS_P(CLASS) \ + reg_class_subset_p ((CLASS), FLOAT_REGS) +#define SSE_CLASS_P(CLASS) \ + reg_class_subset_p ((CLASS), SSE_REGS) +#define MMX_CLASS_P(CLASS) \ + ((CLASS) == MMX_REGS) +#define MAYBE_INTEGER_CLASS_P(CLASS) \ + reg_classes_intersect_p ((CLASS), GENERAL_REGS) +#define MAYBE_FLOAT_CLASS_P(CLASS) \ + reg_classes_intersect_p ((CLASS), FLOAT_REGS) +#define MAYBE_SSE_CLASS_P(CLASS) \ + reg_classes_intersect_p (SSE_REGS, (CLASS)) +#define MAYBE_MMX_CLASS_P(CLASS) \ + reg_classes_intersect_p (MMX_REGS, (CLASS)) + +#define Q_CLASS_P(CLASS) \ + reg_class_subset_p ((CLASS), Q_REGS) + +/* Give names of register classes as strings for dump file. */ + +#define REG_CLASS_NAMES \ +{ "NO_REGS", \ + "AREG", "DREG", "CREG", "BREG", \ + "SIREG", "DIREG", \ + "AD_REGS", \ + "Q_REGS", "NON_Q_REGS", \ + "INDEX_REGS", \ + "LEGACY_REGS", \ + "CLOBBERED_REGS", \ + "GENERAL_REGS", \ + "FP_TOP_REG", "FP_SECOND_REG", \ + "FLOAT_REGS", \ + "SSE_FIRST_REG", \ + "SSE_REGS", \ + "MMX_REGS", \ + "FP_TOP_SSE_REGS", \ + "FP_SECOND_SSE_REGS", \ + "FLOAT_SSE_REGS", \ + "FLOAT_INT_REGS", \ + "INT_SSE_REGS", \ + "FLOAT_INT_SSE_REGS", \ + "ALL_REGS" } + +/* Define which registers fit in which classes. This is an initializer + for a vector of HARD_REG_SET of length N_REG_CLASSES. + + Note that CLOBBERED_REGS are calculated by + TARGET_CONDITIONAL_REGISTER_USAGE. */ + +#define REG_CLASS_CONTENTS \ +{ { 0x00, 0x0 }, \ + { 0x01, 0x0 }, { 0x02, 0x0 }, /* AREG, DREG */ \ + { 0x04, 0x0 }, { 0x08, 0x0 }, /* CREG, BREG */ \ + { 0x10, 0x0 }, { 0x20, 0x0 }, /* SIREG, DIREG */ \ + { 0x03, 0x0 }, /* AD_REGS */ \ + { 0x0f, 0x0 }, /* Q_REGS */ \ + { 0x1100f0, 0x1fe0 }, /* NON_Q_REGS */ \ + { 0x7f, 0x1fe0 }, /* INDEX_REGS */ \ + { 0x1100ff, 0x0 }, /* LEGACY_REGS */ \ + { 0x00, 0x0 }, /* CLOBBERED_REGS */ \ + { 0x1100ff, 0x1fe0 }, /* GENERAL_REGS */ \ + { 0x100, 0x0 }, { 0x0200, 0x0 },/* FP_TOP_REG, FP_SECOND_REG */\ + { 0xff00, 0x0 }, /* FLOAT_REGS */ \ + { 0x200000, 0x0 }, /* SSE_FIRST_REG */ \ +{ 0x1fe00000,0x1fe000 }, /* SSE_REGS */ \ +{ 0xe0000000, 0x1f }, /* MMX_REGS */ \ +{ 0x1fe00100,0x1fe000 }, /* FP_TOP_SSE_REG */ \ +{ 0x1fe00200,0x1fe000 }, /* FP_SECOND_SSE_REG */ \ +{ 0x1fe0ff00,0x1fe000 }, /* FLOAT_SSE_REGS */ \ + { 0x11ffff, 0x1fe0 }, /* FLOAT_INT_REGS */ \ +{ 0x1ff100ff,0x1fffe0 }, /* INT_SSE_REGS */ \ +{ 0x1ff1ffff,0x1fffe0 }, /* FLOAT_INT_SSE_REGS */ \ +{ 0xffffffff,0x1fffff } \ +} + +/* The same information, inverted: + Return the class number of the smallest class containing + reg number REGNO. This could be a conditional expression + or could index an array. */ + +#define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO]) + +/* When this hook returns true for MODE, the compiler allows + registers explicitly used in the rtl to be used as spill registers + but prevents the compiler from extending the lifetime of these + registers. */ +#define TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P hook_bool_mode_true + +#define QI_REG_P(X) (REG_P (X) && QI_REGNO_P (REGNO (X))) +#define QI_REGNO_P(N) IN_RANGE ((N), AX_REG, BX_REG) + +#define GENERAL_REG_P(X) \ + (REG_P (X) && GENERAL_REGNO_P (REGNO (X))) +#define GENERAL_REGNO_P(N) \ + (IN_RANGE ((N), AX_REG, SP_REG) || REX_INT_REGNO_P (N)) + +#define ANY_QI_REG_P(X) (REG_P (X) && ANY_QI_REGNO_P (REGNO (X))) +#define ANY_QI_REGNO_P(N) \ + (TARGET_64BIT ? GENERAL_REGNO_P (N) : QI_REGNO_P (N)) + +#define REX_INT_REG_P(X) (REG_P (X) && REX_INT_REGNO_P (REGNO (X))) +#define REX_INT_REGNO_P(N) \ + IN_RANGE ((N), FIRST_REX_INT_REG, LAST_REX_INT_REG) + +#define STACK_REG_P(X) (REG_P (X) && STACK_REGNO_P (REGNO (X))) +#define STACK_REGNO_P(N) IN_RANGE ((N), FIRST_STACK_REG, LAST_STACK_REG) + +#define ANY_FP_REG_P(X) (REG_P (X) && ANY_FP_REGNO_P (REGNO (X))) +#define ANY_FP_REGNO_P(N) (STACK_REGNO_P (N) || SSE_REGNO_P (N)) + +#define X87_FLOAT_MODE_P(MODE) \ + (TARGET_80387 && ((MODE) == SFmode || (MODE) == DFmode || (MODE) == XFmode)) + +#define SSE_REG_P(X) (REG_P (X) && SSE_REGNO_P (REGNO (X))) +#define SSE_REGNO_P(N) \ + (IN_RANGE ((N), FIRST_SSE_REG, LAST_SSE_REG) \ + || REX_SSE_REGNO_P (N)) + +#define REX_SSE_REGNO_P(N) \ + IN_RANGE ((N), FIRST_REX_SSE_REG, LAST_REX_SSE_REG) + +#define SSE_REGNO(N) \ + ((N) < 8 ? FIRST_SSE_REG + (N) : FIRST_REX_SSE_REG + (N) - 8) + +#define SSE_FLOAT_MODE_P(MODE) \ + ((TARGET_SSE && (MODE) == SFmode) || (TARGET_SSE2 && (MODE) == DFmode)) + +#define FMA4_VEC_FLOAT_MODE_P(MODE) \ + (TARGET_FMA4 && ((MODE) == V4SFmode || (MODE) == V2DFmode \ + || (MODE) == V8SFmode || (MODE) == V4DFmode)) + +#define MMX_REG_P(X) (REG_P (X) && MMX_REGNO_P (REGNO (X))) +#define MMX_REGNO_P(N) IN_RANGE ((N), FIRST_MMX_REG, LAST_MMX_REG) + +#define STACK_TOP_P(X) (REG_P (X) && REGNO (X) == FIRST_STACK_REG) + +#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X))) +#define CC_REGNO_P(X) ((X) == FLAGS_REG || (X) == FPSR_REG) + +/* The class value for index registers, and the one for base regs. */ + +#define INDEX_REG_CLASS INDEX_REGS +#define BASE_REG_CLASS GENERAL_REGS + +/* Place additional restrictions on the register class to use when it + is necessary to be able to hold a value of mode MODE in a reload + register for which class CLASS would ordinarily be used. + + We avoid classes containing registers from multiple units due to + the limitation in ix86_secondary_memory_needed. We limit these + classes to their "natural mode" single unit register class, depending + on the unit availability. + + Please note that reg_class_subset_p is not commutative, so these + conditions mean "... if (CLASS) includes ALL registers from the + register set." */ + +#define LIMIT_RELOAD_CLASS(MODE, CLASS) \ + (((MODE) == QImode && !TARGET_64BIT \ + && reg_class_subset_p (Q_REGS, (CLASS))) ? Q_REGS \ + : (((MODE) == SImode || (MODE) == DImode) \ + && reg_class_subset_p (GENERAL_REGS, (CLASS))) ? GENERAL_REGS \ + : (SSE_FLOAT_MODE_P (MODE) && TARGET_SSE_MATH \ + && reg_class_subset_p (SSE_REGS, (CLASS))) ? SSE_REGS \ + : (X87_FLOAT_MODE_P (MODE) \ + && reg_class_subset_p (FLOAT_REGS, (CLASS))) ? FLOAT_REGS \ + : (CLASS)) + +/* If we are copying between general and FP registers, we need a memory + location. The same is true for SSE and MMX registers. */ +#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ + ix86_secondary_memory_needed ((CLASS1), (CLASS2), (MODE), 1) + +/* Get_secondary_mem widens integral modes to BITS_PER_WORD. + There is no need to emit full 64 bit move on 64 bit targets + for integral modes that can be moved using 32 bit move. */ +#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ + (GET_MODE_BITSIZE (MODE) < 32 && INTEGRAL_MODE_P (MODE) \ + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ + : MODE) + +/* Return a class of registers that cannot change FROM mode to TO mode. */ + +#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \ + ix86_cannot_change_mode_class (FROM, TO, CLASS) + +/* Stack layout; function entry, exit and calling. */ + +/* Define this if pushing a word on the stack + makes the stack pointer a smaller address. */ +#define STACK_GROWS_DOWNWARD + +/* Define this to nonzero if the nominal address of the stack frame + is at the high-address end of the local variables; + that is, each additional local variable allocated + goes at a more negative offset in the frame. */ +#define FRAME_GROWS_DOWNWARD 1 + +/* Offset within stack frame to start allocating local variables at. + If FRAME_GROWS_DOWNWARD, this is the offset to the END of the + first local allocated. Otherwise, it is the offset to the BEGINNING + of the first local allocated. */ +#define STARTING_FRAME_OFFSET 0 + +/* If we generate an insn to push BYTES bytes, this says how many the stack + pointer really advances by. On 386, we have pushw instruction that + decrements by exactly 2 no matter what the position was, there is no pushb. + + But as CIE data alignment factor on this arch is -4 for 32bit targets + and -8 for 64bit targets, we need to make sure all stack pointer adjustments + are in multiple of 4 for 32bit targets and 8 for 64bit targets. */ + +#define PUSH_ROUNDING(BYTES) \ + (((BYTES) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD) + +/* If defined, the maximum amount of space required for outgoing arguments + will be computed and placed into the variable `crtl->outgoing_args_size'. + No space will be pushed onto the stack for each call; instead, the + function prologue should increase the stack frame size by this amount. + + 64-bit MS ABI seem to require 16 byte alignment everywhere except for + function prologue and apilogue. This is not possible without + ACCUMULATE_OUTGOING_ARGS. */ + +#define ACCUMULATE_OUTGOING_ARGS \ + (TARGET_ACCUMULATE_OUTGOING_ARGS || TARGET_64BIT_MS_ABI) + +/* If defined, a C expression whose value is nonzero when we want to use PUSH + instructions to pass outgoing arguments. */ + +#define PUSH_ARGS (TARGET_PUSH_ARGS && !ACCUMULATE_OUTGOING_ARGS) + +/* We want the stack and args grow in opposite directions, even if + PUSH_ARGS is 0. */ +#define PUSH_ARGS_REVERSED 1 + +/* Offset of first parameter from the argument pointer register value. */ +#define FIRST_PARM_OFFSET(FNDECL) 0 + +/* Define this macro if functions should assume that stack space has been + allocated for arguments even when their values are passed in registers. + + The value of this macro is the size, in bytes, of the area reserved for + arguments passed in registers for the function represented by FNDECL. + + This space can be allocated by the caller, or be a part of the + machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says + which. */ +#define REG_PARM_STACK_SPACE(FNDECL) ix86_reg_parm_stack_space (FNDECL) + +#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) \ + (TARGET_64BIT && ix86_function_type_abi (FNTYPE) == MS_ABI) + +/* Define how to find the value returned by a library function + assuming the value has mode MODE. */ + +#define LIBCALL_VALUE(MODE) ix86_libcall_value (MODE) + +/* Define the size of the result block used for communication between + untyped_call and untyped_return. The block contains a DImode value + followed by the block used by fnsave and frstor. */ + +#define APPLY_RESULT_SIZE (8+108) + +/* 1 if N is a possible register number for function argument passing. */ +#define FUNCTION_ARG_REGNO_P(N) ix86_function_arg_regno_p (N) + +/* Define a data type for recording info about an argument list + during the scan of that argument list. This data type should + hold all necessary information about the function itself + and about the args processed so far, enough to enable macros + such as FUNCTION_ARG to determine where the next arg should go. */ + +typedef struct ix86_args { + int words; /* # words passed so far */ + int nregs; /* # registers available for passing */ + int regno; /* next available register number */ + int fastcall; /* fastcall or thiscall calling convention + is used */ + int sse_words; /* # sse words passed so far */ + int sse_nregs; /* # sse registers available for passing */ + int warn_avx; /* True when we want to warn about AVX ABI. */ + int warn_sse; /* True when we want to warn about SSE ABI. */ + int warn_mmx; /* True when we want to warn about MMX ABI. */ + int sse_regno; /* next available sse register number */ + int mmx_words; /* # mmx words passed so far */ + int mmx_nregs; /* # mmx registers available for passing */ + int mmx_regno; /* next available mmx register number */ + int maybe_vaarg; /* true for calls to possibly vardic fncts. */ + int caller; /* true if it is caller. */ + int float_in_sse; /* Set to 1 or 2 for 32bit targets if + SFmode/DFmode arguments should be passed + in SSE registers. Otherwise 0. */ + enum calling_abi call_abi; /* Set to SYSV_ABI for sysv abi. Otherwise + MS_ABI for ms abi. */ +} CUMULATIVE_ARGS; + +/* Initialize a variable CUM of type CUMULATIVE_ARGS + for a call to a function whose data type is FNTYPE. + For a library call, FNTYPE is 0. */ + +#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \ + init_cumulative_args (&(CUM), (FNTYPE), (LIBNAME), (FNDECL), \ + (N_NAMED_ARGS) != -1) + +/* Output assembler code to FILE to increment profiler label # LABELNO + for profiling a function entry. */ + +#define FUNCTION_PROFILER(FILE, LABELNO) x86_function_profiler (FILE, LABELNO) + +#define MCOUNT_NAME "_mcount" + +#define MCOUNT_NAME_BEFORE_PROLOGUE "__fentry__" + +#define PROFILE_COUNT_REGISTER "edx" + +/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, + the stack pointer does not matter. The value is tested only in + functions that have frame pointers. + No definition is equivalent to always zero. */ +/* Note on the 386 it might be more efficient not to define this since + we have to restore it ourselves from the frame pointer, in order to + use pop */ + +#define EXIT_IGNORE_STACK 1 + +/* Output assembler code for a block containing the constant parts + of a trampoline, leaving space for the variable parts. */ + +/* On the 386, the trampoline contains two instructions: + mov #STATIC,ecx + jmp FUNCTION + The trampoline is generated entirely at runtime. The operand of JMP + is the address of FUNCTION relative to the instruction following the + JMP (which is 5 bytes long). */ + +/* Length in units of the trampoline for entering a nested function. */ + +#define TRAMPOLINE_SIZE (TARGET_64BIT ? 24 : 10) + +/* Definitions for register eliminations. + + This is an array of structures. Each structure initializes one pair + of eliminable registers. The "from" register number is given first, + followed by "to". Eliminations of the same "from" register are listed + in order of preference. + + There are two registers that can always be eliminated on the i386. + The frame pointer and the arg pointer can be replaced by either the + hard frame pointer or to the stack pointer, depending upon the + circumstances. The hard frame pointer is not used before reload and + so it is not eligible for elimination. */ + +#define ELIMINABLE_REGS \ +{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ + { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \ + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ + { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}} \ + +/* Define the offset between two registers, one to be eliminated, and the other + its replacement, at the start of a routine. */ + +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ + ((OFFSET) = ix86_initial_elimination_offset ((FROM), (TO))) + +/* Addressing modes, and classification of registers for them. */ + +/* Macros to check register numbers against specific register classes. */ + +/* These assume that REGNO is a hard or pseudo reg number. + They give nonzero only if REGNO is a hard reg of the suitable class + or a pseudo reg currently allocated to a suitable hard reg. + Since they use reg_renumber, they are safe only once reg_renumber + has been allocated, which happens in reginfo.c during register + allocation. */ + +#define REGNO_OK_FOR_INDEX_P(REGNO) \ + ((REGNO) < STACK_POINTER_REGNUM \ + || REX_INT_REGNO_P (REGNO) \ + || (unsigned) reg_renumber[(REGNO)] < STACK_POINTER_REGNUM \ + || REX_INT_REGNO_P ((unsigned) reg_renumber[(REGNO)])) + +#define REGNO_OK_FOR_BASE_P(REGNO) \ + (GENERAL_REGNO_P (REGNO) \ + || (REGNO) == ARG_POINTER_REGNUM \ + || (REGNO) == FRAME_POINTER_REGNUM \ + || GENERAL_REGNO_P ((unsigned) reg_renumber[(REGNO)])) + +/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx + and check its validity for a certain class. + We have two alternate definitions for each of them. + The usual definition accepts all pseudo regs; the other rejects + them unless they have been allocated suitable hard regs. + The symbol REG_OK_STRICT causes the latter definition to be used. + + Most source files want to accept pseudo regs in the hope that + they will get allocated to the class that the insn wants them to be in. + Source files for reload pass need to be strict. + After reload, it makes no difference, since pseudo regs have + been eliminated by then. */ + + +/* Non strict versions, pseudos are ok. */ +#define REG_OK_FOR_INDEX_NONSTRICT_P(X) \ + (REGNO (X) < STACK_POINTER_REGNUM \ + || REX_INT_REGNO_P (REGNO (X)) \ + || REGNO (X) >= FIRST_PSEUDO_REGISTER) + +#define REG_OK_FOR_BASE_NONSTRICT_P(X) \ + (GENERAL_REGNO_P (REGNO (X)) \ + || REGNO (X) == ARG_POINTER_REGNUM \ + || REGNO (X) == FRAME_POINTER_REGNUM \ + || REGNO (X) >= FIRST_PSEUDO_REGISTER) + +/* Strict versions, hard registers only */ +#define REG_OK_FOR_INDEX_STRICT_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) +#define REG_OK_FOR_BASE_STRICT_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) + +#ifndef REG_OK_STRICT +#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_INDEX_NONSTRICT_P (X) +#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_NONSTRICT_P (X) + +#else +#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_INDEX_STRICT_P (X) +#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_BASE_STRICT_P (X) +#endif + +/* TARGET_LEGITIMATE_ADDRESS_P recognizes an RTL expression + that is a valid memory address for an instruction. + The MODE argument is the machine mode for the MEM expression + that wants to use this address. + + The other macros defined here are used only in TARGET_LEGITIMATE_ADDRESS_P, + except for CONSTANT_ADDRESS_P which is usually machine-independent. + + See legitimize_pic_address in i386.c for details as to what + constitutes a legitimate address when -fpic is used. */ + +#define MAX_REGS_PER_ADDRESS 2 + +#define CONSTANT_ADDRESS_P(X) constant_address_p (X) + +/* Try a machine-dependent way of reloading an illegitimate address + operand. If we find one, push the reload and jump to WIN. This + macro is used in only one place: `find_reloads_address' in reload.c. */ + +#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, INDL, WIN) \ +do { \ + if (ix86_legitimize_reload_address ((X), (MODE), (OPNUM), \ + (int)(TYPE), (INDL))) \ + goto WIN; \ +} while (0) + +/* If defined, a C expression to determine the base term of address X. + This macro is used in only one place: `find_base_term' in alias.c. + + It is always safe for this macro to not be defined. It exists so + that alias analysis can understand machine-dependent addresses. + + The typical use of this macro is to handle addresses containing + a label_ref or symbol_ref within an UNSPEC. */ + +#define FIND_BASE_TERM(X) ix86_find_base_term (X) + +/* Nonzero if the constant value X is a legitimate general operand + when generating PIC code. It is given that flag_pic is on and + that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ + +#define LEGITIMATE_PIC_OPERAND_P(X) legitimate_pic_operand_p (X) + +#define SYMBOLIC_CONST(X) \ + (GET_CODE (X) == SYMBOL_REF \ + || GET_CODE (X) == LABEL_REF \ + || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X))) + +/* Max number of args passed in registers. If this is more than 3, we will + have problems with ebx (register #4), since it is a caller save register and + is also used as the pic register in ELF. So for now, don't allow more than + 3 registers to be passed in registers. */ + +/* Abi specific values for REGPARM_MAX and SSE_REGPARM_MAX */ +#define X86_64_REGPARM_MAX 6 +#define X86_64_MS_REGPARM_MAX 4 + +#define X86_32_REGPARM_MAX 3 + +#define REGPARM_MAX \ + (TARGET_64BIT \ + ? (TARGET_64BIT_MS_ABI \ + ? X86_64_MS_REGPARM_MAX \ + : X86_64_REGPARM_MAX) \ + : X86_32_REGPARM_MAX) + +#define X86_64_SSE_REGPARM_MAX 8 +#define X86_64_MS_SSE_REGPARM_MAX 4 + +#define X86_32_SSE_REGPARM_MAX (TARGET_SSE ? (TARGET_MACHO ? 4 : 3) : 0) + +#define SSE_REGPARM_MAX \ + (TARGET_64BIT \ + ? (TARGET_64BIT_MS_ABI \ + ? X86_64_MS_SSE_REGPARM_MAX \ + : X86_64_SSE_REGPARM_MAX) \ + : X86_32_SSE_REGPARM_MAX) + +#define MMX_REGPARM_MAX (TARGET_64BIT ? 0 : (TARGET_MMX ? 3 : 0)) + +/* Specify the machine mode that this machine uses + for the index in the tablejump instruction. */ +#define CASE_VECTOR_MODE \ + (!TARGET_LP64 || (flag_pic && ix86_cmodel != CM_LARGE_PIC) ? SImode : DImode) + +/* Define this as 1 if `char' should by default be signed; else as 0. */ +#define DEFAULT_SIGNED_CHAR 1 + +/* Max number of bytes we can move from memory to memory + in one reasonably fast instruction. */ +#define MOVE_MAX 16 + +/* MOVE_MAX_PIECES is the number of bytes at a time which we can + move efficiently, as opposed to MOVE_MAX which is the maximum + number of bytes we can move with a single instruction. */ +#define MOVE_MAX_PIECES UNITS_PER_WORD + +/* If a memory-to-memory move would take MOVE_RATIO or more simple + move-instruction pairs, we will do a movmem or libcall instead. + Increasing the value will always make code faster, but eventually + incurs high cost in increased code size. + + If you don't define this, a reasonable default is used. */ + +#define MOVE_RATIO(speed) ((speed) ? ix86_cost->move_ratio : 3) + +/* If a clear memory operation would take CLEAR_RATIO or more simple + move-instruction sequences, we will do a clrmem or libcall instead. */ + +#define CLEAR_RATIO(speed) ((speed) ? MIN (6, ix86_cost->move_ratio) : 2) + +/* Define if shifts truncate the shift count which implies one can + omit a sign-extension or zero-extension of a shift count. + + On i386, shifts do truncate the count. But bit test instructions + take the modulo of the bit offset operand. */ + +/* #define SHIFT_COUNT_TRUNCATED */ + +/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits + is done just by pretending it is already truncated. */ +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 + +/* A macro to update M and UNSIGNEDP when an object whose type is + TYPE and which has the specified mode and signedness is to be + stored in a register. This macro is only called when TYPE is a + scalar type. + + On i386 it is sometimes useful to promote HImode and QImode + quantities to SImode. The choice depends on target type. */ + +#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \ +do { \ + if (((MODE) == HImode && TARGET_PROMOTE_HI_REGS) \ + || ((MODE) == QImode && TARGET_PROMOTE_QI_REGS)) \ + (MODE) = SImode; \ +} while (0) + +/* Specify the machine mode that pointers have. + After generation of rtl, the compiler makes no further distinction + between pointers and any other objects of this machine mode. */ +#define Pmode (ix86_pmode == PMODE_DI ? DImode : SImode) + +/* A C expression whose value is zero if pointers that need to be extended + from being `POINTER_SIZE' bits wide to `Pmode' are sign-extended and + greater then zero if they are zero-extended and less then zero if the + ptr_extend instruction should be used. */ + +#define POINTERS_EXTEND_UNSIGNED 1 + +/* A function address in a call instruction + is a byte address (for indexing purposes) + so give the MEM rtx a byte's mode. */ +#define FUNCTION_MODE QImode + + +/* A C expression for the cost of a branch instruction. A value of 1 + is the default; other values are interpreted relative to that. */ + +#define BRANCH_COST(speed_p, predictable_p) \ + (!(speed_p) ? 2 : (predictable_p) ? 0 : ix86_branch_cost) + +/* An integer expression for the size in bits of the largest integer machine + mode that should actually be used. We allow pairs of registers. */ +#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_64BIT ? TImode : DImode) + +/* Define this macro as a C expression which is nonzero if accessing + less than a word of memory (i.e. a `char' or a `short') is no + faster than accessing a word of memory, i.e., if such access + require more than one instruction or if there is no difference in + cost between byte and (aligned) word loads. + + When this macro is not defined, the compiler will access a field by + finding the smallest containing object; when it is defined, a + fullword load will be used if alignment permits. Unless bytes + accesses are faster than word accesses, using word accesses is + preferable since it may eliminate subsequent memory access if + subsequent accesses occur to other fields in the same word of the + structure, but to different bytes. */ + +#define SLOW_BYTE_ACCESS 0 + +/* Nonzero if access to memory by shorts is slow and undesirable. */ +#define SLOW_SHORT_ACCESS 0 + +/* Define this macro to be the value 1 if unaligned accesses have a + cost many times greater than aligned accesses, for example if they + are emulated in a trap handler. + + When this macro is nonzero, the compiler will act as if + `STRICT_ALIGNMENT' were nonzero when generating code for block + moves. This can cause significantly more instructions to be + produced. Therefore, do not set this macro nonzero if unaligned + accesses only add a cycle or two to the time for a memory access. + + If the value of this macro is always zero, it need not be defined. */ + +/* #define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) 0 */ + +/* Define this macro if it is as good or better to call a constant + function address than to call an address kept in a register. + + Desirable on the 386 because a CALL with a constant address is + faster than one with a register address. */ + +#define NO_FUNCTION_CSE + +/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, + return the mode to be used for the comparison. + + For floating-point equality comparisons, CCFPEQmode should be used. + VOIDmode should be used in all other cases. + + For integer comparisons against zero, reduce to CCNOmode or CCZmode if + possible, to allow for more combinations. */ + +#define SELECT_CC_MODE(OP, X, Y) ix86_cc_mode ((OP), (X), (Y)) + +/* Return nonzero if MODE implies a floating point inequality can be + reversed. */ + +#define REVERSIBLE_CC_MODE(MODE) 1 + +/* A C expression whose value is reversed condition code of the CODE for + comparison done in CC_MODE mode. */ +#define REVERSE_CONDITION(CODE, MODE) ix86_reverse_condition ((CODE), (MODE)) + + +/* Control the assembler format that we output, to the extent + this does not vary between assemblers. */ + +/* How to refer to registers in assembler output. + This sequence is indexed by compiler's hard-register-number (see above). */ + +/* In order to refer to the first 8 regs as 32-bit regs, prefix an "e". + For non floating point regs, the following are the HImode names. + + For float regs, the stack top is sometimes referred to as "%st(0)" + instead of just "%st". TARGET_PRINT_OPERAND handles this with the + "y" code. */ + +#define HI_REGISTER_NAMES \ +{"ax","dx","cx","bx","si","di","bp","sp", \ + "st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)", \ + "argp", "flags", "fpsr", "fpcr", "frame", \ + "xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7", \ + "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", \ + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \ + "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"} + +#define REGISTER_NAMES HI_REGISTER_NAMES + +/* Table of additional register names to use in user input. */ + +#define ADDITIONAL_REGISTER_NAMES \ +{ { "eax", 0 }, { "edx", 1 }, { "ecx", 2 }, { "ebx", 3 }, \ + { "esi", 4 }, { "edi", 5 }, { "ebp", 6 }, { "esp", 7 }, \ + { "rax", 0 }, { "rdx", 1 }, { "rcx", 2 }, { "rbx", 3 }, \ + { "rsi", 4 }, { "rdi", 5 }, { "rbp", 6 }, { "rsp", 7 }, \ + { "al", 0 }, { "dl", 1 }, { "cl", 2 }, { "bl", 3 }, \ + { "ah", 0 }, { "dh", 1 }, { "ch", 2 }, { "bh", 3 } } + +/* Note we are omitting these since currently I don't know how +to get gcc to use these, since they want the same but different +number as al, and ax. +*/ + +#define QI_REGISTER_NAMES \ +{"al", "dl", "cl", "bl", "sil", "dil", "bpl", "spl",} + +/* These parallel the array above, and can be used to access bits 8:15 + of regs 0 through 3. */ + +#define QI_HIGH_REGISTER_NAMES \ +{"ah", "dh", "ch", "bh", } + +/* How to renumber registers for dbx and gdb. */ + +#define DBX_REGISTER_NUMBER(N) \ + (TARGET_64BIT ? dbx64_register_map[(N)] : dbx_register_map[(N)]) + +extern int const dbx_register_map[FIRST_PSEUDO_REGISTER]; +extern int const dbx64_register_map[FIRST_PSEUDO_REGISTER]; +extern int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER]; + +/* Before the prologue, RA is at 0(%esp). */ +#define INCOMING_RETURN_ADDR_RTX \ + gen_rtx_MEM (VOIDmode, gen_rtx_REG (VOIDmode, STACK_POINTER_REGNUM)) + +/* After the prologue, RA is at -4(AP) in the current frame. */ +#define RETURN_ADDR_RTX(COUNT, FRAME) \ + ((COUNT) == 0 \ + ? gen_rtx_MEM (Pmode, plus_constant (Pmode, arg_pointer_rtx, \ + -UNITS_PER_WORD)) \ + : gen_rtx_MEM (Pmode, plus_constant (Pmode, FRAME, UNITS_PER_WORD))) + +/* PC is dbx register 8; let's use that column for RA. */ +#define DWARF_FRAME_RETURN_COLUMN (TARGET_64BIT ? 16 : 8) + +/* Before the prologue, the top of the frame is at 4(%esp). */ +#define INCOMING_FRAME_SP_OFFSET UNITS_PER_WORD + +/* Describe how we implement __builtin_eh_return. */ +#define EH_RETURN_DATA_REGNO(N) ((N) <= DX_REG ? (N) : INVALID_REGNUM) +#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, CX_REG) + + +/* Select a format to encode pointers in exception handling data. CODE + is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is + true if the symbol may be affected by dynamic relocations. + + ??? All x86 object file formats are capable of representing this. + After all, the relocation needed is the same as for the call insn. + Whether or not a particular assembler allows us to enter such, I + guess we'll have to see. */ +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \ + asm_preferred_eh_data_format ((CODE), (GLOBAL)) + +/* This is how to output an insn to push a register on the stack. + It need not be very fast code. */ + +#define ASM_OUTPUT_REG_PUSH(FILE, REGNO) \ +do { \ + if (TARGET_64BIT) \ + asm_fprintf ((FILE), "\tpush{q}\t%%r%s\n", \ + reg_names[(REGNO)] + (REX_INT_REGNO_P (REGNO) != 0)); \ + else \ + asm_fprintf ((FILE), "\tpush{l}\t%%e%s\n", reg_names[(REGNO)]); \ +} while (0) + +/* This is how to output an insn to pop a register from the stack. + It need not be very fast code. */ + +#define ASM_OUTPUT_REG_POP(FILE, REGNO) \ +do { \ + if (TARGET_64BIT) \ + asm_fprintf ((FILE), "\tpop{q}\t%%r%s\n", \ + reg_names[(REGNO)] + (REX_INT_REGNO_P (REGNO) != 0)); \ + else \ + asm_fprintf ((FILE), "\tpop{l}\t%%e%s\n", reg_names[(REGNO)]); \ +} while (0) + +/* This is how to output an element of a case-vector that is absolute. */ + +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ + ix86_output_addr_vec_elt ((FILE), (VALUE)) + +/* This is how to output an element of a case-vector that is relative. */ + +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ + ix86_output_addr_diff_elt ((FILE), (VALUE), (REL)) + +/* When we see %v, we will print the 'v' prefix if TARGET_AVX is true. */ + +#define ASM_OUTPUT_AVX_PREFIX(STREAM, PTR) \ +{ \ + if ((PTR)[0] == '%' && (PTR)[1] == 'v') \ + (PTR) += TARGET_AVX ? 1 : 2; \ +} + +/* A C statement or statements which output an assembler instruction + opcode to the stdio stream STREAM. The macro-operand PTR is a + variable of type `char *' which points to the opcode name in + its "internal" form--the form that is written in the machine + description. */ + +#define ASM_OUTPUT_OPCODE(STREAM, PTR) \ + ASM_OUTPUT_AVX_PREFIX ((STREAM), (PTR)) + +/* A C statement to output to the stdio stream FILE an assembler + command to pad the location counter to a multiple of 1<machine->stack_locals) +#define ix86_varargs_gpr_size (cfun->machine->varargs_gpr_size) +#define ix86_varargs_fpr_size (cfun->machine->varargs_fpr_size) +#define ix86_optimize_mode_switching (cfun->machine->optimize_mode_switching) +#define ix86_current_function_needs_cld (cfun->machine->needs_cld) +#define ix86_tls_descriptor_calls_expanded_in_cfun \ + (cfun->machine->tls_descriptor_call_expanded_p) +/* Since tls_descriptor_call_expanded is not cleared, even if all TLS + calls are optimized away, we try to detect cases in which it was + optimized away. Since such instructions (use (reg REG_SP)), we can + verify whether there's any such instruction live by testing that + REG_SP is live. */ +#define ix86_current_function_calls_tls_descriptor \ + (ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG)) +#define ix86_static_chain_on_stack (cfun->machine->static_chain_on_stack) + +/* Control behavior of x86_file_start. */ +#define X86_FILE_START_VERSION_DIRECTIVE false +#define X86_FILE_START_FLTUSED false + +/* Flag to mark data that is in the large address area. */ +#define SYMBOL_FLAG_FAR_ADDR (SYMBOL_FLAG_MACH_DEP << 0) +#define SYMBOL_REF_FAR_ADDR_P(X) \ + ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_FAR_ADDR) != 0) + +/* Flags to mark dllimport/dllexport. Used by PE ports, but handy to + have defined always, to avoid ifdefing. */ +#define SYMBOL_FLAG_DLLIMPORT (SYMBOL_FLAG_MACH_DEP << 1) +#define SYMBOL_REF_DLLIMPORT_P(X) \ + ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_DLLIMPORT) != 0) + +#define SYMBOL_FLAG_DLLEXPORT (SYMBOL_FLAG_MACH_DEP << 2) +#define SYMBOL_REF_DLLEXPORT_P(X) \ + ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_DLLEXPORT) != 0) + +extern void debug_ready_dispatch (void); +extern void debug_dispatch_window (int); + +/* The value at zero is only defined for the BMI instructions + LZCNT and TZCNT, not the BSR/BSF insns in the original isa. */ +#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \ + ((VALUE) = GET_MODE_BITSIZE (MODE), TARGET_BMI) +#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \ + ((VALUE) = GET_MODE_BITSIZE (MODE), TARGET_LZCNT) + + +/* Flags returned by ix86_get_callcvt (). */ +#define IX86_CALLCVT_CDECL 0x1 +#define IX86_CALLCVT_STDCALL 0x2 +#define IX86_CALLCVT_FASTCALL 0x4 +#define IX86_CALLCVT_THISCALL 0x8 +#define IX86_CALLCVT_REGPARM 0x10 +#define IX86_CALLCVT_SSEREGPARM 0x20 + +#define IX86_BASE_CALLCVT(FLAGS) \ + ((FLAGS) & (IX86_CALLCVT_CDECL | IX86_CALLCVT_STDCALL \ + | IX86_CALLCVT_FASTCALL | IX86_CALLCVT_THISCALL)) + +#define RECIP_MASK_NONE 0x00 +#define RECIP_MASK_DIV 0x01 +#define RECIP_MASK_SQRT 0x02 +#define RECIP_MASK_VEC_DIV 0x04 +#define RECIP_MASK_VEC_SQRT 0x08 +#define RECIP_MASK_ALL (RECIP_MASK_DIV | RECIP_MASK_SQRT \ + | RECIP_MASK_VEC_DIV | RECIP_MASK_VEC_SQRT) +#define RECIP_MASK_DEFAULT (RECIP_MASK_VEC_DIV | RECIP_MASK_VEC_SQRT) + +#define TARGET_RECIP_DIV ((recip_mask & RECIP_MASK_DIV) != 0) +#define TARGET_RECIP_SQRT ((recip_mask & RECIP_MASK_SQRT) != 0) +#define TARGET_RECIP_VEC_DIV ((recip_mask & RECIP_MASK_VEC_DIV) != 0) +#define TARGET_RECIP_VEC_SQRT ((recip_mask & RECIP_MASK_VEC_SQRT) != 0) + +#define IX86_HLE_ACQUIRE (1 << 16) +#define IX86_HLE_RELEASE (1 << 17) + +/* +Local variables: +version-control: t +End: +*/ diff --git a/src/include/config/i386/linux-common.h b/src/include/config/i386/linux-common.h new file mode 100644 index 0000000..1e8bf6b --- /dev/null +++ b/src/include/config/i386/linux-common.h @@ -0,0 +1,55 @@ +/* Definitions for Intel 386 running Linux-based GNU systems with ELF format. + Copyright (C) 2012-2013 Free Software Foundation, Inc. + Contributed by Ilya Enkovich. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#undef TARGET_OS_CPP_BUILTINS +#define TARGET_OS_CPP_BUILTINS() \ + do \ + { \ + GNU_USER_TARGET_OS_CPP_BUILTINS(); \ + ANDROID_TARGET_OS_CPP_BUILTINS(); \ + } \ + while (0) + +#undef CC1_SPEC +#define CC1_SPEC \ + LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \ + GNU_USER_TARGET_CC1_SPEC " " ANDROID_CC1_SPEC) + +#undef LINK_SPEC +#define LINK_SPEC \ + LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LINK_SPEC, \ + GNU_USER_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC) + +#undef LIB_SPEC +#define LIB_SPEC \ + LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LIB_SPEC, \ + GNU_USER_TARGET_LIB_SPEC " " ANDROID_LIB_SPEC) + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC \ + LINUX_OR_ANDROID_LD (GNU_USER_TARGET_STARTFILE_SPEC, \ + ANDROID_STARTFILE_SPEC) + +#undef ENDFILE_SPEC +#define ENDFILE_SPEC \ + LINUX_OR_ANDROID_LD (GNU_USER_TARGET_MATHFILE_SPEC " " \ + GNU_USER_TARGET_ENDFILE_SPEC, \ + GNU_USER_TARGET_MATHFILE_SPEC " " \ + ANDROID_ENDFILE_SPEC) diff --git a/src/include/config/i386/linux64.h b/src/include/config/i386/linux64.h new file mode 100644 index 0000000..b793e08 --- /dev/null +++ b/src/include/config/i386/linux64.h @@ -0,0 +1,32 @@ +/* Definitions for AMD x86-64 running Linux-based GNU systems with ELF format. + Copyright (C) 2001-2013 Free Software Foundation, Inc. + Contributed by Jan Hubicka , based on linux.h. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#define GNU_USER_LINK_EMULATION32 "elf_i386" +#define GNU_USER_LINK_EMULATION64 "elf_x86_64" +#define GNU_USER_LINK_EMULATIONX32 "elf32_x86_64" + +#define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2" +#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2" +#define GLIBC_DYNAMIC_LINKERX32 "/libx32/ld-linux-x32.so.2" diff --git a/src/include/config/i386/unix.h b/src/include/config/i386/unix.h new file mode 100644 index 0000000..0eeee4d --- /dev/null +++ b/src/include/config/i386/unix.h @@ -0,0 +1,80 @@ +/* Definitions for Unix assembler syntax for the Intel 80386. + Copyright (C) 1988-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* This file defines the aspects of assembler syntax + that are the same for all the i386 Unix systems + (though they may differ in non-Unix systems). */ + +/* Define macro used to output shift-double opcodes when the shift + count is in %cl. Some assemblers require %cl as an argument; + some don't. This macro controls what to do: by default, don't + print %cl. */ +#define SHIFT_DOUBLE_OMITS_COUNT 1 + +/* Define the syntax of pseudo-ops, labels and comments. */ + +/* String containing the assembler's comment-starter. + Note the trailing space is necessary in case the character + that immediately follows the comment is '*'. If this happens + and the space is not there the assembler will interpret this + as the start of a C-like slash-star comment and complain when + there is no terminator. */ + +#define ASM_COMMENT_START "/ " + +/* Output to assembler file text saying following lines + may contain character constants, extra white space, comments, etc. */ + +#define ASM_APP_ON "/APP\n" + +/* Output to assembler file text saying following lines + no longer contain unusual constructs. */ + +#define ASM_APP_OFF "/NO_APP\n" + +/* Output before read-only data. */ + +#define TEXT_SECTION_ASM_OP "\t.text" + +/* Output before writable (initialized) data. */ + +#define DATA_SECTION_ASM_OP "\t.data" + +/* Output before writable (uninitialized) data. */ + +#define BSS_SECTION_ASM_OP "\t.bss" + +/* Globalizing directive for a label. */ +#define GLOBAL_ASM_OP "\t.globl\t" + +/* By default, target has a 80387, uses IEEE compatible arithmetic, + and returns float values in the 387. */ +#undef TARGET_SUBTARGET_DEFAULT +#define TARGET_SUBTARGET_DEFAULT \ + (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS) + +/* By default, 64-bit mode uses 128-bit long double. */ +#undef TARGET_SUBTARGET64_DEFAULT +#define TARGET_SUBTARGET64_DEFAULT \ + MASK_128BIT_LONG_DOUBLE diff --git a/src/include/config/i386/x86-64.h b/src/include/config/i386/x86-64.h new file mode 100644 index 0000000..66f96d9 --- /dev/null +++ b/src/include/config/i386/x86-64.h @@ -0,0 +1,108 @@ +/* OS independent definitions for AMD x86-64. + Copyright (C) 2001-2013 Free Software Foundation, Inc. + Contributed by Bo Thorsen . + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#undef ASM_COMMENT_START +#define ASM_COMMENT_START "#" + +#undef DBX_REGISTER_NUMBER +#define DBX_REGISTER_NUMBER(n) \ + (TARGET_64BIT ? dbx64_register_map[n] : svr4_dbx_register_map[n]) + +/* Output assembler code to FILE to call the profiler. */ +#define NO_PROFILE_COUNTERS 1 + +#undef MCOUNT_NAME +#define MCOUNT_NAME "mcount" + +#undef SIZE_TYPE +#define SIZE_TYPE (TARGET_LP64 ? "long unsigned int" : "unsigned int") + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE (TARGET_LP64 ? "long int" : "int") + +#undef WCHAR_TYPE +#define WCHAR_TYPE "int" + +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE 32 + +#undef ASM_SPEC +#define ASM_SPEC "%{m32:--32} %{m64:--64}" + +#undef ASM_OUTPUT_ALIGNED_BSS +#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ + x86_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN) + +#undef ASM_OUTPUT_ALIGNED_COMMON +#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \ + x86_elf_aligned_common (FILE, NAME, SIZE, ALIGN); + +/* This is used to align code labels according to Intel recommendations. */ + +#ifdef HAVE_GAS_MAX_SKIP_P2ALIGN +#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \ + do { \ + if ((LOG) != 0) { \ + if ((MAX_SKIP) == 0) fprintf ((FILE), "\t.p2align %d\n", (LOG)); \ + else { \ + fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \ + /* Make sure that we have at least 8 byte alignment if > 8 byte \ + alignment is preferred. */ \ + if ((LOG) > 3 \ + && (1 << (LOG)) > ((MAX_SKIP) + 1) \ + && (MAX_SKIP) >= 7) \ + fputs ("\t.p2align 3\n", (FILE)); \ + } \ + } \ + } while (0) +#undef ASM_OUTPUT_MAX_SKIP_PAD +#define ASM_OUTPUT_MAX_SKIP_PAD(FILE, LOG, MAX_SKIP) \ + if ((LOG) != 0) \ + { \ + if ((MAX_SKIP) == 0) \ + fprintf ((FILE), "\t.p2align %d\n", (LOG)); \ + else \ + fprintf ((FILE), "\t.p2align %d,,%d\n", (LOG), (MAX_SKIP)); \ + } +#endif + + +/* i386 System V Release 4 uses DWARF debugging info. + x86-64 ABI specifies DWARF2. */ + +#define DWARF2_DEBUGGING_INFO 1 +#define DWARF2_UNWIND_INFO 1 + +#undef PREFERRED_DEBUGGING_TYPE +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG + +#undef TARGET_ASM_SELECT_SECTION +#define TARGET_ASM_SELECT_SECTION x86_64_elf_select_section + +#undef TARGET_ASM_UNIQUE_SECTION +#define TARGET_ASM_UNIQUE_SECTION x86_64_elf_unique_section + +#undef TARGET_SECTION_TYPE_FLAGS +#define TARGET_SECTION_TYPE_FLAGS x86_64_elf_section_type_flags diff --git a/src/include/config/initfini-array.h b/src/include/config/initfini-array.h new file mode 100644 index 0000000..b14870a --- /dev/null +++ b/src/include/config/initfini-array.h @@ -0,0 +1,40 @@ +/* Definitions for ELF systems with .init_array/.fini_array section + support. + Copyright (C) 2011-2013 Free Software Foundation, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#ifdef HAVE_INITFINI_ARRAY_SUPPORT + +#define USE_INITFINI_ARRAY + +#undef INIT_SECTION_ASM_OP +#undef FINI_SECTION_ASM_OP + +#undef INIT_ARRAY_SECTION_ASM_OP +#define INIT_ARRAY_SECTION_ASM_OP + +#undef FINI_ARRAY_SECTION_ASM_OP +#define FINI_ARRAY_SECTION_ASM_OP + +/* Use .init_array/.fini_array section for constructors and destructors. */ +#undef TARGET_ASM_CONSTRUCTOR +#define TARGET_ASM_CONSTRUCTOR default_elf_init_array_asm_out_constructor +#undef TARGET_ASM_DESTRUCTOR +#define TARGET_ASM_DESTRUCTOR default_elf_fini_array_asm_out_destructor + +#endif diff --git a/src/include/config/linux-android.h b/src/include/config/linux-android.h new file mode 100644 index 0000000..2c87c84 --- /dev/null +++ b/src/include/config/linux-android.h @@ -0,0 +1,59 @@ +/* Configuration file for Linux Android targets. + Copyright (C) 2008-2013 Free Software Foundation, Inc. + Contributed by Doug Kwan (dougkwan@google.com) + Rewritten by CodeSourcery, Inc. + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + . */ + +#define ANDROID_TARGET_OS_CPP_BUILTINS() \ + do { \ + if (TARGET_ANDROID) \ + builtin_define ("__ANDROID__"); \ + } while (0) + +#if ANDROID_DEFAULT +# define NOANDROID "mno-android" +#else +# define NOANDROID "!mandroid" +#endif + +#define LINUX_OR_ANDROID_CC(LINUX_SPEC, ANDROID_SPEC) \ + "%{" NOANDROID "|tno-android-cc:" LINUX_SPEC ";:" ANDROID_SPEC "}" + +#define LINUX_OR_ANDROID_LD(LINUX_SPEC, ANDROID_SPEC) \ + "%{" NOANDROID "|tno-android-ld:" LINUX_SPEC ";:" ANDROID_SPEC "}" + +#define ANDROID_LINK_SPEC \ + "%{shared: -Bsymbolic}" + +#define ANDROID_CC1_SPEC \ + "%{!mglibc:%{!muclibc:%{!mbionic: -mbionic}}} " \ + "%{!fno-pic:%{!fno-PIC:%{!fpic:%{!fPIC: -fPIC}}}}" + +#define ANDROID_CC1PLUS_SPEC \ + "%{!fexceptions:%{!fno-exceptions: -fno-exceptions}} " \ + "%{!frtti:%{!fno-rtti: -fno-rtti}}" + +#define ANDROID_LIB_SPEC \ + "%{!static: -ldl}" + +#define ANDROID_STARTFILE_SPEC \ + "%{shared: crtbegin_so%O%s;:" \ + " %{static: crtbegin_static%O%s;: crtbegin_dynamic%O%s}}" + +#define ANDROID_ENDFILE_SPEC \ + "%{shared: crtend_so%O%s;: crtend_android%O%s}" diff --git a/src/include/config/linux.h b/src/include/config/linux.h new file mode 100644 index 0000000..2be1079 --- /dev/null +++ b/src/include/config/linux.h @@ -0,0 +1,109 @@ +/* Definitions for systems using the Linux kernel, with or without + MMU, using ELF at the compiler level but possibly FLT for final + linked executables and shared libraries in some no-MMU cases, and + possibly with a choice of libc implementations. + Copyright (C) 1995-2013 Free Software Foundation, Inc. + Contributed by Eric Youngdale. + Modified for stabs-in-ELF by H.J. Lu (hjl@lucon.org). + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* C libraries supported on Linux. */ +#ifdef SINGLE_LIBC +#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC) +#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC) +#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC) +#else +#define OPTION_GLIBC (linux_libc == LIBC_GLIBC) +#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC) +#define OPTION_BIONIC (linux_libc == LIBC_BIONIC) +#endif + +#define GNU_USER_TARGET_OS_CPP_BUILTINS() \ + do { \ + if (OPTION_GLIBC) \ + builtin_define ("__gnu_linux__"); \ + builtin_define_std ("linux"); \ + builtin_define_std ("unix"); \ + builtin_assert ("system=linux"); \ + builtin_assert ("system=unix"); \ + builtin_assert ("system=posix"); \ + } while (0) + +/* Determine which dynamic linker to use depending on whether GLIBC or + uClibc or Bionic is the default C library and whether + -muclibc or -mglibc or -mbionic has been passed to change the default. */ + +#define CHOOSE_DYNAMIC_LINKER1(LIBC1, LIBC2, LIBC3, LD1, LD2, LD3) \ + "%{" LIBC2 ":" LD2 ";:%{" LIBC3 ":" LD3 ";:" LD1 "}}" + +#if DEFAULT_LIBC == LIBC_GLIBC +#define CHOOSE_DYNAMIC_LINKER(G, U, B) \ + CHOOSE_DYNAMIC_LINKER1 ("mglibc", "muclibc", "mbionic", G, U, B) +#elif DEFAULT_LIBC == LIBC_UCLIBC +#define CHOOSE_DYNAMIC_LINKER(G, U, B) \ + CHOOSE_DYNAMIC_LINKER1 ("muclibc", "mglibc", "mbionic", U, G, B) +#elif DEFAULT_LIBC == LIBC_BIONIC +#define CHOOSE_DYNAMIC_LINKER(G, U, B) \ + CHOOSE_DYNAMIC_LINKER1 ("mbionic", "mglibc", "muclibc", B, G, U) +#else +#error "Unsupported DEFAULT_LIBC" +#endif /* DEFAULT_LIBC */ + +/* For most targets the following definitions suffice; + GLIBC_DYNAMIC_LINKER must be defined for each target using them, or + GLIBC_DYNAMIC_LINKER32 and GLIBC_DYNAMIC_LINKER64 for targets + supporting both 32-bit and 64-bit compilation. */ +#define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" +#define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0" +#define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0" +#define UCLIBC_DYNAMIC_LINKERX32 "/lib/ldx32-uClibc.so.0" +#define BIONIC_DYNAMIC_LINKER "/system/bin/linker" +#define BIONIC_DYNAMIC_LINKER32 "/system/bin/linker" +#define BIONIC_DYNAMIC_LINKER64 "/system/bin/linker64" +#define BIONIC_DYNAMIC_LINKERX32 "/system/bin/linkerx32" + +#define GNU_USER_DYNAMIC_LINKER \ + CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER, \ + BIONIC_DYNAMIC_LINKER) +#define GNU_USER_DYNAMIC_LINKER32 \ + CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER32, UCLIBC_DYNAMIC_LINKER32, \ + BIONIC_DYNAMIC_LINKER32) +#define GNU_USER_DYNAMIC_LINKER64 \ + CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, \ + BIONIC_DYNAMIC_LINKER64) +#define GNU_USER_DYNAMIC_LINKERX32 \ + CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \ + BIONIC_DYNAMIC_LINKERX32) + +/* Determine whether the entire c99 runtime + is present in the runtime library. */ +#undef TARGET_C99_FUNCTIONS +#define TARGET_C99_FUNCTIONS (OPTION_GLIBC) + +/* Whether we have sincos that follows the GNU extension. */ +#undef TARGET_HAS_SINCOS +#define TARGET_HAS_SINCOS (OPTION_GLIBC || OPTION_BIONIC) + +/* Whether we have Bionic libc runtime */ +#undef TARGET_HAS_BIONIC +#define TARGET_HAS_BIONIC (OPTION_BIONIC) diff --git a/src/include/config/vxworks-dummy.h b/src/include/config/vxworks-dummy.h new file mode 100644 index 0000000..b390edb --- /dev/null +++ b/src/include/config/vxworks-dummy.h @@ -0,0 +1,40 @@ +/* Dummy definitions of VxWorks-related macros + Copyright (C) 2007-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* True if we're targeting VxWorks. */ +#ifndef TARGET_VXWORKS +#define TARGET_VXWORKS 0 +#endif + +/* True if generating code for a VxWorks RTP. */ +#ifndef TARGET_VXWORKS_RTP +#define TARGET_VXWORKS_RTP false +#endif + +/* The symbol that points to an RTP's table of GOTs. */ +#define VXWORKS_GOTT_BASE (gcc_unreachable (), "") + +/* The symbol that holds the index of the current module's GOT in + VXWORKS_GOTT_BASE. */ +#define VXWORKS_GOTT_INDEX (gcc_unreachable (), "") diff --git a/src/include/configargs.h b/src/include/configargs.h new file mode 100644 index 0000000..3712247 --- /dev/null +++ b/src/include/configargs.h @@ -0,0 +1,7 @@ +/* Generated automatically. */ +static const char configuration_arguments[] = "../configure --prefix=/home/zet/bin/gcc-48 --disable-bootstrap --enable-languages=c,c++ --enable-shared --enable-threads=posix --enable-lto --enable-plugin --enable-gold=yes --without-included-gettext --enable-nls --disable-libmudflap --disable-browser-plugin --disable-werror"; +static const char thread_model[] = "posix"; + +static const struct { + const char *name, *value; +} configure_default_options[] = { { "cpu", "generic" }, { "arch", "x86-64" } }; diff --git a/src/include/coretypes.h b/src/include/coretypes.h new file mode 100644 index 0000000..320b4dd --- /dev/null +++ b/src/include/coretypes.h @@ -0,0 +1,208 @@ +/* GCC core type declarations. + Copyright (C) 2002-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +/* Provide forward declarations of core types which are referred to by + most of the compiler. This allows header files to use these types + (e.g. in function prototypes) without concern for whether the full + definitions are visible. Some other declarations that need to be + universally visible are here, too. + + In the context of tconfig.h, most of these have special definitions + which prevent them from being used except in further type + declarations. This is a kludge; the right thing is to avoid + including the "tm.h" header set in the context of tconfig.h, but + we're not there yet. */ + +#ifndef GCC_CORETYPES_H +#define GCC_CORETYPES_H + +#ifndef GTY +#define GTY(x) /* nothing - marker for gengtype */ +#endif + +#ifndef USED_FOR_TARGET + +struct bitmap_head_def; +typedef struct bitmap_head_def *bitmap; +typedef const struct bitmap_head_def *const_bitmap; +struct simple_bitmap_def; +typedef struct simple_bitmap_def *sbitmap; +typedef const struct simple_bitmap_def *const_sbitmap; +struct rtx_def; +typedef struct rtx_def *rtx; +typedef const struct rtx_def *const_rtx; +struct rtvec_def; +typedef struct rtvec_def *rtvec; +typedef const struct rtvec_def *const_rtvec; +union tree_node; +typedef union tree_node *tree; +typedef const union tree_node *const_tree; +union gimple_statement_d; +typedef union gimple_statement_d *gimple; +typedef const union gimple_statement_d *const_gimple; +typedef gimple gimple_seq; +union section; +typedef union section section; +struct gcc_options; +struct cl_target_option; +struct cl_optimization; +struct cl_option; +struct cl_decoded_option; +struct cl_option_handlers; +struct diagnostic_context; +typedef struct diagnostic_context diagnostic_context; +struct pretty_print_info; +typedef struct pretty_print_info pretty_printer; + +/* Address space number for named address space support. */ +typedef unsigned char addr_space_t; + +/* The value of addr_space_t that represents the generic address space. */ +#define ADDR_SPACE_GENERIC 0 +#define ADDR_SPACE_GENERIC_P(AS) ((AS) == ADDR_SPACE_GENERIC) + +/* The major intermediate representations of GCC. */ +enum ir_type { + IR_GIMPLE, + IR_RTL_CFGRTL, + IR_RTL_CFGLAYOUT +}; + +/* Provide forward struct declaration so that we don't have to include + all of cpplib.h whenever a random prototype includes a pointer. + Note that the cpp_reader and cpp_token typedefs remain part of + cpplib.h. */ + +struct cpp_reader; +struct cpp_token; + +/* The thread-local storage model associated with a given VAR_DECL + or SYMBOL_REF. This isn't used much, but both trees and RTL refer + to it, so it's here. */ +enum tls_model { + TLS_MODEL_NONE, + TLS_MODEL_EMULATED, + TLS_MODEL_REAL, + TLS_MODEL_GLOBAL_DYNAMIC = TLS_MODEL_REAL, + TLS_MODEL_LOCAL_DYNAMIC, + TLS_MODEL_INITIAL_EXEC, + TLS_MODEL_LOCAL_EXEC +}; + +/* Types of unwind/exception handling info that can be generated. */ + +enum unwind_info_type +{ + UI_NONE, + UI_SJLJ, + UI_DWARF2, + UI_TARGET, + UI_SEH +}; + +/* Callgraph node profile representation. */ +enum node_frequency { + /* This function most likely won't be executed at all. + (set only when profile feedback is available or via function attribute). */ + NODE_FREQUENCY_UNLIKELY_EXECUTED, + /* For functions that are known to be executed once (i.e. constructors, destructors + and main function. */ + NODE_FREQUENCY_EXECUTED_ONCE, + /* The default value. */ + NODE_FREQUENCY_NORMAL, + /* Optimize this function hard + (set only when profile feedback is available or via function attribute). */ + NODE_FREQUENCY_HOT +}; + +/* Possible initialization status of a variable. When requested + by the user, this information is tracked and recorded in the DWARF + debug information, along with the variable's location. */ +enum var_init_status +{ + VAR_INIT_STATUS_UNKNOWN, + VAR_INIT_STATUS_UNINITIALIZED, + VAR_INIT_STATUS_INITIALIZED +}; + + +struct edge_def; +typedef struct edge_def *edge; +typedef const struct edge_def *const_edge; +struct basic_block_def; +typedef struct basic_block_def *basic_block; +typedef const struct basic_block_def *const_basic_block; + +#define obstack_chunk_alloc ((void *(*) (long)) xmalloc) +#define obstack_chunk_free ((void (*) (void *)) free) +#define OBSTACK_CHUNK_SIZE 0 +#define gcc_obstack_init(OBSTACK) \ + _obstack_begin ((OBSTACK), OBSTACK_CHUNK_SIZE, 0, \ + obstack_chunk_alloc, \ + obstack_chunk_free) + +/* enum reg_class is target specific, so it should not appear in + target-independent code or interfaces, like the target hook declarations + in target.h. */ +typedef int reg_class_t; + +#else + +struct _dont_use_rtx_here_; +struct _dont_use_rtvec_here_; +union _dont_use_tree_here_; +#define rtx struct _dont_use_rtx_here_ * +#define const_rtx struct _dont_use_rtx_here_ * +#define rtvec struct _dont_use_rtvec_here * +#define const_rtvec struct _dont_use_rtvec_here * +#define tree union _dont_use_tree_here_ * +#define const_tree union _dont_use_tree_here_ * + +#endif + +/* Memory model types for the __atomic* builtins. + This must match the order in libstdc++-v3/include/bits/atomic_base.h. */ +enum memmodel +{ + MEMMODEL_RELAXED = 0, + MEMMODEL_CONSUME = 1, + MEMMODEL_ACQUIRE = 2, + MEMMODEL_RELEASE = 3, + MEMMODEL_ACQ_REL = 4, + MEMMODEL_SEQ_CST = 5, + MEMMODEL_LAST = 6 +}; + +/* Suppose that higher bits are target dependant. */ +#define MEMMODEL_MASK ((1<<16)-1) + +/* Support for user-provided GGC and PCH markers. The first parameter + is a pointer to a pointer, the second a cookie. */ +typedef void (*gt_pointer_operator) (void *, void *); + +#if !defined (HAVE_UCHAR) +typedef unsigned char uchar; +#endif + +#endif /* coretypes.h */ diff --git a/src/include/cp/cp-tree.def b/src/include/cp/cp-tree.def new file mode 100644 index 0000000..bd9bfa8 --- /dev/null +++ b/src/include/cp/cp-tree.def @@ -0,0 +1,479 @@ +/* This file contains the definitions and documentation for the + additional tree codes used in the GNU C++ compiler (see tree.def + for the standard codes). + Copyright (C) 1987-2013 Free Software Foundation, Inc. + Hacked by Michael Tiemann (tiemann@cygnus.com) + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + + +/* An OFFSET_REF is used in two situations: + + 1. An expression of the form `A::m' where `A' is a class and `m' is + a non-static member. In this case, operand 0 will be a TYPE + (corresponding to `A') and operand 1 will be a FIELD_DECL, + BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m'). + + The expression is a pointer-to-member if its address is taken, + but simply denotes a member of the object if its address is not + taken. + + This form is only used during the parsing phase; once semantic + analysis has taken place they are eliminated. + + 2. An expression of the form `x.*p'. In this case, operand 0 will + be an expression corresponding to `x' and operand 1 will be an + expression with pointer-to-member type. */ +DEFTREECODE (OFFSET_REF, "offset_ref", tcc_reference, 2) + +/* A pointer-to-member constant. For a pointer-to-member constant + `X::Y' The PTRMEM_CST_CLASS is the RECORD_TYPE for `X' and the + PTRMEM_CST_MEMBER is the _DECL for `Y'. */ +DEFTREECODE (PTRMEM_CST, "ptrmem_cst", tcc_constant, 0) + +/* For NEW_EXPR, operand 0 is the placement list. + Operand 1 is the new-declarator. + Operand 2 is the number of elements in the array. + Operand 3 is the initializer. */ +DEFTREECODE (NEW_EXPR, "nw_expr", tcc_expression, 4) +DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", tcc_expression, 3) + +/* For DELETE_EXPR, operand 0 is the store to be destroyed. + Operand 1 is the value to pass to the destroying function + saying whether the store should be deallocated as well. */ +DEFTREECODE (DELETE_EXPR, "dl_expr", tcc_expression, 2) +DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", tcc_expression, 2) + +/* Value is reference to particular overloaded class method. + Operand 0 is the class, operand 1 is the field + The COMPLEXITY field holds the class level (usually 0). */ +DEFTREECODE (SCOPE_REF, "scope_ref", tcc_reference, 2) + +/* When composing an object with a member, this is the result. + Operand 0 is the object. Operand 1 is the member (usually + a dereferenced pointer to member). */ +DEFTREECODE (MEMBER_REF, "member_ref", tcc_reference, 2) + +/* Type conversion operator in C++. TREE_TYPE is type that this + operator converts to. Operand is expression to be converted. */ +DEFTREECODE (TYPE_EXPR, "type_expr", tcc_expression, 1) + +/* AGGR_INIT_EXPRs have a variably-sized representation similar to + that of CALL_EXPRs. Operand 0 is an INTEGER_CST node containing the + operand count, operand 1 is the function which performs initialization, + operand 2 is the slot which was allocated for this expression, and + the remaining operands are the arguments to the initialization function. */ +DEFTREECODE (AGGR_INIT_EXPR, "aggr_init_expr", tcc_vl_exp, 3) + +/* Initialization of an array from another array, expressed at a high level + so that it works with TARGET_EXPR. Operand 0 is the target, operand 1 + is the initializer. */ +DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", tcc_expression, 2) + +/* A throw expression. operand 0 is the expression, if there was one, + else it is NULL_TREE. */ +DEFTREECODE (THROW_EXPR, "throw_expr", tcc_expression, 1) + +/* An empty class object. The TREE_TYPE gives the class type. We use + these to avoid actually creating instances of the empty classes. */ +DEFTREECODE (EMPTY_CLASS_EXPR, "empty_class_expr", tcc_expression, 0) + +/* A reference to a member function or member functions from a base + class. BASELINK_FUNCTIONS gives the FUNCTION_DECL, + TEMPLATE_DECL, OVERLOAD, or TEMPLATE_ID_EXPR corresponding to the + functions. BASELINK_BINFO gives the base from which the functions + come, i.e., the base to which the `this' pointer must be converted + before the functions are called. BASELINK_ACCESS_BINFO gives the + base used to name the functions. + + A BASELINK is an expression; the TREE_TYPE of the BASELINK gives + the type of the expression. This type is either a FUNCTION_TYPE, + METHOD_TYPE, or `unknown_type_node' indicating that the function is + overloaded. */ +DEFTREECODE (BASELINK, "baselink", tcc_exceptional, 0) + +/* Template definition. The following fields have the specified uses, + although there are other macros in cp-tree.h that should be used for + accessing this data. + DECL_ARGUMENTS template parm vector + DECL_TEMPLATE_INFO template text &c + DECL_VINDEX list of instantiations already produced; + only done for functions so far + For class template: + DECL_INITIAL associated templates (methods &c) + DECL_TEMPLATE_RESULT null + For non-class templates: + TREE_TYPE type of object to be constructed + DECL_TEMPLATE_RESULT decl for object to be created + (e.g., FUNCTION_DECL with tmpl parms used) + */ +DEFTREECODE (TEMPLATE_DECL, "template_decl", tcc_declaration, 0) + +/* Index into a template parameter list. The TEMPLATE_PARM_IDX gives + the index (from 0) of the parameter, while the TEMPLATE_PARM_LEVEL + gives the level (from 1) of the parameter. + + Here's an example: + + template // Index 0, Level 1. + struct S + { + template // Index 1, Level 2. + void f(); + }; + + The DESCENDANTS will be a chain of TEMPLATE_PARM_INDEXs descended + from this one. The first descendant will have the same IDX, but + its LEVEL will be one less. The TREE_CHAIN field is used to chain + together the descendants. The TEMPLATE_PARM_DECL is the + declaration of this parameter, either a TYPE_DECL or CONST_DECL. + The TEMPLATE_PARM_ORIG_LEVEL is the LEVEL of the most distant + parent, i.e., the LEVEL that the parameter originally had when it + was declared. For example, if we instantiate S, we will have: + + struct S + { + template // Index 1, Level 1, Orig Level 2 + void f(); + }; + + The LEVEL is the level of the parameter when we are worrying about + the types of things; the ORIG_LEVEL is the level when we are + worrying about instantiating things. */ +DEFTREECODE (TEMPLATE_PARM_INDEX, "template_parm_index", tcc_exceptional, 0) + +/* Index into a template parameter list for template template parameters. + This parameter must be a type. The TYPE_FIELDS value will be a + TEMPLATE_PARM_INDEX. + + It is used without template arguments like TT in C, + TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO is NULL_TREE + and TYPE_NAME is a TEMPLATE_DECL. */ +DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", tcc_type, 0) + +/* The ordering of the following codes is optimized for the checking + macros in tree.h. Changing the order will degrade the speed of the + compiler. TEMPLATE_TYPE_PARM, TYPENAME_TYPE, TYPEOF_TYPE, + BOUND_TEMPLATE_TEMPLATE_PARM. */ + +/* Index into a template parameter list. This parameter must be a type. + The type.values field will be a TEMPLATE_PARM_INDEX. */ +DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", tcc_type, 0) + +/* A type designated by `typename T::t'. TYPE_CONTEXT is `T', + TYPE_NAME is an IDENTIFIER_NODE for `t'. If the type was named via + template-id, TYPENAME_TYPE_FULLNAME will hold the TEMPLATE_ID_EXPR. + TREE_TYPE is always NULL. */ +DEFTREECODE (TYPENAME_TYPE, "typename_type", tcc_type, 0) + +/* A type designated by `__typeof (expr)'. TYPEOF_TYPE_EXPR is the + expression in question. */ +DEFTREECODE (TYPEOF_TYPE, "typeof_type", tcc_type, 0) + +/* Like TEMPLATE_TEMPLATE_PARM it is used with bound template arguments + like TT. + In this case, TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO contains the + template name and its bound arguments. TYPE_NAME is a TYPE_DECL. */ +DEFTREECODE (BOUND_TEMPLATE_TEMPLATE_PARM, "bound_template_template_parm", + tcc_type, 0) + +/* For template template argument of the form `T::template C'. + TYPE_CONTEXT is `T', the template parameter dependent object. + TYPE_NAME is an IDENTIFIER_NODE for `C', the member class template. */ +DEFTREECODE (UNBOUND_CLASS_TEMPLATE, "unbound_class_template", tcc_type, 0) + +/* A using declaration. USING_DECL_SCOPE contains the specified + scope. In a member using decl, unless DECL_DEPENDENT_P is true, + USING_DECL_DECLS contains the _DECL or OVERLOAD so named. This is + not an alias, but is later expanded into multiple aliases. */ +DEFTREECODE (USING_DECL, "using_decl", tcc_declaration, 0) + +/* A using directive. The operand is USING_STMT_NAMESPACE. */ +DEFTREECODE (USING_STMT, "using_stmt", tcc_statement, 1) + +/* An un-parsed default argument. Holds a vector of input tokens and + a vector of places where the argument was instantiated before + parsing had occurred. */ +DEFTREECODE (DEFAULT_ARG, "default_arg", tcc_exceptional, 0) + +/* An uninstantiated noexcept-specification. DEFERRED_NOEXCEPT_PATTERN is + the pattern from the template, and DEFERRED_NOEXCEPT_ARGS are the + template arguments to substitute into the pattern when needed. */ +DEFTREECODE (DEFERRED_NOEXCEPT, "deferred_noexcept", tcc_exceptional, 0) + +/* A template-id, like foo. The first operand is the template. + The second is NULL if there are no explicit arguments, or a + TREE_VEC of arguments. The template will be a FUNCTION_DECL, + TEMPLATE_DECL, or an OVERLOAD. If the template-id refers to a + member template, the template may be an IDENTIFIER_NODE. */ +DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", tcc_expression, 2) + +/* A list-like node for chaining overloading candidates. TREE_TYPE is + the original name, and the parameter is the FUNCTION_DECL. */ +DEFTREECODE (OVERLOAD, "overload", tcc_exceptional, 0) + +/* A pseudo-destructor, of the form "OBJECT.~DESTRUCTOR" or + "OBJECT.SCOPE::~DESTRUCTOR. The first operand is the OBJECT. The + second operand (if non-NULL) is the SCOPE. The third operand is + the TYPE node corresponding to the DESTRUCTOR. The type of the + first operand will always be a scalar type. + + The type of a PSEUDO_DTOR_EXPR is always "void", even though it can + be used as if it were a zero-argument function. We handle the + function-call case specially, and giving it "void" type prevents it + being used in expressions in ways that are not permitted. */ +DEFTREECODE (PSEUDO_DTOR_EXPR, "pseudo_dtor_expr", tcc_expression, 3) + +/* A whole bunch of tree codes for the initial, superficial parsing of + templates. */ +DEFTREECODE (MODOP_EXPR, "modop_expr", tcc_expression, 3) +DEFTREECODE (CAST_EXPR, "cast_expr", tcc_unary, 1) +DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", tcc_unary, 1) +DEFTREECODE (CONST_CAST_EXPR, "const_cast_expr", tcc_unary, 1) +DEFTREECODE (STATIC_CAST_EXPR, "static_cast_expr", tcc_unary, 1) +DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", tcc_unary, 1) +DEFTREECODE (IMPLICIT_CONV_EXPR, "implicit_conv_expr", tcc_unary, 1) +DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", tcc_expression, 2) +DEFTREECODE (TYPEID_EXPR, "typeid_expr", tcc_expression, 1) +DEFTREECODE (NOEXCEPT_EXPR, "noexcept_expr", tcc_unary, 1) + +/* A placeholder for an expression that is not type-dependent, but + does occur in a template. When an expression that is not + type-dependent appears in a larger expression, we must compute the + type of that larger expression. That computation would normally + modify the original expression, which would change the mangling of + that expression if it appeared in a template argument list. In + that situation, we create a NON_DEPENDENT_EXPR to take the place of + the original expression. The expression is the only operand -- it + is only needed for diagnostics. */ +DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", tcc_expression, 1) + +/* CTOR_INITIALIZER is a placeholder in template code for a call to + setup_vtbl_pointer (and appears in all functions, not just ctors). */ +DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", tcc_expression, 1) + +DEFTREECODE (TRY_BLOCK, "try_block", tcc_statement, 2) + +DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", tcc_statement, 2) + +/* A HANDLER wraps a catch handler for the HANDLER_TYPE. If this is + CATCH_ALL_TYPE, then the handler catches all types. The declaration of + the catch variable is in HANDLER_PARMS, and the body block in + HANDLER_BODY. */ +DEFTREECODE (HANDLER, "handler", tcc_statement, 2) + +/* A MUST_NOT_THROW_EXPR wraps an expression that may not + throw, and must call terminate if it does. The second argument + is a condition, used in templates to express noexcept (condition). */ +DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", tcc_expression, 2) + +/* A CLEANUP_STMT marks the point at which a declaration is fully + constructed. The CLEANUP_EXPR is run on behalf of CLEANUP_DECL + when CLEANUP_BODY completes. */ +DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", tcc_statement, 3) + +/* Represents an 'if' statement. The operands are IF_COND, + THEN_CLAUSE, and ELSE_CLAUSE, and the current scope, respectively. */ +/* ??? It is currently still necessary to distinguish between IF_STMT + and COND_EXPR for the benefit of templates. */ +DEFTREECODE (IF_STMT, "if_stmt", tcc_statement, 4) + +/* Used to represent a `for' statement. The operands are + FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */ +DEFTREECODE (FOR_STMT, "for_stmt", tcc_statement, 5) + +/* Used to represent a range-based `for' statement. The operands are + RANGE_FOR_DECL, RANGE_FOR_EXPR, RANGE_FOR_BODY, and RANGE_FOR_SCOPE, + respectively. Only used in templates. */ +DEFTREECODE (RANGE_FOR_STMT, "range_for_stmt", tcc_statement, 4) + +/* Used to represent a 'while' statement. The operands are WHILE_COND + and WHILE_BODY, respectively. */ +DEFTREECODE (WHILE_STMT, "while_stmt", tcc_statement, 2) + +/* Used to represent a 'do' statement. The operands are DO_BODY and + DO_COND, respectively. */ +DEFTREECODE (DO_STMT, "do_stmt", tcc_statement, 2) + +/* Used to represent a 'break' statement. */ +DEFTREECODE (BREAK_STMT, "break_stmt", tcc_statement, 0) + +/* Used to represent a 'continue' statement. */ +DEFTREECODE (CONTINUE_STMT, "continue_stmt", tcc_statement, 0) + +/* Used to represent a 'switch' statement. The operands are + SWITCH_STMT_COND, SWITCH_STMT_BODY, SWITCH_STMT_TYPE, and + SWITCH_STMT_SCOPE, respectively. */ +DEFTREECODE (SWITCH_STMT, "switch_stmt", tcc_statement, 4) + +/* Used to represent an expression statement. Use `EXPR_STMT_EXPR' to + obtain the expression. */ +DEFTREECODE (EXPR_STMT, "expr_stmt", tcc_expression, 1) + +DEFTREECODE (TAG_DEFN, "tag_defn", tcc_expression, 0) + +/* Represents an 'offsetof' expression during template expansion. */ +DEFTREECODE (OFFSETOF_EXPR, "offsetof_expr", tcc_expression, 1) + +/* Represents the -> operator during template expansion. */ +DEFTREECODE (ARROW_EXPR, "arrow_expr", tcc_expression, 1) + +/* Represents an '__alignof__' expression during template + expansion. */ +DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", tcc_expression, 1) + +/* Represents an Objective-C++ '@encode' expression during template + expansion. */ +DEFTREECODE (AT_ENCODE_EXPR, "at_encode_expr", tcc_expression, 1) + +/* A STMT_EXPR represents a statement-expression during template + expansion. This is the GCC extension { ( ... ) }. The + STMT_EXPR_STMT is the statement given by the expression. */ +DEFTREECODE (STMT_EXPR, "stmt_expr", tcc_expression, 1) + +/* Unary plus. Operand 0 is the expression to which the unary plus + is applied. */ +DEFTREECODE (UNARY_PLUS_EXPR, "unary_plus_expr", tcc_unary, 1) + +/** C++0x extensions. */ + +/* A static assertion. This is a C++0x extension. + STATIC_ASSERT_CONDITION contains the condition that is being + checked. STATIC_ASSERT_MESSAGE contains the message (a string + literal) to be displayed if the condition fails to hold. */ +DEFTREECODE (STATIC_ASSERT, "static_assert", tcc_exceptional, 0) + +/* Represents an argument pack of types (or templates). An argument + pack stores zero or more arguments that will be used to instantiate + a parameter pack. + + ARGUMENT_PACK_ARGS retrieves the arguments stored in the argument + pack. + + Example: + template + class tuple { ... }; + + tuple t; + + Values is a (template) parameter pack. When tuple is instantiated, the Values parameter pack is instantiated + with the argument pack . ARGUMENT_PACK_ARGS will + be a TREE_VEC containing int, float, and double. */ +DEFTREECODE (TYPE_ARGUMENT_PACK, "type_argument_pack", tcc_type, 0) + +/* Represents an argument pack of values, which can be used either for + non-type template arguments or function call arguments. + + NONTYPE_ARGUMENT_PACK plays precisely the same role as + TYPE_ARGUMENT_PACK, but will be used for packing non-type template + arguments (e.g., "int... Dimensions") or function arguments ("const + Args&... args"). */ +DEFTREECODE (NONTYPE_ARGUMENT_PACK, "nontype_argument_pack", tcc_expression, 1) + +/* Represents a type expression that will be expanded into a list of + types when instantiated with one or more argument packs. + + PACK_EXPANSION_PATTERN retrieves the expansion pattern. This is + the type or expression that we will substitute into with each + argument in an argument pack. + + SET_PACK_EXPANSION_PATTERN sets the expansion pattern. + + PACK_EXPANSION_PARAMETER_PACKS contains a TREE_LIST of the parameter + packs that are used in this pack expansion. + + Example: + template + struct tied : tuple { + // ... + }; + + The derivation from tuple contains a TYPE_PACK_EXPANSION for the + template arguments. Its PACK_EXPANSION_PATTERN is "Values&" and its + PACK_EXPANSION_PARAMETER_PACKS will contain "Values". */ +DEFTREECODE (TYPE_PACK_EXPANSION, "type_pack_expansion", tcc_type, 0) + +/* Represents an expression that will be expanded into a list of + expressions when instantiated with one or more argument packs. + + EXPR_PACK_EXPANSION plays precisely the same role as TYPE_PACK_EXPANSION, + but will be used for expressions. */ +DEFTREECODE (EXPR_PACK_EXPANSION, "expr_pack_expansion", tcc_expression, 3) + +/* Selects the Ith parameter out of an argument pack. This node will + be used when instantiating pack expansions; see + tsubst_pack_expansion. + + ARGUMENT_PACK_SELECT_FROM_PACK contains the *_ARGUMENT_PACK node + from which the argument will be selected. + + ARGUMENT_PACK_SELECT_INDEX contains the index into the argument + pack that will be returned by this ARGUMENT_PACK_SELECT node. The + index is a machine integer. */ +DEFTREECODE (ARGUMENT_PACK_SELECT, "argument_pack_select", tcc_exceptional, 0) + +/** C++ extensions. */ + +/* Represents a trait expression during template expansion. */ +DEFTREECODE (TRAIT_EXPR, "trait_expr", tcc_exceptional, 0) + +/* A lambda expression. This is a C++0x extension. + LAMBDA_EXPR_DEFAULT_CAPTURE_MODE is an enum for the default, which may be + none. + LAMBDA_EXPR_CAPTURE_LIST holds the capture-list, including `this'. + LAMBDA_EXPR_THIS_CAPTURE goes straight to the capture of `this', if it exists. + LAMBDA_EXPR_PENDING_PROXIES is a vector of capture proxies which need to + be pushed once scope returns to the lambda. + LAMBDA_EXPR_MUTABLE_P signals whether this lambda was declared mutable. + LAMBDA_EXPR_RETURN_TYPE holds the return type, if it was specified. */ +DEFTREECODE (LAMBDA_EXPR, "lambda_expr", tcc_exceptional, 0) + +/* The declared type of an expression. This is a C++0x extension. + DECLTYPE_TYPE_EXPR is the expression whose type we are computing. + DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P states whether the + expression was parsed as an id-expression or a member access + expression. When false, it was parsed as a full expression. + DECLTYPE_FOR_LAMBDA_CAPTURE is set if we want lambda capture semantics. + DECLTYPE_FOR_LAMBDA_RETURN is set if we want lambda return deduction. */ +DEFTREECODE (DECLTYPE_TYPE, "decltype_type", tcc_type, 0) + +/* A type designated by `__underlying_type (type)'. + UNDERLYING_TYPE_TYPE is the type in question. */ +DEFTREECODE (UNDERLYING_TYPE, "underlying_type", tcc_type, 0) + +/* A type designated by one of the bases type traits. + BASES_TYPE is the type in question. */ +DEFTREECODE (BASES, "bases", tcc_type, 0) + +/* Used to represent the template information stored by template + specializations. + The accessors are: + TI_TEMPLATE the template declaration associated to the specialization + TI_ARGS the arguments of the template specialization + TI_TYPEDEFS_NEEDING_ACCESS_CHECKING the vector of typedefs used in + the pattern of the template for which access check is needed at template + instantiation time. */ +DEFTREECODE (TEMPLATE_INFO, "template_info", tcc_exceptional, 0) + +/* +Local variables: +mode:c +End: +*/ diff --git a/src/include/cp/cp-tree.h b/src/include/cp/cp-tree.h new file mode 100644 index 0000000..b0b79f8 --- /dev/null +++ b/src/include/cp/cp-tree.h @@ -0,0 +1,6095 @@ +/* Definitions for C++ parsing and type checking. + Copyright (C) 1987-2013 Free Software Foundation, Inc. + Contributed by Michael Tiemann (tiemann@cygnus.com) + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_CP_TREE_H +#define GCC_CP_TREE_H + +#include "ggc.h" +#include "function.h" +#include "hashtab.h" +#include "vec.h" + +/* In order for the format checking to accept the C++ front end + diagnostic framework extensions, you must include this file before + diagnostic-core.h, not after. We override the definition of GCC_DIAG_STYLE + in c-common.h. */ +#undef GCC_DIAG_STYLE +#define GCC_DIAG_STYLE __gcc_cxxdiag__ +#if defined(GCC_DIAGNOSTIC_CORE_H) || defined (GCC_C_COMMON_H) +#error \ +In order for the format checking to accept the C++ front end diagnostic \ +framework extensions, you must include this file before diagnostic-core.h and \ +c-common.h, not after. +#endif +#include "c-family/c-common.h" +#include "diagnostic.h" + +#include "name-lookup.h" + +/* Usage of TREE_LANG_FLAG_?: + 0: IDENTIFIER_MARKED (IDENTIFIER_NODEs) + NEW_EXPR_USE_GLOBAL (in NEW_EXPR). + DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR). + COMPOUND_EXPR_OVERLOADED (in COMPOUND_EXPR). + TREE_INDIRECT_USING (in NAMESPACE_DECL). + CLEANUP_P (in TRY_BLOCK) + AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR) + PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF, SCOPE_REF) + PAREN_STRING_LITERAL (in STRING_CST) + DECL_GNU_TLS_P (in VAR_DECL) + KOENIG_LOOKUP_P (in CALL_EXPR) + STATEMENT_LIST_NO_SCOPE (in STATEMENT_LIST). + EXPR_STMT_STMT_EXPR_RESULT (in EXPR_STMT) + STMT_EXPR_NO_SCOPE (in STMT_EXPR) + BIND_EXPR_TRY_BLOCK (in BIND_EXPR) + TYPENAME_IS_ENUM_P (in TYPENAME_TYPE) + OMP_FOR_GIMPLIFYING_P (in OMP_FOR) + BASELINK_QUALIFIED_P (in BASELINK) + TARGET_EXPR_IMPLICIT_P (in TARGET_EXPR) + TEMPLATE_PARM_PARAMETER_PACK (in TEMPLATE_PARM_INDEX) + ATTR_IS_DEPENDENT (in the TREE_LIST for an attribute) + CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR) + LAMBDA_EXPR_CAPTURES_THIS_P (in LAMBDA_EXPR) + DECLTYPE_FOR_LAMBDA_CAPTURE (in DECLTYPE_TYPE) + VEC_INIT_EXPR_IS_CONSTEXPR (in VEC_INIT_EXPR) + DECL_OVERRIDE_P (in FUNCTION_DECL) + IMPLICIT_CONV_EXPR_DIRECT_INIT (in IMPLICIT_CONV_EXPR) + TRANSACTION_EXPR_IS_STMT (in TRANSACTION_EXPR) + CONVERT_EXPR_VBASE_PATH (in CONVERT_EXPR) + OVL_ARG_DEPENDENT (in OVERLOAD) + PACK_EXPANSION_LOCAL_P (in *_PACK_EXPANSION) + TINFO_RECHECK_ACCESS_P (in TEMPLATE_INFO) + SIZEOF_EXPR_TYPE_P (in SIZEOF_EXPR) + 1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE) + TI_PENDING_TEMPLATE_FLAG. + TEMPLATE_PARMS_FOR_INLINE. + DELETE_EXPR_USE_VEC (in DELETE_EXPR). + (TREE_CALLS_NEW) (in _EXPR or _REF) (commented-out). + ICS_ELLIPSIS_FLAG (in _CONV) + DECL_INITIALIZED_P (in VAR_DECL) + TYPENAME_IS_CLASS_P (in TYPENAME_TYPE) + STMT_IS_FULL_EXPR_P (in _STMT) + TARGET_EXPR_LIST_INIT_P (in TARGET_EXPR) + LAMBDA_EXPR_MUTABLE_P (in LAMBDA_EXPR) + DECL_FINAL_P (in FUNCTION_DECL) + QUALIFIED_NAME_IS_TEMPLATE (in SCOPE_REF) + 2: IDENTIFIER_OPNAME_P (in IDENTIFIER_NODE) + ICS_THIS_FLAG (in _CONV) + DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL) + STATEMENT_LIST_TRY_BLOCK (in STATEMENT_LIST) + TYPENAME_IS_RESOLVING_P (in TYPE_NAME_TYPE) + TARGET_EXPR_DIRECT_INIT_P (in TARGET_EXPR) + FNDECL_USED_AUTO (in FUNCTION_DECL) + 3: (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out). + ICS_BAD_FLAG (in _CONV) + FN_TRY_BLOCK_P (in TRY_BLOCK) + IDENTIFIER_CTOR_OR_DTOR_P (in IDENTIFIER_NODE) + BIND_EXPR_BODY_BLOCK (in BIND_EXPR) + DECL_NON_TRIVIALLY_INITIALIZED_P (in VAR_DECL) + 4: TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, + or FIELD_DECL). + IDENTIFIER_TYPENAME_P (in IDENTIFIER_NODE) + DECL_TINFO_P (in VAR_DECL) + FUNCTION_REF_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE) + 5: C_IS_RESERVED_WORD (in IDENTIFIER_NODE) + DECL_VTABLE_OR_VTT_P (in VAR_DECL) + FUNCTION_RVALUE_QUALIFIED (in FUNCTION_TYPE, METHOD_TYPE) + 6: IDENTIFIER_REPO_CHOSEN (in IDENTIFIER_NODE) + DECL_CONSTRUCTION_VTABLE_P (in VAR_DECL) + TYPE_MARKED_P (in _TYPE) + + Usage of TYPE_LANG_FLAG_?: + 0: TYPE_DEPENDENT_P + 1: TYPE_HAS_USER_CONSTRUCTOR. + 2: unused + 3: TYPE_FOR_JAVA. + 4: TYPE_HAS_NONTRIVIAL_DESTRUCTOR + 5: CLASS_TYPE_P (in RECORD_TYPE and UNION_TYPE) + ENUM_FIXED_UNDERLYING_TYPE_P (in ENUMERAL_TYPE) + 6: TYPE_DEPENDENT_P_VALID + + Usage of DECL_LANG_FLAG_?: + 0: DECL_ERROR_REPORTED (in VAR_DECL). + DECL_TEMPLATE_PARM_P (in PARM_DECL, CONST_DECL, TYPE_DECL, or TEMPLATE_DECL) + DECL_LOCAL_FUNCTION_P (in FUNCTION_DECL) + DECL_MUTABLE_P (in FIELD_DECL) + DECL_DEPENDENT_P (in USING_DECL) + 1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL). + DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL) + DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL) + FUNCTION_PARAMETER_PACK_P (in PARM_DECL) + USING_DECL_TYPENAME_P (in USING_DECL) + 2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL). + DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL) + 3: DECL_IN_AGGR_P. + 4: DECL_C_BIT_FIELD (in a FIELD_DECL) + DECL_ANON_UNION_VAR_P (in a VAR_DECL) + DECL_SELF_REFERENCE_P (in a TYPE_DECL) + DECL_INVALID_OVERRIDER_P (in a FUNCTION_DECL) + 5: DECL_INTERFACE_KNOWN. + 6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL). + DECL_FIELD_IS_BASE (in FIELD_DECL) + TYPE_DECL_ALIAS_P (in TYPE_DECL) + 7: DECL_DEAD_FOR_LOCAL (in VAR_DECL). + DECL_THUNK_P (in a member FUNCTION_DECL) + DECL_NORMAL_CAPTURE_P (in FIELD_DECL) + 8: DECL_DECLARED_CONSTEXPR_P (in VAR_DECL, FUNCTION_DECL) + + Usage of language-independent fields in a language-dependent manner: + + TYPE_ALIAS_SET + This field is used by TYPENAME_TYPEs, TEMPLATE_TYPE_PARMs, and so + forth as a substitute for the mark bits provided in `lang_type'. + At present, only the six low-order bits are used. + + TYPE_LANG_SLOT_1 + For an ENUMERAL_TYPE, this is ENUM_TEMPLATE_INFO. + For a FUNCTION_TYPE or METHOD_TYPE, this is TYPE_RAISES_EXCEPTIONS + + BINFO_VIRTUALS + For a binfo, this is a TREE_LIST. There is an entry for each + virtual function declared either in BINFO or its direct and + indirect primary bases. + + The BV_DELTA of each node gives the amount by which to adjust the + `this' pointer when calling the function. If the method is an + overridden version of a base class method, then it is assumed + that, prior to adjustment, the this pointer points to an object + of the base class. + + The BV_VCALL_INDEX of each node, if non-NULL, gives the vtable + index of the vcall offset for this entry. + + The BV_FN is the declaration for the virtual function itself. + + If BV_LOST_PRIMARY is set, it means that this entry is for a lost + primary virtual base and can be left null in the vtable. + + BINFO_VTABLE + This is an expression with POINTER_TYPE that gives the value + to which the vptr should be initialized. Use get_vtbl_decl_for_binfo + to extract the VAR_DECL for the complete vtable. + + DECL_VINDEX + This field is NULL for a non-virtual function. For a virtual + function, it is eventually set to an INTEGER_CST indicating the + index in the vtable at which this function can be found. When + a virtual function is declared, but before it is known what + function is overridden, this field is the error_mark_node. + + Temporarily, it may be set to a TREE_LIST whose TREE_VALUE is + the virtual function this one overrides, and whose TREE_CHAIN is + the old DECL_VINDEX. */ + +/* Language-specific tree checkers. */ + +#define VAR_OR_FUNCTION_DECL_CHECK(NODE) \ + TREE_CHECK2(NODE,VAR_DECL,FUNCTION_DECL) + +#define TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK(NODE) \ + TREE_CHECK3(NODE,TYPE_DECL,TEMPLATE_DECL,FUNCTION_DECL) + +#define TYPE_FUNCTION_OR_TEMPLATE_DECL_P(NODE) \ + (TREE_CODE (NODE) == TYPE_DECL || TREE_CODE (NODE) == TEMPLATE_DECL \ + || TREE_CODE (NODE) == FUNCTION_DECL) + +#define VAR_FUNCTION_OR_PARM_DECL_CHECK(NODE) \ + TREE_CHECK3(NODE,VAR_DECL,FUNCTION_DECL,PARM_DECL) + +#define VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK(NODE) \ + TREE_CHECK4(NODE,VAR_DECL,FUNCTION_DECL,TYPE_DECL,TEMPLATE_DECL) + +#define VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK(NODE) \ + TREE_CHECK5(NODE,VAR_DECL,FIELD_DECL,FUNCTION_DECL,TYPE_DECL,TEMPLATE_DECL) + +#define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) \ + TREE_CHECK(NODE,BOUND_TEMPLATE_TEMPLATE_PARM) + +#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) +#define THUNK_FUNCTION_CHECK(NODE) __extension__ \ +({ __typeof (NODE) const __t = (NODE); \ + if (TREE_CODE (__t) != FUNCTION_DECL || !__t->decl_common.lang_specific \ + || !__t->decl_common.lang_specific->u.fn.thunk_p) \ + tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, 0); \ + __t; }) +#else +#define THUNK_FUNCTION_CHECK(NODE) (NODE) +#endif + +/* Language-dependent contents of an identifier. */ + +struct GTY(()) lang_identifier { + struct c_common_identifier c_common; + cxx_binding *namespace_bindings; + cxx_binding *bindings; + tree class_template_info; + tree label_value; +}; + +/* In an IDENTIFIER_NODE, nonzero if this identifier is actually a + keyword. C_RID_CODE (node) is then the RID_* value of the keyword, + and C_RID_YYCODE is the token number wanted by Yacc. */ + +#define C_IS_RESERVED_WORD(ID) TREE_LANG_FLAG_5 (ID) + +#define LANG_IDENTIFIER_CAST(NODE) \ + ((struct lang_identifier*)IDENTIFIER_NODE_CHECK (NODE)) + +struct GTY(()) template_parm_index_s { + struct tree_common common; + int index; + int level; + int orig_level; + tree decl; +}; +typedef struct template_parm_index_s template_parm_index; + +struct GTY(()) ptrmem_cst { + struct tree_common common; + tree member; +}; +typedef struct ptrmem_cst * ptrmem_cst_t; + +#define IDENTIFIER_GLOBAL_VALUE(NODE) \ + namespace_binding ((NODE), global_namespace) +#define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \ + set_namespace_binding ((NODE), global_namespace, (VAL)) +#define IDENTIFIER_NAMESPACE_VALUE(NODE) \ + namespace_binding ((NODE), current_namespace) +#define SET_IDENTIFIER_NAMESPACE_VALUE(NODE, VAL) \ + set_namespace_binding ((NODE), current_namespace, (VAL)) + +#define CLEANUP_P(NODE) TREE_LANG_FLAG_0 (TRY_BLOCK_CHECK (NODE)) + +#define BIND_EXPR_TRY_BLOCK(NODE) \ + TREE_LANG_FLAG_0 (BIND_EXPR_CHECK (NODE)) + +/* Used to mark the block around the member initializers and cleanups. */ +#define BIND_EXPR_BODY_BLOCK(NODE) \ + TREE_LANG_FLAG_3 (BIND_EXPR_CHECK (NODE)) +#define FUNCTION_NEEDS_BODY_BLOCK(NODE) \ + (DECL_CONSTRUCTOR_P (NODE) || DECL_DESTRUCTOR_P (NODE) \ + || LAMBDA_FUNCTION_P (NODE)) + +#define STATEMENT_LIST_NO_SCOPE(NODE) \ + TREE_LANG_FLAG_0 (STATEMENT_LIST_CHECK (NODE)) +#define STATEMENT_LIST_TRY_BLOCK(NODE) \ + TREE_LANG_FLAG_2 (STATEMENT_LIST_CHECK (NODE)) + +/* Nonzero if this statement should be considered a full-expression, + i.e., if temporaries created during this statement should have + their destructors run at the end of this statement. */ +#define STMT_IS_FULL_EXPR_P(NODE) TREE_LANG_FLAG_1 ((NODE)) + +/* Marks the result of a statement expression. */ +#define EXPR_STMT_STMT_EXPR_RESULT(NODE) \ + TREE_LANG_FLAG_0 (EXPR_STMT_CHECK (NODE)) + +/* Nonzero if this statement-expression does not have an associated scope. */ +#define STMT_EXPR_NO_SCOPE(NODE) \ + TREE_LANG_FLAG_0 (STMT_EXPR_CHECK (NODE)) + +/* Returns nonzero iff TYPE1 and TYPE2 are the same type, in the usual + sense of `same'. */ +#define same_type_p(TYPE1, TYPE2) \ + comptypes ((TYPE1), (TYPE2), COMPARE_STRICT) + +/* Returns nonzero iff NODE is a declaration for the global function + `main'. */ +#define DECL_MAIN_P(NODE) \ + (DECL_EXTERN_C_FUNCTION_P (NODE) \ + && DECL_NAME (NODE) != NULL_TREE \ + && MAIN_NAME_P (DECL_NAME (NODE)) \ + && flag_hosted) + +/* The overloaded FUNCTION_DECL. */ +#define OVL_FUNCTION(NODE) \ + (((struct tree_overload*)OVERLOAD_CHECK (NODE))->function) +#define OVL_CHAIN(NODE) TREE_CHAIN (NODE) +/* Polymorphic access to FUNCTION and CHAIN. */ +#define OVL_CURRENT(NODE) \ + ((TREE_CODE (NODE) == OVERLOAD) ? OVL_FUNCTION (NODE) : (NODE)) +#define OVL_NEXT(NODE) \ + ((TREE_CODE (NODE) == OVERLOAD) ? TREE_CHAIN (NODE) : NULL_TREE) +/* If set, this was imported in a using declaration. + This is not to confuse with being used somewhere, which + is not important for this node. */ +#define OVL_USED(NODE) TREE_USED (NODE) +/* If set, this OVERLOAD was created for argument-dependent lookup + and can be freed afterward. */ +#define OVL_ARG_DEPENDENT(NODE) TREE_LANG_FLAG_0 (OVERLOAD_CHECK (NODE)) + +struct GTY(()) tree_overload { + struct tree_common common; + tree function; +}; + +/* Returns true iff NODE is a BASELINK. */ +#define BASELINK_P(NODE) \ + (TREE_CODE (NODE) == BASELINK) +/* The BINFO indicating the base in which lookup found the + BASELINK_FUNCTIONS. */ +#define BASELINK_BINFO(NODE) \ + (((struct tree_baselink*) BASELINK_CHECK (NODE))->binfo) +/* The functions referred to by the BASELINK; either a FUNCTION_DECL, + a TEMPLATE_DECL, an OVERLOAD, or a TEMPLATE_ID_EXPR. */ +#define BASELINK_FUNCTIONS(NODE) \ + (((struct tree_baselink*) BASELINK_CHECK (NODE))->functions) +/* The BINFO in which the search for the functions indicated by this baselink + began. This base is used to determine the accessibility of functions + selected by overload resolution. */ +#define BASELINK_ACCESS_BINFO(NODE) \ + (((struct tree_baselink*) BASELINK_CHECK (NODE))->access_binfo) +/* For a type-conversion operator, the BASELINK_OPTYPE indicates the type + to which the conversion should occur. This value is important if + the BASELINK_FUNCTIONS include a template conversion operator -- + the BASELINK_OPTYPE can be used to determine what type the user + requested. */ +#define BASELINK_OPTYPE(NODE) \ + (TREE_CHAIN (BASELINK_CHECK (NODE))) +/* Nonzero if this baselink was from a qualified lookup. */ +#define BASELINK_QUALIFIED_P(NODE) \ + TREE_LANG_FLAG_0 (BASELINK_CHECK (NODE)) + +struct GTY(()) tree_baselink { + struct tree_common common; + tree binfo; + tree functions; + tree access_binfo; +}; + +/* The different kinds of ids that we encounter. */ + +typedef enum cp_id_kind +{ + /* Not an id at all. */ + CP_ID_KIND_NONE, + /* An unqualified-id that is not a template-id. */ + CP_ID_KIND_UNQUALIFIED, + /* An unqualified-id that is a dependent name. */ + CP_ID_KIND_UNQUALIFIED_DEPENDENT, + /* An unqualified template-id. */ + CP_ID_KIND_TEMPLATE_ID, + /* A qualified-id. */ + CP_ID_KIND_QUALIFIED +} cp_id_kind; + + +/* The various kinds of C++0x warnings we encounter. */ + +typedef enum cpp0x_warn_str +{ + /* extended initializer lists */ + CPP0X_INITIALIZER_LISTS, + /* explicit conversion operators */ + CPP0X_EXPLICIT_CONVERSION, + /* variadic templates */ + CPP0X_VARIADIC_TEMPLATES, + /* lambda expressions */ + CPP0X_LAMBDA_EXPR, + /* C++0x auto */ + CPP0X_AUTO, + /* scoped enums */ + CPP0X_SCOPED_ENUMS, + /* defaulted and deleted functions */ + CPP0X_DEFAULTED_DELETED, + /* inline namespaces */ + CPP0X_INLINE_NAMESPACES, + /* override controls, override/final */ + CPP0X_OVERRIDE_CONTROLS, + /* non-static data member initializers */ + CPP0X_NSDMI, + /* user defined literals */ + CPP0X_USER_DEFINED_LITERALS, + /* delegating constructors */ + CPP0X_DELEGATING_CTORS, + /* inheriting constructors */ + CPP0X_INHERITING_CTORS, + /* C++11 attributes */ + CPP0X_ATTRIBUTES, + /* ref-qualified member functions */ + CPP0X_REF_QUALIFIER +} cpp0x_warn_str; + +/* The various kinds of operation used by composite_pointer_type. */ + +typedef enum composite_pointer_operation +{ + /* comparison */ + CPO_COMPARISON, + /* conversion */ + CPO_CONVERSION, + /* conditional expression */ + CPO_CONDITIONAL_EXPR +} composite_pointer_operation; + +/* Possible cases of expression list used by build_x_compound_expr_from_list. */ +typedef enum expr_list_kind { + ELK_INIT, /* initializer */ + ELK_MEM_INIT, /* member initializer */ + ELK_FUNC_CAST /* functional cast */ +} expr_list_kind; + +/* Possible cases of implicit bad rhs conversions. */ +typedef enum impl_conv_rhs { + ICR_DEFAULT_ARGUMENT, /* default argument */ + ICR_CONVERTING, /* converting */ + ICR_INIT, /* initialization */ + ICR_ARGPASS, /* argument passing */ + ICR_RETURN, /* return */ + ICR_ASSIGN /* assignment */ +} impl_conv_rhs; + +/* Possible cases of implicit or explicit bad conversions to void. */ +typedef enum impl_conv_void { + ICV_CAST, /* (explicit) conversion to void */ + ICV_SECOND_OF_COND, /* second operand of conditional expression */ + ICV_THIRD_OF_COND, /* third operand of conditional expression */ + ICV_RIGHT_OF_COMMA, /* right operand of comma operator */ + ICV_LEFT_OF_COMMA, /* left operand of comma operator */ + ICV_STATEMENT, /* statement */ + ICV_THIRD_IN_FOR /* for increment expression */ +} impl_conv_void; + +/* Macros for access to language-specific slots in an identifier. */ + +#define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \ + (LANG_IDENTIFIER_CAST (NODE)->namespace_bindings) +#define IDENTIFIER_TEMPLATE(NODE) \ + (LANG_IDENTIFIER_CAST (NODE)->class_template_info) + +/* The IDENTIFIER_BINDING is the innermost cxx_binding for the + identifier. It's PREVIOUS is the next outermost binding. Each + VALUE field is a DECL for the associated declaration. Thus, + name lookup consists simply of pulling off the node at the front + of the list (modulo oddities for looking up the names of types, + and such.) You can use SCOPE field to determine the scope + that bound the name. */ +#define IDENTIFIER_BINDING(NODE) \ + (LANG_IDENTIFIER_CAST (NODE)->bindings) + +/* TREE_TYPE only indicates on local and class scope the current + type. For namespace scope, the presence of a type in any namespace + is indicated with global_type_node, and the real type behind must + be found through lookup. */ +#define IDENTIFIER_TYPE_VALUE(NODE) identifier_type_value (NODE) +#define REAL_IDENTIFIER_TYPE_VALUE(NODE) TREE_TYPE (NODE) +#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = (TYPE)) +#define IDENTIFIER_HAS_TYPE_VALUE(NODE) (IDENTIFIER_TYPE_VALUE (NODE) ? 1 : 0) + +#define IDENTIFIER_LABEL_VALUE(NODE) \ + (LANG_IDENTIFIER_CAST (NODE)->label_value) +#define SET_IDENTIFIER_LABEL_VALUE(NODE, VALUE) \ + IDENTIFIER_LABEL_VALUE (NODE) = (VALUE) + +/* Nonzero if this identifier is used as a virtual function name somewhere + (optimizes searches). */ +#define IDENTIFIER_VIRTUAL_P(NODE) TREE_LANG_FLAG_1 (NODE) + +/* Nonzero if this identifier is the prefix for a mangled C++ operator + name. */ +#define IDENTIFIER_OPNAME_P(NODE) TREE_LANG_FLAG_2 (NODE) + +/* Nonzero if this identifier is the name of a type-conversion + operator. */ +#define IDENTIFIER_TYPENAME_P(NODE) \ + TREE_LANG_FLAG_4 (NODE) + +/* Nonzero if this identifier is the name of a constructor or + destructor. */ +#define IDENTIFIER_CTOR_OR_DTOR_P(NODE) \ + TREE_LANG_FLAG_3 (NODE) + +/* True iff NAME is the DECL_ASSEMBLER_NAME for an entity with vague + linkage which the prelinker has assigned to this translation + unit. */ +#define IDENTIFIER_REPO_CHOSEN(NAME) \ + (TREE_LANG_FLAG_6 (NAME)) + +/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */ +#define C_TYPE_FIELDS_READONLY(TYPE) \ + (LANG_TYPE_CLASS_CHECK (TYPE)->fields_readonly) + +/* The tokens stored in the default argument. */ + +#define DEFARG_TOKENS(NODE) \ + (((struct tree_default_arg *)DEFAULT_ARG_CHECK (NODE))->tokens) +#define DEFARG_INSTANTIATIONS(NODE) \ + (((struct tree_default_arg *)DEFAULT_ARG_CHECK (NODE))->instantiations) + +struct GTY (()) tree_default_arg { + struct tree_common common; + struct cp_token_cache *tokens; + vec *instantiations; +}; + + +#define DEFERRED_NOEXCEPT_PATTERN(NODE) \ + (((struct tree_deferred_noexcept *)DEFERRED_NOEXCEPT_CHECK (NODE))->pattern) +#define DEFERRED_NOEXCEPT_ARGS(NODE) \ + (((struct tree_deferred_noexcept *)DEFERRED_NOEXCEPT_CHECK (NODE))->args) +#define DEFERRED_NOEXCEPT_SPEC_P(NODE) \ + ((NODE) && (TREE_PURPOSE (NODE)) \ + && (TREE_CODE (TREE_PURPOSE (NODE)) == DEFERRED_NOEXCEPT \ + || is_overloaded_fn (TREE_PURPOSE (NODE)))) + +struct GTY (()) tree_deferred_noexcept { + struct tree_base base; + tree pattern; + tree args; +}; + + +/* The condition associated with the static assertion. This must be + an integral constant expression. */ +#define STATIC_ASSERT_CONDITION(NODE) \ + (((struct tree_static_assert *)STATIC_ASSERT_CHECK (NODE))->condition) + +/* The message associated with the static assertion. This must be a + string constant, which will be emitted as an error message when the + static assert condition is false. */ +#define STATIC_ASSERT_MESSAGE(NODE) \ + (((struct tree_static_assert *)STATIC_ASSERT_CHECK (NODE))->message) + +/* Source location information for a static assertion. */ +#define STATIC_ASSERT_SOURCE_LOCATION(NODE) \ + (((struct tree_static_assert *)STATIC_ASSERT_CHECK (NODE))->location) + +struct GTY (()) tree_static_assert { + struct tree_common common; + tree condition; + tree message; + location_t location; +}; + +struct GTY (()) tree_argument_pack_select { + struct tree_common common; + tree argument_pack; + int index; +}; + +/* The different kinds of traits that we encounter. */ + +typedef enum cp_trait_kind +{ + CPTK_BASES, + CPTK_DIRECT_BASES, + CPTK_HAS_NOTHROW_ASSIGN, + CPTK_HAS_NOTHROW_CONSTRUCTOR, + CPTK_HAS_NOTHROW_COPY, + CPTK_HAS_TRIVIAL_ASSIGN, + CPTK_HAS_TRIVIAL_CONSTRUCTOR, + CPTK_HAS_TRIVIAL_COPY, + CPTK_HAS_TRIVIAL_DESTRUCTOR, + CPTK_HAS_VIRTUAL_DESTRUCTOR, + CPTK_IS_ABSTRACT, + CPTK_IS_BASE_OF, + CPTK_IS_CLASS, + CPTK_IS_CONVERTIBLE_TO, + CPTK_IS_EMPTY, + CPTK_IS_ENUM, + CPTK_IS_FINAL, + CPTK_IS_LITERAL_TYPE, + CPTK_IS_POD, + CPTK_IS_POLYMORPHIC, + CPTK_IS_STD_LAYOUT, + CPTK_IS_TRIVIAL, + CPTK_IS_UNION, + CPTK_UNDERLYING_TYPE +} cp_trait_kind; + +/* The types that we are processing. */ +#define TRAIT_EXPR_TYPE1(NODE) \ + (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->type1) + +#define TRAIT_EXPR_TYPE2(NODE) \ + (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->type2) + +/* The specific trait that we are processing. */ +#define TRAIT_EXPR_KIND(NODE) \ + (((struct tree_trait_expr *)TRAIT_EXPR_CHECK (NODE))->kind) + +struct GTY (()) tree_trait_expr { + struct tree_common common; + tree type1; + tree type2; + enum cp_trait_kind kind; +}; + +/* Based off of TYPE_ANONYMOUS_P. */ +#define LAMBDA_TYPE_P(NODE) \ + (CLASS_TYPE_P (NODE) && CLASSTYPE_LAMBDA_EXPR (NODE)) + +/* Test if FUNCTION_DECL is a lambda function. */ +#define LAMBDA_FUNCTION_P(FNDECL) \ + (DECL_OVERLOADED_OPERATOR_P (FNDECL) == CALL_EXPR \ + && LAMBDA_TYPE_P (CP_DECL_CONTEXT (FNDECL))) + +enum cp_lambda_default_capture_mode_type { + CPLD_NONE, + CPLD_COPY, + CPLD_REFERENCE +}; + +/* The method of default capture, if any. */ +#define LAMBDA_EXPR_DEFAULT_CAPTURE_MODE(NODE) \ + (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->default_capture_mode) + +/* The capture-list, including `this'. Each capture is stored as a FIELD_DECL + * so that the name, type, and field are all together, whether or not it has + * been added to the lambda's class type. + TREE_LIST: + TREE_PURPOSE: The FIELD_DECL for this capture. + TREE_VALUE: The initializer. This is part of a GNU extension. */ +#define LAMBDA_EXPR_CAPTURE_LIST(NODE) \ + (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->capture_list) + +/* During parsing of the lambda-introducer, the node in the capture-list + that holds the 'this' capture. During parsing of the body, the + capture proxy for that node. */ +#define LAMBDA_EXPR_THIS_CAPTURE(NODE) \ + (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->this_capture) + +/* Predicate tracking whether `this' is in the effective capture set. */ +#define LAMBDA_EXPR_CAPTURES_THIS_P(NODE) \ + LAMBDA_EXPR_THIS_CAPTURE(NODE) + +/* Predicate tracking whether the lambda was declared 'mutable'. */ +#define LAMBDA_EXPR_MUTABLE_P(NODE) \ + TREE_LANG_FLAG_1 (LAMBDA_EXPR_CHECK (NODE)) + +/* The return type in the expression. + * NULL_TREE indicates that none was specified. */ +#define LAMBDA_EXPR_RETURN_TYPE(NODE) \ + (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->return_type) + +/* The source location of the lambda. */ +#define LAMBDA_EXPR_LOCATION(NODE) \ + (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->locus) + +/* The mangling scope for the lambda: FUNCTION_DECL, PARM_DECL, VAR_DECL, + FIELD_DECL or NULL_TREE. If this is NULL_TREE, we have no linkage. */ +#define LAMBDA_EXPR_EXTRA_SCOPE(NODE) \ + (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->extra_scope) + +/* If EXTRA_SCOPE, this is the number of the lambda within that scope. */ +#define LAMBDA_EXPR_DISCRIMINATOR(NODE) \ + (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->discriminator) + +/* During parsing of the lambda, a vector of capture proxies which need + to be pushed once we're done processing a nested lambda. */ +#define LAMBDA_EXPR_PENDING_PROXIES(NODE) \ + (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->pending_proxies) + +/* The closure type of the lambda. Note that the TREE_TYPE of a + LAMBDA_EXPR is always NULL_TREE, because we need to instantiate the + LAMBDA_EXPR in order to instantiate the type. */ +#define LAMBDA_EXPR_CLOSURE(NODE) \ + (((struct tree_lambda_expr *)LAMBDA_EXPR_CHECK (NODE))->closure) + +struct GTY (()) tree_lambda_expr +{ + struct tree_typed typed; + tree capture_list; + tree this_capture; + tree return_type; + tree extra_scope; + tree closure; + vec *pending_proxies; + location_t locus; + enum cp_lambda_default_capture_mode_type default_capture_mode; + int discriminator; +}; + +/* A (typedef,context,usage location) triplet. + It represents a typedef used through a + context at a given source location. + e.g. + struct foo { + typedef int myint; + }; + + struct bar { + foo::myint v; // #1<-- this location. + }; + + In bar, the triplet will be (myint, foo, #1). + */ +struct GTY(()) qualified_typedef_usage_s { + tree typedef_decl; + tree context; + location_t locus; +}; +typedef struct qualified_typedef_usage_s qualified_typedef_usage_t; + +/* Non-zero if this template specialization has access violations that + should be rechecked when the function is instantiated outside argument + deduction. */ +#define TINFO_HAS_ACCESS_ERRORS(NODE) \ + (TREE_LANG_FLAG_0 (TEMPLATE_INFO_CHECK (NODE))) +#define FNDECL_HAS_ACCESS_ERRORS(NODE) \ + (TINFO_HAS_ACCESS_ERRORS (DECL_TEMPLATE_INFO (NODE))) + +struct GTY(()) tree_template_info { + struct tree_common common; + vec *typedefs_needing_access_checking; +}; + +enum cp_tree_node_structure_enum { + TS_CP_GENERIC, + TS_CP_IDENTIFIER, + TS_CP_TPI, + TS_CP_PTRMEM, + TS_CP_BINDING, + TS_CP_OVERLOAD, + TS_CP_BASELINK, + TS_CP_WRAPPER, + TS_CP_DEFAULT_ARG, + TS_CP_DEFERRED_NOEXCEPT, + TS_CP_STATIC_ASSERT, + TS_CP_ARGUMENT_PACK_SELECT, + TS_CP_TRAIT_EXPR, + TS_CP_LAMBDA_EXPR, + TS_CP_TEMPLATE_INFO, + TS_CP_USERDEF_LITERAL, + LAST_TS_CP_ENUM +}; + +/* The resulting tree type. */ +union GTY((desc ("cp_tree_node_structure (&%h)"), + chain_next ("(union lang_tree_node *) c_tree_chain_next (&%h.generic)"))) lang_tree_node { + union tree_node GTY ((tag ("TS_CP_GENERIC"), + desc ("tree_node_structure (&%h)"))) generic; + struct template_parm_index_s GTY ((tag ("TS_CP_TPI"))) tpi; + struct ptrmem_cst GTY ((tag ("TS_CP_PTRMEM"))) ptrmem; + struct tree_overload GTY ((tag ("TS_CP_OVERLOAD"))) overload; + struct tree_baselink GTY ((tag ("TS_CP_BASELINK"))) baselink; + struct tree_default_arg GTY ((tag ("TS_CP_DEFAULT_ARG"))) default_arg; + struct tree_deferred_noexcept GTY ((tag ("TS_CP_DEFERRED_NOEXCEPT"))) deferred_noexcept; + struct lang_identifier GTY ((tag ("TS_CP_IDENTIFIER"))) identifier; + struct tree_static_assert GTY ((tag ("TS_CP_STATIC_ASSERT"))) + static_assertion; + struct tree_argument_pack_select GTY ((tag ("TS_CP_ARGUMENT_PACK_SELECT"))) + argument_pack_select; + struct tree_trait_expr GTY ((tag ("TS_CP_TRAIT_EXPR"))) + trait_expression; + struct tree_lambda_expr GTY ((tag ("TS_CP_LAMBDA_EXPR"))) + lambda_expression; + struct tree_template_info GTY ((tag ("TS_CP_TEMPLATE_INFO"))) + template_info; + struct tree_userdef_literal GTY ((tag ("TS_CP_USERDEF_LITERAL"))) + userdef_literal; +}; + + +enum cp_tree_index +{ + CPTI_JAVA_BYTE_TYPE, + CPTI_JAVA_SHORT_TYPE, + CPTI_JAVA_INT_TYPE, + CPTI_JAVA_LONG_TYPE, + CPTI_JAVA_FLOAT_TYPE, + CPTI_JAVA_DOUBLE_TYPE, + CPTI_JAVA_CHAR_TYPE, + CPTI_JAVA_BOOLEAN_TYPE, + + CPTI_WCHAR_DECL, + CPTI_VTABLE_ENTRY_TYPE, + CPTI_DELTA_TYPE, + CPTI_VTABLE_INDEX_TYPE, + CPTI_CLEANUP_TYPE, + CPTI_VTT_PARM_TYPE, + + CPTI_CLASS_TYPE, + CPTI_UNKNOWN_TYPE, + CPTI_INIT_LIST_TYPE, + CPTI_VTBL_TYPE, + CPTI_VTBL_PTR_TYPE, + CPTI_STD, + CPTI_ABI, + CPTI_CONST_TYPE_INFO_TYPE, + CPTI_TYPE_INFO_PTR_TYPE, + CPTI_ABORT_FNDECL, + CPTI_GLOBAL_DELETE_FNDECL, + CPTI_AGGR_TAG, + + CPTI_CTOR_IDENTIFIER, + CPTI_COMPLETE_CTOR_IDENTIFIER, + CPTI_BASE_CTOR_IDENTIFIER, + CPTI_DTOR_IDENTIFIER, + CPTI_COMPLETE_DTOR_IDENTIFIER, + CPTI_BASE_DTOR_IDENTIFIER, + CPTI_DELETING_DTOR_IDENTIFIER, + CPTI_DELTA_IDENTIFIER, + CPTI_IN_CHARGE_IDENTIFIER, + CPTI_VTT_PARM_IDENTIFIER, + CPTI_NELTS_IDENTIFIER, + CPTI_THIS_IDENTIFIER, + CPTI_PFN_IDENTIFIER, + CPTI_VPTR_IDENTIFIER, + CPTI_STD_IDENTIFIER, + + CPTI_LANG_NAME_C, + CPTI_LANG_NAME_CPLUSPLUS, + CPTI_LANG_NAME_JAVA, + + CPTI_EMPTY_EXCEPT_SPEC, + CPTI_NOEXCEPT_TRUE_SPEC, + CPTI_NOEXCEPT_FALSE_SPEC, + CPTI_JCLASS, + CPTI_TERMINATE, + CPTI_CALL_UNEXPECTED, + CPTI_ATEXIT_FN_PTR_TYPE, + CPTI_ATEXIT, + CPTI_DSO_HANDLE, + CPTI_DCAST, + + CPTI_KEYED_CLASSES, + + CPTI_NULLPTR, + CPTI_NULLPTR_TYPE, + + CPTI_MAX +}; + +extern GTY(()) tree cp_global_trees[CPTI_MAX]; + +#define java_byte_type_node cp_global_trees[CPTI_JAVA_BYTE_TYPE] +#define java_short_type_node cp_global_trees[CPTI_JAVA_SHORT_TYPE] +#define java_int_type_node cp_global_trees[CPTI_JAVA_INT_TYPE] +#define java_long_type_node cp_global_trees[CPTI_JAVA_LONG_TYPE] +#define java_float_type_node cp_global_trees[CPTI_JAVA_FLOAT_TYPE] +#define java_double_type_node cp_global_trees[CPTI_JAVA_DOUBLE_TYPE] +#define java_char_type_node cp_global_trees[CPTI_JAVA_CHAR_TYPE] +#define java_boolean_type_node cp_global_trees[CPTI_JAVA_BOOLEAN_TYPE] + +#define wchar_decl_node cp_global_trees[CPTI_WCHAR_DECL] +#define vtable_entry_type cp_global_trees[CPTI_VTABLE_ENTRY_TYPE] +/* The type used to represent an offset by which to adjust the `this' + pointer in pointer-to-member types. */ +#define delta_type_node cp_global_trees[CPTI_DELTA_TYPE] +/* The type used to represent an index into the vtable. */ +#define vtable_index_type cp_global_trees[CPTI_VTABLE_INDEX_TYPE] + +#define class_type_node cp_global_trees[CPTI_CLASS_TYPE] +#define unknown_type_node cp_global_trees[CPTI_UNKNOWN_TYPE] +#define init_list_type_node cp_global_trees[CPTI_INIT_LIST_TYPE] +#define vtbl_type_node cp_global_trees[CPTI_VTBL_TYPE] +#define vtbl_ptr_type_node cp_global_trees[CPTI_VTBL_PTR_TYPE] +#define std_node cp_global_trees[CPTI_STD] +#define abi_node cp_global_trees[CPTI_ABI] +#define const_type_info_type_node cp_global_trees[CPTI_CONST_TYPE_INFO_TYPE] +#define type_info_ptr_type cp_global_trees[CPTI_TYPE_INFO_PTR_TYPE] +#define abort_fndecl cp_global_trees[CPTI_ABORT_FNDECL] +#define global_delete_fndecl cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL] +#define current_aggr cp_global_trees[CPTI_AGGR_TAG] +#define nullptr_node cp_global_trees[CPTI_NULLPTR] +#define nullptr_type_node cp_global_trees[CPTI_NULLPTR_TYPE] + +/* We cache these tree nodes so as to call get_identifier less + frequently. */ + +/* The name of a constructor that takes an in-charge parameter to + decide whether or not to construct virtual base classes. */ +#define ctor_identifier cp_global_trees[CPTI_CTOR_IDENTIFIER] +/* The name of a constructor that constructs virtual base classes. */ +#define complete_ctor_identifier cp_global_trees[CPTI_COMPLETE_CTOR_IDENTIFIER] +/* The name of a constructor that does not construct virtual base classes. */ +#define base_ctor_identifier cp_global_trees[CPTI_BASE_CTOR_IDENTIFIER] +/* The name of a destructor that takes an in-charge parameter to + decide whether or not to destroy virtual base classes and whether + or not to delete the object. */ +#define dtor_identifier cp_global_trees[CPTI_DTOR_IDENTIFIER] +/* The name of a destructor that destroys virtual base classes. */ +#define complete_dtor_identifier cp_global_trees[CPTI_COMPLETE_DTOR_IDENTIFIER] +/* The name of a destructor that does not destroy virtual base + classes. */ +#define base_dtor_identifier cp_global_trees[CPTI_BASE_DTOR_IDENTIFIER] +/* The name of a destructor that destroys virtual base classes, and + then deletes the entire object. */ +#define deleting_dtor_identifier cp_global_trees[CPTI_DELETING_DTOR_IDENTIFIER] +#define delta_identifier cp_global_trees[CPTI_DELTA_IDENTIFIER] +#define in_charge_identifier cp_global_trees[CPTI_IN_CHARGE_IDENTIFIER] +/* The name of the parameter that contains a pointer to the VTT to use + for this subobject constructor or destructor. */ +#define vtt_parm_identifier cp_global_trees[CPTI_VTT_PARM_IDENTIFIER] +#define nelts_identifier cp_global_trees[CPTI_NELTS_IDENTIFIER] +#define this_identifier cp_global_trees[CPTI_THIS_IDENTIFIER] +#define pfn_identifier cp_global_trees[CPTI_PFN_IDENTIFIER] +#define vptr_identifier cp_global_trees[CPTI_VPTR_IDENTIFIER] +/* The name of the std namespace. */ +#define std_identifier cp_global_trees[CPTI_STD_IDENTIFIER] +#define lang_name_c cp_global_trees[CPTI_LANG_NAME_C] +#define lang_name_cplusplus cp_global_trees[CPTI_LANG_NAME_CPLUSPLUS] +#define lang_name_java cp_global_trees[CPTI_LANG_NAME_JAVA] + +/* Exception specifier used for throw(). */ +#define empty_except_spec cp_global_trees[CPTI_EMPTY_EXCEPT_SPEC] +#define noexcept_true_spec cp_global_trees[CPTI_NOEXCEPT_TRUE_SPEC] +#define noexcept_false_spec cp_global_trees[CPTI_NOEXCEPT_FALSE_SPEC] + +/* If non-NULL, a POINTER_TYPE equivalent to (java::lang::Class*). */ +#define jclass_node cp_global_trees[CPTI_JCLASS] + +/* The declaration for `std::terminate'. */ +#define terminate_node cp_global_trees[CPTI_TERMINATE] + +/* The declaration for "__cxa_call_unexpected". */ +#define call_unexpected_node cp_global_trees[CPTI_CALL_UNEXPECTED] + +/* The type of the function-pointer argument to "__cxa_atexit" (or + "std::atexit", if "__cxa_atexit" is not being used). */ +#define atexit_fn_ptr_type_node cp_global_trees[CPTI_ATEXIT_FN_PTR_TYPE] + +/* A pointer to `std::atexit'. */ +#define atexit_node cp_global_trees[CPTI_ATEXIT] + +/* A pointer to `__dso_handle'. */ +#define dso_handle_node cp_global_trees[CPTI_DSO_HANDLE] + +/* The declaration of the dynamic_cast runtime. */ +#define dynamic_cast_node cp_global_trees[CPTI_DCAST] + +/* The type of a destructor. */ +#define cleanup_type cp_global_trees[CPTI_CLEANUP_TYPE] + +/* The type of the vtt parameter passed to subobject constructors and + destructors. */ +#define vtt_parm_type cp_global_trees[CPTI_VTT_PARM_TYPE] + +/* A TREE_LIST of the dynamic classes whose vtables may have to be + emitted in this translation unit. */ + +#define keyed_classes cp_global_trees[CPTI_KEYED_CLASSES] + +/* Node to indicate default access. This must be distinct from the + access nodes in tree.h. */ + +#define access_default_node null_node + +/* Global state. */ + +struct GTY(()) saved_scope { + vec *old_bindings; + tree old_namespace; + vec *decl_ns_list; + tree class_name; + tree class_type; + tree access_specifier; + tree function_decl; + vec *lang_base; + tree lang_name; + tree template_parms; + cp_binding_level *x_previous_class_level; + tree x_saved_tree; + + /* Only used for uses of this in trailing return type. */ + tree x_current_class_ptr; + tree x_current_class_ref; + + int x_processing_template_decl; + int x_processing_specialization; + BOOL_BITFIELD x_processing_explicit_instantiation : 1; + BOOL_BITFIELD need_pop_function_context : 1; + + int unevaluated_operand; + int inhibit_evaluation_warnings; + + struct stmt_tree_s x_stmt_tree; + + cp_binding_level *class_bindings; + cp_binding_level *bindings; + + struct saved_scope *prev; +}; + +/* The current open namespace. */ + +#define current_namespace scope_chain->old_namespace + +/* The stack for namespaces of current declarations. */ + +#define decl_namespace_list scope_chain->decl_ns_list + +/* IDENTIFIER_NODE: name of current class */ + +#define current_class_name scope_chain->class_name + +/* _TYPE: the type of the current class */ + +#define current_class_type scope_chain->class_type + +/* When parsing a class definition, the access specifier most recently + given by the user, or, if no access specifier was given, the + default value appropriate for the kind of class (i.e., struct, + class, or union). */ + +#define current_access_specifier scope_chain->access_specifier + +/* Pointer to the top of the language name stack. */ + +#define current_lang_base scope_chain->lang_base +#define current_lang_name scope_chain->lang_name + +/* When parsing a template declaration, a TREE_LIST represents the + active template parameters. Each node in the list represents one + level of template parameters. The innermost level is first in the + list. The depth of each level is stored as an INTEGER_CST in the + TREE_PURPOSE of each node. The parameters for that level are + stored in the TREE_VALUE. */ + +#define current_template_parms scope_chain->template_parms + +#define processing_template_decl scope_chain->x_processing_template_decl +#define processing_specialization scope_chain->x_processing_specialization +#define processing_explicit_instantiation scope_chain->x_processing_explicit_instantiation + +/* The cached class binding level, from the most recently exited + class, or NULL if none. */ + +#define previous_class_level scope_chain->x_previous_class_level + +/* A list of private types mentioned, for deferred access checking. */ + +extern GTY(()) struct saved_scope *scope_chain; + +struct GTY(()) cxx_int_tree_map { + unsigned int uid; + tree to; +}; + +extern unsigned int cxx_int_tree_map_hash (const void *); +extern int cxx_int_tree_map_eq (const void *, const void *); + +/* Global state pertinent to the current function. */ + +struct GTY(()) language_function { + struct c_language_function base; + + tree x_cdtor_label; + tree x_current_class_ptr; + tree x_current_class_ref; + tree x_eh_spec_block; + tree x_in_charge_parm; + tree x_vtt_parm; + tree x_return_value; + tree x_auto_return_pattern; + + BOOL_BITFIELD returns_value : 1; + BOOL_BITFIELD returns_null : 1; + BOOL_BITFIELD returns_abnormally : 1; + BOOL_BITFIELD x_in_function_try_handler : 1; + BOOL_BITFIELD x_in_base_initializer : 1; + + /* True if this function can throw an exception. */ + BOOL_BITFIELD can_throw : 1; + + htab_t GTY((param_is(struct named_label_entry))) x_named_labels; + cp_binding_level *bindings; + vec *x_local_names; + htab_t GTY((param_is (struct cxx_int_tree_map))) extern_decl_map; +}; + +/* The current C++-specific per-function global variables. */ + +#define cp_function_chain (cfun->language) + +/* In a constructor destructor, the point at which all derived class + destroying/construction has been done. I.e., just before a + constructor returns, or before any base class destroying will be done + in a destructor. */ + +#define cdtor_label cp_function_chain->x_cdtor_label + +/* When we're processing a member function, current_class_ptr is the + PARM_DECL for the `this' pointer. The current_class_ref is an + expression for `*this'. */ + +#define current_class_ptr \ + (*(cfun && cp_function_chain \ + ? &cp_function_chain->x_current_class_ptr \ + : &scope_chain->x_current_class_ptr)) +#define current_class_ref \ + (*(cfun && cp_function_chain \ + ? &cp_function_chain->x_current_class_ref \ + : &scope_chain->x_current_class_ref)) + +/* The EH_SPEC_BLOCK for the exception-specifiers for the current + function, if any. */ + +#define current_eh_spec_block cp_function_chain->x_eh_spec_block + +/* The `__in_chrg' parameter for the current function. Only used for + constructors and destructors. */ + +#define current_in_charge_parm cp_function_chain->x_in_charge_parm + +/* The `__vtt_parm' parameter for the current function. Only used for + constructors and destructors. */ + +#define current_vtt_parm cp_function_chain->x_vtt_parm + +/* Set to 0 at beginning of a function definition, set to 1 if + a return statement that specifies a return value is seen. */ + +#define current_function_returns_value cp_function_chain->returns_value + +/* Set to 0 at beginning of a function definition, set to 1 if + a return statement with no argument is seen. */ + +#define current_function_returns_null cp_function_chain->returns_null + +/* Set to 0 at beginning of a function definition, set to 1 if + a call to a noreturn function is seen. */ + +#define current_function_returns_abnormally \ + cp_function_chain->returns_abnormally + +/* Nonzero if we are processing a base initializer. Zero elsewhere. */ +#define in_base_initializer cp_function_chain->x_in_base_initializer + +#define in_function_try_handler cp_function_chain->x_in_function_try_handler + +/* Expression always returned from function, or error_mark_node + otherwise, for use by the automatic named return value optimization. */ + +#define current_function_return_value \ + (cp_function_chain->x_return_value) + +/* A type involving 'auto' to be used for return type deduction. */ + +#define current_function_auto_return_pattern \ + (cp_function_chain->x_auto_return_pattern) + +/* True if NAME is the IDENTIFIER_NODE for an overloaded "operator + new" or "operator delete". */ +#define NEW_DELETE_OPNAME_P(NAME) \ + ((NAME) == ansi_opname (NEW_EXPR) \ + || (NAME) == ansi_opname (VEC_NEW_EXPR) \ + || (NAME) == ansi_opname (DELETE_EXPR) \ + || (NAME) == ansi_opname (VEC_DELETE_EXPR)) + +#define ansi_opname(CODE) \ + (operator_name_info[(int) (CODE)].identifier) +#define ansi_assopname(CODE) \ + (assignment_operator_name_info[(int) (CODE)].identifier) + +/* TRUE if a tree code represents a statement. */ +extern bool statement_code_p[MAX_TREE_CODES]; + +#define STATEMENT_CODE_P(CODE) statement_code_p[(int) (CODE)] + +enum languages { lang_c, lang_cplusplus, lang_java }; + +/* Macros to make error reporting functions' lives easier. */ +#define TYPE_IDENTIFIER(NODE) (DECL_NAME (TYPE_NAME (NODE))) +#define TYPE_LINKAGE_IDENTIFIER(NODE) \ + (TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (NODE))) +#define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE))) +#define TYPE_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (TYPE_IDENTIFIER (NODE))) + +/* Nonzero if NODE has no name for linkage purposes. */ +#define TYPE_ANONYMOUS_P(NODE) \ + (TAGGED_TYPE_P (NODE) && ANON_AGGRNAME_P (TYPE_LINKAGE_IDENTIFIER (NODE))) + +/* The _DECL for this _TYPE. */ +#define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE))) + +/* Nonzero if T is a type that could resolve to any kind of concrete type + at instantiation time. */ +#define WILDCARD_TYPE_P(T) \ + (TREE_CODE (T) == TEMPLATE_TYPE_PARM \ + || TREE_CODE (T) == TYPENAME_TYPE \ + || TREE_CODE (T) == TYPEOF_TYPE \ + || TREE_CODE (T) == BOUND_TEMPLATE_TEMPLATE_PARM \ + || TREE_CODE (T) == DECLTYPE_TYPE) + +/* Nonzero if T is a class (or struct or union) type. Also nonzero + for template type parameters, typename types, and instantiated + template template parameters. Keep these checks in ascending code + order. */ +#define MAYBE_CLASS_TYPE_P(T) (WILDCARD_TYPE_P (T) || CLASS_TYPE_P (T)) + +/* Set CLASS_TYPE_P for T to VAL. T must be a class, struct, or + union type. */ +#define SET_CLASS_TYPE_P(T, VAL) \ + (TYPE_LANG_FLAG_5 (T) = (VAL)) + +/* Nonzero if T is a class type. Zero for template type parameters, + typename types, and so forth. */ +#define CLASS_TYPE_P(T) \ + (RECORD_OR_UNION_CODE_P (TREE_CODE (T)) && TYPE_LANG_FLAG_5 (T)) + +/* Nonzero if T is a class type but not an union. */ +#define NON_UNION_CLASS_TYPE_P(T) \ + (CLASS_TYPE_P (T) && TREE_CODE (T) != UNION_TYPE) + +/* Keep these checks in ascending code order. */ +#define RECORD_OR_UNION_CODE_P(T) \ + ((T) == RECORD_TYPE || (T) == UNION_TYPE) +#define TAGGED_TYPE_P(T) \ + (CLASS_TYPE_P (T) || TREE_CODE (T) == ENUMERAL_TYPE) +#define IS_OVERLOAD_TYPE(T) TAGGED_TYPE_P (T) + +/* True if this a "Java" type, defined in 'extern "Java"'. */ +#define TYPE_FOR_JAVA(NODE) TYPE_LANG_FLAG_3 (NODE) + +/* True if this type is dependent. This predicate is only valid if + TYPE_DEPENDENT_P_VALID is true. */ +#define TYPE_DEPENDENT_P(NODE) TYPE_LANG_FLAG_0 (NODE) + +/* True if dependent_type_p has been called for this type, with the + result that TYPE_DEPENDENT_P is valid. */ +#define TYPE_DEPENDENT_P_VALID(NODE) TYPE_LANG_FLAG_6(NODE) + +/* Nonzero if this type is const-qualified. */ +#define CP_TYPE_CONST_P(NODE) \ + ((cp_type_quals (NODE) & TYPE_QUAL_CONST) != 0) + +/* Nonzero if this type is volatile-qualified. */ +#define CP_TYPE_VOLATILE_P(NODE) \ + ((cp_type_quals (NODE) & TYPE_QUAL_VOLATILE) != 0) + +/* Nonzero if this type is restrict-qualified. */ +#define CP_TYPE_RESTRICT_P(NODE) \ + ((cp_type_quals (NODE) & TYPE_QUAL_RESTRICT) != 0) + +/* Nonzero if this type is const-qualified, but not + volatile-qualified. Other qualifiers are ignored. This macro is + used to test whether or not it is OK to bind an rvalue to a + reference. */ +#define CP_TYPE_CONST_NON_VOLATILE_P(NODE) \ + ((cp_type_quals (NODE) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) \ + == TYPE_QUAL_CONST) + +#define FUNCTION_ARG_CHAIN(NODE) \ + TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE))) + +/* Given a FUNCTION_DECL, returns the first TREE_LIST out of TYPE_ARG_TYPES + which refers to a user-written parameter. */ +#define FUNCTION_FIRST_USER_PARMTYPE(NODE) \ + skip_artificial_parms_for ((NODE), TYPE_ARG_TYPES (TREE_TYPE (NODE))) + +/* Similarly, but for DECL_ARGUMENTS. */ +#define FUNCTION_FIRST_USER_PARM(NODE) \ + skip_artificial_parms_for ((NODE), DECL_ARGUMENTS (NODE)) + +/* Nonzero iff TYPE is derived from PARENT. Ignores accessibility and + ambiguity issues. */ +#define DERIVED_FROM_P(PARENT, TYPE) \ + (lookup_base ((TYPE), (PARENT), ba_any, NULL, tf_warning_or_error)\ + != NULL_TREE) + +/* Gives the visibility specification for a class type. */ +#define CLASSTYPE_VISIBILITY(TYPE) \ + DECL_VISIBILITY (TYPE_MAIN_DECL (TYPE)) +#define CLASSTYPE_VISIBILITY_SPECIFIED(TYPE) \ + DECL_VISIBILITY_SPECIFIED (TYPE_MAIN_DECL (TYPE)) + +typedef struct GTY (()) tree_pair_s { + tree purpose; + tree value; +} tree_pair_s; +typedef tree_pair_s *tree_pair_p; + +/* This is a few header flags for 'struct lang_type'. Actually, + all but the first are used only for lang_type_class; they + are put in this structure to save space. */ +struct GTY(()) lang_type_header { + BOOL_BITFIELD is_lang_type_class : 1; + + BOOL_BITFIELD has_type_conversion : 1; + BOOL_BITFIELD has_copy_ctor : 1; + BOOL_BITFIELD has_default_ctor : 1; + BOOL_BITFIELD const_needs_init : 1; + BOOL_BITFIELD ref_needs_init : 1; + BOOL_BITFIELD has_const_copy_assign : 1; + + BOOL_BITFIELD spare : 1; +}; + +/* This structure provides additional information above and beyond + what is provide in the ordinary tree_type. In the past, we used it + for the types of class types, template parameters types, typename + types, and so forth. However, there can be many (tens to hundreds + of thousands) of template parameter types in a compilation, and + there's no need for this additional information in that case. + Therefore, we now use this data structure only for class types. + + In the past, it was thought that there would be relatively few + class types. However, in the presence of heavy use of templates, + many (i.e., thousands) of classes can easily be generated. + Therefore, we should endeavor to keep the size of this structure to + a minimum. */ +struct GTY(()) lang_type_class { + struct lang_type_header h; + + unsigned char align; + + unsigned has_mutable : 1; + unsigned com_interface : 1; + unsigned non_pod_class : 1; + unsigned nearly_empty_p : 1; + unsigned user_align : 1; + unsigned has_copy_assign : 1; + unsigned has_new : 1; + unsigned has_array_new : 1; + + unsigned gets_delete : 2; + unsigned interface_only : 1; + unsigned interface_unknown : 1; + unsigned contains_empty_class_p : 1; + unsigned anon_aggr : 1; + unsigned non_zero_init : 1; + unsigned empty_p : 1; + + unsigned vec_new_uses_cookie : 1; + unsigned declared_class : 1; + unsigned diamond_shaped : 1; + unsigned repeated_base : 1; + unsigned being_defined : 1; + unsigned java_interface : 1; + unsigned debug_requested : 1; + unsigned fields_readonly : 1; + + unsigned use_template : 2; + unsigned ptrmemfunc_flag : 1; + unsigned was_anonymous : 1; + unsigned lazy_default_ctor : 1; + unsigned lazy_copy_ctor : 1; + unsigned lazy_copy_assign : 1; + unsigned lazy_destructor : 1; + + unsigned has_const_copy_ctor : 1; + unsigned has_complex_copy_ctor : 1; + unsigned has_complex_copy_assign : 1; + unsigned non_aggregate : 1; + unsigned has_complex_dflt : 1; + unsigned has_list_ctor : 1; + unsigned non_std_layout : 1; + unsigned is_literal : 1; + + unsigned lazy_move_ctor : 1; + unsigned lazy_move_assign : 1; + unsigned has_complex_move_ctor : 1; + unsigned has_complex_move_assign : 1; + unsigned has_constexpr_ctor : 1; + unsigned is_final : 1; + + /* When adding a flag here, consider whether or not it ought to + apply to a template instance if it applies to the template. If + so, make sure to copy it in instantiate_class_template! */ + + /* There are some bits left to fill out a 32-bit word. Keep track + of this by updating the size of this bitfield whenever you add or + remove a flag. */ + unsigned dummy : 2; + + tree primary_base; + vec *vcall_indices; + tree vtables; + tree typeinfo_var; + vec *vbases; + binding_table nested_udts; + tree as_base; + vec *pure_virtuals; + tree friend_classes; + vec * GTY((reorder ("resort_type_method_vec"))) methods; + tree key_method; + tree decl_list; + tree template_info; + tree befriending_classes; + /* In a RECORD_TYPE, information specific to Objective-C++, such + as a list of adopted protocols or a pointer to a corresponding + @interface. See objc/objc-act.h for details. */ + tree objc_info; + /* sorted_fields is sorted based on a pointer, so we need to be able + to resort it if pointers get rearranged. */ + struct sorted_fields_type * GTY ((reorder ("resort_sorted_fields"))) + sorted_fields; + /* FIXME reuse another field? */ + tree lambda_expr; +}; + +struct GTY(()) lang_type_ptrmem { + struct lang_type_header h; + tree record; +}; + +struct GTY((variable_size)) lang_type { + union lang_type_u + { + struct lang_type_header GTY((skip (""))) h; + struct lang_type_class GTY((tag ("1"))) c; + struct lang_type_ptrmem GTY((tag ("0"))) ptrmem; + } GTY((desc ("%h.h.is_lang_type_class"))) u; +}; + +#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) + +#define LANG_TYPE_CLASS_CHECK(NODE) __extension__ \ +({ struct lang_type *lt = TYPE_LANG_SPECIFIC (NODE); \ + if (! lt->u.h.is_lang_type_class) \ + lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ + <->u.c; }) + +#define LANG_TYPE_PTRMEM_CHECK(NODE) __extension__ \ +({ struct lang_type *lt = TYPE_LANG_SPECIFIC (NODE); \ + if (lt->u.h.is_lang_type_class) \ + lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ + <->u.ptrmem; }) + +#else + +#define LANG_TYPE_CLASS_CHECK(NODE) (&TYPE_LANG_SPECIFIC (NODE)->u.c) +#define LANG_TYPE_PTRMEM_CHECK(NODE) (&TYPE_LANG_SPECIFIC (NODE)->u.ptrmem) + +#endif /* ENABLE_TREE_CHECKING */ + +/* Nonzero for _CLASSTYPE means that operator delete is defined. */ +#define TYPE_GETS_DELETE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->gets_delete) +#define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1) + +/* Nonzero if `new NODE[x]' should cause the allocation of extra + storage to indicate how many array elements are in use. */ +#define TYPE_VEC_NEW_USES_COOKIE(NODE) \ + (CLASS_TYPE_P (NODE) \ + && LANG_TYPE_CLASS_CHECK (NODE)->vec_new_uses_cookie) + +/* Nonzero means that this _CLASSTYPE node defines ways of converting + itself to other types. */ +#define TYPE_HAS_CONVERSION(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->h.has_type_conversion) + +/* Nonzero means that NODE (a class type) has a default constructor -- + but that it has not yet been declared. */ +#define CLASSTYPE_LAZY_DEFAULT_CTOR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->lazy_default_ctor) + +/* Nonzero means that NODE (a class type) has a copy constructor -- + but that it has not yet been declared. */ +#define CLASSTYPE_LAZY_COPY_CTOR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->lazy_copy_ctor) + +/* Nonzero means that NODE (a class type) has a move constructor -- + but that it has not yet been declared. */ +#define CLASSTYPE_LAZY_MOVE_CTOR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->lazy_move_ctor) + +/* Nonzero means that NODE (a class type) has an assignment operator + -- but that it has not yet been declared. */ +#define CLASSTYPE_LAZY_COPY_ASSIGN(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->lazy_copy_assign) + +/* Nonzero means that NODE (a class type) has an assignment operator + -- but that it has not yet been declared. */ +#define CLASSTYPE_LAZY_MOVE_ASSIGN(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->lazy_move_assign) + +/* Nonzero means that NODE (a class type) has a destructor -- but that + it has not yet been declared. */ +#define CLASSTYPE_LAZY_DESTRUCTOR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->lazy_destructor) + +/* Nonzero means that NODE (a class type) is final */ +#define CLASSTYPE_FINAL(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->is_final) + + +/* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */ +#define TYPE_HAS_COPY_ASSIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_copy_assign) + +/* True iff the class type NODE has an "operator =" whose parameter + has a parameter of type "const X&". */ +#define TYPE_HAS_CONST_COPY_ASSIGN(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->h.has_const_copy_assign) + +/* Nonzero means that this _CLASSTYPE node has an X(X&) constructor. */ +#define TYPE_HAS_COPY_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->h.has_copy_ctor) +#define TYPE_HAS_CONST_COPY_CTOR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->has_const_copy_ctor) + +/* Nonzero if this class has an X(initializer_list) constructor. */ +#define TYPE_HAS_LIST_CTOR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->has_list_ctor) + +/* Nonzero if this class has a constexpr constructor other than a copy/move + constructor. Note that a class can have constexpr constructors for + static initialization even if it isn't a literal class. */ +#define TYPE_HAS_CONSTEXPR_CTOR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->has_constexpr_ctor) + +/* Nonzero if this class defines an overloaded operator new. (An + operator new [] doesn't count.) */ +#define TYPE_HAS_NEW_OPERATOR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->has_new) + +/* Nonzero if this class defines an overloaded operator new[]. */ +#define TYPE_HAS_ARRAY_NEW_OPERATOR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->has_array_new) + +/* Nonzero means that this type is being defined. I.e., the left brace + starting the definition of this type has been seen. */ +#define TYPE_BEING_DEFINED(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->being_defined) + +/* Nonzero means that this type is either complete or being defined, so we + can do lookup in it. */ +#define COMPLETE_OR_OPEN_TYPE_P(NODE) \ + (COMPLETE_TYPE_P (NODE) || (CLASS_TYPE_P (NODE) && TYPE_BEING_DEFINED (NODE))) + +/* Mark bits for repeated base checks. */ +#define TYPE_MARKED_P(NODE) TREE_LANG_FLAG_6 (TYPE_CHECK (NODE)) + +/* Nonzero if the class NODE has multiple paths to the same (virtual) + base object. */ +#define CLASSTYPE_DIAMOND_SHAPED_P(NODE) \ + (LANG_TYPE_CLASS_CHECK(NODE)->diamond_shaped) + +/* Nonzero if the class NODE has multiple instances of the same base + type. */ +#define CLASSTYPE_REPEATED_BASE_P(NODE) \ + (LANG_TYPE_CLASS_CHECK(NODE)->repeated_base) + +/* The member function with which the vtable will be emitted: + the first noninline non-pure-virtual member function. NULL_TREE + if there is no key function or if this is a class template */ +#define CLASSTYPE_KEY_METHOD(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->key_method) + +/* Vector member functions defined in this class. Each element is + either a FUNCTION_DECL, a TEMPLATE_DECL, or an OVERLOAD. All + functions with the same name end up in the same slot. The first + two elements are for constructors, and destructors, respectively. + All template conversion operators to innermost template dependent + types are overloaded on the next slot, if they exist. Note, the + names for these functions will not all be the same. The + non-template conversion operators & templated conversions to + non-innermost template types are next, followed by ordinary member + functions. There may be empty entries at the end of the vector. + The conversion operators are unsorted. The ordinary member + functions are sorted, once the class is complete. */ +#define CLASSTYPE_METHOD_VEC(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->methods) + +/* For class templates, this is a TREE_LIST of all member data, + functions, types, and friends in the order of declaration. + The TREE_PURPOSE of each TREE_LIST is NULL_TREE for a friend, + and the RECORD_TYPE for the class template otherwise. */ +#define CLASSTYPE_DECL_LIST(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->decl_list) + +/* The slot in the CLASSTYPE_METHOD_VEC where constructors go. */ +#define CLASSTYPE_CONSTRUCTOR_SLOT 0 + +/* The slot in the CLASSTYPE_METHOD_VEC where destructors go. */ +#define CLASSTYPE_DESTRUCTOR_SLOT 1 + +/* The first slot in the CLASSTYPE_METHOD_VEC where conversion + operators can appear. */ +#define CLASSTYPE_FIRST_CONVERSION_SLOT 2 + +/* A FUNCTION_DECL or OVERLOAD for the constructors for NODE. These + are the constructors that take an in-charge parameter. */ +#define CLASSTYPE_CONSTRUCTORS(NODE) \ + ((*CLASSTYPE_METHOD_VEC (NODE))[CLASSTYPE_CONSTRUCTOR_SLOT]) + +/* A FUNCTION_DECL for the destructor for NODE. These are the + destructors that take an in-charge parameter. If + CLASSTYPE_LAZY_DESTRUCTOR is true, then this entry will be NULL + until the destructor is created with lazily_declare_fn. */ +#define CLASSTYPE_DESTRUCTORS(NODE) \ + (CLASSTYPE_METHOD_VEC (NODE) \ + ? (*CLASSTYPE_METHOD_VEC (NODE))[CLASSTYPE_DESTRUCTOR_SLOT] \ + : NULL_TREE) + +/* A dictionary of the nested user-defined-types (class-types, or enums) + found within this class. This table includes nested member class + templates. */ +#define CLASSTYPE_NESTED_UTDS(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->nested_udts) + +/* Nonzero if NODE has a primary base class, i.e., a base class with + which it shares the virtual function table pointer. */ +#define CLASSTYPE_HAS_PRIMARY_BASE_P(NODE) \ + (CLASSTYPE_PRIMARY_BINFO (NODE) != NULL_TREE) + +/* If non-NULL, this is the binfo for the primary base class, i.e., + the base class which contains the virtual function table pointer + for this class. */ +#define CLASSTYPE_PRIMARY_BINFO(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->primary_base) + +/* A vector of BINFOs for the direct and indirect virtual base classes + that this type uses in a post-order depth-first left-to-right + order. (In other words, these bases appear in the order that they + should be initialized.) */ +#define CLASSTYPE_VBASECLASSES(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->vbases) + +/* The type corresponding to NODE when NODE is used as a base class, + i.e., NODE without virtual base classes. */ + +#define CLASSTYPE_AS_BASE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->as_base) + +/* True iff NODE is the CLASSTYPE_AS_BASE version of some type. */ + +#define IS_FAKE_BASE_TYPE(NODE) \ + (TREE_CODE (NODE) == RECORD_TYPE \ + && TYPE_CONTEXT (NODE) && CLASS_TYPE_P (TYPE_CONTEXT (NODE)) \ + && CLASSTYPE_AS_BASE (TYPE_CONTEXT (NODE)) == (NODE)) + +/* These are the size and alignment of the type without its virtual + base classes, for when we use this type as a base itself. */ +#define CLASSTYPE_SIZE(NODE) TYPE_SIZE (CLASSTYPE_AS_BASE (NODE)) +#define CLASSTYPE_SIZE_UNIT(NODE) TYPE_SIZE_UNIT (CLASSTYPE_AS_BASE (NODE)) +#define CLASSTYPE_ALIGN(NODE) TYPE_ALIGN (CLASSTYPE_AS_BASE (NODE)) +#define CLASSTYPE_USER_ALIGN(NODE) TYPE_USER_ALIGN (CLASSTYPE_AS_BASE (NODE)) + +/* The alignment of NODE, without its virtual bases, in bytes. */ +#define CLASSTYPE_ALIGN_UNIT(NODE) \ + (CLASSTYPE_ALIGN (NODE) / BITS_PER_UNIT) + +/* True if this a Java interface type, declared with + '__attribute__ ((java_interface))'. */ +#define TYPE_JAVA_INTERFACE(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->java_interface) + +/* A vec of virtual functions which cannot be inherited by + derived classes. When deriving from this type, the derived + class must provide its own definition for each of these functions. */ +#define CLASSTYPE_PURE_VIRTUALS(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->pure_virtuals) + +/* Nonzero means that this type is an abstract class type. */ +#define ABSTRACT_CLASS_TYPE_P(NODE) \ + (CLASS_TYPE_P (NODE) && CLASSTYPE_PURE_VIRTUALS(NODE)) + +/* Nonzero means that this type has an X() constructor. */ +#define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->h.has_default_ctor) + +/* Nonzero means that this type contains a mutable member. */ +#define CLASSTYPE_HAS_MUTABLE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_mutable) +#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE)) + +/* Nonzero means that this class type is not POD for the purpose of layout + (as defined in the ABI). This is different from the language's POD. */ +#define CLASSTYPE_NON_LAYOUT_POD_P(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->non_pod_class) + +/* Nonzero means that this class type is a non-standard-layout class. */ +#define CLASSTYPE_NON_STD_LAYOUT(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->non_std_layout) + +/* Nonzero means that this class contains pod types whose default + initialization is not a zero initialization (namely, pointers to + data members). */ +#define CLASSTYPE_NON_ZERO_INIT_P(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->non_zero_init) + +/* Nonzero if this class is "empty" in the sense of the C++ ABI. */ +#define CLASSTYPE_EMPTY_P(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->empty_p) + +/* Nonzero if this class is "nearly empty", i.e., contains only a + virtual function table pointer. */ +#define CLASSTYPE_NEARLY_EMPTY_P(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->nearly_empty_p) + +/* Nonzero if this class contains an empty subobject. */ +#define CLASSTYPE_CONTAINS_EMPTY_CLASS_P(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->contains_empty_class_p) + +/* A list of class types of which this type is a friend. The + TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the + case of a template friend. */ +#define CLASSTYPE_FRIEND_CLASSES(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->friend_classes) + +/* A list of the classes which grant friendship to this class. */ +#define CLASSTYPE_BEFRIENDING_CLASSES(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->befriending_classes) + +/* The associated LAMBDA_EXPR that made this class. */ +#define CLASSTYPE_LAMBDA_EXPR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->lambda_expr) +/* The extra mangling scope for this closure type. */ +#define LAMBDA_TYPE_EXTRA_SCOPE(NODE) \ + (LAMBDA_EXPR_EXTRA_SCOPE (CLASSTYPE_LAMBDA_EXPR (NODE))) + +/* Say whether this node was declared as a "class" or a "struct". */ +#define CLASSTYPE_DECLARED_CLASS(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->declared_class) + +/* Nonzero if this class has const members + which have no specified initialization. */ +#define CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE) \ + (TYPE_LANG_SPECIFIC (NODE) \ + ? LANG_TYPE_CLASS_CHECK (NODE)->h.const_needs_init : 0) +#define SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE, VALUE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->h.const_needs_init = (VALUE)) + +/* Nonzero if this class has ref members + which have no specified initialization. */ +#define CLASSTYPE_REF_FIELDS_NEED_INIT(NODE) \ + (TYPE_LANG_SPECIFIC (NODE) \ + ? LANG_TYPE_CLASS_CHECK (NODE)->h.ref_needs_init : 0) +#define SET_CLASSTYPE_REF_FIELDS_NEED_INIT(NODE, VALUE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->h.ref_needs_init = (VALUE)) + +/* Nonzero if this class is included from a header file which employs + `#pragma interface', and it is not included in its implementation file. */ +#define CLASSTYPE_INTERFACE_ONLY(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->interface_only) + +/* True if we have already determined whether or not vtables, VTTs, + typeinfo, and other similar per-class data should be emitted in + this translation unit. This flag does not indicate whether or not + these items should be emitted; it only indicates that we know one + way or the other. */ +#define CLASSTYPE_INTERFACE_KNOWN(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown == 0) +/* The opposite of CLASSTYPE_INTERFACE_KNOWN. */ +#define CLASSTYPE_INTERFACE_UNKNOWN(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown) + +#define SET_CLASSTYPE_INTERFACE_UNKNOWN_X(NODE,X) \ + (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = !!(X)) +#define SET_CLASSTYPE_INTERFACE_UNKNOWN(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = 1) +#define SET_CLASSTYPE_INTERFACE_KNOWN(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->interface_unknown = 0) + +/* Nonzero if a _DECL node requires us to output debug info for this class. */ +#define CLASSTYPE_DEBUG_REQUESTED(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->debug_requested) + +/* Additional macros for inheritance information. */ + +/* Nonzero means that this class is on a path leading to a new vtable. */ +#define BINFO_VTABLE_PATH_MARKED(NODE) BINFO_FLAG_1 (NODE) + +/* Nonzero means B (a BINFO) has its own vtable. Any copies will not + have this flag set. */ +#define BINFO_NEW_VTABLE_MARKED(B) (BINFO_FLAG_2 (B)) + +/* Compare a BINFO_TYPE with another type for equality. For a binfo, + this is functionally equivalent to using same_type_p, but + measurably faster. At least one of the arguments must be a + BINFO_TYPE. The other can be a BINFO_TYPE or a regular type. If + BINFO_TYPE(T) ever stops being the main variant of the class the + binfo is for, this macro must change. */ +#define SAME_BINFO_TYPE_P(A, B) ((A) == (B)) + +/* Any subobject that needs a new vtable must have a vptr and must not + be a non-virtual primary base (since it would then use the vtable from a + derived class and never become non-primary.) */ +#define SET_BINFO_NEW_VTABLE_MARKED(B) \ + (BINFO_NEW_VTABLE_MARKED (B) = 1, \ + gcc_assert (!BINFO_PRIMARY_P (B) || BINFO_VIRTUAL_P (B)), \ + gcc_assert (TYPE_VFIELD (BINFO_TYPE (B)))) + +/* Nonzero if this binfo is for a dependent base - one that should not + be searched. */ +#define BINFO_DEPENDENT_BASE_P(NODE) BINFO_FLAG_3 (NODE) + +/* Nonzero if this binfo has lost its primary base binfo (because that + is a nearly-empty virtual base that has been taken by some other + base in the complete hierarchy. */ +#define BINFO_LOST_PRIMARY_P(NODE) BINFO_FLAG_4 (NODE) + +/* Nonzero if this BINFO is a primary base class. */ +#define BINFO_PRIMARY_P(NODE) BINFO_FLAG_5(NODE) + +/* Used by various search routines. */ +#define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE) + +/* A vec of the vcall indices associated with the class + NODE. The PURPOSE of each element is a FUNCTION_DECL for a virtual + function. The VALUE is the index into the virtual table where the + vcall offset for that function is stored, when NODE is a virtual + base. */ +#define CLASSTYPE_VCALL_INDICES(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->vcall_indices) + +/* The various vtables for the class NODE. The primary vtable will be + first, followed by the construction vtables and VTT, if any. */ +#define CLASSTYPE_VTABLES(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->vtables) + +/* The std::type_info variable representing this class, or NULL if no + such variable has been created. This field is only set for the + TYPE_MAIN_VARIANT of the class. */ +#define CLASSTYPE_TYPEINFO_VAR(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->typeinfo_var) + +/* Accessor macros for the BINFO_VIRTUALS list. */ + +/* The number of bytes by which to adjust the `this' pointer when + calling this virtual function. Subtract this value from the this + pointer. Always non-NULL, might be constant zero though. */ +#define BV_DELTA(NODE) (TREE_PURPOSE (NODE)) + +/* If non-NULL, the vtable index at which to find the vcall offset + when calling this virtual function. Add the value at that vtable + index to the this pointer. */ +#define BV_VCALL_INDEX(NODE) (TREE_TYPE (NODE)) + +/* The function to call. */ +#define BV_FN(NODE) (TREE_VALUE (NODE)) + +/* Whether or not this entry is for a lost primary virtual base. */ +#define BV_LOST_PRIMARY(NODE) (TREE_LANG_FLAG_0 (NODE)) + +/* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that + this type can raise. Each TREE_VALUE is a _TYPE. The TREE_VALUE + will be NULL_TREE to indicate a throw specification of `()', or + no exceptions allowed. For a noexcept specification, TREE_VALUE + is NULL_TREE and TREE_PURPOSE is the constant-expression. For + a deferred noexcept-specification, TREE_PURPOSE is a DEFERRED_NOEXCEPT + (for templates) or an OVERLOAD list of functions (for implicitly + declared functions). */ +#define TYPE_RAISES_EXCEPTIONS(NODE) TYPE_LANG_SLOT_1 (NODE) + +/* For FUNCTION_TYPE or METHOD_TYPE, return 1 iff it is declared `throw()' + or noexcept(true). */ +#define TYPE_NOTHROW_P(NODE) nothrow_spec_p (TYPE_RAISES_EXCEPTIONS (NODE)) + +/* For FUNCTION_TYPE or METHOD_TYPE, true if NODE is noexcept. This is the + case for things declared noexcept(true) and, with -fnothrow-opt, for + throw() functions. */ +#define TYPE_NOEXCEPT_P(NODE) type_noexcept_p (NODE) + +/* The binding level associated with the namespace. */ +#define NAMESPACE_LEVEL(NODE) \ + (LANG_DECL_NS_CHECK (NODE)->level) + +/* Flags shared by all forms of DECL_LANG_SPECIFIC. + + Some of the flags live here only to make lang_decl_min/fn smaller. Do + not make this struct larger than 32 bits; instead, make sel smaller. */ + +struct GTY(()) lang_decl_base { + unsigned selector : 16; /* Larger than necessary for faster access. */ + ENUM_BITFIELD(languages) language : 4; + unsigned use_template : 2; + unsigned not_really_extern : 1; /* var or fn */ + unsigned initialized_in_class : 1; /* var or fn */ + unsigned repo_available_p : 1; /* var or fn */ + unsigned threadprivate_or_deleted_p : 1; /* var or fn */ + unsigned anticipated_p : 1; /* fn, type or template */ + unsigned friend_attr : 1; /* fn, type or template */ + unsigned template_conv_p : 1; /* var or template */ + unsigned odr_used : 1; /* var or fn */ + unsigned u2sel : 1; + /* 1 spare bit */ +}; + +/* True for DECL codes which have template info and access. */ +#define LANG_DECL_HAS_MIN(NODE) \ + (TREE_CODE (NODE) == FUNCTION_DECL \ + || TREE_CODE (NODE) == FIELD_DECL \ + || TREE_CODE (NODE) == VAR_DECL \ + || TREE_CODE (NODE) == CONST_DECL \ + || TREE_CODE (NODE) == TYPE_DECL \ + || TREE_CODE (NODE) == TEMPLATE_DECL \ + || TREE_CODE (NODE) == USING_DECL) + +/* DECL_LANG_SPECIFIC for the above codes. */ + +struct GTY(()) lang_decl_min { + struct lang_decl_base base; + + /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is + THUNK_ALIAS. + In a FUNCTION_DECL for which DECL_THUNK_P does not hold, + VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this is + DECL_TEMPLATE_INFO. */ + tree template_info; + + union lang_decl_u2 { + /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is + THUNK_VIRTUAL_OFFSET. + Otherwise this is DECL_ACCESS. */ + tree GTY ((tag ("0"))) access; + + /* For VAR_DECL in function, this is DECL_DISCRIMINATOR. */ + int GTY ((tag ("1"))) discriminator; + } GTY ((desc ("%0.u.base.u2sel"))) u2; +}; + +/* Additional DECL_LANG_SPECIFIC information for functions. */ + +struct GTY(()) lang_decl_fn { + struct lang_decl_min min; + + /* In an overloaded operator, this is the value of + DECL_OVERLOADED_OPERATOR_P. */ + ENUM_BITFIELD (tree_code) operator_code : 16; + + unsigned global_ctor_p : 1; + unsigned global_dtor_p : 1; + unsigned constructor_attr : 1; + unsigned destructor_attr : 1; + unsigned assignment_operator_p : 1; + unsigned static_function : 1; + unsigned pure_virtual : 1; + unsigned defaulted_p : 1; + + unsigned has_in_charge_parm_p : 1; + unsigned has_vtt_parm_p : 1; + unsigned pending_inline_p : 1; + unsigned nonconverting : 1; + unsigned thunk_p : 1; + unsigned this_thunk_p : 1; + unsigned hidden_friend_p : 1; + /* 1 spare bit. */ + + /* For a non-thunk function decl, this is a tree list of + friendly classes. For a thunk function decl, it is the + thunked to function decl. */ + tree befriending_classes; + + /* For a non-virtual FUNCTION_DECL, this is + DECL_FRIEND_CONTEXT. For a virtual FUNCTION_DECL for which + DECL_THIS_THUNK_P does not hold, this is DECL_THUNKS. Both + this pointer and result pointer adjusting thunks are + chained here. This pointer thunks to return pointer thunks + will be chained on the return pointer thunk. */ + tree context; + + union lang_decl_u5 + { + /* In a non-thunk FUNCTION_DECL or TEMPLATE_DECL, this is + DECL_CLONED_FUNCTION. */ + tree GTY ((tag ("0"))) cloned_function; + + /* In a FUNCTION_DECL for which THUNK_P holds this is the + THUNK_FIXED_OFFSET. */ + HOST_WIDE_INT GTY ((tag ("1"))) fixed_offset; + } GTY ((desc ("%1.thunk_p"))) u5; + + union lang_decl_u3 + { + struct cp_token_cache * GTY ((tag ("1"))) pending_inline_info; + struct language_function * GTY ((tag ("0"))) + saved_language_function; + } GTY ((desc ("%1.pending_inline_p"))) u; + +}; + +/* DECL_LANG_SPECIFIC for namespaces. */ + +struct GTY(()) lang_decl_ns { + struct lang_decl_base base; + cp_binding_level *level; +}; + +/* DECL_LANG_SPECIFIC for parameters. */ + +struct GTY(()) lang_decl_parm { + struct lang_decl_base base; + int level; + int index; +}; + +/* DECL_LANG_SPECIFIC for all types. It would be nice to just make this a + union rather than a struct containing a union as its only field, but + tree.h declares it as a struct. */ + +struct GTY((variable_size)) lang_decl { + union GTY((desc ("%h.base.selector"))) lang_decl_u { + struct lang_decl_base GTY ((default)) base; + struct lang_decl_min GTY((tag ("0"))) min; + struct lang_decl_fn GTY ((tag ("1"))) fn; + struct lang_decl_ns GTY((tag ("2"))) ns; + struct lang_decl_parm GTY((tag ("3"))) parm; + } u; +}; + +/* Looks through a template (if present) to find what it declares. */ +#define STRIP_TEMPLATE(NODE) \ + (TREE_CODE (NODE) == TEMPLATE_DECL ? DECL_TEMPLATE_RESULT (NODE) : NODE) + +#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) + +#define LANG_DECL_MIN_CHECK(NODE) __extension__ \ +({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \ + if (!LANG_DECL_HAS_MIN (NODE)) \ + lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ + <->u.min; }) + +/* We want to be able to check DECL_CONSTRUCTOR_P and such on a function + template, not just on a FUNCTION_DECL. So when looking for things in + lang_decl_fn, look down through a TEMPLATE_DECL into its result. */ +#define LANG_DECL_FN_CHECK(NODE) __extension__ \ +({ struct lang_decl *lt = DECL_LANG_SPECIFIC (STRIP_TEMPLATE (NODE)); \ + if (!DECL_DECLARES_FUNCTION_P (NODE) || lt->u.base.selector != 1) \ + lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ + <->u.fn; }) + +#define LANG_DECL_NS_CHECK(NODE) __extension__ \ +({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \ + if (TREE_CODE (NODE) != NAMESPACE_DECL || lt->u.base.selector != 2) \ + lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ + <->u.ns; }) + +#define LANG_DECL_PARM_CHECK(NODE) __extension__ \ +({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \ + if (TREE_CODE (NODE) != PARM_DECL) \ + lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ + <->u.parm; }) + +#define LANG_DECL_U2_CHECK(NODE, TF) __extension__ \ +({ struct lang_decl *lt = DECL_LANG_SPECIFIC (NODE); \ + if (!LANG_DECL_HAS_MIN (NODE) || lt->u.base.u2sel != TF) \ + lang_check_failed (__FILE__, __LINE__, __FUNCTION__); \ + <->u.min.u2; }) + +#else + +#define LANG_DECL_MIN_CHECK(NODE) \ + (&DECL_LANG_SPECIFIC (NODE)->u.min) + +#define LANG_DECL_FN_CHECK(NODE) \ + (&DECL_LANG_SPECIFIC (STRIP_TEMPLATE (NODE))->u.fn) + +#define LANG_DECL_NS_CHECK(NODE) \ + (&DECL_LANG_SPECIFIC (NODE)->u.ns) + +#define LANG_DECL_PARM_CHECK(NODE) \ + (&DECL_LANG_SPECIFIC (NODE)->u.parm) + +#define LANG_DECL_U2_CHECK(NODE, TF) \ + (&DECL_LANG_SPECIFIC (NODE)->u.min.u2) + +#endif /* ENABLE_TREE_CHECKING */ + +/* For a FUNCTION_DECL or a VAR_DECL, the language linkage for the + declaration. Some entities (like a member function in a local + class, or a local variable) do not have linkage at all, and this + macro should not be used in those cases. + + Implementation note: A FUNCTION_DECL without DECL_LANG_SPECIFIC was + created by language-independent code, and has C linkage. Most + VAR_DECLs have C++ linkage, and do not have DECL_LANG_SPECIFIC, but + we do create DECL_LANG_SPECIFIC for variables with non-C++ linkage. */ +#define DECL_LANGUAGE(NODE) \ + (DECL_LANG_SPECIFIC (NODE) \ + ? DECL_LANG_SPECIFIC (NODE)->u.base.language \ + : (TREE_CODE (NODE) == FUNCTION_DECL \ + ? lang_c : lang_cplusplus)) + +/* Set the language linkage for NODE to LANGUAGE. */ +#define SET_DECL_LANGUAGE(NODE, LANGUAGE) \ + (DECL_LANG_SPECIFIC (NODE)->u.base.language = (LANGUAGE)) + +/* For FUNCTION_DECLs: nonzero means that this function is a constructor. */ +#define DECL_CONSTRUCTOR_P(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->constructor_attr) + +/* Nonzero if NODE (a FUNCTION_DECL) is a constructor for a complete + object. */ +#define DECL_COMPLETE_CONSTRUCTOR_P(NODE) \ + (DECL_CONSTRUCTOR_P (NODE) \ + && DECL_NAME (NODE) == complete_ctor_identifier) + +/* Nonzero if NODE (a FUNCTION_DECL) is a constructor for a base + object. */ +#define DECL_BASE_CONSTRUCTOR_P(NODE) \ + (DECL_CONSTRUCTOR_P (NODE) \ + && DECL_NAME (NODE) == base_ctor_identifier) + +/* Nonzero if NODE (a FUNCTION_DECL) is a constructor, but not either the + specialized in-charge constructor or the specialized not-in-charge + constructor. */ +#define DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P(NODE) \ + (DECL_DECLARES_FUNCTION_P (NODE) && DECL_CONSTRUCTOR_P (NODE) \ + && !DECL_CLONED_FUNCTION_P (NODE)) + +/* Nonzero if NODE (a FUNCTION_DECL) is a copy constructor. */ +#define DECL_COPY_CONSTRUCTOR_P(NODE) \ + (DECL_CONSTRUCTOR_P (NODE) && copy_fn_p (NODE) > 0) + +/* Nonzero if NODE (a FUNCTION_DECL) is a move constructor. */ +#define DECL_MOVE_CONSTRUCTOR_P(NODE) \ + (DECL_CONSTRUCTOR_P (NODE) && move_fn_p (NODE)) + +/* Nonzero if NODE is a destructor. */ +#define DECL_DESTRUCTOR_P(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->destructor_attr) + +/* Nonzero if NODE (a FUNCTION_DECL) is a destructor, but not the + specialized in-charge constructor, in-charge deleting constructor, + or the base destructor. */ +#define DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P(NODE) \ + (DECL_DECLARES_FUNCTION_P (NODE) && DECL_DESTRUCTOR_P (NODE) \ + && !DECL_CLONED_FUNCTION_P (NODE)) + +/* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a complete + object. */ +#define DECL_COMPLETE_DESTRUCTOR_P(NODE) \ + (DECL_DESTRUCTOR_P (NODE) \ + && DECL_NAME (NODE) == complete_dtor_identifier) + +/* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a base + object. */ +#define DECL_BASE_DESTRUCTOR_P(NODE) \ + (DECL_DESTRUCTOR_P (NODE) \ + && DECL_NAME (NODE) == base_dtor_identifier) + +/* Nonzero if NODE (a FUNCTION_DECL) is a destructor for a complete + object that deletes the object after it has been destroyed. */ +#define DECL_DELETING_DESTRUCTOR_P(NODE) \ + (DECL_DESTRUCTOR_P (NODE) \ + && DECL_NAME (NODE) == deleting_dtor_identifier) + +/* Nonzero if NODE (a FUNCTION_DECL) is a cloned constructor or + destructor. */ +#define DECL_CLONED_FUNCTION_P(NODE) (!!decl_cloned_function_p (NODE, true)) + +/* If DECL_CLONED_FUNCTION_P holds, this is the function that was + cloned. */ +#define DECL_CLONED_FUNCTION(NODE) (*decl_cloned_function_p (NODE, false)) + +/* Perform an action for each clone of FN, if FN is a function with + clones. This macro should be used like: + + FOR_EACH_CLONE (clone, fn) + { ... } + + */ +#define FOR_EACH_CLONE(CLONE, FN) \ + if (TREE_CODE (FN) == FUNCTION_DECL \ + && (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (FN) \ + || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (FN))) \ + for (CLONE = DECL_CHAIN (FN); \ + CLONE && DECL_CLONED_FUNCTION_P (CLONE); \ + CLONE = DECL_CHAIN (CLONE)) + +/* Nonzero if NODE has DECL_DISCRIMINATOR and not DECL_ACCESS. */ +#define DECL_DISCRIMINATOR_P(NODE) \ + (TREE_CODE (NODE) == VAR_DECL \ + && DECL_FUNCTION_SCOPE_P (NODE)) + +/* Discriminator for name mangling. */ +#define DECL_DISCRIMINATOR(NODE) (LANG_DECL_U2_CHECK (NODE, 1)->discriminator) + +/* True iff DECL_DISCRIMINATOR is set for a DECL_DISCRIMINATOR_P decl. */ +#define DECL_DISCRIMINATOR_SET_P(NODE) \ + (DECL_LANG_SPECIFIC (NODE) && DECL_LANG_SPECIFIC (NODE)->u.base.u2sel == 1) + +/* The index of a user-declared parameter in its function, starting at 1. + All artificial parameters will have index 0. */ +#define DECL_PARM_INDEX(NODE) \ + (LANG_DECL_PARM_CHECK (NODE)->index) + +/* The level of a user-declared parameter in its function, starting at 1. + A parameter of the function will have level 1; a parameter of the first + nested function declarator (i.e. t in void f (void (*p)(T t))) will have + level 2. */ +#define DECL_PARM_LEVEL(NODE) \ + (LANG_DECL_PARM_CHECK (NODE)->level) + +/* Nonzero if the VTT parm has been added to NODE. */ +#define DECL_HAS_VTT_PARM_P(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p) + +/* Nonzero if NODE is a FUNCTION_DECL for which a VTT parameter is + required. */ +#define DECL_NEEDS_VTT_PARM_P(NODE) \ + (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (NODE)) \ + && (DECL_BASE_CONSTRUCTOR_P (NODE) \ + || DECL_BASE_DESTRUCTOR_P (NODE))) + +/* Nonzero if NODE is a user-defined conversion operator. */ +#define DECL_CONV_FN_P(NODE) \ + (DECL_NAME (NODE) && IDENTIFIER_TYPENAME_P (DECL_NAME (NODE))) + +/* If FN is a conversion operator, the type to which it converts. + Otherwise, NULL_TREE. */ +#define DECL_CONV_FN_TYPE(FN) \ + (DECL_CONV_FN_P (FN) ? TREE_TYPE (DECL_NAME (FN)) : NULL_TREE) + +/* Nonzero if NODE, which is a TEMPLATE_DECL, is a template + conversion operator to a type dependent on the innermost template + args. */ +#define DECL_TEMPLATE_CONV_FN_P(NODE) \ + (DECL_LANG_SPECIFIC (TEMPLATE_DECL_CHECK (NODE))->u.base.template_conv_p) + +/* Nonzero if NODE, a static data member, was declared in its class as an + array of unknown bound. */ +#define VAR_HAD_UNKNOWN_BOUND(NODE) \ + (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE)) \ + ? DECL_LANG_SPECIFIC (NODE)->u.base.template_conv_p \ + : false) +#define SET_VAR_HAD_UNKNOWN_BOUND(NODE) \ + (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (NODE))->u.base.template_conv_p = true) + +/* Set the overloaded operator code for NODE to CODE. */ +#define SET_OVERLOADED_OPERATOR_CODE(NODE, CODE) \ + (LANG_DECL_FN_CHECK (NODE)->operator_code = (CODE)) + +/* If NODE is an overloaded operator, then this returns the TREE_CODE + associated with the overloaded operator. + DECL_ASSIGNMENT_OPERATOR_P must also be checked to determine + whether or not NODE is an assignment operator. If NODE is not an + overloaded operator, ERROR_MARK is returned. Since the numerical + value of ERROR_MARK is zero, this macro can be used as a predicate + to test whether or not NODE is an overloaded operator. */ +#define DECL_OVERLOADED_OPERATOR_P(NODE) \ + (IDENTIFIER_OPNAME_P (DECL_NAME (NODE)) \ + ? LANG_DECL_FN_CHECK (NODE)->operator_code : ERROR_MARK) + +/* Nonzero if NODE is an assignment operator (including += and such). */ +#define DECL_ASSIGNMENT_OPERATOR_P(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->assignment_operator_p) + +/* For FUNCTION_DECLs: nonzero means that this function is a + constructor or a destructor with an extra in-charge parameter to + control whether or not virtual bases are constructed. */ +#define DECL_HAS_IN_CHARGE_PARM_P(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->has_in_charge_parm_p) + +/* Nonzero if DECL is a declaration of __builtin_constant_p. */ +#define DECL_IS_BUILTIN_CONSTANT_P(NODE) \ + (TREE_CODE (NODE) == FUNCTION_DECL \ + && DECL_BUILT_IN_CLASS (NODE) == BUILT_IN_NORMAL \ + && DECL_FUNCTION_CODE (NODE) == BUILT_IN_CONSTANT_P) + +/* Nonzero for _DECL means that this decl appears in (or will appear + in) as a member in a RECORD_TYPE or UNION_TYPE node. It is also for + detecting circularity in case members are multiply defined. In the + case of a VAR_DECL, it is also used to determine how program storage + should be allocated. */ +#define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3 (NODE)) + +/* Nonzero for a VAR_DECL means that the variable's initialization (if + any) has been processed. (In general, DECL_INITIALIZED_P is + !DECL_EXTERNAL, but static data members may be initialized even if + not defined.) */ +#define DECL_INITIALIZED_P(NODE) \ + (TREE_LANG_FLAG_1 (VAR_DECL_CHECK (NODE))) + +/* Nonzero for a VAR_DECL iff an explicit initializer was provided + or a non-trivial constructor is called. */ +#define DECL_NONTRIVIALLY_INITIALIZED_P(NODE) \ + (TREE_LANG_FLAG_3 (VAR_DECL_CHECK (NODE))) + +/* Nonzero for a VAR_DECL that was initialized with a + constant-expression. */ +#define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \ + (TREE_LANG_FLAG_2 (VAR_DECL_CHECK (NODE))) + +/* Nonzero if the DECL was initialized in the class definition itself, + rather than outside the class. This is used for both static member + VAR_DECLS, and FUNCTION_DECLS that are defined in the class. */ +#define DECL_INITIALIZED_IN_CLASS_P(DECL) \ + (DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL)) \ + ->u.base.initialized_in_class) + +/* Nonzero if the DECL is used in the sense of 3.2 [basic.def.odr]. + Only available for decls with DECL_LANG_SPECIFIC. */ +#define DECL_ODR_USED(DECL) \ + (DECL_LANG_SPECIFIC (VAR_OR_FUNCTION_DECL_CHECK (DECL)) \ + ->u.base.odr_used) + +/* Nonzero for DECL means that this decl is just a friend declaration, + and should not be added to the list of members for this class. */ +#define DECL_FRIEND_P(NODE) \ + (DECL_LANG_SPECIFIC (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK (NODE)) \ + ->u.base.friend_attr) + +/* A TREE_LIST of the types which have befriended this FUNCTION_DECL. */ +#define DECL_BEFRIENDING_CLASSES(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->befriending_classes) + +/* Nonzero for FUNCTION_DECL means that this decl is a static + member function. */ +#define DECL_STATIC_FUNCTION_P(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->static_function) + +/* Nonzero for FUNCTION_DECL means that this decl is a non-static + member function. */ +#define DECL_NONSTATIC_MEMBER_FUNCTION_P(NODE) \ + (TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE) + +/* Nonzero for FUNCTION_DECL means that this decl is a member function + (static or non-static). */ +#define DECL_FUNCTION_MEMBER_P(NODE) \ + (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE)) + +/* Nonzero for FUNCTION_DECL means that this member function + has `this' as const X *const. */ +#define DECL_CONST_MEMFUNC_P(NODE) \ + (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \ + && CP_TYPE_CONST_P (TREE_TYPE (TREE_VALUE \ + (TYPE_ARG_TYPES (TREE_TYPE (NODE)))))) + +/* Nonzero for FUNCTION_DECL means that this member function + has `this' as volatile X *const. */ +#define DECL_VOLATILE_MEMFUNC_P(NODE) \ + (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \ + && CP_TYPE_VOLATILE_P (TREE_TYPE (TREE_VALUE \ + (TYPE_ARG_TYPES (TREE_TYPE (NODE)))))) + +/* Nonzero for a DECL means that this member is a non-static member. */ +#define DECL_NONSTATIC_MEMBER_P(NODE) \ + (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \ + || TREE_CODE (NODE) == FIELD_DECL) + +/* Nonzero for _DECL means that this member object type + is mutable. */ +#define DECL_MUTABLE_P(NODE) (DECL_LANG_FLAG_0 (NODE)) + +/* Nonzero for _DECL means that this constructor or conversion function is + non-converting. */ +#define DECL_NONCONVERTING_P(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->nonconverting) + +/* Nonzero for FUNCTION_DECL means that this member function is a pure + virtual function. */ +#define DECL_PURE_VIRTUAL_P(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->pure_virtual) + +/* True (in a FUNCTION_DECL) if NODE is a virtual function that is an + invalid overrider for a function from a base class. Once we have + complained about an invalid overrider we avoid complaining about it + again. */ +#define DECL_INVALID_OVERRIDER_P(NODE) \ + (DECL_LANG_FLAG_4 (NODE)) + +/* True (in a FUNCTION_DECL) if NODE is a function declared with + an override virt-specifier */ +#define DECL_OVERRIDE_P(NODE) (TREE_LANG_FLAG_0 (NODE)) + +/* True (in a FUNCTION_DECL) if NODE is a function declared with + a final virt-specifier */ +#define DECL_FINAL_P(NODE) (TREE_LANG_FLAG_1 (NODE)) + +/* The thunks associated with NODE, a FUNCTION_DECL. */ +#define DECL_THUNKS(NODE) \ + (DECL_VIRTUAL_P (NODE) ? LANG_DECL_FN_CHECK (NODE)->context : NULL_TREE) + +/* Set DECL_THUNKS. */ +#define SET_DECL_THUNKS(NODE,THUNKS) \ + (LANG_DECL_FN_CHECK (NODE)->context = (THUNKS)) + +/* If NODE, a FUNCTION_DECL, is a C++11 inheriting constructor, then this + is the base it inherits from. */ +#define DECL_INHERITED_CTOR_BASE(NODE) \ + (DECL_CONSTRUCTOR_P (NODE) ? LANG_DECL_FN_CHECK (NODE)->context : NULL_TREE) + +/* Set the inherited base. */ +#define SET_DECL_INHERITED_CTOR_BASE(NODE,INH) \ + (LANG_DECL_FN_CHECK (NODE)->context = (INH)) + +/* Nonzero if NODE is a thunk, rather than an ordinary function. */ +#define DECL_THUNK_P(NODE) \ + (TREE_CODE (NODE) == FUNCTION_DECL \ + && DECL_LANG_SPECIFIC (NODE) \ + && LANG_DECL_FN_CHECK (NODE)->thunk_p) + +/* Set DECL_THUNK_P for node. */ +#define SET_DECL_THUNK_P(NODE, THIS_ADJUSTING) \ + (LANG_DECL_FN_CHECK (NODE)->thunk_p = 1, \ + LANG_DECL_FN_CHECK (NODE)->this_thunk_p = (THIS_ADJUSTING)) + +/* Nonzero if NODE is a this pointer adjusting thunk. */ +#define DECL_THIS_THUNK_P(NODE) \ + (DECL_THUNK_P (NODE) && LANG_DECL_FN_CHECK (NODE)->this_thunk_p) + +/* Nonzero if NODE is a result pointer adjusting thunk. */ +#define DECL_RESULT_THUNK_P(NODE) \ + (DECL_THUNK_P (NODE) && !LANG_DECL_FN_CHECK (NODE)->this_thunk_p) + +/* Nonzero if NODE is a FUNCTION_DECL, but not a thunk. */ +#define DECL_NON_THUNK_FUNCTION_P(NODE) \ + (TREE_CODE (NODE) == FUNCTION_DECL && !DECL_THUNK_P (NODE)) + +/* Nonzero if NODE is `extern "C"'. */ +#define DECL_EXTERN_C_P(NODE) \ + (DECL_LANGUAGE (NODE) == lang_c) + +/* Nonzero if NODE is an `extern "C"' function. */ +#define DECL_EXTERN_C_FUNCTION_P(NODE) \ + (DECL_NON_THUNK_FUNCTION_P (NODE) && DECL_EXTERN_C_P (NODE)) + +/* True iff DECL is an entity with vague linkage whose definition is + available in this translation unit. */ +#define DECL_REPO_AVAILABLE_P(NODE) \ + (DECL_LANG_SPECIFIC (NODE)->u.base.repo_available_p) + +/* True if DECL is declared 'constexpr'. */ +#define DECL_DECLARED_CONSTEXPR_P(DECL) \ + DECL_LANG_FLAG_8 (VAR_OR_FUNCTION_DECL_CHECK (STRIP_TEMPLATE (DECL))) + +/* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a + template function. */ +#define DECL_PRETTY_FUNCTION_P(NODE) \ + (DECL_NAME (NODE) \ + && !strcmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__PRETTY_FUNCTION__")) + +/* Nonzero if the thread-local variable was declared with __thread + as opposed to thread_local. */ +#define DECL_GNU_TLS_P(NODE) \ + (TREE_LANG_FLAG_0 (VAR_DECL_CHECK (NODE))) + +/* The _TYPE context in which this _DECL appears. This field holds the + class where a virtual function instance is actually defined. */ +#define DECL_CLASS_CONTEXT(NODE) \ + (DECL_CLASS_SCOPE_P (NODE) ? DECL_CONTEXT (NODE) : NULL_TREE) + +/* For a non-member friend function, the class (if any) in which this + friend was defined. For example, given: + + struct S { friend void f (); }; + + the DECL_FRIEND_CONTEXT for `f' will be `S'. */ +#define DECL_FRIEND_CONTEXT(NODE) \ + ((DECL_DECLARES_FUNCTION_P (NODE) \ + && DECL_FRIEND_P (NODE) && !DECL_FUNCTION_MEMBER_P (NODE)) \ + ? LANG_DECL_FN_CHECK (NODE)->context \ + : NULL_TREE) + +/* Set the DECL_FRIEND_CONTEXT for NODE to CONTEXT. */ +#define SET_DECL_FRIEND_CONTEXT(NODE, CONTEXT) \ + (LANG_DECL_FN_CHECK (NODE)->context = (CONTEXT)) + +#define CP_DECL_CONTEXT(NODE) \ + (!DECL_FILE_SCOPE_P (NODE) ? DECL_CONTEXT (NODE) : global_namespace) +#define CP_TYPE_CONTEXT(NODE) \ + (!TYPE_FILE_SCOPE_P (NODE) ? TYPE_CONTEXT (NODE) : global_namespace) +#define FROB_CONTEXT(NODE) \ + ((NODE) == global_namespace ? DECL_CONTEXT (NODE) : (NODE)) + +/* 1 iff NODE has namespace scope, including the global namespace. */ +#define DECL_NAMESPACE_SCOPE_P(NODE) \ + (!DECL_TEMPLATE_PARM_P (NODE) \ + && TREE_CODE (CP_DECL_CONTEXT (NODE)) == NAMESPACE_DECL) + +#define TYPE_NAMESPACE_SCOPE_P(NODE) \ + (TREE_CODE (CP_TYPE_CONTEXT (NODE)) == NAMESPACE_DECL) + +#define NAMESPACE_SCOPE_P(NODE) \ + ((DECL_P (NODE) && DECL_NAMESPACE_SCOPE_P (NODE)) \ + || (TYPE_P (NODE) && TYPE_NAMESPACE_SCOPE_P (NODE))) + +/* 1 iff NODE is a class member. */ +#define DECL_CLASS_SCOPE_P(NODE) \ + (DECL_CONTEXT (NODE) && TYPE_P (DECL_CONTEXT (NODE))) + +#define TYPE_CLASS_SCOPE_P(NODE) \ + (TYPE_CONTEXT (NODE) && TYPE_P (TYPE_CONTEXT (NODE))) + +/* 1 iff NODE is function-local. */ +#define DECL_FUNCTION_SCOPE_P(NODE) \ + (DECL_CONTEXT (NODE) \ + && TREE_CODE (DECL_CONTEXT (NODE)) == FUNCTION_DECL) + +#define TYPE_FUNCTION_SCOPE_P(NODE) \ + (TYPE_CONTEXT (NODE) && TREE_CODE (TYPE_CONTEXT (NODE)) == FUNCTION_DECL) + +/* 1 iff VAR_DECL node NODE is a type-info decl. This flag is set for + both the primary typeinfo object and the associated NTBS name. */ +#define DECL_TINFO_P(NODE) TREE_LANG_FLAG_4 (VAR_DECL_CHECK (NODE)) + +/* 1 iff VAR_DECL node NODE is virtual table or VTT. */ +#define DECL_VTABLE_OR_VTT_P(NODE) TREE_LANG_FLAG_5 (VAR_DECL_CHECK (NODE)) + +/* 1 iff FUNCTION_TYPE or METHOD_TYPE has a ref-qualifier (either & or &&). */ +#define FUNCTION_REF_QUALIFIED(NODE) \ + TREE_LANG_FLAG_4 (FUNC_OR_METHOD_CHECK (NODE)) + +/* 1 iff FUNCTION_TYPE or METHOD_TYPE has &&-ref-qualifier. */ +#define FUNCTION_RVALUE_QUALIFIED(NODE) \ + TREE_LANG_FLAG_5 (FUNC_OR_METHOD_CHECK (NODE)) + +/* Returns 1 iff VAR_DECL is a construction virtual table. + DECL_VTABLE_OR_VTT_P will be true in this case and must be checked + before using this macro. */ +#define DECL_CONSTRUCTION_VTABLE_P(NODE) \ + TREE_LANG_FLAG_6 (VAR_DECL_CHECK (NODE)) + +/* 1 iff NODE is function-local, but for types. */ +#define LOCAL_CLASS_P(NODE) \ + (decl_function_context (TYPE_MAIN_DECL (NODE)) != NULL_TREE) + +/* For a NAMESPACE_DECL: the list of using namespace directives + The PURPOSE is the used namespace, the value is the namespace + that is the common ancestor. */ +#define DECL_NAMESPACE_USING(NODE) DECL_VINDEX (NAMESPACE_DECL_CHECK (NODE)) + +/* In a NAMESPACE_DECL, the DECL_INITIAL is used to record all users + of a namespace, to record the transitive closure of using namespace. */ +#define DECL_NAMESPACE_USERS(NODE) DECL_INITIAL (NAMESPACE_DECL_CHECK (NODE)) + +/* In a NAMESPACE_DECL, the list of namespaces which have associated + themselves with this one. */ +#define DECL_NAMESPACE_ASSOCIATIONS(NODE) \ + (NAMESPACE_DECL_CHECK (NODE)->decl_non_common.saved_tree) + +/* In a NAMESPACE_DECL, points to the original namespace if this is + a namespace alias. */ +#define DECL_NAMESPACE_ALIAS(NODE) \ + DECL_ABSTRACT_ORIGIN (NAMESPACE_DECL_CHECK (NODE)) +#define ORIGINAL_NAMESPACE(NODE) \ + (DECL_NAMESPACE_ALIAS (NODE) ? DECL_NAMESPACE_ALIAS (NODE) : (NODE)) + +/* Nonzero if NODE is the std namespace. */ +#define DECL_NAMESPACE_STD_P(NODE) \ + (TREE_CODE (NODE) == NAMESPACE_DECL \ + && CP_DECL_CONTEXT (NODE) == global_namespace \ + && DECL_NAME (NODE) == std_identifier) + +/* In a TREE_LIST concatenating using directives, indicate indirect + directives */ +#define TREE_INDIRECT_USING(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE)) + +/* In a TREE_LIST in an attribute list, indicates that the attribute + must be applied at instantiation time. */ +#define ATTR_IS_DEPENDENT(NODE) TREE_LANG_FLAG_0 (TREE_LIST_CHECK (NODE)) + +extern tree decl_shadowed_for_var_lookup (tree); +extern void decl_shadowed_for_var_insert (tree, tree); + +/* Non zero if this is a using decl for a dependent scope. */ +#define DECL_DEPENDENT_P(NODE) DECL_LANG_FLAG_0 (USING_DECL_CHECK (NODE)) + +/* The scope named in a using decl. */ +#define USING_DECL_SCOPE(NODE) TREE_TYPE (USING_DECL_CHECK (NODE)) + +/* The decls named by a using decl. */ +#define USING_DECL_DECLS(NODE) DECL_INITIAL (USING_DECL_CHECK (NODE)) + +/* Non zero if the using decl refers to a dependent type. */ +#define USING_DECL_TYPENAME_P(NODE) DECL_LANG_FLAG_1 (USING_DECL_CHECK (NODE)) + +/* In a VAR_DECL, true if we have a shadowed local variable + in the shadowed var table for this VAR_DECL. */ +#define DECL_HAS_SHADOWED_FOR_VAR_P(NODE) \ + (VAR_DECL_CHECK (NODE)->decl_with_vis.shadowed_for_var_p) + +/* In a VAR_DECL for a variable declared in a for statement, + this is the shadowed (local) variable. */ +#define DECL_SHADOWED_FOR_VAR(NODE) \ + (DECL_HAS_SHADOWED_FOR_VAR_P(NODE) ? decl_shadowed_for_var_lookup (NODE) : NULL) + +#define SET_DECL_SHADOWED_FOR_VAR(NODE, VAL) \ + (decl_shadowed_for_var_insert (NODE, VAL)) + +/* In a FUNCTION_DECL, this is nonzero if this function was defined in + the class definition. We have saved away the text of the function, + but have not yet processed it. */ +#define DECL_PENDING_INLINE_P(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->pending_inline_p) + +/* If DECL_PENDING_INLINE_P holds, this is the saved text of the + function. */ +#define DECL_PENDING_INLINE_INFO(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->u.pending_inline_info) + +/* Nonzero for TYPE_DECL means that it was written 'using name = type'. */ +#define TYPE_DECL_ALIAS_P(NODE) \ + DECL_LANG_FLAG_6 (TYPE_DECL_CHECK (NODE)) + +/* Nonzero for a type which is an alias for another type; i.e, a type + which declaration was written 'using name-of-type = + another-type'. */ +#define TYPE_ALIAS_P(NODE) \ + (TYPE_P (NODE) \ + && TYPE_NAME (NODE) \ + && TREE_CODE (TYPE_NAME (NODE)) == TYPE_DECL \ + && TYPE_DECL_ALIAS_P (TYPE_NAME (NODE))) + +/* For a class type: if this structure has many fields, we'll sort them + and put them into a TREE_VEC. */ +#define CLASSTYPE_SORTED_FIELDS(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->sorted_fields) + +/* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or + TEMPLATE_DECL, the entity is either a template specialization (if + DECL_USE_TEMPLATE is nonzero) or the abstract instance of the + template itself. + + In either case, DECL_TEMPLATE_INFO is a TREE_LIST, whose + TREE_PURPOSE is the TEMPLATE_DECL of which this entity is a + specialization or abstract instance. The TREE_VALUE is the + template arguments used to specialize the template. + + Consider: + + template struct S { friend void f(T) {} }; + + In this case, S::f is, from the point of view of the compiler, + an instantiation of a template -- but, from the point of view of + the language, each instantiation of S results in a wholly unrelated + global function f. In this case, DECL_TEMPLATE_INFO for S::f + will be non-NULL, but DECL_USE_TEMPLATE will be zero. */ +#define DECL_TEMPLATE_INFO(NODE) \ + (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK (NODE)) \ + ->u.min.template_info) + +/* For a VAR_DECL, indicates that the variable is actually a + non-static data member of anonymous union that has been promoted to + variable status. */ +#define DECL_ANON_UNION_VAR_P(NODE) \ + (DECL_LANG_FLAG_4 (VAR_DECL_CHECK (NODE))) + +/* Template information for a RECORD_TYPE or UNION_TYPE. */ +#define CLASSTYPE_TEMPLATE_INFO(NODE) \ + (LANG_TYPE_CLASS_CHECK (RECORD_OR_UNION_CHECK (NODE))->template_info) + +/* Template information for an ENUMERAL_TYPE. Although an enumeration may + not be a primary template, it may be declared within the scope of a + primary template and the enumeration constants may depend on + non-type template parameters. */ +#define ENUM_TEMPLATE_INFO(NODE) \ + (TYPE_LANG_SLOT_1 (ENUMERAL_TYPE_CHECK (NODE))) + +/* Template information for a template template parameter. */ +#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) \ + (LANG_TYPE_CLASS_CHECK (BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK (NODE)) \ + ->template_info) + +/* Template information for an ENUMERAL_, RECORD_, UNION_TYPE, or + BOUND_TEMPLATE_TEMPLATE_PARM type. Note that if NODE is a + specialization of an alias template, this accessor returns the + template info for the alias template, not the one (if any) for the + template of the underlying type. */ +#define TYPE_TEMPLATE_INFO(NODE) \ + ((TYPE_ALIAS_P (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE))) \ + ? (DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \ + ? DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) \ + : NULL_TREE) \ + : ((TREE_CODE (NODE) == ENUMERAL_TYPE) \ + ? ENUM_TEMPLATE_INFO (NODE) \ + : ((TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM) \ + ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \ + : (CLASS_TYPE_P (NODE) \ + ? CLASSTYPE_TEMPLATE_INFO (NODE) \ + : NULL_TREE)))) + + +/* Set the template information for an ENUMERAL_, RECORD_, or + UNION_TYPE to VAL. */ +#define SET_TYPE_TEMPLATE_INFO(NODE, VAL) \ + (TREE_CODE (NODE) == ENUMERAL_TYPE \ + ? (ENUM_TEMPLATE_INFO (NODE) = (VAL)) \ + : ((CLASS_TYPE_P (NODE) && !TYPE_ALIAS_P (NODE)) \ + ? (CLASSTYPE_TEMPLATE_INFO (NODE) = (VAL)) \ + : (DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) = (VAL)))) + +#define TI_TEMPLATE(NODE) TREE_TYPE (TEMPLATE_INFO_CHECK (NODE)) +#define TI_ARGS(NODE) TREE_CHAIN (TEMPLATE_INFO_CHECK (NODE)) +#define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE) +/* For a given TREE_VEC containing a template argument list, + this property contains the number of arguments that are not + defaulted. */ +#define NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) TREE_CHAIN (TREE_VEC_CHECK (NODE)) +/* Below are the setter and getter of the NON_DEFAULT_TEMPLATE_ARGS_COUNT + property. */ +#define SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE, INT_VALUE) \ + NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) = build_int_cst (NULL_TREE, INT_VALUE) +#ifdef ENABLE_CHECKING +#define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \ + int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE)) +#else +#define GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT(NODE) \ + NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE) \ + ? int_cst_value (NON_DEFAULT_TEMPLATE_ARGS_COUNT (NODE)) \ + : TREE_VEC_LENGTH (INNERMOST_TEMPLATE_ARGS (NODE)) +#endif +/* The list of typedefs - used in the template - that need + access checking at template instantiation time. */ +#define TI_TYPEDEFS_NEEDING_ACCESS_CHECKING(NODE) \ + ((struct tree_template_info*)TEMPLATE_INFO_CHECK \ + (NODE))->typedefs_needing_access_checking + +/* We use TREE_VECs to hold template arguments. If there is only one + level of template arguments, then the TREE_VEC contains the + arguments directly. If there is more than one level of template + arguments, then each entry in the TREE_VEC is itself a TREE_VEC, + containing the template arguments for a single level. The first + entry in the outer TREE_VEC is the outermost level of template + parameters; the last is the innermost. + + It is incorrect to ever form a template argument vector containing + only one level of arguments, but which is a TREE_VEC containing as + its only entry the TREE_VEC for that level. + + For each TREE_VEC containing the template arguments for a single + level, it's possible to get or set the number of non defaulted + template arguments by using the accessor macros + GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT or + SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT. */ + +/* Nonzero if the template arguments is actually a vector of vectors, + rather than just a vector. */ +#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \ + (NODE && TREE_VEC_LENGTH (NODE) && TREE_VEC_ELT (NODE, 0) \ + && TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC) + +/* The depth of a template argument vector. When called directly by + the parser, we use a TREE_LIST rather than a TREE_VEC to represent + template arguments. In fact, we may even see NULL_TREE if there + are no template arguments. In both of those cases, there is only + one level of template arguments. */ +#define TMPL_ARGS_DEPTH(NODE) \ + (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (NODE) ? TREE_VEC_LENGTH (NODE) : 1) + +/* The LEVELth level of the template ARGS. The outermost level of + args is level 1, not level 0. */ +#define TMPL_ARGS_LEVEL(ARGS, LEVEL) \ + (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (ARGS) \ + ? TREE_VEC_ELT (ARGS, (LEVEL) - 1) : (ARGS)) + +/* Set the LEVELth level of the template ARGS to VAL. This macro does + not work with single-level argument vectors. */ +#define SET_TMPL_ARGS_LEVEL(ARGS, LEVEL, VAL) \ + (TREE_VEC_ELT (ARGS, (LEVEL) - 1) = (VAL)) + +/* Accesses the IDXth parameter in the LEVELth level of the ARGS. */ +#define TMPL_ARG(ARGS, LEVEL, IDX) \ + (TREE_VEC_ELT (TMPL_ARGS_LEVEL (ARGS, LEVEL), IDX)) + +/* Given a single level of template arguments in NODE, return the + number of arguments. */ +#define NUM_TMPL_ARGS(NODE) \ + (TREE_VEC_LENGTH (NODE)) + +/* Returns the innermost level of template arguments in ARGS. */ +#define INNERMOST_TEMPLATE_ARGS(NODE) \ + (get_innermost_template_args ((NODE), 1)) + +/* The number of levels of template parameters given by NODE. */ +#define TMPL_PARMS_DEPTH(NODE) \ + ((HOST_WIDE_INT) TREE_INT_CST_LOW (TREE_PURPOSE (NODE))) + +/* The TEMPLATE_DECL instantiated or specialized by NODE. This + TEMPLATE_DECL will be the immediate parent, not the most general + template. For example, in: + + template struct S { template void f(U); } + + the FUNCTION_DECL for S::f will have, as its + DECL_TI_TEMPLATE, `template S::f'. + + As a special case, for a member friend template of a template + class, this value will not be a TEMPLATE_DECL, but rather an + IDENTIFIER_NODE or OVERLOAD indicating the name of the template and + any explicit template arguments provided. For example, in: + + template struct S { friend void f(int, double); } + + the DECL_TI_TEMPLATE will be an IDENTIFIER_NODE for `f' and the + DECL_TI_ARGS will be {int}. + + For a FIELD_DECL with a non-static data member initializer, this value + is the FIELD_DECL it was instantiated from. */ +#define DECL_TI_TEMPLATE(NODE) TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE)) + +/* The template arguments used to obtain this decl from the most + general form of DECL_TI_TEMPLATE. For the example given for + DECL_TI_TEMPLATE, the DECL_TI_ARGS will be {int, double}. These + are always the full set of arguments required to instantiate this + declaration from the most general template specialized here. */ +#define DECL_TI_ARGS(NODE) TI_ARGS (DECL_TEMPLATE_INFO (NODE)) + +/* The TEMPLATE_DECL associated with NODE, a class type. Even if NODE + will be generated from a partial specialization, the TEMPLATE_DECL + referred to here will be the original template. For example, + given: + + template struct S {}; + template struct S {}; + + the CLASSTPYE_TI_TEMPLATE for S will be S, not the S. */ +#define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO (NODE)) +#define CLASSTYPE_TI_ARGS(NODE) TI_ARGS (CLASSTYPE_TEMPLATE_INFO (NODE)) + +/* For a template instantiation TYPE, returns the TYPE corresponding + to the primary template. Otherwise returns TYPE itself. */ +#define CLASSTYPE_PRIMARY_TEMPLATE_TYPE(TYPE) \ + ((CLASSTYPE_USE_TEMPLATE ((TYPE)) \ + && !CLASSTYPE_TEMPLATE_SPECIALIZATION ((TYPE))) \ + ? TREE_TYPE (DECL_TEMPLATE_RESULT (DECL_PRIMARY_TEMPLATE \ + (CLASSTYPE_TI_TEMPLATE ((TYPE))))) \ + : (TYPE)) + +/* Like CLASS_TI_TEMPLATE, but also works for ENUMERAL_TYPEs. */ +#define TYPE_TI_TEMPLATE(NODE) \ + (TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE))) + +/* Like DECL_TI_ARGS, but for an ENUMERAL_, RECORD_, or UNION_TYPE. */ +#define TYPE_TI_ARGS(NODE) \ + (TI_ARGS (TYPE_TEMPLATE_INFO (NODE))) + +#define INNERMOST_TEMPLATE_PARMS(NODE) TREE_VALUE (NODE) + +/* Nonzero if NODE (a TEMPLATE_DECL) is a member template, in the + sense of [temp.mem]. */ +#define DECL_MEMBER_TEMPLATE_P(NODE) \ + (DECL_LANG_FLAG_1 (TEMPLATE_DECL_CHECK (NODE))) + +/* Nonzero if the NODE corresponds to the template parameters for a + member template, whose inline definition is being processed after + the class definition is complete. */ +#define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE) + +/* Determine if a parameter (i.e., a PARM_DECL) is a function + parameter pack. */ +#define FUNCTION_PARAMETER_PACK_P(NODE) \ + (DECL_LANG_FLAG_1 (PARM_DECL_CHECK (NODE))) + +/* Determines if NODE is an expansion of one or more parameter packs, + e.g., a TYPE_PACK_EXPANSION or EXPR_PACK_EXPANSION. */ +#define PACK_EXPANSION_P(NODE) \ + (TREE_CODE (NODE) == TYPE_PACK_EXPANSION \ + || TREE_CODE (NODE) == EXPR_PACK_EXPANSION) + +/* Extracts the type or expression pattern from a TYPE_PACK_EXPANSION or + EXPR_PACK_EXPANSION. */ +#define PACK_EXPANSION_PATTERN(NODE) \ + (TREE_CODE (NODE) == TYPE_PACK_EXPANSION? TREE_TYPE (NODE) \ + : TREE_OPERAND (NODE, 0)) + +/* Sets the type or expression pattern for a TYPE_PACK_EXPANSION or + EXPR_PACK_EXPANSION. */ +#define SET_PACK_EXPANSION_PATTERN(NODE,VALUE) \ + if (TREE_CODE (NODE) == TYPE_PACK_EXPANSION) \ + TREE_TYPE (NODE) = VALUE; \ + else \ + TREE_OPERAND (NODE, 0) = VALUE + +/* The list of parameter packs used in the PACK_EXPANSION_* node. The + TREE_VALUE of each TREE_LIST contains the parameter packs. */ +#define PACK_EXPANSION_PARAMETER_PACKS(NODE) \ + *(TREE_CODE (NODE) == EXPR_PACK_EXPANSION \ + ? &TREE_OPERAND (NODE, 1) \ + : &TYPE_MINVAL (TYPE_PACK_EXPANSION_CHECK (NODE))) + +/* Any additional template args to be applied when substituting into + the pattern, set by tsubst_pack_expansion for partial instantiations. */ +#define PACK_EXPANSION_EXTRA_ARGS(NODE) \ + *(TREE_CODE (NODE) == TYPE_PACK_EXPANSION \ + ? &TYPE_MAXVAL (NODE) \ + : &TREE_OPERAND ((NODE), 2)) + +/* True iff this pack expansion is within a function context. */ +#define PACK_EXPANSION_LOCAL_P(NODE) TREE_LANG_FLAG_0 (NODE) + +/* Determine if this is an argument pack. */ +#define ARGUMENT_PACK_P(NODE) \ + (TREE_CODE (NODE) == TYPE_ARGUMENT_PACK \ + || TREE_CODE (NODE) == NONTYPE_ARGUMENT_PACK) + +/* The arguments stored in an argument pack. Arguments are stored in a + TREE_VEC, which may have length zero. */ +#define ARGUMENT_PACK_ARGS(NODE) \ + (TREE_CODE (NODE) == TYPE_ARGUMENT_PACK? TREE_TYPE (NODE) \ + : TREE_OPERAND (NODE, 0)) + +/* Set the arguments stored in an argument pack. VALUE must be a + TREE_VEC. */ +#define SET_ARGUMENT_PACK_ARGS(NODE,VALUE) \ + if (TREE_CODE (NODE) == TYPE_ARGUMENT_PACK) \ + TREE_TYPE (NODE) = VALUE; \ + else \ + TREE_OPERAND (NODE, 0) = VALUE + +/* Whether the argument pack is "incomplete", meaning that more + arguments can still be deduced. Incomplete argument packs are only + used when the user has provided an explicit template argument list + for a variadic function template. Some of the explicit template + arguments will be placed into the beginning of the argument pack, + but additional arguments might still be deduced. */ +#define ARGUMENT_PACK_INCOMPLETE_P(NODE) \ + TREE_ADDRESSABLE (ARGUMENT_PACK_ARGS (NODE)) + +/* When ARGUMENT_PACK_INCOMPLETE_P, stores the explicit template + arguments used to fill this pack. */ +#define ARGUMENT_PACK_EXPLICIT_ARGS(NODE) \ + TREE_TYPE (ARGUMENT_PACK_ARGS (NODE)) + +/* In an ARGUMENT_PACK_SELECT, the argument pack from which an + argument will be selected. */ +#define ARGUMENT_PACK_SELECT_FROM_PACK(NODE) \ + (((struct tree_argument_pack_select *)ARGUMENT_PACK_SELECT_CHECK (NODE))->argument_pack) + +/* In an ARGUMENT_PACK_SELECT, the index of the argument we want to + select. */ +#define ARGUMENT_PACK_SELECT_INDEX(NODE) \ + (((struct tree_argument_pack_select *)ARGUMENT_PACK_SELECT_CHECK (NODE))->index) + +/* In an ARGUMENT_PACK_SELECT, the actual underlying argument that the + ARGUMENT_PACK_SELECT represents. */ +#define ARGUMENT_PACK_SELECT_ARG(NODE) \ + TREE_VEC_ELT (ARGUMENT_PACK_ARGS (ARGUMENT_PACK_SELECT_FROM_PACK (NODE)), \ + ARGUMENT_PACK_SELECT_INDEX (NODE)); + +/* In a FUNCTION_DECL, the saved language-specific per-function data. */ +#define DECL_SAVED_FUNCTION_DATA(NODE) \ + (LANG_DECL_FN_CHECK (FUNCTION_DECL_CHECK (NODE)) \ + ->u.saved_language_function) + +/* True if NODE is an implicit INDIRECT_EXPR from convert_from_reference. */ +#define REFERENCE_REF_P(NODE) \ + (TREE_CODE (NODE) == INDIRECT_REF \ + && TREE_TYPE (TREE_OPERAND (NODE, 0)) \ + && (TREE_CODE (TREE_TYPE (TREE_OPERAND ((NODE), 0))) \ + == REFERENCE_TYPE)) + +#define NEW_EXPR_USE_GLOBAL(NODE) \ + TREE_LANG_FLAG_0 (NEW_EXPR_CHECK (NODE)) +#define DELETE_EXPR_USE_GLOBAL(NODE) \ + TREE_LANG_FLAG_0 (DELETE_EXPR_CHECK (NODE)) +#define DELETE_EXPR_USE_VEC(NODE) \ + TREE_LANG_FLAG_1 (DELETE_EXPR_CHECK (NODE)) + +/* Indicates that this is a non-dependent COMPOUND_EXPR which will + resolve to a function call. */ +#define COMPOUND_EXPR_OVERLOADED(NODE) \ + TREE_LANG_FLAG_0 (COMPOUND_EXPR_CHECK (NODE)) + +/* In a CALL_EXPR appearing in a template, true if Koenig lookup + should be performed at instantiation time. */ +#define KOENIG_LOOKUP_P(NODE) TREE_LANG_FLAG_0 (CALL_EXPR_CHECK (NODE)) + +/* Indicates whether a string literal has been parenthesized. Such + usages are disallowed in certain circumstances. */ + +#define PAREN_STRING_LITERAL_P(NODE) \ + TREE_LANG_FLAG_0 (STRING_CST_CHECK (NODE)) + +/* Nonzero if this AGGR_INIT_EXPR provides for initialization via a + constructor call, rather than an ordinary function call. */ +#define AGGR_INIT_VIA_CTOR_P(NODE) \ + TREE_LANG_FLAG_0 (AGGR_INIT_EXPR_CHECK (NODE)) + +/* Nonzero if expanding this AGGR_INIT_EXPR should first zero-initialize + the object. */ +#define AGGR_INIT_ZERO_FIRST(NODE) \ + TREE_LANG_FLAG_2 (AGGR_INIT_EXPR_CHECK (NODE)) + +/* AGGR_INIT_EXPR accessors. These are equivalent to the CALL_EXPR + accessors, except for AGGR_INIT_EXPR_SLOT (which takes the place of + CALL_EXPR_STATIC_CHAIN). */ + +#define AGGR_INIT_EXPR_FN(NODE) TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 1) +#define AGGR_INIT_EXPR_SLOT(NODE) \ + TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 2) +#define AGGR_INIT_EXPR_ARG(NODE, I) \ + TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), (I) + 3) +#define aggr_init_expr_nargs(NODE) (VL_EXP_OPERAND_LENGTH(NODE) - 3) + +/* AGGR_INIT_EXPR_ARGP returns a pointer to the argument vector for NODE. + We can't use &AGGR_INIT_EXPR_ARG (NODE, 0) because that will complain if + the argument count is zero when checking is enabled. Instead, do + the pointer arithmetic to advance past the 3 fixed operands in a + AGGR_INIT_EXPR. That produces a valid pointer to just past the end of + the operand array, even if it's not valid to dereference it. */ +#define AGGR_INIT_EXPR_ARGP(NODE) \ + (&(TREE_OPERAND (AGGR_INIT_EXPR_CHECK (NODE), 0)) + 3) + +/* Abstract iterators for AGGR_INIT_EXPRs. */ + +/* Structure containing iterator state. */ +typedef struct aggr_init_expr_arg_iterator_d { + tree t; /* the aggr_init_expr */ + int n; /* argument count */ + int i; /* next argument index */ +} aggr_init_expr_arg_iterator; + +/* Initialize the abstract argument list iterator object ITER with the + arguments from AGGR_INIT_EXPR node EXP. */ +static inline void +init_aggr_init_expr_arg_iterator (tree exp, + aggr_init_expr_arg_iterator *iter) +{ + iter->t = exp; + iter->n = aggr_init_expr_nargs (exp); + iter->i = 0; +} + +/* Return the next argument from abstract argument list iterator object ITER, + and advance its state. Return NULL_TREE if there are no more arguments. */ +static inline tree +next_aggr_init_expr_arg (aggr_init_expr_arg_iterator *iter) +{ + tree result; + if (iter->i >= iter->n) + return NULL_TREE; + result = AGGR_INIT_EXPR_ARG (iter->t, iter->i); + iter->i++; + return result; +} + +/* Initialize the abstract argument list iterator object ITER, then advance + past and return the first argument. Useful in for expressions, e.g. + for (arg = first_aggr_init_expr_arg (exp, &iter); arg; + arg = next_aggr_init_expr_arg (&iter)) */ +static inline tree +first_aggr_init_expr_arg (tree exp, aggr_init_expr_arg_iterator *iter) +{ + init_aggr_init_expr_arg_iterator (exp, iter); + return next_aggr_init_expr_arg (iter); +} + +/* Test whether there are more arguments in abstract argument list iterator + ITER, without changing its state. */ +static inline bool +more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) +{ + return (iter->i < iter->n); +} + +/* Iterate through each argument ARG of AGGR_INIT_EXPR CALL, using variable + ITER (of type aggr_init_expr_arg_iterator) to hold the iteration state. */ +#define FOR_EACH_AGGR_INIT_EXPR_ARG(arg, iter, call) \ + for ((arg) = first_aggr_init_expr_arg ((call), &(iter)); (arg); \ + (arg) = next_aggr_init_expr_arg (&(iter))) + +/* VEC_INIT_EXPR accessors. */ +#define VEC_INIT_EXPR_SLOT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 0) +#define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 1) + +/* Indicates that a VEC_INIT_EXPR is a potential constant expression. + Only set when the current function is constexpr. */ +#define VEC_INIT_EXPR_IS_CONSTEXPR(NODE) \ + TREE_LANG_FLAG_0 (VEC_INIT_EXPR_CHECK (NODE)) + +/* Indicates that a VEC_INIT_EXPR is expressing value-initialization. */ +#define VEC_INIT_EXPR_VALUE_INIT(NODE) \ + TREE_LANG_FLAG_1 (VEC_INIT_EXPR_CHECK (NODE)) + +/* The condition under which this MUST_NOT_THROW_EXPR actually blocks + exceptions. NULL_TREE means 'true'. */ +#define MUST_NOT_THROW_COND(NODE) \ + TREE_OPERAND (MUST_NOT_THROW_EXPR_CHECK (NODE), 1) + +/* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a + TEMPLATE_DECL. This macro determines whether or not a given class + type is really a template type, as opposed to an instantiation or + specialization of one. */ +#define CLASSTYPE_IS_TEMPLATE(NODE) \ + (CLASSTYPE_TEMPLATE_INFO (NODE) \ + && !CLASSTYPE_USE_TEMPLATE (NODE) \ + && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))) + +/* The name used by the user to name the typename type. Typically, + this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the + corresponding TYPE_DECL. However, this may also be a + TEMPLATE_ID_EXPR if we had something like `typename X::Y'. */ +#define TYPENAME_TYPE_FULLNAME(NODE) \ + (TYPE_VALUES_RAW (TYPENAME_TYPE_CHECK (NODE))) + +/* True if a TYPENAME_TYPE was declared as an "enum". */ +#define TYPENAME_IS_ENUM_P(NODE) \ + (TREE_LANG_FLAG_0 (TYPENAME_TYPE_CHECK (NODE))) + +/* True if a TYPENAME_TYPE was declared as a "class", "struct", or + "union". */ +#define TYPENAME_IS_CLASS_P(NODE) \ + (TREE_LANG_FLAG_1 (TYPENAME_TYPE_CHECK (NODE))) + +/* True if a TYPENAME_TYPE is in the process of being resolved. */ +#define TYPENAME_IS_RESOLVING_P(NODE) \ + (TREE_LANG_FLAG_2 (TYPENAME_TYPE_CHECK (NODE))) + +/* [class.virtual] + + A class that declares or inherits a virtual function is called a + polymorphic class. */ +#define TYPE_POLYMORPHIC_P(NODE) (TREE_LANG_FLAG_2 (NODE)) + +/* Nonzero if this class has a virtual function table pointer. */ +#define TYPE_CONTAINS_VPTR_P(NODE) \ + (TYPE_POLYMORPHIC_P (NODE) || CLASSTYPE_VBASECLASSES (NODE)) + +/* This flag is true of a local VAR_DECL if it was declared in a for + statement, but we are no longer in the scope of the for. */ +#define DECL_DEAD_FOR_LOCAL(NODE) DECL_LANG_FLAG_7 (VAR_DECL_CHECK (NODE)) + +/* This flag is set on a VAR_DECL that is a DECL_DEAD_FOR_LOCAL + if we already emitted a warning about using it. */ +#define DECL_ERROR_REPORTED(NODE) DECL_LANG_FLAG_0 (VAR_DECL_CHECK (NODE)) + +/* Nonzero if NODE is a FUNCTION_DECL (for a function with global + scope) declared in a local scope. */ +#define DECL_LOCAL_FUNCTION_P(NODE) \ + DECL_LANG_FLAG_0 (FUNCTION_DECL_CHECK (NODE)) + +/* True if NODE was declared with auto in its return type, but it has + started compilation and so the return type might have been changed by + return type deduction; its declared return type should be found in + DECL_STRUCT_FUNCTION(NODE)->language->x_auto_return_pattern. */ +#define FNDECL_USED_AUTO(NODE) \ + TREE_LANG_FLAG_2 (FUNCTION_DECL_CHECK (NODE)) + +/* Nonzero if NODE is a DECL which we know about but which has not + been explicitly declared, such as a built-in function or a friend + declared inside a class. In the latter case DECL_HIDDEN_FRIEND_P + will be set. */ +#define DECL_ANTICIPATED(NODE) \ + (DECL_LANG_SPECIFIC (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK (NODE)) \ + ->u.base.anticipated_p) + +/* Nonzero if NODE is a FUNCTION_DECL which was declared as a friend + within a class but has not been declared in the surrounding scope. + The function is invisible except via argument dependent lookup. */ +#define DECL_HIDDEN_FRIEND_P(NODE) \ + (LANG_DECL_FN_CHECK (DECL_COMMON_CHECK (NODE))->hidden_friend_p) + +/* Nonzero if DECL has been declared threadprivate by + #pragma omp threadprivate. */ +#define CP_DECL_THREADPRIVATE_P(DECL) \ + (DECL_LANG_SPECIFIC (VAR_DECL_CHECK (DECL))->u.base.threadprivate_or_deleted_p) + +/* Nonzero if DECL was declared with '= delete'. */ +#define DECL_DELETED_FN(DECL) \ + (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->u.base.threadprivate_or_deleted_p) + +/* Nonzero if DECL was declared with '= default' (maybe implicitly). */ +#define DECL_DEFAULTED_FN(DECL) \ + (LANG_DECL_FN_CHECK (DECL)->defaulted_p) + +/* Nonzero if DECL is explicitly defaulted in the class body. */ +#define DECL_DEFAULTED_IN_CLASS_P(DECL) \ + (DECL_DEFAULTED_FN (DECL) && DECL_INITIALIZED_IN_CLASS_P (DECL)) +/* Nonzero if DECL was defaulted outside the class body. */ +#define DECL_DEFAULTED_OUTSIDE_CLASS_P(DECL) \ + (DECL_DEFAULTED_FN (DECL) \ + && !(DECL_ARTIFICIAL (DECL) || DECL_INITIALIZED_IN_CLASS_P (DECL))) + +/* Record whether a typedef for type `int' was actually `signed int'. */ +#define C_TYPEDEF_EXPLICITLY_SIGNED(EXP) DECL_LANG_FLAG_1 (EXP) + +/* Returns nonzero if DECL has external linkage, as specified by the + language standard. (This predicate may hold even when the + corresponding entity is not actually given external linkage in the + object file; see decl_linkage for details.) */ +#define DECL_EXTERNAL_LINKAGE_P(DECL) \ + (decl_linkage (DECL) == lk_external) + +/* Keep these codes in ascending code order. */ + +#define INTEGRAL_CODE_P(CODE) \ + ((CODE) == ENUMERAL_TYPE \ + || (CODE) == BOOLEAN_TYPE \ + || (CODE) == INTEGER_TYPE) + +/* [basic.fundamental] + + Types bool, char, wchar_t, and the signed and unsigned integer types + are collectively called integral types. + + Note that INTEGRAL_TYPE_P, as defined in tree.h, allows enumeration + types as well, which is incorrect in C++. Keep these checks in + ascending code order. */ +#define CP_INTEGRAL_TYPE_P(TYPE) \ + (TREE_CODE (TYPE) == BOOLEAN_TYPE \ + || TREE_CODE (TYPE) == INTEGER_TYPE) + +/* Returns true if TYPE is an integral or enumeration name. Keep + these checks in ascending code order. */ +#define INTEGRAL_OR_ENUMERATION_TYPE_P(TYPE) \ + (TREE_CODE (TYPE) == ENUMERAL_TYPE || CP_INTEGRAL_TYPE_P (TYPE)) + +/* Returns true if TYPE is an integral or unscoped enumeration type. */ +#define INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P(TYPE) \ + (UNSCOPED_ENUM_P (TYPE) || CP_INTEGRAL_TYPE_P (TYPE)) + +/* True if the class type TYPE is a literal type. */ +#define CLASSTYPE_LITERAL_P(TYPE) \ + (LANG_TYPE_CLASS_CHECK (TYPE)->is_literal) + +/* [basic.fundamental] + + Integral and floating types are collectively called arithmetic + types. + + As a GNU extension, we also accept complex types. + + Keep these checks in ascending code order. */ +#define ARITHMETIC_TYPE_P(TYPE) \ + (CP_INTEGRAL_TYPE_P (TYPE) \ + || TREE_CODE (TYPE) == REAL_TYPE \ + || TREE_CODE (TYPE) == COMPLEX_TYPE) + +/* True iff TYPE is cv decltype(nullptr). */ +#define NULLPTR_TYPE_P(TYPE) (TREE_CODE (TYPE) == NULLPTR_TYPE) + +/* [basic.types] + + Arithmetic types, enumeration types, pointer types, + pointer-to-member types, and std::nullptr_t are collectively called + scalar types. + + Keep these checks in ascending code order. */ +#define SCALAR_TYPE_P(TYPE) \ + (TYPE_PTRDATAMEM_P (TYPE) \ + || TREE_CODE (TYPE) == ENUMERAL_TYPE \ + || ARITHMETIC_TYPE_P (TYPE) \ + || TYPE_PTR_P (TYPE) \ + || TYPE_PTRMEMFUNC_P (TYPE) \ + || NULLPTR_TYPE_P (TYPE)) + +/* Determines whether this type is a C++0x scoped enumeration + type. Scoped enumerations types are introduced via "enum class" or + "enum struct", e.g., + + enum class Color { + Red, Green, Blue + }; + + Scoped enumeration types are different from normal (unscoped) + enumeration types in several ways: + + - The enumerators of a scoped enumeration type are only available + within the scope of the enumeration type and not in the + enclosing scope. For example, the Red color can be referred to + with "Color::Red" but not "Red". + + - Scoped enumerators and enumerations do not implicitly convert + to integers or 'bool'. + + - The underlying type of the enum is well-defined. */ +#define SCOPED_ENUM_P(TYPE) \ + (TREE_CODE (TYPE) == ENUMERAL_TYPE && ENUM_IS_SCOPED (TYPE)) + +/* Determine whether this is an unscoped enumeration type. */ +#define UNSCOPED_ENUM_P(TYPE) \ + (TREE_CODE (TYPE) == ENUMERAL_TYPE && !ENUM_IS_SCOPED (TYPE)) + +/* Set the flag indicating whether an ENUMERAL_TYPE is a C++0x scoped + enumeration type (1) or a normal (unscoped) enumeration type + (0). */ +#define SET_SCOPED_ENUM_P(TYPE, VAL) \ + (ENUM_IS_SCOPED (TYPE) = (VAL)) + +#define SET_OPAQUE_ENUM_P(TYPE, VAL) \ + (ENUM_IS_OPAQUE (TYPE) = (VAL)) + +#define OPAQUE_ENUM_P(TYPE) \ + (TREE_CODE (TYPE) == ENUMERAL_TYPE && ENUM_IS_OPAQUE (TYPE)) + +/* Determines whether an ENUMERAL_TYPE has an explicit + underlying type. */ +#define ENUM_FIXED_UNDERLYING_TYPE_P(NODE) (TYPE_LANG_FLAG_5 (NODE)) + +/* Returns the underlying type of the given enumeration type. The + underlying type is determined in different ways, depending on the + properties of the enum: + + - In C++0x, the underlying type can be explicitly specified, e.g., + + enum E1 : char { ... } // underlying type is char + + - In a C++0x scoped enumeration, the underlying type is int + unless otherwises specified: + + enum class E2 { ... } // underlying type is int + + - Otherwise, the underlying type is determined based on the + values of the enumerators. In this case, the + ENUM_UNDERLYING_TYPE will not be set until after the definition + of the enumeration is completed by finish_enum. */ +#define ENUM_UNDERLYING_TYPE(TYPE) \ + TREE_TYPE (ENUMERAL_TYPE_CHECK (TYPE)) + +/* [dcl.init.aggr] + + An aggregate is an array or a class with no user-provided + constructors, no brace-or-equal-initializers for non-static data + members, no private or protected non-static data members, no + base classes, and no virtual functions. + + As an extension, we also treat vectors as aggregates. Keep these + checks in ascending code order. */ +#define CP_AGGREGATE_TYPE_P(TYPE) \ + (TREE_CODE (TYPE) == VECTOR_TYPE \ + ||TREE_CODE (TYPE) == ARRAY_TYPE \ + || (CLASS_TYPE_P (TYPE) && !CLASSTYPE_NON_AGGREGATE (TYPE))) + +/* Nonzero for a class type means that the class type has a + user-declared constructor. */ +#define TYPE_HAS_USER_CONSTRUCTOR(NODE) (TYPE_LANG_FLAG_1 (NODE)) + +/* When appearing in an INDIRECT_REF, it means that the tree structure + underneath is actually a call to a constructor. This is needed + when the constructor must initialize local storage (which can + be automatically destroyed), rather than allowing it to allocate + space from the heap. + + When appearing in a SAVE_EXPR, it means that underneath + is a call to a constructor. + + When appearing in a CONSTRUCTOR, the expression is a + compound literal. + + When appearing in a FIELD_DECL, it means that this field + has been duly initialized in its constructor. */ +#define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4 (NODE)) + +/* True if NODE is a brace-enclosed initializer. */ +#define BRACE_ENCLOSED_INITIALIZER_P(NODE) \ + (TREE_CODE (NODE) == CONSTRUCTOR && TREE_TYPE (NODE) == init_list_type_node) + +/* True if NODE is a compound-literal, i.e., a brace-enclosed + initializer cast to a particular type. */ +#define COMPOUND_LITERAL_P(NODE) \ + (TREE_CODE (NODE) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (NODE)) + +#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \ + && vec_safe_is_empty(CONSTRUCTOR_ELTS(NODE))\ + && !TREE_HAS_CONSTRUCTOR (NODE)) + +/* True if NODE is a init-list used as a direct-initializer, i.e. + B b{1,2}, not B b({1,2}) or B b = {1,2}. */ +#define CONSTRUCTOR_IS_DIRECT_INIT(NODE) (TREE_LANG_FLAG_0 (CONSTRUCTOR_CHECK (NODE))) + +/* True if NODE represents a conversion for direct-initialization in a + template. Set by perform_implicit_conversion_flags. */ +#define IMPLICIT_CONV_EXPR_DIRECT_INIT(NODE) \ + (TREE_LANG_FLAG_0 (IMPLICIT_CONV_EXPR_CHECK (NODE))) + +/* Nonzero means that an object of this type can not be initialized using + an initializer list. */ +#define CLASSTYPE_NON_AGGREGATE(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->non_aggregate) +#define TYPE_NON_AGGREGATE_CLASS(NODE) \ + (CLASS_TYPE_P (NODE) && CLASSTYPE_NON_AGGREGATE (NODE)) + +/* Nonzero if there is a non-trivial X::op=(cv X&) for this class. */ +#define TYPE_HAS_COMPLEX_COPY_ASSIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_copy_assign) + +/* Nonzero if there is a non-trivial X::X(cv X&) for this class. */ +#define TYPE_HAS_COMPLEX_COPY_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_copy_ctor) + +/* Nonzero if there is a non-trivial X::op=(X&&) for this class. */ +#define TYPE_HAS_COMPLEX_MOVE_ASSIGN(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_move_assign) + +/* Nonzero if there is a non-trivial X::X(X&&) for this class. */ +#define TYPE_HAS_COMPLEX_MOVE_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_move_ctor) + +/* Nonzero if there is a non-trivial default constructor for this class. */ +#define TYPE_HAS_COMPLEX_DFLT(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_dflt) + +/* Nonzero if TYPE has a trivial destructor. From [class.dtor]: + + A destructor is trivial if it is an implicitly declared + destructor and if: + + - all of the direct base classes of its class have trivial + destructors, + + - for all of the non-static data members of its class that are + of class type (or array thereof), each such class has a + trivial destructor. */ +#define TYPE_HAS_TRIVIAL_DESTRUCTOR(NODE) \ + (!TYPE_HAS_NONTRIVIAL_DESTRUCTOR (NODE)) + +/* Nonzero for _TYPE node means that this type does not have a trivial + destructor. Therefore, destroying an object of this type will + involve a call to a destructor. This can apply to objects of + ARRAY_TYPE is the type of the elements needs a destructor. */ +#define TYPE_HAS_NONTRIVIAL_DESTRUCTOR(NODE) \ + (TYPE_LANG_FLAG_4 (NODE)) + +/* Nonzero for class type means that the default constructor is trivial. */ +#define TYPE_HAS_TRIVIAL_DFLT(NODE) \ + (TYPE_HAS_DEFAULT_CONSTRUCTOR (NODE) && ! TYPE_HAS_COMPLEX_DFLT (NODE)) + +/* Nonzero for class type means that copy initialization of this type can use + a bitwise copy. */ +#define TYPE_HAS_TRIVIAL_COPY_CTOR(NODE) \ + (TYPE_HAS_COPY_CTOR (NODE) && ! TYPE_HAS_COMPLEX_COPY_CTOR (NODE)) + +/* Nonzero for class type means that assignment of this type can use + a bitwise copy. */ +#define TYPE_HAS_TRIVIAL_COPY_ASSIGN(NODE) \ + (TYPE_HAS_COPY_ASSIGN (NODE) && ! TYPE_HAS_COMPLEX_COPY_ASSIGN (NODE)) + +/* Returns true if NODE is a pointer-to-data-member. */ +#define TYPE_PTRDATAMEM_P(NODE) \ + (TREE_CODE (NODE) == OFFSET_TYPE) +/* Returns true if NODE is a pointer. */ +#define TYPE_PTR_P(NODE) \ + (TREE_CODE (NODE) == POINTER_TYPE) + +/* Returns true if NODE is an object type: + + [basic.types] + + An object type is a (possibly cv-qualified) type that is not a + function type, not a reference type, and not a void type. + + Keep these checks in ascending order, for speed. */ +#define TYPE_OBJ_P(NODE) \ + (TREE_CODE (NODE) != REFERENCE_TYPE \ + && TREE_CODE (NODE) != VOID_TYPE \ + && TREE_CODE (NODE) != FUNCTION_TYPE \ + && TREE_CODE (NODE) != METHOD_TYPE) + +/* Returns true if NODE is a pointer to an object. Keep these checks + in ascending tree code order. */ +#define TYPE_PTROB_P(NODE) \ + (TYPE_PTR_P (NODE) && TYPE_OBJ_P (TREE_TYPE (NODE))) + +/* Returns true if NODE is a reference to an object. Keep these checks + in ascending tree code order. */ +#define TYPE_REF_OBJ_P(NODE) \ + (TREE_CODE (NODE) == REFERENCE_TYPE && TYPE_OBJ_P (TREE_TYPE (NODE))) + +/* Returns true if NODE is a pointer to an object, or a pointer to + void. Keep these checks in ascending tree code order. */ +#define TYPE_PTROBV_P(NODE) \ + (TYPE_PTR_P (NODE) \ + && !(TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE \ + || TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE)) + +/* Returns true if NODE is a pointer to function. */ +#define TYPE_PTRFN_P(NODE) \ + (TREE_CODE (NODE) == POINTER_TYPE \ + && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE) + +/* Returns true if NODE is a reference to function. */ +#define TYPE_REFFN_P(NODE) \ + (TREE_CODE (NODE) == REFERENCE_TYPE \ + && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE) + +/* Nonzero for _TYPE node means that this type is a pointer to member + function type. */ +#define TYPE_PTRMEMFUNC_P(NODE) \ + (TREE_CODE (NODE) == RECORD_TYPE \ + && TYPE_LANG_SPECIFIC (NODE) \ + && TYPE_PTRMEMFUNC_FLAG (NODE)) + +#define TYPE_PTRMEMFUNC_FLAG(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->ptrmemfunc_flag) + +/* Returns true if NODE is a pointer-to-member. */ +#define TYPE_PTRMEM_P(NODE) \ + (TYPE_PTRDATAMEM_P (NODE) || TYPE_PTRMEMFUNC_P (NODE)) + +/* Returns true if NODE is a pointer or a pointer-to-member. */ +#define TYPE_PTR_OR_PTRMEM_P(NODE) \ + (TYPE_PTR_P (NODE) || TYPE_PTRMEM_P (NODE)) + +/* Indicates when overload resolution may resolve to a pointer to + member function. [expr.unary.op]/3 */ +#define PTRMEM_OK_P(NODE) \ + TREE_LANG_FLAG_0 (TREE_CHECK3 ((NODE), ADDR_EXPR, OFFSET_REF, SCOPE_REF)) + +/* Get the POINTER_TYPE to the METHOD_TYPE associated with this + pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true, + before using this macro. */ +#define TYPE_PTRMEMFUNC_FN_TYPE(NODE) \ + (TREE_TYPE (TYPE_FIELDS (NODE))) + +/* Returns `A' for a type like `int (A::*)(double)' */ +#define TYPE_PTRMEMFUNC_OBJECT_TYPE(NODE) \ + TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (NODE))) + +/* These are use to manipulate the canonical RECORD_TYPE from the + hashed POINTER_TYPE, and can only be used on the POINTER_TYPE. */ +#define TYPE_GET_PTRMEMFUNC_TYPE(NODE) \ + (TYPE_LANG_SPECIFIC (NODE) ? LANG_TYPE_PTRMEM_CHECK (NODE)->record : NULL) +#define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE) \ + do { \ + if (TYPE_LANG_SPECIFIC (NODE) == NULL) \ + { \ + TYPE_LANG_SPECIFIC (NODE) = ggc_alloc_cleared_lang_type \ + (sizeof (struct lang_type_ptrmem)); \ + TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.h.is_lang_type_class = 0; \ + } \ + TYPE_LANG_SPECIFIC (NODE)->u.ptrmem.record = (VALUE); \ + } while (0) + +/* For a pointer-to-member type of the form `T X::*', this is `X'. + For a type like `void (X::*)() const', this type is `X', not `const + X'. To get at the `const X' you have to look at the + TYPE_PTRMEM_POINTED_TO_TYPE; there, the first parameter will have + type `const X*'. */ +#define TYPE_PTRMEM_CLASS_TYPE(NODE) \ + (TYPE_PTRDATAMEM_P (NODE) \ + ? TYPE_OFFSET_BASETYPE (NODE) \ + : TYPE_PTRMEMFUNC_OBJECT_TYPE (NODE)) + +/* For a pointer-to-member type of the form `T X::*', this is `T'. */ +#define TYPE_PTRMEM_POINTED_TO_TYPE(NODE) \ + (TYPE_PTRDATAMEM_P (NODE) \ + ? TREE_TYPE (NODE) \ + : TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (NODE))) + +/* For a pointer-to-member constant `X::Y' this is the RECORD_TYPE for + `X'. */ +#define PTRMEM_CST_CLASS(NODE) \ + TYPE_PTRMEM_CLASS_TYPE (TREE_TYPE (PTRMEM_CST_CHECK (NODE))) + +/* For a pointer-to-member constant `X::Y' this is the _DECL for + `Y'. */ +#define PTRMEM_CST_MEMBER(NODE) (((ptrmem_cst_t)PTRMEM_CST_CHECK (NODE))->member) + +/* The expression in question for a TYPEOF_TYPE. */ +#define TYPEOF_TYPE_EXPR(NODE) (TYPE_VALUES_RAW (TYPEOF_TYPE_CHECK (NODE))) + +/* The type in question for an UNDERLYING_TYPE. */ +#define UNDERLYING_TYPE_TYPE(NODE) \ + (TYPE_VALUES_RAW (UNDERLYING_TYPE_CHECK (NODE))) + +/* The type in question for BASES. */ +#define BASES_TYPE(NODE) \ + (TYPE_VALUES_RAW (BASES_CHECK (NODE))) + +#define BASES_DIRECT(NODE) \ + TREE_LANG_FLAG_0 (BASES_CHECK (NODE)) + +/* The expression in question for a DECLTYPE_TYPE. */ +#define DECLTYPE_TYPE_EXPR(NODE) (TYPE_VALUES_RAW (DECLTYPE_TYPE_CHECK (NODE))) + +/* Whether the DECLTYPE_TYPE_EXPR of NODE was originally parsed as an + id-expression or a member-access expression. When false, it was + parsed as a full expression. */ +#define DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P(NODE) \ + (DECLTYPE_TYPE_CHECK (NODE))->type_common.string_flag + +/* These flags indicate that we want different semantics from normal + decltype: lambda capture just drops references, lambda proxies look + through implicit dereference. */ +#define DECLTYPE_FOR_LAMBDA_CAPTURE(NODE) \ + TREE_LANG_FLAG_0 (DECLTYPE_TYPE_CHECK (NODE)) +#define DECLTYPE_FOR_LAMBDA_PROXY(NODE) \ + TREE_LANG_FLAG_2 (DECLTYPE_TYPE_CHECK (NODE)) + +/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `extern' was + specified in its declaration. This can also be set for an + erroneously declared PARM_DECL. */ +#define DECL_THIS_EXTERN(NODE) \ + DECL_LANG_FLAG_2 (VAR_FUNCTION_OR_PARM_DECL_CHECK (NODE)) + +/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `static' was + specified in its declaration. This can also be set for an + erroneously declared PARM_DECL. */ +#define DECL_THIS_STATIC(NODE) \ + DECL_LANG_FLAG_6 (VAR_FUNCTION_OR_PARM_DECL_CHECK (NODE)) + +/* Nonzero for FIELD_DECL node means that this field is a base class + of the parent object, as opposed to a member field. */ +#define DECL_FIELD_IS_BASE(NODE) \ + DECL_LANG_FLAG_6 (FIELD_DECL_CHECK (NODE)) + +/* Nonzero for FIELD_DECL node means that this field is a simple (no + explicit initializer) lambda capture field, making it invisible to + name lookup in unevaluated contexts. */ +#define DECL_NORMAL_CAPTURE_P(NODE) \ + DECL_LANG_FLAG_7 (FIELD_DECL_CHECK (NODE)) + +/* Nonzero if TYPE is an anonymous union or struct type. We have to use a + flag for this because "A union for which objects or pointers are + declared is not an anonymous union" [class.union]. */ +#define ANON_AGGR_TYPE_P(NODE) \ + (CLASS_TYPE_P (NODE) && LANG_TYPE_CLASS_CHECK (NODE)->anon_aggr) +#define SET_ANON_AGGR_TYPE_P(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->anon_aggr = 1) + +/* Nonzero if TYPE is an anonymous union type. */ +#define ANON_UNION_TYPE_P(NODE) \ + (TREE_CODE (NODE) == UNION_TYPE && ANON_AGGR_TYPE_P (NODE)) + +/* Define fields and accessors for nodes representing declared names. */ + +#define TYPE_WAS_ANONYMOUS(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->was_anonymous) + +/* C++: all of these are overloaded! These apply only to TYPE_DECLs. */ + +/* The format of each node in the DECL_FRIENDLIST is as follows: + + The TREE_PURPOSE will be the name of a function, i.e., an + IDENTIFIER_NODE. The TREE_VALUE will be itself a TREE_LIST, whose + TREE_VALUEs are friends with the given name. */ +#define DECL_FRIENDLIST(NODE) (DECL_INITIAL (NODE)) +#define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST)) +#define FRIEND_DECLS(LIST) (TREE_VALUE (LIST)) + +/* The DECL_ACCESS, if non-NULL, is a TREE_LIST. The TREE_PURPOSE of + each node is a type; the TREE_VALUE is the access granted for this + DECL in that type. The DECL_ACCESS is set by access declarations. + For example, if a member that would normally be public in a + derived class is made protected, then the derived class and the + protected_access_node will appear in the DECL_ACCESS for the node. */ +#define DECL_ACCESS(NODE) (LANG_DECL_U2_CHECK (NODE, 0)->access) + +/* Nonzero if the FUNCTION_DECL is a global constructor. */ +#define DECL_GLOBAL_CTOR_P(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->global_ctor_p) + +/* Nonzero if the FUNCTION_DECL is a global destructor. */ +#define DECL_GLOBAL_DTOR_P(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->global_dtor_p) + +/* Accessor macros for C++ template decl nodes. */ + +/* The DECL_TEMPLATE_PARMS are a list. The TREE_PURPOSE of each node + is a INT_CST whose TREE_INT_CST_LOW indicates the level of the + template parameters, with 1 being the outermost set of template + parameters. The TREE_VALUE is a vector, whose elements are the + template parameters at each level. Each element in the vector is a + TREE_LIST, whose TREE_VALUE is a PARM_DECL (if the parameter is a + non-type parameter), or a TYPE_DECL (if the parameter is a type + parameter). The TREE_PURPOSE is the default value, if any. The + TEMPLATE_PARM_INDEX for the parameter is available as the + DECL_INITIAL (for a PARM_DECL) or as the TREE_TYPE (for a + TYPE_DECL). */ +#define DECL_TEMPLATE_PARMS(NODE) DECL_NON_COMMON_CHECK (NODE)->decl_non_common.arguments +#define DECL_INNERMOST_TEMPLATE_PARMS(NODE) \ + INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (NODE)) +#define DECL_NTPARMS(NODE) \ + TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (NODE)) +/* For function, method, class-data templates. */ +#define DECL_TEMPLATE_RESULT(NODE) DECL_RESULT_FLD (NODE) +/* For a function template at namespace scope, DECL_TEMPLATE_INSTANTIATIONS + lists all instantiations and specializations of the function so that + tsubst_friend_function can reassign them to another template if we find + that the namespace-scope template is really a partial instantiation of a + friend template. + + For a class template the DECL_TEMPLATE_INSTANTIATIONS lists holds + all instantiations and specializations of the class type, including + partial instantiations and partial specializations, so that if we + explicitly specialize a partial instantiation we can walk the list + in maybe_process_partial_specialization and reassign them or complain + as appropriate. + + In both cases, the TREE_PURPOSE of each node contains the arguments + used; the TREE_VALUE contains the generated variable. The template + arguments are always complete. For example, given: + + template struct S1 { + template struct S2 {}; + template struct S2 {}; + }; + + the record for the partial specialization will contain, as its + argument list, { {T}, {U*} }, and will be on the + DECL_TEMPLATE_INSTANTIATIONS list for `template template + struct S1::S2'. + + This list is not used for other templates. */ +#define DECL_TEMPLATE_INSTANTIATIONS(NODE) DECL_VINDEX (NODE) +/* For a class template, this list contains the partial + specializations of this template. (Full specializations are not + recorded on this list.) The TREE_PURPOSE holds the arguments used + in the partial specialization (e.g., for `template struct + S' this will be `T*'.) The arguments will also include + any outer template arguments. The TREE_VALUE holds the innermost + template parameters for the specialization (e.g., `T' in the + example above.) The TREE_TYPE is the _TYPE node for the partial + specialization. + + This list is not used for other templates. */ +#define DECL_TEMPLATE_SPECIALIZATIONS(NODE) DECL_SIZE (NODE) + +/* Nonzero for a DECL which is actually a template parameter. Keep + these checks in ascending tree code order. */ +#define DECL_TEMPLATE_PARM_P(NODE) \ + (DECL_LANG_FLAG_0 (NODE) \ + && (TREE_CODE (NODE) == CONST_DECL \ + || TREE_CODE (NODE) == PARM_DECL \ + || TREE_CODE (NODE) == TYPE_DECL \ + || TREE_CODE (NODE) == TEMPLATE_DECL)) + +/* Mark NODE as a template parameter. */ +#define SET_DECL_TEMPLATE_PARM_P(NODE) \ + (DECL_LANG_FLAG_0 (NODE) = 1) + +/* Nonzero if NODE is a template template parameter. */ +#define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \ + (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE)) + +/* Nonzero if NODE is a TEMPLATE_DECL representing an + UNBOUND_CLASS_TEMPLATE tree node. */ +#define DECL_UNBOUND_CLASS_TEMPLATE_P(NODE) \ + (TREE_CODE (NODE) == TEMPLATE_DECL && !DECL_TEMPLATE_RESULT (NODE)) + +#define DECL_FUNCTION_TEMPLATE_P(NODE) \ + (TREE_CODE (NODE) == TEMPLATE_DECL \ + && !DECL_UNBOUND_CLASS_TEMPLATE_P (NODE) \ + && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL) + +/* Nonzero for a DECL that represents a class template or alias + template. */ +#define DECL_TYPE_TEMPLATE_P(NODE) \ + (TREE_CODE (NODE) == TEMPLATE_DECL \ + && DECL_TEMPLATE_RESULT (NODE) != NULL_TREE \ + && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == TYPE_DECL) + +/* Nonzero for a DECL that represents a class template. */ +#define DECL_CLASS_TEMPLATE_P(NODE) \ + (DECL_TYPE_TEMPLATE_P (NODE) \ + && DECL_IMPLICIT_TYPEDEF_P (DECL_TEMPLATE_RESULT (NODE))) + +/* Nonzero for a TEMPLATE_DECL that represents an alias template. */ +#define DECL_ALIAS_TEMPLATE_P(NODE) \ + (DECL_TYPE_TEMPLATE_P (NODE) \ + && !DECL_ARTIFICIAL (DECL_TEMPLATE_RESULT (NODE))) + +/* Nonzero for a NODE which declares a type. */ +#define DECL_DECLARES_TYPE_P(NODE) \ + (TREE_CODE (NODE) == TYPE_DECL || DECL_TYPE_TEMPLATE_P (NODE)) + +/* Nonzero if NODE declares a function. */ +#define DECL_DECLARES_FUNCTION_P(NODE) \ + (TREE_CODE (NODE) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (NODE)) + +/* Nonzero if NODE is the typedef implicitly generated for a type when + the type is declared. In C++, `struct S {};' is roughly + equivalent to `struct S {}; typedef struct S S;' in C. + DECL_IMPLICIT_TYPEDEF_P will hold for the typedef indicated in this + example. In C++, there is a second implicit typedef for each + class, in the scope of `S' itself, so that you can say `S::S'. + DECL_SELF_REFERENCE_P will hold for that second typedef. */ +#define DECL_IMPLICIT_TYPEDEF_P(NODE) \ + (TREE_CODE (NODE) == TYPE_DECL && DECL_LANG_FLAG_2 (NODE)) +#define SET_DECL_IMPLICIT_TYPEDEF_P(NODE) \ + (DECL_LANG_FLAG_2 (NODE) = 1) +#define DECL_SELF_REFERENCE_P(NODE) \ + (TREE_CODE (NODE) == TYPE_DECL && DECL_LANG_FLAG_4 (NODE)) +#define SET_DECL_SELF_REFERENCE_P(NODE) \ + (DECL_LANG_FLAG_4 (NODE) = 1) + +/* A `primary' template is one that has its own template header. A + member function of a class template is a template, but not primary. + A member template is primary. Friend templates are primary, too. */ + +/* Returns the primary template corresponding to these parameters. */ +#define DECL_PRIMARY_TEMPLATE(NODE) \ + (TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS (NODE))) + +/* Returns nonzero if NODE is a primary template. */ +#define PRIMARY_TEMPLATE_P(NODE) (DECL_PRIMARY_TEMPLATE (NODE) == (NODE)) + +/* Nonzero iff NODE is a specialization of a template. The value + indicates the type of specializations: + + 1=implicit instantiation + + 2=partial or explicit specialization, e.g.: + + template <> int min (int, int), + + 3=explicit instantiation, e.g.: + + template int min (int, int); + + Note that NODE will be marked as a specialization even if the + template it is instantiating is not a primary template. For + example, given: + + template struct O { + void f(); + struct I {}; + }; + + both O::f and O::I will be marked as instantiations. + + If DECL_USE_TEMPLATE is nonzero, then DECL_TEMPLATE_INFO will also + be non-NULL. */ +#define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC (NODE)->u.base.use_template) + +/* Like DECL_USE_TEMPLATE, but for class types. */ +#define CLASSTYPE_USE_TEMPLATE(NODE) \ + (LANG_TYPE_CLASS_CHECK (NODE)->use_template) + +/* True if NODE is a specialization of a primary template. */ +#define CLASSTYPE_SPECIALIZATION_OF_PRIMARY_TEMPLATE_P(NODE) \ + (CLASS_TYPE_P (NODE) \ + && CLASSTYPE_USE_TEMPLATE (NODE) \ + && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))) + +#define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1) +#define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \ + (CLASSTYPE_USE_TEMPLATE (NODE) & 1) + +#define DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) == 2) +#define SET_DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) = 2) + +/* Returns true for an explicit or partial specialization of a class + template. */ +#define CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \ + (CLASSTYPE_USE_TEMPLATE (NODE) == 2) +#define SET_CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \ + (CLASSTYPE_USE_TEMPLATE (NODE) = 2) + +#define DECL_IMPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) == 1) +#define SET_DECL_IMPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) = 1) +#define CLASSTYPE_IMPLICIT_INSTANTIATION(NODE) \ + (CLASSTYPE_USE_TEMPLATE (NODE) == 1) +#define SET_CLASSTYPE_IMPLICIT_INSTANTIATION(NODE) \ + (CLASSTYPE_USE_TEMPLATE (NODE) = 1) + +#define DECL_EXPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) == 3) +#define SET_DECL_EXPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) = 3) +#define CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \ + (CLASSTYPE_USE_TEMPLATE (NODE) == 3) +#define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \ + (CLASSTYPE_USE_TEMPLATE (NODE) = 3) + +/* Nonzero if DECL is a friend function which is an instantiation + from the point of view of the compiler, but not from the point of + view of the language. For example given: + template struct S { friend void f(T) {}; }; + the declaration of `void f(int)' generated when S is + instantiated will not be a DECL_TEMPLATE_INSTANTIATION, but will be + a DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION. */ +#define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \ + (DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL)) + +/* Nonzero if DECL is a function generated from a function 'temploid', + i.e. template, member of class template, or dependent friend. */ +#define DECL_TEMPLOID_INSTANTIATION(DECL) \ + (DECL_TEMPLATE_INSTANTIATION (DECL) \ + || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (DECL)) + +/* Nonzero if DECL is either defined implicitly by the compiler or + generated from a temploid. */ +#define DECL_GENERATED_P(DECL) \ + (DECL_TEMPLOID_INSTANTIATION (DECL) || DECL_DEFAULTED_FN (DECL)) + +/* Nonzero iff we are currently processing a declaration for an + entity with its own template parameter list, and which is not a + full specialization. */ +#define PROCESSING_REAL_TEMPLATE_DECL_P() \ + (processing_template_decl > template_class_depth (current_scope ())) + +/* Nonzero if this VAR_DECL or FUNCTION_DECL has already been + instantiated, i.e. its definition has been generated from the + pattern given in the template. */ +#define DECL_TEMPLATE_INSTANTIATED(NODE) \ + DECL_LANG_FLAG_1 (VAR_OR_FUNCTION_DECL_CHECK (NODE)) + +/* We know what we're doing with this decl now. */ +#define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE) + +/* DECL_EXTERNAL must be set on a decl until the decl is actually emitted, + so that assemble_external will work properly. So we have this flag to + tell us whether the decl is really not external. + + This flag does not indicate whether or not the decl is defined in the + current translation unit; it indicates whether or not we should emit the + decl at the end of compilation if it is defined and needed. */ +#define DECL_NOT_REALLY_EXTERN(NODE) \ + (DECL_LANG_SPECIFIC (NODE)->u.base.not_really_extern) + +#define DECL_REALLY_EXTERN(NODE) \ + (DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE)) + +/* A thunk is a stub function. + + A thunk is an alternate entry point for an ordinary FUNCTION_DECL. + The address of the ordinary FUNCTION_DECL is given by the + DECL_INITIAL, which is always an ADDR_EXPR whose operand is a + FUNCTION_DECL. The job of the thunk is to either adjust the this + pointer before transferring control to the FUNCTION_DECL, or call + FUNCTION_DECL and then adjust the result value. Note, the result + pointer adjusting thunk must perform a call to the thunked + function, (or be implemented via passing some invisible parameter + to the thunked function, which is modified to perform the + adjustment just before returning). + + A thunk may perform either, or both, of the following operations: + + o Adjust the this or result pointer by a constant offset. + o Adjust the this or result pointer by looking up a vcall or vbase offset + in the vtable. + + A this pointer adjusting thunk converts from a base to a derived + class, and hence adds the offsets. A result pointer adjusting thunk + converts from a derived class to a base, and hence subtracts the + offsets. If both operations are performed, then the constant + adjustment is performed first for this pointer adjustment and last + for the result pointer adjustment. + + The constant adjustment is given by THUNK_FIXED_OFFSET. If the + vcall or vbase offset is required, THUNK_VIRTUAL_OFFSET is + used. For this pointer adjusting thunks, it is the vcall offset + into the vtable. For result pointer adjusting thunks it is the + binfo of the virtual base to convert to. Use that binfo's vbase + offset. + + It is possible to have equivalent covariant thunks. These are + distinct virtual covariant thunks whose vbase offsets happen to + have the same value. THUNK_ALIAS is used to pick one as the + canonical thunk, which will get all the this pointer adjusting + thunks attached to it. */ + +/* An integer indicating how many bytes should be subtracted from the + this or result pointer when this function is called. */ +#define THUNK_FIXED_OFFSET(DECL) \ + (DECL_LANG_SPECIFIC (THUNK_FUNCTION_CHECK (DECL))->u.fn.u5.fixed_offset) + +/* A tree indicating how to perform the virtual adjustment. For a this + adjusting thunk it is the number of bytes to be added to the vtable + to find the vcall offset. For a result adjusting thunk, it is the + binfo of the relevant virtual base. If NULL, then there is no + virtual adjust. (The vptr is always located at offset zero from + the this or result pointer.) (If the covariant type is within the + class hierarchy being laid out, the vbase index is not yet known + at the point we need to create the thunks, hence the need to use + binfos.) */ + +#define THUNK_VIRTUAL_OFFSET(DECL) \ + (LANG_DECL_U2_CHECK (FUNCTION_DECL_CHECK (DECL), 0)->access) + +/* A thunk which is equivalent to another thunk. */ +#define THUNK_ALIAS(DECL) \ + (DECL_LANG_SPECIFIC (FUNCTION_DECL_CHECK (DECL))->u.min.template_info) + +/* For thunk NODE, this is the FUNCTION_DECL thunked to. It is + possible for the target to be a thunk too. */ +#define THUNK_TARGET(NODE) \ + (LANG_DECL_FN_CHECK (NODE)->befriending_classes) + +/* True for a SCOPE_REF iff the "template" keyword was used to + indicate that the qualified name denotes a template. */ +#define QUALIFIED_NAME_IS_TEMPLATE(NODE) \ + (TREE_LANG_FLAG_1 (SCOPE_REF_CHECK (NODE))) + +/* True for an OMP_ATOMIC that has dependent parameters. These are stored + as an expr in operand 1, and integer_zero_node in operand 0. */ +#define OMP_ATOMIC_DEPENDENT_P(NODE) \ + (TREE_CODE (TREE_OPERAND (OMP_ATOMIC_CHECK (NODE), 0)) == INTEGER_CST) + +/* Used while gimplifying continue statements bound to OMP_FOR nodes. */ +#define OMP_FOR_GIMPLIFYING_P(NODE) \ + (TREE_LANG_FLAG_0 (OMP_FOR_CHECK (NODE))) + +/* A language-specific token attached to the OpenMP data clauses to + hold code (or code fragments) related to ctors, dtors, and op=. + See semantics.c for details. */ +#define CP_OMP_CLAUSE_INFO(NODE) \ + TREE_TYPE (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_PRIVATE, \ + OMP_CLAUSE_COPYPRIVATE)) + +/* Nonzero if this transaction expression's body contains statements. */ +#define TRANSACTION_EXPR_IS_STMT(NODE) \ + TREE_LANG_FLAG_0 (TRANSACTION_EXPR_CHECK (NODE)) + +/* These macros provide convenient access to the various _STMT nodes + created when parsing template declarations. */ +#define TRY_STMTS(NODE) TREE_OPERAND (TRY_BLOCK_CHECK (NODE), 0) +#define TRY_HANDLERS(NODE) TREE_OPERAND (TRY_BLOCK_CHECK (NODE), 1) + +#define EH_SPEC_STMTS(NODE) TREE_OPERAND (EH_SPEC_BLOCK_CHECK (NODE), 0) +#define EH_SPEC_RAISES(NODE) TREE_OPERAND (EH_SPEC_BLOCK_CHECK (NODE), 1) + +#define USING_STMT_NAMESPACE(NODE) TREE_OPERAND (USING_STMT_CHECK (NODE), 0) + +/* Nonzero if this try block is a function try block. */ +#define FN_TRY_BLOCK_P(NODE) TREE_LANG_FLAG_3 (TRY_BLOCK_CHECK (NODE)) +#define HANDLER_PARMS(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 0) +#define HANDLER_BODY(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 1) +#define HANDLER_TYPE(NODE) TREE_TYPE (HANDLER_CHECK (NODE)) + +/* CLEANUP_STMT accessors. The statement(s) covered, the cleanup to run + and the VAR_DECL for which this cleanup exists. */ +#define CLEANUP_BODY(NODE) TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 0) +#define CLEANUP_EXPR(NODE) TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 1) +#define CLEANUP_DECL(NODE) TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 2) + +/* IF_STMT accessors. These give access to the condition of the if + statement, the then block of the if statement, and the else block + of the if statement if it exists. */ +#define IF_COND(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 0) +#define THEN_CLAUSE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 1) +#define ELSE_CLAUSE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 2) +#define IF_SCOPE(NODE) TREE_OPERAND (IF_STMT_CHECK (NODE), 3) + +/* WHILE_STMT accessors. These give access to the condition of the + while statement and the body of the while statement, respectively. */ +#define WHILE_COND(NODE) TREE_OPERAND (WHILE_STMT_CHECK (NODE), 0) +#define WHILE_BODY(NODE) TREE_OPERAND (WHILE_STMT_CHECK (NODE), 1) + +/* DO_STMT accessors. These give access to the condition of the do + statement and the body of the do statement, respectively. */ +#define DO_COND(NODE) TREE_OPERAND (DO_STMT_CHECK (NODE), 0) +#define DO_BODY(NODE) TREE_OPERAND (DO_STMT_CHECK (NODE), 1) + +/* FOR_STMT accessors. These give access to the init statement, + condition, update expression, and body of the for statement, + respectively. */ +#define FOR_INIT_STMT(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 0) +#define FOR_COND(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 1) +#define FOR_EXPR(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 2) +#define FOR_BODY(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 3) +#define FOR_SCOPE(NODE) TREE_OPERAND (FOR_STMT_CHECK (NODE), 4) + +/* RANGE_FOR_STMT accessors. These give access to the declarator, + expression, body, and scope of the statement, respectively. */ +#define RANGE_FOR_DECL(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 0) +#define RANGE_FOR_EXPR(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 1) +#define RANGE_FOR_BODY(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 2) +#define RANGE_FOR_SCOPE(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 3) + +#define SWITCH_STMT_COND(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 0) +#define SWITCH_STMT_BODY(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 1) +#define SWITCH_STMT_TYPE(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 2) +#define SWITCH_STMT_SCOPE(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 3) + +/* STMT_EXPR accessor. */ +#define STMT_EXPR_STMT(NODE) TREE_OPERAND (STMT_EXPR_CHECK (NODE), 0) + +/* EXPR_STMT accessor. This gives the expression associated with an + expression statement. */ +#define EXPR_STMT_EXPR(NODE) TREE_OPERAND (EXPR_STMT_CHECK (NODE), 0) + +/* True if this TARGET_EXPR was created by build_cplus_new, and so we can + discard it if it isn't useful. */ +#define TARGET_EXPR_IMPLICIT_P(NODE) \ + TREE_LANG_FLAG_0 (TARGET_EXPR_CHECK (NODE)) + +/* True if this TARGET_EXPR is the result of list-initialization of a + temporary. */ +#define TARGET_EXPR_LIST_INIT_P(NODE) \ + TREE_LANG_FLAG_1 (TARGET_EXPR_CHECK (NODE)) + +/* True if this TARGET_EXPR expresses direct-initialization of an object + to be named later. */ +#define TARGET_EXPR_DIRECT_INIT_P(NODE) \ + TREE_LANG_FLAG_2 (TARGET_EXPR_CHECK (NODE)) + +/* True if EXPR expresses direct-initialization of a TYPE. */ +#define DIRECT_INIT_EXPR_P(TYPE,EXPR) \ + (TREE_CODE (EXPR) == TARGET_EXPR && TREE_LANG_FLAG_2 (EXPR) \ + && same_type_ignoring_top_level_qualifiers_p (TYPE, TREE_TYPE (EXPR))) + +/* True if this CONVERT_EXPR is for a conversion to virtual base in + an NSDMI, and should be re-evaluated when used in a constructor. */ +#define CONVERT_EXPR_VBASE_PATH(NODE) \ + TREE_LANG_FLAG_0 (CONVERT_EXPR_CHECK (NODE)) + +/* True if SIZEOF_EXPR argument is type. */ +#define SIZEOF_EXPR_TYPE_P(NODE) \ + TREE_LANG_FLAG_0 (SIZEOF_EXPR_CHECK (NODE)) + +/* An enumeration of the kind of tags that C++ accepts. */ +enum tag_types { + none_type = 0, /* Not a tag type. */ + record_type, /* "struct" types. */ + class_type, /* "class" types. */ + union_type, /* "union" types. */ + enum_type, /* "enum" types. */ + typename_type /* "typename" types. */ +}; + +/* The various kinds of lvalues we distinguish. */ +enum cp_lvalue_kind_flags { + clk_none = 0, /* Things that are not an lvalue. */ + clk_ordinary = 1, /* An ordinary lvalue. */ + clk_rvalueref = 2,/* An xvalue (rvalue formed using an rvalue reference) */ + clk_class = 4, /* A prvalue of class-type. */ + clk_bitfield = 8, /* An lvalue for a bit-field. */ + clk_packed = 16 /* An lvalue for a packed field. */ +}; + +/* This type is used for parameters and variables which hold + combinations of the flags in enum cp_lvalue_kind_flags. */ +typedef int cp_lvalue_kind; + +/* Various kinds of template specialization, instantiation, etc. */ +typedef enum tmpl_spec_kind { + tsk_none, /* Not a template at all. */ + tsk_invalid_member_spec, /* An explicit member template + specialization, but the enclosing + classes have not all been explicitly + specialized. */ + tsk_invalid_expl_inst, /* An explicit instantiation containing + template parameter lists. */ + tsk_excessive_parms, /* A template declaration with too many + template parameter lists. */ + tsk_insufficient_parms, /* A template declaration with too few + parameter lists. */ + tsk_template, /* A template declaration. */ + tsk_expl_spec, /* An explicit specialization. */ + tsk_expl_inst /* An explicit instantiation. */ +} tmpl_spec_kind; + +/* The various kinds of access. BINFO_ACCESS depends on these being + two bit quantities. The numerical values are important; they are + used to initialize RTTI data structures, so changing them changes + the ABI. */ +typedef enum access_kind { + ak_none = 0, /* Inaccessible. */ + ak_public = 1, /* Accessible, as a `public' thing. */ + ak_protected = 2, /* Accessible, as a `protected' thing. */ + ak_private = 3 /* Accessible, as a `private' thing. */ +} access_kind; + +/* The various kinds of special functions. If you add to this list, + you should update special_function_p as well. */ +typedef enum special_function_kind { + sfk_none = 0, /* Not a special function. This enumeral + must have value zero; see + special_function_p. */ + sfk_constructor, /* A constructor. */ + sfk_copy_constructor, /* A copy constructor. */ + sfk_move_constructor, /* A move constructor. */ + sfk_copy_assignment, /* A copy assignment operator. */ + sfk_move_assignment, /* A move assignment operator. */ + sfk_destructor, /* A destructor. */ + sfk_complete_destructor, /* A destructor for complete objects. */ + sfk_base_destructor, /* A destructor for base subobjects. */ + sfk_deleting_destructor, /* A destructor for complete objects that + deletes the object after it has been + destroyed. */ + sfk_conversion, /* A conversion operator. */ + sfk_inheriting_constructor /* An inheriting constructor */ +} special_function_kind; + +/* The various kinds of linkage. From [basic.link], + + A name is said to have linkage when it might denote the same + object, reference, function, type, template, namespace or value + as a name introduced in another scope: + + -- When a name has external linkage, the entity it denotes can + be referred to from scopes of other translation units or from + other scopes of the same translation unit. + + -- When a name has internal linkage, the entity it denotes can + be referred to by names from other scopes in the same + translation unit. + + -- When a name has no linkage, the entity it denotes cannot be + referred to by names from other scopes. */ + +typedef enum linkage_kind { + lk_none, /* No linkage. */ + lk_internal, /* Internal linkage. */ + lk_external /* External linkage. */ +} linkage_kind; + +typedef enum duration_kind { + dk_static, + dk_thread, + dk_auto, + dk_dynamic +} duration_kind; + +/* Bitmask flags to control type substitution. */ +enum tsubst_flags { + tf_none = 0, /* nothing special */ + tf_error = 1 << 0, /* give error messages */ + tf_warning = 1 << 1, /* give warnings too */ + tf_ignore_bad_quals = 1 << 2, /* ignore bad cvr qualifiers */ + tf_keep_type_decl = 1 << 3, /* retain typedef type decls + (make_typename_type use) */ + tf_ptrmem_ok = 1 << 4, /* pointers to member ok (internal + instantiate_type use) */ + tf_user = 1 << 5, /* found template must be a user template + (lookup_template_class use) */ + tf_conv = 1 << 6, /* We are determining what kind of + conversion might be permissible, + not actually performing the + conversion. */ + tf_decltype = 1 << 7, /* We are the operand of decltype. + Used to implement the special rules + for calls in decltype (5.2.2/11). */ + tf_partial = 1 << 8, /* Doing initial explicit argument + substitution in fn_type_unification. */ + /* Convenient substitution flags combinations. */ + tf_warning_or_error = tf_warning | tf_error +}; + +/* This type is used for parameters and variables which hold + combinations of the flags in enum tsubst_flags. */ +typedef int tsubst_flags_t; + +/* The kind of checking we can do looking in a class hierarchy. */ +enum base_access_flags { + ba_any = 0, /* Do not check access, allow an ambiguous base, + prefer a non-virtual base */ + ba_unique = 1 << 0, /* Must be a unique base. */ + ba_check_bit = 1 << 1, /* Check access. */ + ba_check = ba_unique | ba_check_bit, + ba_ignore_scope = 1 << 2 /* Ignore access allowed by local scope. */ +}; + +/* This type is used for parameters and variables which hold + combinations of the flags in enum base_access_flags. */ +typedef int base_access; + +/* The various kinds of access check during parsing. */ +typedef enum deferring_kind { + dk_no_deferred = 0, /* Check access immediately */ + dk_deferred = 1, /* Deferred check */ + dk_no_check = 2 /* No access check */ +} deferring_kind; + +/* The kind of base we can find, looking in a class hierarchy. + Values <0 indicate we failed. */ +typedef enum base_kind { + bk_inaccessible = -3, /* The base is inaccessible */ + bk_ambig = -2, /* The base is ambiguous */ + bk_not_base = -1, /* It is not a base */ + bk_same_type = 0, /* It is the same type */ + bk_proper_base = 1, /* It is a proper base */ + bk_via_virtual = 2 /* It is a proper base, but via a virtual + path. This might not be the canonical + binfo. */ +} base_kind; + +/* Node for "pointer to (virtual) function". + This may be distinct from ptr_type_node so gdb can distinguish them. */ +#define vfunc_ptr_type_node vtable_entry_type + + +/* For building calls to `delete'. */ +extern GTY(()) tree integer_two_node; + +/* The number of function bodies which we are currently processing. + (Zero if we are at namespace scope, one inside the body of a + function, two inside the body of a function in a local class, etc.) */ +extern int function_depth; + +/* Nonzero if we are inside eq_specializations, which affects comparison of + PARM_DECLs in cp_tree_equal. */ +extern int comparing_specializations; + +/* In parser.c. */ + +/* Nonzero if we are parsing an unevaluated operand: an operand to + sizeof, typeof, or alignof. This is a count since operands to + sizeof can be nested. */ + +extern int cp_unevaluated_operand; +extern tree cp_convert_range_for (tree, tree, tree); + +/* in pt.c */ + +/* These values are used for the `STRICT' parameter to type_unification and + fn_type_unification. Their meanings are described with the + documentation for fn_type_unification. */ + +typedef enum unification_kind_t { + DEDUCE_CALL, + DEDUCE_CONV, + DEDUCE_EXACT +} unification_kind_t; + +/* in class.c */ + +extern int current_class_depth; + +/* An array of all local classes present in this translation unit, in + declaration order. */ +extern GTY(()) vec *local_classes; + +/* Here's where we control how name mangling takes place. */ + +/* Cannot use '$' up front, because this confuses gdb + (names beginning with '$' are gdb-local identifiers). + + Note that all forms in which the '$' is significant are long enough + for direct indexing (meaning that if we know there is a '$' + at a particular location, we can index into the string at + any other location that provides distinguishing characters). */ + +/* Define NO_DOT_IN_LABEL in your favorite tm file if your assembler + doesn't allow '.' in symbol names. */ +#ifndef NO_DOT_IN_LABEL + +#define JOINER '.' + +#define AUTO_TEMP_NAME "_.tmp_" +#define VFIELD_BASE ".vf" +#define VFIELD_NAME "_vptr." +#define VFIELD_NAME_FORMAT "_vptr.%s" + +#define ANON_AGGRNAME_FORMAT "._%d" + +#else /* NO_DOT_IN_LABEL */ + +#ifndef NO_DOLLAR_IN_LABEL + +#define JOINER '$' + +#define AUTO_TEMP_NAME "_$tmp_" +#define VFIELD_BASE "$vf" +#define VFIELD_NAME "_vptr$" +#define VFIELD_NAME_FORMAT "_vptr$%s" +#define ANON_AGGRNAME_FORMAT "$_%d" + +#else /* NO_DOLLAR_IN_LABEL */ + +#define AUTO_TEMP_NAME "__tmp_" +#define TEMP_NAME_P(ID_NODE) \ + (!strncmp (IDENTIFIER_POINTER (ID_NODE), AUTO_TEMP_NAME, \ + sizeof (AUTO_TEMP_NAME) - 1)) +#define VTABLE_NAME "__vt_" +#define VTABLE_NAME_P(ID_NODE) \ + (!strncmp (IDENTIFIER_POINTER (ID_NODE), VTABLE_NAME, \ + sizeof (VTABLE_NAME) - 1)) +#define VFIELD_BASE "__vfb" +#define VFIELD_NAME "__vptr_" +#define VFIELD_NAME_P(ID_NODE) \ + (!strncmp (IDENTIFIER_POINTER (ID_NODE), VFIELD_NAME, \ + sizeof (VFIELD_NAME) - 1)) +#define VFIELD_NAME_FORMAT "__vptr_%s" + +#define ANON_AGGRNAME_PREFIX "__anon_" +#define ANON_AGGRNAME_P(ID_NODE) \ + (!strncmp (IDENTIFIER_POINTER (ID_NODE), ANON_AGGRNAME_PREFIX, \ + sizeof (ANON_AGGRNAME_PREFIX) - 1)) +#define ANON_AGGRNAME_FORMAT "__anon_%d" + +#endif /* NO_DOLLAR_IN_LABEL */ +#endif /* NO_DOT_IN_LABEL */ + +#define THIS_NAME "this" + +#define IN_CHARGE_NAME "__in_chrg" + +#define VTBL_PTR_TYPE "__vtbl_ptr_type" +#define VTABLE_DELTA_NAME "__delta" +#define VTABLE_PFN_NAME "__pfn" + +#define LAMBDANAME_PREFIX "__lambda" +#define LAMBDANAME_FORMAT LAMBDANAME_PREFIX "%d" + +#define UDLIT_OP_ANSI_PREFIX "operator\"\" " +#define UDLIT_OP_ANSI_FORMAT UDLIT_OP_ANSI_PREFIX "%s" +#define UDLIT_OP_MANGLED_PREFIX "li" +#define UDLIT_OP_MANGLED_FORMAT UDLIT_OP_MANGLED_PREFIX "%s" +#define UDLIT_OPER_P(ID_NODE) \ + (!strncmp (IDENTIFIER_POINTER (ID_NODE), \ + UDLIT_OP_ANSI_PREFIX, \ + sizeof (UDLIT_OP_ANSI_PREFIX) - 1)) +#define UDLIT_OP_SUFFIX(ID_NODE) \ + (IDENTIFIER_POINTER (ID_NODE) + sizeof (UDLIT_OP_ANSI_PREFIX) - 1) + +#if !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) + +#define VTABLE_NAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[1] == 'v' \ + && IDENTIFIER_POINTER (ID_NODE)[2] == 't' \ + && IDENTIFIER_POINTER (ID_NODE)[3] == JOINER) + +#define TEMP_NAME_P(ID_NODE) \ + (!strncmp (IDENTIFIER_POINTER (ID_NODE), AUTO_TEMP_NAME, sizeof (AUTO_TEMP_NAME)-1)) +#define VFIELD_NAME_P(ID_NODE) \ + (!strncmp (IDENTIFIER_POINTER (ID_NODE), VFIELD_NAME, sizeof(VFIELD_NAME)-1)) + +/* For anonymous aggregate types, we need some sort of name to + hold on to. In practice, this should not appear, but it should + not be harmful if it does. */ +#define ANON_AGGRNAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == JOINER \ + && IDENTIFIER_POINTER (ID_NODE)[1] == '_') +#endif /* !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) */ + + +/* Nonzero if we're done parsing and into end-of-file activities. */ + +extern int at_eof; + +/* A list of namespace-scope objects which have constructors or + destructors which reside in the global scope. The decl is stored + in the TREE_VALUE slot and the initializer is stored in the + TREE_PURPOSE slot. */ +extern GTY(()) tree static_aggregates; +/* Likewise, for thread local storage. */ +extern GTY(()) tree tls_aggregates; + +enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG }; + +/* These are uses as bits in flags passed to various functions to + control their behavior. Despite the LOOKUP_ prefix, many of these + do not control name lookup. ??? Functions using these flags should + probably be modified to accept explicit boolean flags for the + behaviors relevant to them. */ +/* Check for access violations. */ +#define LOOKUP_PROTECT (1 << 0) +#define LOOKUP_NORMAL (LOOKUP_PROTECT) +/* Even if the function found by lookup is a virtual function, it + should be called directly. */ +#define LOOKUP_NONVIRTUAL (1 << 1) +/* Non-converting (i.e., "explicit") constructors are not tried. This flag + indicates that we are not performing direct-initialization. */ +#define LOOKUP_ONLYCONVERTING (1 << 2) +#define LOOKUP_IMPLICIT (LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING) +/* If a temporary is created, it should be created so that it lives + as long as the current variable bindings; otherwise it only lives + until the end of the complete-expression. It also forces + direct-initialization in cases where other parts of the compiler + have already generated a temporary, such as reference + initialization and the catch parameter. */ +#define DIRECT_BIND (1 << 3) +/* We're performing a user-defined conversion, so more user-defined + conversions are not permitted (only built-in conversions). */ +#define LOOKUP_NO_CONVERSION (1 << 4) +/* The user has explicitly called a destructor. (Therefore, we do + not need to check that the object is non-NULL before calling the + destructor.) */ +#define LOOKUP_DESTRUCTOR (1 << 5) +/* Do not permit references to bind to temporaries. */ +#define LOOKUP_NO_TEMP_BIND (1 << 6) +/* Do not accept objects, and possibly namespaces. */ +#define LOOKUP_PREFER_TYPES (1 << 7) +/* Do not accept objects, and possibly types. */ +#define LOOKUP_PREFER_NAMESPACES (1 << 8) +/* Accept types or namespaces. */ +#define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES) +/* Return friend declarations and un-declared builtin functions. + (Normally, these entities are registered in the symbol table, but + not found by lookup.) */ +#define LOOKUP_HIDDEN (LOOKUP_PREFER_NAMESPACES << 1) +/* Prefer that the lvalue be treated as an rvalue. */ +#define LOOKUP_PREFER_RVALUE (LOOKUP_HIDDEN << 1) +/* We're inside an init-list, so narrowing conversions are ill-formed. */ +#define LOOKUP_NO_NARROWING (LOOKUP_PREFER_RVALUE << 1) +/* We're looking up a constructor for list-initialization. */ +#define LOOKUP_LIST_INIT_CTOR (LOOKUP_NO_NARROWING << 1) +/* This is the first parameter of a copy constructor. */ +#define LOOKUP_COPY_PARM (LOOKUP_LIST_INIT_CTOR << 1) +/* We only want to consider list constructors. */ +#define LOOKUP_LIST_ONLY (LOOKUP_COPY_PARM << 1) +/* Return after determining which function to call and checking access. + Used by sythesized_method_walk to determine which functions will + be called to initialize subobjects, in order to determine exception + specification and possible implicit delete. + This is kind of a hack, but exiting early avoids problems with trying + to perform argument conversions when the class isn't complete yet. */ +#define LOOKUP_SPECULATIVE (LOOKUP_LIST_ONLY << 1) +/* Used by calls from defaulted functions to limit the overload set to avoid + cycles trying to declare them (core issue 1092). */ +#define LOOKUP_DEFAULTED (LOOKUP_SPECULATIVE << 1) +/* Used in calls to store_init_value to suppress its usual call to + digest_init. */ +#define LOOKUP_ALREADY_DIGESTED (LOOKUP_DEFAULTED << 1) +/* An instantiation with explicit template arguments. */ +#define LOOKUP_EXPLICIT_TMPL_ARGS (LOOKUP_ALREADY_DIGESTED << 1) +/* Like LOOKUP_NO_TEMP_BIND, but also prevent binding to xvalues. */ +#define LOOKUP_NO_RVAL_BIND (LOOKUP_EXPLICIT_TMPL_ARGS << 1) + +#define LOOKUP_NAMESPACES_ONLY(F) \ + (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES)) +#define LOOKUP_TYPES_ONLY(F) \ + (!((F) & LOOKUP_PREFER_NAMESPACES) && ((F) & LOOKUP_PREFER_TYPES)) +#define LOOKUP_QUALIFIERS_ONLY(F) ((F) & LOOKUP_PREFER_BOTH) + + +/* These flags are used by the conversion code. + CONV_IMPLICIT : Perform implicit conversions (standard and user-defined). + CONV_STATIC : Perform the explicit conversions for static_cast. + CONV_CONST : Perform the explicit conversions for const_cast. + CONV_REINTERPRET: Perform the explicit conversions for reinterpret_cast. + CONV_PRIVATE : Perform upcasts to private bases. + CONV_FORCE_TEMP : Require a new temporary when converting to the same + aggregate type. */ + +#define CONV_IMPLICIT 1 +#define CONV_STATIC 2 +#define CONV_CONST 4 +#define CONV_REINTERPRET 8 +#define CONV_PRIVATE 16 +/* #define CONV_NONCONVERTING 32 */ +#define CONV_FORCE_TEMP 64 +#define CONV_OLD_CONVERT (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \ + | CONV_REINTERPRET) +#define CONV_C_CAST (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \ + | CONV_REINTERPRET | CONV_PRIVATE | CONV_FORCE_TEMP) + +/* Used by build_expr_type_conversion to indicate which types are + acceptable as arguments to the expression under consideration. */ + +#define WANT_INT 1 /* integer types, including bool */ +#define WANT_FLOAT 2 /* floating point types */ +#define WANT_ENUM 4 /* enumerated types */ +#define WANT_POINTER 8 /* pointer types */ +#define WANT_NULL 16 /* null pointer constant */ +#define WANT_VECTOR_OR_COMPLEX 32 /* vector or complex types */ +#define WANT_ARITH (WANT_INT | WANT_FLOAT | WANT_VECTOR_OR_COMPLEX) + +/* Used with comptypes, and related functions, to guide type + comparison. */ + +#define COMPARE_STRICT 0 /* Just check if the types are the + same. */ +#define COMPARE_BASE 1 /* Check to see if the second type is + derived from the first. */ +#define COMPARE_DERIVED 2 /* Like COMPARE_BASE, but in + reverse. */ +#define COMPARE_REDECLARATION 4 /* The comparison is being done when + another declaration of an existing + entity is seen. */ +#define COMPARE_STRUCTURAL 8 /* The comparison is intended to be + structural. The actual comparison + will be identical to + COMPARE_STRICT. */ + +/* Used with push_overloaded_decl. */ +#define PUSH_GLOBAL 0 /* Push the DECL into namespace scope, + regardless of the current scope. */ +#define PUSH_LOCAL 1 /* Push the DECL into the current + scope. */ +#define PUSH_USING 2 /* We are pushing this DECL as the + result of a using declaration. */ + +/* Used with start function. */ +#define SF_DEFAULT 0 /* No flags. */ +#define SF_PRE_PARSED 1 /* The function declaration has + already been parsed. */ +#define SF_INCLASS_INLINE 2 /* The function is an inline, defined + in the class body. */ + +/* Used with start_decl's initialized parameter. */ +#define SD_UNINITIALIZED 0 +#define SD_INITIALIZED 1 +#define SD_DEFAULTED 2 +#define SD_DELETED 3 + +/* Returns nonzero iff TYPE1 and TYPE2 are the same type, or if TYPE2 + is derived from TYPE1, or if TYPE2 is a pointer (reference) to a + class derived from the type pointed to (referred to) by TYPE1. */ +#define same_or_base_type_p(TYPE1, TYPE2) \ + comptypes ((TYPE1), (TYPE2), COMPARE_BASE) + +/* These macros are used to access a TEMPLATE_PARM_INDEX. */ +#define TEMPLATE_PARM_INDEX_CAST(NODE) \ + ((template_parm_index*)TEMPLATE_PARM_INDEX_CHECK (NODE)) +#define TEMPLATE_PARM_IDX(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->index) +#define TEMPLATE_PARM_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->level) +#define TEMPLATE_PARM_DESCENDANTS(NODE) (TREE_CHAIN (NODE)) +#define TEMPLATE_PARM_ORIG_LEVEL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->orig_level) +#define TEMPLATE_PARM_DECL(NODE) (TEMPLATE_PARM_INDEX_CAST (NODE)->decl) +#define TEMPLATE_PARM_PARAMETER_PACK(NODE) \ + (TREE_LANG_FLAG_0 (TEMPLATE_PARM_INDEX_CHECK (NODE))) + +/* These macros are for accessing the fields of TEMPLATE_TYPE_PARM, + TEMPLATE_TEMPLATE_PARM and BOUND_TEMPLATE_TEMPLATE_PARM nodes. */ +#define TEMPLATE_TYPE_PARM_INDEX(NODE) \ + (TYPE_VALUES_RAW (TREE_CHECK3 ((NODE), TEMPLATE_TYPE_PARM, \ + TEMPLATE_TEMPLATE_PARM, \ + BOUND_TEMPLATE_TEMPLATE_PARM))) +#define TEMPLATE_TYPE_IDX(NODE) \ + (TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (NODE))) +#define TEMPLATE_TYPE_LEVEL(NODE) \ + (TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE))) +#define TEMPLATE_TYPE_ORIG_LEVEL(NODE) \ + (TEMPLATE_PARM_ORIG_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE))) +#define TEMPLATE_TYPE_DECL(NODE) \ + (TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (NODE))) +#define TEMPLATE_TYPE_PARAMETER_PACK(NODE) \ + (TEMPLATE_PARM_PARAMETER_PACK (TEMPLATE_TYPE_PARM_INDEX (NODE))) + +/* These constants can used as bit flags in the process of tree formatting. + + TFF_PLAIN_IDENTIFIER: unqualified part of a name. + TFF_SCOPE: include the class and namespace scope of the name. + TFF_CHASE_TYPEDEF: print the original type-id instead of the typedef-name. + TFF_DECL_SPECIFIERS: print decl-specifiers. + TFF_CLASS_KEY_OR_ENUM: precede a class-type name (resp. enum name) with + a class-key (resp. `enum'). + TFF_RETURN_TYPE: include function return type. + TFF_FUNCTION_DEFAULT_ARGUMENTS: include function default parameter values. + TFF_EXCEPTION_SPECIFICATION: show function exception specification. + TFF_TEMPLATE_HEADER: show the template<...> header in a + template-declaration. + TFF_TEMPLATE_NAME: show only template-name. + TFF_EXPR_IN_PARENS: parenthesize expressions. + TFF_NO_FUNCTION_ARGUMENTS: don't show function arguments. + TFF_UNQUALIFIED_NAME: do not print the qualifying scope of the + top-level entity. + TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS: do not omit template arguments + identical to their defaults. */ + +#define TFF_PLAIN_IDENTIFIER (0) +#define TFF_SCOPE (1) +#define TFF_CHASE_TYPEDEF (1 << 1) +#define TFF_DECL_SPECIFIERS (1 << 2) +#define TFF_CLASS_KEY_OR_ENUM (1 << 3) +#define TFF_RETURN_TYPE (1 << 4) +#define TFF_FUNCTION_DEFAULT_ARGUMENTS (1 << 5) +#define TFF_EXCEPTION_SPECIFICATION (1 << 6) +#define TFF_TEMPLATE_HEADER (1 << 7) +#define TFF_TEMPLATE_NAME (1 << 8) +#define TFF_EXPR_IN_PARENS (1 << 9) +#define TFF_NO_FUNCTION_ARGUMENTS (1 << 10) +#define TFF_UNQUALIFIED_NAME (1 << 11) +#define TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS (1 << 12) + +/* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM + node. */ +#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL(NODE) \ + ((TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM) \ + ? TYPE_TI_TEMPLATE (NODE) \ + : TYPE_NAME (NODE)) + +/* in lex.c */ + +extern void init_reswords (void); + +typedef struct GTY(()) operator_name_info_t { + /* The IDENTIFIER_NODE for the operator. */ + tree identifier; + /* The name of the operator. */ + const char *name; + /* The mangled name of the operator. */ + const char *mangled_name; + /* The arity of the operator. */ + int arity; +} operator_name_info_t; + +/* A mapping from tree codes to operator name information. */ +extern GTY(()) operator_name_info_t operator_name_info + [(int) MAX_TREE_CODES]; +/* Similar, but for assignment operators. */ +extern GTY(()) operator_name_info_t assignment_operator_name_info + [(int) MAX_TREE_CODES]; + +/* A type-qualifier, or bitmask therefore, using the TYPE_QUAL + constants. */ + +typedef int cp_cv_quals; + +/* Non-static member functions have an optional virt-specifier-seq. + There is a VIRT_SPEC value for each virt-specifier. + They can be combined by bitwise-or to form the complete set of + virt-specifiers for a member function. */ +enum virt_specifier + { + VIRT_SPEC_UNSPECIFIED = 0x0, + VIRT_SPEC_FINAL = 0x1, + VIRT_SPEC_OVERRIDE = 0x2 + }; + +/* A type-qualifier, or bitmask therefore, using the VIRT_SPEC + constants. */ + +typedef int cp_virt_specifiers; + +/* Wherever there is a function-cv-qual, there could also be a ref-qualifier: + + [dcl.fct] + The return type, the parameter-type-list, the ref-qualifier, and + the cv-qualifier-seq, but not the default arguments or the exception + specification, are part of the function type. + + REF_QUAL_NONE Ordinary member function with no ref-qualifier + REF_QUAL_LVALUE Member function with the &-ref-qualifier + REF_QUAL_RVALUE Member function with the &&-ref-qualifier */ + +enum cp_ref_qualifier { + REF_QUAL_NONE = 0, + REF_QUAL_LVALUE = 1, + REF_QUAL_RVALUE = 2 +}; + +/* A storage class. */ + +typedef enum cp_storage_class { + /* sc_none must be zero so that zeroing a cp_decl_specifier_seq + sets the storage_class field to sc_none. */ + sc_none = 0, + sc_auto, + sc_register, + sc_static, + sc_extern, + sc_mutable +} cp_storage_class; + +/* An individual decl-specifier. This is used to index the array of + locations for the declspecs in struct cp_decl_specifier_seq + below. */ + +typedef enum cp_decl_spec { + ds_first, + ds_signed = ds_first, + ds_unsigned, + ds_short, + ds_long, + ds_const, + ds_volatile, + ds_restrict, + ds_inline, + ds_virtual, + ds_explicit, + ds_friend, + ds_typedef, + ds_alias, + ds_constexpr, + ds_complex, + ds_thread, + ds_type_spec, + ds_redefined_builtin_type_spec, + ds_attribute, + ds_std_attribute, + ds_storage_class, + ds_long_long, + ds_last /* This enumerator must always be the last one. */ +} cp_decl_spec; + +/* A decl-specifier-seq. */ + +typedef struct cp_decl_specifier_seq { + /* An array of locations for the declaration sepecifiers, indexed by + enum cp_decl_spec_word. */ + source_location locations[ds_last]; + /* The primary type, if any, given by the decl-specifier-seq. + Modifiers, like "short", "const", and "unsigned" are not + reflected here. This field will be a TYPE, unless a typedef-name + was used, in which case it will be a TYPE_DECL. */ + tree type; + /* The attributes, if any, provided with the specifier sequence. */ + tree attributes; + /* The c++11 attributes that follows the type specifier. */ + tree std_attributes; + /* If non-NULL, a built-in type that the user attempted to redefine + to some other type. */ + tree redefined_builtin_type; + /* The storage class specified -- or sc_none if no storage class was + explicitly specified. */ + cp_storage_class storage_class; + /* True iff TYPE_SPEC defines a class or enum. */ + BOOL_BITFIELD type_definition_p : 1; + /* True iff multiple types were (erroneously) specified for this + decl-specifier-seq. */ + BOOL_BITFIELD multiple_types_p : 1; + /* True iff multiple storage classes were (erroneously) specified + for this decl-specifier-seq or a combination of a storage class + with a typedef specifier. */ + BOOL_BITFIELD conflicting_specifiers_p : 1; + /* True iff at least one decl-specifier was found. */ + BOOL_BITFIELD any_specifiers_p : 1; + /* True iff at least one type-specifier was found. */ + BOOL_BITFIELD any_type_specifiers_p : 1; + /* True iff "int" was explicitly provided. */ + BOOL_BITFIELD explicit_int_p : 1; + /* True iff "__int128" was explicitly provided. */ + BOOL_BITFIELD explicit_int128_p : 1; + /* True iff "char" was explicitly provided. */ + BOOL_BITFIELD explicit_char_p : 1; + /* True iff ds_thread is set for __thread, not thread_local. */ + BOOL_BITFIELD gnu_thread_keyword_p : 1; +} cp_decl_specifier_seq; + +/* The various kinds of declarators. */ + +typedef enum cp_declarator_kind { + cdk_id, + cdk_function, + cdk_array, + cdk_pointer, + cdk_reference, + cdk_ptrmem, + cdk_error +} cp_declarator_kind; + +/* A declarator. */ + +typedef struct cp_declarator cp_declarator; + +typedef struct cp_parameter_declarator cp_parameter_declarator; + +/* A parameter, before it has been semantically analyzed. */ +struct cp_parameter_declarator { + /* The next parameter, or NULL_TREE if none. */ + cp_parameter_declarator *next; + /* The decl-specifiers-seq for the parameter. */ + cp_decl_specifier_seq decl_specifiers; + /* The declarator for the parameter. */ + cp_declarator *declarator; + /* The default-argument expression, or NULL_TREE, if none. */ + tree default_argument; + /* True iff this is the first parameter in the list and the + parameter sequence ends with an ellipsis. */ + bool ellipsis_p; +}; + +/* A declarator. */ +struct cp_declarator { + /* The kind of declarator. */ + ENUM_BITFIELD (cp_declarator_kind) kind : 4; + /* Whether we parsed an ellipsis (`...') just before the declarator, + to indicate this is a parameter pack. */ + BOOL_BITFIELD parameter_pack_p : 1; + location_t id_loc; /* Currently only set for cdk_id and cdk_function. */ + /* GNU Attributes that apply to this declarator. If the declarator + is a pointer or a reference, these attribute apply to the type + pointed to. */ + tree attributes; + /* Standard C++11 attributes that apply to this declarator. If the + declarator is a pointer or a reference, these attributes apply + to the pointer, rather than to the type pointed to. */ + tree std_attributes; + /* For all but cdk_id and cdk_error, the contained declarator. For + cdk_id and cdk_error, guaranteed to be NULL. */ + cp_declarator *declarator; + union { + /* For identifiers. */ + struct { + /* If non-NULL, the qualifying scope (a NAMESPACE_DECL or + *_TYPE) for this identifier. */ + tree qualifying_scope; + /* The unqualified name of the entity -- an IDENTIFIER_NODE, + BIT_NOT_EXPR, or TEMPLATE_ID_EXPR. */ + tree unqualified_name; + /* If this is the name of a function, what kind of special + function (if any). */ + special_function_kind sfk; + } id; + /* For functions. */ + struct { + /* The parameters to the function as a TREE_LIST of decl/default. */ + tree parameters; + /* The cv-qualifiers for the function. */ + cp_cv_quals qualifiers; + /* The virt-specifiers for the function. */ + cp_virt_specifiers virt_specifiers; + /* The ref-qualifier for the function. */ + cp_ref_qualifier ref_qualifier; + /* The exception-specification for the function. */ + tree exception_specification; + /* The late-specified return type, if any. */ + tree late_return_type; + } function; + /* For arrays. */ + struct { + /* The bounds to the array. */ + tree bounds; + } array; + /* For cdk_pointer and cdk_ptrmem. */ + struct { + /* The cv-qualifiers for the pointer. */ + cp_cv_quals qualifiers; + /* For cdk_ptrmem, the class type containing the member. */ + tree class_type; + } pointer; + /* For cdk_reference */ + struct { + /* The cv-qualifiers for the reference. These qualifiers are + only used to diagnose ill-formed code. */ + cp_cv_quals qualifiers; + /* Whether this is an rvalue reference */ + bool rvalue_ref; + } reference; + } u; +}; + +/* A level of template instantiation. */ +struct GTY((chain_next ("%h.next"))) tinst_level { + /* The immediately deeper level in the chain. */ + struct tinst_level *next; + + /* The original node. Can be either a DECL (for a function or static + data member) or a TYPE (for a class), depending on what we were + asked to instantiate. */ + tree decl; + + /* The location where the template is instantiated. */ + location_t locus; + + /* errorcount+sorrycount when we pushed this level. */ + int errors; + + /* True if the location is in a system header. */ + bool in_system_header_p; +}; + +bool decl_spec_seq_has_spec_p (const cp_decl_specifier_seq *, cp_decl_spec); + +/* Return the type of the `this' parameter of FNTYPE. */ + +static inline tree +type_of_this_parm (const_tree fntype) +{ + function_args_iterator iter; + gcc_assert (TREE_CODE (fntype) == METHOD_TYPE); + function_args_iter_init (&iter, fntype); + return function_args_iter_cond (&iter); +} + +/* Return the class of the `this' parameter of FNTYPE. */ + +static inline tree +class_of_this_parm (const_tree fntype) +{ + return TREE_TYPE (type_of_this_parm (fntype)); +} + +/* A parameter list indicating for a function with no parameters, + e.g "int f(void)". */ +extern cp_parameter_declarator *no_parameters; + +/* True if we saw "#pragma GCC java_exceptions". */ +extern bool pragma_java_exceptions; + +/* in call.c */ +extern bool check_dtor_name (tree, tree); + +extern tree build_conditional_expr (tree, tree, tree, + tsubst_flags_t); +extern tree build_addr_func (tree, tsubst_flags_t); +extern void set_flags_from_callee (tree); +extern tree build_call_a (tree, int, tree*); +extern tree build_call_n (tree, int, ...); +extern bool null_ptr_cst_p (tree); +extern bool null_member_pointer_value_p (tree); +extern bool sufficient_parms_p (const_tree); +extern tree type_decays_to (tree); +extern tree build_user_type_conversion (tree, tree, int, + tsubst_flags_t); +extern tree build_new_function_call (tree, vec **, bool, + tsubst_flags_t); +extern tree build_operator_new_call (tree, vec **, tree *, + tree *, tree, tree *, + tsubst_flags_t); +extern tree build_new_method_call (tree, tree, vec **, + tree, int, tree *, + tsubst_flags_t); +extern tree build_special_member_call (tree, tree, vec **, + tree, int, tsubst_flags_t); +extern tree build_new_op (location_t, enum tree_code, + int, tree, tree, tree, tree *, + tsubst_flags_t); +extern tree build_op_call (tree, vec **, + tsubst_flags_t); +extern tree build_op_delete_call (enum tree_code, tree, tree, + bool, tree, tree, + tsubst_flags_t); +extern bool can_convert (tree, tree, tsubst_flags_t); +extern bool can_convert_arg (tree, tree, tree, int, + tsubst_flags_t); +extern bool can_convert_arg_bad (tree, tree, tree, int, + tsubst_flags_t); +extern bool enforce_access (tree, tree, tree, + tsubst_flags_t); +extern void push_defarg_context (tree); +extern void pop_defarg_context (void); +extern tree convert_default_arg (tree, tree, tree, int, + tsubst_flags_t); +extern tree convert_arg_to_ellipsis (tree, tsubst_flags_t); +extern tree build_x_va_arg (source_location, tree, tree); +extern tree cxx_type_promotes_to (tree); +extern tree type_passed_as (tree); +extern tree convert_for_arg_passing (tree, tree, tsubst_flags_t); +extern bool is_properly_derived_from (tree, tree); +extern tree initialize_reference (tree, tree, int, + tsubst_flags_t); +extern tree extend_ref_init_temps (tree, tree, vec**); +extern tree make_temporary_var_for_ref_to_temp (tree, tree); +extern bool type_has_extended_temps (tree); +extern tree strip_top_quals (tree); +extern bool reference_related_p (tree, tree); +extern tree perform_implicit_conversion (tree, tree, tsubst_flags_t); +extern tree perform_implicit_conversion_flags (tree, tree, tsubst_flags_t, int); +extern tree build_integral_nontype_arg_conv (tree, tree, tsubst_flags_t); +extern tree perform_direct_initialization_if_possible (tree, tree, bool, + tsubst_flags_t); +extern tree in_charge_arg_for_name (tree); +extern tree build_cxx_call (tree, int, tree *, + tsubst_flags_t); +extern bool is_std_init_list (tree); +extern bool is_list_ctor (tree); +#ifdef ENABLE_CHECKING +extern void validate_conversion_obstack (void); +#endif /* ENABLE_CHECKING */ +extern void mark_versions_used (tree); +extern tree get_function_version_dispatcher (tree); + +/* in class.c */ +extern tree build_vfield_ref (tree, tree); +extern tree build_base_path (enum tree_code, tree, + tree, int, tsubst_flags_t); +extern tree convert_to_base (tree, tree, bool, bool, + tsubst_flags_t); +extern tree convert_to_base_statically (tree, tree); +extern tree build_vtbl_ref (tree, tree); +extern tree build_vfn_ref (tree, tree); +extern tree get_vtable_decl (tree, int); +extern void resort_type_method_vec (void *, void *, + gt_pointer_operator, void *); +extern bool add_method (tree, tree, tree); +extern bool currently_open_class (tree); +extern tree currently_open_derived_class (tree); +extern tree current_nonlambda_class_type (void); +extern tree finish_struct (tree, tree); +extern void finish_struct_1 (tree); +extern int resolves_to_fixed_type_p (tree, int *); +extern void init_class_processing (void); +extern int is_empty_class (tree); +extern bool is_really_empty_class (tree); +extern void pushclass (tree); +extern void popclass (void); +extern void push_nested_class (tree); +extern void pop_nested_class (void); +extern int current_lang_depth (void); +extern void push_lang_context (tree); +extern void pop_lang_context (void); +extern tree instantiate_type (tree, tree, tsubst_flags_t); +extern void print_class_statistics (void); +extern void build_self_reference (void); +extern int same_signature_p (const_tree, const_tree); +extern void maybe_add_class_template_decl_list (tree, tree, int); +extern void unreverse_member_declarations (tree); +extern void invalidate_class_lookup_cache (void); +extern void maybe_note_name_used_in_class (tree, tree); +extern void note_name_declared_in_class (tree, tree); +extern tree get_vtbl_decl_for_binfo (tree); +extern void debug_class (tree); +extern void debug_thunks (tree); +extern void set_linkage_according_to_type (tree, tree); +extern void determine_key_method (tree); +extern void check_for_override (tree, tree); +extern void push_class_stack (void); +extern void pop_class_stack (void); +extern bool type_has_user_nondefault_constructor (tree); +extern tree in_class_defaulted_default_constructor (tree); +extern bool user_provided_p (tree); +extern bool type_has_user_provided_constructor (tree); +extern bool type_has_user_provided_default_constructor (tree); +extern bool vbase_has_user_provided_move_assign (tree); +extern tree default_init_uninitialized_part (tree); +extern bool trivial_default_constructor_is_constexpr (tree); +extern bool type_has_constexpr_default_constructor (tree); +extern bool type_has_virtual_destructor (tree); +extern bool type_has_move_constructor (tree); +extern bool type_has_move_assign (tree); +extern bool type_has_user_declared_move_constructor (tree); +extern bool type_has_user_declared_move_assign(tree); +extern bool type_build_ctor_call (tree); +extern void explain_non_literal_class (tree); +extern void defaulted_late_check (tree); +extern bool defaultable_fn_check (tree); +extern void fixup_type_variants (tree); +extern void fixup_attribute_variants (tree); +extern tree* decl_cloned_function_p (const_tree, bool); +extern void clone_function_decl (tree, int); +extern void adjust_clone_args (tree); +extern void deduce_noexcept_on_destructor (tree); +extern void insert_late_enum_def_into_classtype_sorted_fields (tree, tree); +extern bool uniquely_derived_from_p (tree, tree); +extern bool publicly_uniquely_derived_p (tree, tree); + +/* in cvt.c */ +extern tree convert_to_reference (tree, tree, int, int, tree, + tsubst_flags_t); +extern tree convert_from_reference (tree); +extern tree force_rvalue (tree, tsubst_flags_t); +extern tree ocp_convert (tree, tree, int, int, + tsubst_flags_t); +extern tree cp_convert (tree, tree, tsubst_flags_t); +extern tree cp_convert_and_check (tree, tree, tsubst_flags_t); +extern tree cp_fold_convert (tree, tree); +extern tree convert_to_void (tree, impl_conv_void, + tsubst_flags_t); +extern tree convert_force (tree, tree, int, + tsubst_flags_t); +extern tree build_expr_type_conversion (int, tree, bool); +extern tree type_promotes_to (tree); +extern tree perform_qualification_conversions (tree, tree); + +/* in name-lookup.c */ +extern tree pushdecl (tree); +extern tree pushdecl_maybe_friend (tree, bool); +extern void maybe_push_cleanup_level (tree); +extern tree pushtag (tree, tree, tag_scope); +extern tree make_anon_name (void); +extern tree pushdecl_top_level_maybe_friend (tree, bool); +extern tree pushdecl_top_level_and_finish (tree, tree); +extern tree check_for_out_of_scope_variable (tree); +extern void print_other_binding_stack (cp_binding_level *); +extern tree maybe_push_decl (tree); +extern tree current_decl_namespace (void); + +/* decl.c */ +extern tree poplevel (int, int, int); +extern void cxx_init_decl_processing (void); +enum cp_tree_node_structure_enum cp_tree_node_structure + (union lang_tree_node *); +extern void finish_scope (void); +extern void push_switch (tree); +extern void pop_switch (void); +extern tree make_lambda_name (void); +extern int decls_match (tree, tree); +extern tree duplicate_decls (tree, tree, bool); +extern tree declare_local_label (tree); +extern tree define_label (location_t, tree); +extern void check_goto (tree); +extern bool check_omp_return (void); +extern tree make_typename_type (tree, tree, enum tag_types, tsubst_flags_t); +extern tree make_unbound_class_template (tree, tree, tree, tsubst_flags_t); +extern tree build_library_fn_ptr (const char *, tree); +extern tree build_cp_library_fn_ptr (const char *, tree); +extern tree push_library_fn (tree, tree, tree); +extern tree push_void_library_fn (tree, tree); +extern tree push_throw_library_fn (tree, tree); +extern void warn_misplaced_attr_for_class_type (source_location location, + tree class_type); +extern tree check_tag_decl (cp_decl_specifier_seq *, bool); +extern tree shadow_tag (cp_decl_specifier_seq *); +extern tree groktypename (cp_decl_specifier_seq *, const cp_declarator *, bool); +extern tree start_decl (const cp_declarator *, cp_decl_specifier_seq *, int, tree, tree, tree *); +extern void start_decl_1 (tree, bool); +extern bool check_array_initializer (tree, tree, tree); +extern void cp_finish_decl (tree, tree, bool, tree, int); +extern int cp_complete_array_type (tree *, tree, bool); +extern int cp_complete_array_type_or_error (tree *, tree, bool, tsubst_flags_t); +extern tree build_ptrmemfunc_type (tree); +extern tree build_ptrmem_type (tree, tree); +/* the grokdeclarator prototype is in decl.h */ +extern tree build_this_parm (tree, cp_cv_quals); +extern int copy_fn_p (const_tree); +extern bool move_fn_p (const_tree); +extern bool move_signature_fn_p (const_tree); +extern tree get_scope_of_declarator (const cp_declarator *); +extern void grok_special_member_properties (tree); +extern int grok_ctor_properties (const_tree, const_tree); +extern bool grok_op_properties (tree, bool); +extern tree xref_tag (enum tag_types, tree, tag_scope, bool); +extern tree xref_tag_from_type (tree, tree, tag_scope); +extern bool xref_basetypes (tree, tree); +extern tree start_enum (tree, tree, tree, bool, bool *); +extern void finish_enum_value_list (tree); +extern void finish_enum (tree); +extern void build_enumerator (tree, tree, tree, location_t); +extern tree lookup_enumerator (tree, tree); +extern void start_preparsed_function (tree, tree, int); +extern int start_function (cp_decl_specifier_seq *, const cp_declarator *, tree); +extern tree begin_function_body (void); +extern void finish_function_body (tree); +extern tree outer_curly_brace_block (tree); +extern tree finish_function (int); +extern tree grokmethod (cp_decl_specifier_seq *, const cp_declarator *, tree); +extern void maybe_register_incomplete_var (tree); +extern void maybe_commonize_var (tree); +extern void complete_vars (tree); +extern void finish_stmt (void); +extern tree static_fn_type (tree); +extern void revert_static_member_fn (tree); +extern void fixup_anonymous_aggr (tree); +extern tree compute_array_index_type (tree, tree, tsubst_flags_t); +extern tree check_default_argument (tree, tree, tsubst_flags_t); +typedef int (*walk_namespaces_fn) (tree, void *); +extern int walk_namespaces (walk_namespaces_fn, + void *); +extern int wrapup_globals_for_namespace (tree, void *); +extern tree create_implicit_typedef (tree, tree); +extern int local_variable_p (const_tree); +extern tree register_dtor_fn (tree); +extern tmpl_spec_kind current_tmpl_spec_kind (int); +extern tree cp_fname_init (const char *, tree *); +extern tree cxx_builtin_function (tree decl); +extern tree cxx_builtin_function_ext_scope (tree decl); +extern tree check_elaborated_type_specifier (enum tag_types, tree, bool); +extern void warn_extern_redeclared_static (tree, tree); +extern tree cxx_comdat_group (tree); +extern bool cp_missing_noreturn_ok_p (tree); +extern void initialize_artificial_var (tree, vec *); +extern tree check_var_type (tree, tree); +extern tree reshape_init (tree, tree, tsubst_flags_t); +extern tree next_initializable_field (tree); + +extern bool defer_mark_used_calls; +extern GTY(()) vec *deferred_mark_used_calls; +extern tree finish_case_label (location_t, tree, tree); +extern tree cxx_maybe_build_cleanup (tree, tsubst_flags_t); + +/* in decl2.c */ +extern bool check_java_method (tree); +extern tree build_memfn_type (tree, tree, cp_cv_quals, cp_ref_qualifier); +extern tree build_pointer_ptrmemfn_type (tree); +extern tree change_return_type (tree, tree); +extern void maybe_retrofit_in_chrg (tree); +extern void maybe_make_one_only (tree); +extern bool vague_linkage_p (tree); +extern void grokclassfn (tree, tree, + enum overload_flags); +extern tree grok_array_decl (location_t, tree, tree, bool); +extern tree delete_sanity (tree, tree, bool, int, tsubst_flags_t); +extern tree check_classfn (tree, tree, tree); +extern void check_member_template (tree); +extern tree grokfield (const cp_declarator *, cp_decl_specifier_seq *, + tree, bool, tree, tree); +extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *, + tree, tree); +extern tree cp_reconstruct_complex_type (tree, tree); +extern void cplus_decl_attributes (tree *, tree, int); +extern void finish_anon_union (tree); +extern void cp_write_global_declarations (void); +extern tree coerce_new_type (tree); +extern tree coerce_delete_type (tree); +extern void comdat_linkage (tree); +extern void determine_visibility (tree); +extern void constrain_class_visibility (tree); +extern void import_export_decl (tree); +extern tree build_cleanup (tree); +extern tree build_offset_ref_call_from_tree (tree, vec **, + tsubst_flags_t); +extern bool decl_constant_var_p (tree); +extern bool decl_maybe_constant_var_p (tree); +extern void check_default_args (tree); +extern bool mark_used (tree); +extern void finish_static_data_member_decl (tree, tree, bool, tree, int); +extern tree cp_build_parm_decl (tree, tree); +extern tree get_guard (tree); +extern tree get_guard_cond (tree); +extern tree set_guard (tree); +extern tree get_tls_wrapper_fn (tree); +extern void mark_needed (tree); +extern bool decl_needed_p (tree); +extern void note_vague_linkage_fn (tree); +extern tree build_artificial_parm (tree, tree); +extern bool possibly_inlined_p (tree); +extern int parm_index (tree); + +/* in error.c */ +extern void init_error (void); +extern const char *type_as_string (tree, int); +extern const char *type_as_string_translate (tree, int); +extern const char *decl_as_string (tree, int); +extern const char *decl_as_string_translate (tree, int); +extern const char *decl_as_dwarf_string (tree, int); +extern const char *expr_as_string (tree, int); +extern const char *lang_decl_name (tree, int, bool); +extern const char *lang_decl_dwarf_name (tree, int, bool); +extern const char *language_to_string (enum languages); +extern const char *class_key_or_enum_as_string (tree); +extern void print_instantiation_context (void); +extern void maybe_warn_variadic_templates (void); +extern void maybe_warn_cpp0x (cpp0x_warn_str str); +extern bool pedwarn_cxx98 (location_t, int, const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); +extern location_t location_of (tree); +extern void qualified_name_lookup_error (tree, tree, tree, + location_t); + +/* in except.c */ +extern void init_exception_processing (void); +extern tree expand_start_catch_block (tree); +extern void expand_end_catch_block (void); +extern tree build_exc_ptr (void); +extern tree build_throw (tree); +extern int nothrow_libfn_p (const_tree); +extern void check_handlers (tree); +extern tree finish_noexcept_expr (tree, tsubst_flags_t); +extern bool expr_noexcept_p (tree, tsubst_flags_t); +extern void perform_deferred_noexcept_checks (void); +extern bool nothrow_spec_p (const_tree); +extern bool type_noexcept_p (const_tree); +extern bool type_throw_all_p (const_tree); +extern tree build_noexcept_spec (tree, int); +extern void choose_personality_routine (enum languages); +extern tree build_must_not_throw_expr (tree,tree); +extern tree eh_type_info (tree); +extern tree begin_eh_spec_block (void); +extern void finish_eh_spec_block (tree, tree); +extern tree build_eh_type_type (tree); +extern tree cp_protect_cleanup_actions (void); + +/* in expr.c */ +extern tree cplus_expand_constant (tree); +extern tree mark_rvalue_use (tree); +extern tree mark_lvalue_use (tree); +extern tree mark_type_use (tree); +extern void mark_exp_read (tree); + +/* friend.c */ +extern int is_friend (tree, tree); +extern void make_friend_class (tree, tree, bool); +extern void add_friend (tree, tree, bool); +extern tree do_friend (tree, tree, tree, tree, enum overload_flags, bool); + +/* in init.c */ +extern tree expand_member_init (tree); +extern void emit_mem_initializers (tree); +extern tree build_aggr_init (tree, tree, int, + tsubst_flags_t); +extern int is_class_type (tree, int); +extern tree get_type_value (tree); +extern tree build_zero_init (tree, tree, bool); +extern tree build_value_init (tree, tsubst_flags_t); +extern tree build_value_init_noctor (tree, tsubst_flags_t); +extern tree build_offset_ref (tree, tree, bool, + tsubst_flags_t); +extern tree build_new (vec **, tree, tree, + vec **, int, + tsubst_flags_t); +extern tree get_temp_regvar (tree, tree); +extern tree build_vec_init (tree, tree, tree, bool, int, + tsubst_flags_t); +extern tree build_delete (tree, tree, + special_function_kind, + int, int, tsubst_flags_t); +extern void push_base_cleanups (void); +extern tree build_vec_delete (tree, tree, + special_function_kind, int, + tsubst_flags_t); +extern tree create_temporary_var (tree); +extern void initialize_vtbl_ptrs (tree); +extern tree build_java_class_ref (tree); +extern tree integral_constant_value (tree); +extern tree decl_constant_value_safe (tree); +extern int diagnose_uninitialized_cst_or_ref_member (tree, bool, bool); + +/* in lex.c */ +extern void cxx_dup_lang_specific_decl (tree); +extern void yyungetc (int, int); + +extern tree unqualified_name_lookup_error (tree); +extern tree unqualified_fn_lookup_error (tree); +extern tree build_lang_decl (enum tree_code, tree, tree); +extern tree build_lang_decl_loc (location_t, enum tree_code, tree, tree); +extern void retrofit_lang_decl (tree); +extern tree copy_decl (tree); +extern tree copy_type (tree); +extern tree cxx_make_type (enum tree_code); +extern tree make_class_type (enum tree_code); +extern bool cxx_init (void); +extern void cxx_finish (void); +extern bool in_main_input_context (void); + +/* in method.c */ +extern void init_method (void); +extern tree make_thunk (tree, bool, tree, tree); +extern void finish_thunk (tree); +extern void use_thunk (tree, bool); +extern bool trivial_fn_p (tree); +extern bool maybe_explain_implicit_delete (tree); +extern void explain_implicit_non_constexpr (tree); +extern void deduce_inheriting_ctor (tree); +extern void synthesize_method (tree); +extern tree lazily_declare_fn (special_function_kind, + tree); +extern tree skip_artificial_parms_for (const_tree, tree); +extern int num_artificial_parms_for (const_tree); +extern tree make_alias_for (tree, tree); +extern tree get_copy_ctor (tree, tsubst_flags_t); +extern tree get_copy_assign (tree); +extern tree get_default_ctor (tree); +extern tree get_dtor (tree, tsubst_flags_t); +extern tree locate_ctor (tree); +extern tree implicitly_declare_fn (special_function_kind, tree, + bool, tree, tree); + +/* In optimize.c */ +extern bool maybe_clone_body (tree); + +/* in pt.c */ +extern bool check_template_shadow (tree); +extern tree get_innermost_template_args (tree, int); +extern void maybe_begin_member_template_processing (tree); +extern void maybe_end_member_template_processing (void); +extern tree finish_member_template_decl (tree); +extern void begin_template_parm_list (void); +extern bool begin_specialization (void); +extern void reset_specialization (void); +extern void end_specialization (void); +extern void begin_explicit_instantiation (void); +extern void end_explicit_instantiation (void); +extern tree check_explicit_specialization (tree, tree, int, int); +extern int num_template_headers_for_class (tree); +extern void check_template_variable (tree); +extern tree make_auto (void); +extern tree do_auto_deduction (tree, tree, tree); +extern tree type_uses_auto (tree); +extern void append_type_to_template_for_access_check (tree, tree, tree, + location_t); +extern tree splice_late_return_type (tree, tree); +extern bool is_auto (const_tree); +extern tree process_template_parm (tree, location_t, tree, + bool, bool); +extern tree end_template_parm_list (tree); +extern void end_template_decl (void); +extern tree maybe_update_decl_type (tree, tree); +extern bool check_default_tmpl_args (tree, tree, bool, bool, int); +extern tree push_template_decl (tree); +extern tree push_template_decl_real (tree, bool); +extern tree add_inherited_template_parms (tree, tree); +extern bool redeclare_class_template (tree, tree); +extern tree lookup_template_class (tree, tree, tree, tree, + int, tsubst_flags_t); +extern tree lookup_template_function (tree, tree); +extern int uses_template_parms (tree); +extern int uses_template_parms_level (tree, int); +extern bool in_template_function (void); +extern tree instantiate_class_template (tree); +extern tree instantiate_template (tree, tree, tsubst_flags_t); +extern tree fn_type_unification (tree, tree, tree, + const tree *, unsigned int, + tree, unification_kind_t, int, + bool); +extern void mark_decl_instantiated (tree, int); +extern int more_specialized_fn (tree, tree, int); +extern void do_decl_instantiation (tree, tree); +extern void do_type_instantiation (tree, tree, tsubst_flags_t); +extern bool always_instantiate_p (tree); +extern void maybe_instantiate_noexcept (tree); +extern tree instantiate_decl (tree, int, bool); +extern int comp_template_parms (const_tree, const_tree); +extern bool uses_parameter_packs (tree); +extern bool template_parameter_pack_p (const_tree); +extern bool function_parameter_pack_p (const_tree); +extern bool function_parameter_expanded_from_pack_p (tree, tree); +extern tree make_pack_expansion (tree); +extern bool check_for_bare_parameter_packs (tree); +extern tree build_template_info (tree, tree); +extern tree get_template_info (const_tree); +extern vec *get_types_needing_access_check (tree); +extern int template_class_depth (tree); +extern int is_specialization_of (tree, tree); +extern bool is_specialization_of_friend (tree, tree); +extern tree get_pattern_parm (tree, tree); +extern int comp_template_args (tree, tree); +extern tree maybe_process_partial_specialization (tree); +extern tree most_specialized_instantiation (tree); +extern void print_candidates (tree); +extern void instantiate_pending_templates (int); +extern tree tsubst_default_argument (tree, tree, tree, + tsubst_flags_t); +extern tree tsubst (tree, tree, tsubst_flags_t, tree); +extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t, + tree, bool, bool); +extern tree most_general_template (tree); +extern tree get_mostly_instantiated_function_type (tree); +extern int problematic_instantiation_changed (void); +extern void record_last_problematic_instantiation (void); +extern struct tinst_level *current_instantiation(void); +extern tree maybe_get_template_decl_from_type_decl (tree); +extern int processing_template_parmlist; +extern bool dependent_type_p (tree); +extern bool dependent_scope_p (tree); +extern bool any_dependent_template_arguments_p (const_tree); +extern bool dependent_template_p (tree); +extern bool dependent_template_id_p (tree, tree); +extern bool type_dependent_expression_p (tree); +extern bool any_type_dependent_arguments_p (const vec *); +extern bool any_type_dependent_elements_p (const_tree); +extern bool type_dependent_expression_p_push (tree); +extern bool value_dependent_expression_p (tree); +extern bool instantiation_dependent_expression_p (tree); +extern bool any_value_dependent_elements_p (const_tree); +extern bool dependent_omp_for_p (tree, tree, tree, tree); +extern tree resolve_typename_type (tree, bool); +extern tree template_for_substitution (tree); +extern tree build_non_dependent_expr (tree); +extern void make_args_non_dependent (vec *); +extern bool reregister_specialization (tree, tree, tree); +extern tree fold_non_dependent_expr (tree); +extern tree fold_non_dependent_expr_sfinae (tree, tsubst_flags_t); +extern bool alias_type_or_template_p (tree); +extern bool alias_template_specialization_p (const_tree); +extern bool explicit_class_specialization_p (tree); +extern int push_tinst_level (tree); +extern void pop_tinst_level (void); +extern struct tinst_level *outermost_tinst_level(void); +extern void init_template_processing (void); +extern void print_template_statistics (void); +bool template_template_parameter_p (const_tree); +bool template_type_parameter_p (const_tree); +extern bool primary_template_instantiation_p (const_tree); +extern tree get_primary_template_innermost_parameters (const_tree); +extern tree get_template_parms_at_level (tree, int); +extern tree get_template_innermost_arguments (const_tree); +extern tree get_template_argument_pack_elems (const_tree); +extern tree get_function_template_decl (const_tree); +extern tree resolve_nondeduced_context (tree); +extern hashval_t iterative_hash_template_arg (tree arg, hashval_t val); + +/* in repo.c */ +extern void init_repo (void); +extern int repo_emit_p (tree); +extern bool repo_export_class_p (const_tree); +extern void finish_repo (void); + +/* in rtti.c */ +/* A vector of all tinfo decls that haven't been emitted yet. */ +extern GTY(()) vec *unemitted_tinfo_decls; + +extern void init_rtti_processing (void); +extern tree build_typeid (tree, tsubst_flags_t); +extern tree get_tinfo_decl (tree); +extern tree get_typeid (tree, tsubst_flags_t); +extern tree build_headof (tree); +extern tree build_dynamic_cast (tree, tree, tsubst_flags_t); +extern void emit_support_tinfos (void); +extern bool emit_tinfo_decl (tree); + +/* in search.c */ +extern bool accessible_base_p (tree, tree, bool); +extern tree lookup_base (tree, tree, base_access, + base_kind *, tsubst_flags_t); +extern tree dcast_base_hint (tree, tree); +extern int accessible_p (tree, tree, bool); +extern int accessible_in_template_p (tree, tree); +extern tree lookup_field_1 (tree, tree, bool); +extern tree lookup_field (tree, tree, int, bool); +extern int lookup_fnfields_1 (tree, tree); +extern tree lookup_fnfields_slot (tree, tree); +extern tree lookup_fnfields_slot_nolazy (tree, tree); +extern int class_method_index_for_fn (tree, tree); +extern tree lookup_fnfields (tree, tree, int); +extern tree lookup_member (tree, tree, int, bool, + tsubst_flags_t); +extern int look_for_overrides (tree, tree); +extern void get_pure_virtuals (tree); +extern void maybe_suppress_debug_info (tree); +extern void note_debug_info_needed (tree); +extern void print_search_statistics (void); +extern void reinit_search_statistics (void); +extern tree current_scope (void); +extern int at_function_scope_p (void); +extern bool at_class_scope_p (void); +extern bool at_namespace_scope_p (void); +extern tree context_for_name_lookup (tree); +extern tree lookup_conversions (tree); +extern tree binfo_from_vbase (tree); +extern tree binfo_for_vbase (tree, tree); +extern tree look_for_overrides_here (tree, tree); +#define dfs_skip_bases ((tree)1) +extern tree dfs_walk_all (tree, tree (*) (tree, void *), + tree (*) (tree, void *), void *); +extern tree dfs_walk_once (tree, tree (*) (tree, void *), + tree (*) (tree, void *), void *); +extern tree binfo_via_virtual (tree, tree); +extern tree build_baselink (tree, tree, tree, tree); +extern tree adjust_result_of_qualified_name_lookup + (tree, tree, tree); +extern tree copied_binfo (tree, tree); +extern tree original_binfo (tree, tree); +extern int shared_member_p (tree); + + +/* The representation of a deferred access check. */ + +typedef struct GTY(()) deferred_access_check { + /* The base class in which the declaration is referenced. */ + tree binfo; + /* The declaration whose access must be checked. */ + tree decl; + /* The declaration that should be used in the error message. */ + tree diag_decl; + /* The location of this access. */ + location_t loc; +} deferred_access_check; + +/* in semantics.c */ +extern void push_deferring_access_checks (deferring_kind); +extern void resume_deferring_access_checks (void); +extern void stop_deferring_access_checks (void); +extern void pop_deferring_access_checks (void); +extern vec *get_deferred_access_checks (void); +extern void reopen_deferring_access_checks (vec *); +extern void pop_to_parent_deferring_access_checks (void); +extern bool perform_access_checks (vec *, + tsubst_flags_t); +extern bool perform_deferred_access_checks (tsubst_flags_t); +extern bool perform_or_defer_access_check (tree, tree, tree, + tsubst_flags_t); +extern int stmts_are_full_exprs_p (void); +extern void init_cp_semantics (void); +extern tree do_poplevel (tree); +extern void add_decl_expr (tree); +extern tree maybe_cleanup_point_expr_void (tree); +extern tree finish_expr_stmt (tree); +extern tree begin_if_stmt (void); +extern void finish_if_stmt_cond (tree, tree); +extern tree finish_then_clause (tree); +extern void begin_else_clause (tree); +extern void finish_else_clause (tree); +extern void finish_if_stmt (tree); +extern tree begin_while_stmt (void); +extern void finish_while_stmt_cond (tree, tree); +extern void finish_while_stmt (tree); +extern tree begin_do_stmt (void); +extern void finish_do_body (tree); +extern void finish_do_stmt (tree, tree); +extern tree finish_return_stmt (tree); +extern tree begin_for_scope (tree *); +extern tree begin_for_stmt (tree, tree); +extern void finish_for_init_stmt (tree); +extern void finish_for_cond (tree, tree); +extern void finish_for_expr (tree, tree); +extern void finish_for_stmt (tree); +extern tree begin_range_for_stmt (tree, tree); +extern void finish_range_for_decl (tree, tree, tree); +extern void finish_range_for_stmt (tree); +extern tree finish_break_stmt (void); +extern tree finish_continue_stmt (void); +extern tree begin_switch_stmt (void); +extern void finish_switch_cond (tree, tree); +extern void finish_switch_stmt (tree); +extern tree finish_goto_stmt (tree); +extern tree begin_try_block (void); +extern void finish_try_block (tree); +extern void finish_handler_sequence (tree); +extern tree begin_function_try_block (tree *); +extern void finish_function_try_block (tree); +extern void finish_function_handler_sequence (tree, tree); +extern void finish_cleanup_try_block (tree); +extern tree begin_handler (void); +extern void finish_handler_parms (tree, tree); +extern void finish_handler (tree); +extern void finish_cleanup (tree, tree); +extern bool literal_type_p (tree); +extern tree register_constexpr_fundef (tree, tree); +extern bool check_constexpr_ctor_body (tree, tree); +extern tree ensure_literal_type_for_constexpr_object (tree); +extern bool potential_constant_expression (tree); +extern bool potential_rvalue_constant_expression (tree); +extern bool require_potential_constant_expression (tree); +extern bool require_potential_rvalue_constant_expression (tree); +extern tree cxx_constant_value (tree); +extern tree maybe_constant_value (tree); +extern tree maybe_constant_init (tree); +extern bool is_sub_constant_expr (tree); +extern bool reduced_constant_expression_p (tree); +extern void explain_invalid_constexpr_fn (tree); +extern vec cx_error_context (void); + +enum { + BCS_NO_SCOPE = 1, + BCS_TRY_BLOCK = 2, + BCS_FN_BODY = 4 +}; +extern tree begin_compound_stmt (unsigned int); + +extern void finish_compound_stmt (tree); +extern tree finish_asm_stmt (int, tree, tree, tree, tree, + tree); +extern tree finish_label_stmt (tree); +extern void finish_label_decl (tree); +extern tree finish_parenthesized_expr (tree); +extern tree finish_non_static_data_member (tree, tree, tree); +extern tree begin_stmt_expr (void); +extern tree finish_stmt_expr_expr (tree, tree); +extern tree finish_stmt_expr (tree, bool); +extern tree stmt_expr_value_expr (tree); +bool empty_expr_stmt_p (tree); +extern tree perform_koenig_lookup (tree, vec *, bool, + tsubst_flags_t); +extern tree finish_call_expr (tree, vec **, bool, + bool, tsubst_flags_t); +extern tree finish_increment_expr (tree, enum tree_code); +extern tree finish_this_expr (void); +extern tree finish_pseudo_destructor_expr (tree, tree, tree); +extern tree finish_unary_op_expr (location_t, enum tree_code, tree, + tsubst_flags_t); +extern tree finish_compound_literal (tree, tree, tsubst_flags_t); +extern tree finish_fname (tree); +extern void finish_translation_unit (void); +extern tree finish_template_type_parm (tree, tree); +extern tree finish_template_template_parm (tree, tree); +extern tree begin_class_definition (tree); +extern void finish_template_decl (tree); +extern tree finish_template_type (tree, tree, int); +extern tree finish_base_specifier (tree, tree, bool); +extern void finish_member_declaration (tree); +extern tree finish_id_expression (tree, tree, tree, + cp_id_kind *, + bool, bool, bool *, + bool, bool, bool, bool, + const char **, + location_t); +extern tree finish_typeof (tree); +extern tree finish_underlying_type (tree); +extern tree calculate_bases (tree); +extern tree finish_bases (tree, bool); +extern tree calculate_direct_bases (tree); +extern tree finish_offsetof (tree); +extern void finish_decl_cleanup (tree, tree); +extern void finish_eh_cleanup (tree); +extern void emit_associated_thunks (tree); +extern void finish_mem_initializers (tree); +extern tree check_template_template_default_arg (tree); +extern bool expand_or_defer_fn_1 (tree); +extern void expand_or_defer_fn (tree); +extern void add_typedef_to_current_template_for_access_check (tree, tree, + location_t); +extern void check_accessibility_of_qualified_id (tree, tree, tree); +extern tree finish_qualified_id_expr (tree, tree, bool, bool, + bool, bool, tsubst_flags_t); +extern void simplify_aggr_init_expr (tree *); +extern void finalize_nrv (tree *, tree, tree); +extern void note_decl_for_pch (tree); +extern tree finish_omp_clauses (tree); +extern void finish_omp_threadprivate (tree); +extern tree begin_omp_structured_block (void); +extern tree finish_omp_structured_block (tree); +extern tree begin_omp_parallel (void); +extern tree finish_omp_parallel (tree, tree); +extern tree begin_omp_task (void); +extern tree finish_omp_task (tree, tree); +extern tree finish_omp_for (location_t, tree, tree, + tree, tree, tree, tree, tree); +extern void finish_omp_atomic (enum tree_code, enum tree_code, + tree, tree, tree, tree, tree); +extern void finish_omp_barrier (void); +extern void finish_omp_flush (void); +extern void finish_omp_taskwait (void); +extern tree begin_transaction_stmt (location_t, tree *, int); +extern void finish_transaction_stmt (tree, tree, int, tree); +extern tree build_transaction_expr (location_t, tree, int, tree); +extern void finish_omp_taskyield (void); +extern bool cxx_omp_create_clause_info (tree, tree, bool, bool, bool); +extern tree baselink_for_fns (tree); +extern void finish_static_assert (tree, tree, location_t, + bool); +extern tree finish_decltype_type (tree, bool, tsubst_flags_t); +extern tree finish_trait_expr (enum cp_trait_kind, tree, tree); +extern tree build_lambda_expr (void); +extern tree build_lambda_object (tree); +extern tree begin_lambda_type (tree); +extern tree lambda_capture_field_type (tree); +extern tree lambda_return_type (tree); +extern tree lambda_proxy_type (tree); +extern tree lambda_function (tree); +extern void apply_deduced_return_type (tree, tree); +extern tree add_capture (tree, tree, tree, bool, bool); +extern tree add_default_capture (tree, tree, tree); +extern tree build_capture_proxy (tree); +extern void insert_capture_proxy (tree); +extern void insert_pending_capture_proxies (void); +extern bool is_capture_proxy (tree); +extern bool is_normal_capture_proxy (tree); +extern void register_capture_members (tree); +extern tree lambda_expr_this_capture (tree); +extern tree maybe_resolve_dummy (tree); +extern tree nonlambda_method_basetype (void); +extern void maybe_add_lambda_conv_op (tree); +extern bool is_lambda_ignored_entity (tree); + +/* in tree.c */ +extern int cp_tree_operand_length (const_tree); +void cp_free_lang_data (tree t); +extern tree force_target_expr (tree, tree, tsubst_flags_t); +extern tree build_target_expr_with_type (tree, tree, tsubst_flags_t); +extern void lang_check_failed (const char *, int, + const char *) ATTRIBUTE_NORETURN; +extern tree stabilize_expr (tree, tree *); +extern void stabilize_call (tree, tree *); +extern bool stabilize_init (tree, tree *); +extern tree add_stmt_to_compound (tree, tree); +extern void init_tree (void); +extern bool pod_type_p (const_tree); +extern bool layout_pod_type_p (const_tree); +extern bool std_layout_type_p (const_tree); +extern bool trivial_type_p (const_tree); +extern bool trivially_copyable_p (const_tree); +extern bool scalarish_type_p (const_tree); +extern bool type_has_nontrivial_default_init (const_tree); +extern bool type_has_nontrivial_copy_init (const_tree); +extern bool class_tmpl_impl_spec_p (const_tree); +extern int zero_init_p (const_tree); +extern bool check_abi_tag_redeclaration (const_tree, const_tree, const_tree); +extern tree strip_typedefs (tree); +extern tree strip_typedefs_expr (tree); +extern tree copy_binfo (tree, tree, tree, + tree *, int); +extern int member_p (const_tree); +extern cp_lvalue_kind real_lvalue_p (const_tree); +extern cp_lvalue_kind lvalue_kind (const_tree); +extern bool lvalue_or_rvalue_with_address_p (const_tree); +extern bool xvalue_p (const_tree); +extern bool builtin_valid_in_constant_expr_p (const_tree); +extern tree build_min (enum tree_code, tree, ...); +extern tree build_min_nt_loc (location_t, enum tree_code, + ...); +extern tree build_min_non_dep (enum tree_code, tree, ...); +extern tree build_min_non_dep_call_vec (tree, tree, vec *); +extern tree build_cplus_new (tree, tree, tsubst_flags_t); +extern tree build_aggr_init_expr (tree, tree); +extern tree get_target_expr (tree); +extern tree get_target_expr_sfinae (tree, tsubst_flags_t); +extern tree build_cplus_array_type (tree, tree); +extern tree build_array_of_n_type (tree, int); +extern tree build_array_copy (tree); +extern tree build_vec_init_expr (tree, tree, tsubst_flags_t); +extern void diagnose_non_constexpr_vec_init (tree); +extern tree hash_tree_cons (tree, tree, tree); +extern tree hash_tree_chain (tree, tree); +extern tree build_qualified_name (tree, tree, tree, bool); +extern tree build_ref_qualified_type (tree, cp_ref_qualifier); +extern int is_overloaded_fn (tree); +extern tree dependent_name (tree); +extern tree get_fns (tree); +extern tree get_first_fn (tree); +extern tree ovl_cons (tree, tree); +extern tree build_overload (tree, tree); +extern tree ovl_scope (tree); +extern bool non_static_member_function_p (tree); +extern const char *cxx_printable_name (tree, int); +extern const char *cxx_printable_name_translate (tree, int); +extern tree build_exception_variant (tree, tree); +extern tree bind_template_template_parm (tree, tree); +extern tree array_type_nelts_total (tree); +extern tree array_type_nelts_top (tree); +extern tree break_out_target_exprs (tree); +extern tree get_type_decl (tree); +extern tree decl_namespace_context (tree); +extern bool decl_anon_ns_mem_p (const_tree); +extern tree lvalue_type (tree); +extern tree error_type (tree); +extern int varargs_function_p (const_tree); +extern bool really_overloaded_fn (tree); +extern bool cp_tree_equal (tree, tree); +extern tree no_linkage_check (tree, bool); +extern void debug_binfo (tree); +extern tree build_dummy_object (tree); +extern tree maybe_dummy_object (tree, tree *); +extern int is_dummy_object (const_tree); +extern const struct attribute_spec cxx_attribute_table[]; +extern tree make_ptrmem_cst (tree, tree); +extern tree cp_build_type_attribute_variant (tree, tree); +extern tree cp_build_reference_type (tree, bool); +extern tree move (tree); +extern tree cp_build_qualified_type_real (tree, int, tsubst_flags_t); +#define cp_build_qualified_type(TYPE, QUALS) \ + cp_build_qualified_type_real ((TYPE), (QUALS), tf_warning_or_error) +extern bool cv_qualified_p (const_tree); +extern tree cv_unqualified (tree); +extern special_function_kind special_function_p (const_tree); +extern int count_trees (tree); +extern int char_type_p (tree); +extern void verify_stmt_tree (tree); +extern linkage_kind decl_linkage (tree); +extern duration_kind decl_storage_duration (tree); +extern tree cp_walk_subtrees (tree*, int*, walk_tree_fn, + void*, struct pointer_set_t*); +#define cp_walk_tree(tp,func,data,pset) \ + walk_tree_1 (tp, func, data, pset, cp_walk_subtrees) +#define cp_walk_tree_without_duplicates(tp,func,data) \ + walk_tree_without_duplicates_1 (tp, func, data, cp_walk_subtrees) +extern tree fold_if_not_in_template (tree); +extern tree rvalue (tree); +extern tree convert_bitfield_to_declared_type (tree); +extern tree cp_save_expr (tree); +extern bool cast_valid_in_integral_constant_expression_p (tree); +extern bool cxx_type_hash_eq (const_tree, const_tree); + +extern void cxx_print_statistics (void); +extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t); + +/* in ptree.c */ +extern void cxx_print_xnode (FILE *, tree, int); +extern void cxx_print_decl (FILE *, tree, int); +extern void cxx_print_type (FILE *, tree, int); +extern void cxx_print_identifier (FILE *, tree, int); +extern void cxx_print_error_function (diagnostic_context *, + const char *, + struct diagnostic_info *); + +/* in typeck.c */ +extern bool cxx_mark_addressable (tree); +extern int string_conv_p (const_tree, const_tree, int); +extern tree cp_truthvalue_conversion (tree); +extern tree condition_conversion (tree); +extern tree require_complete_type (tree); +extern tree require_complete_type_sfinae (tree, tsubst_flags_t); +extern tree complete_type (tree); +extern tree complete_type_or_else (tree, tree); +extern tree complete_type_or_maybe_complain (tree, tree, tsubst_flags_t); +extern int type_unknown_p (const_tree); +enum { ce_derived, ce_normal, ce_exact }; +extern bool comp_except_specs (const_tree, const_tree, int); +extern bool comptypes (tree, tree, int); +extern bool same_type_ignoring_top_level_qualifiers_p (tree, tree); +extern bool compparms (const_tree, const_tree); +extern int comp_cv_qualification (const_tree, const_tree); +extern int comp_cv_qual_signature (tree, tree); +extern tree cxx_sizeof_or_alignof_expr (tree, enum tree_code, bool); +extern tree cxx_sizeof_or_alignof_type (tree, enum tree_code, bool); +extern tree cxx_alignas_expr (tree); +extern tree cxx_sizeof_nowarn (tree); +extern tree is_bitfield_expr_with_lowered_type (const_tree); +extern tree unlowered_expr_type (const_tree); +extern tree decay_conversion (tree, tsubst_flags_t); +extern tree build_class_member_access_expr (tree, tree, tree, bool, + tsubst_flags_t); +extern tree finish_class_member_access_expr (tree, tree, bool, + tsubst_flags_t); +extern tree build_x_indirect_ref (location_t, tree, + ref_operator, tsubst_flags_t); +extern tree cp_build_indirect_ref (tree, ref_operator, + tsubst_flags_t); +extern tree build_array_ref (location_t, tree, tree); +extern tree cp_build_array_ref (location_t, tree, tree, + tsubst_flags_t); +extern tree get_member_function_from_ptrfunc (tree *, tree, tsubst_flags_t); +extern tree cp_build_function_call (tree, tree, tsubst_flags_t); +extern tree cp_build_function_call_nary (tree, tsubst_flags_t, ...) + ATTRIBUTE_SENTINEL; +extern tree cp_build_function_call_vec (tree, vec **, + tsubst_flags_t); +extern tree build_x_binary_op (location_t, + enum tree_code, tree, + enum tree_code, tree, + enum tree_code, tree *, + tsubst_flags_t); +extern tree build_x_array_ref (location_t, tree, tree, + tsubst_flags_t); +extern tree build_x_unary_op (location_t, + enum tree_code, tree, + tsubst_flags_t); +extern tree cp_build_addr_expr (tree, tsubst_flags_t); +extern tree cp_build_addr_expr_strict (tree, tsubst_flags_t); +extern tree cp_build_unary_op (enum tree_code, tree, int, + tsubst_flags_t); +extern tree unary_complex_lvalue (enum tree_code, tree); +extern tree build_x_conditional_expr (location_t, tree, tree, tree, + tsubst_flags_t); +extern tree build_x_compound_expr_from_list (tree, expr_list_kind, + tsubst_flags_t); +extern tree build_x_compound_expr_from_vec (vec *, + const char *, tsubst_flags_t); +extern tree build_x_compound_expr (location_t, tree, tree, + tsubst_flags_t); +extern tree build_compound_expr (location_t, tree, tree); +extern tree cp_build_compound_expr (tree, tree, tsubst_flags_t); +extern tree build_static_cast (tree, tree, tsubst_flags_t); +extern tree build_reinterpret_cast (tree, tree, tsubst_flags_t); +extern tree build_const_cast (tree, tree, tsubst_flags_t); +extern tree build_c_cast (location_t, tree, tree); +extern tree cp_build_c_cast (tree, tree, tsubst_flags_t); +extern tree build_x_modify_expr (location_t, tree, + enum tree_code, tree, + tsubst_flags_t); +extern tree cp_build_modify_expr (tree, enum tree_code, tree, + tsubst_flags_t); +extern tree convert_for_initialization (tree, tree, tree, int, + impl_conv_rhs, tree, int, + tsubst_flags_t); +extern int comp_ptr_ttypes (tree, tree); +extern bool comp_ptr_ttypes_const (tree, tree); +extern bool error_type_p (const_tree); +extern int ptr_reasonably_similar (const_tree, const_tree); +extern tree build_ptrmemfunc (tree, tree, int, bool, + tsubst_flags_t); +extern int cp_type_quals (const_tree); +extern int type_memfn_quals (const_tree); +extern cp_ref_qualifier type_memfn_rqual (const_tree); +extern tree apply_memfn_quals (tree, cp_cv_quals, cp_ref_qualifier); +extern bool cp_has_mutable_p (const_tree); +extern bool at_least_as_qualified_p (const_tree, const_tree); +extern void cp_apply_type_quals_to_decl (int, tree); +extern tree build_ptrmemfunc1 (tree, tree, tree); +extern void expand_ptrmemfunc_cst (tree, tree *, tree *); +extern tree type_after_usual_arithmetic_conversions (tree, tree); +extern tree common_pointer_type (tree, tree); +extern tree composite_pointer_type (tree, tree, tree, tree, + composite_pointer_operation, + tsubst_flags_t); +extern tree merge_types (tree, tree); +extern tree strip_array_domain (tree); +extern tree check_return_expr (tree, bool *); +extern tree cp_build_binary_op (location_t, + enum tree_code, tree, tree, + tsubst_flags_t); +#define cxx_sizeof(T) cxx_sizeof_or_alignof_type (T, SIZEOF_EXPR, true) +extern tree build_ptrmemfunc_access_expr (tree, tree); +extern tree build_address (tree); +extern tree build_typed_address (tree, tree); +extern tree build_nop (tree, tree); +extern tree non_reference (tree); +extern tree lookup_anon_field (tree, tree); +extern bool invalid_nonstatic_memfn_p (const_tree, tsubst_flags_t); +extern tree convert_member_func_to_ptr (tree, tree, tsubst_flags_t); +extern tree convert_ptrmem (tree, tree, bool, bool, + tsubst_flags_t); +extern int lvalue_or_else (tree, enum lvalue_use, + tsubst_flags_t); +extern void check_template_keyword (tree); +extern bool check_raw_literal_operator (const_tree decl); +extern bool check_literal_operator_args (const_tree, bool *, bool *); +extern void maybe_warn_about_useless_cast (tree, tree, tsubst_flags_t); +extern tree cp_perform_integral_promotions (tree, tsubst_flags_t); + +/* in typeck2.c */ +extern void require_complete_eh_spec_types (tree, tree); +extern void cxx_incomplete_type_diagnostic (const_tree, const_tree, diagnostic_t); +#undef cxx_incomplete_type_error +extern void cxx_incomplete_type_error (const_tree, const_tree); +#define cxx_incomplete_type_error(V,T) \ + (cxx_incomplete_type_diagnostic ((V), (T), DK_ERROR)) +extern tree error_not_base_type (tree, tree); +extern tree binfo_or_else (tree, tree); +extern void cxx_readonly_error (tree, enum lvalue_use); +extern void complete_type_check_abstract (tree); +extern int abstract_virtuals_error (tree, tree); +extern int abstract_virtuals_error_sfinae (tree, tree, tsubst_flags_t); + +extern tree store_init_value (tree, tree, vec**, int); +extern void check_narrowing (tree, tree); +extern tree digest_init (tree, tree, tsubst_flags_t); +extern tree digest_init_flags (tree, tree, int); +extern tree build_scoped_ref (tree, tree, tree *); +extern tree build_x_arrow (location_t, tree, + tsubst_flags_t); +extern tree build_m_component_ref (tree, tree, tsubst_flags_t); +extern tree build_functional_cast (tree, tree, tsubst_flags_t); +extern tree add_exception_specifier (tree, tree, int); +extern tree merge_exception_specifiers (tree, tree, tree); + +/* in mangle.c */ +extern void init_mangle (void); +extern void mangle_decl (tree); +extern const char *mangle_type_string (tree); +extern tree mangle_typeinfo_for_type (tree); +extern tree mangle_typeinfo_string_for_type (tree); +extern tree mangle_vtbl_for_type (tree); +extern tree mangle_vtt_for_type (tree); +extern tree mangle_ctor_vtbl_for_type (tree, tree); +extern tree mangle_thunk (tree, int, tree, tree); +extern tree mangle_conv_op_name_for_type (tree); +extern tree mangle_guard_variable (tree); +extern tree mangle_tls_init_fn (tree); +extern tree mangle_tls_wrapper_fn (tree); +extern bool decl_tls_wrapper_p (tree); +extern tree mangle_ref_init_variable (tree); + +/* in dump.c */ +extern bool cp_dump_tree (void *, tree); + +/* In cp/cp-objcp-common.c. */ + +extern alias_set_type cxx_get_alias_set (tree); +extern bool cxx_warn_unused_global_decl (const_tree); +extern size_t cp_tree_size (enum tree_code); +extern bool cp_var_mod_type_p (tree, tree); +extern void cxx_initialize_diagnostics (diagnostic_context *); +extern int cxx_types_compatible_p (tree, tree); +extern void init_shadowed_var_for_decl (void); +extern bool cxx_block_may_fallthru (const_tree); + +/* in cp-gimplify.c */ +extern int cp_gimplify_expr (tree *, gimple_seq *, + gimple_seq *); +extern void cp_genericize (tree); +extern bool cxx_omp_const_qual_no_mutable (tree); +extern enum omp_clause_default_kind cxx_omp_predetermined_sharing (tree); +extern tree cxx_omp_clause_default_ctor (tree, tree, tree); +extern tree cxx_omp_clause_copy_ctor (tree, tree, tree); +extern tree cxx_omp_clause_assign_op (tree, tree, tree); +extern tree cxx_omp_clause_dtor (tree, tree); +extern void cxx_omp_finish_clause (tree); +extern bool cxx_omp_privatize_by_reference (const_tree); + +/* in name-lookup.c */ +extern void suggest_alternatives_for (location_t, tree); +extern tree strip_using_decl (tree); + +/* -- end of C++ */ + +#endif /* ! GCC_CP_TREE_H */ diff --git a/src/include/cp/cxx-pretty-print.h b/src/include/cp/cxx-pretty-print.h new file mode 100644 index 0000000..f1ab0e6 --- /dev/null +++ b/src/include/cp/cxx-pretty-print.h @@ -0,0 +1,79 @@ +/* Interface for the GNU C++ pretty-printer. + Copyright (C) 2003-2013 Free Software Foundation, Inc. + Contributed by Gabriel Dos Reis + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_CXX_PRETTY_PRINT_H +#define GCC_CXX_PRETTY_PRINT_H + +#include "c-family/c-pretty-print.h" + +#undef pp_c_base +#define pp_c_base(PP) (&(PP)->c_base) + +typedef enum +{ + /* Ask for a qualified-id. */ + pp_cxx_flag_default_argument = 1 << pp_c_flag_last_bit + +} cxx_pretty_printer_flags; + +typedef struct +{ + c_pretty_printer c_base; + /* This is the enclosing scope of the entity being pretty-printed. */ + tree enclosing_scope; +} cxx_pretty_printer; + +#define pp_cxx_cv_qualifier_seq(PP, T) \ + pp_c_type_qualifier_list (pp_c_base (PP), T) + +#define pp_cxx_whitespace(PP) pp_c_whitespace (pp_c_base (PP)) +#define pp_cxx_left_paren(PP) pp_c_left_paren (pp_c_base (PP)) +#define pp_cxx_right_paren(PP) pp_c_right_paren (pp_c_base (PP)) +#define pp_cxx_left_brace(PP) pp_c_left_brace (pp_c_base (PP)) +#define pp_cxx_right_brace(PP) pp_c_right_brace (pp_c_base (PP)) +#define pp_cxx_left_bracket(PP) pp_c_left_bracket (pp_c_base (PP)) +#define pp_cxx_right_bracket(PP) pp_c_right_bracket (pp_c_base (PP)) +#define pp_cxx_dot(PP) pp_c_dot (pp_c_base (PP)) +#define pp_cxx_ampersand(PP) pp_c_ampersand (pp_c_base (PP)) +#define pp_cxx_star(PP) pp_c_star (pp_c_base (PP)) +#define pp_cxx_arrow(PP) pp_c_arrow (pp_c_base (PP)) +#define pp_cxx_semicolon(PP) pp_c_semicolon (pp_c_base (PP)) +#define pp_cxx_complement(PP) pp_c_complement (pp_c_base (PP)) + +#define pp_cxx_ws_string(PP, I) pp_c_ws_string (pp_c_base (PP), I) +#define pp_cxx_identifier(PP, I) pp_c_identifier (pp_c_base (PP), I) +#define pp_cxx_tree_identifier(PP, T) \ + pp_c_tree_identifier (pp_c_base (PP), T) + +void pp_cxx_pretty_printer_init (cxx_pretty_printer *); +void pp_cxx_begin_template_argument_list (cxx_pretty_printer *); +void pp_cxx_end_template_argument_list (cxx_pretty_printer *); +void pp_cxx_colon_colon (cxx_pretty_printer *); +void pp_cxx_separate_with (cxx_pretty_printer *, int); + +void pp_cxx_declaration (cxx_pretty_printer *, tree); +void pp_cxx_canonical_template_parameter (cxx_pretty_printer *, tree); +void pp_cxx_trait_expression (cxx_pretty_printer *, tree); +void pp_cxx_va_arg_expression (cxx_pretty_printer *, tree); +void pp_cxx_offsetof_expression (cxx_pretty_printer *, tree); +void pp_cxx_userdef_literal (cxx_pretty_printer *, tree); + + +#endif /* GCC_CXX_PRETTY_PRINT_H */ diff --git a/src/include/cp/name-lookup.h b/src/include/cp/name-lookup.h new file mode 100644 index 0000000..b88ada3 --- /dev/null +++ b/src/include/cp/name-lookup.h @@ -0,0 +1,369 @@ +/* Declarations for C++ name lookup routines. + Copyright (C) 2003-2013 Free Software Foundation, Inc. + Contributed by Gabriel Dos Reis + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_CP_NAME_LOOKUP_H +#define GCC_CP_NAME_LOOKUP_H + +#include "c-family/c-common.h" + +/* The type of dictionary used to map names to types declared at + a given scope. */ +typedef struct binding_table_s *binding_table; +typedef struct binding_entry_s *binding_entry; + +/* The type of a routine repeatedly called by binding_table_foreach. */ +typedef void (*bt_foreach_proc) (binding_entry, void *); + +struct GTY(()) binding_entry_s { + binding_entry chain; + tree name; + tree type; +}; + +/* These macros indicate the initial chains count for binding_table. */ +#define SCOPE_DEFAULT_HT_SIZE (1 << 3) +#define CLASS_SCOPE_HT_SIZE (1 << 3) +#define NAMESPACE_ORDINARY_HT_SIZE (1 << 5) +#define NAMESPACE_STD_HT_SIZE (1 << 8) +#define GLOBAL_SCOPE_HT_SIZE (1 << 8) + +extern void binding_table_foreach (binding_table, bt_foreach_proc, void *); +extern binding_entry binding_table_find (binding_table, tree); + +/* Datatype that represents binding established by a declaration between + a name and a C++ entity. */ +typedef struct cxx_binding cxx_binding; + +/* The datatype used to implement C++ scope. */ +typedef struct cp_binding_level cp_binding_level; + +/* Nonzero if this binding is for a local scope, as opposed to a class + or namespace scope. */ +#define LOCAL_BINDING_P(NODE) ((NODE)->is_local) + +/* True if NODE->value is from a base class of the class which is + currently being defined. */ +#define INHERITED_VALUE_BINDING_P(NODE) ((NODE)->value_is_inherited) + +struct GTY(()) cxx_binding { + /* Link to chain together various bindings for this name. */ + cxx_binding *previous; + /* The non-type entity this name is bound to. */ + tree value; + /* The type entity this name is bound to. */ + tree type; + /* The scope at which this binding was made. */ + cp_binding_level *scope; + unsigned value_is_inherited : 1; + unsigned is_local : 1; +}; + +/* Datatype used to temporarily save C++ bindings (for implicit + instantiations purposes and like). Implemented in decl.c. */ +typedef struct GTY(()) cxx_saved_binding { + /* The name of the current binding. */ + tree identifier; + /* The binding we're saving. */ + cxx_binding *binding; + tree real_type_value; +} cxx_saved_binding; + + +extern tree identifier_type_value (tree); +extern void set_identifier_type_value (tree, tree); +extern void pop_binding (tree, tree); +extern tree constructor_name (tree); +extern bool constructor_name_p (tree, tree); + +/* The kinds of scopes we recognize. */ +typedef enum scope_kind { + sk_block = 0, /* An ordinary block scope. This enumerator must + have the value zero because "cp_binding_level" + is initialized by using "memset" to set the + contents to zero, and the default scope kind + is "sk_block". */ + sk_cleanup, /* A scope for (pseudo-)scope for cleanup. It is + pseudo in that it is transparent to name lookup + activities. */ + sk_try, /* A try-block. */ + sk_catch, /* A catch-block. */ + sk_for, /* The scope of the variable declared in a + for-init-statement. */ + sk_cond, /* The scope of the variable declared in the condition + of an if or switch statement. */ + sk_function_parms, /* The scope containing function parameters. */ + sk_class, /* The scope containing the members of a class. */ + sk_scoped_enum, /* The scope containing the enumertors of a C++0x + scoped enumeration. */ + sk_namespace, /* The scope containing the members of a + namespace, including the global scope. */ + sk_template_parms, /* A scope for template parameters. */ + sk_template_spec, /* Like sk_template_parms, but for an explicit + specialization. Since, by definition, an + explicit specialization is introduced by + "template <>", this scope is always empty. */ + sk_omp /* An OpenMP structured block. */ +} scope_kind; + +/* The scope where the class/struct/union/enum tag applies. */ +typedef enum tag_scope { + ts_current = 0, /* Current scope only. This is for the + class-key identifier; + case mentioned in [basic.lookup.elab]/2, + or the class/enum definition + class-key identifier { ... }; */ + ts_global = 1, /* All scopes. This is the 3.4.1 + [basic.lookup.unqual] lookup mentioned + in [basic.lookup.elab]/2. */ + ts_within_enclosing_non_class = 2, /* Search within enclosing non-class + only, for friend class lookup + according to [namespace.memdef]/3 + and [class.friend]/9. */ + ts_lambda = 3 /* Declaring a lambda closure. */ +} tag_scope; + +typedef struct GTY(()) cp_class_binding { + cxx_binding *base; + /* The bound name. */ + tree identifier; +} cp_class_binding; + + +typedef struct GTY(()) cp_label_binding { + /* The bound LABEL_DECL. */ + tree label; + /* The previous IDENTIFIER_LABEL_VALUE. */ + tree prev_value; +} cp_label_binding; + + +/* For each binding contour we allocate a binding_level structure + which records the names defined in that contour. + Contours include: + 0) the global one + 1) one for each function definition, + where internal declarations of the parameters appear. + 2) one for each compound statement, + to record its declarations. + + The current meaning of a name can be found by searching the levels + from the current one out to the global one. + + Off to the side, may be the class_binding_level. This exists only + to catch class-local declarations. It is otherwise nonexistent. + + Also there may be binding levels that catch cleanups that must be + run when exceptions occur. Thus, to see whether a name is bound in + the current scope, it is not enough to look in the + CURRENT_BINDING_LEVEL. You should use lookup_name_current_level + instead. */ + +/* Note that the information in the `names' component of the global contour + is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */ + +struct GTY(()) cp_binding_level { + /* A chain of _DECL nodes for all variables, constants, functions, + and typedef types. These are in the reverse of the order + supplied. There may be OVERLOADs on this list, too, but they + are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */ + tree names; + + /* A chain of NAMESPACE_DECL nodes. */ + tree namespaces; + + /* An array of static functions and variables (for namespaces only) */ + vec *static_decls; + + /* A list of USING_DECL nodes. */ + tree usings; + + /* A list of used namespaces. PURPOSE is the namespace, + VALUE the common ancestor with this binding_level's namespace. */ + tree using_directives; + + /* For the binding level corresponding to a class, the entities + declared in the class or its base classes. */ + vec *class_shadowed; + + /* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and + is used for all binding levels. The TREE_PURPOSE is the name of + the entity, the TREE_TYPE is the associated type. In addition + the TREE_VALUE is the IDENTIFIER_TYPE_VALUE before we entered + the class. */ + tree type_shadowed; + + /* Similar to class_shadowed, but for IDENTIFIER_LABEL_VALUE, and + used for all binding levels. */ + vec *shadowed_labels; + + /* For each level (except not the global one), + a chain of BLOCK nodes for all the levels + that were entered and exited one level down. */ + tree blocks; + + /* The entity (namespace, class, function) the scope of which this + binding contour corresponds to. Otherwise NULL. */ + tree this_entity; + + /* The binding level which this one is contained in (inherits from). */ + cp_binding_level *level_chain; + + /* List of VAR_DECLS saved from a previous for statement. + These would be dead in ISO-conforming code, but might + be referenced in ARM-era code. */ + vec *dead_vars_from_for; + + /* STATEMENT_LIST for statements in this binding contour. + Only used at present for SK_CLEANUP temporary bindings. */ + tree statement_list; + + /* Binding depth at which this level began. */ + int binding_depth; + + /* The kind of scope that this object represents. However, a + SK_TEMPLATE_SPEC scope is represented with KIND set to + SK_TEMPLATE_PARMS and EXPLICIT_SPEC_P set to true. */ + ENUM_BITFIELD (scope_kind) kind : 4; + + /* True if this scope is an SK_TEMPLATE_SPEC scope. This field is + only valid if KIND == SK_TEMPLATE_PARMS. */ + BOOL_BITFIELD explicit_spec_p : 1; + + /* true means make a BLOCK for this level regardless of all else. */ + unsigned keep : 1; + + /* Nonzero if this level can safely have additional + cleanup-needing variables added to it. */ + unsigned more_cleanups_ok : 1; + unsigned have_cleanups : 1; + + /* 24 bits left to fill a 32-bit word. */ +}; + +/* The binding level currently in effect. */ + +#define current_binding_level \ + (*(cfun && cp_function_chain && cp_function_chain->bindings \ + ? &cp_function_chain->bindings \ + : &scope_chain->bindings)) + +/* The binding level of the current class, if any. */ + +#define class_binding_level scope_chain->class_bindings + +/* The tree node representing the global scope. */ +extern GTY(()) tree global_namespace; +extern GTY(()) tree global_scope_name; + +/* Indicates that there is a type value in some namespace, although + that is not necessarily in scope at the moment. */ + +extern GTY(()) tree global_type_node; + +/* True if SCOPE designates the global scope binding contour. */ +#define global_scope_p(SCOPE) \ + ((SCOPE) == NAMESPACE_LEVEL (global_namespace)) + +extern cp_binding_level *leave_scope (void); +extern bool kept_level_p (void); +extern bool global_bindings_p (void); +extern bool toplevel_bindings_p (void); +extern bool namespace_bindings_p (void); +extern bool local_bindings_p (void); +extern bool template_parm_scope_p (void); +extern scope_kind innermost_scope_kind (void); +extern cp_binding_level *begin_scope (scope_kind, tree); +extern void print_binding_stack (void); +extern void push_to_top_level (void); +extern void pop_from_top_level (void); +extern void pop_everything (void); +extern void keep_next_level (bool); +extern bool is_ancestor (tree, tree); +extern tree push_scope (tree); +extern void pop_scope (tree); +extern tree push_inner_scope (tree); +extern void pop_inner_scope (tree, tree); +extern void push_binding_level (cp_binding_level *); + +extern void push_namespace (tree); +extern void pop_namespace (void); +extern void push_nested_namespace (tree); +extern void pop_nested_namespace (tree); +extern bool handle_namespace_attrs (tree, tree); +extern void pushlevel_class (void); +extern void poplevel_class (void); +extern tree pushdecl_with_scope (tree, cp_binding_level *, bool); +extern tree lookup_name_prefer_type (tree, int); +extern tree lookup_name_real (tree, int, int, bool, int, int); +extern tree lookup_type_scope (tree, tag_scope); +extern tree namespace_binding (tree, tree); +extern void set_namespace_binding (tree, tree, tree); +extern bool hidden_name_p (tree); +extern tree remove_hidden_names (tree); +extern tree lookup_qualified_name (tree, tree, bool, bool); +extern tree lookup_name_nonclass (tree); +extern tree lookup_name_innermost_nonclass_level (tree); +extern bool is_local_extern (tree); +extern tree lookup_function_nonclass (tree, vec *, bool); +extern void push_local_binding (tree, tree, int); +extern bool pushdecl_class_level (tree); +extern tree pushdecl_namespace_level (tree, bool); +extern bool push_class_level_binding (tree, tree); +extern tree getdecls (void); +extern int function_parm_depth (void); +extern tree cp_namespace_decls (tree); +extern void set_decl_namespace (tree, tree, bool); +extern void push_decl_namespace (tree); +extern void pop_decl_namespace (void); +extern void do_namespace_alias (tree, tree); +extern void do_toplevel_using_decl (tree, tree, tree); +extern void do_local_using_decl (tree, tree, tree); +extern tree do_class_using_decl (tree, tree); +extern void do_using_directive (tree); +extern tree lookup_arg_dependent (tree, tree, vec *, bool); +extern bool is_associated_namespace (tree, tree); +extern void parse_using_directive (tree, tree); +extern tree innermost_non_namespace_value (tree); +extern cxx_binding *outer_binding (tree, cxx_binding *, bool); +extern void cp_emit_debug_info_for_using (tree, tree); + +/* Set *DECL to the (non-hidden) declaration for ID at global scope, + if present and return true; otherwise return false. */ + +static inline bool +get_global_value_if_present (tree id, tree *decl) +{ + tree global_value = namespace_binding (id, global_namespace); + if (global_value) + *decl = global_value; + return global_value != NULL; +} + +/* True is the binding of IDENTIFIER at global scope names a type. */ + +static inline bool +is_typename_at_global_scope (tree id) +{ + tree global_value = namespace_binding (id, global_namespace); + + return global_value && TREE_CODE (global_value) == TYPE_DECL; +} + +#endif /* GCC_CP_NAME_LOOKUP_H */ diff --git a/src/include/cppdefault.h b/src/include/cppdefault.h new file mode 100644 index 0000000..3d52619 --- /dev/null +++ b/src/include/cppdefault.h @@ -0,0 +1,71 @@ +/* CPP Library. + Copyright (C) 1986-2013 Free Software Foundation, Inc. + Contributed by Per Bothner, 1994-95. + Based on CCCP program by Paul Rubin, June 1986 + Adapted to ANSI C, Richard Stallman, Jan 1987 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not see + . */ + +#ifndef GCC_CPPDEFAULT_H +#define GCC_CPPDEFAULT_H + +/* This is the default list of directories to search for include files. + It may be overridden by the various -I and -ixxx options. + + #include "file" looks in the same directory as the current file, + then this list. + #include just looks in this list. + + All these directories are treated as `system' include directories + (they are not subject to pedantic warnings in some cases). */ + +struct default_include +{ + const char *const fname; /* The name of the directory. */ + const char *const component; /* The component containing the directory + (see update_path in prefix.c) */ + const char cplusplus; /* Only look here if we're compiling C++. */ + const char cxx_aware; /* Includes in this directory don't need to + be wrapped in extern "C" when compiling + C++. */ + const char add_sysroot; /* FNAME should be prefixed by + cpp_SYSROOT. */ + const char multilib; /* FNAME should have appended + - the multilib path specified with -imultilib + when set to 1, + - the multiarch path specified with + -imultiarch, when set to 2. */ +}; + +extern const struct default_include cpp_include_defaults[]; +extern const char cpp_GCC_INCLUDE_DIR[]; +extern const size_t cpp_GCC_INCLUDE_DIR_len; + +/* The configure-time prefix, i.e., the value supplied as the argument + to --prefix=. */ +extern const char cpp_PREFIX[]; +/* The length of the configure-time prefix. */ +extern const size_t cpp_PREFIX_len; +/* The configure-time execution prefix. This is typically the lib/gcc + subdirectory of cpp_PREFIX. */ +extern const char cpp_EXEC_PREFIX[]; +/* The run-time execution prefix. This is typically the lib/gcc + subdirectory of the actual installation. */ +extern const char *gcc_exec_prefix; + +/* Return true if the toolchain is relocated. */ +bool cpp_relocated (void); + +#endif /* ! GCC_CPPDEFAULT_H */ diff --git a/src/include/cpplib.h b/src/include/cpplib.h new file mode 100644 index 0000000..a48ac87 --- /dev/null +++ b/src/include/cpplib.h @@ -0,0 +1,1059 @@ +/* Definitions for CPP library. + Copyright (C) 1995-2013 Free Software Foundation, Inc. + Written by Per Bothner, 1994-95. + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; see the file COPYING3. If not see +. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! */ +#ifndef LIBCPP_CPPLIB_H +#define LIBCPP_CPPLIB_H + +#include +#include "symtab.h" +#include "line-map.h" + +typedef struct cpp_reader cpp_reader; +typedef struct cpp_buffer cpp_buffer; +typedef struct cpp_options cpp_options; +typedef struct cpp_token cpp_token; +typedef struct cpp_string cpp_string; +typedef struct cpp_hashnode cpp_hashnode; +typedef struct cpp_macro cpp_macro; +typedef struct cpp_callbacks cpp_callbacks; +typedef struct cpp_dir cpp_dir; + +struct answer; +struct _cpp_file; + +/* The first three groups, apart from '=', can appear in preprocessor + expressions (+= and -= are used to indicate unary + and - resp.). + This allows a lookup table to be implemented in _cpp_parse_expr. + + The first group, to CPP_LAST_EQ, can be immediately followed by an + '='. The lexer needs operators ending in '=', like ">>=", to be in + the same order as their counterparts without the '=', like ">>". + + See the cpp_operator table optab in expr.c if you change the order or + add or remove anything in the first group. */ + +#define TTYPE_TABLE \ + OP(EQ, "=") \ + OP(NOT, "!") \ + OP(GREATER, ">") /* compare */ \ + OP(LESS, "<") \ + OP(PLUS, "+") /* math */ \ + OP(MINUS, "-") \ + OP(MULT, "*") \ + OP(DIV, "/") \ + OP(MOD, "%") \ + OP(AND, "&") /* bit ops */ \ + OP(OR, "|") \ + OP(XOR, "^") \ + OP(RSHIFT, ">>") \ + OP(LSHIFT, "<<") \ + \ + OP(COMPL, "~") \ + OP(AND_AND, "&&") /* logical */ \ + OP(OR_OR, "||") \ + OP(QUERY, "?") \ + OP(COLON, ":") \ + OP(COMMA, ",") /* grouping */ \ + OP(OPEN_PAREN, "(") \ + OP(CLOSE_PAREN, ")") \ + TK(EOF, NONE) \ + OP(EQ_EQ, "==") /* compare */ \ + OP(NOT_EQ, "!=") \ + OP(GREATER_EQ, ">=") \ + OP(LESS_EQ, "<=") \ + \ + /* These two are unary + / - in preprocessor expressions. */ \ + OP(PLUS_EQ, "+=") /* math */ \ + OP(MINUS_EQ, "-=") \ + \ + OP(MULT_EQ, "*=") \ + OP(DIV_EQ, "/=") \ + OP(MOD_EQ, "%=") \ + OP(AND_EQ, "&=") /* bit ops */ \ + OP(OR_EQ, "|=") \ + OP(XOR_EQ, "^=") \ + OP(RSHIFT_EQ, ">>=") \ + OP(LSHIFT_EQ, "<<=") \ + /* Digraphs together, beginning with CPP_FIRST_DIGRAPH. */ \ + OP(HASH, "#") /* digraphs */ \ + OP(PASTE, "##") \ + OP(OPEN_SQUARE, "[") \ + OP(CLOSE_SQUARE, "]") \ + OP(OPEN_BRACE, "{") \ + OP(CLOSE_BRACE, "}") \ + /* The remainder of the punctuation. Order is not significant. */ \ + OP(SEMICOLON, ";") /* structure */ \ + OP(ELLIPSIS, "...") \ + OP(PLUS_PLUS, "++") /* increment */ \ + OP(MINUS_MINUS, "--") \ + OP(DEREF, "->") /* accessors */ \ + OP(DOT, ".") \ + OP(SCOPE, "::") \ + OP(DEREF_STAR, "->*") \ + OP(DOT_STAR, ".*") \ + OP(ATSIGN, "@") /* used in Objective-C */ \ + \ + TK(NAME, IDENT) /* word */ \ + TK(AT_NAME, IDENT) /* @word - Objective-C */ \ + TK(NUMBER, LITERAL) /* 34_be+ta */ \ + \ + TK(CHAR, LITERAL) /* 'char' */ \ + TK(WCHAR, LITERAL) /* L'char' */ \ + TK(CHAR16, LITERAL) /* u'char' */ \ + TK(CHAR32, LITERAL) /* U'char' */ \ + TK(OTHER, LITERAL) /* stray punctuation */ \ + \ + TK(STRING, LITERAL) /* "string" */ \ + TK(WSTRING, LITERAL) /* L"string" */ \ + TK(STRING16, LITERAL) /* u"string" */ \ + TK(STRING32, LITERAL) /* U"string" */ \ + TK(UTF8STRING, LITERAL) /* u8"string" */ \ + TK(OBJC_STRING, LITERAL) /* @"string" - Objective-C */ \ + TK(HEADER_NAME, LITERAL) /* in #include */ \ + \ + TK(CHAR_USERDEF, LITERAL) /* 'char'_suffix - C++-0x */ \ + TK(WCHAR_USERDEF, LITERAL) /* L'char'_suffix - C++-0x */ \ + TK(CHAR16_USERDEF, LITERAL) /* u'char'_suffix - C++-0x */ \ + TK(CHAR32_USERDEF, LITERAL) /* U'char'_suffix - C++-0x */ \ + TK(STRING_USERDEF, LITERAL) /* "string"_suffix - C++-0x */ \ + TK(WSTRING_USERDEF, LITERAL) /* L"string"_suffix - C++-0x */ \ + TK(STRING16_USERDEF, LITERAL) /* u"string"_suffix - C++-0x */ \ + TK(STRING32_USERDEF, LITERAL) /* U"string"_suffix - C++-0x */ \ + TK(UTF8STRING_USERDEF,LITERAL) /* u8"string"_suffix - C++-0x */ \ + \ + TK(COMMENT, LITERAL) /* Only if output comments. */ \ + /* SPELL_LITERAL happens to DTRT. */ \ + TK(MACRO_ARG, NONE) /* Macro argument. */ \ + TK(PRAGMA, NONE) /* Only for deferred pragmas. */ \ + TK(PRAGMA_EOL, NONE) /* End-of-line for deferred pragmas. */ \ + TK(PADDING, NONE) /* Whitespace for -E. */ + +#define OP(e, s) CPP_ ## e, +#define TK(e, s) CPP_ ## e, +enum cpp_ttype +{ + TTYPE_TABLE + N_TTYPES, + + /* Positions in the table. */ + CPP_LAST_EQ = CPP_LSHIFT, + CPP_FIRST_DIGRAPH = CPP_HASH, + CPP_LAST_PUNCTUATOR= CPP_ATSIGN, + CPP_LAST_CPP_OP = CPP_LESS_EQ +}; +#undef OP +#undef TK + +/* C language kind, used when calling cpp_create_reader. */ +enum c_lang {CLK_GNUC89 = 0, CLK_GNUC99, CLK_GNUC11, + CLK_STDC89, CLK_STDC94, CLK_STDC99, CLK_STDC11, + CLK_GNUCXX, CLK_CXX98, CLK_GNUCXX11, CLK_CXX11, CLK_ASM}; + +/* Payload of a NUMBER, STRING, CHAR or COMMENT token. */ +struct GTY(()) cpp_string { + unsigned int len; + const unsigned char *text; +}; + +/* Flags for the cpp_token structure. */ +#define PREV_WHITE (1 << 0) /* If whitespace before this token. */ +#define DIGRAPH (1 << 1) /* If it was a digraph. */ +#define STRINGIFY_ARG (1 << 2) /* If macro argument to be stringified. */ +#define PASTE_LEFT (1 << 3) /* If on LHS of a ## operator. */ +#define NAMED_OP (1 << 4) /* C++ named operators. */ +#define NO_EXPAND (1 << 5) /* Do not macro-expand this token. */ +#define BOL (1 << 6) /* Token at beginning of line. */ +#define PURE_ZERO (1 << 7) /* Single 0 digit, used by the C++ frontend, + set in c-lex.c. */ +#define SP_DIGRAPH (1 << 8) /* # or ## token was a digraph. */ +#define SP_PREV_WHITE (1 << 9) /* If whitespace before a ## + operator, or before this token + after a # operator. */ + +/* Specify which field, if any, of the cpp_token union is used. */ + +enum cpp_token_fld_kind { + CPP_TOKEN_FLD_NODE, + CPP_TOKEN_FLD_SOURCE, + CPP_TOKEN_FLD_STR, + CPP_TOKEN_FLD_ARG_NO, + CPP_TOKEN_FLD_TOKEN_NO, + CPP_TOKEN_FLD_PRAGMA, + CPP_TOKEN_FLD_NONE +}; + +/* A macro argument in the cpp_token union. */ +struct GTY(()) cpp_macro_arg { + /* Argument number. */ + unsigned int arg_no; +}; + +/* An identifier in the cpp_token union. */ +struct GTY(()) cpp_identifier { + /* The canonical (UTF-8) spelling of the identifier. */ + cpp_hashnode * + GTY ((nested_ptr (union tree_node, + "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL", + "%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"))) + node; +}; + +/* A preprocessing token. This has been carefully packed and should + occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts. */ +struct GTY(()) cpp_token { + source_location src_loc; /* Location of first char of token. */ + ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT; /* token type */ + unsigned short flags; /* flags - see above */ + + union cpp_token_u + { + /* An identifier. */ + struct cpp_identifier GTY ((tag ("CPP_TOKEN_FLD_NODE"))) node; + + /* Inherit padding from this token. */ + cpp_token * GTY ((tag ("CPP_TOKEN_FLD_SOURCE"))) source; + + /* A string, or number. */ + struct cpp_string GTY ((tag ("CPP_TOKEN_FLD_STR"))) str; + + /* Argument no. for a CPP_MACRO_ARG. */ + struct cpp_macro_arg GTY ((tag ("CPP_TOKEN_FLD_ARG_NO"))) macro_arg; + + /* Original token no. for a CPP_PASTE (from a sequence of + consecutive paste tokens in a macro expansion). */ + unsigned int GTY ((tag ("CPP_TOKEN_FLD_TOKEN_NO"))) token_no; + + /* Caller-supplied identifier for a CPP_PRAGMA. */ + unsigned int GTY ((tag ("CPP_TOKEN_FLD_PRAGMA"))) pragma; + } GTY ((desc ("cpp_token_val_index (&%1)"))) val; +}; + +/* Say which field is in use. */ +extern enum cpp_token_fld_kind cpp_token_val_index (cpp_token *tok); + +/* A type wide enough to hold any multibyte source character. + cpplib's character constant interpreter requires an unsigned type. + Also, a typedef for the signed equivalent. + The width of this type is capped at 32 bits; there do exist targets + where wchar_t is 64 bits, but only in a non-default mode, and there + would be no meaningful interpretation for a wchar_t value greater + than 2^32 anyway -- the widest wide-character encoding around is + ISO 10646, which stops at 2^31. */ +#if CHAR_BIT * SIZEOF_INT >= 32 +# define CPPCHAR_SIGNED_T int +#elif CHAR_BIT * SIZEOF_LONG >= 32 +# define CPPCHAR_SIGNED_T long +#else +# error "Cannot find a least-32-bit signed integer type" +#endif +typedef unsigned CPPCHAR_SIGNED_T cppchar_t; +typedef CPPCHAR_SIGNED_T cppchar_signed_t; + +/* Style of header dependencies to generate. */ +enum cpp_deps_style { DEPS_NONE = 0, DEPS_USER, DEPS_SYSTEM }; + +/* The possible normalization levels, from most restrictive to least. */ +enum cpp_normalize_level { + /* In NFKC. */ + normalized_KC = 0, + /* In NFC. */ + normalized_C, + /* In NFC, except for subsequences where being in NFC would make + the identifier invalid. */ + normalized_identifier_C, + /* Not normalized at all. */ + normalized_none +}; + +/* This structure is nested inside struct cpp_reader, and + carries all the options visible to the command line. */ +struct cpp_options +{ + /* Characters between tab stops. */ + unsigned int tabstop; + + /* The language we're preprocessing. */ + enum c_lang lang; + + /* Nonzero means use extra default include directories for C++. */ + unsigned char cplusplus; + + /* Nonzero means handle cplusplus style comments. */ + unsigned char cplusplus_comments; + + /* Nonzero means define __OBJC__, treat @ as a special token, use + the OBJC[PLUS]_INCLUDE_PATH environment variable, and allow + "#import". */ + unsigned char objc; + + /* Nonzero means don't copy comments into the output file. */ + unsigned char discard_comments; + + /* Nonzero means don't copy comments into the output file during + macro expansion. */ + unsigned char discard_comments_in_macro_exp; + + /* Nonzero means process the ISO trigraph sequences. */ + unsigned char trigraphs; + + /* Nonzero means process the ISO digraph sequences. */ + unsigned char digraphs; + + /* Nonzero means to allow hexadecimal floats and LL suffixes. */ + unsigned char extended_numbers; + + /* Nonzero means process u/U prefix literals (UTF-16/32). */ + unsigned char uliterals; + + /* Nonzero means process r/R raw strings. If this is set, uliterals + must be set as well. */ + unsigned char rliterals; + + /* Nonzero means print names of header files (-H). */ + unsigned char print_include_names; + + /* Nonzero means complain about deprecated features. */ + unsigned char cpp_warn_deprecated; + + /* Nonzero means warn if slash-star appears in a comment. */ + unsigned char warn_comments; + + /* Nonzero means warn if a user-supplied include directory does not + exist. */ + unsigned char warn_missing_include_dirs; + + /* Nonzero means warn if there are any trigraphs. */ + unsigned char warn_trigraphs; + + /* Nonzero means warn about multicharacter charconsts. */ + unsigned char warn_multichar; + + /* Nonzero means warn about various incompatibilities with + traditional C. */ + unsigned char cpp_warn_traditional; + + /* Nonzero means warn about long long numeric constants. */ + unsigned char cpp_warn_long_long; + + /* Nonzero means warn about text after an #endif (or #else). */ + unsigned char warn_endif_labels; + + /* Nonzero means warn about implicit sign changes owing to integer + promotions. */ + unsigned char warn_num_sign_change; + + /* Zero means don't warn about __VA_ARGS__ usage in c89 pedantic mode. + Presumably the usage is protected by the appropriate #ifdef. */ + unsigned char warn_variadic_macros; + + /* Nonzero means warn about builtin macros that are redefined or + explicitly undefined. */ + unsigned char warn_builtin_macro_redefined; + + /* Nonzero means we should look for header.gcc files that remap file + names. */ + unsigned char remap; + + /* Zero means dollar signs are punctuation. */ + unsigned char dollars_in_ident; + + /* Nonzero means UCNs are accepted in identifiers. */ + unsigned char extended_identifiers; + + /* True if we should warn about dollars in identifiers or numbers + for this translation unit. */ + unsigned char warn_dollars; + + /* Nonzero means warn if undefined identifiers are evaluated in an #if. */ + unsigned char warn_undef; + + /* Nonzero means warn of unused macros from the main file. */ + unsigned char warn_unused_macros; + + /* Nonzero for the 1999 C Standard, including corrigenda and amendments. */ + unsigned char c99; + + /* Nonzero if we are conforming to a specific C or C++ standard. */ + unsigned char std; + + /* Nonzero means give all the error messages the ANSI standard requires. */ + unsigned char cpp_pedantic; + + /* Nonzero means we're looking at already preprocessed code, so don't + bother trying to do macro expansion and whatnot. */ + unsigned char preprocessed; + + /* Nonzero means we are going to emit debugging logs during + preprocessing. */ + unsigned char debug; + + /* Nonzero means we are tracking locations of tokens involved in + macro expansion. 1 Means we track the location in degraded mode + where we do not track locations of tokens resulting from the + expansion of arguments of function-like macro. 2 Means we do + track all macro expansions. This last option is the one that + consumes the highest amount of memory. */ + unsigned char track_macro_expansion; + + /* Nonzero means handle C++ alternate operator names. */ + unsigned char operator_names; + + /* Nonzero means warn about use of C++ alternate operator names. */ + unsigned char warn_cxx_operator_names; + + /* True for traditional preprocessing. */ + unsigned char traditional; + + /* Nonzero for C++ 2011 Standard user-defnied literals. */ + unsigned char user_literals; + + /* Nonzero means warn when a string or character literal is followed by a + ud-suffix which does not beging with an underscore. */ + unsigned char warn_literal_suffix; + + /* Nonzero means interpret imaginary, fixed-point, or other gnu extension + literal number suffixes as user-defined literal number suffixes. */ + unsigned char ext_numeric_literals; + + /* Holds the name of the target (execution) character set. */ + const char *narrow_charset; + + /* Holds the name of the target wide character set. */ + const char *wide_charset; + + /* Holds the name of the input character set. */ + const char *input_charset; + + /* The minimum permitted level of normalization before a warning + is generated. */ + enum cpp_normalize_level warn_normalize; + + /* True to warn about precompiled header files we couldn't use. */ + bool warn_invalid_pch; + + /* True if dependencies should be restored from a precompiled header. */ + bool restore_pch_deps; + + /* Dependency generation. */ + struct + { + /* Style of header dependencies to generate. */ + enum cpp_deps_style style; + + /* Assume missing files are generated files. */ + bool missing_files; + + /* Generate phony targets for each dependency apart from the first + one. */ + bool phony_targets; + + /* If true, no dependency is generated on the main file. */ + bool ignore_main_file; + + /* If true, intend to use the preprocessor output (e.g., for compilation) + in addition to the dependency info. */ + bool need_preprocessor_output; + } deps; + + /* Target-specific features set by the front end or client. */ + + /* Precision for target CPP arithmetic, target characters, target + ints and target wide characters, respectively. */ + size_t precision, char_precision, int_precision, wchar_precision; + + /* True means chars (wide chars) are unsigned. */ + bool unsigned_char, unsigned_wchar; + + /* True if the most significant byte in a word has the lowest + address in memory. */ + bool bytes_big_endian; + + /* Nonzero means __STDC__ should have the value 0 in system headers. */ + unsigned char stdc_0_in_system_headers; + + /* True disables tokenization outside of preprocessing directives. */ + bool directives_only; + + /* True enables canonicalization of system header file paths. */ + bool canonical_system_headers; +}; + +/* Callback for header lookup for HEADER, which is the name of a + source file. It is used as a method of last resort to find headers + that are not otherwise found during the normal include processing. + The return value is the malloced name of a header to try and open, + if any, or NULL otherwise. This callback is called only if the + header is otherwise unfound. */ +typedef const char *(*missing_header_cb)(cpp_reader *, const char *header, cpp_dir **); + +/* Call backs to cpplib client. */ +struct cpp_callbacks +{ + /* Called when a new line of preprocessed output is started. */ + void (*line_change) (cpp_reader *, const cpp_token *, int); + + /* Called when switching to/from a new file. + The line_map is for the new file. It is NULL if there is no new file. + (In C this happens when done with + and also + when done with a main file.) This can be used for resource cleanup. */ + void (*file_change) (cpp_reader *, const struct line_map *); + + void (*dir_change) (cpp_reader *, const char *); + void (*include) (cpp_reader *, source_location, const unsigned char *, + const char *, int, const cpp_token **); + void (*define) (cpp_reader *, source_location, cpp_hashnode *); + void (*undef) (cpp_reader *, source_location, cpp_hashnode *); + void (*ident) (cpp_reader *, source_location, const cpp_string *); + void (*def_pragma) (cpp_reader *, source_location); + int (*valid_pch) (cpp_reader *, const char *, int); + void (*read_pch) (cpp_reader *, const char *, int, const char *); + missing_header_cb missing_header; + + /* Context-sensitive macro support. Returns macro (if any) that should + be expanded. */ + cpp_hashnode * (*macro_to_expand) (cpp_reader *, const cpp_token *); + + /* Called to emit a diagnostic. This callback receives the + translated message. */ + bool (*error) (cpp_reader *, int, int, source_location, unsigned int, + const char *, va_list *) + ATTRIBUTE_FPTR_PRINTF(6,0); + + /* Callbacks for when a macro is expanded, or tested (whether + defined or not at the time) in #ifdef, #ifndef or "defined". */ + void (*used_define) (cpp_reader *, source_location, cpp_hashnode *); + void (*used_undef) (cpp_reader *, source_location, cpp_hashnode *); + /* Called before #define and #undef or other macro definition + changes are processed. */ + void (*before_define) (cpp_reader *); + /* Called whenever a macro is expanded or tested. + Second argument is the location of the start of the current expansion. */ + void (*used) (cpp_reader *, source_location, cpp_hashnode *); + + /* Callback that can change a user builtin into normal macro. */ + bool (*user_builtin_macro) (cpp_reader *, cpp_hashnode *); +}; + +#ifdef VMS +#define INO_T_CPP ino_t ino[3] +#else +#define INO_T_CPP ino_t ino +#endif + +/* Chain of directories to look for include files in. */ +struct cpp_dir +{ + /* NULL-terminated singly-linked list. */ + struct cpp_dir *next; + + /* NAME of the directory, NUL-terminated. */ + char *name; + unsigned int len; + + /* One if a system header, two if a system header that has extern + "C" guards for C++. */ + unsigned char sysp; + + /* Is this a user-supplied directory? */ + bool user_supplied_p; + + /* The canonicalized NAME as determined by lrealpath. This field + is only used by hosts that lack reliable inode numbers. */ + char *canonical_name; + + /* Mapping of file names for this directory for MS-DOS and related + platforms. A NULL-terminated array of (from, to) pairs. */ + const char **name_map; + + /* Routine to construct pathname, given the search path name and the + HEADER we are trying to find, return a constructed pathname to + try and open. If this is NULL, the constructed pathname is as + constructed by append_file_to_dir. */ + char *(*construct) (const char *header, cpp_dir *dir); + + /* The C front end uses these to recognize duplicated + directories in the search path. */ + INO_T_CPP; + dev_t dev; +}; + +/* The structure of a node in the hash table. The hash table has + entries for all identifiers: either macros defined by #define + commands (type NT_MACRO), assertions created with #assert + (NT_ASSERTION), or neither of the above (NT_VOID). Builtin macros + like __LINE__ are flagged NODE_BUILTIN. Poisoned identifiers are + flagged NODE_POISONED. NODE_OPERATOR (C++ only) indicates an + identifier that behaves like an operator such as "xor". + NODE_DIAGNOSTIC is for speed in lex_token: it indicates a + diagnostic may be required for this node. Currently this only + applies to __VA_ARGS__, poisoned identifiers, and -Wc++-compat + warnings about NODE_OPERATOR. */ + +/* Hash node flags. */ +#define NODE_OPERATOR (1 << 0) /* C++ named operator. */ +#define NODE_POISONED (1 << 1) /* Poisoned identifier. */ +#define NODE_BUILTIN (1 << 2) /* Builtin macro. */ +#define NODE_DIAGNOSTIC (1 << 3) /* Possible diagnostic when lexed. */ +#define NODE_WARN (1 << 4) /* Warn if redefined or undefined. */ +#define NODE_DISABLED (1 << 5) /* A disabled macro. */ +#define NODE_MACRO_ARG (1 << 6) /* Used during #define processing. */ +#define NODE_USED (1 << 7) /* Dumped with -dU. */ +#define NODE_CONDITIONAL (1 << 8) /* Conditional macro */ +#define NODE_WARN_OPERATOR (1 << 9) /* Warn about C++ named operator. */ + +/* Different flavors of hash node. */ +enum node_type +{ + NT_VOID = 0, /* No definition yet. */ + NT_MACRO, /* A macro of some form. */ + NT_ASSERTION /* Predicate for #assert. */ +}; + +/* Different flavors of builtin macro. _Pragma is an operator, but we + handle it with the builtin code for efficiency reasons. */ +enum cpp_builtin_type +{ + BT_SPECLINE = 0, /* `__LINE__' */ + BT_DATE, /* `__DATE__' */ + BT_FILE, /* `__FILE__' */ + BT_BASE_FILE, /* `__BASE_FILE__' */ + BT_INCLUDE_LEVEL, /* `__INCLUDE_LEVEL__' */ + BT_TIME, /* `__TIME__' */ + BT_STDC, /* `__STDC__' */ + BT_PRAGMA, /* `_Pragma' operator */ + BT_TIMESTAMP, /* `__TIMESTAMP__' */ + BT_COUNTER, /* `__COUNTER__' */ + BT_FIRST_USER, /* User defined builtin macros. */ + BT_LAST_USER = BT_FIRST_USER + 31 +}; + +#define CPP_HASHNODE(HNODE) ((cpp_hashnode *) (HNODE)) +#define HT_NODE(NODE) ((ht_identifier *) (NODE)) +#define NODE_LEN(NODE) HT_LEN (&(NODE)->ident) +#define NODE_NAME(NODE) HT_STR (&(NODE)->ident) + +/* Specify which field, if any, of the union is used. */ + +enum { + NTV_MACRO, + NTV_ANSWER, + NTV_BUILTIN, + NTV_ARGUMENT, + NTV_NONE +}; + +#define CPP_HASHNODE_VALUE_IDX(HNODE) \ + ((HNODE.flags & NODE_MACRO_ARG) ? NTV_ARGUMENT \ + : HNODE.type == NT_MACRO ? ((HNODE.flags & NODE_BUILTIN) \ + ? NTV_BUILTIN : NTV_MACRO) \ + : HNODE.type == NT_ASSERTION ? NTV_ANSWER \ + : NTV_NONE) + +/* The common part of an identifier node shared amongst all 3 C front + ends. Also used to store CPP identifiers, which are a superset of + identifiers in the grammatical sense. */ + +union GTY(()) _cpp_hashnode_value { + /* If a macro. */ + cpp_macro * GTY((tag ("NTV_MACRO"))) macro; + /* Answers to an assertion. */ + struct answer * GTY ((tag ("NTV_ANSWER"))) answers; + /* Code for a builtin macro. */ + enum cpp_builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin; + /* Macro argument index. */ + unsigned short GTY ((tag ("NTV_ARGUMENT"))) arg_index; +}; + +struct GTY(()) cpp_hashnode { + struct ht_identifier ident; + unsigned int is_directive : 1; + unsigned int directive_index : 7; /* If is_directive, + then index into directive table. + Otherwise, a NODE_OPERATOR. */ + unsigned char rid_code; /* Rid code - for front ends. */ + ENUM_BITFIELD(node_type) type : 6; /* CPP node type. */ + unsigned int flags : 10; /* CPP flags. */ + + union _cpp_hashnode_value GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value; +}; + +/* Call this first to get a handle to pass to other functions. + + If you want cpplib to manage its own hashtable, pass in a NULL + pointer. Otherwise you should pass in an initialized hash table + that cpplib will share; this technique is used by the C front + ends. */ +extern cpp_reader *cpp_create_reader (enum c_lang, struct ht *, + struct line_maps *); + +/* Reset the cpp_reader's line_map. This is only used after reading a + PCH file. */ +extern void cpp_set_line_map (cpp_reader *, struct line_maps *); + +/* Call this to change the selected language standard (e.g. because of + command line options). */ +extern void cpp_set_lang (cpp_reader *, enum c_lang); + +/* Set the include paths. */ +extern void cpp_set_include_chains (cpp_reader *, cpp_dir *, cpp_dir *, int); + +/* Call these to get pointers to the options, callback, and deps + structures for a given reader. These pointers are good until you + call cpp_finish on that reader. You can either edit the callbacks + through the pointer returned from cpp_get_callbacks, or set them + with cpp_set_callbacks. */ +extern cpp_options *cpp_get_options (cpp_reader *); +extern cpp_callbacks *cpp_get_callbacks (cpp_reader *); +extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *); +extern struct deps *cpp_get_deps (cpp_reader *); + +/* This function reads the file, but does not start preprocessing. It + returns the name of the original file; this is the same as the + input file, except for preprocessed input. This will generate at + least one file change callback, and possibly a line change callback + too. If there was an error opening the file, it returns NULL. */ +extern const char *cpp_read_main_file (cpp_reader *, const char *); + +/* Set up built-ins with special behavior. Use cpp_init_builtins() + instead unless your know what you are doing. */ +extern void cpp_init_special_builtins (cpp_reader *); + +/* Set up built-ins like __FILE__. */ +extern void cpp_init_builtins (cpp_reader *, int); + +/* This is called after options have been parsed, and partially + processed. */ +extern void cpp_post_options (cpp_reader *); + +/* Set up translation to the target character set. */ +extern void cpp_init_iconv (cpp_reader *); + +/* Call this to finish preprocessing. If you requested dependency + generation, pass an open stream to write the information to, + otherwise NULL. It is your responsibility to close the stream. */ +extern void cpp_finish (cpp_reader *, FILE *deps_stream); + +/* Call this to release the handle at the end of preprocessing. Any + use of the handle after this function returns is invalid. */ +extern void cpp_destroy (cpp_reader *); + +extern unsigned int cpp_token_len (const cpp_token *); +extern unsigned char *cpp_token_as_text (cpp_reader *, const cpp_token *); +extern unsigned char *cpp_spell_token (cpp_reader *, const cpp_token *, + unsigned char *, bool); +extern void cpp_register_pragma (cpp_reader *, const char *, const char *, + void (*) (cpp_reader *), bool); +extern void cpp_register_deferred_pragma (cpp_reader *, const char *, + const char *, unsigned, bool, bool); +extern int cpp_avoid_paste (cpp_reader *, const cpp_token *, + const cpp_token *); +extern const cpp_token *cpp_get_token (cpp_reader *); +extern const cpp_token *cpp_get_token_with_location (cpp_reader *, + source_location *); +extern const unsigned char *cpp_macro_definition (cpp_reader *, + cpp_hashnode *); +extern void _cpp_backup_tokens (cpp_reader *, unsigned int); +extern const cpp_token *cpp_peek_token (cpp_reader *, int); + +/* Evaluate a CPP_*CHAR* token. */ +extern cppchar_t cpp_interpret_charconst (cpp_reader *, const cpp_token *, + unsigned int *, int *); +/* Evaluate a vector of CPP_*STRING* tokens. */ +extern bool cpp_interpret_string (cpp_reader *, + const cpp_string *, size_t, + cpp_string *, enum cpp_ttype); +extern bool cpp_interpret_string_notranslate (cpp_reader *, + const cpp_string *, size_t, + cpp_string *, enum cpp_ttype); + +/* Convert a host character constant to the execution character set. */ +extern cppchar_t cpp_host_to_exec_charset (cpp_reader *, cppchar_t); + +/* Used to register macros and assertions, perhaps from the command line. + The text is the same as the command line argument. */ +extern void cpp_define (cpp_reader *, const char *); +extern void cpp_define_formatted (cpp_reader *pfile, + const char *fmt, ...) ATTRIBUTE_PRINTF_2; +extern void cpp_assert (cpp_reader *, const char *); +extern void cpp_undef (cpp_reader *, const char *); +extern void cpp_unassert (cpp_reader *, const char *); + +/* Undefine all macros and assertions. */ +extern void cpp_undef_all (cpp_reader *); + +extern cpp_buffer *cpp_push_buffer (cpp_reader *, const unsigned char *, + size_t, int); +extern int cpp_defined (cpp_reader *, const unsigned char *, int); + +/* A preprocessing number. Code assumes that any unused high bits of + the double integer are set to zero. */ +typedef unsigned HOST_WIDE_INT cpp_num_part; +typedef struct cpp_num cpp_num; +struct cpp_num +{ + cpp_num_part high; + cpp_num_part low; + bool unsignedp; /* True if value should be treated as unsigned. */ + bool overflow; /* True if the most recent calculation overflowed. */ +}; + +/* cpplib provides two interfaces for interpretation of preprocessing + numbers. + + cpp_classify_number categorizes numeric constants according to + their field (integer, floating point, or invalid), radix (decimal, + octal, hexadecimal), and type suffixes. */ + +#define CPP_N_CATEGORY 0x000F +#define CPP_N_INVALID 0x0000 +#define CPP_N_INTEGER 0x0001 +#define CPP_N_FLOATING 0x0002 + +#define CPP_N_WIDTH 0x00F0 +#define CPP_N_SMALL 0x0010 /* int, float, shrot _Fract/Accum */ +#define CPP_N_MEDIUM 0x0020 /* long, double, long _Fract/_Accum. */ +#define CPP_N_LARGE 0x0040 /* long long, long double, + long long _Fract/Accum. */ + +#define CPP_N_WIDTH_MD 0xF0000 /* machine defined. */ +#define CPP_N_MD_W 0x10000 +#define CPP_N_MD_Q 0x20000 + +#define CPP_N_RADIX 0x0F00 +#define CPP_N_DECIMAL 0x0100 +#define CPP_N_HEX 0x0200 +#define CPP_N_OCTAL 0x0400 +#define CPP_N_BINARY 0x0800 + +#define CPP_N_UNSIGNED 0x1000 /* Properties. */ +#define CPP_N_IMAGINARY 0x2000 +#define CPP_N_DFLOAT 0x4000 +#define CPP_N_DEFAULT 0x8000 + +#define CPP_N_FRACT 0x100000 /* Fract types. */ +#define CPP_N_ACCUM 0x200000 /* Accum types. */ + +#define CPP_N_USERDEF 0x1000000 /* C++0x user-defined literal. */ + +/* Classify a CPP_NUMBER token. The return value is a combination of + the flags from the above sets. */ +extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *, + const char **, source_location); + +/* Return the classification flags for a float suffix. */ +extern unsigned int cpp_interpret_float_suffix (cpp_reader *, const char *, + size_t); + +/* Return the classification flags for an int suffix. */ +extern unsigned int cpp_interpret_int_suffix (cpp_reader *, const char *, + size_t); + +/* Evaluate a token classified as category CPP_N_INTEGER. */ +extern cpp_num cpp_interpret_integer (cpp_reader *, const cpp_token *, + unsigned int); + +/* Sign extend a number, with PRECISION significant bits and all + others assumed clear, to fill out a cpp_num structure. */ +cpp_num cpp_num_sign_extend (cpp_num, size_t); + +/* Diagnostic levels. To get a diagnostic without associating a + position in the translation unit with it, use cpp_error_with_line + with a line number of zero. */ + +enum { + /* Warning, an error with -Werror. */ + CPP_DL_WARNING = 0, + /* Same as CPP_DL_WARNING, except it is not suppressed in system headers. */ + CPP_DL_WARNING_SYSHDR, + /* Warning, an error with -pedantic-errors or -Werror. */ + CPP_DL_PEDWARN, + /* An error. */ + CPP_DL_ERROR, + /* An internal consistency check failed. Prints "internal error: ", + otherwise the same as CPP_DL_ERROR. */ + CPP_DL_ICE, + /* An informative note following a warning. */ + CPP_DL_NOTE, + /* A fatal error. */ + CPP_DL_FATAL +}; + +/* Warning reason codes. Use a reason code of zero for unclassified warnings + and errors that are not warnings. */ +enum { + CPP_W_NONE = 0, + CPP_W_DEPRECATED, + CPP_W_COMMENTS, + CPP_W_MISSING_INCLUDE_DIRS, + CPP_W_TRIGRAPHS, + CPP_W_MULTICHAR, + CPP_W_TRADITIONAL, + CPP_W_LONG_LONG, + CPP_W_ENDIF_LABELS, + CPP_W_NUM_SIGN_CHANGE, + CPP_W_VARIADIC_MACROS, + CPP_W_BUILTIN_MACRO_REDEFINED, + CPP_W_DOLLARS, + CPP_W_UNDEF, + CPP_W_UNUSED_MACROS, + CPP_W_CXX_OPERATOR_NAMES, + CPP_W_NORMALIZE, + CPP_W_INVALID_PCH, + CPP_W_WARNING_DIRECTIVE, + CPP_W_LITERAL_SUFFIX +}; + +/* Output a diagnostic of some kind. */ +extern bool cpp_error (cpp_reader *, int, const char *msgid, ...) + ATTRIBUTE_PRINTF_3; +extern bool cpp_warning (cpp_reader *, int, const char *msgid, ...) + ATTRIBUTE_PRINTF_3; +extern bool cpp_pedwarning (cpp_reader *, int, const char *msgid, ...) + ATTRIBUTE_PRINTF_3; +extern bool cpp_warning_syshdr (cpp_reader *, int, const char *msgid, ...) + ATTRIBUTE_PRINTF_3; + +/* Output a diagnostic with "MSGID: " preceding the + error string of errno. No location is printed. */ +extern bool cpp_errno (cpp_reader *, int, const char *msgid); + +/* Same as cpp_error, except additionally specifies a position as a + (translation unit) physical line and physical column. If the line is + zero, then no location is printed. */ +extern bool cpp_error_with_line (cpp_reader *, int, source_location, + unsigned, const char *msgid, ...) + ATTRIBUTE_PRINTF_5; +extern bool cpp_warning_with_line (cpp_reader *, int, source_location, + unsigned, const char *msgid, ...) + ATTRIBUTE_PRINTF_5; +extern bool cpp_pedwarning_with_line (cpp_reader *, int, source_location, + unsigned, const char *msgid, ...) + ATTRIBUTE_PRINTF_5; +extern bool cpp_warning_with_line_syshdr (cpp_reader *, int, source_location, + unsigned, const char *msgid, ...) + ATTRIBUTE_PRINTF_5; + +/* In lex.c */ +extern int cpp_ideq (const cpp_token *, const char *); +extern void cpp_output_line (cpp_reader *, FILE *); +extern unsigned char *cpp_output_line_to_string (cpp_reader *, + const unsigned char *); +extern void cpp_output_token (const cpp_token *, FILE *); +extern const char *cpp_type2name (enum cpp_ttype, unsigned char flags); +/* Returns the value of an escape sequence, truncated to the correct + target precision. PSTR points to the input pointer, which is just + after the backslash. LIMIT is how much text we have. WIDE is true + if the escape sequence is part of a wide character constant or + string literal. Handles all relevant diagnostics. */ +extern cppchar_t cpp_parse_escape (cpp_reader *, const unsigned char ** pstr, + const unsigned char *limit, int wide); + +/* Structure used to hold a comment block at a given location in the + source code. */ + +typedef struct +{ + /* Text of the comment including the terminators. */ + char *comment; + + /* source location for the given comment. */ + source_location sloc; +} cpp_comment; + +/* Structure holding all comments for a given cpp_reader. */ + +typedef struct +{ + /* table of comment entries. */ + cpp_comment *entries; + + /* number of actual entries entered in the table. */ + int count; + + /* number of entries allocated currently. */ + int allocated; +} cpp_comment_table; + +/* Returns the table of comments encountered by the preprocessor. This + table is only populated when pfile->state.save_comments is true. */ +extern cpp_comment_table *cpp_get_comments (cpp_reader *); + +/* In hash.c */ + +/* Lookup an identifier in the hashtable. Puts the identifier in the + table if it is not already there. */ +extern cpp_hashnode *cpp_lookup (cpp_reader *, const unsigned char *, + unsigned int); + +typedef int (*cpp_cb) (cpp_reader *, cpp_hashnode *, void *); +extern void cpp_forall_identifiers (cpp_reader *, cpp_cb, void *); + +/* In macro.c */ +extern void cpp_scan_nooutput (cpp_reader *); +extern int cpp_sys_macro_p (cpp_reader *); +extern unsigned char *cpp_quote_string (unsigned char *, const unsigned char *, + unsigned int); + +/* In files.c */ +extern bool cpp_included (cpp_reader *, const char *); +extern bool cpp_included_before (cpp_reader *, const char *, source_location); +extern void cpp_make_system_header (cpp_reader *, int, int); +extern bool cpp_push_include (cpp_reader *, const char *); +extern bool cpp_push_default_include (cpp_reader *, const char *); +extern void cpp_change_file (cpp_reader *, enum lc_reason, const char *); +extern const char *cpp_get_path (struct _cpp_file *); +extern cpp_dir *cpp_get_dir (struct _cpp_file *); +extern cpp_buffer *cpp_get_buffer (cpp_reader *); +extern struct _cpp_file *cpp_get_file (cpp_buffer *); +extern cpp_buffer *cpp_get_prev (cpp_buffer *); +extern void cpp_clear_file_cache (cpp_reader *); + +/* In pch.c */ +struct save_macro_data; +extern int cpp_save_state (cpp_reader *, FILE *); +extern int cpp_write_pch_deps (cpp_reader *, FILE *); +extern int cpp_write_pch_state (cpp_reader *, FILE *); +extern int cpp_valid_state (cpp_reader *, const char *, int); +extern void cpp_prepare_state (cpp_reader *, struct save_macro_data **); +extern int cpp_read_state (cpp_reader *, const char *, FILE *, + struct save_macro_data *); + +/* In lex.c */ +extern void cpp_force_token_locations (cpp_reader *, source_location *); +extern void cpp_stop_forcing_token_locations (cpp_reader *); + +/* In expr.c */ +extern enum cpp_ttype cpp_userdef_string_remove_type + (enum cpp_ttype type); +extern enum cpp_ttype cpp_userdef_string_add_type + (enum cpp_ttype type); +extern enum cpp_ttype cpp_userdef_char_remove_type + (enum cpp_ttype type); +extern enum cpp_ttype cpp_userdef_char_add_type + (enum cpp_ttype type); +extern bool cpp_userdef_string_p + (enum cpp_ttype type); +extern bool cpp_userdef_char_p + (enum cpp_ttype type); +extern const char * cpp_get_userdef_suffix + (const cpp_token *); + +#endif /* ! LIBCPP_CPPLIB_H */ diff --git a/src/include/debug.h b/src/include/debug.h new file mode 100644 index 0000000..886de17 --- /dev/null +++ b/src/include/debug.h @@ -0,0 +1,195 @@ +/* Debug hooks for GCC. + Copyright (C) 2001-2013 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING3. If not see + . */ + +#ifndef GCC_DEBUG_H +#define GCC_DEBUG_H + +/* This structure contains hooks for the debug information output + functions, accessed through the global instance debug_hooks set in + toplev.c according to command line options. */ +struct gcc_debug_hooks +{ + /* Initialize debug output. MAIN_FILENAME is the name of the main + input file. */ + void (* init) (const char *main_filename); + + /* Output debug symbols. */ + void (* finish) (const char *main_filename); + + /* Called from cgraph_optimize before starting to assemble + functions/variables/toplevel asms. */ + void (* assembly_start) (void); + + /* Macro defined on line LINE with name and expansion TEXT. */ + void (* define) (unsigned int line, const char *text); + + /* MACRO undefined on line LINE. */ + void (* undef) (unsigned int line, const char *macro); + + /* Record the beginning of a new source file FILE from LINE number + in the previous one. */ + void (* start_source_file) (unsigned int line, const char *file); + + /* Record the resumption of a source file. LINE is the line number + in the source file we are returning to. */ + void (* end_source_file) (unsigned int line); + + /* Record the beginning of block N, counting from 1 and not + including the function-scope block, at LINE. */ + void (* begin_block) (unsigned int line, unsigned int n); + + /* Record the end of a block. Arguments as for begin_block. */ + void (* end_block) (unsigned int line, unsigned int n); + + /* Returns nonzero if it is appropriate not to emit any debugging + information for BLOCK, because it doesn't contain any + instructions. This may not be the case for blocks containing + nested functions, since we may actually call such a function even + though the BLOCK information is messed up. Defaults to true. */ + bool (* ignore_block) (const_tree); + + /* Record a source file location at (FILE, LINE, DISCRIMINATOR). */ + void (* source_line) (unsigned int line, const char *file, + int discriminator, bool is_stmt); + + /* Called at start of prologue code. LINE is the first line in the + function. */ + void (* begin_prologue) (unsigned int line, const char *file); + + /* Called at end of prologue code. LINE is the first line in the + function. */ + void (* end_prologue) (unsigned int line, const char *file); + + /* Called at beginning of epilogue code. */ + void (* begin_epilogue) (unsigned int line, const char *file); + + /* Record end of epilogue code. */ + void (* end_epilogue) (unsigned int line, const char *file); + + /* Called at start of function DECL, before it is declared. */ + void (* begin_function) (tree decl); + + /* Record end of function. LINE is highest line number in function. */ + void (* end_function) (unsigned int line); + + /* Debug information for a function DECL. This might include the + function name (a symbol), its parameters, and the block that + makes up the function's body, and the local variables of the + function. */ + void (* function_decl) (tree decl); + + /* Debug information for a global DECL. Called from toplev.c after + compilation proper has finished. */ + void (* global_decl) (tree decl); + + /* Debug information for a type DECL. Called from toplev.c after + compilation proper, also from various language front ends to + record built-in types. The second argument is properly a + boolean, which indicates whether or not the type is a "local" + type as determined by the language. (It's not a boolean for + legacy reasons.) */ + void (* type_decl) (tree decl, int local); + + /* Debug information for imported modules and declarations. */ + void (* imported_module_or_decl) (tree decl, tree name, + tree context, bool child); + + /* DECL is an inline function, whose body is present, but which is + not being output at this point. */ + void (* deferred_inline_function) (tree decl); + + /* DECL is an inline function which is about to be emitted out of + line. The hook is useful to, e.g., emit abstract debug info for + the inline before it gets mangled by optimization. */ + void (* outlining_inline_function) (tree decl); + + /* Called from final_scan_insn for any CODE_LABEL insn whose + LABEL_NAME is non-null. */ + void (* label) (rtx); + + /* Called after the start and before the end of writing a PCH file. + The parameter is 0 if after the start, 1 if before the end. */ + void (* handle_pch) (unsigned int); + + /* Called from final_scan_insn for any NOTE_INSN_VAR_LOCATION note. */ + void (* var_location) (rtx); + + /* Called from final_scan_insn if there is a switch between hot and cold + text sections. */ + void (* switch_text_section) (void); + + /* Called from grokdeclarator. Replaces the anonymous name with the + type name. */ + void (* set_name) (tree, tree); + + /* This is 1 if the debug writer wants to see start and end commands for the + main source files, and 0 otherwise. */ + int start_end_main_source_file; + + /* The type of symtab field used by these debug hooks. This is one + of the TYPE_SYMTAB_IS_xxx values defined in tree.h. */ + int tree_type_symtab_field; +}; + +extern const struct gcc_debug_hooks *debug_hooks; + +/* The do-nothing hooks. */ +extern void debug_nothing_void (void); +extern void debug_nothing_charstar (const char *); +extern void debug_nothing_int_charstar (unsigned int, const char *); +extern void debug_nothing_int_charstar_int_bool (unsigned int, const char *, + int, bool); +extern void debug_nothing_int (unsigned int); +extern void debug_nothing_int_int (unsigned int, unsigned int); +extern void debug_nothing_tree (tree); +extern void debug_nothing_tree_tree (tree, tree); +extern void debug_nothing_tree_int (tree, int); +extern void debug_nothing_tree_tree_tree_bool (tree, tree, tree, bool); +extern bool debug_true_const_tree (const_tree); +extern void debug_nothing_rtx (rtx); +extern void debug_nothing_rtx_rtx (rtx, rtx); + +/* Hooks for various debug formats. */ +extern const struct gcc_debug_hooks do_nothing_debug_hooks; +extern const struct gcc_debug_hooks dbx_debug_hooks; +extern const struct gcc_debug_hooks sdb_debug_hooks; +extern const struct gcc_debug_hooks xcoff_debug_hooks; +extern const struct gcc_debug_hooks dwarf2_debug_hooks; +extern const struct gcc_debug_hooks vmsdbg_debug_hooks; + +/* Dwarf2 frame information. */ + +extern void dwarf2out_begin_prologue (unsigned int, const char *); +extern void dwarf2out_vms_end_prologue (unsigned int, const char *); +extern void dwarf2out_vms_begin_epilogue (unsigned int, const char *); +extern void dwarf2out_end_epilogue (unsigned int, const char *); +extern void dwarf2out_frame_finish (void); +/* Decide whether we want to emit frame unwind information for the current + translation unit. */ +extern bool dwarf2out_do_frame (void); +extern bool dwarf2out_do_cfi_asm (void); +extern void dwarf2out_switch_text_section (void); + +const char *remap_debug_filename (const char *); +void add_debug_prefix_map (const char *); + +/* For -fdump-go-spec. */ + +extern const struct gcc_debug_hooks * +dump_go_spec_init (const char *, const struct gcc_debug_hooks *); + +#endif /* !GCC_DEBUG_H */ diff --git a/src/include/defaults.h b/src/include/defaults.h new file mode 100644 index 0000000..4f43f6f --- /dev/null +++ b/src/include/defaults.h @@ -0,0 +1,1409 @@ +/* Definitions of various defaults for tm.h macros. + Copyright (C) 1992-2013 Free Software Foundation, Inc. + Contributed by Ron Guilmette (rfg@monkeys.com) + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +Under Section 7 of GPL version 3, you are granted additional +permissions described in the GCC Runtime Library Exception, version +3.1, as published by the Free Software Foundation. + +You should have received a copy of the GNU General Public License and +a copy of the GCC Runtime Library Exception along with this program; +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +. */ + +#ifndef GCC_DEFAULTS_H +#define GCC_DEFAULTS_H + +/* How to start an assembler comment. */ +#ifndef ASM_COMMENT_START +#define ASM_COMMENT_START ";#" +#endif + +/* Store in OUTPUT a string (made with alloca) containing an + assembler-name for a local static variable or function named NAME. + LABELNO is an integer which is different for each call. */ + +#ifndef ASM_PN_FORMAT +# ifndef NO_DOT_IN_LABEL +# define ASM_PN_FORMAT "%s.%lu" +# else +# ifndef NO_DOLLAR_IN_LABEL +# define ASM_PN_FORMAT "%s$%lu" +# else +# define ASM_PN_FORMAT "__%s_%lu" +# endif +# endif +#endif /* ! ASM_PN_FORMAT */ + +#ifndef ASM_FORMAT_PRIVATE_NAME +# define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ + do { const char *const name_ = (NAME); \ + char *const output_ = (OUTPUT) = \ + (char *) alloca (strlen (name_) + 32); \ + sprintf (output_, ASM_PN_FORMAT, name_, (unsigned long)(LABELNO)); \ + } while (0) +#endif + +/* Choose a reasonable default for ASM_OUTPUT_ASCII. */ + +#ifndef ASM_OUTPUT_ASCII +#define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \ + do { \ + FILE *_hide_asm_out_file = (MYFILE); \ + const unsigned char *_hide_p = (const unsigned char *) (MYSTRING); \ + int _hide_thissize = (MYLENGTH); \ + { \ + FILE *asm_out_file = _hide_asm_out_file; \ + const unsigned char *p = _hide_p; \ + int thissize = _hide_thissize; \ + int i; \ + fprintf (asm_out_file, "\t.ascii \""); \ + \ + for (i = 0; i < thissize; i++) \ + { \ + int c = p[i]; \ + if (c == '\"' || c == '\\') \ + putc ('\\', asm_out_file); \ + if (ISPRINT(c)) \ + putc (c, asm_out_file); \ + else \ + { \ + fprintf (asm_out_file, "\\%o", c); \ + /* After an octal-escape, if a digit follows, \ + terminate one string constant and start another. \ + The VAX assembler fails to stop reading the escape \ + after three digits, so this is the only way we \ + can get it to parse the data properly. */ \ + if (i < thissize - 1 && ISDIGIT(p[i + 1])) \ + fprintf (asm_out_file, "\"\n\t.ascii \""); \ + } \ + } \ + fprintf (asm_out_file, "\"\n"); \ + } \ + } \ + while (0) +#endif + +/* This is how we tell the assembler to equate two values. */ +#ifdef SET_ASM_OP +#ifndef ASM_OUTPUT_DEF +#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \ + do { fprintf ((FILE), "%s", SET_ASM_OP); \ + assemble_name (FILE, LABEL1); \ + fprintf (FILE, ","); \ + assemble_name (FILE, LABEL2); \ + fprintf (FILE, "\n"); \ + } while (0) +#endif +#endif + +#ifndef IFUNC_ASM_TYPE +#define IFUNC_ASM_TYPE "gnu_indirect_function" +#endif + +#ifndef TLS_COMMON_ASM_OP +#define TLS_COMMON_ASM_OP ".tls_common" +#endif + +#if defined (HAVE_AS_TLS) && !defined (ASM_OUTPUT_TLS_COMMON) +#define ASM_OUTPUT_TLS_COMMON(FILE, DECL, NAME, SIZE) \ + do \ + { \ + fprintf ((FILE), "\t%s\t", TLS_COMMON_ASM_OP); \ + assemble_name ((FILE), (NAME)); \ + fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED",%u\n", \ + (SIZE), DECL_ALIGN (DECL) / BITS_PER_UNIT); \ + } \ + while (0) +#endif + +/* Decide whether to defer emitting the assembler output for an equate + of two values. The default is to not defer output. */ +#ifndef TARGET_DEFERRED_OUTPUT_DEFS +#define TARGET_DEFERRED_OUTPUT_DEFS(DECL,TARGET) false +#endif + +/* This is how to output the definition of a user-level label named + NAME, such as the label on variable NAME. */ + +#ifndef ASM_OUTPUT_LABEL +#define ASM_OUTPUT_LABEL(FILE,NAME) \ + do { \ + assemble_name ((FILE), (NAME)); \ + fputs (":\n", (FILE)); \ + } while (0) +#endif + +/* This is how to output the definition of a user-level label named + NAME, such as the label on a function. */ + +#ifndef ASM_OUTPUT_FUNCTION_LABEL +#define ASM_OUTPUT_FUNCTION_LABEL(FILE, NAME, DECL) \ + ASM_OUTPUT_LABEL ((FILE), (NAME)) +#endif + +/* Output the definition of a compiler-generated label named NAME. */ +#ifndef ASM_OUTPUT_INTERNAL_LABEL +#define ASM_OUTPUT_INTERNAL_LABEL(FILE,NAME) \ + do { \ + assemble_name_raw ((FILE), (NAME)); \ + fputs (":\n", (FILE)); \ + } while (0) +#endif + +/* This is how to output a reference to a user-level label named NAME. */ + +#ifndef ASM_OUTPUT_LABELREF +#define ASM_OUTPUT_LABELREF(FILE,NAME) \ + do { \ + fputs (user_label_prefix, (FILE)); \ + fputs ((NAME), (FILE)); \ + } while (0); +#endif + +/* Allow target to print debug info labels specially. This is useful for + VLIW targets, since debug info labels should go into the middle of + instruction bundles instead of breaking them. */ + +#ifndef ASM_OUTPUT_DEBUG_LABEL +#define ASM_OUTPUT_DEBUG_LABEL(FILE, PREFIX, NUM) \ + (*targetm.asm_out.internal_label) (FILE, PREFIX, NUM) +#endif + +/* This is how we tell the assembler that a symbol is weak. */ +#ifndef ASM_OUTPUT_WEAK_ALIAS +#if defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_DEF) +#define ASM_OUTPUT_WEAK_ALIAS(STREAM, NAME, VALUE) \ + do \ + { \ + ASM_WEAKEN_LABEL (STREAM, NAME); \ + if (VALUE) \ + ASM_OUTPUT_DEF (STREAM, NAME, VALUE); \ + } \ + while (0) +#endif +#endif + +/* This is how we tell the assembler that a symbol is a weak alias to + another symbol that doesn't require the other symbol to be defined. + Uses of the former will turn into weak uses of the latter, i.e., + uses that, in case the latter is undefined, will not cause errors, + and will add it to the symbol table as weak undefined. However, if + the latter is referenced directly, a strong reference prevails. */ +#ifndef ASM_OUTPUT_WEAKREF +#if defined HAVE_GAS_WEAKREF +#define ASM_OUTPUT_WEAKREF(FILE, DECL, NAME, VALUE) \ + do \ + { \ + fprintf ((FILE), "\t.weakref\t"); \ + assemble_name ((FILE), (NAME)); \ + fprintf ((FILE), ","); \ + assemble_name ((FILE), (VALUE)); \ + fprintf ((FILE), "\n"); \ + } \ + while (0) +#endif +#endif + +/* How to emit a .type directive. */ +#ifndef ASM_OUTPUT_TYPE_DIRECTIVE +#if defined TYPE_ASM_OP && defined TYPE_OPERAND_FMT +#define ASM_OUTPUT_TYPE_DIRECTIVE(STREAM, NAME, TYPE) \ + do \ + { \ + fputs (TYPE_ASM_OP, STREAM); \ + assemble_name (STREAM, NAME); \ + fputs (", ", STREAM); \ + fprintf (STREAM, TYPE_OPERAND_FMT, TYPE); \ + putc ('\n', STREAM); \ + } \ + while (0) +#endif +#endif + +/* How to emit a .size directive. */ +#ifndef ASM_OUTPUT_SIZE_DIRECTIVE +#ifdef SIZE_ASM_OP +#define ASM_OUTPUT_SIZE_DIRECTIVE(STREAM, NAME, SIZE) \ + do \ + { \ + HOST_WIDE_INT size_ = (SIZE); \ + fputs (SIZE_ASM_OP, STREAM); \ + assemble_name (STREAM, NAME); \ + fprintf (STREAM, ", " HOST_WIDE_INT_PRINT_DEC "\n", size_); \ + } \ + while (0) + +#define ASM_OUTPUT_MEASURED_SIZE(STREAM, NAME) \ + do \ + { \ + fputs (SIZE_ASM_OP, STREAM); \ + assemble_name (STREAM, NAME); \ + fputs (", .-", STREAM); \ + assemble_name (STREAM, NAME); \ + putc ('\n', STREAM); \ + } \ + while (0) + +#endif +#endif + +/* This determines whether or not we support weak symbols. SUPPORTS_WEAK + must be a preprocessor constant. */ +#ifndef SUPPORTS_WEAK +#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) +#define SUPPORTS_WEAK 1 +#else +#define SUPPORTS_WEAK 0 +#endif +#endif + +/* This determines whether or not we support weak symbols during target + code generation. TARGET_SUPPORTS_WEAK can be any valid C expression. */ +#ifndef TARGET_SUPPORTS_WEAK +#define TARGET_SUPPORTS_WEAK (SUPPORTS_WEAK) +#endif + +/* This determines whether or not we support the discriminator + attribute in the .loc directive. */ +#ifndef SUPPORTS_DISCRIMINATOR +#ifdef HAVE_GAS_DISCRIMINATOR +#define SUPPORTS_DISCRIMINATOR 1 +#else +#define SUPPORTS_DISCRIMINATOR 0 +#endif +#endif + +/* This determines whether or not we support link-once semantics. */ +#ifndef SUPPORTS_ONE_ONLY +#ifdef MAKE_DECL_ONE_ONLY +#define SUPPORTS_ONE_ONLY 1 +#else +#define SUPPORTS_ONE_ONLY 0 +#endif +#endif + +/* This determines whether weak symbols must be left out of a static + archive's table of contents. Defining this macro to be nonzero has + the consequence that certain symbols will not be made weak that + otherwise would be. The C++ ABI requires this macro to be zero; + see the documentation. */ +#ifndef TARGET_WEAK_NOT_IN_ARCHIVE_TOC +#define TARGET_WEAK_NOT_IN_ARCHIVE_TOC 0 +#endif + +/* This determines whether or not we need linkonce unwind information. */ +#ifndef TARGET_USES_WEAK_UNWIND_INFO +#define TARGET_USES_WEAK_UNWIND_INFO 0 +#endif + +/* By default, there is no prefix on user-defined symbols. */ +#ifndef USER_LABEL_PREFIX +#define USER_LABEL_PREFIX "" +#endif + +/* If the target supports weak symbols, define TARGET_ATTRIBUTE_WEAK to + provide a weak attribute. Else define it to nothing. + + This would normally belong in ansidecl.h, but SUPPORTS_WEAK is + not available at that time. + + Note, this is only for use by target files which we know are to be + compiled by GCC. */ +#ifndef TARGET_ATTRIBUTE_WEAK +# if SUPPORTS_WEAK +# define TARGET_ATTRIBUTE_WEAK __attribute__ ((weak)) +# else +# define TARGET_ATTRIBUTE_WEAK +# endif +#endif + +/* By default we can assume that all global symbols are in one namespace, + across all shared libraries. */ +#ifndef MULTIPLE_SYMBOL_SPACES +# define MULTIPLE_SYMBOL_SPACES 0 +#endif + +/* If the target supports init_priority C++ attribute, give + SUPPORTS_INIT_PRIORITY a nonzero value. */ +#ifndef SUPPORTS_INIT_PRIORITY +#define SUPPORTS_INIT_PRIORITY 1 +#endif /* SUPPORTS_INIT_PRIORITY */ + +/* If we have a definition of INCOMING_RETURN_ADDR_RTX, assume that + the rest of the DWARF 2 frame unwind support is also provided. */ +#if !defined (DWARF2_UNWIND_INFO) && defined (INCOMING_RETURN_ADDR_RTX) +#define DWARF2_UNWIND_INFO 1 +#endif + +/* If we have named sections, and we're using crtstuff to run ctors, + use them for registering eh frame information. */ +#if defined (TARGET_ASM_NAMED_SECTION) && DWARF2_UNWIND_INFO \ + && !defined(EH_FRAME_IN_DATA_SECTION) +#ifndef EH_FRAME_SECTION_NAME +#define EH_FRAME_SECTION_NAME ".eh_frame" +#endif +#endif + +/* On many systems, different EH table encodings are used under + difference circumstances. Some will require runtime relocations; + some will not. For those that do not require runtime relocations, + we would like to make the table read-only. However, since the + read-only tables may need to be combined with read-write tables + that do require runtime relocation, it is not safe to make the + tables read-only unless the linker will merge read-only and + read-write sections into a single read-write section. If your + linker does not have this ability, but your system is such that no + encoding used with non-PIC code will ever require a runtime + relocation, then you can define EH_TABLES_CAN_BE_READ_ONLY to 1 in + your target configuration file. */ +#ifndef EH_TABLES_CAN_BE_READ_ONLY +#ifdef HAVE_LD_RO_RW_SECTION_MIXING +#define EH_TABLES_CAN_BE_READ_ONLY 1 +#else +#define EH_TABLES_CAN_BE_READ_ONLY 0 +#endif +#endif + +/* If we have named section and we support weak symbols, then use the + .jcr section for recording java classes which need to be registered + at program start-up time. */ +#if defined (TARGET_ASM_NAMED_SECTION) && SUPPORTS_WEAK +#ifndef JCR_SECTION_NAME +#define JCR_SECTION_NAME ".jcr" +#endif +#endif + +/* This decision to use a .jcr section can be overridden by defining + USE_JCR_SECTION to 0 in target file. This is necessary if target + can define JCR_SECTION_NAME but does not have crtstuff or + linker support for .jcr section. */ +#ifndef TARGET_USE_JCR_SECTION +#ifdef JCR_SECTION_NAME +#define TARGET_USE_JCR_SECTION 1 +#else +#define TARGET_USE_JCR_SECTION 0 +#endif +#endif + +/* Number of hardware registers that go into the DWARF-2 unwind info. + If not defined, equals FIRST_PSEUDO_REGISTER */ + +#ifndef DWARF_FRAME_REGISTERS +#define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER +#endif + +/* Offsets recorded in opcodes are a multiple of this alignment factor. */ +#ifndef DWARF_CIE_DATA_ALIGNMENT +#ifdef STACK_GROWS_DOWNWARD +#define DWARF_CIE_DATA_ALIGNMENT (-((int) UNITS_PER_WORD)) +#else +#define DWARF_CIE_DATA_ALIGNMENT ((int) UNITS_PER_WORD) +#endif +#endif + +/* The DWARF 2 CFA column which tracks the return address. Normally this + is the column for PC, or the first column after all of the hard + registers. */ +#ifndef DWARF_FRAME_RETURN_COLUMN +#ifdef PC_REGNUM +#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (PC_REGNUM) +#else +#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGISTERS +#endif +#endif + +/* How to renumber registers for dbx and gdb. If not defined, assume + no renumbering is necessary. */ + +#ifndef DBX_REGISTER_NUMBER +#define DBX_REGISTER_NUMBER(REGNO) (REGNO) +#endif + +/* The mapping from gcc register number to DWARF 2 CFA column number. + By default, we just provide columns for all registers. */ +#ifndef DWARF_FRAME_REGNUM +#define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG) +#endif + +/* Map register numbers held in the call frame info that gcc has + collected using DWARF_FRAME_REGNUM to those that should be output in + .debug_frame and .eh_frame. */ +#ifndef DWARF2_FRAME_REG_OUT +#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) (REGNO) +#endif + +/* The size of addresses as they appear in the Dwarf 2 data. + Some architectures use word addresses to refer to code locations, + but Dwarf 2 info always uses byte addresses. On such machines, + Dwarf 2 addresses need to be larger than the architecture's + pointers. */ +#ifndef DWARF2_ADDR_SIZE +#define DWARF2_ADDR_SIZE (POINTER_SIZE / BITS_PER_UNIT) +#endif + +/* The size in bytes of a DWARF field indicating an offset or length + relative to a debug info section, specified to be 4 bytes in the + DWARF-2 specification. The SGI/MIPS ABI defines it to be the same + as PTR_SIZE. */ +#ifndef DWARF_OFFSET_SIZE +#define DWARF_OFFSET_SIZE 4 +#endif + +/* The size in bytes of a DWARF 4 type signature. */ +#ifndef DWARF_TYPE_SIGNATURE_SIZE +#define DWARF_TYPE_SIGNATURE_SIZE 8 +#endif + +/* Default sizes for base C types. If the sizes are different for + your target, you should override these values by defining the + appropriate symbols in your tm.h file. */ + +#ifndef BITS_PER_UNIT +#define BITS_PER_UNIT 8 +#endif + +#ifndef BITS_PER_WORD +#define BITS_PER_WORD (BITS_PER_UNIT * UNITS_PER_WORD) +#endif + +#ifndef CHAR_TYPE_SIZE +#define CHAR_TYPE_SIZE BITS_PER_UNIT +#endif + +#ifndef BOOL_TYPE_SIZE +/* `bool' has size and alignment `1', on almost all platforms. */ +#define BOOL_TYPE_SIZE CHAR_TYPE_SIZE +#endif + +#ifndef SHORT_TYPE_SIZE +#define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2)) +#endif + +#ifndef INT_TYPE_SIZE +#define INT_TYPE_SIZE BITS_PER_WORD +#endif + +#ifndef LONG_TYPE_SIZE +#define LONG_TYPE_SIZE BITS_PER_WORD +#endif + +#ifndef LONG_LONG_TYPE_SIZE +#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) +#endif + +#ifndef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE INT_TYPE_SIZE +#endif + +#ifndef FLOAT_TYPE_SIZE +#define FLOAT_TYPE_SIZE BITS_PER_WORD +#endif + +#ifndef DOUBLE_TYPE_SIZE +#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) +#endif + +#ifndef LONG_DOUBLE_TYPE_SIZE +#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) +#endif + +#ifndef DECIMAL32_TYPE_SIZE +#define DECIMAL32_TYPE_SIZE 32 +#endif + +#ifndef DECIMAL64_TYPE_SIZE +#define DECIMAL64_TYPE_SIZE 64 +#endif + +#ifndef DECIMAL128_TYPE_SIZE +#define DECIMAL128_TYPE_SIZE 128 +#endif + +#ifndef SHORT_FRACT_TYPE_SIZE +#define SHORT_FRACT_TYPE_SIZE BITS_PER_UNIT +#endif + +#ifndef FRACT_TYPE_SIZE +#define FRACT_TYPE_SIZE (BITS_PER_UNIT * 2) +#endif + +#ifndef LONG_FRACT_TYPE_SIZE +#define LONG_FRACT_TYPE_SIZE (BITS_PER_UNIT * 4) +#endif + +#ifndef LONG_LONG_FRACT_TYPE_SIZE +#define LONG_LONG_FRACT_TYPE_SIZE (BITS_PER_UNIT * 8) +#endif + +#ifndef SHORT_ACCUM_TYPE_SIZE +#define SHORT_ACCUM_TYPE_SIZE (SHORT_FRACT_TYPE_SIZE * 2) +#endif + +#ifndef ACCUM_TYPE_SIZE +#define ACCUM_TYPE_SIZE (FRACT_TYPE_SIZE * 2) +#endif + +#ifndef LONG_ACCUM_TYPE_SIZE +#define LONG_ACCUM_TYPE_SIZE (LONG_FRACT_TYPE_SIZE * 2) +#endif + +#ifndef LONG_LONG_ACCUM_TYPE_SIZE +#define LONG_LONG_ACCUM_TYPE_SIZE (LONG_LONG_FRACT_TYPE_SIZE * 2) +#endif + +/* We let tm.h override the types used here, to handle trivial differences + such as the choice of unsigned int or long unsigned int for size_t. + When machines start needing nontrivial differences in the size type, + it would be best to do something here to figure out automatically + from other information what type to use. */ + +#ifndef SIZE_TYPE +#define SIZE_TYPE "long unsigned int" +#endif + +#ifndef SIZETYPE +#define SIZETYPE SIZE_TYPE +#endif + +#ifndef PID_TYPE +#define PID_TYPE "int" +#endif + +/* If GCC knows the exact uint_least16_t and uint_least32_t types from + , use them for char16_t and char32_t. Otherwise, use + these guesses; getting the wrong type of a given width will not + affect C++ name mangling because in C++ these are distinct types + not typedefs. */ + +#ifdef UINT_LEAST16_TYPE +#define CHAR16_TYPE UINT_LEAST16_TYPE +#else +#define CHAR16_TYPE "short unsigned int" +#endif + +#ifdef UINT_LEAST32_TYPE +#define CHAR32_TYPE UINT_LEAST32_TYPE +#else +#define CHAR32_TYPE "unsigned int" +#endif + +#ifndef WCHAR_TYPE +#define WCHAR_TYPE "int" +#endif + +/* WCHAR_TYPE gets overridden by -fshort-wchar. */ +#define MODIFIED_WCHAR_TYPE \ + (flag_short_wchar ? "short unsigned int" : WCHAR_TYPE) + +#ifndef PTRDIFF_TYPE +#define PTRDIFF_TYPE "long int" +#endif + +#ifndef WINT_TYPE +#define WINT_TYPE "unsigned int" +#endif + +#ifndef INTMAX_TYPE +#define INTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \ + ? "int" \ + : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \ + ? "long int" \ + : "long long int")) +#endif + +#ifndef UINTMAX_TYPE +#define UINTMAX_TYPE ((INT_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \ + ? "unsigned int" \ + : ((LONG_TYPE_SIZE == LONG_LONG_TYPE_SIZE) \ + ? "long unsigned int" \ + : "long long unsigned int")) +#endif + + +/* There are no default definitions of these types. */ + +#ifndef SIG_ATOMIC_TYPE +#define SIG_ATOMIC_TYPE ((const char *) NULL) +#endif + +#ifndef INT8_TYPE +#define INT8_TYPE ((const char *) NULL) +#endif + +#ifndef INT16_TYPE +#define INT16_TYPE ((const char *) NULL) +#endif + +#ifndef INT32_TYPE +#define INT32_TYPE ((const char *) NULL) +#endif + +#ifndef INT64_TYPE +#define INT64_TYPE ((const char *) NULL) +#endif + +#ifndef UINT8_TYPE +#define UINT8_TYPE ((const char *) NULL) +#endif + +#ifndef UINT16_TYPE +#define UINT16_TYPE ((const char *) NULL) +#endif + +#ifndef UINT32_TYPE +#define UINT32_TYPE ((const char *) NULL) +#endif + +#ifndef UINT64_TYPE +#define UINT64_TYPE ((const char *) NULL) +#endif + +#ifndef INT_LEAST8_TYPE +#define INT_LEAST8_TYPE ((const char *) NULL) +#endif + +#ifndef INT_LEAST16_TYPE +#define INT_LEAST16_TYPE ((const char *) NULL) +#endif + +#ifndef INT_LEAST32_TYPE +#define INT_LEAST32_TYPE ((const char *) NULL) +#endif + +#ifndef INT_LEAST64_TYPE +#define INT_LEAST64_TYPE ((const char *) NULL) +#endif + +#ifndef UINT_LEAST8_TYPE +#define UINT_LEAST8_TYPE ((const char *) NULL) +#endif + +#ifndef UINT_LEAST16_TYPE +#define UINT_LEAST16_TYPE ((const char *) NULL) +#endif + +#ifndef UINT_LEAST32_TYPE +#define UINT_LEAST32_TYPE ((const char *) NULL) +#endif + +#ifndef UINT_LEAST64_TYPE +#define UINT_LEAST64_TYPE ((const char *) NULL) +#endif + +#ifndef INT_FAST8_TYPE +#define INT_FAST8_TYPE ((const char *) NULL) +#endif + +#ifndef INT_FAST16_TYPE +#define INT_FAST16_TYPE ((const char *) NULL) +#endif + +#ifndef INT_FAST32_TYPE +#define INT_FAST32_TYPE ((const char *) NULL) +#endif + +#ifndef INT_FAST64_TYPE +#define INT_FAST64_TYPE ((const char *) NULL) +#endif + +#ifndef UINT_FAST8_TYPE +#define UINT_FAST8_TYPE ((const char *) NULL) +#endif + +#ifndef UINT_FAST16_TYPE +#define UINT_FAST16_TYPE ((const char *) NULL) +#endif + +#ifndef UINT_FAST32_TYPE +#define UINT_FAST32_TYPE ((const char *) NULL) +#endif + +#ifndef UINT_FAST64_TYPE +#define UINT_FAST64_TYPE ((const char *) NULL) +#endif + +#ifndef INTPTR_TYPE +#define INTPTR_TYPE ((const char *) NULL) +#endif + +#ifndef UINTPTR_TYPE +#define UINTPTR_TYPE ((const char *) NULL) +#endif + +/* Width in bits of a pointer. Mind the value of the macro `Pmode'. */ +#ifndef POINTER_SIZE +#define POINTER_SIZE BITS_PER_WORD +#endif + +#ifndef PIC_OFFSET_TABLE_REGNUM +#define PIC_OFFSET_TABLE_REGNUM INVALID_REGNUM +#endif + +#ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED +#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED 0 +#endif + +#ifndef TARGET_DLLIMPORT_DECL_ATTRIBUTES +#define TARGET_DLLIMPORT_DECL_ATTRIBUTES 0 +#endif + +#ifndef TARGET_DECLSPEC +#if TARGET_DLLIMPORT_DECL_ATTRIBUTES +/* If the target supports the "dllimport" attribute, users are + probably used to the "__declspec" syntax. */ +#define TARGET_DECLSPEC 1 +#else +#define TARGET_DECLSPEC 0 +#endif +#endif + +/* By default, the preprocessor should be invoked the same way in C++ + as in C. */ +#ifndef CPLUSPLUS_CPP_SPEC +#ifdef CPP_SPEC +#define CPLUSPLUS_CPP_SPEC CPP_SPEC +#endif +#endif + +#ifndef ACCUMULATE_OUTGOING_ARGS +#define ACCUMULATE_OUTGOING_ARGS 0 +#endif + +/* By default, use the GNU runtime for Objective C. */ +#ifndef NEXT_OBJC_RUNTIME +#define NEXT_OBJC_RUNTIME 0 +#endif + +/* Supply a default definition for PUSH_ARGS. */ +#ifndef PUSH_ARGS +#ifdef PUSH_ROUNDING +#define PUSH_ARGS !ACCUMULATE_OUTGOING_ARGS +#else +#define PUSH_ARGS 0 +#endif +#endif + +/* Decide whether a function's arguments should be processed + from first to last or from last to first. + + They should if the stack and args grow in opposite directions, but + only if we have push insns. */ + +#ifdef PUSH_ROUNDING + +#ifndef PUSH_ARGS_REVERSED +#if defined (STACK_GROWS_DOWNWARD) != defined (ARGS_GROW_DOWNWARD) +#define PUSH_ARGS_REVERSED PUSH_ARGS +#endif +#endif + +#endif + +#ifndef PUSH_ARGS_REVERSED +#define PUSH_ARGS_REVERSED 0 +#endif + +/* Default value for the alignment (in bits) a C conformant malloc has to + provide. This default is intended to be safe and always correct. */ +#ifndef MALLOC_ABI_ALIGNMENT +#define MALLOC_ABI_ALIGNMENT BITS_PER_WORD +#endif + +/* If PREFERRED_STACK_BOUNDARY is not defined, set it to STACK_BOUNDARY. + STACK_BOUNDARY is required. */ +#ifndef PREFERRED_STACK_BOUNDARY +#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY +#endif + +/* Set INCOMING_STACK_BOUNDARY to PREFERRED_STACK_BOUNDARY if it is not + defined. */ +#ifndef INCOMING_STACK_BOUNDARY +#define INCOMING_STACK_BOUNDARY PREFERRED_STACK_BOUNDARY +#endif + +#ifndef TARGET_DEFAULT_PACK_STRUCT +#define TARGET_DEFAULT_PACK_STRUCT 0 +#endif + +/* By default, the vtable entries are void pointers, the so the alignment + is the same as pointer alignment. The value of this macro specifies + the alignment of the vtable entry in bits. It should be defined only + when special alignment is necessary. */ +#ifndef TARGET_VTABLE_ENTRY_ALIGN +#define TARGET_VTABLE_ENTRY_ALIGN POINTER_SIZE +#endif + +/* There are a few non-descriptor entries in the vtable at offsets below + zero. If these entries must be padded (say, to preserve the alignment + specified by TARGET_VTABLE_ENTRY_ALIGN), set this to the number of + words in each data entry. */ +#ifndef TARGET_VTABLE_DATA_ENTRY_DISTANCE +#define TARGET_VTABLE_DATA_ENTRY_DISTANCE 1 +#endif + +/* Decide whether it is safe to use a local alias for a virtual function + when constructing thunks. */ +#ifndef TARGET_USE_LOCAL_THUNK_ALIAS_P +#ifdef ASM_OUTPUT_DEF +#define TARGET_USE_LOCAL_THUNK_ALIAS_P(DECL) 1 +#else +#define TARGET_USE_LOCAL_THUNK_ALIAS_P(DECL) 0 +#endif +#endif + +/* Select a format to encode pointers in exception handling data. We + prefer those that result in fewer dynamic relocations. Assume no + special support here and encode direct references. */ +#ifndef ASM_PREFERRED_EH_DATA_FORMAT +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) DW_EH_PE_absptr +#endif + +/* By default, the C++ compiler will use the lowest bit of the pointer + to function to indicate a pointer-to-member-function points to a + virtual member function. However, if FUNCTION_BOUNDARY indicates + function addresses aren't always even, the lowest bit of the delta + field will be used. */ +#ifndef TARGET_PTRMEMFUNC_VBIT_LOCATION +#define TARGET_PTRMEMFUNC_VBIT_LOCATION \ + (FUNCTION_BOUNDARY >= 2 * BITS_PER_UNIT \ + ? ptrmemfunc_vbit_in_pfn : ptrmemfunc_vbit_in_delta) +#endif + +#ifndef DEFAULT_GDB_EXTENSIONS +#define DEFAULT_GDB_EXTENSIONS 1 +#endif + +/* If more than one debugging type is supported, you must define + PREFERRED_DEBUGGING_TYPE to choose the default. */ + +#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) \ + + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO) \ + + defined (VMS_DEBUGGING_INFO)) +#ifndef PREFERRED_DEBUGGING_TYPE +#error You must define PREFERRED_DEBUGGING_TYPE +#endif /* no PREFERRED_DEBUGGING_TYPE */ + +/* If only one debugging format is supported, define PREFERRED_DEBUGGING_TYPE + here so other code needn't care. */ +#elif defined DBX_DEBUGGING_INFO +#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG + +#elif defined SDB_DEBUGGING_INFO +#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG + +#elif defined DWARF2_DEBUGGING_INFO +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG + +#elif defined VMS_DEBUGGING_INFO +#define PREFERRED_DEBUGGING_TYPE VMS_AND_DWARF2_DEBUG + +#elif defined XCOFF_DEBUGGING_INFO +#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG + +#else +/* No debugging format is supported by this target. */ +#define PREFERRED_DEBUGGING_TYPE NO_DEBUG +#endif + +#ifndef LARGEST_EXPONENT_IS_NORMAL +#define LARGEST_EXPONENT_IS_NORMAL(SIZE) 0 +#endif + +#ifndef ROUND_TOWARDS_ZERO +#define ROUND_TOWARDS_ZERO 0 +#endif + +#ifndef FLOAT_LIB_COMPARE_RETURNS_BOOL +#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) false +#endif + +/* True if the targets integer-comparison functions return { 0, 1, 2 + } to indicate { <, ==, > }. False if { -1, 0, 1 } is used + instead. The libgcc routines are biased. */ +#ifndef TARGET_LIB_INT_CMP_BIASED +#define TARGET_LIB_INT_CMP_BIASED (true) +#endif + +/* If FLOAT_WORDS_BIG_ENDIAN is not defined in the header files, + then the word-endianness is the same as for integers. */ +#ifndef FLOAT_WORDS_BIG_ENDIAN +#define FLOAT_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN +#endif + +#ifndef REG_WORDS_BIG_ENDIAN +#define REG_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN +#endif + +#ifdef TARGET_FLT_EVAL_METHOD +#define TARGET_FLT_EVAL_METHOD_NON_DEFAULT 1 +#else +#define TARGET_FLT_EVAL_METHOD 0 +#define TARGET_FLT_EVAL_METHOD_NON_DEFAULT 0 +#endif + +#ifndef TARGET_DEC_EVAL_METHOD +#define TARGET_DEC_EVAL_METHOD 2 +#endif + +#ifndef HAS_LONG_COND_BRANCH +#define HAS_LONG_COND_BRANCH 0 +#endif + +#ifndef HAS_LONG_UNCOND_BRANCH +#define HAS_LONG_UNCOND_BRANCH 0 +#endif + +/* Determine whether __cxa_atexit, rather than atexit, is used to + register C++ destructors for local statics and global objects. */ +#ifndef DEFAULT_USE_CXA_ATEXIT +#define DEFAULT_USE_CXA_ATEXIT 0 +#endif + +/* If none of these macros are defined, the port must use the new + technique of defining constraints in the machine description. + tm_p.h will define those macros that machine-independent code + still uses. */ +#if !defined CONSTRAINT_LEN \ + && !defined REG_CLASS_FROM_LETTER \ + && !defined REG_CLASS_FROM_CONSTRAINT \ + && !defined CONST_OK_FOR_LETTER_P \ + && !defined CONST_OK_FOR_CONSTRAINT_P \ + && !defined CONST_DOUBLE_OK_FOR_LETTER_P \ + && !defined CONST_DOUBLE_OK_FOR_CONSTRAINT_P \ + && !defined EXTRA_CONSTRAINT \ + && !defined EXTRA_CONSTRAINT_STR \ + && !defined EXTRA_MEMORY_CONSTRAINT \ + && !defined EXTRA_ADDRESS_CONSTRAINT + +#define USE_MD_CONSTRAINTS + +#if GCC_VERSION >= 3000 && defined IN_GCC +/* These old constraint macros shouldn't appear anywhere in a + configuration using MD constraint definitions. */ +#pragma GCC poison REG_CLASS_FROM_LETTER CONST_OK_FOR_LETTER_P \ + CONST_DOUBLE_OK_FOR_LETTER_P EXTRA_CONSTRAINT +#endif + +#else /* old constraint mechanism in use */ + +/* Determine whether extra constraint letter should be handled + via address reload (like 'o'). */ +#ifndef EXTRA_MEMORY_CONSTRAINT +#define EXTRA_MEMORY_CONSTRAINT(C,STR) 0 +#endif + +/* Determine whether extra constraint letter should be handled + as an address (like 'p'). */ +#ifndef EXTRA_ADDRESS_CONSTRAINT +#define EXTRA_ADDRESS_CONSTRAINT(C,STR) 0 +#endif + +/* When a port defines CONSTRAINT_LEN, it should use DEFAULT_CONSTRAINT_LEN + for all the characters that it does not want to change, so things like the + 'length' of a digit in a matching constraint is an implementation detail, + and not part of the interface. */ +#define DEFAULT_CONSTRAINT_LEN(C,STR) 1 + +#ifndef CONSTRAINT_LEN +#define CONSTRAINT_LEN(C,STR) DEFAULT_CONSTRAINT_LEN (C, STR) +#endif + +#if defined (CONST_OK_FOR_LETTER_P) && ! defined (CONST_OK_FOR_CONSTRAINT_P) +#define CONST_OK_FOR_CONSTRAINT_P(VAL,C,STR) CONST_OK_FOR_LETTER_P (VAL, C) +#endif + +#if defined (CONST_DOUBLE_OK_FOR_LETTER_P) && ! defined (CONST_DOUBLE_OK_FOR_CONSTRAINT_P) +#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(OP,C,STR) \ + CONST_DOUBLE_OK_FOR_LETTER_P (OP, C) +#endif + +#ifndef REG_CLASS_FROM_CONSTRAINT +#define REG_CLASS_FROM_CONSTRAINT(C,STR) REG_CLASS_FROM_LETTER (C) +#endif + +#if defined (EXTRA_CONSTRAINT) && ! defined (EXTRA_CONSTRAINT_STR) +#define EXTRA_CONSTRAINT_STR(OP, C,STR) EXTRA_CONSTRAINT (OP, C) +#endif + +#endif /* old constraint mechanism in use */ + +/* Determine whether the entire c99 runtime + is present in the runtime library. */ +#ifndef TARGET_C99_FUNCTIONS +#define TARGET_C99_FUNCTIONS 0 +#endif + +/* Determine whether the target runtime library has + a sincos implementation following the GNU extension. */ +#ifndef TARGET_HAS_SINCOS +#define TARGET_HAS_SINCOS 0 +#endif + +/* Determin whether the target runtime library is Bionic */ +#ifndef TARGET_HAS_BIONIC +#define TARGET_HAS_BIONIC 0 +#endif + +/* Indicate that CLZ and CTZ are undefined at zero. */ +#ifndef CLZ_DEFINED_VALUE_AT_ZERO +#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) 0 +#endif +#ifndef CTZ_DEFINED_VALUE_AT_ZERO +#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) 0 +#endif + +/* Provide a default value for STORE_FLAG_VALUE. */ +#ifndef STORE_FLAG_VALUE +#define STORE_FLAG_VALUE 1 +#endif + +/* This macro is used to determine what the largest unit size that + move_by_pieces can use is. */ + +/* MOVE_MAX_PIECES is the number of bytes at a time which we can + move efficiently, as opposed to MOVE_MAX which is the maximum + number of bytes we can move with a single instruction. */ + +#ifndef MOVE_MAX_PIECES +#define MOVE_MAX_PIECES MOVE_MAX +#endif + +#ifndef MAX_MOVE_MAX +#define MAX_MOVE_MAX MOVE_MAX +#endif + +#ifndef MIN_UNITS_PER_WORD +#define MIN_UNITS_PER_WORD UNITS_PER_WORD +#endif + +#ifndef MAX_BITS_PER_WORD +#define MAX_BITS_PER_WORD BITS_PER_WORD +#endif + +#ifndef STACK_POINTER_OFFSET +#define STACK_POINTER_OFFSET 0 +#endif + +#ifndef LOCAL_REGNO +#define LOCAL_REGNO(REGNO) 0 +#endif + +/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, + the stack pointer does not matter. The value is tested only in + functions that have frame pointers. */ +#ifndef EXIT_IGNORE_STACK +#define EXIT_IGNORE_STACK 0 +#endif + +/* Assume that case vectors are not pc-relative. */ +#ifndef CASE_VECTOR_PC_RELATIVE +#define CASE_VECTOR_PC_RELATIVE 0 +#endif + +/* Assume that trampolines need function alignment. */ +#ifndef TRAMPOLINE_ALIGNMENT +#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY +#endif + +/* Register mappings for target machines without register windows. */ +#ifndef INCOMING_REGNO +#define INCOMING_REGNO(N) (N) +#endif + +#ifndef OUTGOING_REGNO +#define OUTGOING_REGNO(N) (N) +#endif + +#ifndef SHIFT_COUNT_TRUNCATED +#define SHIFT_COUNT_TRUNCATED 0 +#endif + +#ifndef LEGITIMATE_PIC_OPERAND_P +#define LEGITIMATE_PIC_OPERAND_P(X) 1 +#endif + +#ifndef TARGET_MEM_CONSTRAINT +#define TARGET_MEM_CONSTRAINT 'm' +#endif + +#ifndef REVERSIBLE_CC_MODE +#define REVERSIBLE_CC_MODE(MODE) 0 +#endif + +/* Biggest alignment supported by the object file format of this machine. */ +#ifndef MAX_OFILE_ALIGNMENT +#define MAX_OFILE_ALIGNMENT BIGGEST_ALIGNMENT +#endif + +#ifndef FRAME_GROWS_DOWNWARD +#define FRAME_GROWS_DOWNWARD 0 +#endif + +/* On most machines, the CFA coincides with the first incoming parm. */ +#ifndef ARG_POINTER_CFA_OFFSET +#define ARG_POINTER_CFA_OFFSET(FNDECL) \ + (FIRST_PARM_OFFSET (FNDECL) + crtl->args.pretend_args_size) +#endif + +/* On most machines, we use the CFA as DW_AT_frame_base. */ +#ifndef CFA_FRAME_BASE_OFFSET +#define CFA_FRAME_BASE_OFFSET(FNDECL) 0 +#endif + +/* The offset from the incoming value of %sp to the top of the stack frame + for the current function. */ +#ifndef INCOMING_FRAME_SP_OFFSET +#define INCOMING_FRAME_SP_OFFSET 0 +#endif + +#ifndef HARD_REGNO_NREGS_HAS_PADDING +#define HARD_REGNO_NREGS_HAS_PADDING(REGNO, MODE) 0 +#define HARD_REGNO_NREGS_WITH_PADDING(REGNO, MODE) -1 +#endif + +#ifndef OUTGOING_REG_PARM_STACK_SPACE +#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 0 +#endif + +/* MAX_STACK_ALIGNMENT is the maximum stack alignment guaranteed by + the backend. MAX_SUPPORTED_STACK_ALIGNMENT is the maximum best + effort stack alignment supported by the backend. If the backend + supports stack alignment, MAX_SUPPORTED_STACK_ALIGNMENT and + MAX_STACK_ALIGNMENT are the same. Otherwise, the incoming stack + boundary will limit the maximum guaranteed stack alignment. */ +#ifdef MAX_STACK_ALIGNMENT +#define MAX_SUPPORTED_STACK_ALIGNMENT MAX_STACK_ALIGNMENT +#else +#define MAX_STACK_ALIGNMENT STACK_BOUNDARY +#define MAX_SUPPORTED_STACK_ALIGNMENT PREFERRED_STACK_BOUNDARY +#endif + +#define SUPPORTS_STACK_ALIGNMENT (MAX_STACK_ALIGNMENT > STACK_BOUNDARY) + +#ifndef LOCAL_ALIGNMENT +#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT +#endif + +#ifndef STACK_SLOT_ALIGNMENT +#define STACK_SLOT_ALIGNMENT(TYPE,MODE,ALIGN) \ + ((TYPE) ? LOCAL_ALIGNMENT ((TYPE), (ALIGN)) : (ALIGN)) +#endif + +#ifndef LOCAL_DECL_ALIGNMENT +#define LOCAL_DECL_ALIGNMENT(DECL) \ + LOCAL_ALIGNMENT (TREE_TYPE (DECL), DECL_ALIGN (DECL)) +#endif + +#ifndef MINIMUM_ALIGNMENT +#define MINIMUM_ALIGNMENT(EXP,MODE,ALIGN) (ALIGN) +#endif + +/* Alignment value for attribute ((aligned)). */ +#ifndef ATTRIBUTE_ALIGNED_VALUE +#define ATTRIBUTE_ALIGNED_VALUE BIGGEST_ALIGNMENT +#endif + +#ifndef SLOW_UNALIGNED_ACCESS +#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT +#endif + +/* For most ports anything that evaluates to a constant symbolic + or integer value is acceptable as a constant address. */ +#ifndef CONSTANT_ADDRESS_P +#define CONSTANT_ADDRESS_P(X) (CONSTANT_P (X) && GET_CODE (X) != CONST_DOUBLE) +#endif + +#ifndef MAX_FIXED_MODE_SIZE +#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode) +#endif + +/* Nonzero if structures and unions should be returned in memory. + + This should only be defined if compatibility with another compiler or + with an ABI is needed, because it results in slower code. */ + +#ifndef DEFAULT_PCC_STRUCT_RETURN +#define DEFAULT_PCC_STRUCT_RETURN 1 +#endif + +#ifdef GCC_INSN_FLAGS_H +/* Dependent default target macro definitions + + This section of defaults.h defines target macros that depend on generated + headers. This is a bit awkward: We want to put all default definitions + for target macros in defaults.h, but some of the defaults depend on the + HAVE_* flags defines of insn-flags.h. But insn-flags.h is not always + included by files that do include defaults.h. + + Fortunately, the default macro definitions that depend on the HAVE_* + macros are also the ones that will only be used inside GCC itself, i.e. + not in the gen* programs or in target objects like libgcc. + + Obviously, it would be best to keep this section of defaults.h as small + as possible, by converting the macros defined below to target hooks or + functions. +*/ + +/* The default branch cost is 1. */ +#ifndef BRANCH_COST +#define BRANCH_COST(speed_p, predictable_p) 1 +#endif + +/* If a memory-to-memory move would take MOVE_RATIO or more simple + move-instruction sequences, we will do a movmem or libcall instead. */ + +#ifndef MOVE_RATIO +#if defined (HAVE_movmemqi) || defined (HAVE_movmemhi) || defined (HAVE_movmemsi) || defined (HAVE_movmemdi) || defined (HAVE_movmemti) +#define MOVE_RATIO(speed) 2 +#else +/* If we are optimizing for space (-Os), cut down the default move ratio. */ +#define MOVE_RATIO(speed) ((speed) ? 15 : 3) +#endif +#endif + +/* If a clear memory operation would take CLEAR_RATIO or more simple + move-instruction sequences, we will do a setmem or libcall instead. */ + +#ifndef CLEAR_RATIO +#if defined (HAVE_setmemqi) || defined (HAVE_setmemhi) || defined (HAVE_setmemsi) || defined (HAVE_setmemdi) || defined (HAVE_setmemti) +#define CLEAR_RATIO(speed) 2 +#else +/* If we are optimizing for space, cut down the default clear ratio. */ +#define CLEAR_RATIO(speed) ((speed) ? 15 :3) +#endif +#endif + +/* If a memory set (to value other than zero) operation would take + SET_RATIO or more simple move-instruction sequences, we will do a movmem + or libcall instead. */ +#ifndef SET_RATIO +#define SET_RATIO(speed) MOVE_RATIO(speed) +#endif + +/* Supply a default definition for FUNCTION_ARG_PADDING: + usually pad upward, but pad short args downward on + big-endian machines. */ + +#define DEFAULT_FUNCTION_ARG_PADDING(MODE, TYPE) \ + (! BYTES_BIG_ENDIAN \ + ? upward \ + : (((MODE) == BLKmode \ + ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \ + && int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT)) \ + : GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY) \ + ? downward : upward)) + +#ifndef FUNCTION_ARG_PADDING +#define FUNCTION_ARG_PADDING(MODE, TYPE) \ + DEFAULT_FUNCTION_ARG_PADDING ((MODE), (TYPE)) +#endif + +/* Supply a default definition of STACK_SAVEAREA_MODE for emit_stack_save. + Normally move_insn, so Pmode stack pointer. */ + +#ifndef STACK_SAVEAREA_MODE +#define STACK_SAVEAREA_MODE(LEVEL) Pmode +#endif + +/* Supply a default definition of STACK_SIZE_MODE for + allocate_dynamic_stack_space. Normally PLUS/MINUS, so word_mode. */ + +#ifndef STACK_SIZE_MODE +#define STACK_SIZE_MODE word_mode +#endif + +/* Provide default values for the macros controlling stack checking. */ + +/* The default is neither full builtin stack checking... */ +#ifndef STACK_CHECK_BUILTIN +#define STACK_CHECK_BUILTIN 0 +#endif + +/* ...nor static builtin stack checking. */ +#ifndef STACK_CHECK_STATIC_BUILTIN +#define STACK_CHECK_STATIC_BUILTIN 0 +#endif + +/* The default interval is one page (4096 bytes). */ +#ifndef STACK_CHECK_PROBE_INTERVAL_EXP +#define STACK_CHECK_PROBE_INTERVAL_EXP 12 +#endif + +/* The default is not to move the stack pointer. */ +#ifndef STACK_CHECK_MOVING_SP +#define STACK_CHECK_MOVING_SP 0 +#endif + +/* This is a kludge to try to capture the discrepancy between the old + mechanism (generic stack checking) and the new mechanism (static + builtin stack checking). STACK_CHECK_PROTECT needs to be bumped + for the latter because part of the protection area is effectively + included in STACK_CHECK_MAX_FRAME_SIZE for the former. */ +#ifdef STACK_CHECK_PROTECT +#define STACK_OLD_CHECK_PROTECT STACK_CHECK_PROTECT +#else +#define STACK_OLD_CHECK_PROTECT \ + (targetm_common.except_unwind_info (&global_options) == UI_SJLJ \ + ? 75 * UNITS_PER_WORD \ + : 8 * 1024) +#endif + +/* Minimum amount of stack required to recover from an anticipated stack + overflow detection. The default value conveys an estimate of the amount + of stack required to propagate an exception. */ +#ifndef STACK_CHECK_PROTECT +#define STACK_CHECK_PROTECT \ + (targetm_common.except_unwind_info (&global_options) == UI_SJLJ \ + ? 75 * UNITS_PER_WORD \ + : 12 * 1024) +#endif + +/* Make the maximum frame size be the largest we can and still only need + one probe per function. */ +#ifndef STACK_CHECK_MAX_FRAME_SIZE +#define STACK_CHECK_MAX_FRAME_SIZE \ + ((1 << STACK_CHECK_PROBE_INTERVAL_EXP) - UNITS_PER_WORD) +#endif + +/* This is arbitrary, but should be large enough everywhere. */ +#ifndef STACK_CHECK_FIXED_FRAME_SIZE +#define STACK_CHECK_FIXED_FRAME_SIZE (4 * UNITS_PER_WORD) +#endif + +/* Provide a reasonable default for the maximum size of an object to + allocate in the fixed frame. We may need to be able to make this + controllable by the user at some point. */ +#ifndef STACK_CHECK_MAX_VAR_SIZE +#define STACK_CHECK_MAX_VAR_SIZE (STACK_CHECK_MAX_FRAME_SIZE / 100) +#endif + +/* By default, the C++ compiler will use function addresses in the + vtable entries. Setting this nonzero tells the compiler to use + function descriptors instead. The value of this macro says how + many words wide the descriptor is (normally 2). It is assumed + that the address of a function descriptor may be treated as a + pointer to a function. */ +#ifndef TARGET_VTABLE_USES_DESCRIPTORS +#define TARGET_VTABLE_USES_DESCRIPTORS 0 +#endif + +#ifndef SWITCHABLE_TARGET +#define SWITCHABLE_TARGET 0 +#endif + +#endif /* GCC_INSN_FLAGS_H */ + +#endif /* ! GCC_DEFAULTS_H */ diff --git a/src/include/diagnostic-core.h b/src/include/diagnostic-core.h new file mode 100644 index 0000000..68ec837 --- /dev/null +++ b/src/include/diagnostic-core.h @@ -0,0 +1,89 @@ +/* Declarations of core diagnostic functionality for code that does + not need to deal with diagnostic contexts or diagnostic info + structures. + Copyright (C) 1998-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_DIAGNOSTIC_CORE_H +#define GCC_DIAGNOSTIC_CORE_H + +#include "input.h" +#include "bversion.h" + +/* Constants used to discriminate diagnostics. */ +typedef enum +{ +#define DEFINE_DIAGNOSTIC_KIND(K, msgid) K, +#include "diagnostic.def" +#undef DEFINE_DIAGNOSTIC_KIND + DK_LAST_DIAGNOSTIC_KIND, + /* This is used for tagging pragma pops in the diagnostic + classification history chain. */ + DK_POP +} diagnostic_t; + +extern const char *progname; + +extern const char *trim_filename (const char *); + +/* If we haven't already defined a front-end-specific diagnostics + style, use the generic one. */ +#ifndef GCC_DIAG_STYLE +#define GCC_DIAG_STYLE __gcc_tdiag__ +#endif +/* None of these functions are suitable for ATTRIBUTE_PRINTF, because + each language front end can extend them with its own set of format + specifiers. We must use custom format checks. */ +#if (ENABLE_CHECKING && GCC_VERSION >= 4001) || GCC_VERSION == BUILDING_GCC_VERSION +#define ATTRIBUTE_GCC_DIAG(m, n) __attribute__ ((__format__ (GCC_DIAG_STYLE, m, n))) ATTRIBUTE_NONNULL(m) +#else +#define ATTRIBUTE_GCC_DIAG(m, n) ATTRIBUTE_NONNULL(m) +#endif +extern void internal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2) + ATTRIBUTE_NORETURN; +/* Pass one of the OPT_W* from options.h as the first parameter. */ +extern bool warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); +extern bool warning_at (location_t, int, const char *, ...) + ATTRIBUTE_GCC_DIAG(3,4); +extern void error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); +extern void error_n (location_t, int, const char *, const char *, ...) + ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5); +extern void error_at (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); +extern void fatal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2) + ATTRIBUTE_NORETURN; +/* Pass one of the OPT_W* from options.h as the second parameter. */ +extern bool pedwarn (location_t, int, const char *, ...) + ATTRIBUTE_GCC_DIAG(3,4); +extern bool permerror (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); +extern void sorry (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); +extern void inform (location_t, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); +extern void inform_n (location_t, int, const char *, const char *, ...) + ATTRIBUTE_GCC_DIAG(3,5) ATTRIBUTE_GCC_DIAG(4,5); +extern void verbatim (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2); +extern bool emit_diagnostic (diagnostic_t, location_t, int, + const char *, ...) ATTRIBUTE_GCC_DIAG(4,5); +extern bool seen_error (void); + +#ifdef BUFSIZ + /* N.B. Unlike all the others, fnotice is just gettext+fprintf, and + therefore it can have ATTRIBUTE_PRINTF. */ +extern void fnotice (FILE *, const char *, ...) + ATTRIBUTE_PRINTF_2; +#endif + +#endif /* ! GCC_DIAGNOSTIC_CORE_H */ diff --git a/src/include/diagnostic.def b/src/include/diagnostic.def new file mode 100644 index 0000000..53179e4 --- /dev/null +++ b/src/include/diagnostic.def @@ -0,0 +1,45 @@ +/* Copyright (C) 2001-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* DK_UNSPECIFIED must be first so it has a value of zero. We never + assign this kind to an actual diagnostic, we only use this in + variables that can hold a kind, to mean they have yet to have a + kind specified. I.e. they're uninitialized. Within the diagnostic + machinery, this kind also means "don't change the existing kind", + meaning "no change is specified". */ +DEFINE_DIAGNOSTIC_KIND (DK_UNSPECIFIED, "") + +/* If a diagnostic is set to DK_IGNORED, it won't get reported at all. + This is used by the diagnostic machinery when it wants to disable a + diagnostic without disabling the option which causes it. */ +DEFINE_DIAGNOSTIC_KIND (DK_IGNORED, "") + +/* The remainder are real diagnostic types. */ +DEFINE_DIAGNOSTIC_KIND (DK_FATAL, "fatal error: ") +DEFINE_DIAGNOSTIC_KIND (DK_ICE, "internal compiler error: ") +DEFINE_DIAGNOSTIC_KIND (DK_ERROR, "error: ") +DEFINE_DIAGNOSTIC_KIND (DK_SORRY, "sorry, unimplemented: ") +DEFINE_DIAGNOSTIC_KIND (DK_WARNING, "warning: ") +DEFINE_DIAGNOSTIC_KIND (DK_ANACHRONISM, "anachronism: ") +DEFINE_DIAGNOSTIC_KIND (DK_NOTE, "note: ") +DEFINE_DIAGNOSTIC_KIND (DK_DEBUG, "debug: ") +/* These two would be re-classified as DK_WARNING or DK_ERROR, so the +prefix does not matter. */ +DEFINE_DIAGNOSTIC_KIND (DK_PEDWARN, "pedwarn: ") +DEFINE_DIAGNOSTIC_KIND (DK_PERMERROR, "permerror: ") + diff --git a/src/include/diagnostic.h b/src/include/diagnostic.h new file mode 100644 index 0000000..f0fae96 --- /dev/null +++ b/src/include/diagnostic.h @@ -0,0 +1,296 @@ +/* Various declarations for language-independent diagnostics subroutines. + Copyright (C) 2000-2013 Free Software Foundation, Inc. + Contributed by Gabriel Dos Reis + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_DIAGNOSTIC_H +#define GCC_DIAGNOSTIC_H + +#include "pretty-print.h" +#include "diagnostic-core.h" + +/* A diagnostic is described by the MESSAGE to send, the FILE and LINE of + its context and its KIND (ice, error, warning, note, ...) See complete + list in diagnostic.def. */ +typedef struct diagnostic_info +{ + text_info message; + location_t location; + unsigned int override_column; + /* Auxiliary data for client. */ + void *x_data; + /* The kind of diagnostic it is about. */ + diagnostic_t kind; + /* Which OPT_* directly controls this diagnostic. */ + int option_index; +} diagnostic_info; + +/* Each time a diagnostic's classification is changed with a pragma, + we record the change and the location of the change in an array of + these structs. */ +typedef struct diagnostic_classification_change_t +{ + location_t location; + int option; + diagnostic_t kind; +} diagnostic_classification_change_t; + +/* Forward declarations. */ +typedef void (*diagnostic_starter_fn) (diagnostic_context *, + diagnostic_info *); +typedef diagnostic_starter_fn diagnostic_finalizer_fn; + +/* This data structure bundles altogether any information relevant to + the context of a diagnostic message. */ +struct diagnostic_context +{ + /* Where most of the diagnostic formatting work is done. */ + pretty_printer *printer; + + /* The number of times we have issued diagnostics. */ + int diagnostic_count[DK_LAST_DIAGNOSTIC_KIND]; + + /* True if we should display the "warnings are being tread as error" + message, usually displayed once per compiler run. */ + bool some_warnings_are_errors; + + /* True if it has been requested that warnings be treated as errors. */ + bool warning_as_error_requested; + + /* The number of option indexes that can be passed to warning() et + al. */ + int n_opts; + + /* For each option index that can be passed to warning() et al + (OPT_* from options.h when using this code with the core GCC + options), this array may contain a new kind that the diagnostic + should be changed to before reporting, or DK_UNSPECIFIED to leave + it as the reported kind, or DK_IGNORED to not report it at + all. */ + diagnostic_t *classify_diagnostic; + + /* History of all changes to the classifications above. This list + is stored in location-order, so we can search it, either + binary-wise or end-to-front, to find the most recent + classification for a given diagnostic, given the location of the + diagnostic. */ + diagnostic_classification_change_t *classification_history; + + /* The size of the above array. */ + int n_classification_history; + + /* For pragma push/pop. */ + int *push_list; + int n_push; + + /* True if we should print the source line with a caret indicating + the location. */ + bool show_caret; + + /* Maximum width of the source line printed. */ + int caret_max_width; + + /* True if we should print the command line option which controls + each diagnostic, if known. */ + bool show_option_requested; + + /* True if we should raise a SIGABRT on errors. */ + bool abort_on_error; + + /* True if we should show the column number on diagnostics. */ + bool show_column; + + /* True if pedwarns are errors. */ + bool pedantic_errors; + + /* True if permerrors are warnings. */ + bool permissive; + + /* The index of the option to associate with turning permerrors into + warnings. */ + int opt_permissive; + + /* True if errors are fatal. */ + bool fatal_errors; + + /* True if all warnings should be disabled. */ + bool dc_inhibit_warnings; + + /* True if warnings should be given in system headers. */ + bool dc_warn_system_headers; + + /* Maximum number of errors to report. */ + unsigned int max_errors; + + /* This function is called before any message is printed out. It is + responsible for preparing message prefix and such. For example, it + might say: + In file included from "/usr/local/include/curses.h:5: + from "/home/gdr/src/nifty_printer.h:56: + ... + */ + diagnostic_starter_fn begin_diagnostic; + + /* This function is called after the diagnostic message is printed. */ + diagnostic_finalizer_fn end_diagnostic; + + /* Client hook to report an internal error. */ + void (*internal_error) (diagnostic_context *, const char *, va_list *); + + /* Client hook to say whether the option controlling a diagnostic is + enabled. Returns nonzero if enabled, zero if disabled. */ + int (*option_enabled) (int, void *); + + /* Client information to pass as second argument to + option_enabled. */ + void *option_state; + + /* Client hook to return the name of an option that controls a + diagnostic. Returns malloced memory. The first diagnostic_t + argument is the kind of diagnostic before any reclassification + (of warnings as errors, etc.); the second is the kind after any + reclassification. May return NULL if no name is to be printed. + May be passed 0 as well as the index of a particular option. */ + char *(*option_name) (diagnostic_context *, int, diagnostic_t, diagnostic_t); + + /* Auxiliary data for client. */ + void *x_data; + + /* Used to detect that the last caret was printed at the same location. */ + location_t last_location; + + /* Used to detect when the input file stack has changed since last + described. */ + const struct line_map *last_module; + + int lock; + + bool inhibit_notes_p; +}; + +static inline void +diagnostic_inhibit_notes (diagnostic_context * context) +{ + context->inhibit_notes_p = true; +} + + +/* Client supplied function to announce a diagnostic. */ +#define diagnostic_starter(DC) (DC)->begin_diagnostic + +/* Client supplied function called after a diagnostic message is + displayed. */ +#define diagnostic_finalizer(DC) (DC)->end_diagnostic + +/* Extension hooks for client. */ +#define diagnostic_context_auxiliary_data(DC) (DC)->x_data +#define diagnostic_info_auxiliary_data(DI) (DI)->x_data + +/* Same as pp_format_decoder. Works on 'diagnostic_context *'. */ +#define diagnostic_format_decoder(DC) ((DC)->printer->format_decoder) + +/* Same as output_prefixing_rule. Works on 'diagnostic_context *'. */ +#define diagnostic_prefixing_rule(DC) ((DC)->printer->wrapping.rule) + +/* Maximum characters per line in automatic line wrapping mode. + Zero means don't wrap lines. */ +#define diagnostic_line_cutoff(DC) ((DC)->printer->wrapping.line_cutoff) + +#define diagnostic_flush_buffer(DC) pp_base_flush ((DC)->printer) + +/* True if the last module or file in which a diagnostic was reported is + different from the current one. */ +#define diagnostic_last_module_changed(DC, MAP) \ + ((DC)->last_module != MAP) + +/* Remember the current module or file as being the last one in which we + report a diagnostic. */ +#define diagnostic_set_last_module(DC, MAP) \ + (DC)->last_module = MAP + +/* Raise SIGABRT on any diagnostic of severity DK_ERROR or higher. */ +#define diagnostic_abort_on_error(DC) \ + (DC)->abort_on_error = true + +/* This diagnostic_context is used by front-ends that directly output + diagnostic messages without going through `error', `warning', + and similar functions. */ +extern diagnostic_context *global_dc; + +/* The total count of a KIND of diagnostics emitted so far. */ +#define diagnostic_kind_count(DC, DK) (DC)->diagnostic_count[(int) (DK)] + +/* The number of errors that have been issued so far. Ideally, these + would take a diagnostic_context as an argument. */ +#define errorcount diagnostic_kind_count (global_dc, DK_ERROR) +/* Similarly, but for warnings. */ +#define warningcount diagnostic_kind_count (global_dc, DK_WARNING) +/* Similarly, but for sorrys. */ +#define sorrycount diagnostic_kind_count (global_dc, DK_SORRY) + +/* Returns nonzero if warnings should be emitted. */ +#define diagnostic_report_warnings_p(DC, LOC) \ + (!(DC)->dc_inhibit_warnings \ + && !(in_system_header_at (LOC) && !(DC)->dc_warn_system_headers)) + +#define report_diagnostic(D) diagnostic_report_diagnostic (global_dc, D) + +/* Override the column number to be used for reporting a + diagnostic. */ +#define diagnostic_override_column(DI, COL) (DI)->override_column = (COL) + +/* Override the option index to be used for reporting a + diagnostic. */ +#define diagnostic_override_option_index(DI, OPTIDX) \ + ((DI)->option_index = (OPTIDX)) + +/* Diagnostic related functions. */ +extern void diagnostic_initialize (diagnostic_context *, int); +extern void diagnostic_finish (diagnostic_context *); +extern void diagnostic_report_current_module (diagnostic_context *, location_t); +extern void diagnostic_show_locus (diagnostic_context *, const diagnostic_info *); + +/* Force diagnostics controlled by OPTIDX to be kind KIND. */ +extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *, + int /* optidx */, + diagnostic_t /* kind */, + location_t); +extern void diagnostic_push_diagnostics (diagnostic_context *, location_t); +extern void diagnostic_pop_diagnostics (diagnostic_context *, location_t); +extern bool diagnostic_report_diagnostic (diagnostic_context *, + diagnostic_info *); +#ifdef ATTRIBUTE_GCC_DIAG +extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *, + location_t, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0); +extern void diagnostic_set_info_translated (diagnostic_info *, const char *, + va_list *, location_t, + diagnostic_t) + ATTRIBUTE_GCC_DIAG(2,0); +extern void diagnostic_append_note (diagnostic_context *, location_t, + const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); +#endif +extern char *diagnostic_build_prefix (diagnostic_context *, const diagnostic_info *); +void default_diagnostic_starter (diagnostic_context *, diagnostic_info *); +void default_diagnostic_finalizer (diagnostic_context *, diagnostic_info *); +void diagnostic_set_caret_max_width (diagnostic_context *context, int value); + + +/* Pure text formatting support functions. */ +extern char *file_name_as_prefix (const char *); + +#endif /* ! GCC_DIAGNOSTIC_H */ diff --git a/src/include/double-int.h b/src/include/double-int.h new file mode 100644 index 0000000..5c425a8 --- /dev/null +++ b/src/include/double-int.h @@ -0,0 +1,457 @@ +/* Operations with long integers. + Copyright (C) 2006-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3, or (at your option) any +later version. + +GCC is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef DOUBLE_INT_H +#define DOUBLE_INT_H + +/* A large integer is currently represented as a pair of HOST_WIDE_INTs. + It therefore represents a number with precision of + 2 * HOST_BITS_PER_WIDE_INT bits (it is however possible that the + internal representation will change, if numbers with greater precision + are needed, so the users should not rely on it). The representation does + not contain any information about signedness of the represented value, so + it can be used to represent both signed and unsigned numbers. For + operations where the results depend on signedness (division, comparisons), + it must be specified separately. For each such operation, there are three + versions of the function -- double_int_op, that takes an extra UNS argument + giving the signedness of the values, and double_int_sop and double_int_uop + that stand for its specializations for signed and unsigned values. + + You may also represent with numbers in smaller precision using double_int. + You however need to use double_int_ext (that fills in the bits of the + number over the prescribed precision with zeros or with the sign bit) before + operations that do not perform arithmetics modulo 2^precision (comparisons, + division), and possibly before storing the results, if you want to keep + them in some canonical form). In general, the signedness of double_int_ext + should match the signedness of the operation. + + ??? The components of double_int differ in signedness mostly for + historical reasons (they replace an older structure used to represent + numbers with precision higher than HOST_WIDE_INT). It might be less + confusing to have them both signed or both unsigned. */ + +struct double_int +{ + /* Normally, we would define constructors to create instances. + Two things prevent us from doing so. + First, defining a constructor makes the class non-POD in C++03, + and we certainly want double_int to be a POD. + Second, the GCC conding conventions prefer explicit conversion, + and explicit conversion operators are not available until C++11. */ + + static double_int from_uhwi (unsigned HOST_WIDE_INT cst); + static double_int from_shwi (HOST_WIDE_INT cst); + static double_int from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low); + + /* Construct from a fuffer of length LEN. BUFFER will be read according + to byte endianess and word endianess. */ + static double_int from_buffer (const unsigned char *buffer, int len); + + /* No copy assignment operator or destructor to keep the type a POD. */ + + /* There are some special value-creation static member functions. */ + + static double_int mask (unsigned prec); + static double_int max_value (unsigned int prec, bool uns); + static double_int min_value (unsigned int prec, bool uns); + + /* The following functions are mutating operations. */ + + double_int &operator ++ (); // prefix + double_int &operator -- (); // prefix + double_int &operator *= (double_int); + double_int &operator += (double_int); + double_int &operator -= (double_int); + double_int &operator &= (double_int); + double_int &operator ^= (double_int); + double_int &operator |= (double_int); + + /* The following functions are non-mutating operations. */ + + /* Conversion functions. */ + + HOST_WIDE_INT to_shwi () const; + unsigned HOST_WIDE_INT to_uhwi () const; + + /* Conversion query functions. */ + + bool fits_uhwi () const; + bool fits_shwi () const; + bool fits_hwi (bool uns) const; + + /* Attribute query functions. */ + + int trailing_zeros () const; + int popcount () const; + + /* Arithmetic query operations. */ + + bool multiple_of (double_int, bool, double_int *) const; + + /* Arithmetic operation functions. */ + + /* The following operations perform arithmetics modulo 2^precision, so you + do not need to call .ext between them, even if you are representing + numbers with precision less than HOST_BITS_PER_DOUBLE_INT bits. */ + + double_int set_bit (unsigned) const; + double_int mul_with_sign (double_int, bool unsigned_p, bool *overflow) const; + double_int wide_mul_with_sign (double_int, bool unsigned_p, + double_int *higher, bool *overflow) const; + double_int add_with_sign (double_int, bool unsigned_p, bool *overflow) const; + double_int sub_with_overflow (double_int, bool *overflow) const; + double_int neg_with_overflow (bool *overflow) const; + + double_int operator * (double_int) const; + double_int operator + (double_int) const; + double_int operator - (double_int) const; + double_int operator - () const; + double_int operator ~ () const; + double_int operator & (double_int) const; + double_int operator | (double_int) const; + double_int operator ^ (double_int) const; + double_int and_not (double_int) const; + + double_int lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const; + double_int rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const; + double_int alshift (HOST_WIDE_INT count, unsigned int prec) const; + double_int arshift (HOST_WIDE_INT count, unsigned int prec) const; + double_int llshift (HOST_WIDE_INT count, unsigned int prec) const; + double_int lrshift (HOST_WIDE_INT count, unsigned int prec) const; + double_int lrotate (HOST_WIDE_INT count, unsigned int prec) const; + double_int rrotate (HOST_WIDE_INT count, unsigned int prec) const; + + /* You must ensure that double_int::ext is called on the operands + of the following operations, if the precision of the numbers + is less than HOST_BITS_PER_DOUBLE_INT bits. */ + + double_int div (double_int, bool, unsigned) const; + double_int sdiv (double_int, unsigned) const; + double_int udiv (double_int, unsigned) const; + double_int mod (double_int, bool, unsigned) const; + double_int smod (double_int, unsigned) const; + double_int umod (double_int, unsigned) const; + double_int divmod_with_overflow (double_int, bool, unsigned, + double_int *, bool *) const; + double_int divmod (double_int, bool, unsigned, double_int *) const; + double_int sdivmod (double_int, unsigned, double_int *) const; + double_int udivmod (double_int, unsigned, double_int *) const; + + /* Precision control functions. */ + + double_int ext (unsigned prec, bool uns) const; + double_int zext (unsigned prec) const; + double_int sext (unsigned prec) const; + + /* Comparative functions. */ + + bool is_zero () const; + bool is_one () const; + bool is_minus_one () const; + bool is_negative () const; + + int cmp (double_int b, bool uns) const; + int ucmp (double_int b) const; + int scmp (double_int b) const; + + bool ult (double_int b) const; + bool ule (double_int b) const; + bool ugt (double_int b) const; + bool slt (double_int b) const; + bool sle (double_int b) const; + bool sgt (double_int b) const; + + double_int max (double_int b, bool uns); + double_int smax (double_int b); + double_int umax (double_int b); + + double_int min (double_int b, bool uns); + double_int smin (double_int b); + double_int umin (double_int b); + + bool operator == (double_int cst2) const; + bool operator != (double_int cst2) const; + + /* Please migrate away from using these member variables publically. */ + + unsigned HOST_WIDE_INT low; + HOST_WIDE_INT high; + +}; + +#define HOST_BITS_PER_DOUBLE_INT (2 * HOST_BITS_PER_WIDE_INT) + +/* Constructors and conversions. */ + +/* Constructs double_int from integer CST. The bits over the precision of + HOST_WIDE_INT are filled with the sign bit. */ + +inline double_int +double_int::from_shwi (HOST_WIDE_INT cst) +{ + double_int r; + r.low = (unsigned HOST_WIDE_INT) cst; + r.high = cst < 0 ? -1 : 0; + return r; +} + +/* Some useful constants. */ +/* FIXME(crowl): Maybe remove after converting callers? + The problem is that a named constant would not be as optimizable, + while the functional syntax is more verbose. */ + +#define double_int_minus_one (double_int::from_shwi (-1)) +#define double_int_zero (double_int::from_shwi (0)) +#define double_int_one (double_int::from_shwi (1)) +#define double_int_two (double_int::from_shwi (2)) +#define double_int_ten (double_int::from_shwi (10)) + +/* Constructs double_int from unsigned integer CST. The bits over the + precision of HOST_WIDE_INT are filled with zeros. */ + +inline double_int +double_int::from_uhwi (unsigned HOST_WIDE_INT cst) +{ + double_int r; + r.low = cst; + r.high = 0; + return r; +} + +inline double_int +double_int::from_pair (HOST_WIDE_INT high, unsigned HOST_WIDE_INT low) +{ + double_int r; + r.low = low; + r.high = high; + return r; +} + +inline double_int & +double_int::operator ++ () +{ + *this += double_int_one; + return *this; +} + +inline double_int & +double_int::operator -- () +{ + *this -= double_int_one; + return *this; +} + +inline double_int & +double_int::operator *= (double_int b) +{ + *this = *this * b; + return *this; +} + +inline double_int & +double_int::operator += (double_int b) +{ + *this = *this + b; + return *this; +} + +inline double_int & +double_int::operator -= (double_int b) +{ + *this = *this - b; + return *this; +} + +inline double_int & +double_int::operator &= (double_int b) +{ + *this = *this & b; + return *this; +} + +inline double_int & +double_int::operator ^= (double_int b) +{ + *this = *this ^ b; + return *this; +} + +inline double_int & +double_int::operator |= (double_int b) +{ + *this = *this | b; + return *this; +} + +/* Returns value of CST as a signed number. CST must satisfy + double_int::fits_signed. */ + +inline HOST_WIDE_INT +double_int::to_shwi () const +{ + return (HOST_WIDE_INT) low; +} + +/* Returns value of CST as an unsigned number. CST must satisfy + double_int::fits_unsigned. */ + +inline unsigned HOST_WIDE_INT +double_int::to_uhwi () const +{ + return low; +} + +/* Returns true if CST fits in unsigned HOST_WIDE_INT. */ + +inline bool +double_int::fits_uhwi () const +{ + return high == 0; +} + +/* Logical operations. */ + +/* Returns ~A. */ + +inline double_int +double_int::operator ~ () const +{ + double_int result; + result.low = ~low; + result.high = ~high; + return result; +} + +/* Returns A | B. */ + +inline double_int +double_int::operator | (double_int b) const +{ + double_int result; + result.low = low | b.low; + result.high = high | b.high; + return result; +} + +/* Returns A & B. */ + +inline double_int +double_int::operator & (double_int b) const +{ + double_int result; + result.low = low & b.low; + result.high = high & b.high; + return result; +} + +/* Returns A & ~B. */ + +inline double_int +double_int::and_not (double_int b) const +{ + double_int result; + result.low = low & ~b.low; + result.high = high & ~b.high; + return result; +} + +/* Returns A ^ B. */ + +inline double_int +double_int::operator ^ (double_int b) const +{ + double_int result; + result.low = low ^ b.low; + result.high = high ^ b.high; + return result; +} + +void dump_double_int (FILE *, double_int, bool); + +#define ALL_ONES (~((unsigned HOST_WIDE_INT) 0)) + +/* The operands of the following comparison functions must be processed + with double_int_ext, if their precision is less than + HOST_BITS_PER_DOUBLE_INT bits. */ + +/* Returns true if CST is zero. */ + +inline bool +double_int::is_zero () const +{ + return low == 0 && high == 0; +} + +/* Returns true if CST is one. */ + +inline bool +double_int::is_one () const +{ + return low == 1 && high == 0; +} + +/* Returns true if CST is minus one. */ + +inline bool +double_int::is_minus_one () const +{ + return low == ALL_ONES && high == -1; +} + +/* Returns true if CST is negative. */ + +inline bool +double_int::is_negative () const +{ + return high < 0; +} + +/* Returns true if CST1 == CST2. */ + +inline bool +double_int::operator == (double_int cst2) const +{ + return low == cst2.low && high == cst2.high; +} + +/* Returns true if CST1 != CST2. */ + +inline bool +double_int::operator != (double_int cst2) const +{ + return low != cst2.low || high != cst2.high; +} + +/* Return number of set bits of CST. */ + +inline int +double_int::popcount () const +{ + return popcount_hwi (high) + popcount_hwi (low); +} + + +#ifndef GENERATOR_FILE +/* Conversion to and from GMP integer representations. */ + +void mpz_set_double_int (mpz_t, double_int, bool); +double_int mpz_get_double_int (const_tree, mpz_t, bool); +#endif + +#endif /* DOUBLE_INT_H */ diff --git a/src/include/dumpfile.h b/src/include/dumpfile.h new file mode 100644 index 0000000..b912ccf --- /dev/null +++ b/src/include/dumpfile.h @@ -0,0 +1,166 @@ +/* Definitions for the shared dumpfile. + Copyright (C) 2004-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + + +#ifndef GCC_DUMPFILE_H +#define GCC_DUMPFILE_H 1 + +#include "line-map.h" + +/* Different tree dump places. When you add new tree dump places, + extend the DUMP_FILES array in dumpfile.c. */ +enum tree_dump_index +{ + TDI_none, /* No dump */ + TDI_cgraph, /* dump function call graph. */ + TDI_tu, /* dump the whole translation unit. */ + TDI_class, /* dump class hierarchy. */ + TDI_original, /* dump each function before optimizing it */ + TDI_generic, /* dump each function after genericizing it */ + TDI_nested, /* dump each function after unnesting it */ + TDI_tree_all, /* enable all the GENERIC/GIMPLE dumps. */ + TDI_rtl_all, /* enable all the RTL dumps. */ + TDI_ipa_all, /* enable all the IPA dumps. */ + + TDI_end +}; + +/* Bit masks to control dumping. Not all values are applicable to all + dumps. Add new ones at the end. When you define new values, extend + the DUMP_OPTIONS array in dumpfile.c. The TDF_* flags coexist with + MSG_* flags (for -fopt-info) and the bit values must be chosen to + allow that. */ +#define TDF_ADDRESS (1 << 0) /* dump node addresses */ +#define TDF_SLIM (1 << 1) /* don't go wild following links */ +#define TDF_RAW (1 << 2) /* don't unparse the function */ +#define TDF_DETAILS (1 << 3) /* show more detailed info about + each pass */ +#define TDF_STATS (1 << 4) /* dump various statistics about + each pass */ +#define TDF_BLOCKS (1 << 5) /* display basic block boundaries */ +#define TDF_VOPS (1 << 6) /* display virtual operands */ +#define TDF_LINENO (1 << 7) /* display statement line numbers */ +#define TDF_UID (1 << 8) /* display decl UIDs */ + +#define TDF_TREE (1 << 9) /* is a tree dump */ +#define TDF_RTL (1 << 10) /* is a RTL dump */ +#define TDF_IPA (1 << 11) /* is an IPA dump */ +#define TDF_STMTADDR (1 << 12) /* Address of stmt. */ + +#define TDF_GRAPH (1 << 13) /* a graph dump is being emitted */ +#define TDF_MEMSYMS (1 << 14) /* display memory symbols in expr. + Implies TDF_VOPS. */ + +#define TDF_DIAGNOSTIC (1 << 15) /* A dump to be put in a diagnostic + message. */ +#define TDF_VERBOSE (1 << 16) /* A dump that uses the full tree + dumper to print stmts. */ +#define TDF_RHS_ONLY (1 << 17) /* a flag to only print the RHS of + a gimple stmt. */ +#define TDF_ASMNAME (1 << 18) /* display asm names of decls */ +#define TDF_EH (1 << 19) /* display EH region number + holding this gimple statement. */ +#define TDF_NOUID (1 << 20) /* omit UIDs from dumps. */ +#define TDF_ALIAS (1 << 21) /* display alias information */ +#define TDF_ENUMERATE_LOCALS (1 << 22) /* Enumerate locals by uid. */ +#define TDF_CSELIB (1 << 23) /* Dump cselib details. */ +#define TDF_SCEV (1 << 24) /* Dump SCEV details. */ +#define TDF_COMMENT (1 << 25) /* Dump lines with prefix ";;" */ +#define MSG_OPTIMIZED_LOCATIONS (1 << 26) /* -fopt-info optimized sources */ +#define MSG_MISSED_OPTIMIZATION (1 << 27) /* missed opportunities */ +#define MSG_NOTE (1 << 28) /* general optimization info */ +#define MSG_ALL (MSG_OPTIMIZED_LOCATIONS | MSG_MISSED_OPTIMIZATION \ + | MSG_NOTE) + + +/* Flags to control high-level -fopt-info dumps. Usually these flags + define a group of passes. An optimization pass can be part of + multiple groups. */ +#define OPTGROUP_NONE (0) +#define OPTGROUP_IPA (1 << 1) /* IPA optimization passes */ +#define OPTGROUP_LOOP (1 << 2) /* Loop optimization passes */ +#define OPTGROUP_INLINE (1 << 3) /* Inlining passes */ +#define OPTGROUP_VEC (1 << 4) /* Vectorization passes */ +#define OPTGROUP_ALL (OPTGROUP_IPA | OPTGROUP_LOOP | OPTGROUP_INLINE \ + | OPTGROUP_VEC) + +/* Define a tree dump switch. */ +struct dump_file_info +{ + const char *suffix; /* suffix to give output file. */ + const char *swtch; /* command line dump switch */ + const char *glob; /* command line glob */ + const char *pfilename; /* filename for the pass-specific stream */ + const char *alt_filename; /* filename for the -fopt-info stream */ + FILE *pstream; /* pass-specific dump stream */ + FILE *alt_stream; /* -fopt-info stream */ + int pflags; /* dump flags */ + int optgroup_flags; /* optgroup flags for -fopt-info */ + int alt_flags; /* flags for opt-info */ + int pstate; /* state of pass-specific stream */ + int alt_state; /* state of the -fopt-info stream */ + int num; /* dump file number */ +}; + +/* In dumpfile.c */ +extern char *get_dump_file_name (int); +extern int dump_initialized_p (int); +extern FILE *dump_begin (int, int *); +extern void dump_end (int, FILE *); +extern int dump_start (int, int *); +extern void dump_finish (int); +extern void dump_node (const_tree, int, FILE *); +extern int dump_switch_p (const char *); +extern int opt_info_switch_p (const char *); +extern const char *dump_flag_name (int); +extern void dump_printf (int, const char *, ...) ATTRIBUTE_PRINTF_2; +extern void dump_printf_loc (int, source_location, + const char *, ...) ATTRIBUTE_PRINTF_3; +extern void dump_basic_block (int, basic_block, int); +extern void dump_generic_expr_loc (int, source_location, int, tree); +extern void dump_generic_expr (int, int, tree); +extern void dump_gimple_stmt_loc (int, source_location, int, gimple, int); +extern void dump_gimple_stmt (int, int, gimple, int); +extern void print_combine_total_stats (void); +extern unsigned int dump_register (const char *, const char *, const char *, + int, int); +extern bool enable_rtl_dump_file (void); + +/* In combine.c */ +extern void dump_combine_total_stats (FILE *); +/* In cfghooks.c */ +extern void dump_bb (FILE *, basic_block, int, int); + +/* Global variables used to communicate with passes. */ +extern FILE *dump_file; +extern FILE *alt_dump_file; +extern int dump_flags; +extern const char *dump_file_name; + +/* Return the dump_file_info for the given phase. */ +extern struct dump_file_info *get_dump_file_info (int); + +/* Return true if any of the dumps is enabled, false otherwise. */ +static inline bool +dump_enabled_p (void) +{ + return (dump_file || alt_dump_file); +} + +#endif /* GCC_DUMPFILE_H */ diff --git a/src/include/emit-rtl.h b/src/include/emit-rtl.h new file mode 100644 index 0000000..81bb334 --- /dev/null +++ b/src/include/emit-rtl.h @@ -0,0 +1,119 @@ +/* Exported functions from emit-rtl.c + Copyright (C) 2004-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_EMIT_RTL_H +#define GCC_EMIT_RTL_H + +/* Return whether two MEM_ATTRs are equal. */ +bool mem_attrs_eq_p (const struct mem_attrs *, const struct mem_attrs *); + +/* Set the alias set of MEM to SET. */ +extern void set_mem_alias_set (rtx, alias_set_type); + +/* Set the alignment of MEM to ALIGN bits. */ +extern void set_mem_align (rtx, unsigned int); + +/* Set the address space of MEM to ADDRSPACE. */ +extern void set_mem_addr_space (rtx, addr_space_t); + +/* Set the expr for MEM to EXPR. */ +extern void set_mem_expr (rtx, tree); + +/* Set the offset for MEM to OFFSET. */ +extern void set_mem_offset (rtx, HOST_WIDE_INT); + +/* Clear the offset recorded for MEM. */ +extern void clear_mem_offset (rtx); + +/* Set the size for MEM to SIZE. */ +extern void set_mem_size (rtx, HOST_WIDE_INT); + +/* Clear the size recorded for MEM. */ +extern void clear_mem_size (rtx); + +/* Set the attributes for MEM appropriate for a spill slot. */ +extern void set_mem_attrs_for_spill (rtx); +extern tree get_spill_slot_decl (bool); + +/* Return a memory reference like MEMREF, but with its address changed to + ADDR. The caller is asserting that the actual piece of memory pointed + to is the same, just the form of the address is being changed, such as + by putting something into a register. */ +extern rtx replace_equiv_address (rtx, rtx); + +/* Likewise, but the reference is not required to be valid. */ +extern rtx replace_equiv_address_nv (rtx, rtx); + +extern rtx gen_blockage (void); +extern rtvec gen_rtvec (int, ...); +extern rtx copy_insn_1 (rtx); +extern rtx copy_insn (rtx); +extern rtx copy_delay_slot_insn (rtx); +extern rtx gen_int_mode (HOST_WIDE_INT, enum machine_mode); +extern rtx emit_copy_of_insn_after (rtx, rtx); +extern void set_reg_attrs_from_value (rtx, rtx); +extern void set_reg_attrs_for_parm (rtx, rtx); +extern void set_reg_attrs_for_decl_rtl (tree t, rtx x); +extern void adjust_reg_mode (rtx, enum machine_mode); +extern int mem_expr_equal_p (const_tree, const_tree); + +extern bool need_atomic_barrier_p (enum memmodel, bool); + +/* Return the first insn of the current sequence or current function. */ + +static inline rtx +get_insns (void) +{ + return crtl->emit.x_first_insn; +} + +/* Specify a new insn as the first in the chain. */ + +static inline void +set_first_insn (rtx insn) +{ + gcc_checking_assert (!insn || !PREV_INSN (insn)); + crtl->emit.x_first_insn = insn; +} + +/* Return the last insn emitted in current sequence or current function. */ + +static inline rtx +get_last_insn (void) +{ + return crtl->emit.x_last_insn; +} + +/* Specify a new insn as the last in the chain. */ + +static inline void +set_last_insn (rtx insn) +{ + gcc_checking_assert (!insn || !NEXT_INSN (insn)); + crtl->emit.x_last_insn = insn; +} + +/* Return a number larger than any instruction's uid in this function. */ + +static inline int +get_max_uid (void) +{ + return crtl->emit.x_cur_insn_uid; +} +#endif /* GCC_EMIT_RTL_H */ diff --git a/src/include/except.h b/src/include/except.h new file mode 100644 index 0000000..bc9654a --- /dev/null +++ b/src/include/except.h @@ -0,0 +1,335 @@ +/* Exception Handling interface routines. + Copyright (C) 1996-2013 Free Software Foundation, Inc. + Contributed by Mike Stump . + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* No include guards here, but define an include file marker anyway, so + that the compiler can keep track of where this file is included. This + is e.g. used to avoid including this file in front-end specific files. */ +#ifndef GCC_EXCEPT_H +# define GCC_EXCEPT_H +#endif + +#include "hashtab.h" + +struct function; +struct eh_region_d; +struct pointer_map_t; + +/* The type of an exception region. */ +enum eh_region_type +{ + /* CLEANUP regions implement e.g. destructors run when exiting a block. + They can be generated from both GIMPLE_TRY_FINALLY and GIMPLE_TRY_CATCH + nodes. It is expected by the runtime that cleanup regions will *not* + resume normal program flow, but will continue propagation of the + exception. */ + ERT_CLEANUP, + + /* TRY regions implement catching an exception. The list of types associated + with the attached catch handlers is examined in order by the runtime and + control is transferred to the appropriate handler. Note that a NULL type + list is a catch-all handler, and that it will catch *all* exceptions + including those originating from a different language. */ + ERT_TRY, + + /* ALLOWED_EXCEPTIONS regions implement exception filtering, e.g. the + throw(type-list) specification that can be added to C++ functions. + The runtime examines the thrown exception vs the type list, and if + the exception does not match, transfers control to the handler. The + normal handler for C++ calls __cxa_call_unexpected. */ + ERT_ALLOWED_EXCEPTIONS, + + /* MUST_NOT_THROW regions prevent all exceptions from propagating. This + region type is used in C++ to surround destructors being run inside a + CLEANUP region. This differs from an ALLOWED_EXCEPTIONS region with + an empty type list in that the runtime is prepared to terminate the + program directly. We only generate code for MUST_NOT_THROW regions + along control paths that are already handling an exception within the + current function. */ + ERT_MUST_NOT_THROW +}; + + +/* A landing pad for a given exception region. Any transfer of control + from the EH runtime to the function happens at a landing pad. */ + +struct GTY(()) eh_landing_pad_d +{ + /* The linked list of all landing pads associated with the region. */ + struct eh_landing_pad_d *next_lp; + + /* The region with which this landing pad is associated. */ + struct eh_region_d *region; + + /* At the gimple level, the location to which control will be transferred + for this landing pad. There can be both EH and normal edges into the + block containing the post-landing-pad label. */ + tree post_landing_pad; + + /* At the rtl level, the location to which the runtime will transfer + control. This differs from the post-landing-pad in that the target's + EXCEPTION_RECEIVER pattern will be expanded here, as well as other + bookkeeping specific to exceptions. There must not be normal edges + into the block containing the landing-pad label. */ + rtx landing_pad; + + /* The index of this landing pad within fun->eh->lp_array. */ + int index; +}; + +/* A catch handler associated with an ERT_TRY region. */ + +struct GTY(()) eh_catch_d +{ + /* The double-linked list of all catch handlers for the region. */ + struct eh_catch_d *next_catch; + struct eh_catch_d *prev_catch; + + /* A TREE_LIST of runtime type objects that this catch handler + will catch, or NULL if all exceptions are caught. */ + tree type_list; + + /* A TREE_LIST of INTEGER_CSTs that correspond to the type_list entries, + having been mapped by assign_filter_values. These integers are to be + compared against the __builtin_eh_filter value. */ + tree filter_list; + + /* The code that should be executed if this catch handler matches the + thrown exception. This label is only maintained until + pass_lower_eh_dispatch, at which point it is cleared. */ + tree label; +}; + +/* Describes one exception region. */ + +struct GTY(()) eh_region_d +{ + /* The immediately surrounding region. */ + struct eh_region_d *outer; + + /* The list of immediately contained regions. */ + struct eh_region_d *inner; + struct eh_region_d *next_peer; + + /* The index of this region within fun->eh->region_array. */ + int index; + + /* Each region does exactly one thing. */ + enum eh_region_type type; + + /* Holds the action to perform based on the preceding type. */ + union eh_region_u { + struct eh_region_u_try { + /* The double-linked list of all catch handlers for this region. */ + struct eh_catch_d *first_catch; + struct eh_catch_d *last_catch; + } GTY ((tag ("ERT_TRY"))) eh_try; + + struct eh_region_u_allowed { + /* A TREE_LIST of runtime type objects allowed to pass. */ + tree type_list; + /* The code that should be executed if the thrown exception does + not match the type list. This label is only maintained until + pass_lower_eh_dispatch, at which point it is cleared. */ + tree label; + /* The integer that will be passed by the runtime to signal that + we should execute the code at LABEL. This integer is assigned + by assign_filter_values and is to be compared against the + __builtin_eh_filter value. */ + int filter; + } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed; + + struct eh_region_u_must_not_throw { + /* A function decl to be invoked if this region is actually reachable + from within the function, rather than implementable from the runtime. + The normal way for this to happen is for there to be a CLEANUP region + contained within this MUST_NOT_THROW region. Note that if the + runtime handles the MUST_NOT_THROW region, we have no control over + what termination function is called; it will be decided by the + personality function in effect for this CIE. */ + tree failure_decl; + /* The location assigned to the call of FAILURE_DECL, if expanded. */ + location_t failure_loc; + } GTY ((tag ("ERT_MUST_NOT_THROW"))) must_not_throw; + } GTY ((desc ("%0.type"))) u; + + /* The list of landing pads associated with this region. */ + struct eh_landing_pad_d *landing_pads; + + /* EXC_PTR and FILTER values copied from the runtime for this region. + Each region gets its own psuedos so that if there are nested exceptions + we do not overwrite the values of the first exception. */ + rtx exc_ptr_reg, filter_reg; + + /* True if this region should use __cxa_end_cleanup instead + of _Unwind_Resume. */ + bool use_cxa_end_cleanup; +}; + +typedef struct eh_landing_pad_d *eh_landing_pad; +typedef struct eh_catch_d *eh_catch; +typedef struct eh_region_d *eh_region; + + + + +/* The exception status for each function. */ + +struct GTY(()) eh_status +{ + /* The tree of all regions for this function. */ + eh_region region_tree; + + /* The same information as an indexable array. */ + vec *region_array; + + /* The landing pads as an indexable array. */ + vec *lp_array; + + /* At the gimple level, a mapping from gimple statement to landing pad + or must-not-throw region. See record_stmt_eh_region. */ + htab_t GTY((param_is (struct throw_stmt_node))) throw_stmt_table; + + /* All of the runtime type data used by the function. These objects + are emitted to the lang-specific-data-area for the function. */ + vec *ttype_data; + + /* The table of all action chains. These encode the eh_region tree in + a compact form for use by the runtime, and is also emitted to the + lang-specific-data-area. Note that the ARM EABI uses a different + format for the encoding than all other ports. */ + union eh_status_u { + vec *GTY((tag ("1"))) arm_eabi; + vec *GTY((tag ("0"))) other; + } GTY ((desc ("targetm.arm_eabi_unwinder"))) ehspec_data; +}; + + +/* Invokes CALLBACK for every exception handler label. Only used by old + loop hackery; should not be used by new code. */ +extern void for_each_eh_label (void (*) (rtx)); + +extern void init_eh_for_function (void); + +extern void remove_eh_landing_pad (eh_landing_pad); +extern void remove_eh_handler (eh_region); +extern void remove_unreachable_eh_regions (sbitmap); + +extern bool current_function_has_exception_handlers (void); +extern void output_function_exception_table (const char *); + +extern rtx expand_builtin_eh_pointer (tree); +extern rtx expand_builtin_eh_filter (tree); +extern rtx expand_builtin_eh_copy_values (tree); +extern void expand_builtin_unwind_init (void); +extern rtx expand_builtin_eh_return_data_regno (tree); +extern rtx expand_builtin_extract_return_addr (tree); +extern void expand_builtin_init_dwarf_reg_sizes (tree); +extern rtx expand_builtin_frob_return_addr (tree); +extern rtx expand_builtin_dwarf_sp_column (void); +extern void expand_builtin_eh_return (tree, tree); +extern void expand_eh_return (void); +extern rtx expand_builtin_extend_pointer (tree); +extern void expand_dw2_landing_pad_for_region (eh_region); + +typedef tree (*duplicate_eh_regions_map) (tree, void *); +extern struct pointer_map_t *duplicate_eh_regions + (struct function *, eh_region, int, duplicate_eh_regions_map, void *); + +extern void sjlj_emit_function_exit_after (rtx); + +extern eh_region gen_eh_region_cleanup (eh_region); +extern eh_region gen_eh_region_try (eh_region); +extern eh_region gen_eh_region_allowed (eh_region, tree); +extern eh_region gen_eh_region_must_not_throw (eh_region); + +extern eh_catch gen_eh_region_catch (eh_region, tree); +extern eh_landing_pad gen_eh_landing_pad (eh_region); + +extern eh_region get_eh_region_from_number_fn (struct function *, int); +extern eh_region get_eh_region_from_number (int); +extern eh_landing_pad get_eh_landing_pad_from_number_fn (struct function*,int); +extern eh_landing_pad get_eh_landing_pad_from_number (int); +extern eh_region get_eh_region_from_lp_number_fn (struct function *, int); +extern eh_region get_eh_region_from_lp_number (int); + +extern eh_region eh_region_outermost (struct function *, eh_region, eh_region); + +extern void make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr); +extern void make_reg_eh_region_note_nothrow_nononlocal (rtx); + +extern void verify_eh_tree (struct function *); +extern void dump_eh_tree (FILE *, struct function *); +void debug_eh_tree (struct function *); +extern void add_type_for_runtime (tree); +extern tree lookup_type_for_runtime (tree); +extern void assign_filter_values (void); + +extern eh_region get_eh_region_from_rtx (const_rtx); +extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx); + +extern void finish_eh_generation (void); + +struct GTY(()) throw_stmt_node { + gimple stmt; + int lp_nr; +}; + +extern struct htab *get_eh_throw_stmt_table (struct function *); +extern void set_eh_throw_stmt_table (struct function *, struct htab *); + +enum eh_personality_kind { + eh_personality_none, + eh_personality_any, + eh_personality_lang +}; + +extern enum eh_personality_kind +function_needs_eh_personality (struct function *); + +/* Pre-order iteration within the eh_region tree. */ + +static inline eh_region +ehr_next (eh_region r, eh_region start) +{ + if (r->inner) + r = r->inner; + else if (r->next_peer && r != start) + r = r->next_peer; + else + { + do + { + r = r->outer; + if (r == start) + return NULL; + } + while (r->next_peer == NULL); + r = r->next_peer; + } + return r; +} + +#define FOR_ALL_EH_REGION_AT(R, START) \ + for ((R) = (START); (R) != NULL; (R) = ehr_next (R, START)) + +#define FOR_ALL_EH_REGION_FN(R, FN) \ + for ((R) = (FN)->eh->region_tree; (R) != NULL; (R) = ehr_next (R, NULL)) + +#define FOR_ALL_EH_REGION(R) FOR_ALL_EH_REGION_FN (R, cfun) diff --git a/src/include/filenames.h b/src/include/filenames.h new file mode 100644 index 0000000..e799a51 --- /dev/null +++ b/src/include/filenames.h @@ -0,0 +1,97 @@ +/* Macros for taking apart, interpreting and processing file names. + + These are here because some non-Posix (a.k.a. DOSish) systems have + drive letter brain-damage at the beginning of an absolute file name, + use forward- and back-slash in path names interchangeably, and + some of them have case-insensitive file names. + + Copyright 2000, 2001, 2007, 2010 Free Software Foundation, Inc. + +This file is part of BFD, the Binary File Descriptor library. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef FILENAMES_H +#define FILENAMES_H + +#include "hashtab.h" /* for hashval_t */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__MSDOS__) || defined(_WIN32) || defined(__OS2__) || defined (__CYGWIN__) +# ifndef HAVE_DOS_BASED_FILE_SYSTEM +# define HAVE_DOS_BASED_FILE_SYSTEM 1 +# endif +# ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM +# define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1 +# endif +# define HAS_DRIVE_SPEC(f) HAS_DOS_DRIVE_SPEC (f) +# define IS_DIR_SEPARATOR(c) IS_DOS_DIR_SEPARATOR (c) +# define IS_ABSOLUTE_PATH(f) IS_DOS_ABSOLUTE_PATH (f) +#else /* not DOSish */ +# if defined(__APPLE__) +# ifndef HAVE_CASE_INSENSITIVE_FILE_SYSTEM +# define HAVE_CASE_INSENSITIVE_FILE_SYSTEM 1 +# endif +# endif /* __APPLE__ */ +# define HAS_DRIVE_SPEC(f) (0) +# define IS_DIR_SEPARATOR(c) IS_UNIX_DIR_SEPARATOR (c) +# define IS_ABSOLUTE_PATH(f) IS_UNIX_ABSOLUTE_PATH (f) +#endif + +#define IS_DIR_SEPARATOR_1(dos_based, c) \ + (((c) == '/') \ + || (((c) == '\\') && (dos_based))) + +#define HAS_DRIVE_SPEC_1(dos_based, f) \ + ((f)[0] && ((f)[1] == ':') && (dos_based)) + +/* Remove the drive spec from F, assuming HAS_DRIVE_SPEC (f). + The result is a pointer to the remainder of F. */ +#define STRIP_DRIVE_SPEC(f) ((f) + 2) + +#define IS_DOS_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (1, c) +#define IS_DOS_ABSOLUTE_PATH(f) IS_ABSOLUTE_PATH_1 (1, f) +#define HAS_DOS_DRIVE_SPEC(f) HAS_DRIVE_SPEC_1 (1, f) + +#define IS_UNIX_DIR_SEPARATOR(c) IS_DIR_SEPARATOR_1 (0, c) +#define IS_UNIX_ABSOLUTE_PATH(f) IS_ABSOLUTE_PATH_1 (0, f) + +/* Note that when DOS_BASED is true, IS_ABSOLUTE_PATH accepts d:foo as + well, although it is only semi-absolute. This is because the users + of IS_ABSOLUTE_PATH want to know whether to prepend the current + working directory to a file name, which should not be done with a + name like d:foo. */ +#define IS_ABSOLUTE_PATH_1(dos_based, f) \ + (IS_DIR_SEPARATOR_1 (dos_based, (f)[0]) \ + || HAS_DRIVE_SPEC_1 (dos_based, f)) + +extern int filename_cmp (const char *s1, const char *s2); +#define FILENAME_CMP(s1, s2) filename_cmp(s1, s2) + +extern int filename_ncmp (const char *s1, const char *s2, + size_t n); + +extern hashval_t filename_hash (const void *s); + +extern int filename_eq (const void *s1, const void *s2); + +#ifdef __cplusplus +} +#endif + +#endif /* FILENAMES_H */ diff --git a/src/include/fixed-value.h b/src/include/fixed-value.h new file mode 100644 index 0000000..f59466a --- /dev/null +++ b/src/include/fixed-value.h @@ -0,0 +1,116 @@ +/* Fixed-point arithmetic support. + Copyright (C) 2006-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_FIXED_VALUE_H +#define GCC_FIXED_VALUE_H + +#include "machmode.h" +#include "real.h" +#include "double-int.h" + +struct GTY(()) fixed_value +{ + double_int data; /* Store data up to 2 wide integers. */ + enum machine_mode mode; /* Use machine mode to know IBIT and FBIT. */ +}; + +#define FIXED_VALUE_TYPE struct fixed_value + +#define MAX_FCONST0 18 /* For storing 18 fixed-point zeros per + fract, ufract, accum, and uaccum modes . */ +#define MAX_FCONST1 8 /* For storing 8 fixed-point ones per accum + and uaccum modes. */ +/* Constant fixed-point values 0 and 1. */ +extern FIXED_VALUE_TYPE fconst0[MAX_FCONST0]; +extern FIXED_VALUE_TYPE fconst1[MAX_FCONST1]; + +/* Macros to access fconst0 and fconst1 via machine modes. */ +#define FCONST0(mode) fconst0[mode - QQmode] +#define FCONST1(mode) fconst1[mode - HAmode] + +/* Return a CONST_FIXED with value R and mode M. */ +#define CONST_FIXED_FROM_FIXED_VALUE(r, m) \ + const_fixed_from_fixed_value (r, m) +extern rtx const_fixed_from_fixed_value (FIXED_VALUE_TYPE, enum machine_mode); + +/* Construct a FIXED_VALUE from a bit payload and machine mode MODE. + The bits in PAYLOAD are sign-extended/zero-extended according to MODE. */ +extern FIXED_VALUE_TYPE fixed_from_double_int (double_int, + enum machine_mode); + +/* Return a CONST_FIXED from a bit payload and machine mode MODE. + The bits in PAYLOAD are sign-extended/zero-extended according to MODE. */ +static inline rtx +const_fixed_from_double_int (double_int payload, + enum machine_mode mode) +{ + return + const_fixed_from_fixed_value (fixed_from_double_int (payload, mode), + mode); +} + +/* Initialize from a decimal or hexadecimal string. */ +extern void fixed_from_string (FIXED_VALUE_TYPE *, const char *, + enum machine_mode); + +/* In tree.c: wrap up a FIXED_VALUE_TYPE in a tree node. */ +extern tree build_fixed (tree, FIXED_VALUE_TYPE); + +/* Extend or truncate to a new mode. */ +extern bool fixed_convert (FIXED_VALUE_TYPE *, enum machine_mode, + const FIXED_VALUE_TYPE *, bool); + +/* Convert to a fixed-point mode from an integer. */ +extern bool fixed_convert_from_int (FIXED_VALUE_TYPE *, enum machine_mode, + double_int, bool, bool); + +/* Convert to a fixed-point mode from a real. */ +extern bool fixed_convert_from_real (FIXED_VALUE_TYPE *, enum machine_mode, + const REAL_VALUE_TYPE *, bool); + +/* Convert to a real mode from a fixed-point. */ +extern void real_convert_from_fixed (REAL_VALUE_TYPE *, enum machine_mode, + const FIXED_VALUE_TYPE *); + +/* Compare two fixed-point objects for bitwise identity. */ +extern bool fixed_identical (const FIXED_VALUE_TYPE *, const FIXED_VALUE_TYPE *); + +/* Calculate a hash value. */ +extern unsigned int fixed_hash (const FIXED_VALUE_TYPE *); + +#define FIXED_VALUES_IDENTICAL(x, y) fixed_identical (&(x), &(y)) + +/* Determine whether a fixed-point value X is negative. */ +#define FIXED_VALUE_NEGATIVE(x) fixed_isneg (&(x)) + +/* Render F as a decimal floating point constant. */ +extern void fixed_to_decimal (char *str, const FIXED_VALUE_TYPE *, size_t); + +/* Binary or unary arithmetic on tree_code. */ +extern bool fixed_arithmetic (FIXED_VALUE_TYPE *, int, const FIXED_VALUE_TYPE *, + const FIXED_VALUE_TYPE *, bool); + +/* Compare fixed-point values by tree_code. */ +extern bool fixed_compare (int, const FIXED_VALUE_TYPE *, + const FIXED_VALUE_TYPE *); + +/* Determine whether a fixed-point value X is negative. */ +extern bool fixed_isneg (const FIXED_VALUE_TYPE *); + +#endif /* GCC_FIXED_VALUE_H */ diff --git a/src/include/flag-types.h b/src/include/flag-types.h new file mode 100644 index 0000000..4fc5d33 --- /dev/null +++ b/src/include/flag-types.h @@ -0,0 +1,194 @@ +/* Compilation switch flag type definitions for GCC. + Copyright (C) 1987-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_FLAG_TYPES_H +#define GCC_FLAG_TYPES_H + +enum debug_info_type +{ + NO_DEBUG, /* Write no debug info. */ + DBX_DEBUG, /* Write BSD .stabs for DBX (using dbxout.c). */ + SDB_DEBUG, /* Write COFF for (old) SDB (using sdbout.c). */ + DWARF2_DEBUG, /* Write Dwarf v2 debug info (using dwarf2out.c). */ + XCOFF_DEBUG, /* Write IBM/Xcoff debug info (using dbxout.c). */ + VMS_DEBUG, /* Write VMS debug info (using vmsdbgout.c). */ + VMS_AND_DWARF2_DEBUG /* Write VMS debug info (using vmsdbgout.c). + and DWARF v2 debug info (using dwarf2out.c). */ +}; + +enum debug_info_levels +{ + DINFO_LEVEL_NONE, /* Write no debugging info. */ + DINFO_LEVEL_TERSE, /* Write minimal info to support tracebacks only. */ + DINFO_LEVEL_NORMAL, /* Write info for all declarations (and line table). */ + DINFO_LEVEL_VERBOSE /* Write normal info plus #define/#undef info. */ +}; + +/* A major contribution to object and executable size is debug + information size. A major contribution to debug information + size is struct descriptions replicated in several object files. + The following function determines whether or not debug information + should be generated for a given struct. The indirect parameter + indicates that the struct is being handled indirectly, via + a pointer. See opts.c for the implementation. */ + +enum debug_info_usage +{ + DINFO_USAGE_DFN, /* A struct definition. */ + DINFO_USAGE_DIR_USE, /* A direct use, such as the type of a variable. */ + DINFO_USAGE_IND_USE, /* An indirect use, such as through a pointer. */ + DINFO_USAGE_NUM_ENUMS /* The number of enumerators. */ +}; + +/* A major contribution to object and executable size is debug + information size. A major contribution to debug information size + is struct descriptions replicated in several object files. The + following flags attempt to reduce this information. The basic + idea is to not emit struct debugging information in the current + compilation unit when that information will be generated by + another compilation unit. + + Debug information for a struct defined in the current source + file should be generated in the object file. Likewise the + debug information for a struct defined in a header should be + generated in the object file of the corresponding source file. + Both of these case are handled when the base name of the file of + the struct definition matches the base name of the source file + of the current compilation unit. This matching emits minimal + struct debugging information. + + The base file name matching rule above will fail to emit debug + information for structs defined in system headers. So a second + category of files includes system headers in addition to files + with matching bases. + + The remaining types of files are library headers and application + headers. We cannot currently distinguish these two types. */ + +enum debug_struct_file +{ + DINFO_STRUCT_FILE_NONE, /* Debug no structs. */ + DINFO_STRUCT_FILE_BASE, /* Debug structs defined in files with the + same base name as the compilation unit. */ + DINFO_STRUCT_FILE_SYS, /* Also debug structs defined in system + header files. */ + DINFO_STRUCT_FILE_ANY /* Debug structs defined in all files. */ +}; + +/* Enumerate visibility settings. This is deliberately ordered from most + to least visibility. */ +#ifndef SYMBOL_VISIBILITY_DEFINED +#define SYMBOL_VISIBILITY_DEFINED +enum symbol_visibility +{ + VISIBILITY_DEFAULT, + VISIBILITY_PROTECTED, + VISIBILITY_HIDDEN, + VISIBILITY_INTERNAL +}; +#endif + +/* The stack reuse level. */ +enum stack_reuse_level +{ + SR_NONE, + SR_NAMED_VARS, + SR_ALL +}; + +/* The algorithm used for the integrated register allocator (IRA). */ +enum ira_algorithm +{ + IRA_ALGORITHM_CB, + IRA_ALGORITHM_PRIORITY +}; + +/* The regions used for the integrated register allocator (IRA). */ +enum ira_region +{ + IRA_REGION_ONE, + IRA_REGION_ALL, + IRA_REGION_MIXED, + /* This value means that there were no options -fira-region on the + command line and that we should choose a value depending on the + used -O option. */ + IRA_REGION_AUTODETECT +}; + +/* The options for excess precision. */ +enum excess_precision +{ + EXCESS_PRECISION_DEFAULT, + EXCESS_PRECISION_FAST, + EXCESS_PRECISION_STANDARD +}; + +/* Type of stack check. */ +enum stack_check_type +{ + /* Do not check the stack. */ + NO_STACK_CHECK = 0, + + /* Check the stack generically, i.e. assume no specific support + from the target configuration files. */ + GENERIC_STACK_CHECK, + + /* Check the stack and rely on the target configuration files to + check the static frame of functions, i.e. use the generic + mechanism only for dynamic stack allocations. */ + STATIC_BUILTIN_STACK_CHECK, + + /* Check the stack and entirely rely on the target configuration + files, i.e. do not use the generic mechanism at all. */ + FULL_BUILTIN_STACK_CHECK +}; + +/* Names for the different levels of -Wstrict-overflow=N. The numeric + values here correspond to N. */ + +enum warn_strict_overflow_code +{ + /* Overflow warning that should be issued with -Wall: a questionable + construct that is easy to avoid even when using macros. Example: + folding (x + CONSTANT > x) to 1. */ + WARN_STRICT_OVERFLOW_ALL = 1, + /* Overflow warning about folding a comparison to a constant because + of undefined signed overflow, other than cases covered by + WARN_STRICT_OVERFLOW_ALL. Example: folding (abs (x) >= 0) to 1 + (this is false when x == INT_MIN). */ + WARN_STRICT_OVERFLOW_CONDITIONAL = 2, + /* Overflow warning about changes to comparisons other than folding + them to a constant. Example: folding (x + 1 > 1) to (x > 0). */ + WARN_STRICT_OVERFLOW_COMPARISON = 3, + /* Overflow warnings not covered by the above cases. Example: + folding ((x * 10) / 5) to (x * 2). */ + WARN_STRICT_OVERFLOW_MISC = 4, + /* Overflow warnings about reducing magnitude of constants in + comparison. Example: folding (x + 2 > y) to (x + 1 >= y). */ + WARN_STRICT_OVERFLOW_MAGNITUDE = 5 +}; + +/* Floating-point contraction mode. */ +enum fp_contract_mode { + FP_CONTRACT_OFF = 0, + FP_CONTRACT_ON = 1, + FP_CONTRACT_FAST = 2 +}; + +#endif /* ! GCC_FLAG_TYPES_H */ diff --git a/src/include/flags.h b/src/include/flags.h new file mode 100644 index 0000000..8282989 --- /dev/null +++ b/src/include/flags.h @@ -0,0 +1,101 @@ +/* Compilation switch flag definitions for GCC. + Copyright (C) 1987-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_FLAGS_H +#define GCC_FLAGS_H + +#include "flag-types.h" +#include "options.h" + +#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS) && !defined(IN_RTS) + +/* Names of debug_info_type, for error messages. */ +extern const char *const debug_type_names[]; + +extern void strip_off_ending (char *, int); +extern int base_of_path (const char *path, const char **base_out); + +/* Return true iff flags are set as if -ffast-math. */ +extern bool fast_math_flags_set_p (const struct gcc_options *); +extern bool fast_math_flags_struct_set_p (struct cl_optimization *); + + +/* Now the symbols that are set with `-f' switches. */ + +/* True if printing into -fdump-final-insns= dump. */ + +extern bool final_insns_dump_p; + + +/* Other basic status info about current function. */ + +/* Target-dependent global state. */ +struct target_flag_state { + /* Values of the -falign-* flags: how much to align labels in code. + 0 means `use default', 1 means `don't align'. + For each variable, there is an _log variant which is the power + of two not less than the variable, for .align output. */ + int x_align_loops_log; + int x_align_loops_max_skip; + int x_align_jumps_log; + int x_align_jumps_max_skip; + int x_align_labels_log; + int x_align_labels_max_skip; + int x_align_functions_log; + + /* The excess precision currently in effect. */ + enum excess_precision x_flag_excess_precision; +}; + +extern struct target_flag_state default_target_flag_state; +#if SWITCHABLE_TARGET +extern struct target_flag_state *this_target_flag_state; +#else +#define this_target_flag_state (&default_target_flag_state) +#endif + +#define align_loops_log \ + (this_target_flag_state->x_align_loops_log) +#define align_loops_max_skip \ + (this_target_flag_state->x_align_loops_max_skip) +#define align_jumps_log \ + (this_target_flag_state->x_align_jumps_log) +#define align_jumps_max_skip \ + (this_target_flag_state->x_align_jumps_max_skip) +#define align_labels_log \ + (this_target_flag_state->x_align_labels_log) +#define align_labels_max_skip \ + (this_target_flag_state->x_align_labels_max_skip) +#define align_functions_log \ + (this_target_flag_state->x_align_functions_log) +#define flag_excess_precision \ + (this_target_flag_state->x_flag_excess_precision) + +/* Returns TRUE if generated code should match ABI version N or + greater is in use. */ + +#define abi_version_at_least(N) \ + (flag_abi_version == 0 || flag_abi_version >= (N)) + +/* Whether to emit an overflow warning whose code is C. */ +#define issue_strict_overflow_warning(c) (warn_strict_overflow >= (int) (c)) + +#endif + +#endif /* ! GCC_FLAGS_H */ diff --git a/src/include/function.h b/src/include/function.h new file mode 100644 index 0000000..89d71e5 --- /dev/null +++ b/src/include/function.h @@ -0,0 +1,782 @@ +/* Structure for saving state for a nested function. + Copyright (C) 1989-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_FUNCTION_H +#define GCC_FUNCTION_H + +#include "hashtab.h" +#include "vec.h" +#include "machmode.h" +#include "tm.h" /* For CUMULATIVE_ARGS. */ +#include "hard-reg-set.h" /* For HARD_REG_SET in struct rtl_data. */ +#include "input.h" /* For location_t. */ + +/* Stack of pending (incomplete) sequences saved by `start_sequence'. + Each element describes one pending sequence. + The main insn-chain is saved in the last element of the chain, + unless the chain is empty. */ + +struct GTY(()) sequence_stack { + /* First and last insns in the chain of the saved sequence. */ + rtx first; + rtx last; + struct sequence_stack *next; +}; + +struct GTY(()) emit_status { + /* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function. + After rtl generation, it is 1 plus the largest register number used. */ + int x_reg_rtx_no; + + /* Lowest label number in current function. */ + int x_first_label_num; + + /* The ends of the doubly-linked chain of rtl for the current function. + Both are reset to null at the start of rtl generation for the function. + + start_sequence saves both of these on `sequence_stack' and then starts + a new, nested sequence of insns. */ + rtx x_first_insn; + rtx x_last_insn; + + /* Stack of pending (incomplete) sequences saved by `start_sequence'. + Each element describes one pending sequence. + The main insn-chain is saved in the last element of the chain, + unless the chain is empty. */ + struct sequence_stack *sequence_stack; + + /* INSN_UID for next insn emitted. + Reset to 1 for each function compiled. */ + int x_cur_insn_uid; + + /* INSN_UID for next debug insn emitted. Only used if + --param min-nondebug-insn-uid= is given with nonzero value. */ + int x_cur_debug_insn_uid; + + /* The length of the regno_pointer_align, regno_decl, and x_regno_reg_rtx + vectors. Since these vectors are needed during the expansion phase when + the total number of registers in the function is not yet known, the + vectors are copied and made bigger when necessary. */ + int regno_pointer_align_length; + + /* Indexed by pseudo register number, if nonzero gives the known alignment + for that pseudo (if REG_POINTER is set in x_regno_reg_rtx). + Allocated in parallel with x_regno_reg_rtx. */ + unsigned char * GTY((skip)) regno_pointer_align; +}; + + +/* Indexed by register number, gives an rtx for that register (and only + that register). For pseudo registers, it is the unique rtx for + that pseudo. For hard registers, it is an rtx of the mode specified + by reg_raw_mode. + + FIXME: We could put it into emit_status struct, but gengtype is not + able to deal with length attribute nested in top level structures. */ + +extern GTY ((length ("crtl->emit.x_reg_rtx_no"))) rtx * regno_reg_rtx; + +/* For backward compatibility... eventually these should all go away. */ +#define reg_rtx_no (crtl->emit.x_reg_rtx_no) +#define seq_stack (crtl->emit.sequence_stack) + +#define REGNO_POINTER_ALIGN(REGNO) (crtl->emit.regno_pointer_align[REGNO]) + +struct GTY(()) expr_status { + /* Number of units that we should eventually pop off the stack. + These are the arguments to function calls that have already returned. */ + int x_pending_stack_adjust; + + /* Under some ABIs, it is the caller's responsibility to pop arguments + pushed for function calls. A naive implementation would simply pop + the arguments immediately after each call. However, if several + function calls are made in a row, it is typically cheaper to pop + all the arguments after all of the calls are complete since a + single pop instruction can be used. Therefore, GCC attempts to + defer popping the arguments until absolutely necessary. (For + example, at the end of a conditional, the arguments must be popped, + since code outside the conditional won't know whether or not the + arguments need to be popped.) + + When INHIBIT_DEFER_POP is nonzero, however, the compiler does not + attempt to defer pops. Instead, the stack is popped immediately + after each call. Rather then setting this variable directly, use + NO_DEFER_POP and OK_DEFER_POP. */ + int x_inhibit_defer_pop; + + /* If PREFERRED_STACK_BOUNDARY and PUSH_ROUNDING are defined, the stack + boundary can be momentarily unaligned while pushing the arguments. + Record the delta since last aligned boundary here in order to get + stack alignment in the nested function calls working right. */ + int x_stack_pointer_delta; + + /* Nonzero means __builtin_saveregs has already been done in this function. + The value is the pseudoreg containing the value __builtin_saveregs + returned. */ + rtx x_saveregs_value; + + /* Similarly for __builtin_apply_args. */ + rtx x_apply_args_value; + + /* List of labels that must never be deleted. */ + rtx x_forced_labels; +}; + +typedef struct call_site_record_d *call_site_record; + +/* RTL representation of exception handling. */ +struct GTY(()) rtl_eh { + rtx ehr_stackadj; + rtx ehr_handler; + rtx ehr_label; + + rtx sjlj_fc; + rtx sjlj_exit_after; + + vec *action_record_data; + + vec *call_site_record_v[2]; +}; + +#define pending_stack_adjust (crtl->expr.x_pending_stack_adjust) +#define inhibit_defer_pop (crtl->expr.x_inhibit_defer_pop) +#define saveregs_value (crtl->expr.x_saveregs_value) +#define apply_args_value (crtl->expr.x_apply_args_value) +#define forced_labels (crtl->expr.x_forced_labels) +#define stack_pointer_delta (crtl->expr.x_stack_pointer_delta) + +struct gimple_df; +struct temp_slot; +typedef struct temp_slot *temp_slot_p; +struct call_site_record_d; +struct dw_fde_struct; + +struct ipa_opt_pass_d; +typedef struct ipa_opt_pass_d *ipa_opt_pass; + + +struct GTY(()) varasm_status { + /* If we're using a per-function constant pool, this is it. */ + struct rtx_constant_pool *pool; + + /* Number of tree-constants deferred during the expansion of this + function. */ + unsigned int deferred_constants; +}; + +/* Information mainlined about RTL representation of incoming arguments. */ +struct GTY(()) incoming_args { + /* Number of bytes of args popped by function being compiled on its return. + Zero if no bytes are to be popped. + May affect compilation of return insn or of function epilogue. */ + int pops_args; + + /* If function's args have a fixed size, this is that size, in bytes. + Otherwise, it is -1. + May affect compilation of return insn or of function epilogue. */ + int size; + + /* # bytes the prologue should push and pretend that the caller pushed them. + The prologue must do this, but only if parms can be passed in + registers. */ + int pretend_args_size; + + /* This is the offset from the arg pointer to the place where the first + anonymous arg can be found, if there is one. */ + rtx arg_offset_rtx; + + /* Quantities of various kinds of registers + used for the current function's args. */ + CUMULATIVE_ARGS info; + + /* The arg pointer hard register, or the pseudo into which it was copied. */ + rtx internal_arg_pointer; +}; + +/* Data for function partitioning. */ +struct GTY(()) function_subsections { + /* Assembly labels for the hot and cold text sections, to + be used by debugger functions for determining the size of text + sections. */ + + const char *hot_section_label; + const char *cold_section_label; + const char *hot_section_end_label; + const char *cold_section_end_label; +}; + +/* Describe an empty area of space in the stack frame. These can be chained + into a list; this is used to keep track of space wasted for alignment + reasons. */ +struct GTY(()) frame_space +{ + struct frame_space *next; + + HOST_WIDE_INT start; + HOST_WIDE_INT length; +}; + +/* Datastructures maintained for currently processed function in RTL form. */ +struct GTY(()) rtl_data { + struct expr_status expr; + struct emit_status emit; + struct varasm_status varasm; + struct incoming_args args; + struct function_subsections subsections; + struct rtl_eh eh; + + /* For function.c */ + + /* # of bytes of outgoing arguments. If ACCUMULATE_OUTGOING_ARGS is + defined, the needed space is pushed by the prologue. */ + int outgoing_args_size; + + /* If nonzero, an RTL expression for the location at which the current + function returns its result. If the current function returns its + result in a register, current_function_return_rtx will always be + the hard register containing the result. */ + rtx return_rtx; + + /* Vector of initial-value pairs. Each pair consists of a pseudo + register of approprite mode that stores the initial value a hard + register REGNO, and that hard register itself. */ + /* ??? This could be a VEC but there is currently no way to define an + opaque VEC type. */ + struct initial_value_struct *hard_reg_initial_vals; + + /* A variable living at the top of the frame that holds a known value. + Used for detecting stack clobbers. */ + tree stack_protect_guard; + + /* List (chain of EXPR_LIST) of labels heading the current handlers for + nonlocal gotos. */ + rtx x_nonlocal_goto_handler_labels; + + /* Label that will go on function epilogue. + Jumping to this label serves as a "return" instruction + on machines which require execution of the epilogue on all returns. */ + rtx x_return_label; + + /* Label that will go on the end of function epilogue. + Jumping to this label serves as a "naked return" instruction + on machines which require execution of the epilogue on all returns. */ + rtx x_naked_return_label; + + /* List (chain of EXPR_LISTs) of all stack slots in this function. + Made for the sake of unshare_all_rtl. */ + rtx x_stack_slot_list; + + /* List of empty areas in the stack frame. */ + struct frame_space *frame_space_list; + + /* Place after which to insert the tail_recursion_label if we need one. */ + rtx x_stack_check_probe_note; + + /* Location at which to save the argument pointer if it will need to be + referenced. There are two cases where this is done: if nonlocal gotos + exist, or if vars stored at an offset from the argument pointer will be + needed by inner routines. */ + rtx x_arg_pointer_save_area; + + /* Dynamic Realign Argument Pointer used for realigning stack. */ + rtx drap_reg; + + /* Offset to end of allocated area of stack frame. + If stack grows down, this is the address of the last stack slot allocated. + If stack grows up, this is the address for the next slot. */ + HOST_WIDE_INT x_frame_offset; + + /* Insn after which register parms and SAVE_EXPRs are born, if nonopt. */ + rtx x_parm_birth_insn; + + /* List of all used temporaries allocated, by level. */ + vec *x_used_temp_slots; + + /* List of available temp slots. */ + struct temp_slot *x_avail_temp_slots; + + /* Current nesting level for temporaries. */ + int x_temp_slot_level; + + /* The largest alignment needed on the stack, including requirement + for outgoing stack alignment. */ + unsigned int stack_alignment_needed; + + /* Preferred alignment of the end of stack frame, which is preferred + to call other functions. */ + unsigned int preferred_stack_boundary; + + /* The minimum alignment of parameter stack. */ + unsigned int parm_stack_boundary; + + /* The largest alignment of slot allocated on the stack. */ + unsigned int max_used_stack_slot_alignment; + + /* The stack alignment estimated before reload, with consideration of + following factors: + 1. Alignment of local stack variables (max_used_stack_slot_alignment) + 2. Alignment requirement to call other functions + (preferred_stack_boundary) + 3. Alignment of non-local stack variables but might be spilled in + local stack. */ + unsigned int stack_alignment_estimated; + + /* For reorg. */ + + /* Nonzero if function being compiled called builtin_return_addr or + builtin_frame_address with nonzero count. */ + bool accesses_prior_frames; + + /* Nonzero if the function calls __builtin_eh_return. */ + bool calls_eh_return; + + /* Nonzero if function saves all registers, e.g. if it has a nonlocal + label that can reach the exit block via non-exceptional paths. */ + bool saves_all_registers; + + /* Nonzero if function being compiled has nonlocal gotos to parent + function. */ + bool has_nonlocal_goto; + + /* Nonzero if function being compiled has an asm statement. */ + bool has_asm_statement; + + /* This bit is used by the exception handling logic. It is set if all + calls (if any) are sibling calls. Such functions do not have to + have EH tables generated, as they cannot throw. A call to such a + function, however, should be treated as throwing if any of its callees + can throw. */ + bool all_throwers_are_sibcalls; + + /* Nonzero if stack limit checking should be enabled in the current + function. */ + bool limit_stack; + + /* Nonzero if profiling code should be generated. */ + bool profile; + + /* Nonzero if the current function uses the constant pool. */ + bool uses_const_pool; + + /* Nonzero if the current function uses pic_offset_table_rtx. */ + bool uses_pic_offset_table; + + /* Nonzero if the current function needs an lsda for exception handling. */ + bool uses_eh_lsda; + + /* Set when the tail call has been produced. */ + bool tail_call_emit; + + /* Nonzero if code to initialize arg_pointer_save_area has been emitted. */ + bool arg_pointer_save_area_init; + + /* Nonzero if current function must be given a frame pointer. + Set in reload1.c or lra-eliminations.c if anything is allocated + on the stack there. */ + bool frame_pointer_needed; + + /* When set, expand should optimize for speed. */ + bool maybe_hot_insn_p; + + /* Nonzero if function stack realignment is needed. This flag may be + set twice: before and after reload. It is set before reload wrt + stack alignment estimation before reload. It will be changed after + reload if by then criteria of stack realignment is different. + The value set after reload is the accurate one and is finalized. */ + bool stack_realign_needed; + + /* Nonzero if function stack realignment is tried. This flag is set + only once before reload. It affects register elimination. This + is used to generate DWARF debug info for stack variables. */ + bool stack_realign_tried; + + /* Nonzero if function being compiled needs dynamic realigned + argument pointer (drap) if stack needs realigning. */ + bool need_drap; + + /* Nonzero if function stack realignment estimation is done, namely + stack_realign_needed flag has been set before reload wrt estimated + stack alignment info. */ + bool stack_realign_processed; + + /* Nonzero if function stack realignment has been finalized, namely + stack_realign_needed flag has been set and finalized after reload. */ + bool stack_realign_finalized; + + /* True if dbr_schedule has already been called for this function. */ + bool dbr_scheduled_p; + + /* True if current function can not throw. Unlike + TREE_NOTHROW (current_function_decl) it is set even for overwritable + function where currently compiled version of it is nothrow. */ + bool nothrow; + + /* True if we performed shrink-wrapping for the current function. */ + bool shrink_wrapped; + + /* Nonzero if function being compiled doesn't modify the stack pointer + (ignoring the prologue and epilogue). This is only valid after + pass_stack_ptr_mod has run. */ + bool sp_is_unchanging; + + /* Nonzero if function being compiled doesn't contain any calls + (ignoring the prologue and epilogue). This is set prior to + local register allocation and is valid for the remaining + compiler passes. */ + bool is_leaf; + + /* Nonzero if the function being compiled is a leaf function which only + uses leaf registers. This is valid after reload (specifically after + sched2) and is useful only if the port defines LEAF_REGISTERS. */ + bool uses_only_leaf_regs; + + /* Like regs_ever_live, but 1 if a reg is set or clobbered from an + asm. Unlike regs_ever_live, elements of this array corresponding + to eliminable regs (like the frame pointer) are set if an asm + sets them. */ + HARD_REG_SET asm_clobbers; +}; + +#define return_label (crtl->x_return_label) +#define naked_return_label (crtl->x_naked_return_label) +#define stack_slot_list (crtl->x_stack_slot_list) +#define parm_birth_insn (crtl->x_parm_birth_insn) +#define frame_offset (crtl->x_frame_offset) +#define stack_check_probe_note (crtl->x_stack_check_probe_note) +#define arg_pointer_save_area (crtl->x_arg_pointer_save_area) +#define used_temp_slots (crtl->x_used_temp_slots) +#define avail_temp_slots (crtl->x_avail_temp_slots) +#define temp_slot_level (crtl->x_temp_slot_level) +#define nonlocal_goto_handler_labels (crtl->x_nonlocal_goto_handler_labels) +#define frame_pointer_needed (crtl->frame_pointer_needed) +#define stack_realign_fp (crtl->stack_realign_needed && !crtl->need_drap) +#define stack_realign_drap (crtl->stack_realign_needed && crtl->need_drap) + +extern GTY(()) struct rtl_data x_rtl; + +/* Accessor to RTL datastructures. We keep them statically allocated now since + we never keep multiple functions. For threaded compiler we might however + want to do differently. */ +#define crtl (&x_rtl) + +struct GTY(()) stack_usage +{ + /* # of bytes of static stack space allocated by the function. */ + HOST_WIDE_INT static_stack_size; + + /* # of bytes of dynamic stack space allocated by the function. This is + meaningful only if has_unbounded_dynamic_stack_size is zero. */ + HOST_WIDE_INT dynamic_stack_size; + + /* # of bytes of space pushed onto the stack after the prologue. If + !ACCUMULATE_OUTGOING_ARGS, it contains the outgoing arguments. */ + int pushed_stack_size; + + /* Nonzero if the amount of stack space allocated dynamically cannot + be bounded at compile-time. */ + unsigned int has_unbounded_dynamic_stack_size : 1; +}; + +#define current_function_static_stack_size (cfun->su->static_stack_size) +#define current_function_dynamic_stack_size (cfun->su->dynamic_stack_size) +#define current_function_pushed_stack_size (cfun->su->pushed_stack_size) +#define current_function_has_unbounded_dynamic_stack_size \ + (cfun->su->has_unbounded_dynamic_stack_size) +#define current_function_allocates_dynamic_stack_space \ + (current_function_dynamic_stack_size != 0 \ + || current_function_has_unbounded_dynamic_stack_size) + +/* This structure can save all the important global and static variables + describing the status of the current function. */ + +struct GTY(()) function { + struct eh_status *eh; + + /* The control flow graph for this function. */ + struct control_flow_graph *cfg; + + /* GIMPLE body for this function. */ + gimple_seq gimple_body; + + /* SSA and dataflow information. */ + struct gimple_df *gimple_df; + + /* The loops in this function. */ + struct loops *x_current_loops; + + /* The stack usage of this function. */ + struct stack_usage *su; + + /* Value histograms attached to particular statements. */ + htab_t GTY((skip)) value_histograms; + + /* For function.c. */ + + /* Points to the FUNCTION_DECL of this function. */ + tree decl; + + /* A PARM_DECL that should contain the static chain for this function. + It will be initialized at the beginning of the function. */ + tree static_chain_decl; + + /* An expression that contains the non-local goto save area. The first + word is the saved frame pointer and the second is the saved stack + pointer. */ + tree nonlocal_goto_save_area; + + /* Vector of function local variables, functions, types and constants. */ + vec *local_decls; + + /* For md files. */ + + /* tm.h can use this to store whatever it likes. */ + struct machine_function * GTY ((maybe_undef)) machine; + + /* Language-specific code can use this to store whatever it likes. */ + struct language_function * language; + + /* Used types hash table. */ + htab_t GTY ((param_is (union tree_node))) used_types_hash; + + /* Dwarf2 Frame Description Entry, containing the Call Frame Instructions + used for unwinding. Only set when either dwarf2 unwinding or dwarf2 + debugging is enabled. */ + struct dw_fde_struct *fde; + + /* Last statement uid. */ + int last_stmt_uid; + + /* Function sequence number for profiling, debugging, etc. */ + int funcdef_no; + + /* Line number of the start of the function for debugging purposes. */ + location_t function_start_locus; + + /* Line number of the end of the function. */ + location_t function_end_locus; + + /* Properties used by the pass manager. */ + unsigned int curr_properties; + unsigned int last_verified; + + /* Non-null if the function does something that would prevent it from + being copied; this applies to both versioning and inlining. Set to + a string describing the reason for failure. */ + const char * GTY((skip)) cannot_be_copied_reason; + + /* Collected bit flags. */ + + /* Number of units of general registers that need saving in stdarg + function. What unit is depends on the backend, either it is number + of bytes, or it can be number of registers. */ + unsigned int va_list_gpr_size : 8; + + /* Number of units of floating point registers that need saving in stdarg + function. */ + unsigned int va_list_fpr_size : 8; + + /* Nonzero if function being compiled can call setjmp. */ + unsigned int calls_setjmp : 1; + + /* Nonzero if function being compiled can call alloca, + either as a subroutine or builtin. */ + unsigned int calls_alloca : 1; + + /* Nonzero if function being compiled receives nonlocal gotos + from nested functions. */ + unsigned int has_nonlocal_label : 1; + + /* Nonzero if we've set cannot_be_copied_reason. I.e. if + (cannot_be_copied_set && !cannot_be_copied_reason), the function + can in fact be copied. */ + unsigned int cannot_be_copied_set : 1; + + /* Nonzero if current function uses stdarg.h or equivalent. */ + unsigned int stdarg : 1; + + unsigned int after_inlining : 1; + unsigned int always_inline_functions_inlined : 1; + + /* Nonzero if function being compiled can throw synchronous non-call + exceptions. */ + unsigned int can_throw_non_call_exceptions : 1; + + /* Nonzero if instructions that may throw exceptions but don't otherwise + contribute to the execution of the program can be deleted. */ + unsigned int can_delete_dead_exceptions : 1; + + /* Fields below this point are not set for abstract functions; see + allocate_struct_function. */ + + /* Nonzero if function being compiled needs to be given an address + where the value should be stored. */ + unsigned int returns_struct : 1; + + /* Nonzero if function being compiled needs to + return the address of where it has put a structure value. */ + unsigned int returns_pcc_struct : 1; + + /* Nonzero if this function has local DECL_HARD_REGISTER variables. + In this case code motion has to be done more carefully. */ + unsigned int has_local_explicit_reg_vars : 1; + + /* Nonzero if the current function is a thunk, i.e., a lightweight + function implemented by the output_mi_thunk hook) that just + adjusts one of its arguments and forwards to another + function. */ + unsigned int is_thunk : 1; +}; + +/* Add the decl D to the local_decls list of FUN. */ + +static inline void +add_local_decl (struct function *fun, tree d) +{ + vec_safe_push (fun->local_decls, d); +} + +#define FOR_EACH_LOCAL_DECL(FUN, I, D) \ + FOR_EACH_VEC_SAFE_ELT_REVERSE ((FUN)->local_decls, I, D) + +/* If va_list_[gf]pr_size is set to this, it means we don't know how + many units need to be saved. */ +#define VA_LIST_MAX_GPR_SIZE 255 +#define VA_LIST_MAX_FPR_SIZE 255 + +/* The function currently being compiled. */ +extern GTY(()) struct function *cfun; + +/* In order to ensure that cfun is not set directly, we redefine it so + that it is not an lvalue. Rather than assign to cfun, use + push_cfun or set_cfun. */ +#define cfun (cfun + 0) + +/* Nonzero if we've already converted virtual regs to hard regs. */ +extern int virtuals_instantiated; + +/* Nonzero if at least one trampoline has been created. */ +extern int trampolines_created; + +struct GTY(()) types_used_by_vars_entry { + tree type; + tree var_decl; +}; + +/* Hash table making the relationship between a global variable + and the types it references in its initializer. The key of the + entry is a referenced type, and the value is the DECL of the global + variable. types_use_by_vars_do_hash and types_used_by_vars_eq below are + the hash and equality functions to use for this hash table. */ +extern GTY((param_is (struct types_used_by_vars_entry))) htab_t + types_used_by_vars_hash; + +hashval_t types_used_by_vars_do_hash (const void*); +int types_used_by_vars_eq (const void *, const void *); +void types_used_by_var_decl_insert (tree type, tree var_decl); + +/* During parsing of a global variable, this vector contains the types + referenced by the global variable. */ +extern GTY(()) vec *types_used_by_cur_var_decl; + +/* cfun shouldn't be set directly; use one of these functions instead. */ +extern void set_cfun (struct function *new_cfun); +extern void push_cfun (struct function *new_cfun); +extern void pop_cfun (void); +extern void instantiate_decl_rtl (rtx x); + +/* For backward compatibility... eventually these should all go away. */ +#define current_function_funcdef_no (cfun->funcdef_no) + +#define current_loops (cfun->x_current_loops) +#define dom_computed (cfun->cfg->x_dom_computed) +#define n_bbs_in_dom_tree (cfun->cfg->x_n_bbs_in_dom_tree) +#define VALUE_HISTOGRAMS(fun) (fun)->value_histograms + +/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END}, + and create duplicate blocks. */ +extern void reorder_blocks (void); + +/* Set BLOCK_NUMBER for all the blocks in FN. */ +extern void number_blocks (tree); + +extern void clear_block_marks (tree); +extern tree blocks_nreverse (tree); +extern tree block_chainon (tree, tree); + +/* Return size needed for stack frame based on slots so far allocated. + This size counts from zero. It is not rounded to STACK_BOUNDARY; + the caller may have to do that. */ +extern HOST_WIDE_INT get_frame_size (void); + +/* Issue an error message and return TRUE if frame OFFSET overflows in + the signed target pointer arithmetics for function FUNC. Otherwise + return FALSE. */ +extern bool frame_offset_overflow (HOST_WIDE_INT, tree); + +/* A pointer to a function to create target specific, per-function + data structures. */ +extern struct machine_function * (*init_machine_status) (void); + +/* Save and restore status information for a nested function. */ +extern void free_after_parsing (struct function *); +extern void free_after_compilation (struct function *); + +extern void init_varasm_status (void); + +#ifdef RTX_CODE +extern void diddle_return_value (void (*)(rtx, void*), void*); +extern void clobber_return_register (void); +#endif + +extern rtx get_arg_pointer_save_area (void); + +/* Returns the name of the current function. */ +extern const char *fndecl_name (tree); +extern const char *function_name (struct function *); +extern const char *current_function_name (void); + +extern void do_warn_unused_parameter (tree); + +extern bool pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, + tree, bool); +extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode, + tree, bool); + +extern void used_types_insert (tree); + +extern int get_next_funcdef_no (void); +extern int get_last_funcdef_no (void); + +#ifdef HAVE_simple_return +extern bool requires_stack_frame_p (rtx, HARD_REG_SET, HARD_REG_SET); +#endif + +extern rtx get_hard_reg_initial_val (enum machine_mode, unsigned int); +extern rtx has_hard_reg_initial_val (enum machine_mode, unsigned int); +extern rtx get_hard_reg_initial_reg (rtx); +extern bool initial_value_entry (int i, rtx *, rtx *); + +/* Called from gimple_expand_cfg. */ +extern unsigned int emit_initial_value_sets (void); + +/* In predict.c */ +extern bool optimize_function_for_size_p (struct function *); +extern bool optimize_function_for_speed_p (struct function *); + +#endif /* GCC_FUNCTION_H */ diff --git a/src/include/gcc-plugin.h b/src/include/gcc-plugin.h new file mode 100644 index 0000000..8510893 --- /dev/null +++ b/src/include/gcc-plugin.h @@ -0,0 +1,166 @@ +/* Public header file for plugins to include. + Copyright (C) 2009-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_PLUGIN_H +#define GCC_PLUGIN_H + +#ifndef IN_GCC +#define IN_GCC +#endif + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "highlev-plugin-common.h" +#include "hashtab.h" + +/* Event names. */ +enum plugin_event +{ +# define DEFEVENT(NAME) NAME, +# include "plugin.def" +# undef DEFEVENT + PLUGIN_EVENT_FIRST_DYNAMIC +}; + +/* All globals declared here have C linkage to reduce link compatibility + issues with implementation language choice and mangling. */ +#ifdef __cplusplus +extern "C" { +#endif + +extern const char **plugin_event_name; + +struct plugin_argument +{ + char *key; /* key of the argument. */ + char *value; /* value is optional and can be NULL. */ +}; + +/* Additional information about the plugin. Used by --help and --version. */ + +struct plugin_info +{ + const char *version; + const char *help; +}; + +/* Represents the gcc version. Used to avoid using an incompatible plugin. */ + +struct plugin_gcc_version +{ + const char *basever; + const char *datestamp; + const char *devphase; + const char *revision; + const char *configuration_arguments; +}; + +/* Object that keeps track of the plugin name and its arguments. */ +struct plugin_name_args +{ + char *base_name; /* Short name of the plugin (filename without + .so suffix). */ + const char *full_name; /* Path to the plugin as specified with + -fplugin=. */ + int argc; /* Number of arguments specified with + -fplugin-arg-... */ + struct plugin_argument *argv; /* Array of ARGC key-value pairs. */ + const char *version; /* Version string provided by plugin. */ + const char *help; /* Help string provided by plugin. */ +}; + +/* The default version check. Compares every field in VERSION. */ + +extern bool plugin_default_version_check (struct plugin_gcc_version *, + struct plugin_gcc_version *); + +/* Function type for the plugin initialization routine. Each plugin module + should define this as an externally-visible function with name + "plugin_init." + + PLUGIN_INFO - plugin invocation information. + VERSION - the plugin_gcc_version symbol of GCC. + + Returns 0 if initialization finishes successfully. */ + +typedef int (*plugin_init_func) (struct plugin_name_args *plugin_info, + struct plugin_gcc_version *version); + +/* Declaration for "plugin_init" function so that it doesn't need to be + duplicated in every plugin. */ +extern int plugin_init (struct plugin_name_args *plugin_info, + struct plugin_gcc_version *version); + +/* Function type for a plugin callback routine. + + GCC_DATA - event-specific data provided by GCC + USER_DATA - plugin-specific data provided by the plugin */ + +typedef void (*plugin_callback_func) (void *gcc_data, void *user_data); + +/* Called from the plugin's initialization code. Register a single callback. + This function can be called multiple times. + + PLUGIN_NAME - display name for this plugin + EVENT - which event the callback is for + CALLBACK - the callback to be called at the event + USER_DATA - plugin-provided data. +*/ + +/* Number of event ids / names registered so far. */ + +extern int get_event_last (void); + +int get_named_event_id (const char *name, enum insert_option insert); + +/* This is also called without a callback routine for the + PLUGIN_PASS_MANAGER_SETUP, PLUGIN_INFO, PLUGIN_REGISTER_GGC_ROOTS and + PLUGIN_REGISTER_GGC_CACHES pseudo-events, with a specific user_data. + */ + +extern void register_callback (const char *plugin_name, + int event, + plugin_callback_func callback, + void *user_data); + +extern int unregister_callback (const char *plugin_name, int event); + + +/* Retrieve the plugin directory name, as returned by the + -fprint-file-name=plugin argument to the gcc program, which is the + -iplugindir program argument to cc1. */ +extern const char* default_plugin_dir_name (void); + +#ifdef __cplusplus +} +#endif + +/* In case the C++ compiler does name mangling for globals, declare + plugin_is_GPL_compatible extern "C" so that a later definition + in a plugin file will have this linkage. */ +#ifdef __cplusplus +extern "C" { +#endif +extern int plugin_is_GPL_compatible; +#ifdef __cplusplus +} +#endif + +#endif /* GCC_PLUGIN_H */ diff --git a/src/include/genrtl.h b/src/include/genrtl.h new file mode 100644 index 0000000..dfc7220 --- /dev/null +++ b/src/include/genrtl.h @@ -0,0 +1,1219 @@ +/* Generated automatically by gengenrtl from rtl.def. */ + +#ifndef GCC_GENRTL_H +#define GCC_GENRTL_H + +#include "statistics.h" + +static inline rtx +gen_rtx_fmt_0_stat (RTX_CODE code, enum machine_mode mode MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + X0EXP (rt, 0) = NULL_RTX; + + return rt; +} + +#define gen_rtx_fmt_0(c, m)\ + gen_rtx_fmt_0_stat (c, m MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_ee_stat (RTX_CODE code, enum machine_mode mode, + rtx arg0, + rtx arg1 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XEXP (rt, 0) = arg0; + XEXP (rt, 1) = arg1; + + return rt; +} + +#define gen_rtx_fmt_ee(c, m, p0, p1)\ + gen_rtx_fmt_ee_stat (c, m, p0, p1 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_ue_stat (RTX_CODE code, enum machine_mode mode, + rtx arg0, + rtx arg1 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XEXP (rt, 0) = arg0; + XEXP (rt, 1) = arg1; + + return rt; +} + +#define gen_rtx_fmt_ue(c, m, p0, p1)\ + gen_rtx_fmt_ue_stat (c, m, p0, p1 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_E_stat (RTX_CODE code, enum machine_mode mode, + rtvec arg0 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XVEC (rt, 0) = arg0; + + return rt; +} + +#define gen_rtx_fmt_E(c, m, p0)\ + gen_rtx_fmt_E_stat (c, m, p0 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_i_stat (RTX_CODE code, enum machine_mode mode, + int arg0 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XINT (rt, 0) = arg0; + + return rt; +} + +#define gen_rtx_fmt_i(c, m, p0)\ + gen_rtx_fmt_i_stat (c, m, p0 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_iuuBeiie_stat (RTX_CODE code, enum machine_mode mode, + int arg0, + rtx arg1, + rtx arg2, + basic_block arg3, + rtx arg4, + int arg5, + int arg6, + rtx arg7 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XINT (rt, 0) = arg0; + XEXP (rt, 1) = arg1; + XEXP (rt, 2) = arg2; + XBBDEF (rt, 3) = arg3; + XEXP (rt, 4) = arg4; + XINT (rt, 5) = arg5; + XINT (rt, 6) = arg6; + XEXP (rt, 7) = arg7; + + return rt; +} + +#define gen_rtx_fmt_iuuBeiie(c, m, p0, p1, p2, p3, p4, p5, p6, p7)\ + gen_rtx_fmt_iuuBeiie_stat (c, m, p0, p1, p2, p3, p4, p5, p6, p7 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_iuuBeiie0_stat (RTX_CODE code, enum machine_mode mode, + int arg0, + rtx arg1, + rtx arg2, + basic_block arg3, + rtx arg4, + int arg5, + int arg6, + rtx arg7 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XINT (rt, 0) = arg0; + XEXP (rt, 1) = arg1; + XEXP (rt, 2) = arg2; + XBBDEF (rt, 3) = arg3; + XEXP (rt, 4) = arg4; + XINT (rt, 5) = arg5; + XINT (rt, 6) = arg6; + XEXP (rt, 7) = arg7; + X0EXP (rt, 8) = NULL_RTX; + + return rt; +} + +#define gen_rtx_fmt_iuuBeiie0(c, m, p0, p1, p2, p3, p4, p5, p6, p7)\ + gen_rtx_fmt_iuuBeiie0_stat (c, m, p0, p1, p2, p3, p4, p5, p6, p7 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_iuuBeiiee_stat (RTX_CODE code, enum machine_mode mode, + int arg0, + rtx arg1, + rtx arg2, + basic_block arg3, + rtx arg4, + int arg5, + int arg6, + rtx arg7, + rtx arg8 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XINT (rt, 0) = arg0; + XEXP (rt, 1) = arg1; + XEXP (rt, 2) = arg2; + XBBDEF (rt, 3) = arg3; + XEXP (rt, 4) = arg4; + XINT (rt, 5) = arg5; + XINT (rt, 6) = arg6; + XEXP (rt, 7) = arg7; + XEXP (rt, 8) = arg8; + + return rt; +} + +#define gen_rtx_fmt_iuuBeiiee(c, m, p0, p1, p2, p3, p4, p5, p6, p7, p8)\ + gen_rtx_fmt_iuuBeiiee_stat (c, m, p0, p1, p2, p3, p4, p5, p6, p7, p8 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_iuu00000_stat (RTX_CODE code, enum machine_mode mode, + int arg0, + rtx arg1, + rtx arg2 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XINT (rt, 0) = arg0; + XEXP (rt, 1) = arg1; + XEXP (rt, 2) = arg2; + X0EXP (rt, 3) = NULL_RTX; + X0EXP (rt, 4) = NULL_RTX; + X0EXP (rt, 5) = NULL_RTX; + X0EXP (rt, 6) = NULL_RTX; + X0EXP (rt, 7) = NULL_RTX; + + return rt; +} + +#define gen_rtx_fmt_iuu00000(c, m, p0, p1, p2)\ + gen_rtx_fmt_iuu00000_stat (c, m, p0, p1, p2 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_iuuB00is_stat (RTX_CODE code, enum machine_mode mode, + int arg0, + rtx arg1, + rtx arg2, + basic_block arg3, + int arg4, + const char *arg5 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XINT (rt, 0) = arg0; + XEXP (rt, 1) = arg1; + XEXP (rt, 2) = arg2; + XBBDEF (rt, 3) = arg3; + X0EXP (rt, 4) = NULL_RTX; + X0EXP (rt, 5) = NULL_RTX; + XINT (rt, 6) = arg4; + XSTR (rt, 7) = arg5; + + return rt; +} + +#define gen_rtx_fmt_iuuB00is(c, m, p0, p1, p2, p3, p4, p5)\ + gen_rtx_fmt_iuuB00is_stat (c, m, p0, p1, p2, p3, p4, p5 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_si_stat (RTX_CODE code, enum machine_mode mode, + const char *arg0, + int arg1 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XSTR (rt, 0) = arg0; + XINT (rt, 1) = arg1; + + return rt; +} + +#define gen_rtx_fmt_si(c, m, p0, p1)\ + gen_rtx_fmt_si_stat (c, m, p0, p1 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_ssiEEEi_stat (RTX_CODE code, enum machine_mode mode, + const char *arg0, + const char *arg1, + int arg2, + rtvec arg3, + rtvec arg4, + rtvec arg5, + int arg6 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XSTR (rt, 0) = arg0; + XSTR (rt, 1) = arg1; + XINT (rt, 2) = arg2; + XVEC (rt, 3) = arg3; + XVEC (rt, 4) = arg4; + XVEC (rt, 5) = arg5; + XINT (rt, 6) = arg6; + + return rt; +} + +#define gen_rtx_fmt_ssiEEEi(c, m, p0, p1, p2, p3, p4, p5, p6)\ + gen_rtx_fmt_ssiEEEi_stat (c, m, p0, p1, p2, p3, p4, p5, p6 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_Ei_stat (RTX_CODE code, enum machine_mode mode, + rtvec arg0, + int arg1 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XVEC (rt, 0) = arg0; + XINT (rt, 1) = arg1; + + return rt; +} + +#define gen_rtx_fmt_Ei(c, m, p0, p1)\ + gen_rtx_fmt_Ei_stat (c, m, p0, p1 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_eEee0_stat (RTX_CODE code, enum machine_mode mode, + rtx arg0, + rtvec arg1, + rtx arg2, + rtx arg3 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XEXP (rt, 0) = arg0; + XVEC (rt, 1) = arg1; + XEXP (rt, 2) = arg2; + XEXP (rt, 3) = arg3; + X0EXP (rt, 4) = NULL_RTX; + + return rt; +} + +#define gen_rtx_fmt_eEee0(c, m, p0, p1, p2, p3)\ + gen_rtx_fmt_eEee0_stat (c, m, p0, p1, p2, p3 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_eee_stat (RTX_CODE code, enum machine_mode mode, + rtx arg0, + rtx arg1, + rtx arg2 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XEXP (rt, 0) = arg0; + XEXP (rt, 1) = arg1; + XEXP (rt, 2) = arg2; + + return rt; +} + +#define gen_rtx_fmt_eee(c, m, p0, p1, p2)\ + gen_rtx_fmt_eee_stat (c, m, p0, p1, p2 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_e_stat (RTX_CODE code, enum machine_mode mode, + rtx arg0 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XEXP (rt, 0) = arg0; + + return rt; +} + +#define gen_rtx_fmt_e(c, m, p0)\ + gen_rtx_fmt_e_stat (c, m, p0 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt__stat (RTX_CODE code, enum machine_mode mode MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + + return rt; +} + +#define gen_rtx_fmt_(c, m)\ + gen_rtx_fmt__stat (c, m MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_w_stat (RTX_CODE code, enum machine_mode mode, + HOST_WIDE_INT arg0 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XWINT (rt, 0) = arg0; + + return rt; +} + +#define gen_rtx_fmt_w(c, m, p0)\ + gen_rtx_fmt_w_stat (c, m, p0 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_www_stat (RTX_CODE code, enum machine_mode mode, + HOST_WIDE_INT arg0, + HOST_WIDE_INT arg1, + HOST_WIDE_INT arg2 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XWINT (rt, 0) = arg0; + XWINT (rt, 1) = arg1; + XWINT (rt, 2) = arg2; + + return rt; +} + +#define gen_rtx_fmt_www(c, m, p0, p1, p2)\ + gen_rtx_fmt_www_stat (c, m, p0, p1, p2 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_s_stat (RTX_CODE code, enum machine_mode mode, + const char *arg0 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XSTR (rt, 0) = arg0; + + return rt; +} + +#define gen_rtx_fmt_s(c, m, p0)\ + gen_rtx_fmt_s_stat (c, m, p0 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_i00_stat (RTX_CODE code, enum machine_mode mode, + int arg0 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XINT (rt, 0) = arg0; + X0EXP (rt, 1) = NULL_RTX; + X0EXP (rt, 2) = NULL_RTX; + + return rt; +} + +#define gen_rtx_fmt_i00(c, m, p0)\ + gen_rtx_fmt_i00_stat (c, m, p0 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_ei_stat (RTX_CODE code, enum machine_mode mode, + rtx arg0, + int arg1 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XEXP (rt, 0) = arg0; + XINT (rt, 1) = arg1; + + return rt; +} + +#define gen_rtx_fmt_ei(c, m, p0, p1)\ + gen_rtx_fmt_ei_stat (c, m, p0, p1 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_e0_stat (RTX_CODE code, enum machine_mode mode, + rtx arg0 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XEXP (rt, 0) = arg0; + X0EXP (rt, 1) = NULL_RTX; + + return rt; +} + +#define gen_rtx_fmt_e0(c, m, p0)\ + gen_rtx_fmt_e0_stat (c, m, p0 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_u_stat (RTX_CODE code, enum machine_mode mode, + rtx arg0 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XEXP (rt, 0) = arg0; + + return rt; +} + +#define gen_rtx_fmt_u(c, m, p0)\ + gen_rtx_fmt_u_stat (c, m, p0 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_s00_stat (RTX_CODE code, enum machine_mode mode, + const char *arg0 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XSTR (rt, 0) = arg0; + X0EXP (rt, 1) = NULL_RTX; + X0EXP (rt, 2) = NULL_RTX; + + return rt; +} + +#define gen_rtx_fmt_s00(c, m, p0)\ + gen_rtx_fmt_s00_stat (c, m, p0 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_tei_stat (RTX_CODE code, enum machine_mode mode, + tree arg0, + rtx arg1, + int arg2 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XTREE (rt, 0) = arg0; + XEXP (rt, 1) = arg1; + XINT (rt, 2) = arg2; + + return rt; +} + +#define gen_rtx_fmt_tei(c, m, p0, p1, p2)\ + gen_rtx_fmt_tei_stat (c, m, p0, p1, p2 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_t_stat (RTX_CODE code, enum machine_mode mode, + tree arg0 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XTREE (rt, 0) = arg0; + + return rt; +} + +#define gen_rtx_fmt_t(c, m, p0)\ + gen_rtx_fmt_t_stat (c, m, p0 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_iss_stat (RTX_CODE code, enum machine_mode mode, + int arg0, + const char *arg1, + const char *arg2 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XINT (rt, 0) = arg0; + XSTR (rt, 1) = arg1; + XSTR (rt, 2) = arg2; + + return rt; +} + +#define gen_rtx_fmt_iss(c, m, p0, p1, p2)\ + gen_rtx_fmt_iss_stat (c, m, p0, p1, p2 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_is_stat (RTX_CODE code, enum machine_mode mode, + int arg0, + const char *arg1 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XINT (rt, 0) = arg0; + XSTR (rt, 1) = arg1; + + return rt; +} + +#define gen_rtx_fmt_is(c, m, p0, p1)\ + gen_rtx_fmt_is_stat (c, m, p0, p1 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_isE_stat (RTX_CODE code, enum machine_mode mode, + int arg0, + const char *arg1, + rtvec arg2 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XINT (rt, 0) = arg0; + XSTR (rt, 1) = arg1; + XVEC (rt, 2) = arg2; + + return rt; +} + +#define gen_rtx_fmt_isE(c, m, p0, p1, p2)\ + gen_rtx_fmt_isE_stat (c, m, p0, p1, p2 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_iE_stat (RTX_CODE code, enum machine_mode mode, + int arg0, + rtvec arg1 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XINT (rt, 0) = arg0; + XVEC (rt, 1) = arg1; + + return rt; +} + +#define gen_rtx_fmt_iE(c, m, p0, p1)\ + gen_rtx_fmt_iE_stat (c, m, p0, p1 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_ss_stat (RTX_CODE code, enum machine_mode mode, + const char *arg0, + const char *arg1 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XSTR (rt, 0) = arg0; + XSTR (rt, 1) = arg1; + + return rt; +} + +#define gen_rtx_fmt_ss(c, m, p0, p1)\ + gen_rtx_fmt_ss_stat (c, m, p0, p1 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_eE_stat (RTX_CODE code, enum machine_mode mode, + rtx arg0, + rtvec arg1 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XEXP (rt, 0) = arg0; + XVEC (rt, 1) = arg1; + + return rt; +} + +#define gen_rtx_fmt_eE(c, m, p0, p1)\ + gen_rtx_fmt_eE_stat (c, m, p0, p1 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_Ess_stat (RTX_CODE code, enum machine_mode mode, + rtvec arg0, + const char *arg1, + const char *arg2 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XVEC (rt, 0) = arg0; + XSTR (rt, 1) = arg1; + XSTR (rt, 2) = arg2; + + return rt; +} + +#define gen_rtx_fmt_Ess(c, m, p0, p1, p2)\ + gen_rtx_fmt_Ess_stat (c, m, p0, p1, p2 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_ses_stat (RTX_CODE code, enum machine_mode mode, + const char *arg0, + rtx arg1, + const char *arg2 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XSTR (rt, 0) = arg0; + XEXP (rt, 1) = arg1; + XSTR (rt, 2) = arg2; + + return rt; +} + +#define gen_rtx_fmt_ses(c, m, p0, p1, p2)\ + gen_rtx_fmt_ses_stat (c, m, p0, p1, p2 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_sss_stat (RTX_CODE code, enum machine_mode mode, + const char *arg0, + const char *arg1, + const char *arg2 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XSTR (rt, 0) = arg0; + XSTR (rt, 1) = arg1; + XSTR (rt, 2) = arg2; + + return rt; +} + +#define gen_rtx_fmt_sss(c, m, p0, p1, p2)\ + gen_rtx_fmt_sss_stat (c, m, p0, p1, p2 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_sse_stat (RTX_CODE code, enum machine_mode mode, + const char *arg0, + const char *arg1, + rtx arg2 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XSTR (rt, 0) = arg0; + XSTR (rt, 1) = arg1; + XEXP (rt, 2) = arg2; + + return rt; +} + +#define gen_rtx_fmt_sse(c, m, p0, p1, p2)\ + gen_rtx_fmt_sse_stat (c, m, p0, p1, p2 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_sies_stat (RTX_CODE code, enum machine_mode mode, + const char *arg0, + int arg1, + rtx arg2, + const char *arg3 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XSTR (rt, 0) = arg0; + XINT (rt, 1) = arg1; + XEXP (rt, 2) = arg2; + XSTR (rt, 3) = arg3; + + return rt; +} + +#define gen_rtx_fmt_sies(c, m, p0, p1, p2, p3)\ + gen_rtx_fmt_sies_stat (c, m, p0, p1, p2, p3 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_sE_stat (RTX_CODE code, enum machine_mode mode, + const char *arg0, + rtvec arg1 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XSTR (rt, 0) = arg0; + XVEC (rt, 1) = arg1; + + return rt; +} + +#define gen_rtx_fmt_sE(c, m, p0, p1)\ + gen_rtx_fmt_sE_stat (c, m, p0, p1 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_ii_stat (RTX_CODE code, enum machine_mode mode, + int arg0, + int arg1 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XINT (rt, 0) = arg0; + XINT (rt, 1) = arg1; + + return rt; +} + +#define gen_rtx_fmt_ii(c, m, p0, p1)\ + gen_rtx_fmt_ii_stat (c, m, p0, p1 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_Ee_stat (RTX_CODE code, enum machine_mode mode, + rtvec arg0, + rtx arg1 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XVEC (rt, 0) = arg0; + XEXP (rt, 1) = arg1; + + return rt; +} + +#define gen_rtx_fmt_Ee(c, m, p0, p1)\ + gen_rtx_fmt_Ee_stat (c, m, p0, p1 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_sEsE_stat (RTX_CODE code, enum machine_mode mode, + const char *arg0, + rtvec arg1, + const char *arg2, + rtvec arg3 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XSTR (rt, 0) = arg0; + XVEC (rt, 1) = arg1; + XSTR (rt, 2) = arg2; + XVEC (rt, 3) = arg3; + + return rt; +} + +#define gen_rtx_fmt_sEsE(c, m, p0, p1, p2, p3)\ + gen_rtx_fmt_sEsE_stat (c, m, p0, p1, p2, p3 MEM_STAT_INFO) + +static inline rtx +gen_rtx_fmt_ssss_stat (RTX_CODE code, enum machine_mode mode, + const char *arg0, + const char *arg1, + const char *arg2, + const char *arg3 MEM_STAT_DECL) +{ + rtx rt; + rt = rtx_alloc_stat (code PASS_MEM_STAT); + + PUT_MODE (rt, mode); + XSTR (rt, 0) = arg0; + XSTR (rt, 1) = arg1; + XSTR (rt, 2) = arg2; + XSTR (rt, 3) = arg3; + + return rt; +} + +#define gen_rtx_fmt_ssss(c, m, p0, p1, p2, p3)\ + gen_rtx_fmt_ssss_stat (c, m, p0, p1, p2, p3 MEM_STAT_INFO) + + +#define gen_rtx_VALUE(MODE) \ + gen_rtx_fmt_0 (VALUE, (MODE)) +#define gen_rtx_DEBUG_EXPR(MODE) \ + gen_rtx_fmt_0 (DEBUG_EXPR, (MODE)) +#define gen_rtx_EXPR_LIST(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (EXPR_LIST, (MODE), (ARG0), (ARG1)) +#define gen_rtx_INSN_LIST(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ue (INSN_LIST, (MODE), (ARG0), (ARG1)) +#define gen_rtx_SEQUENCE(MODE, ARG0) \ + gen_rtx_fmt_E (SEQUENCE, (MODE), (ARG0)) +#define gen_rtx_ADDRESS(MODE, ARG0) \ + gen_rtx_fmt_i (ADDRESS, (MODE), (ARG0)) +#define gen_rtx_DEBUG_INSN(MODE, ARG0, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + gen_rtx_fmt_iuuBeiie (DEBUG_INSN, (MODE), (ARG0), (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) +#define gen_rtx_INSN(MODE, ARG0, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + gen_rtx_fmt_iuuBeiie (INSN, (MODE), (ARG0), (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) +#define gen_rtx_JUMP_INSN(MODE, ARG0, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ + gen_rtx_fmt_iuuBeiie0 (JUMP_INSN, (MODE), (ARG0), (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) +#define gen_rtx_CALL_INSN(MODE, ARG0, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7, ARG8) \ + gen_rtx_fmt_iuuBeiiee (CALL_INSN, (MODE), (ARG0), (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7), (ARG8)) +#define gen_rtx_BARRIER(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_iuu00000 (BARRIER, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_CODE_LABEL(MODE, ARG0, ARG1, ARG2, ARG3, ARG4, ARG5) \ + gen_rtx_fmt_iuuB00is (CODE_LABEL, (MODE), (ARG0), (ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) +#define gen_rtx_COND_EXEC(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (COND_EXEC, (MODE), (ARG0), (ARG1)) +#define gen_rtx_PARALLEL(MODE, ARG0) \ + gen_rtx_fmt_E (PARALLEL, (MODE), (ARG0)) +#define gen_rtx_ASM_INPUT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_si (ASM_INPUT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_ASM_OPERANDS(MODE, ARG0, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ + gen_rtx_fmt_ssiEEEi (ASM_OPERANDS, (MODE), (ARG0), (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6)) +#define gen_rtx_UNSPEC(MODE, ARG0, ARG1) \ + gen_rtx_fmt_Ei (UNSPEC, (MODE), (ARG0), (ARG1)) +#define gen_rtx_UNSPEC_VOLATILE(MODE, ARG0, ARG1) \ + gen_rtx_fmt_Ei (UNSPEC_VOLATILE, (MODE), (ARG0), (ARG1)) +#define gen_rtx_ADDR_VEC(MODE, ARG0) \ + gen_rtx_fmt_E (ADDR_VEC, (MODE), (ARG0)) +#define gen_rtx_ADDR_DIFF_VEC(MODE, ARG0, ARG1, ARG2, ARG3) \ + gen_rtx_fmt_eEee0 (ADDR_DIFF_VEC, (MODE), (ARG0), (ARG1), (ARG2), (ARG3)) +#define gen_rtx_PREFETCH(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_eee (PREFETCH, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_SET(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (SET, (MODE), (ARG0), (ARG1)) +#define gen_rtx_USE(MODE, ARG0) \ + gen_rtx_fmt_e (USE, (MODE), (ARG0)) +#define gen_rtx_CLOBBER(MODE, ARG0) \ + gen_rtx_fmt_e (CLOBBER, (MODE), (ARG0)) +#define gen_rtx_CALL(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (CALL, (MODE), (ARG0), (ARG1)) +#define gen_rtx_raw_RETURN(MODE) \ + gen_rtx_fmt_ (RETURN, (MODE)) +#define gen_rtx_raw_SIMPLE_RETURN(MODE) \ + gen_rtx_fmt_ (SIMPLE_RETURN, (MODE)) +#define gen_rtx_EH_RETURN(MODE) \ + gen_rtx_fmt_ (EH_RETURN, (MODE)) +#define gen_rtx_TRAP_IF(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (TRAP_IF, (MODE), (ARG0), (ARG1)) +#define gen_rtx_raw_CONST_INT(MODE, ARG0) \ + gen_rtx_fmt_w (CONST_INT, (MODE), (ARG0)) +#define gen_rtx_raw_CONST_VECTOR(MODE, ARG0) \ + gen_rtx_fmt_E (CONST_VECTOR, (MODE), (ARG0)) +#define gen_rtx_CONST_STRING(MODE, ARG0) \ + gen_rtx_fmt_s (CONST_STRING, (MODE), (ARG0)) +#define gen_rtx_CONST(MODE, ARG0) \ + gen_rtx_fmt_e (CONST, (MODE), (ARG0)) +#define gen_rtx_raw_PC(MODE) \ + gen_rtx_fmt_ (PC, (MODE)) +#define gen_rtx_raw_REG(MODE, ARG0) \ + gen_rtx_fmt_i00 (REG, (MODE), (ARG0)) +#define gen_rtx_SCRATCH(MODE) \ + gen_rtx_fmt_0 (SCRATCH, (MODE)) +#define gen_rtx_raw_SUBREG(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ei (SUBREG, (MODE), (ARG0), (ARG1)) +#define gen_rtx_STRICT_LOW_PART(MODE, ARG0) \ + gen_rtx_fmt_e (STRICT_LOW_PART, (MODE), (ARG0)) +#define gen_rtx_CONCAT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (CONCAT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_CONCATN(MODE, ARG0) \ + gen_rtx_fmt_E (CONCATN, (MODE), (ARG0)) +#define gen_rtx_raw_MEM(MODE, ARG0) \ + gen_rtx_fmt_e0 (MEM, (MODE), (ARG0)) +#define gen_rtx_LABEL_REF(MODE, ARG0) \ + gen_rtx_fmt_u (LABEL_REF, (MODE), (ARG0)) +#define gen_rtx_SYMBOL_REF(MODE, ARG0) \ + gen_rtx_fmt_s00 (SYMBOL_REF, (MODE), (ARG0)) +#define gen_rtx_raw_CC0(MODE) \ + gen_rtx_fmt_ (CC0, (MODE)) +#define gen_rtx_IF_THEN_ELSE(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_eee (IF_THEN_ELSE, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_COMPARE(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (COMPARE, (MODE), (ARG0), (ARG1)) +#define gen_rtx_PLUS(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (PLUS, (MODE), (ARG0), (ARG1)) +#define gen_rtx_MINUS(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (MINUS, (MODE), (ARG0), (ARG1)) +#define gen_rtx_NEG(MODE, ARG0) \ + gen_rtx_fmt_e (NEG, (MODE), (ARG0)) +#define gen_rtx_MULT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (MULT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_SS_MULT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (SS_MULT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_US_MULT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (US_MULT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_DIV(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (DIV, (MODE), (ARG0), (ARG1)) +#define gen_rtx_SS_DIV(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (SS_DIV, (MODE), (ARG0), (ARG1)) +#define gen_rtx_US_DIV(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (US_DIV, (MODE), (ARG0), (ARG1)) +#define gen_rtx_MOD(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (MOD, (MODE), (ARG0), (ARG1)) +#define gen_rtx_UDIV(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (UDIV, (MODE), (ARG0), (ARG1)) +#define gen_rtx_UMOD(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (UMOD, (MODE), (ARG0), (ARG1)) +#define gen_rtx_AND(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (AND, (MODE), (ARG0), (ARG1)) +#define gen_rtx_IOR(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (IOR, (MODE), (ARG0), (ARG1)) +#define gen_rtx_XOR(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (XOR, (MODE), (ARG0), (ARG1)) +#define gen_rtx_NOT(MODE, ARG0) \ + gen_rtx_fmt_e (NOT, (MODE), (ARG0)) +#define gen_rtx_ASHIFT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (ASHIFT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_ROTATE(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (ROTATE, (MODE), (ARG0), (ARG1)) +#define gen_rtx_ASHIFTRT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (ASHIFTRT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_LSHIFTRT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (LSHIFTRT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_ROTATERT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (ROTATERT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_SMIN(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (SMIN, (MODE), (ARG0), (ARG1)) +#define gen_rtx_SMAX(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (SMAX, (MODE), (ARG0), (ARG1)) +#define gen_rtx_UMIN(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (UMIN, (MODE), (ARG0), (ARG1)) +#define gen_rtx_UMAX(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (UMAX, (MODE), (ARG0), (ARG1)) +#define gen_rtx_PRE_DEC(MODE, ARG0) \ + gen_rtx_fmt_e (PRE_DEC, (MODE), (ARG0)) +#define gen_rtx_PRE_INC(MODE, ARG0) \ + gen_rtx_fmt_e (PRE_INC, (MODE), (ARG0)) +#define gen_rtx_POST_DEC(MODE, ARG0) \ + gen_rtx_fmt_e (POST_DEC, (MODE), (ARG0)) +#define gen_rtx_POST_INC(MODE, ARG0) \ + gen_rtx_fmt_e (POST_INC, (MODE), (ARG0)) +#define gen_rtx_PRE_MODIFY(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (PRE_MODIFY, (MODE), (ARG0), (ARG1)) +#define gen_rtx_POST_MODIFY(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (POST_MODIFY, (MODE), (ARG0), (ARG1)) +#define gen_rtx_NE(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (NE, (MODE), (ARG0), (ARG1)) +#define gen_rtx_EQ(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (EQ, (MODE), (ARG0), (ARG1)) +#define gen_rtx_GE(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (GE, (MODE), (ARG0), (ARG1)) +#define gen_rtx_GT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (GT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_LE(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (LE, (MODE), (ARG0), (ARG1)) +#define gen_rtx_LT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (LT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_GEU(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (GEU, (MODE), (ARG0), (ARG1)) +#define gen_rtx_GTU(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (GTU, (MODE), (ARG0), (ARG1)) +#define gen_rtx_LEU(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (LEU, (MODE), (ARG0), (ARG1)) +#define gen_rtx_LTU(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (LTU, (MODE), (ARG0), (ARG1)) +#define gen_rtx_UNORDERED(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (UNORDERED, (MODE), (ARG0), (ARG1)) +#define gen_rtx_ORDERED(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (ORDERED, (MODE), (ARG0), (ARG1)) +#define gen_rtx_UNEQ(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (UNEQ, (MODE), (ARG0), (ARG1)) +#define gen_rtx_UNGE(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (UNGE, (MODE), (ARG0), (ARG1)) +#define gen_rtx_UNGT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (UNGT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_UNLE(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (UNLE, (MODE), (ARG0), (ARG1)) +#define gen_rtx_UNLT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (UNLT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_LTGT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (LTGT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_SIGN_EXTEND(MODE, ARG0) \ + gen_rtx_fmt_e (SIGN_EXTEND, (MODE), (ARG0)) +#define gen_rtx_ZERO_EXTEND(MODE, ARG0) \ + gen_rtx_fmt_e (ZERO_EXTEND, (MODE), (ARG0)) +#define gen_rtx_TRUNCATE(MODE, ARG0) \ + gen_rtx_fmt_e (TRUNCATE, (MODE), (ARG0)) +#define gen_rtx_FLOAT_EXTEND(MODE, ARG0) \ + gen_rtx_fmt_e (FLOAT_EXTEND, (MODE), (ARG0)) +#define gen_rtx_FLOAT_TRUNCATE(MODE, ARG0) \ + gen_rtx_fmt_e (FLOAT_TRUNCATE, (MODE), (ARG0)) +#define gen_rtx_FLOAT(MODE, ARG0) \ + gen_rtx_fmt_e (FLOAT, (MODE), (ARG0)) +#define gen_rtx_FIX(MODE, ARG0) \ + gen_rtx_fmt_e (FIX, (MODE), (ARG0)) +#define gen_rtx_UNSIGNED_FLOAT(MODE, ARG0) \ + gen_rtx_fmt_e (UNSIGNED_FLOAT, (MODE), (ARG0)) +#define gen_rtx_UNSIGNED_FIX(MODE, ARG0) \ + gen_rtx_fmt_e (UNSIGNED_FIX, (MODE), (ARG0)) +#define gen_rtx_FRACT_CONVERT(MODE, ARG0) \ + gen_rtx_fmt_e (FRACT_CONVERT, (MODE), (ARG0)) +#define gen_rtx_UNSIGNED_FRACT_CONVERT(MODE, ARG0) \ + gen_rtx_fmt_e (UNSIGNED_FRACT_CONVERT, (MODE), (ARG0)) +#define gen_rtx_SAT_FRACT(MODE, ARG0) \ + gen_rtx_fmt_e (SAT_FRACT, (MODE), (ARG0)) +#define gen_rtx_UNSIGNED_SAT_FRACT(MODE, ARG0) \ + gen_rtx_fmt_e (UNSIGNED_SAT_FRACT, (MODE), (ARG0)) +#define gen_rtx_ABS(MODE, ARG0) \ + gen_rtx_fmt_e (ABS, (MODE), (ARG0)) +#define gen_rtx_SQRT(MODE, ARG0) \ + gen_rtx_fmt_e (SQRT, (MODE), (ARG0)) +#define gen_rtx_BSWAP(MODE, ARG0) \ + gen_rtx_fmt_e (BSWAP, (MODE), (ARG0)) +#define gen_rtx_FFS(MODE, ARG0) \ + gen_rtx_fmt_e (FFS, (MODE), (ARG0)) +#define gen_rtx_CLRSB(MODE, ARG0) \ + gen_rtx_fmt_e (CLRSB, (MODE), (ARG0)) +#define gen_rtx_CLZ(MODE, ARG0) \ + gen_rtx_fmt_e (CLZ, (MODE), (ARG0)) +#define gen_rtx_CTZ(MODE, ARG0) \ + gen_rtx_fmt_e (CTZ, (MODE), (ARG0)) +#define gen_rtx_POPCOUNT(MODE, ARG0) \ + gen_rtx_fmt_e (POPCOUNT, (MODE), (ARG0)) +#define gen_rtx_PARITY(MODE, ARG0) \ + gen_rtx_fmt_e (PARITY, (MODE), (ARG0)) +#define gen_rtx_SIGN_EXTRACT(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_eee (SIGN_EXTRACT, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_ZERO_EXTRACT(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_eee (ZERO_EXTRACT, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_HIGH(MODE, ARG0) \ + gen_rtx_fmt_e (HIGH, (MODE), (ARG0)) +#define gen_rtx_LO_SUM(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (LO_SUM, (MODE), (ARG0), (ARG1)) +#define gen_rtx_VEC_MERGE(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_eee (VEC_MERGE, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_VEC_SELECT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (VEC_SELECT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_VEC_CONCAT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (VEC_CONCAT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_VEC_DUPLICATE(MODE, ARG0) \ + gen_rtx_fmt_e (VEC_DUPLICATE, (MODE), (ARG0)) +#define gen_rtx_SS_PLUS(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (SS_PLUS, (MODE), (ARG0), (ARG1)) +#define gen_rtx_US_PLUS(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (US_PLUS, (MODE), (ARG0), (ARG1)) +#define gen_rtx_SS_MINUS(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (SS_MINUS, (MODE), (ARG0), (ARG1)) +#define gen_rtx_SS_NEG(MODE, ARG0) \ + gen_rtx_fmt_e (SS_NEG, (MODE), (ARG0)) +#define gen_rtx_US_NEG(MODE, ARG0) \ + gen_rtx_fmt_e (US_NEG, (MODE), (ARG0)) +#define gen_rtx_SS_ABS(MODE, ARG0) \ + gen_rtx_fmt_e (SS_ABS, (MODE), (ARG0)) +#define gen_rtx_SS_ASHIFT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (SS_ASHIFT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_US_ASHIFT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (US_ASHIFT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_US_MINUS(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ee (US_MINUS, (MODE), (ARG0), (ARG1)) +#define gen_rtx_SS_TRUNCATE(MODE, ARG0) \ + gen_rtx_fmt_e (SS_TRUNCATE, (MODE), (ARG0)) +#define gen_rtx_US_TRUNCATE(MODE, ARG0) \ + gen_rtx_fmt_e (US_TRUNCATE, (MODE), (ARG0)) +#define gen_rtx_FMA(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_eee (FMA, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_VAR_LOCATION(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_tei (VAR_LOCATION, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_DEBUG_IMPLICIT_PTR(MODE, ARG0) \ + gen_rtx_fmt_t (DEBUG_IMPLICIT_PTR, (MODE), (ARG0)) +#define gen_rtx_ENTRY_VALUE(MODE) \ + gen_rtx_fmt_0 (ENTRY_VALUE, (MODE)) +#define gen_rtx_DEBUG_PARAMETER_REF(MODE, ARG0) \ + gen_rtx_fmt_t (DEBUG_PARAMETER_REF, (MODE), (ARG0)) +#define gen_rtx_MATCH_OPERAND(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_iss (MATCH_OPERAND, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_MATCH_SCRATCH(MODE, ARG0, ARG1) \ + gen_rtx_fmt_is (MATCH_SCRATCH, (MODE), (ARG0), (ARG1)) +#define gen_rtx_MATCH_OPERATOR(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_isE (MATCH_OPERATOR, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_MATCH_PARALLEL(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_isE (MATCH_PARALLEL, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_MATCH_DUP(MODE, ARG0) \ + gen_rtx_fmt_i (MATCH_DUP, (MODE), (ARG0)) +#define gen_rtx_MATCH_OP_DUP(MODE, ARG0, ARG1) \ + gen_rtx_fmt_iE (MATCH_OP_DUP, (MODE), (ARG0), (ARG1)) +#define gen_rtx_MATCH_PAR_DUP(MODE, ARG0, ARG1) \ + gen_rtx_fmt_iE (MATCH_PAR_DUP, (MODE), (ARG0), (ARG1)) +#define gen_rtx_MATCH_CODE(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ss (MATCH_CODE, (MODE), (ARG0), (ARG1)) +#define gen_rtx_MATCH_TEST(MODE, ARG0) \ + gen_rtx_fmt_s (MATCH_TEST, (MODE), (ARG0)) +#define gen_rtx_DEFINE_DELAY(MODE, ARG0, ARG1) \ + gen_rtx_fmt_eE (DEFINE_DELAY, (MODE), (ARG0), (ARG1)) +#define gen_rtx_DEFINE_COND_EXEC(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_Ess (DEFINE_COND_EXEC, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_DEFINE_PREDICATE(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_ses (DEFINE_PREDICATE, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_DEFINE_SPECIAL_PREDICATE(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_ses (DEFINE_SPECIAL_PREDICATE, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_DEFINE_REGISTER_CONSTRAINT(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_sss (DEFINE_REGISTER_CONSTRAINT, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_DEFINE_CONSTRAINT(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_sse (DEFINE_CONSTRAINT, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_DEFINE_MEMORY_CONSTRAINT(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_sse (DEFINE_MEMORY_CONSTRAINT, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_DEFINE_ADDRESS_CONSTRAINT(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_sse (DEFINE_ADDRESS_CONSTRAINT, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_EXCLUSION_SET(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ss (EXCLUSION_SET, (MODE), (ARG0), (ARG1)) +#define gen_rtx_PRESENCE_SET(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ss (PRESENCE_SET, (MODE), (ARG0), (ARG1)) +#define gen_rtx_FINAL_PRESENCE_SET(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ss (FINAL_PRESENCE_SET, (MODE), (ARG0), (ARG1)) +#define gen_rtx_ABSENCE_SET(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ss (ABSENCE_SET, (MODE), (ARG0), (ARG1)) +#define gen_rtx_FINAL_ABSENCE_SET(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ss (FINAL_ABSENCE_SET, (MODE), (ARG0), (ARG1)) +#define gen_rtx_DEFINE_AUTOMATON(MODE, ARG0) \ + gen_rtx_fmt_s (DEFINE_AUTOMATON, (MODE), (ARG0)) +#define gen_rtx_AUTOMATA_OPTION(MODE, ARG0) \ + gen_rtx_fmt_s (AUTOMATA_OPTION, (MODE), (ARG0)) +#define gen_rtx_DEFINE_RESERVATION(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ss (DEFINE_RESERVATION, (MODE), (ARG0), (ARG1)) +#define gen_rtx_DEFINE_INSN_RESERVATION(MODE, ARG0, ARG1, ARG2, ARG3) \ + gen_rtx_fmt_sies (DEFINE_INSN_RESERVATION, (MODE), (ARG0), (ARG1), (ARG2), (ARG3)) +#define gen_rtx_DEFINE_ATTR(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_sse (DEFINE_ATTR, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_DEFINE_ENUM_ATTR(MODE, ARG0, ARG1, ARG2) \ + gen_rtx_fmt_sse (DEFINE_ENUM_ATTR, (MODE), (ARG0), (ARG1), (ARG2)) +#define gen_rtx_ATTR(MODE, ARG0) \ + gen_rtx_fmt_s (ATTR, (MODE), (ARG0)) +#define gen_rtx_SET_ATTR(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ss (SET_ATTR, (MODE), (ARG0), (ARG1)) +#define gen_rtx_SET_ATTR_ALTERNATIVE(MODE, ARG0, ARG1) \ + gen_rtx_fmt_sE (SET_ATTR_ALTERNATIVE, (MODE), (ARG0), (ARG1)) +#define gen_rtx_EQ_ATTR(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ss (EQ_ATTR, (MODE), (ARG0), (ARG1)) +#define gen_rtx_EQ_ATTR_ALT(MODE, ARG0, ARG1) \ + gen_rtx_fmt_ii (EQ_ATTR_ALT, (MODE), (ARG0), (ARG1)) +#define gen_rtx_ATTR_FLAG(MODE, ARG0) \ + gen_rtx_fmt_s (ATTR_FLAG, (MODE), (ARG0)) +#define gen_rtx_COND(MODE, ARG0, ARG1) \ + gen_rtx_fmt_Ee (COND, (MODE), (ARG0), (ARG1)) +#define gen_rtx_DEFINE_SUBST(MODE, ARG0, ARG1, ARG2, ARG3) \ + gen_rtx_fmt_sEsE (DEFINE_SUBST, (MODE), (ARG0), (ARG1), (ARG2), (ARG3)) +#define gen_rtx_DEFINE_SUBST_ATTR(MODE, ARG0, ARG1, ARG2, ARG3) \ + gen_rtx_fmt_ssss (DEFINE_SUBST_ATTR, (MODE), (ARG0), (ARG1), (ARG2), (ARG3)) + +#endif /* GCC_GENRTL_H */ diff --git a/src/include/ggc.h b/src/include/ggc.h new file mode 100644 index 0000000..b31bc80 --- /dev/null +++ b/src/include/ggc.h @@ -0,0 +1,279 @@ +/* Garbage collection for the GNU compiler. + + Copyright (C) 1998-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_GGC_H +#define GCC_GGC_H +#include "statistics.h" + +/* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with + an external gc library that might be linked in. */ + +/* Constants for general use. */ +extern const char empty_string[]; /* empty string */ + +/* Internal functions and data structures used by the GTY + machinery, including the generated gt*.[hc] files. */ + +#include "gtype-desc.h" + +/* One of these applies its third parameter (with cookie in the fourth + parameter) to each pointer in the object pointed to by the first + parameter, using the second parameter. */ +typedef void (*gt_note_pointers) (void *, void *, gt_pointer_operator, + void *); + +/* One of these is called before objects are re-ordered in memory. + The first parameter is the original object, the second is the + subobject that has had its pointers reordered, the third parameter + can compute the new values of a pointer when given the cookie in + the fourth parameter. */ +typedef void (*gt_handle_reorder) (void *, void *, gt_pointer_operator, + void *); + +/* Used by the gt_pch_n_* routines. Register an object in the hash table. */ +extern int gt_pch_note_object (void *, void *, gt_note_pointers); + +/* Used by the gt_pch_n_* routines. Register that an object has a reorder + function. */ +extern void gt_pch_note_reorder (void *, void *, gt_handle_reorder); + +/* Mark the object in the first parameter and anything it points to. */ +typedef void (*gt_pointer_walker) (void *); + +/* Structures for the easy way to mark roots. + In an array, terminated by having base == NULL. */ +struct ggc_root_tab { + void *base; + size_t nelt; + size_t stride; + gt_pointer_walker cb; + gt_pointer_walker pchw; +}; +#define LAST_GGC_ROOT_TAB { NULL, 0, 0, NULL, NULL } +/* Pointers to arrays of ggc_root_tab, terminated by NULL. */ +extern const struct ggc_root_tab * const gt_ggc_rtab[]; +extern const struct ggc_root_tab * const gt_ggc_deletable_rtab[]; +extern const struct ggc_root_tab * const gt_pch_cache_rtab[]; +extern const struct ggc_root_tab * const gt_pch_scalar_rtab[]; + +/* Structure for hash table cache marking. */ +struct htab; +struct ggc_cache_tab { + struct htab * *base; + size_t nelt; + size_t stride; + gt_pointer_walker cb; + gt_pointer_walker pchw; + int (*marked_p) (const void *); +}; +#define LAST_GGC_CACHE_TAB { NULL, 0, 0, NULL, NULL, NULL } +/* Pointers to arrays of ggc_cache_tab, terminated by NULL. */ +extern const struct ggc_cache_tab * const gt_ggc_cache_rtab[]; + +/* If EXPR is not NULL and previously unmarked, mark it and evaluate + to true. Otherwise evaluate to false. */ +#define ggc_test_and_set_mark(EXPR) \ + ((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1 && ! ggc_set_mark (EXPR)) + +#define ggc_mark(EXPR) \ + do { \ + const void *const a__ = (EXPR); \ + if (a__ != NULL && a__ != (void *) 1) \ + ggc_set_mark (a__); \ + } while (0) + +/* Actually set the mark on a particular region of memory, but don't + follow pointers. This function is called by ggc_mark_*. It + returns zero if the object was not previously marked; nonzero if + the object was already marked, or if, for any other reason, + pointers in this data structure should not be traversed. */ +extern int ggc_set_mark (const void *); + +/* Return 1 if P has been marked, zero otherwise. + P must have been allocated by the GC allocator; it mustn't point to + static objects, stack variables, or memory allocated with malloc. */ +extern int ggc_marked_p (const void *); + +/* PCH and GGC handling for strings, mostly trivial. */ +extern void gt_pch_n_S (const void *); +extern void gt_ggc_m_S (const void *); + +/* End of GTY machinery API. */ + +/* Initialize the string pool. */ +extern void init_stringpool (void); + +/* Initialize the garbage collector. */ +extern void init_ggc (void); + +/* When true, identifier nodes are considered as GC roots. When + false, identifier nodes are treated like any other GC-allocated + object, and the identifier hash table is treated as a weak + hash. */ +extern bool ggc_protect_identifiers; + +/* Write out all GCed objects to F. */ +extern void gt_pch_save (FILE *f); + + +/* Allocation. */ + +/* The internal primitive. */ +extern void *ggc_internal_alloc_stat (size_t MEM_STAT_DECL) + ATTRIBUTE_MALLOC; + +extern size_t ggc_round_alloc_size (size_t requested_size); + +#define ggc_internal_alloc(s) ggc_internal_alloc_stat (s MEM_STAT_INFO) + +/* Allocates cleared memory. */ +extern void *ggc_internal_cleared_alloc_stat (size_t MEM_STAT_DECL) + ATTRIBUTE_MALLOC; + +/* Resize a block. */ +extern void *ggc_realloc_stat (void *, size_t MEM_STAT_DECL); + +/* Free a block. To be used when known for certain it's not reachable. */ +extern void ggc_free (void *); + +extern void dump_ggc_loc_statistics (bool); + +/* Reallocators. */ +#define GGC_RESIZEVEC(T, P, N) \ + ((T *) ggc_realloc_stat ((P), (N) * sizeof (T) MEM_STAT_INFO)) + +#define GGC_RESIZEVAR(T, P, N) \ + ((T *) ggc_realloc_stat ((P), (N) MEM_STAT_INFO)) + +static inline void * +ggc_internal_vec_alloc_stat (size_t s, size_t c MEM_STAT_DECL) +{ + return ggc_internal_alloc_stat (c * s PASS_MEM_STAT); +} + +static inline void * +ggc_internal_cleared_vec_alloc_stat (size_t s, size_t c MEM_STAT_DECL) +{ + return ggc_internal_cleared_alloc_stat (c * s PASS_MEM_STAT); +} + +#define ggc_internal_cleared_vec_alloc(s, c) \ + (ggc_internal_cleared_vec_alloc_stat ((s), (c) MEM_STAT_INFO)) + +static inline void * +ggc_alloc_atomic_stat (size_t s MEM_STAT_DECL) +{ + return ggc_internal_alloc_stat (s PASS_MEM_STAT); +} + +#define ggc_alloc_atomic(S) (ggc_alloc_atomic_stat ((S) MEM_STAT_INFO)) + +#define ggc_alloc_cleared_atomic(S) \ + (ggc_internal_cleared_alloc_stat ((S) MEM_STAT_INFO)) + +extern void *ggc_cleared_alloc_htab_ignore_args (size_t, size_t) + ATTRIBUTE_MALLOC; + +extern void *ggc_cleared_alloc_ptr_array_two_args (size_t, size_t) + ATTRIBUTE_MALLOC; + +#define htab_create_ggc(SIZE, HASH, EQ, DEL) \ + htab_create_typed_alloc (SIZE, HASH, EQ, DEL, \ + ggc_cleared_alloc_htab_ignore_args, \ + ggc_cleared_alloc_ptr_array_two_args, \ + ggc_free) + +#define splay_tree_new_ggc(COMPARE, ALLOC_TREE, ALLOC_NODE) \ + splay_tree_new_typed_alloc (COMPARE, NULL, NULL, &ALLOC_TREE, &ALLOC_NODE, \ + &ggc_splay_dont_free, NULL) + +extern void *ggc_splay_alloc (int, void *) + ATTRIBUTE_MALLOC; + +extern void ggc_splay_dont_free (void *, void *); + +/* Allocate a gc-able string, and fill it with LENGTH bytes from CONTENTS. + If LENGTH is -1, then CONTENTS is assumed to be a + null-terminated string and the memory sized accordingly. */ +extern const char *ggc_alloc_string_stat (const char *contents, int length + MEM_STAT_DECL); + +#define ggc_alloc_string(c, l) ggc_alloc_string_stat (c, l MEM_STAT_INFO) + +/* Make a copy of S, in GC-able memory. */ +#define ggc_strdup(S) ggc_alloc_string_stat ((S), -1 MEM_STAT_INFO) + +/* Invoke the collector. Garbage collection occurs only when this + function is called, not during allocations. */ +extern void ggc_collect (void); + +/* Register an additional root table. This can be useful for some + plugins. Does nothing if the passed pointer is NULL. */ +extern void ggc_register_root_tab (const struct ggc_root_tab *); + +/* Register an additional cache table. This can be useful for some + plugins. Does nothing if the passed pointer is NULL. */ +extern void ggc_register_cache_tab (const struct ggc_cache_tab *); + +/* Read objects previously saved with gt_pch_save from F. */ +extern void gt_pch_restore (FILE *f); + +/* Statistics. */ + +/* Print allocation statistics. */ +extern void ggc_print_statistics (void); + +extern void stringpool_statistics (void); + +/* Heuristics. */ +extern void init_ggc_heuristics (void); + +#define ggc_alloc_rtvec_sized(NELT) \ + ggc_alloc_rtvec_def (sizeof (struct rtvec_def) \ + + ((NELT) - 1) * sizeof (rtx)) \ + +/* Memory statistics passing versions of some allocators. Too few of them to + make gengtype produce them, so just define the needed ones here. */ +static inline struct rtx_def * +ggc_alloc_rtx_def_stat (size_t s MEM_STAT_DECL) +{ + return (struct rtx_def *) ggc_internal_alloc_stat (s PASS_MEM_STAT); +} + +static inline union tree_node * +ggc_alloc_tree_node_stat (size_t s MEM_STAT_DECL) +{ + return (union tree_node *) ggc_internal_alloc_stat (s PASS_MEM_STAT); +} + +static inline union tree_node * +ggc_alloc_cleared_tree_node_stat (size_t s MEM_STAT_DECL) +{ + return (union tree_node *) ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT); +} + +static inline union gimple_statement_d * +ggc_alloc_cleared_gimple_statement_d_stat (size_t s MEM_STAT_DECL) +{ + return (union gimple_statement_d *) + ggc_internal_cleared_alloc_stat (s PASS_MEM_STAT); +} + +#endif diff --git a/src/include/gimple-pretty-print.h b/src/include/gimple-pretty-print.h new file mode 100644 index 0000000..3992d22 --- /dev/null +++ b/src/include/gimple-pretty-print.h @@ -0,0 +1,36 @@ +/* Various declarations for pretty formatting of GIMPLE statements and + expressions. + Copyright (C) 2000-2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_GIMPLE_PRETTY_PRINT_H +#define GCC_GIMPLE_PRETTY_PRINT_H + +#include "pretty-print.h" +#include "tree-pretty-print.h" + +/* In gimple-pretty-print.c */ +extern void debug_gimple_stmt (gimple); +extern void debug_gimple_seq (gimple_seq); +extern void print_gimple_seq (FILE *, gimple_seq, int, int); +extern void print_gimple_stmt (FILE *, gimple, int, int); +extern void print_gimple_expr (FILE *, gimple, int, int); +extern void pp_gimple_stmt_1 (pretty_printer *, gimple, int, int); +extern void gimple_dump_bb_for_graph (pretty_printer *, basic_block); + +#endif /* ! GCC_GIMPLE_PRETTY_PRINT_H */ diff --git a/src/include/gimple.def b/src/include/gimple.def new file mode 100644 index 0000000..acad572 --- /dev/null +++ b/src/include/gimple.def @@ -0,0 +1,364 @@ +/* This file contains the definitions of the GIMPLE IR tuples used in GCC. + + Copyright (C) 2007-2013 Free Software Foundation, Inc. + Contributed by Aldy Hernandez + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* The format of this file is + DEFGSCODE(GIMPLE_symbol, printable name, GSS_symbol). */ + + +/* Error marker. This is used in similar ways as ERROR_MARK in tree.def. */ +DEFGSCODE(GIMPLE_ERROR_MARK, "gimple_error_mark", GSS_BASE) + +/* IMPORTANT. Do not rearrange the codes between GIMPLE_COND and + GIMPLE_RETURN. The ordering is exposed by gimple_has_ops calls. + These are all the GIMPLE statements with register operands. */ + +/* GIMPLE_COND + represents the conditional jump: + + if (OP1 COND_CODE OP2) goto TRUE_LABEL else goto FALSE_LABEL + + COND_CODE is the tree code used as the comparison predicate. It + must be of class tcc_comparison. + + OP1 and OP2 are the operands used in the comparison. They must be + accepted by is_gimple_operand. + + TRUE_LABEL and FALSE_LABEL are the LABEL_DECL nodes used as the + jump target for the comparison. */ +DEFGSCODE(GIMPLE_COND, "gimple_cond", GSS_WITH_OPS) + +/* GIMPLE_DEBUG represents a debug statement. */ +DEFGSCODE(GIMPLE_DEBUG, "gimple_debug", GSS_WITH_OPS) + +/* GIMPLE_GOTO represents unconditional jumps. + TARGET is a LABEL_DECL or an expression node for computed GOTOs. */ +DEFGSCODE(GIMPLE_GOTO, "gimple_goto", GSS_WITH_OPS) + +/* GIMPLE_LABEL