* cp-tree.h (cp_cv_quals): New type.
(cp_declarator): Use it instead of "tree" as appropriate.
(grok_method_quals): Adjust prototype.
(grokclassfn): Likewise.
(do_friend): Likewise.
* decl.c (grokfndecl): Use cp_cv_quals, not tree.
(grokdeclarator): Likewise.
* decl2.c (grok_method_quals): Likewise.
(grokclassfn): Likewise.
* friend.c (do_friend): Likewise.
* method.c (implicitly_declare_fn): Adjust call to grokclassfn.
* parser.c (make_call_declarator): Use cp_cv_quals, not tree.
(make_pointer_declarator): Likewise.
(make_reference_declarator): Likewise.
(make_ptrmem_declarator): Likewise.
(cp_parser_ptr_operator): Likewise.
(cp_parser_cv_qualifier_seq_opt): Likewise.
(cp_parser_cv_qualifier_opt): Remove.
(cp_parser_new_declarator_opt): Adjust call to
cp_parser_ptr_operator.
(cp_parser_conversion_declaration_opt): Likewise.
(cp_parser_declarator): Use cp_cv_quals, not tree.
(cp_parser_direct_declarator): Likewise.
From-SVN: r83729
+2004-06-26 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (cp_cv_quals): New type.
+ (cp_declarator): Use it instead of "tree" as appropriate.
+ (grok_method_quals): Adjust prototype.
+ (grokclassfn): Likewise.
+ (do_friend): Likewise.
+ * decl.c (grokfndecl): Use cp_cv_quals, not tree.
+ (grokdeclarator): Likewise.
+ * decl2.c (grok_method_quals): Likewise.
+ (grokclassfn): Likewise.
+ * friend.c (do_friend): Likewise.
+ * method.c (implicitly_declare_fn): Adjust call to grokclassfn.
+ * parser.c (make_call_declarator): Use cp_cv_quals, not tree.
+ (make_pointer_declarator): Likewise.
+ (make_reference_declarator): Likewise.
+ (make_ptrmem_declarator): Likewise.
+ (cp_parser_ptr_operator): Likewise.
+ (cp_parser_cv_qualifier_seq_opt): Likewise.
+ (cp_parser_cv_qualifier_opt): Remove.
+ (cp_parser_new_declarator_opt): Adjust call to
+ cp_parser_ptr_operator.
+ (cp_parser_conversion_declaration_opt): Likewise.
+ (cp_parser_declarator): Use cp_cv_quals, not tree.
+ (cp_parser_direct_declarator): Likewise.
+
2004-06-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* call.c, cp-tree.h, cxx-pretty-print.c, decl.c, decl2.c:
extern GTY(()) operator_name_info_t assignment_operator_name_info
[(int) LAST_CPLUS_TREE_CODE];
+/* A type-qualifier, or bitmask therefore, using the TYPE_QUAL
+ constants. */
+
+typedef int cp_cv_quals;
+
/* A storage class. */
typedef enum cp_storage_class {
/* The parameters to the function. */
cp_parameter_declarator *parameters;
/* The cv-qualifiers for the function. */
- tree qualifiers;
+ cp_cv_quals qualifiers;
/* The exception-specification for the function. */
tree exception_specification;
} function;
/* For cdk_pointer, cdk_reference, and cdk_ptrmem. */
struct {
/* The cv-qualifiers for the pointer. */
- tree qualifiers;
+ cp_cv_quals qualifiers;
/* For cdk_ptrmem, the class type containing the member. */
tree class_type;
} pointer;
/* in decl2.c */
extern bool check_java_method (tree);
-extern int grok_method_quals (tree, tree, tree);
+extern cp_cv_quals grok_method_quals (tree, tree, cp_cv_quals);
extern void maybe_retrofit_in_chrg (tree);
extern void maybe_make_one_only (tree);
-extern void grokclassfn (tree, tree, enum overload_flags, tree);
+extern void grokclassfn (tree, tree, enum overload_flags, cp_cv_quals);
extern tree grok_array_decl (tree, tree);
extern tree delete_sanity (tree, tree, bool, int);
extern tree check_classfn (tree, tree, tree);
extern int is_friend (tree, tree);
extern void make_friend_class (tree, tree, bool);
extern void add_friend (tree, tree, bool);
-extern tree do_friend (tree, tree, tree, tree, enum overload_flags, tree, int);
+extern tree do_friend (tree, tree, tree, tree, enum overload_flags, cp_cv_quals, int);
/* in init.c */
extern tree expand_member_init (tree);
static void push_local_name (tree);
static tree grok_reference_init (tree, tree, tree, tree *);
static tree grokfndecl (tree, tree, tree, tree, tree, int,
- enum overload_flags, tree,
+ enum overload_flags, cp_cv_quals,
tree, int, int, int, int, int, int, tree);
static tree grokvardecl (tree, tree, cp_decl_specifier_seq *, int, int, tree);
static void record_unknown_type (tree, const char *);
tree orig_declarator,
int virtualp,
enum overload_flags flags,
- tree quals,
+ cp_cv_quals quals,
tree raises,
int check,
int friendp,
DECL_INLINE (decl) = 1;
DECL_EXTERNAL (decl) = 1;
- if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE)
+ if (quals && TREE_CODE (type) == FUNCTION_TYPE)
{
- error ("%smember function `%D' cannot have `%T' method qualifier",
- (ctype ? "static " : "non-"), decl, TREE_VALUE (quals));
- quals = NULL_TREE;
+ error ("%smember function `%D' cannot have cv-qualifier",
+ (ctype ? "static " : "non-"), decl);
+ quals = TYPE_UNQUALIFIED;
}
if (IDENTIFIER_OPNAME_P (DECL_NAME (decl)))
tree dname = NULL_TREE;
tree ctor_return_type = NULL_TREE;
enum overload_flags flags = NO_SPECIAL;
- tree quals = NULL_TREE;
+ cp_cv_quals quals = TYPE_UNQUALIFIED;
tree raises = NULL_TREE;
int template_count = 0;
tree returned_attrs = NULL_TREE;
}
else if (declspecs->specs[(int)ds] > 1)
{
- static const char *decl_spec_names[] = {
+ static const char *const decl_spec_names[] = {
"signed",
"unsigned",
"short",
error ("destructor cannot be static member function");
if (quals)
{
- error ("destructors may not be `%E'",
- TREE_VALUE (quals));
- quals = NULL_TREE;
+ error ("destructors may not be cv-qualified");
+ quals = TYPE_UNQUALIFIED;
}
if (decl_context == FIELD)
{
}
if (quals)
{
- error ("constructors may not be `%E'",
- TREE_VALUE (quals));
- quals = NULL_TREE;
+ error ("constructors may not be cv-qualified");
+ quals = TYPE_UNQUALIFIED;
}
if (decl_context == FIELD)
{
grok_method_quals (declarator->u.pointer.class_type,
dummy, quals);
type = TREE_TYPE (dummy);
- quals = NULL_TREE;
+ quals = TYPE_UNQUALIFIED;
}
if (declarator->kind == cdk_reference)
if (declarator->u.pointer.qualifiers)
{
- tree typemodlist;
- int erred = 0;
- int constp = 0;
- int volatilep = 0;
- int restrictp = 0;
-
- for (typemodlist = declarator->u.pointer.qualifiers; typemodlist;
- typemodlist = TREE_CHAIN (typemodlist))
- {
- tree qualifier = TREE_VALUE (typemodlist);
-
- if (qualifier == ridpointers[(int) RID_CONST])
- {
- constp++;
- type_quals |= TYPE_QUAL_CONST;
- }
- else if (qualifier == ridpointers[(int) RID_VOLATILE])
- {
- volatilep++;
- type_quals |= TYPE_QUAL_VOLATILE;
- }
- else if (qualifier == ridpointers[(int) RID_RESTRICT])
- {
- restrictp++;
- type_quals |= TYPE_QUAL_RESTRICT;
- }
- else if (!erred)
- {
- erred = 1;
- 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 = cp_build_qualified_type (type, type_quals);
+ type
+ = cp_build_qualified_type (type,
+ declarator->u.pointer.qualifiers);
type_quals = cp_type_quals (type);
}
ctype = NULL_TREE;
|| (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;
- bad_specifiers (decl, "type", virtualp, quals != NULL_TREE,
+ bad_specifiers (decl, "type", virtualp, quals != TYPE_UNQUALIFIED,
inlinep, friendp, raises != NULL_TREE);
return decl;
{
decl = cp_build_parm_decl (unqualified_id, type);
- bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE,
+ bad_specifiers (decl, "parameter", virtualp, quals != TYPE_UNQUALIFIED,
inlinep, friendp, raises != NULL_TREE);
}
else if (decl_context == FIELD)
}
}
- bad_specifiers (decl, "field", virtualp, quals != NULL_TREE,
+ bad_specifiers (decl, "field", virtualp, quals != TYPE_UNQUALIFIED,
inlinep, friendp, raises != NULL_TREE);
}
}
initialized,
(type_quals & TYPE_QUAL_CONST) != 0,
ctype ? ctype : in_namespace);
- bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE,
+ bad_specifiers (decl, "variable", virtualp, quals != TYPE_UNQUALIFIED,
inlinep, friendp, raises != NULL_TREE);
if (ctype)
TYPE_UNQUALIFIED will be an extension. */
int
-grok_method_quals (tree ctype, tree function, tree quals)
+grok_method_quals (tree ctype, tree function, cp_cv_quals quals)
{
tree fntype = TREE_TYPE (function);
tree raises = TYPE_RAISES_EXCEPTIONS (fntype);
int type_quals = TYPE_UNQUALIFIED;
- int dup_quals = TYPE_UNQUALIFIED;
int this_quals = TYPE_UNQUALIFIED;
- while (quals)
- {
- int tq = cp_type_qual_from_rid (TREE_VALUE (quals));
-
- if ((type_quals | this_quals) & tq)
- dup_quals |= tq;
- else if (tq & TYPE_QUAL_RESTRICT)
- this_quals |= tq;
- else
- type_quals |= tq;
- quals = TREE_CHAIN (quals);
- }
-
- if (dup_quals != TYPE_UNQUALIFIED)
- error ("duplicate type qualifiers in %s declaration",
- TREE_CODE (function) == FUNCTION_DECL
- ? "member function" : "type");
+ type_quals = quals & ~TYPE_QUAL_RESTRICT;
+ this_quals = quals & TYPE_QUAL_RESTRICT;
ctype = cp_build_qualified_type (ctype, type_quals);
fntype = build_method_type_directly (ctype, TREE_TYPE (fntype),
QUALS are the qualifiers for the this pointer. */
void
-grokclassfn (tree ctype, tree function, enum overload_flags flags, tree quals)
+grokclassfn (tree ctype, tree function, enum overload_flags flags,
+ cp_cv_quals quals)
{
tree fn_name = DECL_NAME (function);
- int this_quals = TYPE_UNQUALIFIED;
+ cp_cv_quals this_quals = TYPE_UNQUALIFIED;
/* Even within an `extern "C"' block, members get C++ linkage. See
[dcl.link] for details. */
tree
do_friend (tree ctype, tree declarator, tree decl,
- tree attrlist, enum overload_flags flags, tree quals,
+ tree attrlist, enum overload_flags flags,
+ cp_cv_quals quals,
int funcdef_flag)
{
/* Every decl that gets here is a friend of something. */
}
grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL,
- /*quals=*/NULL_TREE);
+ TYPE_UNQUALIFIED);
grok_special_member_properties (fn);
cp_finish_decl (fn, /*init=*/NULL_TREE, /*asmspec_tree=*/NULL_TREE,
/*flags=*/LOOKUP_ONLYCONVERTING);
static cp_declarator *make_id_declarator
(tree);
static cp_declarator *make_call_declarator
- (cp_declarator *, cp_parameter_declarator *, tree, tree);
+ (cp_declarator *, cp_parameter_declarator *, cp_cv_quals, tree);
static cp_declarator *make_array_declarator
(cp_declarator *, tree);
static cp_declarator *make_pointer_declarator
- (tree, cp_declarator *);
+ (cp_cv_quals, cp_declarator *);
static cp_declarator *make_reference_declarator
- (tree, cp_declarator *);
+ (cp_cv_quals, cp_declarator *);
static cp_parameter_declarator *make_parameter_declarator
(cp_decl_specifier_seq *, cp_declarator *, tree);
static cp_declarator *make_ptrmem_declarator
- (tree, tree, cp_declarator *);
+ (cp_cv_quals, tree, cp_declarator *);
cp_declarator *cp_error_declarator;
type, represented as identifiers. */
cp_declarator *
-make_pointer_declarator (tree cv_qualifiers, cp_declarator *target)
+make_pointer_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target)
{
cp_declarator *declarator;
/* Like make_pointer_declarator -- but for references. */
cp_declarator *
-make_reference_declarator (tree cv_qualifiers, cp_declarator *target)
+make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target)
{
cp_declarator *declarator;
member of CLASS_TYPE. */
cp_declarator *
-make_ptrmem_declarator (tree cv_qualifiers, tree class_type,
+make_ptrmem_declarator (cp_cv_quals cv_qualifiers, tree class_type,
cp_declarator *pointee)
{
cp_declarator *declarator;
cp_declarator *
make_call_declarator (cp_declarator *target,
cp_parameter_declarator *parms,
- tree cv_qualifiers,
+ cp_cv_quals cv_qualifiers,
tree exception_specification)
{
cp_declarator *declarator;
static cp_declarator *cp_parser_direct_declarator
(cp_parser *, cp_parser_declarator_kind, int *);
static enum tree_code cp_parser_ptr_operator
- (cp_parser *, tree *, tree *);
-static tree cp_parser_cv_qualifier_seq_opt
- (cp_parser *);
-static tree cp_parser_cv_qualifier_opt
+ (cp_parser *, tree *, cp_cv_quals *);
+static cp_cv_quals cp_parser_cv_qualifier_seq_opt
(cp_parser *);
static tree cp_parser_declarator_id
(cp_parser *);
{
enum tree_code code;
tree type;
- tree cv_qualifier_seq;
+ cp_cv_quals cv_quals;
/* We don't know if there's a ptr-operator next, or not. */
cp_parser_parse_tentatively (parser);
/* Look for a ptr-operator. */
- code = cp_parser_ptr_operator (parser, &type, &cv_qualifier_seq);
+ code = cp_parser_ptr_operator (parser, &type, &cv_quals);
/* If that worked, look for more new-declarators. */
if (cp_parser_parse_definitely (parser))
{
/* Create the representation of the declarator. */
if (type)
- declarator = make_ptrmem_declarator (cv_qualifier_seq,
- type,
- declarator);
+ declarator = make_ptrmem_declarator (cv_quals, type, declarator);
else if (code == INDIRECT_REF)
- declarator = make_pointer_declarator (cv_qualifier_seq,
- declarator);
+ declarator = make_pointer_declarator (cv_quals, declarator);
else
- declarator = make_reference_declarator (cv_qualifier_seq,
- declarator);
+ declarator = make_reference_declarator (cv_quals, declarator);
return declarator;
}
{
enum tree_code code;
tree class_type;
- tree cv_qualifier_seq;
+ cp_cv_quals cv_quals;
/* We don't know if there's a ptr-operator next, or not. */
cp_parser_parse_tentatively (parser);
/* Try the ptr-operator. */
- code = cp_parser_ptr_operator (parser, &class_type,
- &cv_qualifier_seq);
+ code = cp_parser_ptr_operator (parser, &class_type, &cv_quals);
/* If it worked, look for more conversion-declarators. */
if (cp_parser_parse_definitely (parser))
{
/* Create the representation of the declarator. */
if (class_type)
- declarator = make_ptrmem_declarator (cv_qualifier_seq,
- class_type,
+ declarator = make_ptrmem_declarator (cv_quals, class_type,
declarator);
else if (code == INDIRECT_REF)
- declarator = make_pointer_declarator (cv_qualifier_seq,
- declarator);
+ declarator = make_pointer_declarator (cv_quals, declarator);
else
- declarator = make_reference_declarator (cv_qualifier_seq,
- declarator);
+ declarator = make_reference_declarator (cv_quals, declarator);
return declarator;
}
cp_token *token;
cp_declarator *declarator;
enum tree_code code;
- tree cv_qualifier_seq;
+ cp_cv_quals cv_quals;
tree class_type;
tree attributes = NULL_TREE;
/* Parse the ptr-operator. */
code = cp_parser_ptr_operator (parser,
&class_type,
- &cv_qualifier_seq);
+ &cv_quals);
/* If that worked, then we have a ptr-operator. */
if (cp_parser_parse_definitely (parser))
{
/* Build the representation of the ptr-operator. */
if (class_type)
- declarator = make_ptrmem_declarator (cv_qualifier_seq,
+ declarator = make_ptrmem_declarator (cv_quals,
class_type,
declarator);
else if (code == INDIRECT_REF)
- declarator = make_pointer_declarator (cv_qualifier_seq,
- declarator);
+ declarator = make_pointer_declarator (cv_quals, declarator);
else
- declarator = make_reference_declarator (cv_qualifier_seq,
- declarator);
+ declarator = make_reference_declarator (cv_quals, declarator);
}
/* Everything else is a direct-declarator. */
else
exception-specification. */
if (cp_parser_parse_definitely (parser))
{
- tree cv_qualifiers;
+ cp_cv_quals cv_quals;
tree exception_specification;
if (ctor_dtor_or_conv_p)
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
/* Parse the cv-qualifier-seq. */
- cv_qualifiers = cp_parser_cv_qualifier_seq_opt (parser);
+ cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
/* And the exception-specification. */
exception_specification
= cp_parser_exception_specification_opt (parser);
/* Create the function-declarator. */
declarator = make_call_declarator (declarator,
params,
- cv_qualifiers,
+ cv_quals,
exception_specification);
/* Any subsequent parameter lists are to do with
return type, so are not those of the declared
ptr-operator:
& cv-qualifier-seq [opt]
- Returns INDIRECT_REF if a pointer, or pointer-to-member, was
- used. Returns ADDR_EXPR if a reference was used. In the
- case of a pointer-to-member, *TYPE is filled in with the
- TYPE containing the member. *CV_QUALIFIER_SEQ is filled in
- with the cv-qualifier-seq, or NULL_TREE, if there are no
- cv-qualifiers. Returns ERROR_MARK if an error occurred. */
+ Returns INDIRECT_REF if a pointer, or pointer-to-member, was used.
+ Returns ADDR_EXPR if a reference was used. In the case of a
+ pointer-to-member, *TYPE is filled in with the TYPE containing the
+ member. *CV_QUALS is filled in with the cv-qualifier-seq, or
+ TYPE_UNQUALIFIED, if there are no cv-qualifiers. Returns
+ ERROR_MARK if an error occurred. */
static enum tree_code
cp_parser_ptr_operator (cp_parser* parser,
tree* type,
- tree* cv_qualifier_seq)
+ cp_cv_quals *cv_quals)
{
enum tree_code code = ERROR_MARK;
cp_token *token;
/* Assume that it's not a pointer-to-member. */
*type = NULL_TREE;
/* And that there are no cv-qualifiers. */
- *cv_qualifier_seq = NULL_TREE;
+ *cv_quals = TYPE_UNQUALIFIED;
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
enforced during semantic analysis. */
if (code == INDIRECT_REF
|| cp_parser_allow_gnu_extensions_p (parser))
- *cv_qualifier_seq = cp_parser_cv_qualifier_seq_opt (parser);
+ *cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
}
else
{
/* Indicate that the `*' operator was used. */
code = INDIRECT_REF;
/* Look for the optional cv-qualifier-seq. */
- *cv_qualifier_seq = cp_parser_cv_qualifier_seq_opt (parser);
+ *cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
}
/* If that didn't work we don't have a ptr-operator. */
if (!cp_parser_parse_definitely (parser))
cv-qualifier-seq:
cv-qualifier cv-qualifier-seq [opt]
- Returns a TREE_LIST. The TREE_VALUE of each node is the
- representation of a cv-qualifier. */
-
-static tree
-cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
-{
- tree cv_qualifiers = NULL_TREE;
-
- while (true)
- {
- tree cv_qualifier;
-
- /* Look for the next cv-qualifier. */
- cv_qualifier = cp_parser_cv_qualifier_opt (parser);
- /* If we didn't find one, we're done. */
- if (!cv_qualifier)
- break;
-
- /* Add this cv-qualifier to the list. */
- cv_qualifiers
- = tree_cons (NULL_TREE, cv_qualifier, cv_qualifiers);
- }
-
- /* We built up the list in reverse order. */
- return nreverse (cv_qualifiers);
-}
-
-/* Parse an (optional) cv-qualifier.
-
cv-qualifier:
const
volatile
GNU Extension:
cv-qualifier:
- __restrict__ */
+ __restrict__
-static tree
-cp_parser_cv_qualifier_opt (cp_parser* parser)
+ Returns a bitmask representing the cv-qualifiers. */
+
+static cp_cv_quals
+cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
{
- cp_token *token;
- tree cv_qualifier = NULL_TREE;
+ cp_cv_quals cv_quals = TYPE_UNQUALIFIED;
- /* Peek at the next token. */
- token = cp_lexer_peek_token (parser->lexer);
- /* See if it's a cv-qualifier. */
- switch (token->keyword)
+ while (true)
{
- case RID_CONST:
- case RID_VOLATILE:
- case RID_RESTRICT:
- /* Save the value of the token. */
- cv_qualifier = token->value;
- /* Consume the token. */
- cp_lexer_consume_token (parser->lexer);
- break;
+ cp_token *token;
+ cp_cv_quals cv_qualifier;
+
+ /* Peek at the next token. */
+ token = cp_lexer_peek_token (parser->lexer);
+ /* See if it's a cv-qualifier. */
+ switch (token->keyword)
+ {
+ case RID_CONST:
+ cv_qualifier = TYPE_QUAL_CONST;
+ break;
+
+ case RID_VOLATILE:
+ cv_qualifier = TYPE_QUAL_VOLATILE;
+ break;
+
+ case RID_RESTRICT:
+ cv_qualifier = TYPE_QUAL_RESTRICT;
+ break;
+
+ default:
+ cv_qualifier = TYPE_UNQUALIFIED;
+ break;
+ }
+
+ if (!cv_qualifier)
+ break;
- default:
- break;
+ if (cv_quals & cv_qualifier)
+ {
+ error ("duplicate cv-qualifier");
+ cp_lexer_purge_token (parser->lexer);
+ }
+ else
+ {
+ cp_lexer_consume_token (parser->lexer);
+ cv_quals |= cv_qualifier;
+ }
}
- return cv_qualifier;
+ return cv_quals;
}
/* Parse a declarator-id.