X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fcp%2Fcp-lang.c;h=e5c1c0911df6fc928b4297971501593fe05c08d1;hp=f2689b5da97e7c6c555e7b9e533c900a519c48a6;hb=05b89780615137ded52b999be3b2c4c64a3fb400;hpb=428a5a4e2995981f2292d2458a8466d67262c24a diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index f2689b5da97..e5c1c0911df 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -1,310 +1,242 @@ /* Language-dependent hooks for C++. - Copyright 2001, 2002 Free Software Foundation, Inc. + Copyright 2001, 2002, 2004, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. Contributed by Alexandre Oliva -This file is part of GNU CC. +This file is part of GCC. -GNU CC is free software; you can redistribute it and/or modify +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 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. -GNU CC is distributed in the hope that it will be useful, +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 GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" #include "system.h" +#include "coretypes.h" +#include "tm.h" #include "tree.h" #include "cp-tree.h" -#include "c-common.h" -#include "toplev.h" +#include "c-family/c-common.h" #include "langhooks.h" #include "langhooks-def.h" - -static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree)); -static bool ok_to_generate_alias_set_for_type PARAMS ((tree)); -static bool cxx_warn_unused_global_decl PARAMS ((tree)); -static tree cp_expr_size PARAMS ((tree)); +#include "debug.h" +#include "cp-objcp-common.h" +#include "hashtab.h" +#include "target.h" + +enum c_language_kind c_language = clk_cxx; +static void cp_init_ts (void); +static const char * cxx_dwarf_name (tree t, int verbosity); +static enum classify_record cp_classify_record (tree type); +static tree cp_eh_personality (void); +static tree get_template_innermost_arguments_folded (const_tree); +static tree get_template_argument_pack_elems_folded (const_tree); + +/* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h; + consequently, there should be very few hooks below. */ #undef LANG_HOOKS_NAME #define LANG_HOOKS_NAME "GNU C++" #undef LANG_HOOKS_INIT #define LANG_HOOKS_INIT cxx_init -#undef LANG_HOOKS_FINISH -#define LANG_HOOKS_FINISH cxx_finish -#undef LANG_HOOKS_CLEAR_BINDING_STACK -#define LANG_HOOKS_CLEAR_BINDING_STACK pop_everything -#undef LANG_HOOKS_INIT_OPTIONS -#define LANG_HOOKS_INIT_OPTIONS cxx_init_options -#undef LANG_HOOKS_DECODE_OPTION -#define LANG_HOOKS_DECODE_OPTION c_common_decode_option -#undef LANG_HOOKS_POST_OPTIONS -#define LANG_HOOKS_POST_OPTIONS c_common_post_options -#undef LANG_HOOKS_GET_ALIAS_SET -#define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set -#undef LANG_HOOKS_EXPAND_CONSTANT -#define LANG_HOOKS_EXPAND_CONSTANT cplus_expand_constant -#undef LANG_HOOKS_EXPAND_EXPR -#define LANG_HOOKS_EXPAND_EXPR cxx_expand_expr -#undef LANG_HOOKS_SAFE_FROM_P -#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p -#undef LANG_HOOKS_PARSE_FILE -#define LANG_HOOKS_PARSE_FILE c_common_parse_file -#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL -#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl -#undef LANG_HOOKS_UNSAVE_EXPR_NOW -#define LANG_HOOKS_UNSAVE_EXPR_NOW cxx_unsave_expr_now -#undef LANG_HOOKS_MAYBE_BUILD_CLEANUP -#define LANG_HOOKS_MAYBE_BUILD_CLEANUP cxx_maybe_build_cleanup -#undef LANG_HOOKS_TRUTHVALUE_CONVERSION -#define LANG_HOOKS_TRUTHVALUE_CONVERSION c_common_truthvalue_conversion -#undef LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES -#define LANG_HOOKS_INSERT_DEFAULT_ATTRIBUTES cxx_insert_default_attributes -#undef LANG_HOOKS_UNSAFE_FOR_REEVAL -#define LANG_HOOKS_UNSAFE_FOR_REEVAL c_common_unsafe_for_reeval -#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME -#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME mangle_decl -#undef LANG_HOOKS_MARK_ADDRESSABLE -#define LANG_HOOKS_MARK_ADDRESSABLE cxx_mark_addressable -#undef LANG_HOOKS_PRINT_STATISTICS -#define LANG_HOOKS_PRINT_STATISTICS cxx_print_statistics -#undef LANG_HOOKS_PRINT_XNODE -#define LANG_HOOKS_PRINT_XNODE cxx_print_xnode -#undef LANG_HOOKS_PRINT_DECL -#define LANG_HOOKS_PRINT_DECL cxx_print_decl -#undef LANG_HOOKS_PRINT_TYPE -#define LANG_HOOKS_PRINT_TYPE cxx_print_type -#undef LANG_HOOKS_PRINT_IDENTIFIER -#define LANG_HOOKS_PRINT_IDENTIFIER cxx_print_identifier -#undef LANG_HOOKS_DECL_PRINTABLE_NAME -#define LANG_HOOKS_DECL_PRINTABLE_NAME cxx_printable_name -#undef LANG_HOOKS_PRINT_ERROR_FUNCTION -#define LANG_HOOKS_PRINT_ERROR_FUNCTION cxx_print_error_function -#undef LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL -#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL cxx_warn_unused_global_decl - -#undef LANG_HOOKS_FUNCTION_INIT -#define LANG_HOOKS_FUNCTION_INIT cxx_push_function_context -#undef LANG_HOOKS_FUNCTION_FINAL -#define LANG_HOOKS_FUNCTION_FINAL cxx_pop_function_context - -/* Attribute hooks. */ -#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE -#define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE c_common_attribute_table -#undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE -#define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE c_common_format_attribute_table -#undef LANG_HOOKS_ATTRIBUTE_TABLE -#define LANG_HOOKS_ATTRIBUTE_TABLE cxx_attribute_table - -#undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES -#define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES \ - cp_walk_subtrees -#undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN -#define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \ - cp_cannot_inline_tree_fn -#undef LANG_HOOKS_TREE_INLINING_ADD_PENDING_FN_DECLS -#define LANG_HOOKS_TREE_INLINING_ADD_PENDING_FN_DECLS \ - cp_add_pending_fn_decls -#undef LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P -#define LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P \ - cp_is_overload_p -#undef LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P -#define LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P \ - cp_auto_var_in_fn_p -#undef LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING -#define LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING \ - cp_copy_res_decl_for_inlining -#undef LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING -#define LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \ - cp_convert_parm_for_inlining -#undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P -#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P anon_aggr_type_p -#undef LANG_HOOKS_TREE_INLINING_START_INLINING -#define LANG_HOOKS_TREE_INLINING_START_INLINING cp_start_inlining -#undef LANG_HOOKS_TREE_INLINING_END_INLINING -#define LANG_HOOKS_TREE_INLINING_END_INLINING cp_end_inlining -#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN -#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree -#undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN -#define LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN cp_type_quals -#undef LANG_HOOKS_EXPR_SIZE -#define LANG_HOOKS_EXPR_SIZE cp_expr_size - -#undef LANG_HOOKS_MAKE_TYPE -#define LANG_HOOKS_MAKE_TYPE cxx_make_type -#undef LANG_HOOKS_TYPE_FOR_MODE -#define LANG_HOOKS_TYPE_FOR_MODE c_common_type_for_mode -#undef LANG_HOOKS_TYPE_FOR_SIZE -#define LANG_HOOKS_TYPE_FOR_SIZE c_common_type_for_size -#undef LANG_HOOKS_SIGNED_TYPE -#define LANG_HOOKS_SIGNED_TYPE c_common_signed_type -#undef LANG_HOOKS_UNSIGNED_TYPE -#define LANG_HOOKS_UNSIGNED_TYPE c_common_unsigned_type -#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE -#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE c_common_signed_or_unsigned_type -#undef LANG_HOOKS_INCOMPLETE_TYPE_ERROR -#define LANG_HOOKS_INCOMPLETE_TYPE_ERROR cxx_incomplete_type_error -#undef LANG_HOOKS_TYPE_PROMOTES_TO -#define LANG_HOOKS_TYPE_PROMOTES_TO cxx_type_promotes_to - -/* Each front end provides its own hooks, for toplev.c. */ -const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; - -/* Tree code classes. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, - -const char tree_code_type[] = { -#include "tree.def" - 'x', -#include "c-common.def" - 'x', -#include "cp-tree.def" -}; -#undef DEFTREECODE - -/* Table indexed by tree code giving number of expression - operands beyond the fixed part of the node structure. - Not used for types or decls. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, - -const unsigned char tree_code_length[] = { -#include "tree.def" - 0, -#include "c-common.def" - 0, -#include "cp-tree.def" -}; -#undef DEFTREECODE - -/* Names of tree components. - Used for printing out the tree and error messages. */ -#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, - -const char *const tree_code_name[] = { -#include "tree.def" - "@@dummy", -#include "c-common.def" - "@@dummy", -#include "cp-tree.def" -}; -#undef DEFTREECODE - -/* Check if a C++ type is safe for aliasing. - Return TRUE if T safe for aliasing FALSE otherwise. */ +#undef LANG_HOOKS_CLASSIFY_RECORD +#define LANG_HOOKS_CLASSIFY_RECORD cp_classify_record +#undef LANG_HOOKS_GENERIC_TYPE_P +#define LANG_HOOKS_GENERIC_TYPE_P class_tmpl_impl_spec_p + +#undef LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS +#define LANG_HOOKS_GET_INNERMOST_GENERIC_PARMS \ + get_primary_template_innermost_parameters +#undef LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS +#define LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS \ + get_template_innermost_arguments_folded +#undef LANG_HOOKS_FUNCTION_PARAMETER_PACK_P +#define LANG_HOOKS_FUNCTION_PARAMETER_PACK_P \ + function_parameter_pack_p +#undef LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS +#define LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS \ + get_template_argument_pack_elems_folded +#undef LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P +#define LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P \ + template_template_parameter_p +#undef LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P +#define LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P \ + function_parameter_expanded_from_pack_p +#undef LANG_HOOKS_GET_GENERIC_FUNCTION_DECL +#define LANG_HOOKS_GET_GENERIC_FUNCTION_DECL get_function_template_decl +#undef LANG_HOOKS_DWARF_NAME +#define LANG_HOOKS_DWARF_NAME cxx_dwarf_name +#undef LANG_HOOKS_INIT_TS +#define LANG_HOOKS_INIT_TS cp_init_ts +#undef LANG_HOOKS_EH_PERSONALITY +#define LANG_HOOKS_EH_PERSONALITY cp_eh_personality +#undef LANG_HOOKS_EH_RUNTIME_TYPE +#define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type + +/* Each front end provides its own lang hook initializer. */ +struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; + +/* Lang hook routines common to C++ and ObjC++ appear in cp/cp-objcp-common.c; + there should be very few routines below. */ + +/* The following function does something real, but only in Objective-C++. */ + +tree +objcp_tsubst_copy_and_build (tree t ATTRIBUTE_UNUSED, + tree args ATTRIBUTE_UNUSED, + tsubst_flags_t complain ATTRIBUTE_UNUSED, + tree in_decl ATTRIBUTE_UNUSED, + bool function_p ATTRIBUTE_UNUSED) +{ + return NULL_TREE; +} -static bool -ok_to_generate_alias_set_for_type (t) - tree t; + +static void +cp_init_ts (void) { - if (TYPE_PTRMEMFUNC_P (t)) - return true; - if (AGGREGATE_TYPE_P (t)) - { - if ((TREE_CODE (t) == RECORD_TYPE) || (TREE_CODE (t) == UNION_TYPE)) - { - tree fields; - /* Backend-created structs are safe. */ - if (! CLASS_TYPE_P (t)) - return true; - /* PODs are safe. */ - if (! CLASSTYPE_NON_POD_P(t)) - return true; - /* Classes with virtual baseclasses are not. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (t)) - return false; - /* Recursively check the base classes. */ - if (TYPE_BINFO (t) != NULL && TYPE_BINFO_BASETYPES (t) != NULL) - { - int i; - for (i = 0; i < TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (t)); i++) - { - tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), i); - if (!ok_to_generate_alias_set_for_type (BINFO_TYPE (binfo))) - return false; - } - } - /* Check all the fields. */ - for (fields = TYPE_FIELDS (t); fields; fields = TREE_CHAIN (fields)) - { - if (TREE_CODE (fields) != FIELD_DECL) - continue; - if (! ok_to_generate_alias_set_for_type (TREE_TYPE (fields))) - return false; - } - return true; - } - else if (TREE_CODE (t) == ARRAY_TYPE) - return ok_to_generate_alias_set_for_type (TREE_TYPE (t)); - else - /* This should never happen, we dealt with all the aggregate - types that can appear in C++ above. */ - abort (); - } - else - return true; + tree_contains_struct[NAMESPACE_DECL][TS_DECL_NON_COMMON] = 1; + tree_contains_struct[USING_DECL][TS_DECL_NON_COMMON] = 1; + tree_contains_struct[TEMPLATE_DECL][TS_DECL_NON_COMMON] = 1; + + tree_contains_struct[NAMESPACE_DECL][TS_DECL_WITH_VIS] = 1; + tree_contains_struct[USING_DECL][TS_DECL_WITH_VIS] = 1; + tree_contains_struct[TEMPLATE_DECL][TS_DECL_WITH_VIS] = 1; + + tree_contains_struct[NAMESPACE_DECL][TS_DECL_WRTL] = 1; + tree_contains_struct[USING_DECL][TS_DECL_WRTL] = 1; + tree_contains_struct[TEMPLATE_DECL][TS_DECL_WRTL] = 1; + + tree_contains_struct[NAMESPACE_DECL][TS_DECL_COMMON] = 1; + tree_contains_struct[USING_DECL][TS_DECL_COMMON] = 1; + tree_contains_struct[TEMPLATE_DECL][TS_DECL_COMMON] = 1; + + tree_contains_struct[NAMESPACE_DECL][TS_DECL_MINIMAL] = 1; + tree_contains_struct[USING_DECL][TS_DECL_MINIMAL] = 1; + tree_contains_struct[TEMPLATE_DECL][TS_DECL_MINIMAL] = 1; + + init_shadowed_var_for_decl (); + } -/* Special routine to get the alias set for C++. */ +static const char * +cxx_dwarf_name (tree t, int verbosity) +{ + gcc_assert (DECL_P (t)); + + if (DECL_NAME (t) + && (ANON_AGGRNAME_P (DECL_NAME (t)) || LAMBDANAME_P (DECL_NAME (t)))) + return NULL; + if (verbosity >= 2) + return decl_as_string (t, + TFF_DECL_SPECIFIERS | TFF_UNQUALIFIED_NAME + | TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS); -static HOST_WIDE_INT -cxx_get_alias_set (t) - tree t; + return cxx_printable_name (t, verbosity); +} + +static enum classify_record +cp_classify_record (tree type) { - /* It's not yet safe to use alias sets for classes in C++. */ - if (!ok_to_generate_alias_set_for_type(t)) - return 0; + if (CLASSTYPE_DECLARED_CLASS (type)) + return RECORD_IS_CLASS; - return c_common_get_alias_set (t); + return RECORD_IS_STRUCT; } -/* Called from check_global_declarations. */ +static GTY(()) tree cp_eh_personality_decl; -static bool -cxx_warn_unused_global_decl (decl) - tree decl; +static tree +cp_eh_personality (void) { - if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)) - return false; - if (DECL_IN_SYSTEM_HEADER (decl)) - return false; + if (!cp_eh_personality_decl) + { + const char *lang = (pragma_java_exceptions ? "gcj" : "gxx"); + cp_eh_personality_decl = build_personality_function (lang); + } - /* Const variables take the place of #defines in C++. */ - if (TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl)) - return false; + return cp_eh_personality_decl; +} + +/* This is a subroutine of fold_cplus_constants. It returns TRUE if T + is a C++ specific constant that needs to be folded further before + being passed to the debug info emitter. */ - return true; +static bool +template_arg_needs_folding (const_tree t) +{ + /* For now only PTRMEM_CST nodes are to be folded further. */ + if (TREE_CODE (t) == PTRMEM_CST) + return true; + return false; } -/* Langhook for expr_size: Tell the backend that the value of an expression - of non-POD class type does not include any tail padding; a derived class - might have allocated something there. */ +/* Fold the elements of the TREE_VEC C which are C++ specific nodes + that would need folding so that they can be processed by the debug + info emitter. This is a subroutine of + get_template_innermost_arguments_folded and + get_template_argument_pack_elems_folded. */ static tree -cp_expr_size (exp) - tree exp; +fold_cplus_constants (const_tree c) { - if (CLASS_TYPE_P (TREE_TYPE (exp))) + tree folded_elems, elems = CONST_CAST_TREE (c); + int vec_len, i; + + if (elems == NULL_TREE || elems == error_mark_node) + return elems; + + vec_len = TREE_VEC_LENGTH (elems); + + /* First check if there is at least one element that needs + folding. If there is none, we just return ELEMS. Otherwise create + and return a new tree vector that contains the folded versions of + ELEMS. This is to avoid allocating memory if we don't need + to. */ + for (i = 0; i < vec_len; ++i) + { + if (template_arg_needs_folding (TREE_VEC_ELT (elems, i))) + break; + } + if (i == vec_len) + return elems; + + folded_elems = make_tree_vec (vec_len); + for (i = 0; i < vec_len; ++i) { - /* The backend should not be interested in the size of an expression - of a type with both of these set; all copies of such types must go - through a constructor or assignment op. */ - if (TYPE_HAS_COMPLEX_INIT_REF (TREE_TYPE (exp)) - && TYPE_HAS_COMPLEX_ASSIGN_REF (TREE_TYPE (exp))) - abort (); - /* This would be wrong for a type with virtual bases, but they are - caught by the abort above. */ - return CLASSTYPE_SIZE_UNIT (TREE_TYPE (exp)); + tree elem = TREE_VEC_ELT (elems, i); + TREE_VEC_ELT (folded_elems, i) = + (elem && !TYPE_P (elem)) ? cplus_expand_constant (elem) : elem; + } - else - /* Use the default code. */ - return lhd_expr_size (exp); + return folded_elems; +} + +/* The C++ implementation of the LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS + hook. It returns the innermost template arguments of type T, and + makes sure those arguments are folded enough for the debug info + emitter. */ + +static tree +get_template_innermost_arguments_folded (const_tree t) +{ + return fold_cplus_constants (get_template_innermost_arguments (t)); } + +static tree +get_template_argument_pack_elems_folded (const_tree t) +{ + return fold_cplus_constants (get_template_argument_pack_elems (t)); +} + +#include "gt-cp-cp-lang.h" +#include "gtype-cp.h"