Hi,
as I mentioned a few days ago, since this function grew rather big, I
hope to clean it up a bit. For now at least nothing ground shaking: I
moved together some declarations and initializations; in other cases
exploited the opportunity C++ gives to defer declarations; consistently
changed some int flags to bool (and avoiding names ending by *p for non
bools); plus rather obvious stylistic tweaks (like wrapping way overlong
lines). I'm also improving a bit the diagnostics - see the new testcases
- telling apart <inline> and <constexpr> in two error messages. It's a
start. How does it look to you?
Tested x86_64-linux.
Thanks,
Paolo.
/////////////////////////////
/cp
2013-03-20 Paolo Carlini <paolo.carl...@oracle.com>
* decl.c (grokdeclarator): Tidy.
(bad_specifiers): Likewise.
(grokfndecl): Likewise; improve error messages.
/testsuite
2013-03-20 Paolo Carlini <paolo.carl...@oracle.com>
* g++.dg/cpp0x/constexpr-friend-2.C: New.
* g++.dg/cpp0x/constexpr-main.C: Likewise.
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 196797)
+++ cp/decl.c (working copy)
@@ -77,8 +77,8 @@ static void record_unknown_type (tree, const char
static tree builtin_function_1 (tree, tree, bool);
static tree build_library_fn_1 (tree, enum tree_code, tree);
static int member_function_or_else (tree, tree, enum overload_flags);
-static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int,
- int);
+static void bad_specifiers (tree, enum bad_spec_place, bool, bool, bool,
+ bool, bool);
static void check_for_uninitialized_const_var (tree);
static hashval_t typename_hash (const void *);
static int typename_compare (const void *, const void *);
@@ -7154,11 +7154,11 @@ member_function_or_else (tree ctype, tree cur_type
static void
bad_specifiers (tree object,
enum bad_spec_place type,
- int virtualp,
- int quals,
- int inlinep,
- int friendp,
- int raises)
+ bool virtualp,
+ bool quals,
+ bool inlinep,
+ bool friendp,
+ bool raises)
{
switch (type)
{
@@ -7310,14 +7310,15 @@ grokfndecl (tree ctype,
tree declarator,
tree parms,
tree orig_declarator,
- int virtualp,
+ bool virtualp,
enum overload_flags flags,
cp_cv_quals quals,
tree raises,
int check,
- int friendp,
- int publicp,
- int inlinep,
+ bool friendp,
+ bool publicp,
+ bool inlinep,
+ bool constexprp,
special_function_kind sfk,
bool funcdef_flag,
int template_count,
@@ -7326,7 +7327,7 @@ grokfndecl (tree ctype,
location_t location)
{
tree decl;
- int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
+ bool staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
tree t;
if (raises)
@@ -7427,13 +7428,14 @@ grokfndecl (tree ctype,
return NULL_TREE;
}
- if (inlinep)
- {
- error ("%<inline%> is not allowed in declaration of friend "
- "template specialization %qD",
- decl);
- return NULL_TREE;
- }
+ if (inlinep)
+ error ("%<inline%> is not allowed in declaration of friend "
+ "template specialization %qD", decl);
+ if (constexprp)
+ error ("%<constexpr%> is not allowed in declaration of friend "
+ "template specialization %qD", decl);
+ if (inlinep || constexprp)
+ return NULL_TREE;
}
}
@@ -7474,17 +7476,20 @@ grokfndecl (tree ctype,
error ("cannot declare %<::main%> to be a template");
if (inlinep)
error ("cannot declare %<::main%> to be inline");
+ if (constexprp)
+ error ("cannot declare %<::main%> to be constexpr");
if (!publicp)
error ("cannot declare %<::main%> to be static");
- inlinep = 0;
- publicp = 1;
+ inlinep = false;
+ constexprp = false;
+ publicp = true;
}
/* Members of anonymous types and local classes have no linkage; make
them internal. If a typedef is made later, this will be changed. */
if (ctype && (TYPE_ANONYMOUS_P (ctype)
|| decl_function_context (TYPE_MAIN_DECL (ctype))))
- publicp = 0;
+ publicp = false;
if (publicp && cxx_dialect == cxx98)
{
@@ -7526,9 +7531,9 @@ grokfndecl (tree ctype,
}
/* If the declaration was declared inline, mark it as such. */
- if (inlinep)
+ if (inlinep || constexprp)
DECL_DECLARED_INLINE_P (decl) = 1;
- if (inlinep & 2)
+ if (constexprp)
DECL_DECLARED_CONSTEXPR_P (decl) = true;
DECL_EXTERNAL (decl) = 1;
@@ -7611,7 +7616,7 @@ grokfndecl (tree ctype,
decl = check_explicit_specialization (orig_declarator, decl,
template_count,
2 * funcdef_flag +
- 4 * (friendp != 0));
+ 4 * friendp);
if (decl == error_mark_node)
return NULL_TREE;
@@ -8591,21 +8596,13 @@ grokdeclarator (const cp_declarator *declarator,
int initialized,
tree* attrlist)
{
- tree type = NULL_TREE;
- int longlong = 0;
- int explicit_int128 = 0;
- int virtualp, explicitp, friendp, inlinep, staticp;
- int explicit_int = 0;
- int explicit_char = 0;
- int defaulted_int = 0;
-
tree typedef_decl = NULL_TREE;
const char *name = NULL;
tree typedef_type = NULL_TREE;
/* True if this declarator is a function definition. */
bool funcdef_flag = false;
cp_declarator_kind innermost_code = cdk_error;
- int bitfield = 0;
+ bool bitfield_p = false;
#if 0
/* See the code below that used this. */
tree decl_attr = NULL_TREE;
@@ -8625,8 +8622,6 @@ grokdeclarator (const cp_declarator *declarator,
/* virt-specifiers that apply to the declarator, for a declaration of
a member function. */
cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
- /* cv-qualifiers that apply to the type specified by the DECLSPECS. */
- int type_quals;
tree raises = NULL_TREE;
int template_count = 0;
tree returned_attrs = NULL_TREE;
@@ -8645,30 +8640,30 @@ grokdeclarator (const cp_declarator *declarator,
this value will be NULL_TREE, even if the entity is located at
namespace scope. */
tree in_namespace = NULL_TREE;
- cp_storage_class storage_class;
- bool unsigned_p, signed_p, short_p, long_p, thread_p;
+ bool unsigned_p = decl_spec_seq_has_spec_p (declspecs, ds_unsigned);
+ bool signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed);
+ bool short_p = decl_spec_seq_has_spec_p (declspecs, ds_short);
+ bool long_p = decl_spec_seq_has_spec_p (declspecs, ds_long);
+ bool longlong_p = decl_spec_seq_has_spec_p (declspecs, ds_long_long);
+ bool thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread);
+ bool typedef_p = decl_spec_seq_has_spec_p (declspecs, ds_typedef);
+ bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr);
+ bool explicit_int = declspecs->explicit_int_p;
+ bool explicit_char = declspecs->explicit_char_p;
+ bool explicit_int128 = declspecs->explicit_int128_p;
+ bool defaulted_int = false;
bool type_was_error_mark_node = false;
- bool parameter_pack_p = declarator? declarator->parameter_pack_p : false;
+ bool parameter_pack_p = declarator ? declarator->parameter_pack_p : false;
bool template_type_arg = false;
bool template_parm_flag = false;
- bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr);
source_location saved_loc = input_location;
- const char *errmsg;
- signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed);
- unsigned_p = decl_spec_seq_has_spec_p (declspecs, ds_unsigned);
- short_p = decl_spec_seq_has_spec_p (declspecs, ds_short);
- long_p = decl_spec_seq_has_spec_p (declspecs, ds_long);
- longlong = decl_spec_seq_has_spec_p (declspecs, ds_long_long);
- explicit_int128 = declspecs->explicit_int128_p;
- thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread);
-
if (decl_context == FUNCDEF)
funcdef_flag = true, decl_context = NORMAL;
else if (decl_context == MEMFUNCDEF)
funcdef_flag = true, decl_context = FIELD;
else if (decl_context == BITFIELD)
- bitfield = 1, decl_context = FIELD;
+ bitfield_p = true, decl_context = FIELD;
else if (decl_context == TEMPLATE_TYPE_ARG)
template_type_arg = true, decl_context = TYPENAME;
else if (decl_context == TPARM)
@@ -8751,8 +8746,6 @@ grokdeclarator (const cp_declarator *declarator,
{
case BIT_NOT_EXPR:
{
- tree type;
-
if (innermost_code != cdk_function)
{
error ("declaration of %qD as non-function", decl);
@@ -8765,7 +8758,7 @@ grokdeclarator (const cp_declarator *declarator,
return error_mark_node;
}
- type = TREE_OPERAND (decl, 0);
+ tree type = TREE_OPERAND (decl, 0);
if (TYPE_P (type))
type = constructor_name (type);
name = identifier_to_locale (IDENTIFIER_POINTER (type));
@@ -8862,7 +8855,7 @@ grokdeclarator (const cp_declarator *declarator,
if (dname && IDENTIFIER_OPNAME_P (dname))
{
- if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+ if (typedef_p)
{
error ("declaration of %qD as %<typedef%>", dname);
return error_mark_node;
@@ -8874,6 +8867,12 @@ grokdeclarator (const cp_declarator *declarator,
}
}
+ if (constexpr_p && typedef_p)
+ {
+ error ("%<constexpr%> cannot appear in a typedef declaration");
+ return error_mark_node;
+ }
+
/* Anything declared one level down from the top level
must be one of the parameters of a function
(because the body is at least two levels down). */
@@ -8900,12 +8899,6 @@ grokdeclarator (const cp_declarator *declarator,
if (name == NULL)
name = decl_context == PARM ? "parameter" : "type name";
- if (constexpr_p && decl_spec_seq_has_spec_p (declspecs, ds_typedef))
- {
- error ("%<constexpr%> cannot appear in a typedef declaration");
- return error_mark_node;
- }
-
/* If there were multiple types specified in the decl-specifier-seq,
issue an error message. */
if (declspecs->multiple_types_p)
@@ -8921,7 +8914,7 @@ grokdeclarator (const cp_declarator *declarator,
}
/* Extract the basic type from the decl-specifier-seq. */
- type = declspecs->type;
+ tree type = declspecs->type;
if (type == error_mark_node)
{
type = NULL_TREE;
@@ -8947,11 +8940,8 @@ grokdeclarator (const cp_declarator *declarator,
{
/* These imply 'int'. */
type = integer_type_node;
- defaulted_int = 1;
+ defaulted_int = true;
}
- /* Gather flags. */
- explicit_int = declspecs->explicit_int_p;
- explicit_char = declspecs->explicit_char_p;
#if 0
/* See the code below that used this. */
@@ -8969,26 +8959,25 @@ grokdeclarator (const cp_declarator *declarator,
ctor_return_type);
else if (type == NULL_TREE)
{
- int is_main;
-
- explicit_int = -1;
-
/* We handle `main' specially here, because 'main () { }' is so
common. With no options, it is allowed. With -Wreturn-type,
it is a warning. It is only an error with -pedantic-errors. */
- is_main = (funcdef_flag
- && dname && TREE_CODE (dname) == IDENTIFIER_NODE
- && MAIN_NAME_P (dname)
- && ctype == NULL_TREE
- && in_namespace == NULL_TREE
- && current_namespace == global_namespace);
+ bool is_main = (funcdef_flag
+ && dname && TREE_CODE (dname) == IDENTIFIER_NODE
+ && MAIN_NAME_P (dname)
+ && ctype == NULL_TREE
+ && in_namespace == NULL_TREE
+ && current_namespace == global_namespace);
+ explicit_int = true;
+
if (type_was_error_mark_node)
/* We've already issued an error, don't complain more. */;
else if (in_system_header || flag_ms_extensions)
/* Allow it, sigh. */;
else if (! is_main)
- permerror (input_location, "ISO C++ forbids declaration of %qs with no
type", name);
+ permerror (input_location,
+ "ISO C++ forbids declaration of %qs with no type", name);
else if (pedantic)
pedwarn (input_location, OPT_Wpedantic,
"ISO C++ forbids declaration of %qs with no type", name);
@@ -9017,7 +9006,7 @@ grokdeclarator (const cp_declarator *declarator,
and check for invalid combinations. */
/* Long double is a special combination. */
- if (long_p && !longlong && TYPE_MAIN_VARIANT (type) == double_type_node)
+ if (long_p && !longlong_p && TYPE_MAIN_VARIANT (type) == double_type_node)
{
long_p = false;
type = cp_build_qualified_type (long_double_type_node,
@@ -9028,13 +9017,13 @@ grokdeclarator (const cp_declarator *declarator,
if (unsigned_p || signed_p || long_p || short_p)
{
- int ok = 0;
+ bool ok = false;
if ((signed_p || unsigned_p) && TREE_CODE (type) != INTEGER_TYPE)
error ("%<signed%> or %<unsigned%> invalid for %qs", name);
else if (signed_p && unsigned_p)
error ("%<signed%> and %<unsigned%> specified together for %qs", name);
- else if (longlong && TREE_CODE (type) != INTEGER_TYPE)
+ else if (longlong_p && TREE_CODE (type) != INTEGER_TYPE)
error ("%<long long%> invalid for %qs", name);
else if (long_p && TREE_CODE (type) == REAL_TYPE)
error ("%<long%> invalid for %qs", name);
@@ -9042,8 +9031,10 @@ grokdeclarator (const cp_declarator *declarator,
error ("%<short%> invalid for %qs", name);
else if ((long_p || short_p) && TREE_CODE (type) != INTEGER_TYPE)
error ("%<long%> or %<short%> invalid for %qs", name);
- else if ((long_p || short_p || explicit_char || explicit_int) &&
explicit_int128)
- error ("%<long%>, %<int%>, %<short%>, or %<char%> invalid for %qs",
name);
+ else if ((long_p || short_p || explicit_char || explicit_int)
+ && explicit_int128)
+ error ("%<long%>, %<int%>, %<short%>, or %<char%> invalid for %qs",
+ name);
else if ((long_p || short_p) && explicit_char)
error ("%<long%> or %<short%> specified with char for %qs", name);
else if (long_p && short_p)
@@ -9057,14 +9048,15 @@ grokdeclarator (const cp_declarator *declarator,
}
else
{
- ok = 1;
- if (!explicit_int && !defaulted_int && !explicit_char &&
!explicit_int128 && pedantic)
+ ok = true;
+ if (!explicit_int && !defaulted_int && !explicit_char
+ && !explicit_int128 && pedantic)
{
pedwarn (input_location, OPT_Wpedantic,
"long, short, signed or unsigned used invalidly for %qs",
name);
if (flag_pedantic_errors)
- ok = 0;
+ ok = false;
}
}
@@ -9075,7 +9067,7 @@ grokdeclarator (const cp_declarator *declarator,
signed_p = false;
long_p = false;
short_p = false;
- longlong = 0;
+ longlong_p = false;
}
}
@@ -9090,7 +9082,7 @@ grokdeclarator (const cp_declarator *declarator,
Naturally, we extend this to long long as well. Note that
this does not include wchar_t. */
- || (bitfield && !flag_signed_bitfields
+ || (bitfield_p && !flag_signed_bitfields
&& !signed_p
/* A typedef for plain `int' without `signed' can be
controlled just like plain `int', but a typedef for
@@ -9102,7 +9094,7 @@ grokdeclarator (const cp_declarator *declarator,
{
if (explicit_int128)
type = int128_unsigned_type_node;
- else if (longlong)
+ else if (longlong_p)
type = long_long_unsigned_type_node;
else if (long_p)
type = long_unsigned_type_node;
@@ -9119,7 +9111,7 @@ grokdeclarator (const cp_declarator *declarator,
type = signed_char_type_node;
else if (explicit_int128)
type = int128_integer_type_node;
- else if (longlong)
+ else if (longlong_p)
type = long_long_integer_type_node;
else if (long_p)
type = long_integer_type_node;
@@ -9134,7 +9126,7 @@ grokdeclarator (const cp_declarator *declarator,
"complex double", but if any modifiers at all are specified it is
the complex form of TYPE. E.g, "complex short" is
"complex short int". */
- else if (defaulted_int && ! longlong && ! explicit_int128
+ else if (defaulted_int && ! longlong_p && ! explicit_int128
&& ! (long_p || short_p || signed_p || unsigned_p))
type = complex_double_type_node;
else if (type == integer_type_node)
@@ -9149,7 +9141,8 @@ grokdeclarator (const cp_declarator *declarator,
type = build_complex_type (type);
}
- type_quals = TYPE_UNQUALIFIED;
+ /* cv-qualifiers that apply to the type specified by the DECLSPECS. */
+ int type_quals = TYPE_UNQUALIFIED;
if (decl_spec_seq_has_spec_p (declspecs, ds_const))
type_quals |= TYPE_QUAL_CONST;
if (decl_spec_seq_has_spec_p (declspecs, ds_volatile))
@@ -9178,27 +9171,27 @@ grokdeclarator (const cp_declarator *declarator,
/* We might have ignored or rejected some of the qualifiers. */
type_quals = cp_type_quals (type);
- staticp = 0;
- inlinep = decl_spec_seq_has_spec_p (declspecs, ds_inline);
- virtualp = decl_spec_seq_has_spec_p (declspecs, ds_virtual);
- explicitp = decl_spec_seq_has_spec_p (declspecs, ds_explicit);
+ int staticv = 0;
+ int explicitv = decl_spec_seq_has_spec_p (declspecs, ds_explicit);
+ bool inlinep = decl_spec_seq_has_spec_p (declspecs, ds_inline);
+ bool virtualp = decl_spec_seq_has_spec_p (declspecs, ds_virtual);
+ bool friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend);
- storage_class = declspecs->storage_class;
+ cp_storage_class storage_class = declspecs->storage_class;
if (storage_class == sc_static)
- staticp = 1 + (decl_context == FIELD);
+ staticv = 1 + (decl_context == FIELD);
- if (virtualp && staticp == 2)
+ if (virtualp && staticv == 2)
{
error ("member %qD cannot be declared both virtual and static", dname);
storage_class = sc_none;
- staticp = 0;
+ staticv = 0;
}
- friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend);
/* Issue errors about use of storage classes for parameters. */
if (decl_context == PARM)
{
- if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+ if (typedef_p)
{
error ("typedef declaration invalid in parameter declaration");
return error_mark_node;
@@ -9218,7 +9211,7 @@ grokdeclarator (const cp_declarator *declarator,
if (constexpr_p)
{
error ("a parameter cannot be declared %<constexpr%>");
- constexpr_p = 0;
+ constexpr_p = false;
}
}
@@ -9227,11 +9220,11 @@ grokdeclarator (const cp_declarator *declarator,
&& (current_class_name == NULL_TREE || decl_context != FIELD))
{
error ("%<virtual%> outside class declaration");
- virtualp = 0;
+ virtualp = false;
}
/* Static anonymous unions are dealt with here. */
- if (staticp && decl_context == TYPENAME
+ if (staticv && decl_context == TYPENAME
&& declspecs->type
&& ANON_AGGR_TYPE_P (declspecs->type))
decl_context = FIELD;
@@ -9242,7 +9235,7 @@ grokdeclarator (const cp_declarator *declarator,
&& ((storage_class
&& storage_class != sc_extern
&& storage_class != sc_static)
- || decl_spec_seq_has_spec_p (declspecs, ds_typedef)))
+ || typedef_p))
{
error ("multiple storage classes in declaration of %qs", name);
thread_p = false;
@@ -9256,7 +9249,7 @@ grokdeclarator (const cp_declarator *declarator,
&& (storage_class == sc_register
|| storage_class == sc_auto))
;
- else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+ else if (typedef_p)
;
else if (decl_context == FIELD
/* C++ allows static class elements. */
@@ -9302,14 +9295,14 @@ grokdeclarator (const cp_declarator *declarator,
storage-class-specifier static is implied if it does not appear
explicitly. */
storage_class = declspecs->storage_class = sc_static;
- staticp = 1;
+ staticv = 1;
}
if (storage_class && friendp)
{
error ("storage class specifiers invalid in friend function
declarations");
storage_class = sc_none;
- staticp = 0;
+ staticv = 0;
}
if (!id_declarator)
@@ -9355,9 +9348,8 @@ grokdeclarator (const cp_declarator *declarator,
attrs = declarator->attributes;
if (attrs)
{
- int attr_flags;
+ int attr_flags = 0;
- attr_flags = 0;
if (declarator == NULL || declarator->kind == cdk_id)
attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
if (declarator->kind == cdk_function)
@@ -9390,9 +9382,6 @@ grokdeclarator (const cp_declarator *declarator,
case cdk_function:
{
- tree arg_types;
- int funcdecl_p;
-
/* Declaring a function type.
Make sure we have a valid type for the function to return. */
@@ -9405,7 +9394,7 @@ grokdeclarator (const cp_declarator *declarator,
decl, but to its return type. */
type_quals = TYPE_UNQUALIFIED;
}
- errmsg = targetm.invalid_return_type (type);
+ const char *errmsg = targetm.invalid_return_type (type);
if (errmsg)
{
error (errmsg);
@@ -9442,7 +9431,8 @@ grokdeclarator (const cp_declarator *declarator,
/* Say it's a definition only for the CALL_EXPR
closest to the identifier. */
- funcdecl_p = inner_declarator && inner_declarator->kind == cdk_id;
+ bool funcdecl_p = (inner_declarator
+ && inner_declarator->kind == cdk_id);
/* Handle a late-specified return type. */
if (funcdecl_p)
@@ -9488,7 +9478,7 @@ grokdeclarator (const cp_declarator *declarator,
if (ctype == NULL_TREE
&& decl_context == FIELD
&& funcdecl_p
- && (friendp == 0 || dname == current_class_name))
+ && (! friendp || dname == current_class_name))
ctype = current_class_type;
if (ctype && (sfk == sfk_constructor
@@ -9506,7 +9496,7 @@ grokdeclarator (const cp_declarator *declarator,
ISO C++ 12.1. A constructor may not be declared
const or volatile. A constructor may not be
virtual. A constructor may not be static. */
- if (staticp == 2)
+ if (staticv == 2)
error ((flags == DTOR_FLAG)
? G_("destructor cannot be static member function")
: G_("constructor cannot be static member function"));
@@ -9527,19 +9517,20 @@ grokdeclarator (const cp_declarator *declarator,
if (flags != DTOR_FLAG)
{
/* It's a constructor. */
- if (explicitp == 1)
- explicitp = 2;
+ if (explicitv == 1)
+ explicitv = 2;
if (virtualp)
{
- permerror (input_location, "constructors cannot be
declared virtual");
- virtualp = 0;
+ permerror (input_location,
+ "constructors cannot be declared virtual");
+ virtualp = false;
}
if (decl_context == FIELD
&& sfk != sfk_constructor)
return error_mark_node;
}
if (decl_context == FIELD)
- staticp = 0;
+ staticv = 0;
}
else if (friendp)
{
@@ -9549,7 +9540,7 @@ grokdeclarator (const cp_declarator *declarator,
{
/* Cannot be both friend and virtual. */
error ("virtual functions cannot be friends");
- friendp = 0;
+ friendp = false;
}
if (decl_context == NORMAL)
error ("friend declaration not in class definition");
@@ -9560,15 +9551,15 @@ grokdeclarator (const cp_declarator *declarator,
}
else if (ctype && sfk == sfk_conversion)
{
- if (explicitp == 1)
+ if (explicitv == 1)
{
maybe_warn_cpp0x (CPP0X_EXPLICIT_CONVERSION);
- explicitp = 2;
+ explicitv = 2;
}
}
- arg_types = grokparms (declarator->u.function.parameters,
- &parms);
+ tree arg_types = grokparms (declarator->u.function.parameters,
+ &parms);
if (inner_declarator
&& inner_declarator->kind == cdk_id
@@ -9823,8 +9814,9 @@ grokdeclarator (const cp_declarator *declarator,
{
if (friendp)
{
- permerror (input_location, "member functions are implicitly
friends of their class");
- friendp = 0;
+ permerror (input_location, "member functions are implicitly "
+ "friends of their class");
+ friendp = false;
}
else
permerror (declarator->id_loc,
@@ -9866,8 +9858,7 @@ grokdeclarator (const cp_declarator *declarator,
return error_mark_node;
}
}
- else if (decl_spec_seq_has_spec_p (declspecs, ds_typedef)
- && current_class_type)
+ else if (typedef_p && current_class_type)
{
error ("cannot declare member %<%T::%s%> within %qT",
ctype, name, current_class_type);
@@ -9875,7 +9866,7 @@ grokdeclarator (const cp_declarator *declarator,
}
}
- if (ctype == NULL_TREE && decl_context == FIELD && friendp == 0)
+ if (ctype == NULL_TREE && decl_context == FIELD && !friendp)
ctype = current_class_type;
/* Now TYPE has the actual type. */
@@ -9929,12 +9920,12 @@ grokdeclarator (const cp_declarator *declarator,
type = error_mark_node;
}
- if (explicitp == 1 || (explicitp && friendp))
+ if (explicitv == 1 || (explicitv && friendp))
{
/* [dcl.fct.spec] The explicit specifier shall only be used in
declarations of constructors within a class definition. */
error ("only declarations of constructors can be %<explicit%>");
- explicitp = 0;
+ explicitv = 0;
}
if (storage_class == sc_mutable)
@@ -9944,8 +9935,7 @@ grokdeclarator (const cp_declarator *declarator,
error ("non-member %qs cannot be declared %<mutable%>", name);
storage_class = sc_none;
}
- else if (decl_context == TYPENAME
- || decl_spec_seq_has_spec_p (declspecs, ds_typedef))
+ else if (decl_context == TYPENAME || typedef_p)
{
error ("non-object member %qs cannot be declared %<mutable%>", name);
storage_class = sc_none;
@@ -9956,7 +9946,7 @@ grokdeclarator (const cp_declarator *declarator,
error ("function %qs cannot be declared %<mutable%>", name);
storage_class = sc_none;
}
- else if (staticp)
+ else if (staticv)
{
error ("static %qs cannot be declared %<mutable%>", name);
storage_class = sc_none;
@@ -9975,7 +9965,7 @@ grokdeclarator (const cp_declarator *declarator,
}
/* If this is declaring a typedef name, return a TYPE_DECL. */
- if (decl_spec_seq_has_spec_p (declspecs, ds_typedef) && decl_context !=
TYPENAME)
+ if (typedef_p && decl_context != TYPENAME)
{
tree decl;
@@ -10032,9 +10022,8 @@ grokdeclarator (const cp_declarator *declarator,
}
else if (current_class_type
&& constructor_name_p (unqualified_id, current_class_type))
- permerror (input_location, "ISO C++ forbids nested type %qD with same
name "
- "as enclosing class",
- unqualified_id);
+ permerror (input_location, "ISO C++ forbids nested type %qD with "
+ "same name as enclosing class", unqualified_id);
/* If the user declares "typedef struct {...} foo" then the
struct will have an anonymous name. Fill that name in now.
@@ -10048,10 +10037,8 @@ grokdeclarator (const cp_declarator *declarator,
&& declspecs->type_definition_p
&& cp_type_quals (type) == TYPE_UNQUALIFIED)
{
- tree t;
-
/* Replace the anonymous name with the real name everywhere. */
- for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
{
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
/* We do not rename the debug info representing the
@@ -10111,9 +10098,8 @@ grokdeclarator (const cp_declarator *declarator,
if (type == typedef_type && TREE_CODE (type) == FUNCTION_TYPE)
{
tree decls = NULL_TREE;
- tree args;
- for (args = TYPE_ARG_TYPES (type);
+ for (tree args = TYPE_ARG_TYPES (type);
args && args != void_list_node;
args = TREE_CHAIN (args))
{
@@ -10130,9 +10116,9 @@ grokdeclarator (const cp_declarator *declarator,
/* A cv-qualifier-seq shall only be part of the function type
for a non-static member function. [8.3.5/4 dcl.fct] */
if (type_memfn_quals (type) != TYPE_UNQUALIFIED
- && (current_class_type == NULL_TREE || staticp) )
+ && (current_class_type == NULL_TREE || staticv) )
{
- error (staticp
+ error (staticv
? G_("qualified function types cannot be used to "
"declare static member functions")
: G_("qualified function types cannot be used to "
@@ -10168,22 +10154,22 @@ grokdeclarator (const cp_declarator *declarator,
if (inlinep)
{
error ("%<inline%> specified for friend class declaration");
- inlinep = 0;
+ inlinep = false;
}
if (!current_aggr)
{
/* Don't allow friend declaration without a class-key. */
if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
- permerror (input_location, "template parameters cannot be
friends");
+ permerror (input_location,
+ "template parameters cannot be friends");
else if (TREE_CODE (type) == TYPENAME_TYPE)
- permerror (input_location, "friend declaration requires
class-key, "
- "i.e. %<friend class %T::%D%>",
+ permerror (input_location, "friend declaration requires "
+ "class-key, i.e. %<friend class %T::%D%>",
TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type));
else
- permerror (input_location, "friend declaration requires
class-key, "
- "i.e. %<friend %#T%>",
- type);
+ permerror (input_location, "friend declaration requires "
+ "class-key, i.e. %<friend %#T%>", type);
}
/* Only try to do this stuff if we didn't already give up. */
@@ -10220,7 +10206,7 @@ grokdeclarator (const cp_declarator *declarator,
else if (unqualified_id == NULL_TREE && decl_context != PARM
&& decl_context != CATCHPARM
&& TREE_CODE (type) != UNION_TYPE
- && ! bitfield)
+ && ! bitfield_p)
{
error ("abstract declarator %qT used as declaration", type);
return error_mark_node;
@@ -10273,7 +10259,7 @@ grokdeclarator (const cp_declarator *declarator,
type = build_pointer_type (type);
}
- if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
+ if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticv < 2
&& !NEW_DELETE_OPNAME_P (unqualified_id))
{
cp_cv_quals real_quals = memfn_quals;
@@ -10295,7 +10281,7 @@ grokdeclarator (const cp_declarator *declarator,
}
else if (decl_context == FIELD)
{
- if (!staticp && TREE_CODE (type) != METHOD_TYPE
+ if (!staticv && TREE_CODE (type) != METHOD_TYPE
&& type_uses_auto (type))
{
error ("non-static data member declared %<auto%>");
@@ -10303,7 +10289,7 @@ grokdeclarator (const cp_declarator *declarator,
}
/* The C99 flexible array extension. */
- if (!staticp && TREE_CODE (type) == ARRAY_TYPE
+ if (!staticv && TREE_CODE (type) == ARRAY_TYPE
&& TYPE_DOMAIN (type) == NULL_TREE)
{
tree itype = compute_array_index_type (dname, integer_zero_node,
@@ -10326,10 +10312,9 @@ grokdeclarator (const cp_declarator *declarator,
else if (TREE_CODE (type) == FUNCTION_TYPE
|| TREE_CODE (type) == METHOD_TYPE)
{
- int publicp = 0;
tree function_context;
- if (friendp == 0)
+ if (!friendp)
{
/* This should never happen in pure C++ (the check
could be an assert). It could happen in
@@ -10363,7 +10348,7 @@ grokdeclarator (const cp_declarator *declarator,
error ("%qD cannot be declared virtual, since it "
"is always static",
unqualified_id);
- virtualp = 0;
+ virtualp = false;
}
}
}
@@ -10404,8 +10389,8 @@ grokdeclarator (const cp_declarator *declarator,
/* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */
function_context = (ctype != NULL_TREE) ?
decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
- publicp = (! friendp || ! staticp)
- && function_context == NULL_TREE;
+ bool publicp = ((! friendp || ! staticv)
+ && function_context == NULL_TREE);
decl = grokfndecl (ctype, type,
TREE_CODE (unqualified_id) != TEMPLATE_ID_EXPR
? unqualified_id : dname,
@@ -10413,7 +10398,7 @@ grokdeclarator (const cp_declarator *declarator,
unqualified_id,
virtualp, flags, memfn_quals, raises,
friendp ? -1 : 0, friendp, publicp,
- inlinep | (2 * constexpr_p),
+ inlinep, constexpr_p,
sfk,
funcdef_flag, template_count, in_namespace,
attrlist, declarator->id_loc);
@@ -10433,10 +10418,10 @@ grokdeclarator (const cp_declarator *declarator,
specifies a conversion from the type of its first
parameter to the type of its class. Such a constructor
is called a converting constructor. */
- if (explicitp == 2)
+ if (explicitv == 2)
DECL_NONCONVERTING_P (decl) = 1;
}
- else if (!staticp && !dependent_type_p (type)
+ else if (!staticv && !dependent_type_p (type)
&& !COMPLETE_TYPE_P (complete_type (type))
&& (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))
{
@@ -10463,7 +10448,7 @@ grokdeclarator (const cp_declarator *declarator,
{
error ("%qE is neither function nor member function; "
"cannot be declared friend", unqualified_id);
- friendp = 0;
+ friendp = false;
}
decl = NULL_TREE;
}
@@ -10497,7 +10482,7 @@ grokdeclarator (const cp_declarator *declarator,
if (decl == NULL_TREE)
{
- if (staticp)
+ if (staticv)
{
/* C++ allows static class members. All other work
for this is done by grokfield. */
@@ -10533,8 +10518,8 @@ grokdeclarator (const cp_declarator *declarator,
}
decl = build_decl (input_location,
FIELD_DECL, unqualified_id, type);
- DECL_NONADDRESSABLE_P (decl) = bitfield;
- if (bitfield && !unqualified_id)
+ DECL_NONADDRESSABLE_P (decl) = bitfield_p;
+ if (bitfield_p && !unqualified_id)
TREE_NO_WARNING (decl) = 1;
if (storage_class == sc_mutable)
@@ -10550,7 +10535,7 @@ grokdeclarator (const cp_declarator *declarator,
maybe_warn_cpp0x (CPP0X_NSDMI);
/* If this has been parsed with static storage class, but
- errors forced staticp to be cleared, ensure NSDMI is
+ errors forced staticv to be cleared, ensure NSDMI is
not present. */
if (declspecs->storage_class == sc_static)
DECL_INITIAL (decl) = error_mark_node;
@@ -10566,7 +10551,6 @@ grokdeclarator (const cp_declarator *declarator,
|| TREE_CODE (type) == METHOD_TYPE)
{
tree original_name;
- int publicp = 0;
if (!unqualified_id)
return error_mark_node;
@@ -10591,7 +10575,8 @@ grokdeclarator (const cp_declarator *declarator,
}
if (virt_specifiers)
- error ("virt-specifiers in %qs not allowed outside a class
definition", name);
+ error ("virt-specifiers in %qs not allowed outside a class "
+ "definition", name);
/* Function declaration not at top level.
Storage classes other than `extern' are not allowed
and `extern' makes no difference. */
@@ -10615,7 +10600,7 @@ grokdeclarator (const cp_declarator *declarator,
if (virtualp)
{
error ("virtual non-class function %qs", name);
- virtualp = 0;
+ virtualp = false;
}
else if (sfk == sfk_constructor
|| sfk == sfk_destructor)
@@ -10628,41 +10613,42 @@ grokdeclarator (const cp_declarator *declarator,
}
/* Record whether the function is public. */
- publicp = (ctype != NULL_TREE
- || storage_class != sc_static);
+ bool publicp = (ctype != NULL_TREE
+ || storage_class != sc_static);
decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
virtualp, flags, memfn_quals, raises,
1, friendp,
- publicp, inlinep | (2 * constexpr_p), sfk,
+ publicp, inlinep, constexpr_p, sfk,
funcdef_flag,
template_count, in_namespace, attrlist,
declarator->id_loc);
if (decl == NULL_TREE)
return error_mark_node;
- if (staticp == 1)
+ if (staticv == 1)
{
- int invalid_static = 0;
+ bool invalid_static = false;
/* Don't allow a static member function in a class, and forbid
declaring main to be static. */
if (TREE_CODE (type) == METHOD_TYPE)
{
- permerror (input_location, "cannot declare member function %qD
to have "
- "static linkage", decl);
- invalid_static = 1;
+ permerror (input_location, "cannot declare member function %qD "
+ "to have static linkage", decl);
+ invalid_static = true;
}
else if (current_function_decl)
{
/* FIXME need arm citation */
- error ("cannot declare static function inside another
function");
- invalid_static = 1;
+ error ("cannot declare static function inside another "
+ "function");
+ invalid_static = true;
}
if (invalid_static)
{
- staticp = 0;
+ staticv = 0;
storage_class = sc_none;
}
}
@@ -10684,11 +10670,12 @@ grokdeclarator (const cp_declarator *declarator,
if (ctype)
{
DECL_CONTEXT (decl) = ctype;
- if (staticp == 1)
+ if (staticv == 1)
{
- permerror (input_location, "%<static%> may not be used when
defining "
+ permerror (input_location,
+ "%<static%> may not be used when defining "
"(as opposed to declaring) a static data member");
- staticp = 0;
+ staticv = 0;
storage_class = sc_none;
}
if (storage_class == sc_register && TREE_STATIC (decl))
Index: testsuite/g++.dg/cpp0x/constexpr-friend-2.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-friend-2.C (revision 0)
+++ testsuite/g++.dg/cpp0x/constexpr-friend-2.C (working copy)
@@ -0,0 +1,7 @@
+// { dg-do compile { target c++11 } }
+
+template<typename T> void f(T);
+
+template <class T> class A {
+ friend constexpr void f<>(int); // { dg-error "'constexpr' is not allowed" }
+};
Index: testsuite/g++.dg/cpp0x/constexpr-main.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-main.C (revision 0)
+++ testsuite/g++.dg/cpp0x/constexpr-main.C (working copy)
@@ -0,0 +1,3 @@
+// { dg-do compile { target c++11 } }
+
+constexpr int main (); // { dg-error "constexpr" }