&& DECL_EXTERN_C_P (olddecl)))
return 0;
+#ifdef NO_IMPLICIT_EXTERN_C
+ /* A new declaration doesn't match a built-in one unless it
+ is also extern "C". */
+ if (DECL_BUILT_IN (olddecl)
+ && DECL_EXTERN_C_P (olddecl) && !DECL_EXTERN_C_P (newdecl))
+ return 0;
+#endif
+
if (TREE_CODE (f1) != TREE_CODE (f2))
return 0;
&& TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != NULL_TREE)
{
/* Prototype decl follows defn w/o prototype. */
- warning (0, "prototype for %q+#D", newdecl);
- warning (0, "%Jfollows non-prototype definition here", olddecl);
+ warning_at (input_location, 0, "prototype for %q+#D", newdecl);
+ warning_at (DECL_SOURCE_LOCATION (olddecl), 0,
+ "follows non-prototype definition here");
}
else if ((TREE_CODE (olddecl) == FUNCTION_DECL
|| TREE_CODE (olddecl) == VAR_DECL)
}
DECL_TEMPLATE_INSTANTIATED (newdecl)
|= DECL_TEMPLATE_INSTANTIATED (olddecl);
+ DECL_ODR_USED (newdecl) |= DECL_ODR_USED (olddecl);
/* If the OLDDECL is an instantiation and/or specialization,
then the NEWDECL must be too. But, it may not yet be marked
should have exited above, returning 0. */
gcc_assert (DECL_TEMPLATE_SPECIALIZATION (newdecl));
- if (TREE_USED (olddecl))
+ if (DECL_ODR_USED (olddecl))
/* From [temp.expl.spec]:
If a template, a member template or the member of a class
&& DECL_VISIBILITY_SPECIFIED (newdecl)
&& DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
{
- warning (OPT_Wattributes, "%q+D: visibility attribute ignored "
- "because it", newdecl);
- warning (OPT_Wattributes, "%Jconflicts with previous "
- "declaration here", olddecl);
+ warning_at (input_location, OPT_Wattributes,
+ "%q+D: visibility attribute ignored because it", newdecl);
+ warning_at (DECL_SOURCE_LOCATION (olddecl), OPT_Wattributes,
+ "conflicts with previous declaration here");
}
/* Choose the declaration which specified visibility. */
if (DECL_VISIBILITY_SPECIFIED (olddecl))
static int
decl_jump_unsafe (tree decl)
{
+ /* [stmt.dcl]/3: A program that jumps from a point where a local variable
+ with automatic storage duration is not in scope to a point where it is
+ in scope is ill-formed unless the variable has scalar type, class type
+ with a trivial default constructor and a trivial destructor, a
+ cv-qualified version of one of these types, or an array of one of the
+ preceding types and is declared without an initializer (8.5). */
+ tree type = TREE_TYPE (decl);
+
if (TREE_CODE (decl) != VAR_DECL || TREE_STATIC (decl)
- || TREE_TYPE (decl) == error_mark_node)
+ || type == error_mark_node)
return 0;
- if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))
+ type = strip_array_types (type);
+
+ if (type_has_nontrivial_default_init (TREE_TYPE (decl))
|| DECL_NONTRIVIALLY_INITIALIZED_P (decl))
return 2;
- if (pod_type_p (TREE_TYPE (decl)))
- return 0;
+ if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
+ return 1;
- /* The POD stuff is just pedantry; why should it matter if the class
- contains a field of pointer to member type? */
- return 1;
+ return 0;
}
/* A subroutine of check_previous_goto_1 to identify a branch to the user. */
else
permerror (input_location, "jump to case label");
if (locus)
- permerror (input_location, "%H from here", locus);
+ permerror (*locus, " from here");
}
/* Check that a single previously seen jump to a newly defined label
if (problem > 1)
error (" crosses initialization of %q+#D", new_decls);
else
- permerror (input_location, " enters scope of non-POD %q+#D", new_decls);
+ permerror (input_location, " enters scope of %q+#D which has "
+ "non-trivial destructor", new_decls);
}
if (b == level)
if (u > 1 && DECL_ARTIFICIAL (b))
{
/* Can't skip init of __exception_info. */
- error ("%J enters catch block", b);
+ error_at (DECL_SOURCE_LOCATION (b), " enters catch block");
saw_catch = true;
}
else if (u > 1)
error (" skips initialization of %q+#D", b);
else
- permerror (input_location, " enters scope of non-POD %q+#D", b);
+ permerror (input_location, " enters scope of %q+#D which has "
+ "non-trivial destructor", b);
}
if (ent->in_try_scope)
retrofit_lang_decl (decl);
- /* All nesting of C++ functions is lexical; there is never a "static
- chain" in the sense of GNU C nested functions. */
- DECL_NO_STATIC_CHAIN (decl) = 1;
-
DECL_ARTIFICIAL (decl) = 1;
SET_OVERLOADED_OPERATOR_CODE (decl, ERROR_MARK);
SET_DECL_LANGUAGE (decl, lang_c);
tree decl = TYPE_MAIN_DECL (t);
if (TREE_CODE (t) != UNION_TYPE)
- error ("%Jan anonymous struct cannot have function members", decl);
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "an anonymous struct cannot have function members");
else
- error ("%Jan anonymous union cannot have function members", decl);
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "an anonymous union cannot have function members");
}
/* Anonymous aggregates cannot have fields with ctors, dtors or complex
"and functions");
else if (saw_typedef)
warning (0, "%<typedef%> was ignored in this declaration");
+ else if (declspecs->specs[(int) ds_constexpr])
+ error ("%<constexpr> cannot be used for type declarations");
}
return declared_type;
error ("duplicate initialization of %qD", decl);
if (duplicate_decls (decl, field, /*newdecl_is_friend=*/false))
decl = field;
+ if (declspecs->specs[(int) ds_constexpr]
+ && !DECL_DECLARED_CONSTEXPR_P (field))
+ error ("%qD declared %<constexpr%> outside its class", field);
}
}
else
if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl))
permerror (input_location, "declaration of %q#D outside of class is not definition",
decl);
+
+ if (!ensure_literal_type_for_constexpr_object (decl))
+ return error_mark_node;
}
was_public = TREE_PUBLIC (decl);
return NULL_TREE;
}
- if (TREE_CODE (init) == CONSTRUCTOR)
- {
- error ("ISO C++ forbids use of initializer list to "
- "initialize reference %qD", decl);
- return NULL_TREE;
- }
-
if (TREE_CODE (init) == TREE_LIST)
init = build_x_compound_expr_from_list (init, "initializer");
{
tree aggr_init, array, arrtype;
init = perform_implicit_conversion (type, init, tf_warning_or_error);
+ if (error_operand_p (init))
+ return error_mark_node;
+
aggr_init = TARGET_EXPR_INITIAL (init);
init = build2 (INIT_EXPR, type, decl, init);
/* Don't mess with __FUNCTION__. */
&& ! DECL_ARTIFICIAL (decl)
&& DECL_FUNCTION_SCOPE_P (decl)
- /* Unfortunately, import_export_decl has not always been called
- before the function is processed, so we cannot simply check
- DECL_COMDAT. */
- && (DECL_COMDAT (DECL_CONTEXT (decl))
- || ((DECL_DECLARED_INLINE_P (DECL_CONTEXT (decl))
- || DECL_TEMPLATE_INSTANTIATION (DECL_CONTEXT (decl)))
- && TREE_PUBLIC (DECL_CONTEXT (decl)))))
+ && vague_linkage_fn_p (DECL_CONTEXT (decl)))
{
if (flag_weak)
{
be merged. */
TREE_PUBLIC (decl) = 0;
DECL_COMMON (decl) = 0;
- warning (0, "sorry: semantics of inline function static "
- "data %q+#D are wrong (you'll wind up "
- "with multiple copies)", decl);
- warning (0, "%J you can work around this by removing "
- "the initializer",
- decl);
+ warning_at (input_location, 0,
+ "sorry: semantics of inline function static "
+ "data %q+#D are wrong (you'll wind up "
+ "with multiple copies)", decl);
+ warning_at (DECL_SOURCE_LOCATION (decl), 0,
+ " you can work around this by removing "
+ "the initializer");
}
}
}
{
tree type = TREE_TYPE (decl);
+ if (TREE_CODE (decl) == VAR_DECL && DECL_DECLARED_CONSTEXPR_P (decl)
+ && DECL_INITIAL (decl) == NULL)
+ error ("missing initializer for constexpr %qD", decl);
+
/* ``Unless explicitly declared extern, a const object does not have
external linkage and must be initialized. ($8.4; $12.1)'' ARM
7.1.6 */
- if (TREE_CODE (decl) == VAR_DECL
+ else if (TREE_CODE (decl) == VAR_DECL
&& TREE_CODE (type) != REFERENCE_TYPE
&& CP_TYPE_CONST_P (type)
&& !TYPE_NEEDS_CONSTRUCTING (type)
a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the
iterator within the CONSTRUCTOR which points to the initializer to process.
FIRST_INITIALIZER_P is true if this is the first initializer of the
- CONSTRUCTOR node. */
+ outermost CONSTRUCTOR node. */
static tree
reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
initializer is considered for the initialization of the first
member of the subaggregate. */
if (TREE_CODE (init) != CONSTRUCTOR
- && can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL))
+ /* But don't try this for the first initializer, since that would be
+ looking through the outermost braces; A a2 = { a1 }; is not a
+ valid aggregate initialization. */
+ && !first_initializer_p
+ && (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init))
+ || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL)))
{
d->cur++;
return init;
if (init && TREE_CODE (decl) == FUNCTION_DECL)
{
+ tree clone;
if (init == ridpointers[(int)RID_DELETE])
{
/* FIXME check this is 1st decl. */
DECL_DELETED_FN (decl) = 1;
DECL_DECLARED_INLINE_P (decl) = 1;
DECL_INITIAL (decl) = error_mark_node;
+ FOR_EACH_CLONE (clone, decl)
+ {
+ DECL_DELETED_FN (clone) = 1;
+ DECL_DECLARED_INLINE_P (clone) = 1;
+ DECL_INITIAL (clone) = error_mark_node;
+ }
init = NULL_TREE;
}
else if (init == ridpointers[(int)RID_DEFAULT])
DECL_INITIAL (decl) = NULL_TREE;
}
else
- DECL_DEFAULTED_FN (decl) = 1;
+ {
+ DECL_DEFAULTED_FN (decl) = 1;
+ FOR_EACH_CLONE (clone, decl)
+ DECL_DEFAULTED_FN (clone) = 1;
+ }
}
}
if (TREE_CODE (decl) == VAR_DECL)
{
- /* Only PODs can have thread-local storage. Other types may require
- various kinds of non-trivial initialization. */
- if (DECL_THREAD_LOCAL_P (decl) && !pod_type_p (TREE_TYPE (decl)))
- error ("%qD cannot be thread-local because it has non-POD type %qT",
- decl, TREE_TYPE (decl));
+ /* Only variables with trivial initialization and destruction can
+ have thread-local storage. */
+ if (DECL_THREAD_LOCAL_P (decl)
+ && (type_has_nontrivial_default_init (TREE_TYPE (decl))
+ || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
+ error ("%qD cannot be thread-local because it has non-trivial "
+ "type %qT", decl, TREE_TYPE (decl));
/* If this is a local variable that will need a mangled name,
register it now. We must do this before processing the
initializer for the variable, since the initialization might
type. */
else if (TREE_CODE (type) == ARRAY_TYPE)
layout_type (type);
+
+ if (!processing_template_decl
+ && TREE_STATIC (decl)
+ && !at_function_scope_p ()
+ && current_function_decl == NULL)
+ /* So decl is a global variable or a static member of a
+ non local class. Record the types it uses
+ so that we can decide later to emit debug info for them. */
+ record_types_used_by_current_var_decl (decl);
}
else if (TREE_CODE (decl) == FIELD_DECL
&& TYPE_FOR_JAVA (type) && MAYBE_CLASS_TYPE_P (type))
{
case sfk_constructor:
case sfk_copy_constructor:
+ case sfk_move_constructor:
DECL_CONSTRUCTOR_P (decl) = 1;
break;
case sfk_destructor:
|| decl_function_context (TYPE_MAIN_DECL (ctype))))
publicp = 0;
- if (publicp)
- {
- /* [basic.link]: A name with no linkage (notably, the name of a class
- or enumeration declared in a local scope) shall not be used to
- declare an entity with linkage.
-
- Only check this for public decls for now. See core 319, 389. */
- t = no_linkage_check (TREE_TYPE (decl),
- /*relaxed_p=*/false);
- if (t)
- {
- if (TYPE_ANONYMOUS_P (t))
- {
- if (DECL_EXTERN_C_P (decl))
- /* Allow this; it's pretty common in C. */;
- else
- {
- permerror (input_location, "non-local function %q#D uses anonymous type",
- decl);
- if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
- permerror (input_location, "%q+#D does not refer to the unqualified "
- "type, so it is not used for linkage",
- TYPE_NAME (t));
- }
- }
- else
- permerror (input_location, "non-local function %q#D uses local type %qT", decl, t);
- }
- }
-
TREE_PUBLIC (decl) = publicp;
if (! publicp)
{
&& !grok_op_properties (decl, /*complain=*/true))
return NULL_TREE;
- if (ctype && decl_function_context (decl))
- DECL_NO_STATIC_CHAIN (decl) = 1;
-
if (funcdef_flag)
/* Make the init_value nonzero so pushdecl knows this is not
tentative. error_mark_node is replaced later with the BLOCK. */
if (TREE_PUBLIC (decl))
{
- /* [basic.link]: A name with no linkage (notably, the name of a class
- or enumeration declared in a local scope) shall not be used to
- declare an entity with linkage.
-
- Only check this for public decls for now. */
- tree t = no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false);
- if (t)
- {
- if (TYPE_ANONYMOUS_P (t))
- {
- if (DECL_EXTERN_C_P (decl))
- /* Allow this; it's pretty common in C. */
- ;
- else
- {
- /* DRs 132, 319 and 389 seem to indicate types with
- no linkage can only be used to declare extern "C"
- entities. Since it's not always an error in the
- ISO C++ 90 Standard, we only issue a warning. */
- warning (0, "non-local variable %q#D uses anonymous type",
- decl);
- if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
- warning (0, "%q+#D does not refer to the unqualified "
- "type, so it is not used for linkage",
- TYPE_NAME (t));
- }
- }
- else
- warning (0, "non-local variable %q#D uses local type %qT", decl, t);
- }
+ /* If the type of the decl has no linkage, make sure that we'll
+ notice that in mark_used. */
+ if (DECL_LANG_SPECIFIC (decl) == NULL
+ && TREE_PUBLIC (decl)
+ && !DECL_EXTERN_C_P (decl)
+ && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false))
+ retrofit_lang_decl (decl);
}
else
DECL_INTERFACE_KNOWN (decl) = 1;
/* If this is not the unqualified form of this pointer-to-member
type, set the TYPE_MAIN_VARIANT for this type to be the
unqualified type. Since they are actually RECORD_TYPEs that are
- not variants of each other, we must do this manually. */
+ not variants of each other, we must do this manually.
+ As we just built a new type there is no need to do yet another copy. */
if (cp_type_quals (type) != TYPE_UNQUALIFIED)
{
- t = build_qualified_type (t, cp_type_quals (type));
+ int type_quals = cp_type_quals (type);
+ TYPE_READONLY (t) = (type_quals & TYPE_QUAL_CONST) != 0;
+ TYPE_VOLATILE (t) = (type_quals & TYPE_QUAL_VOLATILE) != 0;
+ TYPE_RESTRICT (t) = (type_quals & TYPE_QUAL_RESTRICT) != 0;
TYPE_MAIN_VARIANT (t) = unqualified_variant;
TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (unqualified_variant);
TYPE_NEXT_VARIANT (unqualified_variant) = t;
bool unsigned_p, signed_p, short_p, long_p, thread_p;
bool type_was_error_mark_node = false;
bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
- bool set_no_warning = false;
bool template_type_arg = false;
+ bool constexpr_p = declspecs->specs[(int) ds_constexpr];
const char *errmsg;
signed_p = declspecs->specs[(int)ds_signed];
type_quals = TYPE_UNQUALIFIED;
if (declspecs->specs[(int)ds_const])
type_quals |= TYPE_QUAL_CONST;
+ /* A `constexpr' specifier used in an object declaration declares
+ the object as `const'. */
+ if (constexpr_p)
+ {
+ if (innermost_code == cdk_function)
+ ;
+ else if (declspecs->specs[(int)ds_const] != 0)
+ error ("both %<const%> and %<constexpr%> cannot be used here");
+ else
+ type_quals |= TYPE_QUAL_CONST;
+ }
if (declspecs->specs[(int)ds_volatile])
type_quals |= TYPE_QUAL_VOLATILE;
if (declspecs->specs[(int)ds_restrict])
error ("parameter declared %<auto%>");
type = error_mark_node;
}
+
+ /* Function parameters cannot be constexpr. If we saw one, moan
+ and pretend it wasn't there. */
+ if (constexpr_p)
+ {
+ error ("a parameter cannot be declared %<constexpr%>");
+ constexpr_p = 0;
+ }
}
/* Give error if `virtual' is used outside of class declaration. */
/* We now know that the TYPE_QUALS don't apply to the
decl, but to its return type. */
type_quals = TYPE_UNQUALIFIED;
- set_no_warning = true;
}
errmsg = targetm.invalid_return_type (type);
if (errmsg)
}
}
+ /* It is not allowed to use `constexpr' in a function
+ declaration that is not a definition.
+ That is too strict, though. */
+ if (constexpr_p && !funcdef_flag)
+ {
+ error ("the %<constexpr%> specifier cannot be used in "
+ "a function declaration that is not a definition");
+ constexpr_p = false;
+ }
+
+ /* A constexpr non-static member function is implicitly const. */
+ if (constexpr_p && decl_context == FIELD && staticp == 0
+ && sfk != sfk_constructor && sfk != sfk_destructor)
+ memfn_quals |= TYPE_QUAL_CONST;
+
arg_types = grokparms (declarator->u.function.parameters,
&parms);
return error_mark_node;
}
+ /* It is not permitted to define a member function outside ist
+ membership class as `constexpr'. */
+ if (constexpr_p)
+ error ("a constexpr function cannot be defined "
+ "outside of its class.");
+
if (TREE_CODE (sname) == IDENTIFIER_NODE
&& NEW_DELETE_OPNAME_P (sname))
/* Overloaded operator new and operator delete
else
decl = build_decl (input_location, TYPE_DECL, unqualified_id, type);
if (id_declarator && declarator->u.id.qualifying_scope) {
- error ("%Jtypedef name may not be a nested-name-specifier", decl);
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "typedef name may not be a nested-name-specifier");
TREE_TYPE (decl) = error_mark_node;
}
DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
= TYPE_IDENTIFIER (type);
+ /* Adjust linkage now that we aren't anonymous anymore. */
+ set_linkage_according_to_type (type, TYPE_MAIN_DECL (type));
+ determine_visibility (TYPE_MAIN_DECL (type));
+
/* FIXME remangle member functions; member functions of a
type with external linkage have external linkage. */
}
uqname, ctype);
return error_mark_node;
}
+ if (constexpr_p)
+ error ("a destructor cannot be %<constexpr%>");
}
else if (sfk == sfk_constructor && friendp)
{
parms,
unqualified_id,
virtualp, flags, memfn_quals, raises,
- friendp ? -1 : 0, friendp, publicp, inlinep,
+ friendp ? -1 : 0, friendp, publicp,
+ inlinep || constexpr_p,
sfk,
funcdef_flag, template_count, in_namespace,
attrlist, declarator->id_loc);
decl = do_friend (ctype, unqualified_id, decl,
*attrlist, flags,
funcdef_flag);
+ DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p;
return decl;
}
else
}
else
{
+ if (constexpr_p)
+ error ("non-static data member %qE declared %<constexpr%>",
+ unqualified_id);
decl = build_decl (input_location,
FIELD_DECL, unqualified_id, type);
DECL_NONADDRESSABLE_P (decl) = bitfield;
decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
virtualp, flags, memfn_quals, raises,
1, friendp,
- publicp, inlinep, sfk, funcdef_flag,
+ publicp, inlinep || constexpr_p, sfk, funcdef_flag,
template_count, in_namespace, attrlist,
declarator->id_loc);
if (decl == NULL_TREE)
else if (storage_class == sc_static)
DECL_THIS_STATIC (decl) = 1;
+ /* Don't forget constexprness. */
+ if (VAR_OR_FUNCTION_DECL_P (decl))
+ DECL_DECLARED_CONSTEXPR_P (decl) = constexpr_p;
+
/* Record constancy and volatility on the DECL itself . There's
no need to do this when processing a template; we'll do this
for the instantiated declaration based on the type of DECL. */
if (!processing_template_decl)
cp_apply_type_quals_to_decl (type_quals, decl);
- if (set_no_warning)
- TREE_NO_WARNING (decl) = 1;
-
return decl;
}
}
/* Remember any special properties of member function DECL. */
+#define DECL_DEFAULTED_IN_CLASS_P(DECL) \
+ (DECL_DEFAULTED_FN (DECL) \
+ && (DECL_ARTIFICIAL (DECL) || DECL_INITIALIZED_IN_CLASS_P (DECL)))
+
void
grok_special_member_properties (tree decl)
{
are no other parameters or else all other parameters have
default arguments. */
TYPE_HAS_INIT_REF (class_type) = 1;
- if (!DECL_DEFAULTED_FN (decl))
+ if (!DECL_DEFAULTED_IN_CLASS_P (decl))
TYPE_HAS_COMPLEX_INIT_REF (class_type) = 1;
if (ctor > 1)
TYPE_HAS_CONST_INIT_REF (class_type) = 1;
else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl)))
{
TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
- if (TREE_CODE (decl) == TEMPLATE_DECL || !DECL_DEFAULTED_FN (decl))
+ if (TREE_CODE (decl) == TEMPLATE_DECL
+ || !DECL_DEFAULTED_IN_CLASS_P (decl))
TYPE_HAS_COMPLEX_DFLT (class_type) = 1;
}
else if (is_list_ctor (decl))
if (assop)
{
TYPE_HAS_ASSIGN_REF (class_type) = 1;
- if (!DECL_DEFAULTED_FN (decl))
+ if (!DECL_DEFAULTED_IN_CLASS_P (decl))
TYPE_HAS_COMPLEX_ASSIGN_REF (class_type) = 1;
if (assop != 1)
TYPE_HAS_CONST_ASSIGN_REF (class_type) = 1;
if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE)
{
- error ("multiple definition of %q#T", enumtype);
- error ("%Jprevious definition here", TYPE_MAIN_DECL (enumtype));
+ error_at (input_location, "multiple definition of %q#T", enumtype);
+ error_at (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
+ "previous definition here");
/* Clear out TYPE_VALUES, and start again. */
TYPE_VALUES (enumtype) = NULL_TREE;
}
if (enumtype == error_mark_node)
name = make_anon_name ();
- enumtype = make_node (ENUMERAL_TYPE);
+ enumtype = cxx_make_type (ENUMERAL_TYPE);
enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);
}
TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (underlying_type);
ENUM_UNDERLYING_TYPE (enumtype) = underlying_type;
}
- else
+ else if (!dependent_type_p (underlying_type))
error ("underlying type %<%T%> of %<%T%> must be an integral type",
underlying_type, enumtype);
}
TREE_TYPE (TREE_VALUE (values)) = enumtype;
if (at_function_scope_p ())
add_stmt (build_min (TAG_DEFN, enumtype));
+ if (SCOPED_ENUM_P (enumtype))
+ finish_scope ();
return;
}
/* Set the underlying type of the enumeration type to the
computed enumeration type, restricted to the enumerator
values. */
- ENUM_UNDERLYING_TYPE (enumtype) = copy_node (underlying_type);
+ ENUM_UNDERLYING_TYPE (enumtype)
+ = build_distinct_type_copy (underlying_type);
set_min_and_max_values_for_integral_type
(ENUM_UNDERLYING_TYPE (enumtype), precision, unsignedp);
}
TREE_READONLY (decl) = 1;
DECL_INITIAL (decl) = value;
- if (context && context == current_class_type)
+ if (context && context == current_class_type && !SCOPED_ENUM_P (enumtype))
/* In something like `struct S { enum E { i = 7 }; };' we put `i'
on the TYPE_FIELDS list for `S'. (That's so that you can say
things like `S::i' later.) */
/* In a function definition, arg types must be complete. */
require_complete_types_for_parms (current_function_parms);
+ /* constexpr functions must have literal argument types and
+ literal return type. */
+ validate_constexpr_fundecl (decl);
+
if (dependent_type_p (return_type))
return;
if (!COMPLETE_OR_VOID_TYPE_P (return_type)
f->x_return_value = NULL;
f->bindings = NULL;
f->extern_decl_map = NULL;
-
- /* Handle attribute((warn_unused_result)). Relies on gimple input. */
- c_warn_unused_result (gimple_body (fndecl));
}
/* Clear out the bits we don't need. */
local_names = NULL;
CHANGES TO CODE IN `grokfield'. */
tree
-start_method (cp_decl_specifier_seq *declspecs,
- const cp_declarator *declarator, tree attrlist)
+grokmethod (cp_decl_specifier_seq *declspecs,
+ const cp_declarator *declarator, tree attrlist)
{
tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
&attrlist);
cp_finish_decl (fndecl, NULL_TREE, false, NULL_TREE, 0);
- /* Make a place for the parms. */
- begin_scope (sk_function_parms, fndecl);
-
DECL_IN_AGGR_P (fndecl) = 1;
return fndecl;
}
-
-/* Go through the motions of finishing a function definition.
- We don't compile this method until after the whole class has
- been processed.
-
- FINISH_METHOD must return something that looks as though it
- came from GROKFIELD (since we are defining a method, after all).
-
- This is called after parsing the body of the function definition.
- STMTS is the chain of statements that makes up the function body.
-
- DECL is the ..._DECL that `start_method' provided. */
-
-tree
-finish_method (tree decl)
-{
- tree fndecl = decl;
- tree old_initial;
-
- tree link;
-
- if (decl == void_type_node)
- return decl;
-
- old_initial = DECL_INITIAL (fndecl);
-
- /* Undo the level for the parms (from start_method).
- This is like poplevel, but it causes nothing to be
- saved. Saving information here confuses symbol-table
- output routines. Besides, this information will
- be correctly output when this method is actually
- compiled. */
-
- /* Clear out the meanings of the local variables of this level;
- also record in each decl which block it belongs to. */
-
- for (link = current_binding_level->names; link; link = TREE_CHAIN (link))
- {
- if (DECL_NAME (link) != NULL_TREE)
- pop_binding (DECL_NAME (link), link);
- gcc_assert (TREE_CODE (link) != FUNCTION_DECL);
- DECL_CONTEXT (link) = NULL_TREE;
- }
-
- poplevel (0, 0, 0);
-
- DECL_INITIAL (fndecl) = old_initial;
-
- return decl;
-}
\f
/* VAR is a VAR_DECL. If its type is incomplete, remember VAR so that
case STATIC_ASSERT: return TS_CP_STATIC_ASSERT;
case ARGUMENT_PACK_SELECT: return TS_CP_ARGUMENT_PACK_SELECT;
case TRAIT_EXPR: return TS_CP_TRAIT_EXPR;
+ case LAMBDA_EXPR: return TS_CP_LAMBDA_EXPR;
default: return TS_CP_GENERIC;
}
}