aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-06-29 17:19:31 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-06-29 17:19:31 -0400
commit417ae187142e16f8c697d68495614ca07e947636 (patch)
tree75c88014994e59c28429b6a5dced3b345cb8ed38 /gcc/cp
parent3fe98897323ab6672dcfb765272fbdb2bdab1015 (diff)
downloadgcc-417ae187142e16f8c697d68495614ca07e947636.zip
gcc-417ae187142e16f8c697d68495614ca07e947636.tar.gz
gcc-417ae187142e16f8c697d68495614ca07e947636.tar.bz2
DR 1207 PR c++/49003
DR 1207 PR c++/49003 * cp-tree.h (struct saved_scope): Add x_current_class_ptr, x_current_class_ref. (current_class_ptr, current_class_ref): Use them. * decl.c (build_this_parm): Handle getting the class type. * parser.c (cp_parser_late_return_type_opt): Set up 'this' for use within the trailing return type. From-SVN: r175671
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h18
-rw-r--r--gcc/cp/decl.c10
-rw-r--r--gcc/cp/parser.c25
4 files changed, 51 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f06c257..c5751bd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,14 @@
2011-06-29 Jason Merrill <jason@redhat.com>
+ DR 1207
+ PR c++/49003
+ * cp-tree.h (struct saved_scope): Add x_current_class_ptr,
+ x_current_class_ref.
+ (current_class_ptr, current_class_ref): Use them.
+ * decl.c (build_this_parm): Handle getting the class type.
+ * parser.c (cp_parser_late_return_type_opt): Set up 'this'
+ for use within the trailing return type.
+
* pt.c (tsubst_decl) [VAR_DECL]: In unevaluated operand,
don't tsubst DECL_INITIAL unless our type use auto.
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 55c88e3..ef25c97 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -953,6 +953,10 @@ struct GTY(()) saved_scope {
struct cp_binding_level *x_previous_class_level;
tree x_saved_tree;
+ /* Only used for uses of this in trailing return type. */
+ tree x_current_class_ptr;
+ tree x_current_class_ref;
+
int x_processing_template_decl;
int x_processing_specialization;
BOOL_BITFIELD x_processing_explicit_instantiation : 1;
@@ -1070,12 +1074,14 @@ struct GTY(()) language_function {
PARM_DECL for the `this' pointer. The current_class_ref is an
expression for `*this'. */
-#define current_class_ptr \
- (cfun && cp_function_chain \
- ? cp_function_chain->x_current_class_ptr : NULL_TREE)
-#define current_class_ref \
- ((cfun && cp_function_chain) \
- ? cp_function_chain->x_current_class_ref : NULL_TREE)
+#define current_class_ptr \
+ (*(cfun && cp_function_chain \
+ ? &cp_function_chain->x_current_class_ptr \
+ : &scope_chain->x_current_class_ptr))
+#define current_class_ref \
+ (*(cfun && cp_function_chain \
+ ? &cp_function_chain->x_current_class_ref \
+ : &scope_chain->x_current_class_ref))
/* The EH_SPEC_BLOCK for the exception-specifiers for the current
function, if any. */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index b8435a6..94d686d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7001,7 +7001,14 @@ build_this_parm (tree type, cp_cv_quals quals)
tree parm;
cp_cv_quals this_quals;
- this_type = type_of_this_parm (type);
+ if (CLASS_TYPE_P (type))
+ {
+ this_type
+ = cp_build_qualified_type (type, quals & ~TYPE_QUAL_RESTRICT);
+ this_type = build_pointer_type (this_type);
+ }
+ else
+ this_type = type_of_this_parm (type);
/* The `this' parameter is implicitly `const'; it cannot be
assigned to. */
this_quals = (quals & TYPE_QUAL_RESTRICT) | TYPE_QUAL_CONST;
@@ -12675,6 +12682,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
cp_function_chain->x_current_class_ref
= cp_build_indirect_ref (t, RO_NULL, tf_warning_or_error);
+ /* Set this second to avoid shortcut in cp_build_indirect_ref. */
cp_function_chain->x_current_class_ptr = t;
/* Constructors and destructors need to know whether they're "in
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index f1b7976..d79326d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1696,7 +1696,7 @@ static cp_cv_quals cp_parser_cv_qualifier_seq_opt
static cp_virt_specifiers cp_parser_virt_specifier_seq_opt
(cp_parser *);
static tree cp_parser_late_return_type_opt
- (cp_parser *);
+ (cp_parser *, cp_cv_quals);
static tree cp_parser_declarator_id
(cp_parser *, bool);
static tree cp_parser_type_id
@@ -14968,7 +14968,7 @@ cp_parser_direct_declarator (cp_parser* parser,
virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);
late_return
- = cp_parser_late_return_type_opt (parser);
+ = cp_parser_late_return_type_opt (parser, cv_quals);
/* Create the function-declarator. */
declarator = make_call_declarator (declarator,
@@ -15537,9 +15537,10 @@ cp_parser_virt_specifier_seq_opt (cp_parser* parser)
Returns the type indicated by the type-id. */
static tree
-cp_parser_late_return_type_opt (cp_parser* parser)
+cp_parser_late_return_type_opt (cp_parser* parser, cp_cv_quals quals)
{
cp_token *token;
+ tree type;
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
@@ -15550,7 +15551,23 @@ cp_parser_late_return_type_opt (cp_parser* parser)
/* Consume the ->. */
cp_lexer_consume_token (parser->lexer);
- return cp_parser_trailing_type_id (parser);
+ if (current_class_type)
+ {
+ /* DR 1207: 'this' is in scope in the trailing return type. */
+ tree this_parm = build_this_parm (current_class_type, quals);
+ gcc_assert (current_class_ptr == NULL_TREE);
+ current_class_ref
+ = cp_build_indirect_ref (this_parm, RO_NULL, tf_warning_or_error);
+ /* Set this second to avoid shortcut in cp_build_indirect_ref. */
+ current_class_ptr = this_parm;
+ }
+
+ type = cp_parser_trailing_type_id (parser);
+
+ if (current_class_type)
+ current_class_ptr = current_class_ref = NULL_TREE;
+
+ return type;
}
/* Parse a declarator-id.