cplus-dem.c (work_stuff): Replace const_type and volatile_type with type_quals.

* cplus-dem.c (work_stuff): Replace const_type and volatile_type
	with type_quals.
	(TYPE_UNQUALIFIED): New macro.
	(TYPE_QUAL_CONST): Likewise.
	(TYPE_QUAL_VOLATILE): Likewise.
	(TYPE_QUAL_RESTRICT): Likewise.
	(code_for_qualifier): New function.
	(qualifier_string): Likewise.
	(demangle_qualifier): Likewise.
	(internal_cplus_demangle): Use them.
	(demangle_signature): Likewise.
	(demangle_template_value_parm): Likewise.
	(do_type): Likewise.
	(demangle_fund_type)): Likewise.
	* Makefile.in (hash.h): Run gperf when necessary.
	* cp-tree.h (CP_TYPE_READONLY): Remove.
	(CP_TYPE_VOLATILE): Likewise.
	(CP_TYPE_QUALS): New macro.
	(CP_TYPE_CONST_P): Likewise.
	(CP_TYPE_VOLATILE_P): Likewise.
	(CP_TYPE_RESTRICT_P): Likewise.
	(CP_TYPE_CONST_NON_VOLATILE_P): Likewise.
	(cp_build_type_variant): Rename to ...
	(cp_build_qualified_type): New function.
	(c_apply_type_quals_to_decl): Declare.
	(SIGNATURE_POINTER_NAME_FORMAT): Modify to allow `restrict'.
	(SIGNATURE_REFERENCE_NAME_FORMAT): Likewise.
	(cp_type_qual_from_rid): New function.
	(compparms): Remove unused parameter.  All callers changed.
	(cp_type_quals): New function.
	(at_least_as_qualified_p): Likewise.
	(more_qualified_p): Likewise.
	* call.c (standard_conversion): Replace calls to
	cp_build_type_variant with cp_build_qualified_type.  Use
	CP_TYPE_QUALS to get qualifiers and at_least_as_qualified_p to
	compare them.  Use CP_TYPE_* macros to check qualifiers.
	(reference_binding): Likewise.
	(implicit_conversion): Likewise.
	(add_builtin_candidates): Likewise.
	(build_over_call): Likewise.
	* class.c (overrides): Compare all qualifiers, not just `const',
	on method declarations.
	* cvt.c (convert_to_reference): More CP_TYPE_QUALS conversion, etc.
	(convert_pointer_to_real): Likewise.
	(type_promotes_to): Likewise.
	* decl.c (check_for_uninitialized_const_var): New function.
	(init_decl_processing): More CP_TYPE_QUALS conversion, etc.
	(cp_finish_decl): Use check_for_uninitialized_const_var.
	(grokdeclarator): More CP_TYPE_QUALS conversion, etc.  Update to
	handle `restrict'.
	(grok_ctor_properties): Likewise.
	(grok_op_properties): Likewise.
	(start_function): Likewise.
	(rever_static_member_fn): Likewise.
	* decl2.c (grok_method_quals): Likewise.
	(grokfield): Likewise.
	* error.c (dump_readonly_or_volatile): Rename to ...
	(dump_qualifiers): New function.  Handle `restrict'.
	(dump_type_real): Use it.
	(dump_aggr_type): Likewise.
	(dump_type_prefix): Likewise.
	(dump_type_suffix): Likewise.
	(dump_function_decl): Likewise.
	(cv_as_string): Likewise.
	* gxx.gperf: Add __restrict and __restrict__.
	* gxxint.texi: Document `u' as used for `__restrict', and a few
	other previously undocumented codes.
	* hash.h: Regenerated.
	* init.c (expand_aggr_init): More CP_TYPE_QUALS conversion, etc.
	(build_member_call): Likewise.
	(build_new_1): Likewise.
	* lex.c (init_parse): Add entry for RID_RESTRICT.
	(cons_up_default_function): More CP_TYPE_QUALS conversion, etc.
	(cp_type_qual_from_rid): Define.
	* lex.h (enum rid): Add RID_RESTRICT.
	* method.c (process_modifiers): Deal with `restrict'.
	* parse.y (primary): More CP_TYPE_QUALS conversion, etc.
	* parse.c: Regenerated.
	* pt.c (convert_nontype_argument): More CP_TYPE_QUALS conversion, etc.
	(tsubst_aggr_type): Likewise.
	(tsubst): Likewise.
	(check_cv_quals_for_unify): Likewise.
	(unify): Likewise.
	* rtti.c (init_rtti_processing): Likewise.
	(build_headof): Likewise.
	(get_tinfo_var): Likewise.
	(buidl_dynamic_cast_1): Likewise.  Fix `volatile' handling.
	(expand_class_desc): Likewise.
	(expand_attr_desc): Likewise.
	(synthesize_tinfo_fn): Likewise.
	* search.c (covariant_return_p): Likewise.  Fix `volatile' handling.
	(get_matching_virtual): Likewise.
	(expand_upcast_fixups): Likewise.
	* sig.c (build_signature_pointer_or_reference_name): Take
	type_quals, not constp and volatilep.
	(build_signature_pointer_or_reference_type): Likewise.
	(match_method_types): More CP_TYPE_QUALS conversion, etc.
	(build_signature_pointer_constructor): Likewise.
	(build_signature_method_call): Likewise.
	* tree.c (build_cplus_array_type): Likewise.
	(cp_build_type_variant): Rename to ...
	(cp_build_qualified_type): New function.  Deal with `__restrict'.
	(canonical_type_variant): More CP_TYPE_QUALS conversion, etc.
	(build_exception_variant): Likewise.
	(mapcar): Likewise.
	* typeck.c (qualif_type): Likewise.
	(common_type): Likewise.
	(comptypes): Likewise.
	(comp_cv_target_types): Likewise.
	(at_least_as_qualified_p): Define.
	(more_qualified_p): Likewise.
	(comp_cv_qualification): More CP_TYPE_QUALS conversion, etc.
	(compparms): Likewise.
	(inline_conversion): Likewise.
	(string_conv_p): Likewise.
	(build_component_ref): Likewise.
	(build_indirect_ref): Likewise.
	(build_array_ref): Likewise.
	(build_unary_op): Likewise.
	(build_conditional_expr): Likewise.
	(build_static_cast): Likewise.
	(build_c_cast): Likewise.
	(build_modify_expr): Likewise.
	(convert_For_assignment): Likewise.
	(comp_ptr_ttypes_real): Likewise.
	(cp_type_quals): New function.

From-SVN: r23258
This commit is contained in:
Mark Mitchell 1998-10-23 14:53:28 +00:00 committed by Mark Mitchell
parent 7b16da78b1
commit 91063b5138
30 changed files with 4718 additions and 4457 deletions

View File

@ -1,3 +1,120 @@
1998-10-23 Mark Mitchell <mark@markmitchell.com>
* Makefile.in (hash.h): Run gperf when necessary.
* cp-tree.h (CP_TYPE_READONLY): Remove.
(CP_TYPE_VOLATILE): Likewise.
(CP_TYPE_QUALS): New macro.
(CP_TYPE_CONST_P): Likewise.
(CP_TYPE_VOLATILE_P): Likewise.
(CP_TYPE_RESTRICT_P): Likewise.
(CP_TYPE_CONST_NON_VOLATILE_P): Likewise.
(cp_build_type_variant): Rename to ...
(cp_build_qualified_type): New function.
(c_apply_type_quals_to_decl): Declare.
(SIGNATURE_POINTER_NAME_FORMAT): Modify to allow `restrict'.
(SIGNATURE_REFERENCE_NAME_FORMAT): Likewise.
(cp_type_qual_from_rid): New function.
(compparms): Remove unused parameter. All callers changed.
(cp_type_quals): New function.
(at_least_as_qualified_p): Likewise.
(more_qualified_p): Likewise.
* call.c (standard_conversion): Replace calls to
cp_build_type_variant with cp_build_qualified_type. Use
CP_TYPE_QUALS to get qualifiers and at_least_as_qualified_p to
compare them. Use CP_TYPE_* macros to check qualifiers.
(reference_binding): Likewise.
(implicit_conversion): Likewise.
(add_builtin_candidates): Likewise.
(build_over_call): Likewise.
* class.c (overrides): Compare all qualifiers, not just `const',
on method declarations.
* cvt.c (convert_to_reference): More CP_TYPE_QUALS conversion, etc.
(convert_pointer_to_real): Likewise.
(type_promotes_to): Likewise.
* decl.c (check_for_uninitialized_const_var): New function.
(init_decl_processing): More CP_TYPE_QUALS conversion, etc.
(cp_finish_decl): Use check_for_uninitialized_const_var.
(grokdeclarator): More CP_TYPE_QUALS conversion, etc. Update to
handle `restrict'.
(grok_ctor_properties): Likewise.
(grok_op_properties): Likewise.
(start_function): Likewise.
(rever_static_member_fn): Likewise.
* decl2.c (grok_method_quals): Likewise.
(grokfield): Likewise.
* error.c (dump_readonly_or_volatile): Rename to ...
(dump_qualifiers): New function. Handle `restrict'.
(dump_type_real): Use it.
(dump_aggr_type): Likewise.
(dump_type_prefix): Likewise.
(dump_type_suffix): Likewise.
(dump_function_decl): Likewise.
(cv_as_string): Likewise.
* gxx.gperf: Add __restrict and __restrict__.
* gxxint.texi: Document `u' as used for `__restrict', and a few
other previously undocumented codes.
* hash.h: Regenerated.
* init.c (expand_aggr_init): More CP_TYPE_QUALS conversion, etc.
(build_member_call): Likewise.
(build_new_1): Likewise.
* lex.c (init_parse): Add entry for RID_RESTRICT.
(cons_up_default_function): More CP_TYPE_QUALS conversion, etc.
(cp_type_qual_from_rid): Define.
* lex.h (enum rid): Add RID_RESTRICT.
* method.c (process_modifiers): Deal with `restrict'.
* parse.y (primary): More CP_TYPE_QUALS conversion, etc.
* parse.c: Regenerated.
* pt.c (convert_nontype_argument): More CP_TYPE_QUALS conversion, etc.
(tsubst_aggr_type): Likewise.
(tsubst): Likewise.
(check_cv_quals_for_unify): Likewise.
(unify): Likewise.
* rtti.c (init_rtti_processing): Likewise.
(build_headof): Likewise.
(get_tinfo_var): Likewise.
(buidl_dynamic_cast_1): Likewise. Fix `volatile' handling.
(expand_class_desc): Likewise.
(expand_attr_desc): Likewise.
(synthesize_tinfo_fn): Likewise.
* search.c (covariant_return_p): Likewise. Fix `volatile' handling.
(get_matching_virtual): Likewise.
(expand_upcast_fixups): Likewise.
* sig.c (build_signature_pointer_or_reference_name): Take
type_quals, not constp and volatilep.
(build_signature_pointer_or_reference_type): Likewise.
(match_method_types): More CP_TYPE_QUALS conversion, etc.
(build_signature_pointer_constructor): Likewise.
(build_signature_method_call): Likewise.
* tree.c (build_cplus_array_type): Likewise.
(cp_build_type_variant): Rename to ...
(cp_build_qualified_type): New function. Deal with `__restrict'.
(canonical_type_variant): More CP_TYPE_QUALS conversion, etc.
(build_exception_variant): Likewise.
(mapcar): Likewise.
* typeck.c (qualif_type): Likewise.
(common_type): Likewise.
(comptypes): Likewise.
(comp_cv_target_types): Likewise.
(at_least_as_qualified_p): Define.
(more_qualified_p): Likewise.
(comp_cv_qualification): More CP_TYPE_QUALS conversion, etc.
(compparms): Likewise.
(inline_conversion): Likewise.
(string_conv_p): Likewise.
(build_component_ref): Likewise.
(build_indirect_ref): Likewise.
(build_array_ref): Likewise.
(build_unary_op): Likewise.
(build_conditional_expr): Likewise.
(build_static_cast): Likewise.
(build_c_cast): Likewise.
(build_modify_expr): Likewise.
(convert_For_assignment): Likewise.
(comp_ptr_ttypes_real): Likewise.
(cp_type_quals): New function.
1998-10-23 Jason Merrill <jason@yorick.cygnus.com>
* cp-tree.h (CP_TYPE_READONLY): New macro to handle arrays.

View File

@ -235,11 +235,10 @@ $(PARSE_C) : $(srcdir)/parse.y
# cp $(PARSE_C) y.tab.c
# touch stamp-parse
# hash.h really depends on $(srcdir)/gxx.gperf.
# But this would screw things for people that don't have gperf,
# if gxx.gpref got touched, say.
# Thus you have to remove hash.h to force it to be re-made.
$(srcdir)/hash.h:
# We used to try to protect people from having to rerun gperf. But,
# the C front-end already requires this if c-parse.gperf is changed,
# so we should be consistent.
$(srcdir)/hash.h: $(srcdir)/gxx.gperf
gperf -L KR-C -F ', 0, 0' -p -j1 -g -o -t -N is_reserved_word \
'-k1,4,7,$$' $(srcdir)/gxx.gperf >$(srcdir)/hash.h

View File

@ -843,9 +843,8 @@ standard_conversion (to, from, expr)
&& ufcode != FUNCTION_TYPE)
{
from = build_pointer_type
(cp_build_type_variant (void_type_node,
TYPE_READONLY (TREE_TYPE (from)),
TYPE_VOLATILE (TREE_TYPE (from))));
(cp_build_qualified_type (void_type_node,
CP_TYPE_QUALS (TREE_TYPE (from))));
conv = build_conv (PTR_CONV, from, conv);
}
else if (ufcode == OFFSET_TYPE && utcode == OFFSET_TYPE)
@ -868,9 +867,9 @@ standard_conversion (to, from, expr)
{
if (DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
{
from = cp_build_type_variant (TREE_TYPE (to),
TYPE_READONLY (TREE_TYPE (from)),
TYPE_VOLATILE (TREE_TYPE (from)));
from =
cp_build_qualified_type (TREE_TYPE (to),
CP_TYPE_QUALS (TREE_TYPE (from)));
from = build_pointer_type (from);
conv = build_conv (PTR_CONV, from, conv);
}
@ -903,13 +902,11 @@ standard_conversion (to, from, expr)
if (! DERIVED_FROM_P (fbase, tbase)
|| ! comptypes (TREE_TYPE (fromfn), TREE_TYPE (tofn), 1)
|| ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)),
TREE_CHAIN (TYPE_ARG_TYPES (tofn)), 1)
|| TYPE_READONLY (fbase) != TYPE_READONLY (tbase)
|| TYPE_VOLATILE (fbase) != TYPE_VOLATILE (tbase))
TREE_CHAIN (TYPE_ARG_TYPES (tofn)))
|| CP_TYPE_QUALS (fbase) != CP_TYPE_QUALS (tbase))
return 0;
from = cp_build_type_variant (tbase, TYPE_READONLY (fbase),
TYPE_VOLATILE (fbase));
from = cp_build_qualified_type (tbase, CP_TYPE_QUALS (fbase));
from = build_cplus_method_type (from, TREE_TYPE (fromfn),
TREE_CHAIN (TYPE_ARG_TYPES (fromfn)));
from = build_ptrmemfunc_type (build_pointer_type (from));
@ -981,9 +978,7 @@ reference_binding (rto, rfrom, expr, flags)
|| (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from)
&& DERIVED_FROM_P (to, from)));
if (lvalue && related
&& TYPE_READONLY (to) >= TYPE_READONLY (from)
&& TYPE_VOLATILE (to) >= TYPE_VOLATILE (from))
if (lvalue && related && at_least_as_qualified_p (to, from))
{
conv = build1 (IDENTITY_CONV, from, expr);
@ -1012,14 +1007,12 @@ reference_binding (rto, rfrom, expr, flags)
TREE_OPERAND (conv, 0) = TREE_OPERAND (TREE_OPERAND (conv, 0), 0);
}
if (conv
&& ((! (TYPE_READONLY (to) && ! TYPE_VOLATILE (to)
&& ((! (CP_TYPE_CONST_NON_VOLATILE_P (to)
&& (flags & LOOKUP_NO_TEMP_BIND) == 0))
/* If T1 is reference-related to T2, cv1 must be the same
cv-qualification as, or greater cv-qualification than,
cv2; otherwise, the program is ill-formed. */
|| (related
&& (TYPE_READONLY (to) < TYPE_READONLY (from)
|| TYPE_VOLATILE (to) < TYPE_VOLATILE (from)))))
|| (related && !at_least_as_qualified_p (to, from))))
ICS_BAD_FLAG (conv) = 1;
}
@ -1071,8 +1064,7 @@ implicit_conversion (to, from, expr, flags)
(TYPE_MAIN_VARIANT (TREE_TYPE (to)), expr, LOOKUP_ONLYCONVERTING);
if (cand)
{
if (! TYPE_READONLY (TREE_TYPE (to))
|| TYPE_VOLATILE (TREE_TYPE (to)))
if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (to)))
ICS_BAD_FLAG (cand->second_conv) = 1;
if (!conv || (ICS_BAD_FLAG (conv)
> ICS_BAD_FLAG (cand->second_conv)))
@ -1823,7 +1815,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags)
if (i == 0 && ref1
&& (TREE_CODE (type) != REFERENCE_TYPE
|| TYPE_READONLY (TREE_TYPE (type))))
|| CP_TYPE_CONST_P (TREE_TYPE (type))))
continue;
if (code == COND_EXPR && TREE_CODE (type) == REFERENCE_TYPE)
@ -3223,17 +3215,9 @@ build_over_call (cand, args, flags)
tree argtype = TREE_TYPE (TREE_VALUE (arg));
tree t;
if (ICS_BAD_FLAG (TREE_VEC_ELT (convs, i)))
{
int dv = (TYPE_VOLATILE (TREE_TYPE (parmtype))
< TYPE_VOLATILE (TREE_TYPE (argtype)));
int dc = (TYPE_READONLY (TREE_TYPE (parmtype))
< TYPE_READONLY (TREE_TYPE (argtype)));
char *p = (dv && dc ? "const and volatile"
: dc ? "const" : dv ? "volatile" : "");
cp_error ("passing `%T' as `this' argument of `%#D' discards qualifiers",
TREE_TYPE (argtype), fn);
cp_error ("passing `%T' as `this' argument of `%#D' discards %s",
TREE_TYPE (argtype), fn, p);
}
/* [class.mfct.nonstatic]: If a nonstatic member function of a class
X is called for an object that is not of type X, or of a type
derived from X, the behavior is undefined.

View File

@ -2387,9 +2387,9 @@ overrides (fndecl, base_fndecl)
#endif
types = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl));
if ((TYPE_READONLY (TREE_TYPE (TREE_VALUE (base_types)))
== TYPE_READONLY (TREE_TYPE (TREE_VALUE (types))))
&& compparms (TREE_CHAIN (base_types), TREE_CHAIN (types), 3))
if ((TYPE_QUALS (TREE_TYPE (TREE_VALUE (base_types)))
== TYPE_QUALS (TREE_TYPE (TREE_VALUE (types))))
&& compparms (TREE_CHAIN (base_types), TREE_CHAIN (types)))
return 1;
}
return 0;

View File

@ -514,15 +514,6 @@ enum languages { lang_c, lang_cplusplus, lang_java };
/* The _DECL for this _TYPE. */
#define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE)))
#define CP_TYPE_READONLY(NODE) \
(TREE_CODE (NODE) == ARRAY_TYPE \
? TYPE_READONLY (TREE_TYPE (NODE)) \
: TYPE_READONLY (NODE))
#define CP_TYPE_VOLATILE(NODE) \
(TREE_CODE (NODE) == ARRAY_TYPE \
? TYPE_VOLATILE (TREE_TYPE (NODE)) \
: TYPE_VOLATILE (NODE))
/* Nonzero if T is a class (or struct or union) type. Also nonzero
for template type parameters and typename types. Despite its name,
this macro has nothing to do with the definition of aggregate given
@ -547,6 +538,33 @@ enum languages { lang_c, lang_cplusplus, lang_java };
/* True if this a "Java" type, defined in 'extern "Java"'. */
#define TYPE_FOR_JAVA(NODE) TYPE_LANG_FLAG_3(NODE)
/* The type qualifiers for this type, including the qualifiers on the
elements for an array type. */
#define CP_TYPE_QUALS(NODE) \
((TREE_CODE (NODE) != ARRAY_TYPE) \
? TYPE_QUALS (NODE) : cp_type_quals (NODE))
/* Nonzero if this type is const-qualified. */
#define CP_TYPE_CONST_P(NODE) \
(CP_TYPE_QUALS (NODE) & TYPE_QUAL_CONST)
/* Nonzero if this type is volatile-qualified. */
#define CP_TYPE_VOLATILE_P(NODE) \
(CP_TYPE_QUALS (NODE) & TYPE_QUAL_VOLATILE)
/* Nonzero if this type is restrict-qualified.
FIXME: Does this make sense? */
#define CP_TYPE_RESTRICT_P(NODE) \
(CP_TYPE_QUALS (NODE) & TYPE_QUAL_RESTRICT)
/* Nonzero if this type is const-qualified, but not
volatile-qualified. Other qualifiers are ignored. This macro is
used to test whether or not it is OK to bind an rvalue to a
reference. */
#define CP_TYPE_CONST_NON_VOLATILE_P(NODE) \
((CP_TYPE_QUALS (NODE) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) \
== TYPE_QUAL_CONST)
#define DELTA_FROM_VTABLE_ENTRY(ENTRY) \
(!flag_vtable_thunks ? \
TREE_VALUE (CONSTRUCTOR_ELTS (ENTRY)) \
@ -1882,7 +1900,7 @@ extern void check_function_format PROTO((tree, tree, tree));
/* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error PROTO((enum tree_code));
extern tree cp_build_type_variant PROTO((tree, int, int));
extern tree cp_build_qualified_type PROTO((tree, int));
extern tree canonical_type_variant PROTO((tree));
extern void c_expand_expr_stmt PROTO((tree));
/* Validate the expression after `case' and apply default promotions. */
@ -1893,6 +1911,7 @@ extern void constant_expression_warning PROTO((tree));
extern tree convert_and_check PROTO((tree, tree));
extern void overflow_warning PROTO((tree));
extern void unsigned_conversion_warning PROTO((tree, tree));
extern void c_apply_type_quals_to_decl PROTO((int, tree));
/* Read the rest of the current #-directive line. */
#if USE_CPPLIB
@ -2161,9 +2180,9 @@ extern int current_function_parms_stored;
#define SIGNATURE_OPTR_NAME "__optr"
#define SIGNATURE_SPTR_NAME "__sptr"
#define SIGNATURE_POINTER_NAME "__sp_"
#define SIGNATURE_POINTER_NAME_FORMAT "__%s%ssp_%s"
#define SIGNATURE_POINTER_NAME_FORMAT "__%s%s%ssp_%s"
#define SIGNATURE_REFERENCE_NAME "__sr_"
#define SIGNATURE_REFERENCE_NAME_FORMAT "__%s%ssr_%s"
#define SIGNATURE_REFERENCE_NAME_FORMAT "__%s%s%ssr_%s"
#define SIGTABLE_PTR_TYPE "__sigtbl_ptr_type"
#define SIGTABLE_NAME_FORMAT "__st_%s_%s"
@ -2815,6 +2834,7 @@ extern void add_defarg_fn PROTO((tree));
extern void do_pending_defargs PROTO((void));
extern int identifier_type PROTO((tree));
extern void yyhook PROTO((int));
extern int cp_type_qual_from_rid PROTO((tree));
/* in method.c */
extern void init_method PROTO((void));
@ -3122,7 +3142,7 @@ extern tree common_type PROTO((tree, tree));
extern int compexcepttypes PROTO((tree, tree));
extern int comptypes PROTO((tree, tree, int));
extern int comp_target_types PROTO((tree, tree, int));
extern int compparms PROTO((tree, tree, int));
extern int compparms PROTO((tree, tree));
extern int comp_target_types PROTO((tree, tree, int));
extern int comp_cv_qualification PROTO((tree, tree));
extern int comp_cv_qual_signature PROTO((tree, tree));
@ -3176,6 +3196,9 @@ extern tree c_expand_start_case PROTO((tree));
extern int comp_ptr_ttypes PROTO((tree, tree));
extern int ptr_reasonably_similar PROTO((tree, tree));
extern tree build_ptrmemfunc PROTO((tree, tree, int));
extern int cp_type_quals PROTO((tree));
extern int at_least_as_qualified_p PROTO((tree, tree));
extern int more_qualified_p PROTO((tree, tree));
/* in typeck2.c */
extern tree error_not_base_type PROTO((tree, tree));

View File

@ -444,13 +444,13 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
initialize a reference, then the reference must be to a
non-volatile const type. */
if (! real_lvalue_p (expr)
&& (!TYPE_READONLY (ttl) || TYPE_VOLATILE (ttl)))
&& !CP_TYPE_CONST_NON_VOLATILE_P (ttl))
{
char* msg;
if (TYPE_VOLATILE (ttl) && decl)
if (CP_TYPE_VOLATILE_P (ttl) && decl)
msg = "initialization of volatile reference type `%#T'";
else if (TYPE_VOLATILE (ttl))
else if (CP_TYPE_VOLATILE_P (ttl))
msg = "conversion to volatile reference type `%#T'";
else if (decl)
msg = "initialization of non-const reference type `%#T'";
@ -460,15 +460,10 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
cp_error (msg, reftype);
cp_error ("from rvalue of type `%T'", intype);
}
else if (! (convtype & CONV_CONST))
{
if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
cp_error ("conversion from `%T' to `%T' discards const",
ttr, reftype);
else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
cp_error ("conversion from `%T' to `%T' discards volatile",
ttr, reftype);
}
else if (! (convtype & CONV_CONST)
&& !at_least_as_qualified_p (ttl, ttr))
cp_error ("conversion from `%T' to `%T' discards qualifiers",
ttr, reftype);
}
return build_up_reference (reftype, expr, flags);
@ -502,7 +497,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl)
return error_mark_node;
rval = build_up_reference (reftype, rval, flags);
if (rval && ! TYPE_READONLY (TREE_TYPE (reftype)))
if (rval && ! CP_TYPE_CONST_P (TREE_TYPE (reftype)))
cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary",
reftype, intype);
}
@ -570,8 +565,8 @@ convert_pointer_to_real (binfo, expr)
binfo = NULL_TREE;
}
ptr_type = cp_build_type_variant (type, TYPE_READONLY (TREE_TYPE (intype)),
TYPE_VOLATILE (TREE_TYPE (intype)));
ptr_type = cp_build_qualified_type (type,
CP_TYPE_QUALS (TREE_TYPE (intype)));
ptr_type = build_pointer_type (ptr_type);
if (ptr_type == TYPE_MAIN_VARIANT (intype))
return expr;
@ -1059,13 +1054,12 @@ tree
type_promotes_to (type)
tree type;
{
int constp, volatilep;
int type_quals;
if (type == error_mark_node)
return error_mark_node;
constp = TYPE_READONLY (type);
volatilep = TYPE_VOLATILE (type);
type_quals = CP_TYPE_QUALS (type);
type = TYPE_MAIN_VARIANT (type);
/* bool always promotes to int (not unsigned), even if it's the same
@ -1099,7 +1093,7 @@ type_promotes_to (type)
else if (type == float_type_node)
type = double_type_node;
return cp_build_type_variant (type, constp, volatilep);
return cp_build_qualified_type (type, type_quals);
}
/* The routines below this point are carefully written to conform to

View File

@ -177,6 +177,7 @@ static void bad_specifiers PROTO((tree, char *, int, int, int, int,
int));
static void lang_print_error_function PROTO((char *));
static tree maybe_process_template_type_declaration PROTO((tree, int, struct binding_level*));
static void check_for_uninitialized_const_var PROTO((tree));
#if defined (DEBUG_CP_BINDING_LEVELS)
static void indent PROTO((void));
@ -2567,7 +2568,7 @@ decls_match (newdecl, olddecl)
TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
}
else
types_match = compparms (p1, p2, 3);
types_match = compparms (p1, p2);
}
else
types_match = 0;
@ -2769,7 +2770,7 @@ duplicate_decls (newdecl, olddecl)
else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL
&& TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
&& compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))),
TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))), 3)
TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))))
&& comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
DECL_TEMPLATE_PARMS (olddecl)))
{
@ -2788,7 +2789,7 @@ duplicate_decls (newdecl, olddecl)
cp_error_at ("previous declaration `%#D' here", olddecl);
}
else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 3))
TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
{
cp_error ("new declaration `%#D'", newdecl);
cp_error_at ("ambiguates old declaration `%#D'", olddecl);
@ -5840,7 +5841,8 @@ init_decl_processing ()
string_type_node = build_pointer_type (char_type_node);
const_string_type_node
= build_pointer_type (build_type_variant (char_type_node, 1, 0));
= build_pointer_type (build_qualified_type (char_type_node,
TYPE_QUAL_CONST));
#if 0
record_builtin_type (RID_MAX, NULL_PTR, string_type_node);
#endif
@ -5870,7 +5872,8 @@ init_decl_processing ()
ptr_type_node = build_pointer_type (void_type_node);
const_ptr_type_node
= build_pointer_type (build_type_variant (void_type_node, 1, 0));
= build_pointer_type (build_qualified_type (void_type_node,
TYPE_QUAL_CONST));
#if 0
record_builtin_type (RID_MAX, NULL_PTR, ptr_type_node);
#endif
@ -6199,14 +6202,15 @@ init_decl_processing ()
DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node);
TREE_UNSIGNED (fields[3]) = 0;
TREE_CHAIN (fields[2]) = fields[3];
vtable_entry_type = build_type_variant (vtable_entry_type, 1, 0);
vtable_entry_type = build_qualified_type (vtable_entry_type,
TYPE_QUAL_CONST);
}
record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type);
vtbl_type_node
= build_array_type (vtable_entry_type, NULL_TREE);
layout_type (vtbl_type_node);
vtbl_type_node = cp_build_type_variant (vtbl_type_node, 1, 0);
vtbl_type_node = build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST);
record_builtin_type (RID_MAX, NULL_PTR, vtbl_type_node);
vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
layout_type (vtbl_ptr_type_node);
@ -6245,7 +6249,8 @@ init_decl_processing ()
TREE_UNSIGNED (fields[5]) = 0;
TREE_CHAIN (fields[4]) = fields[5];
sigtable_entry_type = build_type_variant (sigtable_entry_type, 1, 0);
sigtable_entry_type = build_qualified_type (sigtable_entry_type,
TYPE_QUAL_CONST);
record_builtin_type (RID_MAX, SIGTABLE_PTR_TYPE, sigtable_entry_type);
}
@ -7000,6 +7005,25 @@ obscure_complex_init (decl, init)
return init;
}
/* Issue an error message if DECL is an uninitialized const variable. */
static void
check_for_uninitialized_const_var (decl)
tree decl;
{
tree type = TREE_TYPE (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
&& TREE_CODE (type) != REFERENCE_TYPE
&& CP_TYPE_CONST_P (type)
&& !TYPE_NEEDS_CONSTRUCTING (type)
&& !DECL_INITIAL (decl))
cp_error ("uninitialized const `%D'", decl);
}
/* Finish processing of a declaration;
install its line number and initial value.
If the length of an array type is not known before,
@ -7241,32 +7265,16 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags)
decl);
}
if (TREE_CODE (decl) == VAR_DECL
&& !DECL_INITIAL (decl)
&& !TYPE_NEEDS_CONSTRUCTING (type)
&& (TYPE_READONLY (type) || TREE_READONLY (decl)))
cp_error ("uninitialized const `%D'", decl);
check_for_uninitialized_const_var (decl);
if (TYPE_SIZE (type) != NULL_TREE
&& TYPE_NEEDS_CONSTRUCTING (type))
init = obscure_complex_init (decl, NULL_TREE);
}
else if (TREE_CODE (decl) == VAR_DECL
&& TREE_CODE (type) != REFERENCE_TYPE
&& (TYPE_READONLY (type) || TREE_READONLY (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
However, if it's `const int foo = 1; const int foo;', don't complain
about the second decl, since it does have an initializer before.
We deliberately don't complain about arrays, because they're
supposed to be initialized by a constructor. */
if (! DECL_INITIAL (decl)
&& TREE_CODE (type) != ARRAY_TYPE
&& (!pedantic || !current_class_type))
cp_error ("uninitialized const `%#D'", decl);
}
}
else
check_for_uninitialized_const_var (decl);
/* For top-level declaration, the initial value was read in
the temporary obstack. MAXINDEX, rtl, etc. to be made below
must go in the permanent obstack; but don't discard the
@ -8503,7 +8511,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
tree type = NULL_TREE;
int longlong = 0;
int constp;
int restrictp;
int volatilep;
int type_quals;
int virtualp, explicitp, friendp, inlinep, staticp;
int explicit_int = 0;
int explicit_char = 0;
@ -9065,8 +9075,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
&& TYPE_MAIN_VARIANT (type) == double_type_node)
{
RIDBIT_RESET (RID_LONG, specbits);
type = build_type_variant (long_double_type_node, TYPE_READONLY (type),
TYPE_VOLATILE (type));
type = build_qualified_type (long_double_type_node,
CP_TYPE_QUALS (type));
}
/* Check all other uses of type modifiers. */
@ -9188,17 +9198,24 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (return_type == return_conversion
&& (RIDBIT_SETP (RID_CONST, specbits)
|| RIDBIT_SETP (RID_VOLATILE, specbits)))
cp_error ("`operator %T' cannot be cv-qualified",
|| RIDBIT_SETP (RID_VOLATILE, specbits)
|| RIDBIT_SETP (RID_RESTRICT, specbits)))
cp_error ("qualifiers are not allowed on declaration of `operator %T'",
ctor_return_type);
/* Set CONSTP if this declaration is `const', whether by
explicit specification or via a typedef.
Likewise for VOLATILEP. */
constp = !!RIDBIT_SETP (RID_CONST, specbits) + CP_TYPE_READONLY (type);
volatilep = !!RIDBIT_SETP (RID_VOLATILE, specbits) + CP_TYPE_VOLATILE (type);
type = cp_build_type_variant (type, constp, volatilep);
constp = !! RIDBIT_SETP (RID_CONST, specbits) + CP_TYPE_CONST_P (type);
restrictp =
!! RIDBIT_SETP (RID_RESTRICT, specbits) + CP_TYPE_RESTRICT_P (type);
volatilep =
!! RIDBIT_SETP (RID_VOLATILE, specbits) + CP_TYPE_VOLATILE_P (type);
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
| (volatilep ? TYPE_QUAL_VOLATILE : 0));
type = cp_build_qualified_type (type, type_quals);
staticp = 0;
inlinep = !! RIDBIT_SETP (RID_INLINE, specbits);
virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits);
@ -9275,16 +9292,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
&& IS_SIGNATURE (current_class_type)
&& RIDBIT_NOTSETP (RID_TYPEDEF, specbits))
{
if (constp)
if (type_quals != TYPE_UNQUALIFIED)
{
error ("`const' specified for signature member function `%s'", name);
constp = 0;
}
if (volatilep)
{
error ("`volatile' specified for signature member function `%s'",
name);
volatilep = 0;
error ("type qualifiers specified for signature member function `%s'", name);
type_quals = TYPE_UNQUALIFIED;
}
if (inlinep)
{
@ -9634,9 +9645,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
/* Declaring a function type.
Make sure we have a valid type for the function to return. */
/* We now know that constp and volatilep don't apply to the
/* We now know that the TYPE_QUALS don't apply to the
decl, but to its return type. */
constp = volatilep = 0;
type_quals = TYPE_UNQUALIFIED;
/* Warn about some types functions can't return. */
@ -9844,9 +9855,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
/* Merge any constancy or volatility into the target type
for the pointer. */
/* We now know that constp and volatilep don't apply to the
decl, but to the target of the pointer. */
constp = volatilep = 0;
/* We now know that the TYPE_QUALS don't apply to the decl,
but to the target of the pointer. */
type_quals = TYPE_UNQUALIFIED;
if (IS_SIGNATURE (type))
{
@ -9871,8 +9882,6 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
type);
type = build_signature_pointer_type (type);
}
constp = 0;
volatilep = 0;
}
else if (TREE_CODE (declarator) == ADDR_EXPR)
{
@ -9895,25 +9904,37 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
{
register tree typemodlist;
int erred = 0;
constp = 0;
volatilep = 0;
restrictp = 0;
for (typemodlist = TREE_TYPE (declarator); typemodlist;
typemodlist = TREE_CHAIN (typemodlist))
{
if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_CONST])
tree qualifier = TREE_VALUE (typemodlist);
if (qualifier == ridpointers[(int) RID_CONST])
constp++;
else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_VOLATILE])
else if (qualifier == ridpointers[(int) RID_VOLATILE])
volatilep++;
else if (qualifier == ridpointers[(int) RID_RESTRICT])
restrictp++;
else if (!erred)
{
erred = 1;
error ("invalid type modifier within %s declarator",
TREE_CODE (declarator) == ADDR_EXPR
? "reference" : "pointer");
error ("invalid type modifier within pointer declarator");
}
}
if (constp > 1)
pedwarn ("duplicate `const'");
if (volatilep > 1)
pedwarn ("duplicate `volatile'");
if (restrictp > 1)
pedwarn ("duplicate `restrict'");
type_quals = ((constp ? TYPE_QUAL_CONST : 0)
| (restrictp ? TYPE_QUAL_RESTRICT : 0)
| (volatilep ? TYPE_QUAL_VOLATILE : 0));
if (TREE_CODE (declarator) == ADDR_EXPR
&& (constp || volatilep))
{
@ -9921,9 +9942,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
pedwarn ("discarding `const' applied to a reference");
if (volatilep)
pedwarn ("discarding `volatile' applied to a reference");
constp = volatilep = 0;
type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
}
type = cp_build_type_variant (type, constp, volatilep);
type = cp_build_qualified_type (type, type_quals);
}
declarator = TREE_OPERAND (declarator, 0);
ctype = NULL_TREE;
@ -10131,7 +10152,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
if (RIDBIT_SETP (RID_MUTABLE, specbits))
{
if (constp)
if (type_quals & TYPE_QUAL_CONST)
{
error ("const `%s' cannot be declared `mutable'", name);
RIDBIT_RESET (RID_MUTABLE, specbits);
@ -10268,19 +10289,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
{
/* Note that the grammar rejects storage classes
in typenames, fields or parameters. */
if (constp || volatilep)
if (type_quals != TYPE_UNQUALIFIED)
{
if (IS_SIGNATURE (type))
error ("`const' or `volatile' specified with signature type");
error ("type qualifiers specified for signature type");
type_quals = TYPE_UNQUALIFIED;
}
/* Special case: "friend class foo" looks like a TYPENAME context. */
if (friendp)
{
if (volatilep)
if (type_quals != TYPE_UNQUALIFIED)
{
cp_error ("`volatile' specified for friend class declaration");
volatilep = 0;
cp_error ("type qualifiers specified for friend class declaration");
type_quals = TYPE_UNQUALIFIED;
}
if (inlinep)
{
@ -10360,7 +10382,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
{
/* Transfer const-ness of array into that of type pointed to. */
type = build_pointer_type (TREE_TYPE (type));
volatilep = constp = 0;
type_quals = TYPE_UNQUALIFIED;
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
type = build_pointer_type (type);
@ -10788,14 +10810,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
DECL_THIS_STATIC (decl) = 1;
/* Record constancy and volatility. */
if (constp)
TREE_READONLY (decl) = TREE_CODE (type) != REFERENCE_TYPE;
if (volatilep)
{
TREE_SIDE_EFFECTS (decl) = 1;
TREE_THIS_VOLATILE (decl) = 1;
}
/* FIXME: Disallow `restrict' pointer-to-member declarations. */
c_apply_type_quals_to_decl (type_quals, decl);
return decl;
}
@ -11214,7 +11230,7 @@ grok_ctor_properties (ctype, decl)
|| TREE_PURPOSE (TREE_CHAIN (parmtypes))))
{
TYPE_HAS_INIT_REF (ctype) = 1;
if (TYPE_READONLY (TREE_TYPE (parmtype)))
if (CP_TYPE_CONST_P (TREE_TYPE (parmtype)))
TYPE_HAS_CONST_INIT_REF (ctype) = 1;
}
else if (TYPE_MAIN_VARIANT (parmtype) == ctype
@ -11419,7 +11435,7 @@ grok_op_properties (decl, virtualp, friendp)
{
TYPE_HAS_ASSIGN_REF (current_class_type) = 1;
if (TREE_CODE (parmtype) != REFERENCE_TYPE
|| TYPE_READONLY (TREE_TYPE (parmtype)))
|| CP_TYPE_CONST_P (TREE_TYPE (parmtype)))
TYPE_HAS_CONST_ASSIGN_REF (current_class_type) = 1;
}
}
@ -12436,8 +12452,10 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
TYPE_ARG_TYPES (TREE_TYPE (decl1)));
DECL_RESULT (decl1)
= build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (fntype)));
TREE_READONLY (DECL_RESULT (decl1)) = TYPE_READONLY (TREE_TYPE (fntype));
TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = TYPE_VOLATILE (TREE_TYPE (fntype));
TREE_READONLY (DECL_RESULT (decl1))
= CP_TYPE_CONST_P (TREE_TYPE (fntype));
TREE_THIS_VOLATILE (DECL_RESULT (decl1))
= CP_TYPE_VOLATILE_P (TREE_TYPE (fntype));
}
if (TYPE_LANG_SPECIFIC (TREE_TYPE (fntype))
@ -12621,8 +12639,8 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
{
DECL_RESULT (decl1)
= build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (restype));
TREE_READONLY (DECL_RESULT (decl1)) = TYPE_READONLY (restype);
TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = TYPE_VOLATILE (restype);
TREE_READONLY (DECL_RESULT (decl1)) = CP_TYPE_CONST_P (restype);
TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = CP_TYPE_VOLATILE_P (restype);
}
/* Allocate further tree nodes temporarily during compilation
@ -13864,15 +13882,14 @@ revert_static_member_fn (decl, fn, argtypes)
tree function = fn ? *fn : TREE_TYPE (*decl);
tree args = argtypes ? *argtypes : TYPE_ARG_TYPES (function);
if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (args))))
cp_error ("static member function `%#D' declared const", *decl);
if (TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (args))))
cp_error ("static member function `%#D' declared volatile", *decl);
if (CP_TYPE_QUALS (TREE_TYPE (TREE_VALUE (args)))
!= TYPE_UNQUALIFIED)
cp_error ("static member function `%#D' declared with type qualifiers",
*decl);
args = TREE_CHAIN (args);
tmp = build_function_type (TREE_TYPE (function), args);
tmp = build_type_variant (tmp, TYPE_READONLY (function),
TYPE_VOLATILE (function));
tmp = build_qualified_type (tmp, CP_TYPE_QUALS (function));
tmp = build_exception_variant (tmp,
TYPE_RAISES_EXCEPTIONS (function));
TREE_TYPE (*decl) = tmp;

View File

@ -784,36 +784,27 @@ grok_method_quals (ctype, function, quals)
{
tree fntype = TREE_TYPE (function);
tree raises = TYPE_RAISES_EXCEPTIONS (fntype);
int type_quals = TYPE_UNQUALIFIED;
int dup_quals = TYPE_UNQUALIFIED;
do
{
extern tree ridpointers[];
if (TREE_VALUE (quals) == ridpointers[(int)RID_CONST])
{
if (TYPE_READONLY (ctype))
error ("duplicate `%s' %s",
IDENTIFIER_POINTER (TREE_VALUE (quals)),
(TREE_CODE (function) == FUNCTION_DECL
? "for member function" : "in type declaration"));
ctype = build_type_variant (ctype, 1, TYPE_VOLATILE (ctype));
build_pointer_type (ctype);
}
else if (TREE_VALUE (quals) == ridpointers[(int)RID_VOLATILE])
{
if (TYPE_VOLATILE (ctype))
error ("duplicate `%s' %s",
IDENTIFIER_POINTER (TREE_VALUE (quals)),
(TREE_CODE (function) == FUNCTION_DECL
? "for member function" : "in type declaration"));
ctype = build_type_variant (ctype, TYPE_READONLY (ctype), 1);
build_pointer_type (ctype);
}
int tq = cp_type_qual_from_rid (TREE_VALUE (quals));
if (type_quals & tq)
dup_quals |= tq;
else
my_friendly_abort (20);
type_quals |= tq;
quals = TREE_CHAIN (quals);
}
}
while (quals);
if (dup_quals != TYPE_UNQUALIFIED)
cp_error ("duplicate type qualifiers in %s declaration",
TREE_CODE (function) == FUNCTION_DECL
? "member function" : "type");
ctype = cp_build_qualified_type (ctype, type_quals);
fntype = build_cplus_method_type (ctype, TREE_TYPE (fntype),
(TREE_CODE (fntype) == METHOD_TYPE
? TREE_CHAIN (TYPE_ARG_TYPES (fntype))
@ -1417,7 +1408,7 @@ check_classfn (ctype, function)
if (comptypes (TREE_TYPE (TREE_TYPE (function)),
TREE_TYPE (TREE_TYPE (fndecl)), 1)
&& compparms (p1, p2, 3)
&& compparms (p1, p2)
&& (DECL_TEMPLATE_SPECIALIZATION (function)
== DECL_TEMPLATE_SPECIALIZATION (fndecl))
&& (!DECL_TEMPLATE_SPECIALIZATION (function)
@ -1702,7 +1693,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist)
}
/* Force the compiler to know when an uninitialized static
const member is being used. */
if (TYPE_READONLY (value) && init == 0)
if (CP_TYPE_CONST_P (TREE_TYPE (value)) && init == 0)
TREE_USED (value) = 1;
DECL_INITIAL (value) = init;
DECL_IN_AGGR_P (value) = 1;

View File

@ -102,7 +102,7 @@ static void dump_type_suffix PROTO((tree, int, int));
static void dump_function_name PROTO((tree));
static void dump_expr_list PROTO((tree));
static void dump_global_iord PROTO((tree));
static void dump_readonly_or_volatile PROTO((tree, enum pad));
static void dump_qualifiers PROTO((tree, enum pad));
static void dump_char PROTO((int));
static char *aggr_variety PROTO((tree));
static tree ident_fndecl PROTO((tree));
@ -115,19 +115,46 @@ init_error ()
}
static void
dump_readonly_or_volatile (t, p)
dump_qualifiers (t, p)
tree t;
enum pad p;
{
if (TYPE_READONLY (t) || TYPE_VOLATILE (t))
if (TYPE_QUALS (t))
{
if (p == before) OB_PUTC (' ');
if (TYPE_READONLY (t))
OB_PUTS ("const");
if (TYPE_READONLY (t) && TYPE_VOLATILE (t))
OB_PUTC (' ');
if (TYPE_VOLATILE (t))
OB_PUTS ("volatile");
switch (TYPE_QUALS (t))
{
case TYPE_QUAL_CONST:
OB_PUTS ("const");
break;
case TYPE_QUAL_VOLATILE:
OB_PUTS ("volatile");
break;
case TYPE_QUAL_RESTRICT:
OB_PUTS ("__restrict");
break;
case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
OB_PUTS ("const volatile");
break;
case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
OB_PUTS ("const __restrict");
break;
case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
OB_PUTS ("volatile __restrict");
break;
case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
OB_PUTS ("const volatile __restrict");
break;
default:
my_friendly_abort (0);
}
if (p == after) OB_PUTC (' ');
}
}
@ -197,8 +224,7 @@ dump_type_real (t, v, canonical_name)
if (TYPE_LANG_SPECIFIC (t)
&& (IS_SIGNATURE_POINTER (t) || IS_SIGNATURE_REFERENCE (t)))
{
if (TYPE_READONLY (t) | TYPE_VOLATILE (t))
dump_readonly_or_volatile (t, after);
dump_qualifiers (t, after);
dump_type_real (SIGNATURE_TYPE (t), v, canonical_name);
if (IS_SIGNATURE_POINTER (t))
OB_PUTC ('*');
@ -232,7 +258,7 @@ dump_type_real (t, v, canonical_name)
case BOOLEAN_TYPE:
{
tree type;
dump_readonly_or_volatile (t, after);
dump_qualifiers (t, after);
type = canonical_name ? TYPE_MAIN_VARIANT (t) : t;
if (TYPE_NAME (type) && TYPE_IDENTIFIER (type))
OB_PUTID (TYPE_IDENTIFIER (type));
@ -275,7 +301,7 @@ dump_type_real (t, v, canonical_name)
break;
case TEMPLATE_TYPE_PARM:
dump_readonly_or_volatile (t, after);
dump_qualifiers (t, after);
if (TYPE_IDENTIFIER (t))
OB_PUTID (TYPE_IDENTIFIER (t));
else
@ -343,7 +369,7 @@ dump_aggr_type (t, v, canonical_name)
tree name;
char *variety = aggr_variety (t);
dump_readonly_or_volatile (t, after);
dump_qualifiers (t, after);
if (v > 0)
{
@ -404,13 +430,14 @@ dump_type_prefix (t, v, canonical_name)
switch (TREE_CODE (t))
{
case POINTER_TYPE:
case REFERENCE_TYPE:
{
tree sub = TREE_TYPE (t);
dump_type_prefix (sub, v, canonical_name);
/* A tree for a member pointer looks like pointer to offset,
so let the OFFSET_TYPE case handle it. */
if (TREE_CODE (sub) != OFFSET_TYPE)
if (!TYPE_PTRMEM_P (t))
{
switch (TREE_CODE (sub))
{
@ -425,44 +452,22 @@ dump_type_prefix (t, v, canonical_name)
case POINTER_TYPE:
/* We don't want "char * *" */
if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
if (TYPE_QUALS (sub) == TYPE_UNQUALIFIED)
break;
/* But we do want "char *const *" */
default:
OB_PUTC (' ');
}
OB_PUTC ('*');
dump_readonly_or_volatile (t, none);
if (TREE_CODE (t) == POINTER_TYPE)
OB_PUTC ('*');
else
OB_PUTC ('&');
dump_qualifiers (t, none);
}
}
break;
case REFERENCE_TYPE:
{
tree sub = TREE_TYPE (t);
dump_type_prefix (sub, v, canonical_name);
switch (TREE_CODE (sub))
{
case ARRAY_TYPE:
OB_PUTC2 (' ', '(');
break;
case POINTER_TYPE:
/* We don't want "char * &" */
if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub)))
break;
/* But we do want "char *const &" */
default:
OB_PUTC (' ');
}
}
OB_PUTC ('&');
dump_readonly_or_volatile (t, none);
break;
case OFFSET_TYPE:
offset_type:
dump_type_prefix (TREE_TYPE (t), v, canonical_name);
@ -473,7 +478,7 @@ dump_type_prefix (t, v, canonical_name)
OB_PUTC2 (':', ':');
}
OB_PUTC ('*');
dump_readonly_or_volatile (t, none);
dump_qualifiers (t, none);
break;
/* Can only be reached through function pointer -- this would not be
@ -555,7 +560,7 @@ dump_type_suffix (t, v, canonical_name)
OB_PUTS ("...");
OB_PUTC (')');
if (TREE_CODE (t) == METHOD_TYPE)
dump_readonly_or_volatile
dump_qualifiers
(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before);
dump_type_suffix (TREE_TYPE (t), v, canonical_name);
break;
@ -1000,10 +1005,10 @@ dump_function_decl (t, v)
{
if (IS_SIGNATURE (cname))
/* We look at the type pointed to by the `optr' field of `this.' */
dump_readonly_or_volatile
dump_qualifiers
(TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (TYPE_ARG_TYPES (fntype))))), before);
else
dump_readonly_or_volatile
dump_qualifiers
(TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), before);
}
}
@ -1951,7 +1956,7 @@ cv_as_string (p, v)
{
OB_INIT ();
dump_readonly_or_volatile (p, before);
dump_qualifiers (p, before);
OB_FINISH ();

View File

@ -22,6 +22,8 @@ __label__, LABEL, NORID
__null, CONSTANT, RID_NULL
__real, REALPART, NORID
__real__, REALPART, NORID
__restrict, CV_QUALIFIER, RID_RESTRICT
__restrict__, CV_QUALIFIER, RID_RESTRICT
__signature__, AGGR, RID_SIGNATURE /* Extension */,
__signed, TYPESPEC, RID_SIGNED
__signed__, TYPESPEC, RID_SIGNED

View File

@ -1783,6 +1783,12 @@ Used by squangling to compress qualified names.
@item l
Encodes the C++ @code{long} type.
@item n
Used with squangling.
@item N
Namespaces.
@item P
Indicates a pointer type. Followed by the type pointed to.
@ -1817,11 +1823,14 @@ A modifier that indicates that the following integer type is unsigned.
Also used to indicate that the following class or namespace name
is encoded using Unicode-mangling.
@item u
The @code{restrict} type qualifier.
@item v
Encodes the C++ and Java @code{void} types.
@item V
A modified for a @code{const} type or method.
A modifier for a @code{volatile} type or method.
@item w
Encodes the C++ @code{wchar_t} type, and the Java @code{char} types.

View File

@ -1,14 +1,14 @@
/* KR-C code produced by gperf version 2.7.1 (19981006 egcs) */
/* Command-line: gperf -L KR-C -F , 0, 0 -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ./gxx.gperf */
/* Command-line: gperf -L KR-C -F , 0, 0 -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ../../../gcc/cp/gxx.gperf */
/* Command-line: gperf -L KR-C -F ', 0, 0' -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */
struct resword { char *name; short token; enum rid rid;};
#define TOTAL_KEYWORDS 104
#define TOTAL_KEYWORDS 106
#define MIN_WORD_LENGTH 2
#define MAX_WORD_LENGTH 16
#define MIN_HASH_VALUE 4
#define MAX_HASH_VALUE 261
/* maximum key range = 258, duplicates = 0 */
#define MAX_HASH_VALUE 250
/* maximum key range = 247, duplicates = 0 */
#ifdef __GNUC__
__inline
@ -18,34 +18,34 @@ hash (str, len)
register char *str;
register unsigned int len;
{
static unsigned short asso_values[] =
static unsigned char asso_values[] =
{
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 0, 262, 87, 25, 96,
60, 0, 55, 7, 4, 41, 262, 2, 15, 49,
14, 63, 32, 29, 3, 23, 6, 8, 2, 2,
0, 7, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262, 262, 262, 262, 262,
262, 262, 262, 262, 262, 262
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 0, 251, 64, 93, 3,
0, 0, 74, 35, 0, 26, 251, 2, 31, 65,
23, 76, 7, 19, 45, 37, 6, 64, 12, 38,
14, 4, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
251, 251, 251, 251, 251, 251
};
register int hval = len;
@ -80,155 +80,145 @@ is_reserved_word (str, len)
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"else", ELSE, NORID,},
{"", 0, 0},
{"xor", '^', NORID,},
{"", 0, 0},
{"delete", DELETE, NORID,},
{"case", CASE, NORID,},
{"__real__", REALPART, NORID},
{"", 0, 0},
{"true", CXX_TRUE, NORID,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"catch", CATCH, NORID,},
{"typeid", TYPEID, NORID,},
{"try", TRY, NORID,},
{"", 0, 0}, {"", 0, 0},
{"new", NEW, NORID,},
{"extern", SCSPEC, RID_EXTERN,},
{"__real", REALPART, NORID},
{"while", WHILE, NORID,},
{"not", '!', NORID,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"__extension__", EXTENSION, NORID},
{"", 0, 0},
{"__null", CONSTANT, RID_NULL},
{"__asm__", ASM_KEYWORD, NORID},
{"return", RETURN, NORID,},
{"", 0, 0},
{"long", TYPESPEC, RID_LONG,},
{"using", USING, NORID,},
{"xor_eq", ASSIGN, NORID,},
{"__inline", SCSPEC, RID_INLINE},
{"short", TYPESPEC, RID_SHORT,},
{"__inline__", SCSPEC, RID_INLINE},
{"switch", SWITCH, NORID,},
{"__alignof__", ALIGNOF, NORID},
{"void", TYPESPEC, RID_VOID,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"private", VISSPEC, RID_PRIVATE,},
{"reinterpret_cast", REINTERPRET_CAST, NORID,},
{"struct", AGGR, RID_RECORD,},
{"", 0, 0},
{"virtual", SCSPEC, RID_VIRTUAL,},
{"static_cast", STATIC_CAST, NORID,},
{"template", TEMPLATE, RID_TEMPLATE,},
{"protected", VISSPEC, RID_PROTECTED,},
{"extern", SCSPEC, RID_EXTERN,},
{"", 0, 0}, {"", 0, 0},
{"not_eq", EQCOMPARE, NORID,},
{"not", '!', NORID,},
{"", 0, 0},
{"__signed", TYPESPEC, RID_SIGNED},
{"int", TYPESPEC, RID_INT,},
{"__signed__", TYPESPEC, RID_SIGNED},
{"template", TEMPLATE, RID_TEMPLATE,},
{"__real", REALPART, NORID},
{"", 0, 0},
{"signature", AGGR, RID_SIGNATURE /* Extension */,},
{"register", SCSPEC, RID_REGISTER,},
{"this", THIS, NORID,},
{"__imag__", IMAGPART, NORID},
{"__attribute", ATTRIBUTE, NORID},
{"bool", TYPESPEC, RID_BOOL,},
{"__attribute__", ATTRIBUTE, NORID},
{"for", FOR, NORID,},
{"__imag", IMAGPART, NORID},
{"typename", TYPENAME_KEYWORD, NORID,},
{"", 0, 0}, {"", 0, 0},
{"delete", DELETE, NORID,},
{"typeof", TYPEOF, NORID,},
{"or", OROR, NORID,},
{"", 0, 0},
{"explicit", SCSPEC, RID_EXPLICIT,},
{"", 0, 0},
{"typeid", TYPEID, NORID,},
{"", 0, 0}, {"", 0, 0},
{"export", SCSPEC, RID_EXPORT,},
{"throw", THROW, NORID,},
{"__asm", ASM_KEYWORD, NORID},
{"__const__", CV_QUALIFIER, RID_CONST},
{"__volatile", CV_QUALIFIER, RID_VOLATILE},
{"__typeof__", TYPEOF, NORID},
{"__volatile__", CV_QUALIFIER, RID_VOLATILE},
{"__const", CV_QUALIFIER, RID_CONST},
{"false", CXX_FALSE, NORID,},
{"sizeof", SIZEOF, NORID,},
{"", 0, 0}, {"", 0, 0},
{"__complex", TYPESPEC, RID_COMPLEX},
{"inline", SCSPEC, RID_INLINE,},
{"__complex__", TYPESPEC, RID_COMPLEX},
{"union", AGGR, RID_UNION,},
{"double", TYPESPEC, RID_DOUBLE,},
{"", 0, 0},
{"__alignof", ALIGNOF, NORID},
{"", 0, 0}, {"", 0, 0},
{"bitor", '|', NORID,},
{"or_eq", ASSIGN, NORID,},
{"if", IF, NORID,},
{"", 0, 0},
{"case", CASE, NORID,},
{"", 0, 0},
{"enum", ENUM, NORID,},
{"signed", TYPESPEC, RID_SIGNED,},
{"", 0, 0},
{"__sigof__", SIGOF, NORID /* Extension */,},
{"char", TYPESPEC, RID_CHAR,},
{"", 0, 0}, {"", 0, 0},
{"__signed", TYPESPEC, RID_SIGNED},
{"namespace", NAMESPACE, NORID,},
{"__label__", LABEL, NORID},
{"volatile", CV_QUALIFIER, RID_VOLATILE,},
{"protected", VISSPEC, RID_PROTECTED,},
{"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,},
{"", 0, 0}, {"", 0, 0},
{"unsigned", TYPESPEC, RID_UNSIGNED,},
{"continue", CONTINUE, NORID,},
{"break", BREAK, NORID,},
{"", 0, 0},
{"friend", SCSPEC, RID_FRIEND,},
{"and_eq", ASSIGN, NORID,},
{"typedef", SCSPEC, RID_TYPEDEF,},
{"", 0, 0},
{"do", DO, NORID,},
{"void", TYPESPEC, RID_VOID,},
{"xor_eq", ASSIGN, NORID,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"__attribute", ATTRIBUTE, NORID},
{"__asm__", ASM_KEYWORD, NORID},
{"__attribute__", ATTRIBUTE, NORID},
{"compl", '~', NORID,},
{"public", VISSPEC, RID_PUBLIC,},
{"not_eq", EQCOMPARE, NORID,},
{"switch", SWITCH, NORID,},
{"__extension__", EXTENSION, NORID},
{"const", CV_QUALIFIER, RID_CONST,},
{"static", SCSPEC, RID_STATIC,},
{"", 0, 0},
{"__typeof", TYPEOF, NORID},
{"__inline", SCSPEC, RID_INLINE},
{"", 0, 0},
{"__inline__", SCSPEC, RID_INLINE},
{"__restrict__", CV_QUALIFIER, RID_RESTRICT},
{"inline", SCSPEC, RID_INLINE,},
{"const_cast", CONST_CAST, NORID,},
{"static_cast", STATIC_CAST, NORID,},
{"__restrict", CV_QUALIFIER, RID_RESTRICT},
{"xor", '^', NORID,},
{"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,},
{"new", NEW, NORID,},
{"__alignof__", ALIGNOF, NORID},
{"signed", TYPESPEC, RID_SIGNED,},
{"and", ANDAND, NORID,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"goto", GOTO, NORID,},
{"explicit", SCSPEC, RID_EXPLICIT,},
{"", 0, 0},
{"__imag__", IMAGPART, NORID},
{"while", WHILE, NORID,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"do", DO, NORID,},
{"typename", TYPENAME_KEYWORD, NORID,},
{"friend", SCSPEC, RID_FRIEND,},
{"continue", CONTINUE, NORID,},
{"class", AGGR, RID_CLASS,},
{"default", DEFAULT, NORID,},
{"this", THIS, NORID,},
{"dynamic_cast", DYNAMIC_CAST, NORID,},
{"typeof", TYPEOF, NORID,},
{"virtual", SCSPEC, RID_VIRTUAL,},
{"export", SCSPEC, RID_EXPORT,},
{"and_eq", ASSIGN, NORID,},
{"__typeof__", TYPEOF, NORID},
{"__const__", CV_QUALIFIER, RID_CONST},
{"__volatile", CV_QUALIFIER, RID_VOLATILE},
{"short", TYPESPEC, RID_SHORT,},
{"__volatile__", CV_QUALIFIER, RID_VOLATILE},
{"__const", CV_QUALIFIER, RID_CONST},
{"namespace", NAMESPACE, NORID,},
{"char", TYPESPEC, RID_CHAR,},
{"unsigned", TYPESPEC, RID_UNSIGNED,},
{"double", TYPESPEC, RID_DOUBLE,},
{"or_eq", ASSIGN, NORID,},
{"__null", CONSTANT, RID_NULL},
{"if", IF, NORID,},
{"__signature__", AGGR, RID_SIGNATURE /* Extension */,},
{"__label__", LABEL, NORID},
{"long", TYPESPEC, RID_LONG,},
{"__imag", IMAGPART, NORID},
{"__asm", ASM_KEYWORD, NORID},
{"", 0, 0},
{"__sigof__", SIGOF, NORID /* Extension */,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"struct", AGGR, RID_RECORD,},
{"", 0, 0},
{"volatile", CV_QUALIFIER, RID_VOLATILE,},
{"false", CXX_FALSE, NORID,},
{"sizeof", SIZEOF, NORID,},
{"__complex__", TYPESPEC, RID_COMPLEX},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"for", FOR, NORID,},
{"or", OROR, NORID,},
{"register", SCSPEC, RID_REGISTER,},
{"throw", THROW, NORID,},
{"", 0, 0},
{"using", USING, NORID,},
{"", 0, 0}, {"", 0, 0},
{"__complex", TYPESPEC, RID_COMPLEX},
{"", 0, 0},
{"asm", ASM_KEYWORD, NORID,},
{"operator", OPERATOR, NORID,},
{"__signature__", AGGR, RID_SIGNATURE /* Extension */,},
{"", 0, 0},
{"signature", AGGR, RID_SIGNATURE /* Extension */,},
{"enum", ENUM, NORID,},
{"reinterpret_cast", REINTERPRET_CAST, NORID,},
{"mutable", SCSPEC, RID_MUTABLE,},
{"", 0, 0}, {"", 0, 0},
{"sigof", SIGOF, NORID /* Extension */,},
{"class", AGGR, RID_CLASS,},
{"compl", '~', NORID,},
{"public", VISSPEC, RID_PUBLIC,},
{"and", ANDAND, NORID,},
{"", 0, 0}, {"", 0, 0},
{"__alignof", ALIGNOF, NORID},
{"return", RETURN, NORID,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0},
{"float", TYPESPEC, RID_FLOAT,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"default", DEFAULT, NORID,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0},
{"bool", TYPESPEC, RID_BOOL,},
{"", 0, 0},
{"typedef", SCSPEC, RID_TYPEDEF,},
{"__typeof", TYPEOF, NORID},
{"bitand", '&', NORID,},
{"break", BREAK, NORID,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"union", AGGR, RID_UNION,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"catch", CATCH, NORID,},
{"goto", GOTO, NORID,},
{"sigof", SIGOF, NORID /* Extension */,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"bitor", '|', NORID,},
{"auto", SCSPEC, RID_AUTO,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"const_cast", CONST_CAST, NORID,},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0},
{"", 0, 0}, {"", 0, 0},
{"dynamic_cast", DYNAMIC_CAST, NORID,}
{"operator", OPERATOR, NORID,}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)

View File

@ -1057,7 +1057,7 @@ expand_aggr_init (exp, init, flags)
/* Must arrange to initialize each element of EXP
from elements of INIT. */
tree itype = init ? TREE_TYPE (init) : NULL_TREE;
if (TYPE_READONLY (TREE_TYPE (type)) || TYPE_VOLATILE (TREE_TYPE (type)))
if (CP_TYPE_QUALS (type) != TYPE_UNQUALIFIED)
{
TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type);
if (init)
@ -1424,8 +1424,7 @@ build_member_call (type, name, parmlist)
tree oldtype = TREE_TYPE (TREE_TYPE (olddecl));
if (oldtype != type)
{
tree newtype = build_type_variant (type, TYPE_READONLY (oldtype),
TYPE_VOLATILE (oldtype));
tree newtype = build_qualified_type (type, TYPE_QUALS (oldtype));
decl = convert_force (build_pointer_type (newtype), olddecl, 0);
decl = build_indirect_ref (decl, NULL_PTR);
}
@ -2143,7 +2142,7 @@ build_new_1 (exp)
}
true_type = type;
if (TYPE_READONLY (type) || TYPE_VOLATILE (type))
if (CP_TYPE_QUALS (type))
type = TYPE_MAIN_VARIANT (type);
/* If our base type is an array, then make sure we know how many elements
@ -2345,11 +2344,11 @@ build_new_1 (exp)
allow the expression to be non-const while we do the
initialization. */
deref_type = TREE_TYPE (deref);
if (TYPE_READONLY (deref_type))
if (CP_TYPE_CONST_P (deref_type))
TREE_TYPE (deref)
= cp_build_type_variant (deref_type,
/*constp=*/0,
TYPE_VOLATILE (deref_type));
= cp_build_qualified_type (deref_type,
CP_TYPE_QUALS (deref_type)
& ~TYPE_QUAL_CONST);
TREE_READONLY (deref) = 0;
if (TREE_CHAIN (init) != NULL_TREE)
@ -2469,7 +2468,7 @@ build_new_1 (exp)
}
}
}
else if (TYPE_READONLY (true_type))
else if (CP_TYPE_CONST_P (true_type))
cp_error ("uninitialized const in `new' of `%#T'", true_type);
done:

View File

@ -702,6 +702,9 @@ init_parse (filename)
ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE],
build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE]));
ridpointers[(int) RID_RESTRICT] = get_identifier ("__restrict");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_RESTRICT],
build_tree_list (NULL_TREE, ridpointers[(int) RID_RESTRICT]));
ridpointers[(int) RID_AUTO] = get_identifier ("auto");
SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO],
build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO]));
@ -1984,7 +1987,7 @@ cons_up_default_function (type, full_name, kind)
break;
case 3:
type = build_type_variant (type, 1, 0);
type = build_qualified_type (type, TYPE_QUAL_CONST);
/* Fall through... */
case 4:
/* According to ARM $12.8, the default copy ctor will be declared, but
@ -2002,7 +2005,7 @@ cons_up_default_function (type, full_name, kind)
declspecs = build_decl_list (NULL_TREE, type);
if (kind == 5)
type = build_type_variant (type, 1, 0);
type = build_qualified_type (type, TYPE_QUAL_CONST);
name = ansi_opname [(int) MODIFY_EXPR];
@ -4934,6 +4937,25 @@ handle_cp_pragma (pname)
return 0;
}
/* Return the type-qualifier corresponding to the identifier given by
RID. */
int
cp_type_qual_from_rid (rid)
tree rid;
{
if (rid == ridpointers[(int) RID_CONST])
return TYPE_QUAL_CONST;
else if (rid == ridpointers[(int) RID_VOLATILE])
return TYPE_QUAL_VOLATILE;
else if (rid == ridpointers[(int) RID_RESTRICT])
return TYPE_QUAL_RESTRICT;
my_friendly_abort (0);
return TYPE_UNQUALIFIED;
}
#ifdef HANDLE_GENERIC_PRAGMAS

View File

@ -64,6 +64,7 @@ enum rid
RID_AUTO,
RID_MUTABLE,
RID_COMPLEX,
RID_RESTRICT,
/* This is where grokdeclarator ends its search when setting the
specbits. */

View File

@ -1163,7 +1163,10 @@ void
process_modifiers (parmtype)
tree parmtype;
{
if (TREE_READONLY (parmtype))
/* Note that here we do not use CP_TYPE_CONST_P and friends because
we describe types recursively; we will get the `const' in
`const int ()[10]' when processing the `const int' part. */
if (TYPE_READONLY (parmtype))
OB_PUTC ('C');
if (TREE_CODE (parmtype) == INTEGER_TYPE
&& (TYPE_MAIN_VARIANT (parmtype)
@ -1172,6 +1175,10 @@ process_modifiers (parmtype)
OB_PUTC ('U');
if (TYPE_VOLATILE (parmtype))
OB_PUTC ('V');
/* It would be better to use `R' for `restrict', but that's already
used for reference types. And `r' is used for `long double'. */
if (TYPE_RESTRICT (parmtype))
OB_PUTC ('u');
}
/* Check to see if TYPE has been entered into the Bcode typelist. If

File diff suppressed because it is too large Load Diff

View File

@ -1433,47 +1433,20 @@ primary:
{ $$ = finish_this_expr (); }
| CV_QUALIFIER '(' nonnull_exprlist ')'
{
tree type = NULL_TREE;
tree id = $$;
/* This is a C cast in C++'s `functional' notation
using the "implicit int" extension so that:
`const (3)' is equivalent to `const int (3)'. */
tree type;
/* This is a C cast in C++'s `functional' notation. */
if ($3 == error_mark_node)
{
$$ = error_mark_node;
break;
}
#if 0
if ($3 == NULL_TREE)
{
error ("cannot cast null list to type `%s'",
IDENTIFIER_POINTER (TYPE_NAME (id)));
$$ = error_mark_node;
break;
}
#endif
#if 0
/* type is not set! (mrs) */
if (type == error_mark_node)
$$ = error_mark_node;
else
#endif
{
if (id == ridpointers[(int) RID_CONST])
type = build_type_variant (integer_type_node, 1, 0);
else if (id == ridpointers[(int) RID_VOLATILE])
type = build_type_variant (integer_type_node, 0, 1);
#if 0
/* should not be able to get here (mrs) */
else if (id == ridpointers[(int) RID_FRIEND])
{
error ("cannot cast expression to `friend' type");
$$ = error_mark_node;
break;
}
#endif
else my_friendly_abort (79);
$$ = build_c_cast (type, build_compound_expr ($3));
}
type = cp_build_qualified_type (integer_type_node,
cp_type_qual_from_rid ($1));
$$ = build_c_cast (type, build_compound_expr ($3));
}
| functional_cast
| DYNAMIC_CAST '<' type_id '>' '(' expr ')'

View File

@ -2598,10 +2598,8 @@ convert_nontype_argument (type, expr)
template-argument, which must be an lvalue. */
if (!comptypes (TYPE_MAIN_VARIANT (expr_type),
TYPE_MAIN_VARIANT (type), 1)
|| (TYPE_READONLY (expr_type) >
TYPE_READONLY (type_referred_to))
|| (TYPE_VOLATILE (expr_type) >
TYPE_VOLATILE (type_referred_to))
|| !at_least_as_qualified_p (type_referred_to,
expr_type)
|| !real_lvalue_p (expr))
return error_mark_node;
else
@ -4872,8 +4870,7 @@ tsubst_aggr_type (t, args, in_decl, entering_scope)
{
tree r = build_ptrmemfunc_type
(tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, in_decl));
return cp_build_type_variant (r, TYPE_READONLY (t),
TYPE_VOLATILE (t));
return cp_build_qualified_type (r, TYPE_QUALS (t));
}
/* else fall through */
@ -4907,8 +4904,7 @@ tsubst_aggr_type (t, args, in_decl, entering_scope)
r = lookup_template_class (t, argvec, in_decl, context,
entering_scope);
return cp_build_type_variant (r, TYPE_READONLY (t),
TYPE_VOLATILE (t));
return cp_build_qualified_type (r, TYPE_QUALS (t));
}
else
/* This is not a template type, so there's nothing to do. */
@ -5559,9 +5555,8 @@ tsubst (t, args, in_decl)
{
my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (arg))
== 't', 0);
return cp_build_type_variant
(arg, TYPE_READONLY (arg) || TYPE_READONLY (t),
TYPE_VOLATILE (arg) || TYPE_VOLATILE (t));
return cp_build_qualified_type
(arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t));
}
else if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
{
@ -5585,8 +5580,7 @@ tsubst (t, args, in_decl)
argvec, in_decl,
DECL_CONTEXT (arg),
/*entering_scope=*/0);
return cp_build_type_variant (r, TYPE_READONLY (t),
TYPE_VOLATILE (t));
return cp_build_qualified_type (r, TYPE_QUALS (t));
}
else
/* We are processing a template argument list. */
@ -5736,7 +5730,7 @@ tsubst (t, args, in_decl)
r = build_pointer_type (type);
else
r = build_reference_type (type);
r = cp_build_type_variant (r, TYPE_READONLY (t), TYPE_VOLATILE (t));
r = cp_build_qualified_type (r, TYPE_QUALS (t));
/* Will this ever be needed for TYPE_..._TO values? */
layout_type (r);
@ -5766,10 +5760,7 @@ tsubst (t, args, in_decl)
= build_cplus_method_type (TREE_TYPE (TREE_VALUE (arg_types)),
type,
TREE_CHAIN (arg_types));
fntype = build_type_variant (fntype,
TYPE_READONLY (t),
TYPE_VOLATILE (t));
fntype = build_qualified_type (fntype, TYPE_QUALS (t));
/* Substitue the exception specification. */
raises = TYPE_RAISES_EXCEPTIONS (t);
@ -5820,9 +5811,9 @@ tsubst (t, args, in_decl)
return error_mark_node;
f = make_typename_type (ctx, f);
return cp_build_type_variant
(f, TYPE_READONLY (f) || TYPE_READONLY (t),
TYPE_VOLATILE (f) || TYPE_VOLATILE (t));
return cp_build_qualified_type (f,
CP_TYPE_QUALS (f)
| CP_TYPE_QUALS (t));
}
case INDIRECT_REF:
@ -7085,11 +7076,9 @@ check_cv_quals_for_unify (strict, arg, parm)
tree parm;
{
return !((!(strict & UNIFY_ALLOW_MORE_CV_QUAL)
&& (TYPE_READONLY (arg) < TYPE_READONLY (parm)
|| TYPE_VOLATILE (arg) < TYPE_VOLATILE (parm)))
&& !at_least_as_qualified_p (arg, parm))
|| (!(strict & UNIFY_ALLOW_LESS_CV_QUAL)
&& (TYPE_READONLY (arg) > TYPE_READONLY (parm)
|| TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm))));
&& (!at_least_as_qualified_p (parm, arg))));
}
/* Takes parameters as for type_unification. Returns 0 if the
@ -7249,9 +7238,9 @@ unify (tparms, targs, parm, arg, strict, explicit_mask)
/* Consider the case where ARG is `const volatile int' and
PARM is `const T'. Then, T should be `volatile int'. */
arg =
cp_build_type_variant (arg,
TYPE_READONLY (arg) > TYPE_READONLY (parm),
TYPE_VOLATILE (arg) > TYPE_VOLATILE (parm));
cp_build_qualified_type (arg,
CP_TYPE_QUALS (arg)
& ~CP_TYPE_QUALS (parm));
}
/* Simple cases: Value already set, does match or doesn't. */

View File

@ -65,7 +65,8 @@ init_rtti_processing ()
pop_namespace ();
tinfo_fn_id = get_identifier ("__tf");
tinfo_fn_type = build_function_type
(build_reference_type (build_type_variant (type_info_type_node, 1, 0)),
(build_reference_type (build_qualified_type (type_info_type_node,
TYPE_QUAL_CONST)),
void_list_node);
}
@ -123,8 +124,8 @@ build_headof (exp)
else
offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0);
type = build_type_variant (ptr_type_node, TREE_READONLY (exp),
TREE_THIS_VOLATILE (exp));
type = build_qualified_type (ptr_type_node,
CP_TYPE_QUALS (TREE_TYPE (exp)));
return build (PLUS_EXPR, type, exp,
cp_convert (ptrdiff_type_node, offset));
}
@ -302,7 +303,7 @@ get_tinfo_var (type)
/* Figure out how much space we need to allocate for the type_info object.
If our struct layout or the type_info classes are changed, this will
need to be modified. */
if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
size = 3 * POINTER_SIZE + INT_TYPE_SIZE;
else if (TREE_CODE (type) == POINTER_TYPE
&& ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE
@ -467,8 +468,8 @@ build_dynamic_cast_1 (type, expr)
goto fail;
if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
goto fail;
if (TREE_READONLY (TREE_TYPE (exprtype))
&& ! TYPE_READONLY (TREE_TYPE (type)))
if (!at_least_as_qualified_p (TREE_TYPE (type),
TREE_TYPE (exprtype)))
goto fail;
if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)
break;
@ -487,8 +488,6 @@ build_dynamic_cast_1 (type, expr)
/* Apply trivial conversion T -> T& for dereferenced ptrs. */
if (ec == RECORD_TYPE)
{
exprtype = build_type_variant (exprtype, TREE_READONLY (expr),
TREE_THIS_VOLATILE (expr));
exprtype = build_reference_type (exprtype);
expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT,
LOOKUP_NORMAL, NULL_TREE);
@ -503,8 +502,8 @@ build_dynamic_cast_1 (type, expr)
goto fail;
if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE)
goto fail;
if (TREE_READONLY (TREE_TYPE (exprtype))
&& ! TYPE_READONLY (TREE_TYPE (type)))
if (!at_least_as_qualified_p (TREE_TYPE (type),
TREE_TYPE (exprtype)))
goto fail;
}
@ -766,7 +765,9 @@ expand_class_desc (tdecl, type)
/* Actually const __user_type_info * */
fields [0] = build_lang_field_decl
(FIELD_DECL, NULL_TREE,
build_pointer_type (build_type_variant (type_info_type_node, 1, 0)));
build_pointer_type (build_qualified_type
(type_info_type_node,
TYPE_QUAL_CONST)));
fields [1] = build_lang_field_decl
(FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
DECL_BIT_FIELD (fields[1]) = 1;
@ -967,8 +968,7 @@ expand_attr_desc (tdecl, type)
tree elems, t, fn;
char *name = build_overload_name (type, 1, 1);
tree name_string = combine_strings (build_string (strlen (name)+1, name));
tree attrval = build_int_2
(TYPE_READONLY (type) | TYPE_VOLATILE (type) * 2, 0);
tree attrval = build_int_2 (TYPE_QUALS (type), 0);
expand_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
@ -1091,7 +1091,7 @@ synthesize_tinfo_fn (fndecl)
expand_generic_desc (tdecl, type, "__rtti_func");
else if (TREE_CODE (type) == ARRAY_TYPE)
expand_generic_desc (tdecl, type, "__rtti_array");
else if (TYPE_VOLATILE (type) || TYPE_READONLY (type))
else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED)
expand_attr_desc (tdecl, type);
else if (TREE_CODE (type) == POINTER_TYPE)
{

View File

@ -1752,8 +1752,7 @@ covariant_return_p (brettype, drettype)
if (! (TREE_CODE (brettype) == TREE_CODE (drettype)
&& (TREE_CODE (brettype) == POINTER_TYPE
|| TREE_CODE (brettype) == REFERENCE_TYPE)
&& TYPE_READONLY (brettype) == TYPE_READONLY (drettype)
&& TYPE_VOLATILE (brettype) == TYPE_VOLATILE (drettype)))
&& TYPE_QUALS (brettype) == TYPE_QUALS (drettype)))
return 0;
if (! can_convert (brettype, drettype))
@ -1849,15 +1848,19 @@ get_matching_virtual (binfo, fndecl, dtorp)
btypes = TYPE_ARG_TYPES (TREE_TYPE (tmp));
if (instptr_type == NULL_TREE)
{
if (compparms (TREE_CHAIN (btypes), dtypes, 3))
if (compparms (TREE_CHAIN (btypes), dtypes))
/* Caller knows to give error in this case. */
return tmp;
return NULL_TREE;
}
if ((TYPE_READONLY (TREE_TYPE (TREE_VALUE (btypes)))
== TYPE_READONLY (instptr_type))
&& compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes), 3))
if (/* The first parameter is the `this' parameter,
which has POINTER_TYPE, and we can therefore
safely use TYPE_QUALS, rather than
CP_TYPE_QUALS. */
(TYPE_QUALS (TREE_TYPE (TREE_VALUE (btypes)))
== TYPE_QUALS (instptr_type))
&& compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes)))
{
tree brettype = TREE_TYPE (TREE_TYPE (tmp));
if (comptypes (brettype, drettype, 1))
@ -2603,8 +2606,9 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
TREE_READONLY (new_delta) = 0;
TREE_TYPE (new_delta) =
cp_build_type_variant (TREE_TYPE (new_delta), /*constp=*/0,
TYPE_VOLATILE (TREE_TYPE (new_delta)));
cp_build_qualified_type (TREE_TYPE (new_delta),
CP_TYPE_QUALS (TREE_TYPE (new_delta))
& ~TYPE_QUAL_CONST);
expand_expr_stmt (build_modify_expr (new_delta, NOP_EXPR,
old_delta));
}

View File

@ -40,11 +40,11 @@ static tree build_sptr_ref PROTO((tree));
static tree build_member_function_pointer PROTO((tree));
static void undo_casts PROTO((tree));
static tree build_signature_pointer_or_reference_name
PROTO((tree, int, int, int));
PROTO((tree, int, int));
static void build_signature_pointer_or_reference_decl
PROTO((tree, tree));
static tree build_signature_pointer_or_reference_type
PROTO((tree, int, int, int));
PROTO((tree, int, int));
static tree get_sigtable_name PROTO((tree, tree));
static tree build_signature_table_constructor PROTO((tree, tree));
static int match_method_types PROTO((tree, tree));
@ -58,25 +58,31 @@ static int global_sigtable_name_counter;
can use it's name in function name mangling. */
static tree
build_signature_pointer_or_reference_name (to_type, constp, volatilep, refp)
build_signature_pointer_or_reference_name (to_type, type_quals, refp)
tree to_type;
int constp, volatilep, refp;
int type_quals;
int refp;
{
char * sig_name = TYPE_NAME_STRING (to_type);
int name_len = TYPE_NAME_LENGTH (to_type) + constp + volatilep;
int name_len = TYPE_NAME_LENGTH (to_type) + 3 /* Enough room for
C,V,R. */;
char * name;
char *const_rep = (type_quals & TYPE_QUAL_CONST) ? "C" : "";
char *restrict_rep = (type_quals & TYPE_QUAL_RESTRICT) ? "R" : "";
char *volatile_rep = (type_quals & TYPE_QUAL_VOLATILE) ? "C" : "";
if (refp)
{
name = (char *) alloca (name_len + sizeof (SIGNATURE_REFERENCE_NAME) +2);
sprintf (name, SIGNATURE_REFERENCE_NAME_FORMAT,
constp ? "C" : "", volatilep ? "V": "", sig_name);
const_rep, volatile_rep, restrict_rep, sig_name);
}
else
{
name = (char *) alloca (name_len + sizeof (SIGNATURE_POINTER_NAME) + 2);
sprintf (name, SIGNATURE_POINTER_NAME_FORMAT,
constp ? "C" : "", volatilep ? "V": "", sig_name);
const_rep, volatile_rep, restrict_rep, sig_name);
}
return get_identifier (name);
}
@ -98,21 +104,22 @@ build_signature_pointer_or_reference_decl (type, name)
TREE_CHAIN (type) = decl;
}
/* Construct, lay out and return the type of pointers or references
to signature TO_TYPE. If such a type has already been constructed,
reuse it. If CONSTP or VOLATILEP is specified, make the `optr' const
or volatile, respectively. If we are constructing a const/volatile
type variant and the main type variant doesn't exist yet, it is built
as well. If REFP is 1, we construct a signature reference, otherwise
a signature pointer is constructed.
/* Construct, lay out and return the type of pointers or references to
signature TO_TYPE. If such a type has already been constructed,
reuse it. If TYPE_QUALS are specified, qualify the `optr'. If we
are constructing a const/volatile type variant and the main type
variant doesn't exist yet, it is built as well. If REFP is 1, we
construct a signature reference, otherwise a signature pointer is
constructed.
This function is a subroutine of `build_signature_pointer_type' and
`build_signature_reference_type'. */
static tree
build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
build_signature_pointer_or_reference_type (to_type, type_quals, refp)
tree to_type;
int constp, volatilep, refp;
int type_quals;
int refp;
{
register tree t, m;
register struct obstack *ambient_obstack = current_obstack;
@ -121,13 +128,11 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
m = refp ? SIGNATURE_REFERENCE_TO (to_type) : SIGNATURE_POINTER_TO (to_type);
/* If we don't have the main variant yet, construct it. */
if (m == NULL_TREE
&& (constp || volatilep))
m = build_signature_pointer_or_reference_type (to_type, 0, 0, refp);
if (m == NULL_TREE && type_quals != TYPE_UNQUALIFIED)
m = build_signature_pointer_or_reference_type (to_type,
TYPE_UNQUALIFIED, refp);
/* Treat any nonzero argument as 1. */
constp = !!constp;
volatilep = !!volatilep;
refp = !!refp;
/* If not generating auxiliary info, search the chain of variants to see
@ -141,8 +146,8 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
if (m && !flag_gen_aux_info)
for (t = m; t; t = TYPE_NEXT_VARIANT (t))
if (constp == TYPE_READONLY (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (t))))
&& volatilep == TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (t)))))
if (type_quals == CP_TYPE_QUALS (TREE_TYPE (TREE_TYPE
(TYPE_FIELDS (t)))))
return t;
/* We need a new one. If TO_TYPE is permanent, make this permanent too. */
@ -170,7 +175,7 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
t = make_lang_type (RECORD_TYPE);
{
tree obj_type = build_type_variant (void_type_node, constp, volatilep);
tree obj_type = build_qualified_type (void_type_node, type_quals);
tree optr_type = build_pointer_type (obj_type);
tree optr, sptr;
@ -185,7 +190,8 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
sptr = TREE_CHAIN (TYPE_FIELDS (m));
else
{
tree sig_tbl_type = cp_build_type_variant (to_type, 1, 0);
tree sig_tbl_type =
cp_build_qualified_type (to_type, TYPE_QUAL_CONST);
sptr = build_lang_field_decl (FIELD_DECL,
get_identifier (SIGNATURE_SPTR_NAME),
@ -207,8 +213,9 @@ build_signature_pointer_or_reference_type (to_type, constp, volatilep, refp)
}
{
tree name = build_signature_pointer_or_reference_name (to_type, constp,
volatilep, refp);
tree name = build_signature_pointer_or_reference_name (to_type,
type_quals,
refp);
/* Build a DECL node for this type, so the debugger has access to it. */
build_signature_pointer_or_reference_decl (t, name);
@ -255,8 +262,7 @@ build_signature_pointer_type (to_type)
{
return
build_signature_pointer_or_reference_type (TYPE_MAIN_VARIANT (to_type),
TYPE_READONLY (to_type),
TYPE_VOLATILE (to_type), 0);
CP_TYPE_QUALS (to_type), 0);
}
/* Construct, lay out and return the type of pointers to signature TO_TYPE. */
@ -267,8 +273,7 @@ build_signature_reference_type (to_type)
{
return
build_signature_pointer_or_reference_type (TYPE_MAIN_VARIANT (to_type),
TYPE_READONLY (to_type),
TYPE_VOLATILE (to_type), 1);
CP_TYPE_QUALS (to_type), 1);
}
/* Return the name of the signature table (as an IDENTIFIER_NODE)
@ -420,8 +425,7 @@ match_method_types (sig_mtype, class_mtype)
/* If a signature method's `this' is const or volatile, so has to be
the corresponding class method's `this.' */
if ((TYPE_READONLY (sig_this) && ! TYPE_READONLY (class_this))
|| (TYPE_VOLATILE (sig_this) && ! TYPE_VOLATILE (class_this)))
if (!at_least_as_qualified_p (class_this, sig_this))
return 0;
}
@ -429,7 +433,7 @@ match_method_types (sig_mtype, class_mtype)
class_arg_types = TREE_CHAIN (class_arg_types);
/* The number of arguments and the argument types have to be the same. */
return compparms (sig_arg_types, class_arg_types, 3);
return compparms (sig_arg_types, class_arg_types);
}
/* Undo casts of opaque type variables to the RHS types. */
@ -884,7 +888,7 @@ build_signature_pointer_constructor (lhs, rhs)
}
else
{
if (TREE_READONLY (lhs) || TYPE_READONLY (lhstype))
if (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype))
readonly_error (lhs, "assignment", 0);
optr_expr = build_modify_expr (build_optr_ref (lhs), NOP_EXPR,
@ -978,9 +982,8 @@ build_signature_method_call (function, parms)
tree old_this = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn))));
TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn))))
= build_type_variant (build_pointer_type (basetype),
TYPE_READONLY (old_this),
TYPE_VOLATILE (old_this));
= build_qualified_type (build_pointer_type (basetype),
TYPE_QUALS (old_this));
direct_call = build_function_call (pfn, new_parms);

View File

@ -442,14 +442,14 @@ build_cplus_array_type (elt_type, index_type)
tree index_type;
{
tree t;
int constp = TYPE_READONLY (elt_type);
int volatilep = TYPE_VOLATILE (elt_type);
int type_quals = CP_TYPE_QUALS (elt_type);
elt_type = TYPE_MAIN_VARIANT (elt_type);
t = build_cplus_array_type_1 (elt_type, index_type);
if (constp || volatilep)
t = cp_build_type_variant (t, constp, volatilep);
if (type_quals != TYPE_UNQUALIFIED)
t = cp_build_qualified_type (t, type_quals);
return t;
}
@ -458,21 +458,32 @@ build_cplus_array_type (elt_type, index_type)
down to the element type of an array. */
tree
cp_build_type_variant (type, constp, volatilep)
cp_build_qualified_type (type, type_quals)
tree type;
int constp, volatilep;
int type_quals;
{
if (type == error_mark_node)
return type;
/* A restrict-qualified pointer type must be a pointer (or reference)
to object or incomplete type. */
if ((type_quals & TYPE_QUAL_RESTRICT)
&& (!POINTER_TYPE_P (type)
|| TYPE_PTRMEM_P (type)
|| TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE))
{
cp_error ("`%T' cannot be `restrict'-qualified", type);
type_quals &= ~TYPE_QUAL_RESTRICT;
}
if (TREE_CODE (type) == ARRAY_TYPE)
{
tree real_main_variant = TYPE_MAIN_VARIANT (type);
push_obstacks (TYPE_OBSTACK (real_main_variant),
TYPE_OBSTACK (real_main_variant));
type = build_cplus_array_type_1 (cp_build_type_variant
(TREE_TYPE (type), constp, volatilep),
type = build_cplus_array_type_1 (cp_build_qualified_type
(TREE_TYPE (type), type_quals),
TYPE_DOMAIN (type));
/* TYPE must be on same obstack as REAL_MAIN_VARIANT. If not,
@ -489,7 +500,7 @@ cp_build_type_variant (type, constp, volatilep)
pop_obstacks ();
return type;
}
return build_type_variant (type, constp, volatilep);
return build_qualified_type (type, type_quals);
}
/* Returns the canonical version of TYPE. In other words, if TYPE is
@ -501,8 +512,7 @@ tree
canonical_type_variant (t)
tree t;
{
return cp_build_type_variant (TYPE_MAIN_VARIANT (t), CP_TYPE_READONLY (t),
CP_TYPE_VOLATILE (t));
return cp_build_qualified_type (TYPE_MAIN_VARIANT (t), CP_TYPE_QUALS (t));
}
/* Add OFFSET to all base types of T.
@ -1448,13 +1458,11 @@ build_exception_variant (type, raises)
tree raises;
{
tree v = TYPE_MAIN_VARIANT (type);
int constp = TYPE_READONLY (type);
int volatilep = TYPE_VOLATILE (type);
int type_quals = TYPE_QUALS (type);
for (; v; v = TYPE_NEXT_VARIANT (v))
{
if (TYPE_READONLY (v) != constp
|| TYPE_VOLATILE (v) != volatilep)
if (TYPE_QUALS (v) != type_quals)
continue;
/* @@ This should do set equality, not exact match. */
@ -1931,31 +1939,31 @@ mapcar (t, func)
case POINTER_TYPE:
tmp = build_pointer_type (mapcar (TREE_TYPE (t), func));
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
return cp_build_qualified_type (tmp, TYPE_QUALS (t));
case REFERENCE_TYPE:
tmp = build_reference_type (mapcar (TREE_TYPE (t), func));
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
return cp_build_qualified_type (tmp, TYPE_QUALS (t));
case FUNCTION_TYPE:
tmp = build_function_type (mapcar (TREE_TYPE (t), func),
mapcar (TYPE_ARG_TYPES (t), func));
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
return cp_build_qualified_type (tmp, TYPE_QUALS (t));
case ARRAY_TYPE:
tmp = build_cplus_array_type (mapcar (TREE_TYPE (t), func),
mapcar (TYPE_DOMAIN (t), func));
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
return cp_build_qualified_type (tmp, CP_TYPE_QUALS (t));
case INTEGER_TYPE:
tmp = build_index_type (mapcar (TYPE_MAX_VALUE (t), func));
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
return cp_build_qualified_type (tmp, TYPE_QUALS (t));
case OFFSET_TYPE:
tmp = build_offset_type (mapcar (TYPE_OFFSET_BASETYPE (t), func),
mapcar (TREE_TYPE (t), func));
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
return cp_build_qualified_type (tmp, TYPE_QUALS (t));
case METHOD_TYPE:
tmp = build_cplus_method_type
(mapcar (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), func),
mapcar (TREE_TYPE (t), func),
mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func));
return cp_build_type_variant (tmp, TYPE_READONLY (t), TYPE_VOLATILE (t));
return cp_build_qualified_type (tmp, TYPE_QUALS (t));
case COMPLEX_CST:
t = copy_node (t);

View File

@ -239,10 +239,9 @@ static tree
qualify_type (type, like)
tree type, like;
{
int constflag = TYPE_READONLY (type) || TYPE_READONLY (like);
int volflag = TYPE_VOLATILE (type) || TYPE_VOLATILE (like);
/* @@ Must do member pointers here. */
return cp_build_type_variant (type, constflag, volflag);
return cp_build_qualified_type (type, (CP_TYPE_QUALS (type)
| CP_TYPE_QUALS (like)));
}
/* Return the common type of two parameter lists.
@ -498,10 +497,8 @@ common_type (t1, t2)
{
tree tt1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1));
tree tt2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2));
int constp
= TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2));
int volatilep
= TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2));
int type_quals = (CP_TYPE_QUALS (TREE_TYPE (t1))
| CP_TYPE_QUALS (TREE_TYPE (t2)));
tree target;
if (tt1 == tt2)
@ -515,7 +512,7 @@ common_type (t1, t2)
else
target = common_type (tt1, tt2);
target = cp_build_type_variant (target, constp, volatilep);
target = cp_build_qualified_type (target, type_quals);
if (code1 == POINTER_TYPE)
t1 = build_pointer_type (target);
else
@ -776,9 +773,7 @@ comptypes (type1, type2, strict)
/* Qualifiers must match. */
if (TYPE_READONLY (t1) != TYPE_READONLY (t2))
return 0;
if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2))
if (CP_TYPE_QUALS (t1) != CP_TYPE_QUALS (t2))
return 0;
if (strict > 0 && TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
return 0;
@ -845,8 +840,7 @@ comptypes (type1, type2, strict)
but not vice-versa! */
val = (comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict)
&& compparms (TYPE_ARG_TYPES (t1),
TYPE_ARG_TYPES (t2), strict));
&& compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)));
break;
case POINTER_TYPE:
@ -888,7 +882,7 @@ comptypes (type1, type2, strict)
val = ((TREE_TYPE (t1) == TREE_TYPE (t2)
|| comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict))
&& compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2), strict));
&& compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)));
break;
case ARRAY_TYPE:
@ -920,17 +914,18 @@ comp_cv_target_types (ttl, ttr, nptrs)
int nptrs;
{
int t;
int c = TYPE_READONLY (ttl) - TYPE_READONLY (ttr);
int v = TYPE_VOLATILE (ttl) - TYPE_VOLATILE (ttr);
if ((c > 0 && v < 0) || (c < 0 && v > 0))
if (!at_least_as_qualified_p (ttl, ttr)
&& !at_least_as_qualified_p (ttr, ttl))
/* The qualifications are incomparable. */
return 0;
if (TYPE_MAIN_VARIANT (ttl) == TYPE_MAIN_VARIANT (ttr))
return (c + v < 0) ? -1 : 1;
return more_qualified_p (ttr, ttl) ? -1 : 1;
t = comp_target_types (ttl, ttr, nptrs);
if ((t == 1 && c + v >= 0) || (t == -1 && c + v <= 0))
if ((t == 1 && at_least_as_qualified_p (ttl, ttr))
|| (t == -1 && at_least_as_qualified_p (ttr, ttl)))
return t;
return 0;
@ -1115,6 +1110,29 @@ comp_target_types (ttl, ttr, nptrs)
return 0;
}
/* Returns 1 if TYPE1 is at least as qualified as TYPE2. */
int
at_least_as_qualified_p (type1, type2)
tree type1;
tree type2;
{
/* All qualifiers for TYPE2 must also appear in TYPE1. */
return ((CP_TYPE_QUALS (type1) & CP_TYPE_QUALS (type2))
== CP_TYPE_QUALS (type2));
}
/* Returns 1 if TYPE1 is more qualified than TYPE2. */
int
more_qualified_p (type1, type2)
tree type1;
tree type2;
{
return (CP_TYPE_QUALS (type1) != CP_TYPE_QUALS (type2)
&& at_least_as_qualified_p (type1, type2));
}
/* Returns 1 if TYPE1 is more cv-qualified than TYPE2, -1 if TYPE2 is
more cv-qualified that TYPE1, and 0 otherwise. */
@ -1123,16 +1141,13 @@ comp_cv_qualification (type1, type2)
tree type1;
tree type2;
{
if (TYPE_READONLY (type1) == TYPE_READONLY (type2)
&& TYPE_VOLATILE (type1) == TYPE_VOLATILE (type2))
if (CP_TYPE_QUALS (type1) == CP_TYPE_QUALS (type2))
return 0;
if (TYPE_READONLY (type1) >= TYPE_READONLY (type2)
&& TYPE_VOLATILE (type1) >= TYPE_VOLATILE (type2))
if (at_least_as_qualified_p (type1, type2))
return 1;
if (TYPE_READONLY (type2) >= TYPE_READONLY (type1)
&& TYPE_VOLATILE (type2) >= TYPE_VOLATILE (type1))
else if (at_least_as_qualified_p (type2, type1))
return -1;
return 0;
@ -1220,9 +1235,8 @@ common_base_type (tt1, tt2)
STRICT is no longer used. */
int
compparms (parms1, parms2, strict)
compparms (parms1, parms2)
tree parms1, parms2;
int strict ATTRIBUTE_UNUSED;
{
register tree t1 = parms1, t2 = parms2;
@ -1774,11 +1788,8 @@ inline_conversion (exp)
tree exp;
{
if (TREE_CODE (exp) == FUNCTION_DECL)
{
tree type = build_type_variant
(TREE_TYPE (exp), TREE_READONLY (exp), TREE_THIS_VOLATILE (exp));
exp = build1 (ADDR_EXPR, build_pointer_type (type), exp);
}
exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp);
return exp;
}
@ -1802,7 +1813,7 @@ string_conv_p (totype, exp, warn)
if (TREE_CODE (exp) != STRING_CST)
{
t = build_pointer_type (build_type_variant (t, 1, 0));
t = build_pointer_type (build_qualified_type (t, TYPE_QUAL_CONST));
if (! comptypes (TREE_TYPE (exp), t, 1))
return 0;
STRIP_NOPS (exp);
@ -1947,8 +1958,7 @@ build_component_ref (datum, component, basetype_path, protect)
register tree field = NULL;
register tree ref;
tree field_type;
int constp;
int volatilep;
int type_quals;
if (processing_template_decl)
return build_min_nt (COMPONENT_REF, datum, component);
@ -2167,8 +2177,7 @@ build_component_ref (datum, component, basetype_path, protect)
}
/* Compute the type of the field, as described in [expr.ref]. */
constp = 0;
volatilep = 0;
type_quals = TYPE_UNQUALIFIED;
field_type = TREE_TYPE (field);
if (TREE_CODE (field_type) == REFERENCE_TYPE)
/* The standard says that the type of the result should be the
@ -2177,17 +2186,16 @@ build_component_ref (datum, component, basetype_path, protect)
;
else
{
type_quals = (CP_TYPE_QUALS (field_type)
| CP_TYPE_QUALS (TREE_TYPE (datum)));
/* A field is const (volatile) if the enclosing object, or the
field itself, is const (volatile). But, a mutable field is
not const, even within a const object. */
constp = (!(DECL_LANG_SPECIFIC (field)
&& DECL_MUTABLE_P (field))
&& (TYPE_READONLY (field_type)
|| TYPE_READONLY (TREE_TYPE (datum))));
volatilep = (TYPE_VOLATILE (field_type)
|| TYPE_VOLATILE (TREE_TYPE (datum)));
if (DECL_LANG_SPECIFIC (field) && DECL_MUTABLE_P (field))
type_quals &= ~TYPE_QUAL_CONST;
if (!IS_SIGNATURE (field_type))
field_type = cp_build_type_variant (field_type, constp, volatilep);
field_type = cp_build_qualified_type (field_type, type_quals);
}
ref = fold (build (COMPONENT_REF, field_type,
@ -2196,9 +2204,9 @@ build_component_ref (datum, component, basetype_path, protect)
/* Mark the expression const or volatile, as appropriate. Even
though we've dealt with the type above, we still have to mark the
expression itself. */
if (constp)
if (type_quals & TYPE_QUAL_CONST)
TREE_READONLY (ref) = 1;
else if (volatilep)
else if (type_quals & TYPE_QUAL_VOLATILE)
TREE_THIS_VOLATILE (ref) = 1;
return ref;
@ -2286,8 +2294,8 @@ build_indirect_ref (ptr, errorstring)
/* We *must* set TREE_READONLY when dereferencing a pointer to const,
so that we get the proper error message if the result is used
to assign to. Also, &* is supposed to be a no-op. */
TREE_READONLY (ref) = TYPE_READONLY (t);
TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
TREE_SIDE_EFFECTS (ref)
= (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer)
|| flag_volatile);
@ -2406,11 +2414,11 @@ build_array_ref (array, idx)
/* Array ref is const/volatile if the array elements are
or if the array is.. */
TREE_READONLY (rval)
|= (TYPE_READONLY (type) | TREE_READONLY (array));
|= (CP_TYPE_CONST_P (type) | TREE_READONLY (array));
TREE_SIDE_EFFECTS (rval)
|= (TYPE_VOLATILE (type) | TREE_SIDE_EFFECTS (array));
|= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array));
TREE_THIS_VOLATILE (rval)
|= (TYPE_VOLATILE (type) | TREE_THIS_VOLATILE (array));
|= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array));
return require_complete_type (fold (rval));
}
@ -4449,7 +4457,7 @@ build_unary_op (code, xarg, noconvert)
/* Report something read-only. */
if (TYPE_READONLY (TREE_TYPE (arg))
if (CP_TYPE_CONST_P (TREE_TYPE (arg))
|| TREE_READONLY (arg))
readonly_error (arg, ((code == PREINCREMENT_EXPR
|| code == POSTINCREMENT_EXPR)
@ -5075,10 +5083,9 @@ build_conditional_expr (ifexp, op1, op2)
else if (TREE_READONLY_DECL_P (op2))
op2 = decl_constant_value (op2);
if (type1 != type2)
type1 = cp_build_type_variant
(type1,
TYPE_READONLY (op1) || TYPE_READONLY (op2),
TYPE_VOLATILE (op1) || TYPE_VOLATILE (op2));
type1 = cp_build_qualified_type
(type1, (CP_TYPE_QUALS (TREE_TYPE (op1))
| CP_TYPE_QUALS (TREE_TYPE (op2))));
/* ??? This is a kludge to deal with the fact that
we don't sort out integers and enums properly, yet. */
result = fold (build (COND_EXPR, type1, ifexp, op1, op2));
@ -5151,10 +5158,10 @@ build_conditional_expr (ifexp, op1, op2)
if (type1 == type2)
result_type = type1;
else
result_type = cp_build_type_variant
(type1,
TREE_READONLY (op1) || TREE_READONLY (op2),
TREE_THIS_VOLATILE (op1) || TREE_THIS_VOLATILE (op2));
result_type =
cp_build_qualified_type (type1,
CP_TYPE_QUALS (TREE_TYPE (op1))
| CP_TYPE_QUALS (TREE_TYPE (op2)));
}
else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE)
&& (code2 == INTEGER_TYPE || code2 == REAL_TYPE))
@ -5247,7 +5254,10 @@ build_conditional_expr (ifexp, op1, op2)
tree tmp;
if (code2 == POINTER_TYPE)
tmp = build_pointer_type
(build_type_variant (TREE_TYPE (type2), 1, 1));
(cp_build_qualified_type (TREE_TYPE (type2),
TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT));
else
tmp = type2;
tmp = build_type_conversion (CONVERT_EXPR, tmp, op1, 0);
@ -5269,7 +5279,10 @@ build_conditional_expr (ifexp, op1, op2)
tree tmp;
if (code1 == POINTER_TYPE)
tmp = build_pointer_type
(build_type_variant (TREE_TYPE (type1), 1, 1));
(cp_build_qualified_type (TREE_TYPE (type1),
TYPE_QUAL_CONST
| TYPE_QUAL_VOLATILE
| TYPE_QUAL_RESTRICT));
else
tmp = type1;
@ -5454,10 +5467,8 @@ build_static_cast (type, expr)
{
tree binfo;
if (IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype))
&& (TYPE_READONLY (TREE_TYPE (type))
>= TYPE_READONLY (TREE_TYPE (intype)))
&& (TYPE_VOLATILE (TREE_TYPE (type))
>= TYPE_VOLATILE (TREE_TYPE (intype)))
&& at_least_as_qualified_p (TREE_TYPE (type),
TREE_TYPE (intype))
&& (binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 0))
&& ! TREE_VIA_VIRTUAL (binfo))
ok = 1;
@ -5466,10 +5477,8 @@ build_static_cast (type, expr)
{
if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))),
TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (intype))), 1)
&& (TYPE_READONLY (TREE_TYPE (TREE_TYPE (type)))
>= TYPE_READONLY (TREE_TYPE (TREE_TYPE (intype))))
&& (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (type)))
>= TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (intype))))
&& at_least_as_qualified_p (TREE_TYPE (TREE_TYPE (type)),
TREE_TYPE (TREE_TYPE (intype)))
&& (binfo = get_binfo (TYPE_OFFSET_BASETYPE (TREE_TYPE (type)),
TYPE_OFFSET_BASETYPE (TREE_TYPE (intype)), 0))
&& ! TREE_VIA_VIRTUAL (binfo))
@ -5770,17 +5779,10 @@ build_c_cast (type, expr)
if (warn_cast_qual
&& TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (otype) == POINTER_TYPE)
{
/* For C++ we make these regular warnings, rather than
softening them into pedwarns. */
if (TYPE_VOLATILE (TREE_TYPE (otype))
&& ! TYPE_VOLATILE (TREE_TYPE (type)))
warning ("cast discards `volatile' from pointer target type");
if (TYPE_READONLY (TREE_TYPE (otype))
&& ! TYPE_READONLY (TREE_TYPE (type)))
warning ("cast discards `const' from pointer target type");
}
&& TREE_CODE (otype) == POINTER_TYPE
&& !at_least_as_qualified_p (TREE_TYPE (type),
TREE_TYPE (otype)))
cp_warning ("cast discards qualifiers from pointer target type");
/* Warn about possible alignment problems. */
if (STRICT_ALIGNMENT && warn_cast_align
@ -6067,7 +6069,7 @@ build_modify_expr (lhs, modifycode, rhs)
&& ! (TREE_CODE (lhs) == COMPONENT_REF
&& (IS_SIGNATURE_POINTER (TREE_TYPE (TREE_OPERAND (lhs, 0)))
|| IS_SIGNATURE_REFERENCE (TREE_TYPE (TREE_OPERAND (lhs, 0)))))
&& (TREE_READONLY (lhs) || TYPE_READONLY (lhstype)
&& (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype)
/* Functions are not modifiable, even though they are
lvalues. */
|| TREE_CODE (TREE_TYPE (lhs)) == FUNCTION_TYPE
@ -6075,7 +6077,7 @@ build_modify_expr (lhs, modifycode, rhs)
|| TREE_CODE (lhstype) == UNION_TYPE)
&& C_TYPE_FIELDS_READONLY (lhstype))
|| (TREE_CODE (lhstype) == REFERENCE_TYPE
&& TYPE_READONLY (TREE_TYPE (lhstype)))))
&& CP_TYPE_CONST_P (TREE_TYPE (lhstype)))))
readonly_error (lhs, "assignment", 0);
/* If storing into a structure or union member,
@ -6751,22 +6753,13 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
if (binfo == 0)
return error_not_base_type (ttl, ttr);
if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
if (!at_least_as_qualified_p (ttl, ttr))
{
if (fndecl)
cp_error ("passing `%T' as argument %P of `%D' discards const",
cp_error ("passing `%T' as argument %P of `%D' discards qualifiers",
rhstype, parmnum, fndecl);
else
cp_error ("%s to `%T' from `%T' discards const",
errtype, type, rhstype);
}
if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
{
if (fndecl)
cp_error ("passing `%T' as argument %P of `%D' discards volatile",
rhstype, parmnum, fndecl);
else
cp_error ("%s to `%T' from `%T' discards volatile",
cp_error ("%s to `%T' from `%T' discards qualifiers",
errtype, type, rhstype);
}
}
@ -6815,24 +6808,15 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
error ("%s between pointer to members converting across virtual baseclasses", errtype);
return error_mark_node;
}
else if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr))
else if (!at_least_as_qualified_p (ttl, ttr))
{
if (string_conv_p (type, rhs, 1))
/* converting from string constant to char *, OK. */;
else if (fndecl)
cp_error ("passing `%T' as argument %P of `%D' discards const",
cp_error ("passing `%T' as argument %P of `%D' discards qualifiers",
rhstype, parmnum, fndecl);
else
cp_error ("%s to `%T' from `%T' discards const",
errtype, type, rhstype);
}
else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr))
{
if (fndecl)
cp_error ("passing `%T' as argument %P of `%D' discards volatile",
rhstype, parmnum, fndecl);
else
cp_error ("%s to `%T' from `%T' discards volatile",
cp_error ("%s to `%T' from `%T' discards qualifiers",
errtype, type, rhstype);
}
else if (TREE_CODE (ttl) == TREE_CODE (ttr)
@ -6849,7 +6833,8 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
}
else
{
int add_quals = 0, const_parity = 0, volatile_parity = 0;
int add_quals = 0;
int drops_quals = 0;
int left_const = 1;
int unsigned_parity;
int nptrs = 0;
@ -6858,12 +6843,10 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
for (; ; ttl = TREE_TYPE (ttl), ttr = TREE_TYPE (ttr))
{
nptrs -= 1;
const_parity |= (TYPE_READONLY (ttl) < TYPE_READONLY (ttr));
volatile_parity |= (TYPE_VOLATILE (ttl) < TYPE_VOLATILE (ttr));
drops_quals |= !at_least_as_qualified_p (ttl, ttr);
if (! left_const
&& (TYPE_READONLY (ttl) > TYPE_READONLY (ttr)
|| TYPE_VOLATILE (ttl) > TYPE_VOLATILE (ttr)))
&& !at_least_as_qualified_p (ttr, ttl))
add_quals = 1;
left_const &= TYPE_READONLY (ttl);
@ -6891,24 +6874,15 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
cp_pedwarn ("%s to `%T' from `%T' adds cv-quals without intervening `const'",
errtype, type, rhstype);
}
if (const_parity)
if (drops_quals)
{
if (fndecl)
cp_error ("passing `%T' as argument %P of `%D' discards const",
cp_error ("passing `%T' as argument %P of `%D' discards qualifiers",
rhstype, parmnum, fndecl);
else
cp_error ("%s to `%T' from `%T' discards const",
cp_error ("%s to `%T' from `%T' discards qualifiers",
errtype, type, rhstype);
}
if (volatile_parity)
{
if (fndecl)
cp_error ("passing `%T' as argument %P of `%D' discards volatile",
rhstype, parmnum, fndecl);
else
cp_error ("%s to `%T' from `%T' discards volatile",
errtype, type, rhstype);
}
if (unsigned_parity > 0)
{
if (fndecl)
@ -7215,7 +7189,7 @@ c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line)
else
{
tree type = TREE_TYPE (o[i]);
if (TYPE_READONLY (type)
if (CP_TYPE_CONST_P (type)
|| ((TREE_CODE (type) == RECORD_TYPE
|| TREE_CODE (type) == UNION_TYPE)
&& C_TYPE_FIELDS_READONLY (type)))
@ -7532,12 +7506,10 @@ comp_ptr_ttypes_real (to, from, constp)
so the usual checks are not appropriate. */
if (TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
{
if (TYPE_READONLY (from) > TYPE_READONLY (to)
|| TYPE_VOLATILE (from) > TYPE_VOLATILE (to))
if (!at_least_as_qualified_p (to, from))
return 0;
if (TYPE_READONLY (to) > TYPE_READONLY (from)
|| TYPE_VOLATILE (to) > TYPE_VOLATILE (from))
if (!at_least_as_qualified_p (from, to))
{
if (constp == 0)
return 0;
@ -7633,13 +7605,11 @@ comp_ptr_ttypes_reinterpret (to, from)
so the usual checks are not appropriate. */
if (TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE)
{
if (TYPE_READONLY (from) > TYPE_READONLY (to)
|| TYPE_VOLATILE (from) > TYPE_VOLATILE (to))
if (!at_least_as_qualified_p (to, from))
return 0;
if (! constp
&& (TYPE_READONLY (to) > TYPE_READONLY (from)
|| TYPE_VOLATILE (to) > TYPE_READONLY (from)))
&& !at_least_as_qualified_p (from, to))
return 0;
constp &= TYPE_READONLY (to);
}
@ -7648,3 +7618,15 @@ comp_ptr_ttypes_reinterpret (to, from)
return 1;
}
}
/* Returns the type-qualifier set corresponding to TYPE. */
int
cp_type_quals (type)
tree type;
{
while (TREE_CODE (type) == ARRAY_TYPE)
type = TREE_TYPE (type);
return TYPE_QUALS (type);
}

View File

@ -0,0 +1,9 @@
// Build don't link:
struct S
{
void f()
{
const int i; // ERROR - uninitialized const
}
};

View File

@ -0,0 +1,15 @@
// Build don't link:
class C {
public:
virtual void f();
};
extern volatile C* cp;
extern volatile C& cr;
void f ()
{
dynamic_cast<void*>(cp); // ERROR - cannot dynamic_cast
dynamic_cast<C&>(cr); // ERROR - cannot dynamic_cast
}

View File

@ -7,5 +7,5 @@
void
f()
{
const int var [ 10 ]; // ERROR - missing initializer - XFAIL *-*-*
const int var [ 10 ]; // ERROR - missing initializer
}

View File

@ -0,0 +1,19 @@
struct B
{
virtual int f() volatile
{ return 0; }
};
struct D : public B
{
virtual int f()
{ return 1; }
};
int main()
{
volatile D d;
volatile B& b = d;
return b.f();
}

View File

@ -0,0 +1,24 @@
struct B
{
virtual int f() volatile
{ return 1; }
};
struct D : public B
{
int f()
{ return 0; }
};
struct D2 : public D
{
int f()
{ return 2; }
};
int main()
{
D2 d2;
D& d = d2;
return d.f();
}

View File

@ -126,8 +126,7 @@ struct work_stuff
int constructor;
int destructor;
int static_type; /* A static member function */
int const_type; /* A const member function */
int volatile_type; /* A volatile member function */
int type_quals; /* The type qualifiers. */
int dllimported; /* Symbol imported from a PE DLL */
char **tmpl_argvec; /* Template function arguments. */
int ntmpl_args; /* The number of template function arguments. */
@ -392,6 +391,24 @@ static int
demangle_template_value_parm PARAMS ((struct work_stuff*, const char**,
string*, type_kind_t));
/* There is a TYPE_QUAL value for each type qualifier. They can be
combined by bitwise-or to form the complete set of qualifiers for a
type. */
#define TYPE_UNQUALIFIED 0x0
#define TYPE_QUAL_CONST 0x1
#define TYPE_QUAL_VOLATILE 0x2
#define TYPE_QUAL_RESTRICT 0x4
static int
code_for_qualifier PARAMS ((char));
static const char*
qualifier_string PARAMS ((int));
static const char*
demangle_qualifier PARAMS ((char));
/* Translate count to integer, consuming tokens in the process.
Conversion terminates on the first non-digit character.
Trying to consume something that isn't a count results in
@ -448,6 +465,84 @@ consume_count_with_underscores (mangled)
return idx;
}
/* C is the code for a type-qualifier. Return the TYPE_QUAL
corresponding to this qualifier. */
static int
code_for_qualifier (c)
char c;
{
switch (c)
{
case 'C':
return TYPE_QUAL_CONST;
case 'V':
return TYPE_QUAL_VOLATILE;
case 'u':
return TYPE_QUAL_RESTRICT;
default:
break;
}
/* C was an invalid qualifier. */
abort ();
}
/* Return the string corresponding to the qualifiers given by
TYPE_QUALS. */
static const char*
qualifier_string (type_quals)
int type_quals;
{
switch (type_quals)
{
case TYPE_UNQUALIFIED:
return "";
case TYPE_QUAL_CONST:
return "const";
case TYPE_QUAL_VOLATILE:
return "volatile";
case TYPE_QUAL_RESTRICT:
return "__restrict";
case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE:
return "const volatile";
case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT:
return "const __restrict";
case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
return "volatile __restrict";
case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT:
return "const volatile __restrict";
default:
break;
}
/* TYPE_QUALS was an invalid qualifier set. */
abort ();
}
/* C is the code for a type-qualifier. Return the string
corresponding to this qualifier. This function should only be
called with a valid qualifier code. */
static const char*
demangle_qualifier (c)
char c;
{
return qualifier_string (code_for_qualifier (c));
}
int
cplus_demangle_opname (opname, result, options)
const char *opname;
@ -664,15 +759,12 @@ internal_cplus_demangle (work, mangled)
int success = 0;
char *demangled = NULL;
int s1,s2,s3,s4;
int saved_volatile_type;
s1 = work->constructor;
s2 = work->destructor;
s3 = work->static_type;
s4 = work->const_type;
saved_volatile_type = work->volatile_type;
s4 = work->type_quals;
work->constructor = work->destructor = 0;
work->static_type = work->const_type = 0;
work->volatile_type = 0;
work->type_quals = TYPE_UNQUALIFIED;
work->dllimported = 0;
if ((mangled != NULL) && (*mangled != '\0'))
@ -718,8 +810,7 @@ internal_cplus_demangle (work, mangled)
work->constructor = s1;
work->destructor = s2;
work->static_type = s3;
work->const_type = s4;
work->volatile_type = saved_volatile_type;
work->type_quals = s4;
return (demangled);
}
@ -871,10 +962,8 @@ demangle_signature (work, mangled, declp)
case 'C':
case 'V':
if (**mangled == 'C')
work -> const_type = 1;
else
work->volatile_type = 1;
case 'u':
work->type_quals |= code_for_qualifier (**mangled);
/* a qualified member function */
if (oldmangled == NULL)
@ -1056,12 +1145,16 @@ demangle_signature (work, mangled, declp)
success = demangle_args (work, mangled, declp);
}
}
if (success && work -> static_type && PRINT_ARG_TYPES)
string_append (declp, " static");
if (success && work -> const_type && PRINT_ARG_TYPES)
string_append (declp, " const");
else if (success && work->volatile_type && PRINT_ARG_TYPES)
string_append (declp, " volatile");
if (success && PRINT_ARG_TYPES)
{
if (work->static_type)
string_append (declp, " static");
if (work->type_quals != TYPE_UNQUALIFIED)
{
APPEND_BLANK (declp);
string_append (declp, qualifier_string (work->type_quals));
}
}
return (success);
}
@ -1345,6 +1438,8 @@ demangle_template_value_parm (work, mangled, s, tk)
p [symbol_len] = '\0';
q = internal_cplus_demangle (work, p);
string_appendn (s, "&", 1);
/* FIXME: Pointer-to-member constants should get a
qualifying class name here. */
if (q)
{
string_append (s, q);
@ -2481,8 +2576,7 @@ do_type (work, mangled, result)
int success;
string decl;
const char *remembered_type;
int constp;
int volatilep;
int type_quals;
string btype;
type_kind_t tk = tk_none;
@ -2574,8 +2668,7 @@ do_type (work, mangled, result)
case 'M':
case 'O':
{
constp = 0;
volatilep = 0;
type_quals = TYPE_UNQUALIFIED;
member = **mangled == 'M';
(*mangled)++;
@ -2615,16 +2708,19 @@ do_type (work, mangled, result)
string_prepend (&decl, "(");
if (member)
{
if (**mangled == 'C')
switch (**mangled)
{
case 'C':
case 'V':
case 'u':
type_quals |= code_for_qualifier (**mangled);
(*mangled)++;
constp = 1;
}
if (**mangled == 'V')
{
(*mangled)++;
volatilep = 1;
break;
default:
break;
}
if (*(*mangled)++ != 'F')
{
success = 0;
@ -2642,15 +2738,10 @@ do_type (work, mangled, result)
{
break;
}
if (constp)
if (type_quals != TYPE_UNQUALIFIED)
{
APPEND_BLANK (&decl);
string_append (&decl, "const");
}
if (volatilep)
{
APPEND_BLANK (&decl);
string_append (&decl, "volatile");
string_append (&decl, qualifier_string (type_quals));
}
break;
}
@ -2660,18 +2751,13 @@ do_type (work, mangled, result)
case 'C':
case 'V':
/*
if ((*mangled)[1] == 'P')
{
*/
case 'u':
if (PRINT_ANSI_QUALIFIERS)
{
if (!STRING_EMPTY (&decl))
{
string_prepend (&decl, " ");
}
string_prepend (&decl,
(**mangled) == 'C' ? "const" : "volatile");
string_prepend (&decl, " ");
string_prepend (&decl, demangle_qualifier (**mangled));
}
(*mangled)++;
break;
@ -2794,11 +2880,13 @@ demangle_fund_type (work, mangled, result)
switch (**mangled)
{
case 'C':
case 'V':
case 'u':
(*mangled)++;
if (PRINT_ANSI_QUALIFIERS)
{
APPEND_BLANK (result);
string_append (result, "const");
string_append (result, demangle_qualifier (**mangled));
}
break;
case 'U':
@ -2811,14 +2899,6 @@ demangle_fund_type (work, mangled, result)
APPEND_BLANK (result);
string_append (result, "signed");
break;
case 'V':
(*mangled)++;
if (PRINT_ANSI_QUALIFIERS)
{
APPEND_BLANK (result);
string_append (result, "volatile");
}
break;
case 'J':
(*mangled)++;
APPEND_BLANK (result);