static dw_die_ref base_type_die (tree);
static int is_base_type (tree);
static dw_die_ref subrange_type_die (tree, tree, tree, dw_die_ref);
-static dw_die_ref modified_type_die (tree, int, int, dw_die_ref);
+static int decl_quals (const_tree);
+static dw_die_ref modified_type_die (tree, int, dw_die_ref);
static dw_die_ref generic_parameter_die (tree, tree, bool, dw_die_ref);
static dw_die_ref template_parameter_pack_die (tree, tree, dw_die_ref);
static int type_is_enum (const_tree);
static inline int local_scope_p (dw_die_ref);
static inline int class_scope_p (dw_die_ref);
static inline int class_or_namespace_scope_p (dw_die_ref);
-static void add_type_attribute (dw_die_ref, tree, int, int, dw_die_ref);
+static void add_type_attribute (dw_die_ref, tree, int, dw_die_ref);
static void add_calling_convention_attribute (dw_die_ref, tree);
static const char *type_tag (const_tree);
static tree member_declared_type (const_tree);
return subrange_die;
}
+/* Returns the (const and/or volatile) cv_qualifiers associated with
+ the decl node. This will normally be augmented with the
+ cv_qualifiers of the underlying type in add_type_attribute. */
+
+static int
+decl_quals (const_tree decl)
+{
+ return ((TREE_READONLY (decl)
+ ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED)
+ | (TREE_THIS_VOLATILE (decl)
+ ? TYPE_QUAL_VOLATILE : TYPE_UNQUALIFIED));
+}
+
/* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging
entry that chains various modifiers in front of the given type. */
static dw_die_ref
-modified_type_die (tree type, int is_const_type, int is_volatile_type,
- dw_die_ref context_die)
+modified_type_die (tree type, int cv_quals, dw_die_ref context_die)
{
enum tree_code code = TREE_CODE (type);
dw_die_ref mod_type_die;
if (code == ERROR_MARK)
return NULL;
+ /* Only these cv-qualifiers are currently handled. */
+ cv_quals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+
/* See if we already have the appropriately qualified variant of
this type. */
- qualified_type
- = get_qualified_type (type,
- ((is_const_type ? TYPE_QUAL_CONST : 0)
- | (is_volatile_type ? TYPE_QUAL_VOLATILE : 0)));
+ qualified_type = get_qualified_type (type, cv_quals);
if (qualified_type == sizetype
&& TYPE_NAME (qualified_type)
gen_type_die (qualified_type, context_die);
return lookup_type_die (qualified_type);
}
- else if (is_const_type < TYPE_READONLY (dtype)
- || is_volatile_type < TYPE_VOLATILE (dtype)
- || (is_const_type <= TYPE_READONLY (dtype)
- && is_volatile_type <= TYPE_VOLATILE (dtype)
- && DECL_ORIGINAL_TYPE (name) != type))
- /* cv-unqualified version of named type. Just use the unnamed
- type to which it refers. */
- return modified_type_die (DECL_ORIGINAL_TYPE (name),
- is_const_type, is_volatile_type,
- context_die);
- /* Else cv-qualified version of named type; fall through. */
+ else
+ {
+ int dquals = TYPE_QUALS_NO_ADDR_SPACE (dtype);
+ dquals &= (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
+ if ((dquals & ~cv_quals) != TYPE_UNQUALIFIED
+ || (cv_quals == dquals && DECL_ORIGINAL_TYPE (name) != type))
+ /* cv-unqualified version of named type. Just use
+ the unnamed type to which it refers. */
+ return modified_type_die (DECL_ORIGINAL_TYPE (name),
+ cv_quals, context_die);
+ /* Else cv-qualified version of named type; fall through. */
+ }
}
mod_scope = scope_die_for (type, context_die);
- if (is_const_type
- /* If both is_const_type and is_volatile_type, prefer the path
+ if ((cv_quals & TYPE_QUAL_CONST)
+ /* If both const_type and volatile_type, prefer the path
which leads to a qualified type. */
- && (!is_volatile_type
+ && (!(cv_quals & TYPE_QUAL_VOLATILE)
|| get_qualified_type (type, TYPE_QUAL_CONST) == NULL_TREE
|| get_qualified_type (type, TYPE_QUAL_VOLATILE) != NULL_TREE))
{
mod_type_die = new_die (DW_TAG_const_type, mod_scope, type);
- sub_die = modified_type_die (type, 0, is_volatile_type, context_die);
+ sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_CONST,
+ context_die);
}
- else if (is_volatile_type)
+ else if (cv_quals & TYPE_QUAL_VOLATILE)
{
mod_type_die = new_die (DW_TAG_volatile_type, mod_scope, type);
- sub_die = modified_type_die (type, is_const_type, 0, context_die);
+ sub_die = modified_type_die (type, cv_quals & ~TYPE_QUAL_VOLATILE,
+ context_die);
}
else if (code == POINTER_TYPE)
{
if (name
&& ((TREE_CODE (name) != TYPE_DECL
&& (qualified_type == TYPE_MAIN_VARIANT (type)
- || (!is_const_type && !is_volatile_type)))
+ || (cv_quals == TYPE_UNQUALIFIED)))
|| (TREE_CODE (name) == TYPE_DECL
&& TREE_TYPE (name) == qualified_type
&& DECL_NAME (name))))
recursion will terminate even if the type is recursive. Recursive
types are possible in Ada. */
sub_die = modified_type_die (item_type,
- TYPE_READONLY (item_type),
- TYPE_VOLATILE (item_type),
+ TYPE_QUALS_NO_ADDR_SPACE (item_type),
context_die);
if (sub_die != NULL)
If PARM is a type generic parameter, TMPL_DIE should have a
child DW_AT_type that is set to ARG. */
tmpl_type = TYPE_P (arg) ? arg : TREE_TYPE (arg);
- add_type_attribute (tmpl_die, tmpl_type, 0,
- TREE_THIS_VOLATILE (tmpl_type),
+ add_type_attribute (tmpl_die, tmpl_type,
+ (TREE_THIS_VOLATILE (tmpl_type)
+ ? TYPE_QUAL_VOLATILE : TYPE_UNQUALIFIED),
parent_die);
}
else
}
type_die = lookup_type_die (type);
if (!type_die)
- type_die = modified_type_die (type, false, false, comp_unit_die ());
+ type_die = modified_type_die (type, TYPE_UNQUALIFIED, comp_unit_die ());
if (type_die == NULL || type_die->die_tag != DW_TAG_base_type)
return NULL;
return type_die;
decl_die = new_die (DW_TAG_variable, ctx, bound);
add_AT_flag (decl_die, DW_AT_artificial, 1);
- add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
+ add_type_attribute (decl_die, TREE_TYPE (bound), TYPE_QUAL_CONST, ctx);
add_AT_location_description (decl_die, DW_AT_location, list);
add_AT_die_ref (subrange_die, bound_attr, decl_die);
break;
&& TYPE_NAME (TREE_TYPE (domain)) == NULL_TREE)
;
else
- add_type_attribute (subrange_die, TREE_TYPE (domain), 0, 0,
- type_die);
+ add_type_attribute (subrange_die, TREE_TYPE (domain),
+ TYPE_UNQUALIFIED, type_die);
}
/* ??? If upper is NULL, the array has unspecified length,
/* Many forms of DIEs require a "type description" attribute. This
routine locates the proper "type descriptor" die for the type given
- by 'type', and adds a DW_AT_type attribute below the given die. */
+ by 'type' plus any additional qualifiers given by 'cv_quals', and
+ adds a DW_AT_type attribute below the given die. */
static void
-add_type_attribute (dw_die_ref object_die, tree type, int decl_const,
- int decl_volatile, dw_die_ref context_die)
+add_type_attribute (dw_die_ref object_die, tree type, int cv_quals,
+ dw_die_ref context_die)
{
enum tree_code code = TREE_CODE (type);
dw_die_ref type_die = NULL;
return;
type_die = modified_type_die (type,
- decl_const || TYPE_READONLY (type),
- decl_volatile || TYPE_VOLATILE (type),
+ cv_quals | TYPE_QUALS_NO_ADDR_SPACE (type),
context_die);
if (type_die != NULL)
element_type = TREE_TYPE (element_type);
}
- add_type_attribute (array_die, element_type, 0, 0, context_die);
+ add_type_attribute (array_die, element_type, TYPE_UNQUALIFIED, context_die);
add_gnat_descriptive_type_attribute (array_die, type, context_die);
if (TYPE_ARTIFICIAL (type))
}
gen_type_die (info->element_type, context_die);
- add_type_attribute (array_die, info->element_type, 0, 0, context_die);
+ add_type_attribute (array_die, info->element_type, TYPE_UNQUALIFIED,
+ context_die);
if (get_AT (array_die, DW_AT_name))
add_pubtype (type, array_die);
{
add_name_and_src_coords_attributes (decl_die, decl);
add_type_attribute (decl_die, TREE_TYPE (TREE_TYPE (decl)),
- 0, 0, context_die);
+ TYPE_UNQUALIFIED, context_die);
}
if (DECL_ABSTRACT (decl))
if (dwarf_version >= 3 || !dwarf_strict)
{
tree underlying = lang_hooks.types.enum_underlying_base_type (type);
- add_type_attribute (type_die, underlying, 0, 0, context_die);
+ add_type_attribute (type_die, underlying, TYPE_UNQUALIFIED,
+ context_die);
}
if (TYPE_STUB_DECL (type) != NULL_TREE)
{
{
tree type = TREE_TYPE (node_or_origin);
if (decl_by_reference_p (node_or_origin))
- add_type_attribute (parm_die, TREE_TYPE (type), 0, 0,
- context_die);
+ add_type_attribute (parm_die, TREE_TYPE (type),
+ TYPE_UNQUALIFIED, context_die);
else
add_type_attribute (parm_die, type,
- TREE_READONLY (node_or_origin),
- TREE_THIS_VOLATILE (node_or_origin),
+ decl_quals (node_or_origin),
context_die);
}
if (origin == NULL && DECL_ARTIFICIAL (node))
case tcc_type:
/* We were called with some kind of a ..._TYPE node. */
- add_type_attribute (parm_die, node_or_origin, 0, 0, context_die);
+ add_type_attribute (parm_die, node_or_origin, TYPE_UNQUALIFIED,
+ context_die);
break;
default:
dw_die_ref die = get_AT_ref (old_die, DW_AT_type);
if (die == auto_die || die == decltype_auto_die)
add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)),
- 0, 0, context_die);
+ TYPE_UNQUALIFIED, context_die);
}
}
}
{
add_prototyped_attribute (subr_die, TREE_TYPE (decl));
add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)),
- 0, 0, context_die);
+ TYPE_UNQUALIFIED, context_die);
}
add_pure_or_virtual_attribute (subr_die, decl);
}
var_die = new_die (DW_TAG_variable, com_die, decl);
add_name_and_src_coords_attributes (var_die, decl);
- add_type_attribute (var_die, TREE_TYPE (decl), TREE_READONLY (decl),
- TREE_THIS_VOLATILE (decl), context_die);
+ add_type_attribute (var_die, TREE_TYPE (decl), decl_quals (decl),
+ context_die);
add_AT_flag (var_die, DW_AT_external, 1);
if (loc)
{
tree type = TREE_TYPE (decl_or_origin);
if (decl_by_reference_p (decl_or_origin))
- add_type_attribute (var_die, TREE_TYPE (type), 0, 0, context_die);
+ add_type_attribute (var_die, TREE_TYPE (type), TYPE_UNQUALIFIED,
+ context_die);
else
- add_type_attribute (var_die, type, TREE_READONLY (decl_or_origin),
- TREE_THIS_VOLATILE (decl_or_origin), context_die);
+ add_type_attribute (var_die, type, decl_quals (decl_or_origin),
+ context_die);
}
if (origin == NULL && !specialization_p)
const_die = new_die (DW_TAG_constant, context_die, decl);
add_name_and_src_coords_attributes (const_die, decl);
- add_type_attribute (const_die, type, 1, 0, context_die);
+ add_type_attribute (const_die, type, TYPE_QUAL_CONST, context_die);
if (TREE_PUBLIC (decl))
add_AT_flag (const_die, DW_AT_external, 1);
if (DECL_ARTIFICIAL (decl))
decl_die = new_die (DW_TAG_member, context_die, decl);
add_name_and_src_coords_attributes (decl_die, decl);
add_type_attribute (decl_die, member_declared_type (decl),
- TREE_READONLY (decl), TREE_THIS_VOLATILE (decl),
- context_die);
+ decl_quals (decl), context_die);
if (DECL_BIT_FIELD_TYPE (decl))
{
= new_die (DW_TAG_pointer_type, scope_die_for (type, context_die), type);
equate_type_number_to_die (type, ptr_die);
- add_type_attribute (ptr_die, TREE_TYPE (type), 0, 0, context_die);
+ add_type_attribute (ptr_die, TREE_TYPE (type), TYPE_UNQUALIFIED,
+ context_die);
add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
}
ref_die = new_die (DW_TAG_reference_type, scope_die, type);
equate_type_number_to_die (type, ref_die);
- add_type_attribute (ref_die, TREE_TYPE (type), 0, 0, context_die);
+ add_type_attribute (ref_die, TREE_TYPE (type), TYPE_UNQUALIFIED,
+ context_die);
add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
}
#endif
equate_type_number_to_die (type, ptr_die);
add_AT_die_ref (ptr_die, DW_AT_containing_type,
lookup_type_die (TYPE_OFFSET_BASETYPE (type)));
- add_type_attribute (ptr_die, TREE_TYPE (type), 0, 0, context_die);
+ add_type_attribute (ptr_die, TREE_TYPE (type), TYPE_UNQUALIFIED,
+ context_die);
}
typedef const char *dchar_p; /* For DEF_VEC_P. */
{
dw_die_ref die = new_die (DW_TAG_inheritance, context_die, binfo);
- add_type_attribute (die, BINFO_TYPE (binfo), 0, 0, context_die);
+ add_type_attribute (die, BINFO_TYPE (binfo), TYPE_UNQUALIFIED, context_die);
add_data_member_location_attribute (die, binfo);
if (BINFO_VIRTUAL_P (binfo))
equate_type_number_to_die (type, subr_die);
add_prototyped_attribute (subr_die, type);
- add_type_attribute (subr_die, return_type, 0, 0, context_die);
+ add_type_attribute (subr_die, return_type, TYPE_UNQUALIFIED, context_die);
gen_formal_types_die (type, subr_die);
if (get_AT (subr_die, DW_AT_name))
}
}
- add_type_attribute (type_die, type, TREE_READONLY (decl),
- TREE_THIS_VOLATILE (decl), context_die);
+ add_type_attribute (type_die, type, decl_quals (decl), context_die);
if (is_naming_typedef_decl (decl))
/* We want that all subsequent calls to lookup_type_die with
{
dw_die_ref context_die = get_context_die (TYPE_CONTEXT (type));
- type_die = modified_type_die (type, TYPE_READONLY (type),
- TYPE_VOLATILE (type), context_die);
+ type_die = modified_type_die (type, TYPE_QUALS_NO_ADDR_SPACE (type),
+ context_die);
gcc_assert (type_die);
}
return type_die;