/* Some code common to C++ and ObjC++ front ends.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2007, 2008, 2009, 2010, 2011
+ Free Software Foundation, Inc.
Contributed by Ziemowit Laski <zlaski@apple.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 2, or (at your option) any later
+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
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.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"
#include "diagnostic.h"
/* Special routine to get the alias set for C++. */
-HOST_WIDE_INT
+alias_set_type
cxx_get_alias_set (tree t)
{
if (IS_FAKE_BASE_TYPE (t))
return get_alias_set (TYPE_CONTEXT (t));
/* Punt on PMFs until we canonicalize functions properly. */
- if (TYPE_PTRMEMFUNC_P (t))
+ if (TYPE_PTRMEMFUNC_P (t)
+ || (POINTER_TYPE_P (t)
+ && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))))
return 0;
return c_common_get_alias_set (t);
/* Called from check_global_declarations. */
bool
-cxx_warn_unused_global_decl (tree decl)
+cxx_warn_unused_global_decl (const_tree decl)
{
if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
return false;
return true;
}
-/* 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. */
-
-tree
-cp_expr_size (tree exp)
-{
- tree type = TREE_TYPE (exp);
-
- if (CLASS_TYPE_P (type))
- {
- /* 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. */
- gcc_assert (!TYPE_HAS_COMPLEX_INIT_REF (type)
- || !TYPE_HAS_COMPLEX_ASSIGN_REF (type)
- /* But storing a CONSTRUCTOR isn't a copy. */
- || TREE_CODE (exp) == CONSTRUCTOR
- /* And, the gimplifier will sometimes make a copy of
- an aggregate. In particular, for a case like:
-
- struct S { S(); };
- struct X { int a; S s; };
- X x = { 0 };
-
- the gimplifier will create a temporary with
- static storage duration, perform static
- initialization of the temporary, and then copy
- the result. Since the "s" subobject is never
- constructed, this is a valid transformation. */
- || CP_AGGREGATE_TYPE_P (type));
-
- /* This would be wrong for a type with virtual bases, but they are
- caught by the assert above. */
- return (is_empty_class (type)
- ? size_zero_node
- : CLASSTYPE_SIZE_UNIT (type));
- }
- else
- /* Use the default code. */
- return lhd_expr_size (exp);
-}
-
/* Langhook for tree_size: determine size of our 'x' and 'c' nodes. */
size_t
cp_tree_size (enum tree_code code)
{
switch (code)
{
- case TINST_LEVEL: return sizeof (struct tinst_level_s);
case PTRMEM_CST: return sizeof (struct ptrmem_cst);
case BASELINK: return sizeof (struct tree_baselink);
case TEMPLATE_PARM_INDEX: return sizeof (template_parm_index);
case DEFAULT_ARG: return sizeof (struct tree_default_arg);
+ case DEFERRED_NOEXCEPT: return sizeof (struct tree_deferred_noexcept);
case OVERLOAD: return sizeof (struct tree_overload);
+ case STATIC_ASSERT: return sizeof (struct tree_static_assert);
+ case TYPE_ARGUMENT_PACK:
+ case TYPE_PACK_EXPANSION:
+ return sizeof (struct tree_common);
+
+ case NONTYPE_ARGUMENT_PACK:
+ case EXPR_PACK_EXPANSION:
+ return sizeof (struct tree_exp);
+
+ case ARGUMENT_PACK_SELECT:
+ return sizeof (struct tree_argument_pack_select);
+
+ case TRAIT_EXPR:
+ return sizeof (struct tree_trait_expr);
+
+ case LAMBDA_EXPR: return sizeof (struct tree_lambda_expr);
+
+ case TEMPLATE_INFO: return sizeof (struct tree_template_info);
+
+ case USERDEF_LITERAL: return sizeof (struct tree_userdef_literal);
+
default:
gcc_unreachable ();
}
void
cxx_initialize_diagnostics (diagnostic_context *context)
{
- pretty_printer *base = context->printer;
- cxx_pretty_printer *pp = XNEW (cxx_pretty_printer);
+ pretty_printer *base;
+ cxx_pretty_printer *pp;
+
+ c_common_initialize_diagnostics (context);
+
+ base = context->printer;
+ pp = XNEW (cxx_pretty_printer);
memcpy (pp_base (pp), base, sizeof (pretty_printer));
pp_cxx_pretty_printer_init (pp);
context->printer = (pretty_printer *) pp;
int
cxx_types_compatible_p (tree x, tree y)
{
- if (same_type_ignoring_top_level_qualifiers_p (x, y))
- return 1;
-
- /* Once we get to the middle-end, references and pointers are
- interchangeable. FIXME should we try to replace all references with
- pointers? */
- if (POINTER_TYPE_P (x) && POINTER_TYPE_P (y)
- && TYPE_MODE (x) == TYPE_MODE (y)
- && TYPE_REF_CAN_ALIAS_ALL (x) == TYPE_REF_CAN_ALIAS_ALL (y)
- && same_type_p (TREE_TYPE (x), TREE_TYPE (y)))
- return 1;
-
- return 0;
+ return same_type_ignoring_top_level_qualifiers_p (x, y);
}
-tree
-cxx_staticp (tree arg)
-{
- switch (TREE_CODE (arg))
- {
- case BASELINK:
- return staticp (BASELINK_FUNCTIONS (arg));
+/* Return true if DECL is explicit member function. */
- default:
- break;
- }
-
- return NULL_TREE;
+bool
+cp_function_decl_explicit_p (tree decl)
+{
+ return (decl
+ && FUNCTION_FIRST_USER_PARMTYPE (decl) != void_list_node
+ && DECL_LANG_SPECIFIC (STRIP_TEMPLATE (decl))
+ && DECL_NONCONVERTING_P (decl));
}
/* Stubs to keep c-opts.c happy. */
/* c-pragma.c needs to query whether a decl has extern "C" linkage. */
bool
-has_c_linkage (tree decl)
+has_c_linkage (const_tree decl)
{
return DECL_EXTERN_C_P (decl);
}
-static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
+static GTY ((if_marked ("tree_decl_map_marked_p"), param_is (struct tree_decl_map)))
htab_t shadowed_var_for_decl;
/* Lookup a shadowed var for FROM, and return it if we find one. */
tree
decl_shadowed_for_var_lookup (tree from)
{
- struct tree_map *h, in;
- in.from = from;
+ struct tree_decl_map *h, in;
+ in.base.from = from;
- h = (struct tree_map *) htab_find_with_hash (shadowed_var_for_decl, &in,
- htab_hash_pointer (from));
+ h = (struct tree_decl_map *)
+ htab_find_with_hash (shadowed_var_for_decl, &in, DECL_UID (from));
if (h)
return h->to;
return NULL_TREE;
void
decl_shadowed_for_var_insert (tree from, tree to)
{
- struct tree_map *h;
+ struct tree_decl_map *h;
void **loc;
- h = GGC_NEW (struct tree_map);
- h->hash = htab_hash_pointer (from);
- h->from = from;
+ h = ggc_alloc_tree_decl_map ();
+ h->base.from = from;
h->to = to;
- loc = htab_find_slot_with_hash (shadowed_var_for_decl, h, h->hash, INSERT);
- *(struct tree_map **) loc = h;
+ loc = htab_find_slot_with_hash (shadowed_var_for_decl, h, DECL_UID (from),
+ INSERT);
+ *(struct tree_decl_map **) loc = h;
}
void
init_shadowed_var_for_decl (void)
{
- shadowed_var_for_decl = htab_create_ggc (512, tree_map_hash,
- tree_map_eq, 0);
+ shadowed_var_for_decl = htab_create_ggc (512, tree_decl_map_hash,
+ tree_decl_map_eq, 0);
}
+/* Return true if stmt can fall thru. Used by block_may_fallthru
+ default case. */
+
+bool
+cxx_block_may_fallthru (const_tree stmt)
+{
+ switch (TREE_CODE (stmt))
+ {
+ case EXPR_STMT:
+ return block_may_fallthru (EXPR_STMT_EXPR (stmt));
+
+ case THROW_EXPR:
+ return false;
+
+ default:
+ return true;
+ }
+}
+
+void
+cp_common_init_ts (void)
+{
+ MARK_TS_DECL_NON_COMMON (NAMESPACE_DECL);
+ MARK_TS_DECL_NON_COMMON (USING_DECL);
+ MARK_TS_DECL_NON_COMMON (TEMPLATE_DECL);
+
+ MARK_TS_COMMON (TEMPLATE_TEMPLATE_PARM);
+ MARK_TS_COMMON (TEMPLATE_TYPE_PARM);
+ MARK_TS_COMMON (TEMPLATE_PARM_INDEX);
+ MARK_TS_COMMON (OVERLOAD);
+ MARK_TS_COMMON (TEMPLATE_INFO);
+ MARK_TS_COMMON (TYPENAME_TYPE);
+ MARK_TS_COMMON (TYPEOF_TYPE);
+ MARK_TS_COMMON (UNDERLYING_TYPE);
+ MARK_TS_COMMON (BASELINK);
+ MARK_TS_COMMON (TYPE_PACK_EXPANSION);
+ MARK_TS_COMMON (TYPE_ARGUMENT_PACK);
+ MARK_TS_COMMON (DECLTYPE_TYPE);
+ MARK_TS_COMMON (BOUND_TEMPLATE_TEMPLATE_PARM);
+ MARK_TS_COMMON (UNBOUND_CLASS_TEMPLATE);
+
+ MARK_TS_TYPED (EXPR_PACK_EXPANSION);
+ MARK_TS_TYPED (SWITCH_STMT);
+ MARK_TS_TYPED (IF_STMT);
+ MARK_TS_TYPED (FOR_STMT);
+ MARK_TS_TYPED (RANGE_FOR_STMT);
+ MARK_TS_TYPED (AGGR_INIT_EXPR);
+ MARK_TS_TYPED (EXPR_STMT);
+ MARK_TS_TYPED (EH_SPEC_BLOCK);
+ MARK_TS_TYPED (CLEANUP_STMT);
+ MARK_TS_TYPED (SCOPE_REF);
+ MARK_TS_TYPED (CAST_EXPR);
+ MARK_TS_TYPED (NON_DEPENDENT_EXPR);
+ MARK_TS_TYPED (MODOP_EXPR);
+ MARK_TS_TYPED (TRY_BLOCK);
+ MARK_TS_TYPED (THROW_EXPR);
+ MARK_TS_TYPED (HANDLER);
+ MARK_TS_TYPED (REINTERPRET_CAST_EXPR);
+ MARK_TS_TYPED (CONST_CAST_EXPR);
+ MARK_TS_TYPED (STATIC_CAST_EXPR);
+ MARK_TS_TYPED (DYNAMIC_CAST_EXPR);
+ MARK_TS_TYPED (IMPLICIT_CONV_EXPR);
+ MARK_TS_TYPED (TEMPLATE_ID_EXPR);
+ MARK_TS_TYPED (ARROW_EXPR);
+ MARK_TS_TYPED (SIZEOF_EXPR);
+ MARK_TS_TYPED (ALIGNOF_EXPR);
+ MARK_TS_TYPED (AT_ENCODE_EXPR);
+ MARK_TS_TYPED (UNARY_PLUS_EXPR);
+ MARK_TS_TYPED (TRAIT_EXPR);
+ MARK_TS_TYPED (TYPE_ARGUMENT_PACK);
+ MARK_TS_TYPED (NOEXCEPT_EXPR);
+ MARK_TS_TYPED (NONTYPE_ARGUMENT_PACK);
+ MARK_TS_TYPED (WHILE_STMT);
+ MARK_TS_TYPED (NEW_EXPR);
+ MARK_TS_TYPED (VEC_NEW_EXPR);
+ MARK_TS_TYPED (BREAK_STMT);
+ MARK_TS_TYPED (MEMBER_REF);
+ MARK_TS_TYPED (DOTSTAR_EXPR);
+ MARK_TS_TYPED (DO_STMT);
+ MARK_TS_TYPED (DELETE_EXPR);
+ MARK_TS_TYPED (VEC_DELETE_EXPR);
+ MARK_TS_TYPED (CONTINUE_STMT);
+ MARK_TS_TYPED (TAG_DEFN);
+ MARK_TS_TYPED (PSEUDO_DTOR_EXPR);
+ MARK_TS_TYPED (TYPEID_EXPR);
+ MARK_TS_TYPED (MUST_NOT_THROW_EXPR);
+ MARK_TS_TYPED (STMT_EXPR);
+ MARK_TS_TYPED (OFFSET_REF);
+ MARK_TS_TYPED (OFFSETOF_EXPR);
+ MARK_TS_TYPED (PTRMEM_CST);
+ MARK_TS_TYPED (EMPTY_CLASS_EXPR);
+ MARK_TS_TYPED (VEC_INIT_EXPR);
+ MARK_TS_TYPED (USING_STMT);
+ MARK_TS_TYPED (LAMBDA_EXPR);
+ MARK_TS_TYPED (CTOR_INITIALIZER);
+}
#include "gt-cp-cp-objcp-common.h"