and during the instantiation of template functions.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008 Free Software Foundation, Inc.
+ 2008, 2009 Free Software Foundation, Inc.
Written by Mark Mitchell (mmitchell@usa.net) based on code found
formerly in parse.y and pt.c.
In case of parsing error, we simply call `pop_deferring_access_checks'
without `perform_deferred_access_checks'. */
-typedef struct deferred_access GTY(())
-{
+typedef struct GTY(()) deferred_access {
/* A VEC representing name-lookups for which we have deferred
checking access controls. We cannot check the accessibility of
names used in a decl-specifier-seq until we know what is being
tree orig_type = NULL;
if (!processing_template_decl)
{
- tree index;
-
/* Convert the condition to an integer or enumeration type. */
cond = build_expr_type_conversion (WANT_INT | WANT_ENUM, cond, true);
if (cond == NULL_TREE)
cond = perform_integral_promotions (cond);
cond = maybe_cleanup_point_expr (cond);
}
-
- if (cond != error_mark_node)
- {
- index = get_unwidened (cond, NULL_TREE);
- /* We can't strip a conversion from a signed type to an unsigned,
- because if we did, int_fits_type_p would do the wrong thing
- when checking case values for being in range,
- and it's too hard to do the right thing. */
- if (TYPE_UNSIGNED (TREE_TYPE (cond))
- == TYPE_UNSIGNED (TREE_TYPE (index)))
- cond = index;
- }
}
if (check_for_bare_parameter_packs (cond))
cond = error_mark_node;
{
gcc_assert (TREE_CODE (decl) == FIELD_DECL);
+ if (!object && skip_evaluation)
+ {
+ /* DR 613: Can use non-static data members without an associated
+ object in sizeof/decltype/alignof. */
+ tree scope = qualifying_scope;
+ if (scope == NULL_TREE)
+ scope = context_for_name_lookup (decl);
+ object = maybe_dummy_object (scope, NULL);
+ }
+
if (!object)
{
if (current_function_decl
return error_mark_node;
}
- TREE_USED (current_class_ptr) = 1;
+ if (current_class_ptr)
+ TREE_USED (current_class_ptr) = 1;
if (processing_template_decl && !qualifying_scope)
{
tree type = TREE_TYPE (decl);
else
{
/* Set the cv qualifiers. */
- int quals = cp_type_quals (TREE_TYPE (current_class_ref));
+ int quals = (current_class_ref
+ ? cp_type_quals (TREE_TYPE (current_class_ref))
+ : TYPE_UNQUALIFIED);
if (DECL_MUTABLE_P (decl))
quals &= ~TYPE_QUAL_CONST;
tree scope;
tree qualifying_type = NULL_TREE;
+ /* If we are parsing a template declaration and if decl is a typedef,
+ add it to a list tied to the template.
+ At template instantiation time, that list will be walked and
+ access check performed. */
+ if (is_typedef_decl (decl))
+ {
+ /* This the scope through which type_decl is accessed.
+ It will be useful information later to do access check for
+ type_decl usage. */
+ tree scope = nested_name_specifier
+ ? nested_name_specifier
+ : DECL_CONTEXT (decl);
+ tree templ_info = NULL;
+ tree cs = current_scope ();
+
+ if (cs && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL))
+ templ_info = get_template_info (cs);
+
+ if (templ_info
+ && TI_TEMPLATE (templ_info)
+ && scope
+ && CLASS_TYPE_P (scope)
+ && !currently_open_class (scope))
+ append_type_to_template_for_access_check (current_scope (), decl, scope);
+ }
+
/* If we're not checking, return immediately. */
if (deferred_access_no_check)
return;
{
tree identifier = NULL_TREE;
tree functions = NULL_TREE;
+ tree tmpl_args = NULL_TREE;
+
+ if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
+ {
+ tmpl_args = TREE_OPERAND (fn, 1);
+ fn = TREE_OPERAND (fn, 0);
+ }
/* Find the name of the overloaded function. */
if (TREE_CODE (fn) == IDENTIFIER_NODE)
Do Koenig lookup -- unless any of the arguments are
type-dependent. */
- if (!any_type_dependent_arguments_p (args))
+ if (!any_type_dependent_arguments_p (args)
+ && !any_dependent_template_arguments_p (tmpl_args))
{
fn = lookup_arg_dependent (identifier, functions, args);
if (!fn)
fn = unqualified_fn_lookup_error (identifier);
}
+ if (fn && tmpl_args)
+ fn = build_nt (TEMPLATE_ID_EXPR, fn, tmpl_args);
+
return fn;
}
if (TREE_CODE (fn) == FUNCTION_DECL
&& (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL
|| DECL_BUILT_IN_CLASS (fn) == BUILT_IN_MD))
- result = resolve_overloaded_builtin (fn, args);
+ {
+ VEC(tree,gc)* vec = VEC_alloc (tree, gc, list_length (args));
+ tree p;
+
+ for (p = args; p != NULL_TREE; p = TREE_CHAIN (p))
+ VEC_quick_push (tree, vec, TREE_VALUE (p));
+ result = resolve_overloaded_builtin (fn, vec);
+ VEC_free (tree, gc, vec);
+ }
if (!result)
/* A call to a namespace-scope function. */
if (processing_template_decl)
{
result = build_call_list (TREE_TYPE (result), orig_fn, orig_args);
- /* Don't repeat arg-dependent lookup at instantiation time if this call
- is not type-dependent. */
- KOENIG_LOOKUP_P (result) = 0;
+ KOENIG_LOOKUP_P (result) = koenig_p;
}
return result;
}
dependent. */
if (scope)
{
- /* Since this name was dependent, the expression isn't
- constant -- yet. No error is issued because it might
- be constant when things are instantiated. */
- if (integral_constant_expression_p)
- *non_integral_constant_expression_p = true;
if (TYPE_P (scope))
{
if (address_p && done)
done, address_p,
template_p,
template_arg_p);
- else if (dependent_type_p (scope))
+ else if (dependent_scope_p (scope))
decl = build_qualified_name (/*type=*/NULL_TREE,
scope,
id_expression,
}
if (TREE_DEPRECATED (decl))
- warn_deprecated_use (decl);
+ warn_deprecated_use (decl, NULL_TREE);
return decl;
}
call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot);
}
+ if (AGGR_INIT_ZERO_FIRST (aggr_init_expr))
+ {
+ tree init = build_zero_init (type, NULL_TREE,
+ /*static_storage_p=*/false);
+ init = build2 (INIT_EXPR, void_type_node, slot, init);
+ call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (call_expr),
+ init, call_expr);
+ }
+
*tp = call_expr;
}
for (pc = &clauses, c = clauses; c ; c = *pc)
{
- enum tree_code c_kind = OMP_CLAUSE_CODE (c);
+ enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
bool remove = false;
bool need_complete_non_reference = false;
bool need_default_ctor = false;
case GE_EXPR:
case LT_EXPR:
case LE_EXPR:
+ if (TREE_OPERAND (cond, 1) == iter)
+ cond = build2 (swap_tree_comparison (TREE_CODE (cond)),
+ TREE_TYPE (cond), iter, TREE_OPERAND (cond, 0));
if (TREE_OPERAND (cond, 0) != iter)
cond = error_mark_node;
else
cond = cp_build_binary_op (elocus,
TREE_CODE (cond), decl, diff,
tf_warning_or_error);
- incr = build_modify_expr (elocus, decl, PLUS_EXPR, incr);
+ incr = build_modify_expr (elocus, decl, NULL_TREE, PLUS_EXPR,
+ incr, NULL_TREE);
orig_body = *body;
*body = push_stmt_list ();
break;
}
}
- else
- type = describable_type (expr);
if (type && !type_uses_auto (type))
return type;
}
}
+/* Returns true if TYPE is a complete type, an array of unknown bound,
+ or (possibly cv-qualified) void, returns false otherwise. */
+
+static bool
+check_trait_type (tree type)
+{
+ if (COMPLETE_TYPE_P (type))
+ return true;
+
+ if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
+ return true;
+
+ if (VOID_TYPE_P (type))
+ return true;
+
+ return false;
+}
+
/* Process a trait expression. */
tree
if (type2)
complete_type (type2);
- /* The only required diagnostic. */
- if (kind == CPTK_IS_BASE_OF
- && NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
- && !same_type_ignoring_top_level_qualifiers_p (type1, type2)
- && !COMPLETE_TYPE_P (type2))
+ switch (kind)
{
- error ("incomplete type %qT not allowed", type2);
- return error_mark_node;
+ case CPTK_HAS_NOTHROW_ASSIGN:
+ case CPTK_HAS_TRIVIAL_ASSIGN:
+ case CPTK_HAS_NOTHROW_CONSTRUCTOR:
+ case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
+ case CPTK_HAS_NOTHROW_COPY:
+ case CPTK_HAS_TRIVIAL_COPY:
+ case CPTK_HAS_TRIVIAL_DESTRUCTOR:
+ case CPTK_HAS_VIRTUAL_DESTRUCTOR:
+ case CPTK_IS_ABSTRACT:
+ case CPTK_IS_EMPTY:
+ case CPTK_IS_POD:
+ case CPTK_IS_POLYMORPHIC:
+ if (!check_trait_type (type1))
+ {
+ error ("incomplete type %qT not allowed", type1);
+ return error_mark_node;
+ }
+ break;
+
+ case CPTK_IS_BASE_OF:
+ if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
+ && !same_type_ignoring_top_level_qualifiers_p (type1, type2)
+ && !COMPLETE_TYPE_P (type2))
+ {
+ error ("incomplete type %qT not allowed", type2);
+ return error_mark_node;
+ }
+ break;
+
+ case CPTK_IS_CLASS:
+ case CPTK_IS_ENUM:
+ case CPTK_IS_UNION:
+ break;
+
+ case CPTK_IS_CONVERTIBLE_TO:
+ default:
+ gcc_unreachable ();
}
return (trait_expr_value (kind, type1, type2)
? boolean_true_node : boolean_false_node);
}
+/* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64,
+ which is ignored for C++. */
+
+void
+set_float_const_decimal64 (void)
+{
+}
+
+void
+clear_float_const_decimal64 (void)
+{
+}
+
+bool
+float_const_decimal64_p (void)
+{
+ return 0;
+}
+
#include "gt-cp-semantics.h"