static tree grokfndecl (tree, tree, tree, tree, tree, int,
enum overload_flags, cp_cv_quals,
tree, int, int, int, int, int, int, tree);
-static tree grokvardecl (tree, tree, cp_decl_specifier_seq *, int, int, tree);
+static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
+ int, int, tree);
static void record_unknown_type (tree, const char *);
static tree builtin_function_1 (const char *, tree, tree, int,
enum built_in_class, const char *,
static tree
grokvardecl (tree type,
tree name,
- cp_decl_specifier_seq *declspecs,
+ const cp_decl_specifier_seq *declspecs,
int initialized,
int constp,
tree scope)
tree
grokdeclarator (const cp_declarator *declarator,
- cp_decl_specifier_seq *declspecs,
+ const cp_decl_specifier_seq *declspecs,
enum decl_context decl_context,
int initialized,
tree* attrlist)
namespace scope. */
tree in_namespace = NULL_TREE;
cp_decl_spec ds;
+ cp_storage_class storage_class;
+ bool unsigned_p, signed_p, short_p, long_p, thread_p;
+
+ signed_p = declspecs->specs[(int)ds_signed];
+ unsigned_p = declspecs->specs[(int)ds_unsigned];
+ short_p = declspecs->specs[(int)ds_short];
+ long_p = declspecs->specs[(int)ds_long];
+ thread_p = declspecs->specs[(int)ds_thread];
if (decl_context == FUNCDEF)
funcdef_flag = 1, decl_context = NORMAL;
}
/* No type at all: default to `int', and set DEFAULTED_INT
because it was not a user-defined typedef. */
- if (type == NULL_TREE
- && (declspecs->specs[(int)ds_signed]
- || declspecs->specs[(int)ds_unsigned]
- || declspecs->specs[(int)ds_long]
- || declspecs->specs[(int)ds_short]))
+ if (type == NULL_TREE && (signed_p || unsigned_p || long_p || short_p))
{
/* These imply 'int'. */
type = integer_type_node;
and check for invalid combinations. */
/* Long double is a special combination. */
- if (declspecs->specs[(int)ds_long]
- && TYPE_MAIN_VARIANT (type) == double_type_node)
+ if (long_p && TYPE_MAIN_VARIANT (type) == double_type_node)
{
- declspecs->specs[(int)ds_long] = 0;
+ long_p = false;
type = build_qualified_type (long_double_type_node,
cp_type_quals (type));
}
/* Check all other uses of type modifiers. */
- if (declspecs->specs[(int)ds_unsigned]
- || declspecs->specs[(int)ds_signed]
- || declspecs->specs[(int)ds_long]
- || declspecs->specs[(int)ds_short])
+ if (unsigned_p || signed_p || long_p || short_p)
{
int ok = 0;
error ("short, signed or unsigned invalid for `%s'", name);
else if (TREE_CODE (type) != INTEGER_TYPE)
error ("long, short, signed or unsigned invalid for `%s'", name);
- else if (declspecs->specs[(int)ds_long]
- && declspecs->specs[(int)ds_short])
+ else if (long_p && short_p)
error ("long and short specified together for `%s'", name);
- else if ((declspecs->specs[(int)ds_long]
- || declspecs->specs[(int)ds_short])
- && explicit_char)
+ else if ((long_p || short_p) && explicit_char)
error ("long or short specified with char for `%s'", name);
- else if ((declspecs->specs[(int)ds_long]
- || declspecs->specs[(int)ds_short])
- && TREE_CODE (type) == REAL_TYPE)
+ else if ((long_p|| short_p) && TREE_CODE (type) == REAL_TYPE)
error ("long or short specified with floating type for `%s'", name);
- else if (declspecs->specs[(int)ds_signed]
- && declspecs->specs[(int)ds_unsigned])
+ else if (signed_p && unsigned_p)
error ("signed and unsigned given together for `%s'", name);
else
{
/* Discard the type modifiers if they are invalid. */
if (! ok)
{
- declspecs->specs[(int)ds_unsigned] = 0;
- declspecs->specs[(int)ds_signed] = 0;
- declspecs->specs[(int)ds_long] = 0;
- declspecs->specs[(int)ds_short] = 0;
+ unsigned_p = false;
+ signed_p = false;
+ long_p = false;
+ short_p = false;
longlong = 0;
}
}
- if (declspecs->specs[(int)ds_complex]
- && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
- {
- error ("complex invalid for `%s'", name);
- declspecs->specs[(int)ds_complex] = 0;
- }
-
/* Decide whether an integer type is signed or not.
Optionally treat bitfields as signed by default. */
- if (declspecs->specs[(int)ds_unsigned]
+ if (unsigned_p
/* [class.bit]
It is implementation-defined whether a plain (neither
Naturally, we extend this to long long as well. Note that
this does not include wchar_t. */
|| (bitfield && !flag_signed_bitfields
- && !declspecs->specs[(int)ds_signed]
+ && !signed_p
/* A typedef for plain `int' without `signed' can be
controlled just like plain `int', but a typedef for
`signed int' cannot be so controlled. */
{
if (longlong)
type = long_long_unsigned_type_node;
- else if (declspecs->specs[(int)ds_long])
+ else if (long_p)
type = long_unsigned_type_node;
- else if (declspecs->specs[(int)ds_short])
+ else if (short_p)
type = short_unsigned_type_node;
else if (type == char_type_node)
type = unsigned_char_type_node;
else
type = unsigned_type_node;
}
- else if (declspecs->specs[(int)ds_signed]
- && type == char_type_node)
+ else if (signed_p && type == char_type_node)
type = signed_char_type_node;
else if (longlong)
type = long_long_integer_type_node;
- else if (declspecs->specs[(int)ds_long])
+ else if (long_p)
type = long_integer_type_node;
- else if (declspecs->specs[(int)ds_short])
+ else if (short_p)
type = short_integer_type_node;
if (declspecs->specs[(int)ds_complex])
{
+ if (TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
+ error ("complex invalid for `%s'", name);
/* If we just have "complex", it is equivalent to
"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". */
- if (defaulted_int && ! longlong
- && ! (declspecs->specs[(int)ds_long]
- || declspecs->specs[(int)ds_short]
- || declspecs->specs[(int)ds_signed]
- || declspecs->specs[(int)ds_unsigned]))
+ else if (defaulted_int && ! longlong
+ && ! (long_p || short_p || signed_p || unsigned_p))
type = complex_double_type_node;
else if (type == integer_type_node)
type = complex_integer_type_node;
virtualp = !! declspecs->specs[(int)ds_virtual];
explicitp = !! declspecs->specs[(int)ds_explicit];
- if (declspecs->storage_class == sc_static)
+ storage_class = declspecs->storage_class;
+ if (storage_class == sc_static)
staticp = 1 + (decl_context == FIELD);
if (virtualp && staticp == 2)
{
if (declspecs->specs[(int)ds_typedef])
error ("typedef declaration invalid in parameter declaration");
- else if (declspecs->storage_class == sc_static
- || declspecs->storage_class == sc_extern
- || declspecs->specs[(int)ds_thread])
+ else if (storage_class == sc_static
+ || storage_class == sc_extern
+ || thread_p)
error ("storage class specifiers invalid in parameter declarations");
}
kinds of declarations (parameters, typenames, etc.). */
if (declspecs->multiple_storage_classes_p)
error ("multiple storage classes in declaration of `%s'", name);
- else if (declspecs->specs[(int)ds_thread]
- && ((declspecs->storage_class
- && declspecs->storage_class != sc_extern
- && declspecs->storage_class != sc_static)
+ else if (thread_p
+ && ((storage_class
+ && storage_class != sc_extern
+ && storage_class != sc_static)
|| declspecs->specs[(int)ds_typedef]))
{
error ("multiple storage classes in declaration of `%s'", name);
- declspecs->specs[(int)ds_thread] = 0;
+ thread_p = false;
}
else if (decl_context != NORMAL
- && ((declspecs->storage_class != sc_none
- && declspecs->storage_class != sc_mutable)
- || declspecs->specs[(int)ds_thread]))
+ && ((storage_class != sc_none
+ && storage_class != sc_mutable)
+ || thread_p))
{
if ((decl_context == PARM || decl_context == CATCHPARM)
- && (declspecs->storage_class == sc_register
- || declspecs->storage_class == sc_auto))
+ && (storage_class == sc_register
+ || storage_class == sc_auto))
;
else if (declspecs->specs[(int)ds_typedef])
;
else if (decl_context == FIELD
/* C++ allows static class elements. */
- && declspecs->storage_class == sc_static)
+ && storage_class == sc_static)
/* C++ also allows inlines and signed and unsigned elements,
but in those cases we don't come in here. */
;
else
error ("storage class specified for typename");
}
- if (declspecs->storage_class == sc_register
- || declspecs->storage_class == sc_auto
- || declspecs->storage_class == sc_extern
- || declspecs->specs[(int)ds_thread])
- declspecs->storage_class = sc_none;
+ if (storage_class == sc_register
+ || storage_class == sc_auto
+ || storage_class == sc_extern
+ || thread_p)
+ storage_class = sc_none;
}
}
- else if (declspecs->storage_class == sc_extern && initialized
+ else if (storage_class == sc_extern && initialized
&& !funcdef_flag)
{
if (toplevel_bindings_p ())
else
error ("`%s' has both `extern' and initializer", name);
}
- else if (declspecs->storage_class == sc_extern && funcdef_flag
+ else if (storage_class == sc_extern && funcdef_flag
&& ! toplevel_bindings_p ())
error ("nested function `%s' declared `extern'", name);
else if (toplevel_bindings_p ())
{
- if (declspecs->storage_class == sc_auto)
+ if (storage_class == sc_auto)
error ("top-level declaration of `%s' specifies `auto'", name);
}
- else if (declspecs->specs[(int)ds_thread]
- && declspecs->storage_class != sc_extern
- && declspecs->storage_class != sc_static)
+ else if (thread_p
+ && storage_class != sc_extern
+ && storage_class != sc_static)
{
error ("function-scope `%s' implicitly auto and declared `__thread'",
name);
- declspecs->specs[(int)ds_thread] = 0;
+ thread_p = false;
}
- if (declspecs->storage_class && friendp)
+ if (storage_class && friendp)
error ("storage class specifiers invalid in friend function declarations");
if (!id_declarator)
explicitp = 0;
}
- if (declspecs->storage_class == sc_mutable)
+ if (storage_class == sc_mutable)
{
if (decl_context != FIELD || friendp)
{
error ("non-member `%s' cannot be declared `mutable'", name);
- declspecs->storage_class = sc_none;
+ storage_class = sc_none;
}
else if (decl_context == TYPENAME || declspecs->specs[(int)ds_typedef])
{
error ("non-object member `%s' cannot be declared `mutable'", name);
- declspecs->storage_class = sc_none;
+ storage_class = sc_none;
}
else if (TREE_CODE (type) == FUNCTION_TYPE
|| TREE_CODE (type) == METHOD_TYPE)
{
error ("function `%s' cannot be declared `mutable'", name);
- declspecs->storage_class = sc_none;
+ storage_class = sc_none;
}
else if (staticp)
{
error ("static `%s' cannot be declared `mutable'", name);
- declspecs->storage_class = sc_none;
+ storage_class = sc_none;
}
else if (type_quals & TYPE_QUAL_CONST)
{
error ("const `%s' cannot be declared `mutable'", name);
- declspecs->storage_class = sc_none;
+ storage_class = sc_none;
}
}
grok_method_quals (ctype, decl, quals);
}
- if (declspecs->specs[(int)ds_signed]
+ if (signed_p
|| (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
{
decl = build_decl (FIELD_DECL, unqualified_id, type);
DECL_NONADDRESSABLE_P (decl) = bitfield;
- if (declspecs->storage_class == sc_mutable)
+ if (storage_class == sc_mutable)
{
DECL_MUTABLE_P (decl) = 1;
- declspecs->storage_class = sc_none;
+ storage_class = sc_none;
}
}
else
original_name = unqualified_id;
- if (declspecs->storage_class == sc_auto)
+ if (storage_class == sc_auto)
error ("storage class `auto' invalid for function `%s'", name);
- else if (declspecs->storage_class == sc_register)
+ else if (storage_class == sc_register)
error ("storage class `register' invalid for function `%s'", name);
- else if (declspecs->specs[(int)ds_thread])
+ else if (thread_p)
error ("storage class `__thread' invalid for function `%s'", name);
/* Function declaration not at top level.
Storage classes other than `extern' are not allowed
and `extern' makes no difference. */
if (! toplevel_bindings_p ()
- && (declspecs->storage_class == sc_static
+ && (storage_class == sc_static
|| declspecs->specs[(int)ds_inline])
&& pedantic)
{
- if (declspecs->storage_class == sc_static)
+ if (storage_class == sc_static)
pedwarn ("`static' specified invalid for function `%s' declared out of global scope", name);
else
pedwarn ("`inline' specifier invalid for function `%s' declared out of global scope", name);
/* Record presence of `static'. */
publicp = (ctype != NULL_TREE
- || declspecs->storage_class == sc_extern
- || declspecs->storage_class != sc_static);
+ || storage_class == sc_extern
+ || storage_class != sc_static);
decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
virtualp, flags, quals, raises,
if (invalid_static)
{
staticp = 0;
- declspecs->storage_class = sc_none;
+ storage_class = sc_none;
}
}
}
{
pedwarn ("`static' may not be used when defining (as opposed to declaring) a static data member");
staticp = 0;
- declspecs->storage_class = sc_none;
+ storage_class = sc_none;
}
- if (declspecs->storage_class == sc_register && TREE_STATIC (decl))
+ if (storage_class == sc_register && TREE_STATIC (decl))
{
error ("static member `%D' declared `register'", decl);
- declspecs->storage_class = sc_none;
+ storage_class = sc_none;
}
- if (declspecs->storage_class == sc_extern && pedantic)
+ if (storage_class == sc_extern && pedantic)
{
pedwarn ("cannot explicitly declare member `%#D' to have extern linkage",
decl);
- declspecs->storage_class = sc_none;
+ storage_class = sc_none;
}
}
}
/* Record `register' declaration for warnings on &
and in case doing stupid register allocation. */
- if (declspecs->storage_class == sc_register)
+ if (storage_class == sc_register)
DECL_REGISTER (decl) = 1;
- else if (declspecs->storage_class == sc_extern)
+ else if (storage_class == sc_extern)
DECL_THIS_EXTERN (decl) = 1;
- else if (declspecs->storage_class == sc_static)
+ else if (storage_class == sc_static)
DECL_THIS_STATIC (decl) = 1;
/* Record constancy and volatility. There's no need to do this