DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
= (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));
+
+ DECL_DISREGARD_INLINE_LIMITS (newdecl)
+ = DECL_DISREGARD_INLINE_LIMITS (olddecl)
+ = (DECL_DISREGARD_INLINE_LIMITS (newdecl)
+ || DECL_DISREGARD_INLINE_LIMITS (olddecl));
}
if (DECL_BUILT_IN (olddecl))
if (!diagnose_mismatched_decls (newdecl, olddecl, &newtype, &oldtype))
{
- /* Avoid `unused variable' and other warnings warnings for OLDDECL. */
+ /* Avoid `unused variable' and other warnings for OLDDECL. */
TREE_NO_WARNING (olddecl) = 1;
return false;
}
Obviously, we don't want to generate a duplicate ..._TYPE node if
the TYPE_DECL node that we are now processing really represents a
- standard built-in type.
-
- Since all standard types are effectively declared at line zero
- in the source file, we can easily check to see if we are working
- on a standard type by checking the current value of lineno. */
+ standard built-in type. */
static void
clone_underlying_type (tree x)
DECL_ARTIFICIAL (decl) = 1;
init = build_string (length + 1, name);
- free (CONST_CAST (name));
+ free (CONST_CAST (char *, name));
TREE_TYPE (init) = type;
DECL_INITIAL (decl) = init;
type = c_build_qualified_type (type, type_quals);
type = build_pointer_type (type);
type_quals = array_ptr_quals;
+ if (type_quals)
+ type = c_build_qualified_type (type, type_quals);
/* We don't yet implement attributes in this context. */
if (array_ptr_attrs != NULL_TREE)
/* Finalize the ELF visibility for the function. */
c_determine_visibility (fndecl);
+ /* For GNU C extern inline functions disregard inline limits. */
+ if (DECL_EXTERNAL (fndecl)
+ && DECL_DECLARED_INLINE_P (fndecl))
+ DECL_DISREGARD_INLINE_LIMITS (fndecl) = 1;
+
/* Genericize before inlining. Delay genericizing nested functions
until their parent function is genericized. Since finalizing
requires GENERIC, delay that as well. */
/* We're leaving the context of this function, so zap cfun.
It's still in DECL_STRUCT_FUNCTION, and we'll restore it in
tree_rest_of_compilation. */
- cfun = NULL;
+ set_cfun (NULL);
current_function_decl = NULL;
}
\f
C. */
int
-anon_aggr_type_p (tree ARG_UNUSED (node))
+anon_aggr_type_p (const_tree ARG_UNUSED (node))
{
return 0;
}
ret->const_p = false;
ret->volatile_p = false;
ret->restrict_p = false;
+ ret->saturating_p = false;
return ret;
}
}
if ((int) i <= (int) RID_LAST_MODIFIER)
{
- /* "long", "short", "signed", "unsigned" or "_Complex". */
+ /* "long", "short", "signed", "unsigned", "_Complex" or "_Sat". */
bool dupe = false;
switch (i)
{
else if (specs->typespec_word == cts_dfloat128)
error ("both %<complex%> and %<_Decimal128%> in "
"declaration specifiers");
+ else if (specs->typespec_word == cts_fract)
+ error ("both %<complex%> and %<_Fract%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_accum)
+ error ("both %<complex%> and %<_Accum%> in "
+ "declaration specifiers");
+ else if (specs->saturating_p)
+ error ("both %<complex%> and %<_Sat%> in "
+ "declaration specifiers");
else
specs->complex_p = true;
break;
+ case RID_SAT:
+ dupe = specs->saturating_p;
+ if (pedantic)
+ pedwarn ("ISO C does not support saturating types");
+ if (specs->typespec_word == cts_void)
+ error ("both %<_Sat%> and %<void%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_bool)
+ error ("both %<_Sat%> and %<_Bool%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_char)
+ error ("both %<_Sat%> and %<char%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_int)
+ error ("both %<_Sat%> and %<int%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_float)
+ error ("both %<_Sat%> and %<float%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_double)
+ error ("both %<_Sat%> and %<double%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_dfloat32)
+ error ("both %<_Sat%> and %<_Decimal32%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_dfloat64)
+ error ("both %<_Sat%> and %<_Decimal64%> in "
+ "declaration specifiers");
+ else if (specs->typespec_word == cts_dfloat128)
+ error ("both %<_Sat%> and %<_Decimal128%> in "
+ "declaration specifiers");
+ else if (specs->complex_p)
+ error ("both %<_Sat%> and %<complex%> in "
+ "declaration specifiers");
+ else
+ specs->saturating_p = true;
+ break;
default:
gcc_unreachable ();
}
}
else
{
- /* "void", "_Bool", "char", "int", "float" or "double". */
+ /* "void", "_Bool", "char", "int", "float", "double", "_Decimal32",
+ "_Decimal64", "_Decimal128", "_Fract" or "_Accum". */
if (specs->typespec_word != cts_none)
{
error ("two or more data types in declaration specifiers");
else if (specs->complex_p)
error ("both %<complex%> and %<void%> in "
"declaration specifiers");
+ else if (specs->saturating_p)
+ error ("both %<_Sat%> and %<void%> in "
+ "declaration specifiers");
else
specs->typespec_word = cts_void;
return specs;
else if (specs->complex_p)
error ("both %<complex%> and %<_Bool%> in "
"declaration specifiers");
+ else if (specs->saturating_p)
+ error ("both %<_Sat%> and %<_Bool%> in "
+ "declaration specifiers");
else
specs->typespec_word = cts_bool;
return specs;
else if (specs->short_p)
error ("both %<short%> and %<char%> in "
"declaration specifiers");
+ else if (specs->saturating_p)
+ error ("both %<_Sat%> and %<char%> in "
+ "declaration specifiers");
else
specs->typespec_word = cts_char;
return specs;
case RID_INT:
- specs->typespec_word = cts_int;
+ if (specs->saturating_p)
+ error ("both %<_Sat%> and %<int%> in "
+ "declaration specifiers");
+ else
+ specs->typespec_word = cts_int;
return specs;
case RID_FLOAT:
if (specs->long_p)
else if (specs->unsigned_p)
error ("both %<unsigned%> and %<float%> in "
"declaration specifiers");
+ else if (specs->saturating_p)
+ error ("both %<_Sat%> and %<float%> in "
+ "declaration specifiers");
else
specs->typespec_word = cts_float;
return specs;
else if (specs->unsigned_p)
error ("both %<unsigned%> and %<double%> in "
"declaration specifiers");
+ else if (specs->saturating_p)
+ error ("both %<_Sat%> and %<double%> in "
+ "declaration specifiers");
else
specs->typespec_word = cts_double;
return specs;
else if (specs->complex_p)
error ("both %<complex%> and %<%s%> in "
"declaration specifiers", str);
+ else if (specs->saturating_p)
+ error ("both %<_Sat%> and %<%s%> in "
+ "declaration specifiers", str);
else if (i == RID_DFLOAT32)
specs->typespec_word = cts_dfloat32;
else if (i == RID_DFLOAT64)
if (pedantic)
pedwarn ("ISO C does not support decimal floating point");
return specs;
+ case RID_FRACT:
+ case RID_ACCUM:
+ {
+ const char *str;
+ if (i == RID_FRACT)
+ str = "_Fract";
+ else
+ str = "_Accum";
+ if (specs->complex_p)
+ error ("both %<complex%> and %<%s%> in "
+ "declaration specifiers", str);
+ else if (i == RID_FRACT)
+ specs->typespec_word = cts_fract;
+ else
+ specs->typespec_word = cts_accum;
+ }
+ if (!targetm.fixed_point_supported_p ())
+ error ("fixed-point types not supported for this target");
+ if (pedantic)
+ pedwarn ("ISO C does not support fixed-point types");
+ return specs;
default:
/* ObjC reserved word "id", handled below. */
break;
"_Complex short" is equivalent to "_Complex short int". */
if (specs->typespec_word == cts_none)
{
+ if (specs->saturating_p)
+ error ("%<_Sat%> is used without %<_Fract%> or %<_Accum%>");
if (specs->long_p || specs->short_p
|| specs->signed_p || specs->unsigned_p)
{
else
specs->type = dfloat128_type_node;
break;
+ case cts_fract:
+ gcc_assert (!specs->complex_p);
+ if (specs->saturating_p)
+ {
+ if (specs->long_long_p)
+ specs->type = specs->unsigned_p
+ ? sat_unsigned_long_long_fract_type_node
+ : sat_long_long_fract_type_node;
+ else if (specs->long_p)
+ specs->type = specs->unsigned_p
+ ? sat_unsigned_long_fract_type_node
+ : sat_long_fract_type_node;
+ else if (specs->short_p)
+ specs->type = specs->unsigned_p
+ ? sat_unsigned_short_fract_type_node
+ : sat_short_fract_type_node;
+ else
+ specs->type = specs->unsigned_p
+ ? sat_unsigned_fract_type_node
+ : sat_fract_type_node;
+ }
+ else
+ {
+ if (specs->long_long_p)
+ specs->type = specs->unsigned_p
+ ? unsigned_long_long_fract_type_node
+ : long_long_fract_type_node;
+ else if (specs->long_p)
+ specs->type = specs->unsigned_p
+ ? unsigned_long_fract_type_node
+ : long_fract_type_node;
+ else if (specs->short_p)
+ specs->type = specs->unsigned_p
+ ? unsigned_short_fract_type_node
+ : short_fract_type_node;
+ else
+ specs->type = specs->unsigned_p
+ ? unsigned_fract_type_node
+ : fract_type_node;
+ }
+ break;
+ case cts_accum:
+ gcc_assert (!specs->complex_p);
+ if (specs->saturating_p)
+ {
+ if (specs->long_long_p)
+ specs->type = specs->unsigned_p
+ ? sat_unsigned_long_long_accum_type_node
+ : sat_long_long_accum_type_node;
+ else if (specs->long_p)
+ specs->type = specs->unsigned_p
+ ? sat_unsigned_long_accum_type_node
+ : sat_long_accum_type_node;
+ else if (specs->short_p)
+ specs->type = specs->unsigned_p
+ ? sat_unsigned_short_accum_type_node
+ : sat_short_accum_type_node;
+ else
+ specs->type = specs->unsigned_p
+ ? sat_unsigned_accum_type_node
+ : sat_accum_type_node;
+ }
+ else
+ {
+ if (specs->long_long_p)
+ specs->type = specs->unsigned_p
+ ? unsigned_long_long_accum_type_node
+ : long_long_accum_type_node;
+ else if (specs->long_p)
+ specs->type = specs->unsigned_p
+ ? unsigned_long_accum_type_node
+ : long_accum_type_node;
+ else if (specs->short_p)
+ specs->type = specs->unsigned_p
+ ? unsigned_short_accum_type_node
+ : short_accum_type_node;
+ else
+ specs->type = specs->unsigned_p
+ ? unsigned_accum_type_node
+ : accum_type_node;
+ }
+ break;
default:
gcc_unreachable ();
}