aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-01-22 17:39:15 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-01-22 17:39:15 +0000
commit1fb3244aad216c693e0d90f693b2ff4797b4cb63 (patch)
tree7aaeb0692ae8031ae332889f9c66fc242dcf778b /gcc
parent4888ec5d53eb1207f199f6dd6c152abb61ec9258 (diff)
downloadgcc-1fb3244aad216c693e0d90f693b2ff4797b4cb63.zip
gcc-1fb3244aad216c693e0d90f693b2ff4797b4cb63.tar.gz
gcc-1fb3244aad216c693e0d90f693b2ff4797b4cb63.tar.bz2
re PR c++/9388 ([new parser] ICE in cxx_incomplete_type_diagnostic, at cp/typeck2.c:278)
PR c++/9388 * class.c (currently_open_derived_class): Use dependent_type_p. * cp-tree.h (dependent_type_p): New function. (dependent_template_arg_p): Likewise. (dependent_template_p): Likewise. (type_dependent_expression_p): Likewise. * parser.c (cp_parser_dependent_type_p): Remove. (cp_parser_value_dependent_type_p): Likewise. (cp_parser_type_dependent_expression_p): Likewise. (cp_parser_dependent_template_arg_p): Likewise. (cp_parser_dependent_template_id_p): Likewise. (cp_parser_dependent_template_p): Likewise. (cp_parser_diagnose_invalid_type_name): Replace cp_parser_dependent_type_p with dependent_type_p, etc. (cp_parser_primary_expresion): Likewise. (cp_parser_nested_name_specifier_opt): Likewise. (cp_parser_postfix_expression): Likewise. (cp_parser_unary_expression): Likewise. (cp_parser_template_name): Likewise. (cp_parser_class_name): Likewise. (cp_parser_lookup_name): Likewise. * pt.c (dependent_type_p): New function. (value_dependent_expression_p): Likewise. (type_dependent_expression_p): Likewise. (dependent_template_arg_p): Likewise. (dependent_template_id_p): Likewise. (dependent_template_p): Likewise. PR c++/9285 PR c++/9294 * parser.c (cp_parser_simple_declaration): PR c++/9285 PR c++/9294 * g++.dg/parse/expr2.C: New test. PR c++/9388 * g++.dg/parse/lookup2.C: Likewise. From-SVN: r61596
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog34
-rw-r--r--gcc/cp/class.c4
-rw-r--r--gcc/cp/cp-tree.h4
-rw-r--r--gcc/cp/parser.c343
-rw-r--r--gcc/cp/pt.c281
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/g++.dg/parse/expr2.C8
-rw-r--r--gcc/testsuite/g++.dg/parse/lookup2.C21
8 files changed, 391 insertions, 313 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2576d5c..9ba2af9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,37 @@
+2003-01-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9388
+ * class.c (currently_open_derived_class): Use dependent_type_p.
+ * cp-tree.h (dependent_type_p): New function.
+ (dependent_template_arg_p): Likewise.
+ (dependent_template_p): Likewise.
+ (type_dependent_expression_p): Likewise.
+ * parser.c (cp_parser_dependent_type_p): Remove.
+ (cp_parser_value_dependent_type_p): Likewise.
+ (cp_parser_type_dependent_expression_p): Likewise.
+ (cp_parser_dependent_template_arg_p): Likewise.
+ (cp_parser_dependent_template_id_p): Likewise.
+ (cp_parser_dependent_template_p): Likewise.
+ (cp_parser_diagnose_invalid_type_name): Replace
+ cp_parser_dependent_type_p with dependent_type_p, etc.
+ (cp_parser_primary_expresion): Likewise.
+ (cp_parser_nested_name_specifier_opt): Likewise.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_template_name): Likewise.
+ (cp_parser_class_name): Likewise.
+ (cp_parser_lookup_name): Likewise.
+ * pt.c (dependent_type_p): New function.
+ (value_dependent_expression_p): Likewise.
+ (type_dependent_expression_p): Likewise.
+ (dependent_template_arg_p): Likewise.
+ (dependent_template_id_p): Likewise.
+ (dependent_template_p): Likewise.
+
+ PR c++/9285
+ PR c++/9294
+ * parser.c (cp_parser_simple_declaration):
+
2003-01-21 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
Make-lang.in (cp/decl.o-warn): Add -Wno-error.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 40dad12..456331f 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -6001,6 +6001,10 @@ currently_open_derived_class (t)
{
int i;
+ /* The bases of a dependent type are unknown. */
+ if (dependent_type_p (t))
+ return NULL_TREE;
+
if (DERIVED_FROM_P (t, current_class_type))
return current_class_type;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 57f0621..787ad02 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4088,6 +4088,10 @@ extern void record_last_problematic_instantiation (void);
extern tree current_instantiation (void);
extern tree maybe_get_template_decl_from_type_decl (tree);
extern int processing_template_parmlist;
+extern bool dependent_type_p (tree);
+extern bool dependent_template_arg_p (tree);
+extern bool dependent_template_p (tree);
+extern bool type_dependent_expression_p (tree);
/* in repo.c */
extern void repo_template_used (tree);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 412678c..df9284c8 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1780,18 +1780,6 @@ static bool cp_parser_is_string_literal
PARAMS ((cp_token *));
static bool cp_parser_is_keyword
PARAMS ((cp_token *, enum rid));
-static bool cp_parser_dependent_type_p
- (tree);
-static bool cp_parser_value_dependent_expression_p
- (tree);
-static bool cp_parser_type_dependent_expression_p
- (tree);
-static bool cp_parser_dependent_template_arg_p
- (tree);
-static bool cp_parser_dependent_template_id_p
- (tree, tree);
-static bool cp_parser_dependent_template_p
- (tree);
static tree cp_parser_scope_through_which_access_occurs
(tree, tree, tree);
@@ -1823,283 +1811,6 @@ cp_parser_is_keyword (token, keyword)
return token->keyword == keyword;
}
-/* Returns TRUE if TYPE is dependent, in the sense of
- [temp.dep.type]. */
-
-static bool
-cp_parser_dependent_type_p (type)
- tree type;
-{
- tree scope;
-
- if (!processing_template_decl)
- return false;
-
- /* If the type is NULL, we have not computed a type for the entity
- in question; in that case, the type is dependent. */
- if (!type)
- return true;
-
- /* Erroneous types can be considered non-dependent. */
- if (type == error_mark_node)
- return false;
-
- /* [temp.dep.type]
-
- A type is dependent if it is:
-
- -- a template parameter. */
- if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
- return true;
- /* -- a qualified-id with a nested-name-specifier which contains a
- class-name that names a dependent type or whose unqualified-id
- names a dependent type. */
- if (TREE_CODE (type) == TYPENAME_TYPE)
- return true;
- /* -- a cv-qualified type where the cv-unqualified type is
- dependent. */
- type = TYPE_MAIN_VARIANT (type);
- /* -- a compound type constructed from any dependent type. */
- if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type))
- return (cp_parser_dependent_type_p (TYPE_PTRMEM_CLASS_TYPE (type))
- || cp_parser_dependent_type_p (TYPE_PTRMEM_POINTED_TO_TYPE
- (type)));
- else if (TREE_CODE (type) == POINTER_TYPE
- || TREE_CODE (type) == REFERENCE_TYPE)
- return cp_parser_dependent_type_p (TREE_TYPE (type));
- else if (TREE_CODE (type) == FUNCTION_TYPE
- || TREE_CODE (type) == METHOD_TYPE)
- {
- tree arg_type;
-
- if (cp_parser_dependent_type_p (TREE_TYPE (type)))
- return true;
- for (arg_type = TYPE_ARG_TYPES (type);
- arg_type;
- arg_type = TREE_CHAIN (arg_type))
- if (cp_parser_dependent_type_p (TREE_VALUE (arg_type)))
- return true;
- return false;
- }
- /* -- an array type constructed from any dependent type or whose
- size is specified by a constant expression that is
- value-dependent. */
- if (TREE_CODE (type) == ARRAY_TYPE)
- {
- if (TYPE_DOMAIN (type)
- && ((cp_parser_value_dependent_expression_p
- (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
- || (cp_parser_type_dependent_expression_p
- (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))))
- return true;
- return cp_parser_dependent_type_p (TREE_TYPE (type));
- }
- /* -- a template-id in which either the template name is a template
- parameter or any of the template arguments is a dependent type or
- an expression that is type-dependent or value-dependent.
-
- This language seems somewhat confused; for example, it does not
- discuss template template arguments. Therefore, we use the
- definition for dependent template arguments in [temp.dep.temp]. */
- if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type)
- && (cp_parser_dependent_template_id_p
- (CLASSTYPE_TI_TEMPLATE (type),
- CLASSTYPE_TI_ARGS (type))))
- return true;
- else if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
- return true;
- /* All TYPEOF_TYPEs are dependent; if the argument of the `typeof'
- expression is not type-dependent, then it should already been
- have resolved. */
- if (TREE_CODE (type) == TYPEOF_TYPE)
- return true;
- /* The standard does not specifically mention types that are local
- to template functions or local classes, but they should be
- considered dependent too. For example:
-
- template <int I> void f() {
- enum E { a = I };
- S<sizeof (E)> s;
- }
-
- The size of `E' cannot be known until the value of `I' has been
- determined. Therefore, `E' must be considered dependent. */
- scope = TYPE_CONTEXT (type);
- if (scope && TYPE_P (scope))
- return cp_parser_dependent_type_p (scope);
- else if (scope && TREE_CODE (scope) == FUNCTION_DECL)
- return cp_parser_type_dependent_expression_p (scope);
-
- /* Other types are non-dependent. */
- return false;
-}
-
-/* Returns TRUE if the EXPRESSION is value-dependent. */
-
-static bool
-cp_parser_value_dependent_expression_p (tree expression)
-{
- if (!processing_template_decl)
- return false;
-
- /* A name declared with a dependent type. */
- if (DECL_P (expression)
- && cp_parser_dependent_type_p (TREE_TYPE (expression)))
- return true;
- /* A non-type template parameter. */
- if ((TREE_CODE (expression) == CONST_DECL
- && DECL_TEMPLATE_PARM_P (expression))
- || TREE_CODE (expression) == TEMPLATE_PARM_INDEX)
- return true;
- /* A constant with integral or enumeration type and is initialized
- with an expression that is value-dependent. */
- if (TREE_CODE (expression) == VAR_DECL
- && DECL_INITIAL (expression)
- && (CP_INTEGRAL_TYPE_P (TREE_TYPE (expression))
- || TREE_CODE (TREE_TYPE (expression)) == ENUMERAL_TYPE)
- && cp_parser_value_dependent_expression_p (DECL_INITIAL (expression)))
- return true;
- /* These expressions are value-dependent if the type to which the
- cast occurs is dependent. */
- if ((TREE_CODE (expression) == DYNAMIC_CAST_EXPR
- || TREE_CODE (expression) == STATIC_CAST_EXPR
- || TREE_CODE (expression) == CONST_CAST_EXPR
- || TREE_CODE (expression) == REINTERPRET_CAST_EXPR
- || TREE_CODE (expression) == CAST_EXPR)
- && cp_parser_dependent_type_p (TREE_TYPE (expression)))
- return true;
- /* A `sizeof' expression where the sizeof operand is a type is
- value-dependent if the type is dependent. If the type was not
- dependent, we would no longer have a SIZEOF_EXPR, so any
- SIZEOF_EXPR is dependent. */
- if (TREE_CODE (expression) == SIZEOF_EXPR)
- return true;
- /* A constant expression is value-dependent if any subexpression is
- value-dependent. */
- if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression))))
- {
- switch (TREE_CODE_CLASS (TREE_CODE (expression)))
- {
- case '1':
- return (cp_parser_value_dependent_expression_p
- (TREE_OPERAND (expression, 0)));
- case '<':
- case '2':
- return ((cp_parser_value_dependent_expression_p
- (TREE_OPERAND (expression, 0)))
- || (cp_parser_value_dependent_expression_p
- (TREE_OPERAND (expression, 1))));
- case 'e':
- {
- int i;
- for (i = 0;
- i < TREE_CODE_LENGTH (TREE_CODE (expression));
- ++i)
- if (cp_parser_value_dependent_expression_p
- (TREE_OPERAND (expression, i)))
- return true;
- return false;
- }
- }
- }
-
- /* The expression is not value-dependent. */
- return false;
-}
-
-/* Returns TRUE if the EXPRESSION is type-dependent, in the sense of
- [temp.dep.expr]. */
-
-static bool
-cp_parser_type_dependent_expression_p (expression)
- tree expression;
-{
- if (!processing_template_decl)
- return false;
-
- /* Some expression forms are never type-dependent. */
- if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR
- || TREE_CODE (expression) == SIZEOF_EXPR
- || TREE_CODE (expression) == ALIGNOF_EXPR
- || TREE_CODE (expression) == TYPEID_EXPR
- || TREE_CODE (expression) == DELETE_EXPR
- || TREE_CODE (expression) == VEC_DELETE_EXPR
- || TREE_CODE (expression) == THROW_EXPR)
- return false;
-
- /* The types of these expressions depends only on the type to which
- the cast occurs. */
- if (TREE_CODE (expression) == DYNAMIC_CAST_EXPR
- || TREE_CODE (expression) == STATIC_CAST_EXPR
- || TREE_CODE (expression) == CONST_CAST_EXPR
- || TREE_CODE (expression) == REINTERPRET_CAST_EXPR
- || TREE_CODE (expression) == CAST_EXPR)
- return cp_parser_dependent_type_p (TREE_TYPE (expression));
- /* The types of these expressions depends only on the type created
- by the expression. */
- else if (TREE_CODE (expression) == NEW_EXPR
- || TREE_CODE (expression) == VEC_NEW_EXPR)
- return cp_parser_dependent_type_p (TREE_OPERAND (expression, 1));
-
- if (TREE_CODE (expression) == FUNCTION_DECL
- && DECL_LANG_SPECIFIC (expression)
- && DECL_TEMPLATE_INFO (expression)
- && (cp_parser_dependent_template_id_p
- (DECL_TI_TEMPLATE (expression),
- INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
- return true;
-
- return (cp_parser_dependent_type_p (TREE_TYPE (expression)));
-}
-
-/* Returns TRUE if the ARG (a template argument) is dependent. */
-
-static bool
-cp_parser_dependent_template_arg_p (tree arg)
-{
- if (!processing_template_decl)
- return false;
-
- if (TREE_CODE (arg) == TEMPLATE_DECL
- || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
- return cp_parser_dependent_template_p (arg);
- else if (TYPE_P (arg))
- return cp_parser_dependent_type_p (arg);
- else
- return (cp_parser_type_dependent_expression_p (arg)
- || cp_parser_value_dependent_expression_p (arg));
-}
-
-/* Returns TRUE if the specialization TMPL<ARGS> is dependent. */
-
-static bool
-cp_parser_dependent_template_id_p (tree tmpl, tree args)
-{
- int i;
-
- if (cp_parser_dependent_template_p (tmpl))
- return true;
- for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
- if (cp_parser_dependent_template_arg_p (TREE_VEC_ELT (args, i)))
- return true;
- return false;
-}
-
-/* Returns TRUE if the template TMPL is dependent. */
-
-static bool
-cp_parser_dependent_template_p (tree tmpl)
-{
- /* Template template parameters are dependent. */
- if (DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)
- || TREE_CODE (tmpl) == TEMPLATE_TEMPLATE_PARM)
- return true;
- /* So are member templates of dependent classes. */
- if (TYPE_P (CP_DECL_CONTEXT (tmpl)))
- return cp_parser_dependent_type_p (DECL_CONTEXT (tmpl));
- return false;
-}
-
/* Returns the scope through which DECL is being accessed, or
NULL_TREE if DECL is not a member. If OBJECT_TYPE is non-NULL, we
have just seen `x->' or `x.' and OBJECT_TYPE is the type of `*x',
@@ -2244,7 +1955,7 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser)
{
tree base_type = BINFO_TYPE (b);
if (CLASS_TYPE_P (base_type)
- && cp_parser_dependent_type_p (base_type))
+ && dependent_type_p (base_type))
{
tree field;
/* Go from a particular instantiation of the
@@ -2941,7 +2652,7 @@ cp_parser_primary_expression (cp_parser *parser,
its type. */
else if (!is_overloaded_fn (decl))
dependent_p
- = cp_parser_dependent_type_p (TREE_TYPE (decl));
+ = dependent_type_p (TREE_TYPE (decl));
/* For a set of overloaded functions, check each of the
functions. */
else
@@ -2961,8 +2672,7 @@ cp_parser_primary_expression (cp_parser *parser,
{
while (args)
{
- if (cp_parser_dependent_template_arg_p
- (TREE_VALUE (args)))
+ if (dependent_template_arg_p (TREE_VALUE (args)))
{
dependent_p = true;
break;
@@ -2974,8 +2684,7 @@ cp_parser_primary_expression (cp_parser *parser,
{
int i;
for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
- if (cp_parser_dependent_template_arg_p
- (TREE_VEC_ELT (args, i)))
+ if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
{
dependent_p = true;
break;
@@ -2996,10 +2705,10 @@ cp_parser_primary_expression (cp_parser *parser,
/* Member functions of dependent classes are
dependent. */
if (TREE_CODE (fn) == FUNCTION_DECL
- && cp_parser_type_dependent_expression_p (fn))
+ && type_dependent_expression_p (fn))
dependent_p = true;
else if (TREE_CODE (fn) == TEMPLATE_DECL
- && cp_parser_dependent_template_p (fn))
+ && dependent_template_p (fn))
dependent_p = true;
fns = OVL_NEXT (fns);
@@ -3611,7 +3320,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
avoid doing it if the type is already complete. */
&& !COMPLETE_TYPE_P (parser->scope)
/* Do not try to complete dependent types. */
- && !cp_parser_dependent_type_p (parser->scope))
+ && !dependent_type_p (parser->scope))
complete_type (parser->scope);
}
@@ -4160,7 +3869,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
Do Koenig lookup -- unless any of the arguments are
type-dependent. */
for (arg = args; arg; arg = TREE_CHAIN (arg))
- if (cp_parser_type_dependent_expression_p (TREE_VALUE (arg)))
+ if (type_dependent_expression_p (TREE_VALUE (arg)))
break;
if (!arg)
{
@@ -4244,8 +3953,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
postfix_expression = build_x_arrow (postfix_expression);
/* Check to see whether or not the expression is
type-dependent. */
- dependent_p = (cp_parser_type_dependent_expression_p
- (postfix_expression));
+ dependent_p = (type_dependent_expression_p (postfix_expression));
/* The identifier following the `->' or `.' is not
qualified. */
parser->scope = NULL_TREE;
@@ -4554,8 +4262,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
/* If the type of the operand cannot be determined build a
SIZEOF_EXPR. */
if (TYPE_P (operand)
- ? cp_parser_dependent_type_p (operand)
- : cp_parser_type_dependent_expression_p (operand))
+ ? dependent_type_p (operand)
+ : type_dependent_expression_p (operand))
return build_min (SIZEOF_EXPR, size_type_node, operand);
/* Otherwise, compute the constant value. */
else
@@ -6776,6 +6484,15 @@ cp_parser_simple_declaration (parser, function_definition_allowed_p)
function_definition_allowed_p,
/*member_p=*/false,
&function_definition_p);
+ /* If an error occurred while parsing tentatively, exit quickly.
+ (That usually happens when in the body of a function; each
+ statement is treated as a declaration-statement until proven
+ otherwise.) */
+ if (cp_parser_error_occurred (parser))
+ {
+ pop_deferring_access_checks ();
+ return;
+ }
/* Handle function definitions specially. */
if (function_definition_p)
{
@@ -8344,7 +8061,7 @@ cp_parser_template_name (parser, template_keyword_p, check_dependency_p)
if (DECL_FUNCTION_TEMPLATE_P (decl) || !DECL_P (decl))
{
tree scope = CP_DECL_CONTEXT (get_first_fn (decl));
- if (TYPE_P (scope) && cp_parser_dependent_type_p (scope))
+ if (TYPE_P (scope) && dependent_type_p (scope))
return identifier;
}
@@ -11507,7 +11224,7 @@ cp_parser_class_name (cp_parser *parser,
/* Any name names a type if we're following the `typename' keyword
in a qualified name where the enclosing scope is type-dependent. */
typename_p = (typename_keyword_p && scope && TYPE_P (scope)
- && cp_parser_dependent_type_p (scope));
+ && dependent_type_p (scope));
/* Handle the common case (an identifier, but not a template-id)
efficiently. */
if (token->type == CPP_NAME
@@ -13456,7 +13173,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, bool check_access,
/* Perform the lookup. */
if (parser->scope)
{
- bool dependent_type_p;
+ bool dependent_p;
if (parser->scope == error_mark_node)
return error_mark_node;
@@ -13466,12 +13183,12 @@ cp_parser_lookup_name (cp_parser *parser, tree name, bool check_access,
looking up names in uninstantiated templates. Even then, we
cannot look up the name if the scope is not a class type; it
might, for example, be a template type parameter. */
- dependent_type_p = (TYPE_P (parser->scope)
- && !(parser->in_declarator_p
- && currently_open_class (parser->scope))
- && cp_parser_dependent_type_p (parser->scope));
+ dependent_p = (TYPE_P (parser->scope)
+ && !(parser->in_declarator_p
+ && currently_open_class (parser->scope))
+ && dependent_type_p (parser->scope));
if ((check_dependency || !CLASS_TYPE_P (parser->scope))
- && dependent_type_p)
+ && dependent_p)
{
if (!is_type)
decl = build_nt (SCOPE_REF, parser->scope, name);
@@ -13490,7 +13207,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, bool check_access,
otherwise, we would have processed this lookup above. So
that PARSER->SCOPE is not considered a dependent base by
lookup_member, we must enter the scope here. */
- if (dependent_type_p)
+ if (dependent_p)
push_scope (parser->scope);
/* If the PARSER->SCOPE is a a template specialization, it
may be instantiated during name lookup. In that case,
@@ -13498,7 +13215,7 @@ cp_parser_lookup_name (cp_parser *parser, tree name, bool check_access,
tentative parse, those errors are valid. */
decl = lookup_qualified_name (parser->scope, name, is_type,
/*flags=*/0);
- if (dependent_type_p)
+ if (dependent_p)
pop_scope (parser->scope);
}
parser->qualifying_scope = parser->scope;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index c037676..9f391eb 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -171,6 +171,8 @@ static void copy_default_args_to_explicit_spec PARAMS ((tree));
static int invalid_nontype_parm_type_p PARAMS ((tree, tsubst_flags_t));
static int eq_local_specializations (const void *, const void *);
static tree template_for_substitution (tree);
+static bool value_dependent_expression_p (tree);
+static bool dependent_template_id_p (tree, tree);
/* Make the current scope suitable for access checking when we are
processing T. T can be FUNCTION_DECL for instantiated function
@@ -11187,4 +11189,283 @@ invalid_nontype_parm_type_p (type, complain)
return 1;
}
+/* Returns TRUE if TYPE is dependent, in the sense of
+ [temp.dep.type]. */
+
+bool
+dependent_type_p (type)
+ tree type;
+{
+ tree scope;
+
+ /* If there are no template parameters in scope, then there can't be
+ any dependent types. */
+ if (!processing_template_decl)
+ return false;
+
+ /* If the type is NULL, we have not computed a type for the entity
+ in question; in that case, the type is dependent. */
+ if (!type)
+ return true;
+
+ /* Erroneous types can be considered non-dependent. */
+ if (type == error_mark_node)
+ return false;
+
+ /* [temp.dep.type]
+
+ A type is dependent if it is:
+
+ -- a template parameter. */
+ if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+ return true;
+ /* -- a qualified-id with a nested-name-specifier which contains a
+ class-name that names a dependent type or whose unqualified-id
+ names a dependent type. */
+ if (TREE_CODE (type) == TYPENAME_TYPE)
+ return true;
+ /* -- a cv-qualified type where the cv-unqualified type is
+ dependent. */
+ type = TYPE_MAIN_VARIANT (type);
+ /* -- a compound type constructed from any dependent type. */
+ if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type))
+ return (dependent_type_p (TYPE_PTRMEM_CLASS_TYPE (type))
+ || dependent_type_p (TYPE_PTRMEM_POINTED_TO_TYPE
+ (type)));
+ else if (TREE_CODE (type) == POINTER_TYPE
+ || TREE_CODE (type) == REFERENCE_TYPE)
+ return dependent_type_p (TREE_TYPE (type));
+ else if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)
+ {
+ tree arg_type;
+
+ if (dependent_type_p (TREE_TYPE (type)))
+ return true;
+ for (arg_type = TYPE_ARG_TYPES (type);
+ arg_type;
+ arg_type = TREE_CHAIN (arg_type))
+ if (dependent_type_p (TREE_VALUE (arg_type)))
+ return true;
+ return false;
+ }
+ /* -- an array type constructed from any dependent type or whose
+ size is specified by a constant expression that is
+ value-dependent. */
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ if (TYPE_DOMAIN (type)
+ && ((value_dependent_expression_p
+ (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
+ || (type_dependent_expression_p
+ (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))))
+ return true;
+ return dependent_type_p (TREE_TYPE (type));
+ }
+ /* -- a template-id in which either the template name is a template
+ parameter or any of the template arguments is a dependent type or
+ an expression that is type-dependent or value-dependent.
+
+ This language seems somewhat confused; for example, it does not
+ discuss template template arguments. Therefore, we use the
+ definition for dependent template arguments in [temp.dep.temp]. */
+ if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INFO (type)
+ && (dependent_template_id_p
+ (CLASSTYPE_TI_TEMPLATE (type),
+ CLASSTYPE_TI_ARGS (type))))
+ return true;
+ else if (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM)
+ return true;
+ /* All TYPEOF_TYPEs are dependent; if the argument of the `typeof'
+ expression is not type-dependent, then it should already been
+ have resolved. */
+ if (TREE_CODE (type) == TYPEOF_TYPE)
+ return true;
+ /* The standard does not specifically mention types that are local
+ to template functions or local classes, but they should be
+ considered dependent too. For example:
+
+ template <int I> void f() {
+ enum E { a = I };
+ S<sizeof (E)> s;
+ }
+
+ The size of `E' cannot be known until the value of `I' has been
+ determined. Therefore, `E' must be considered dependent. */
+ scope = TYPE_CONTEXT (type);
+ if (scope && TYPE_P (scope))
+ return dependent_type_p (scope);
+ else if (scope && TREE_CODE (scope) == FUNCTION_DECL)
+ return type_dependent_expression_p (scope);
+
+ /* Other types are non-dependent. */
+ return false;
+}
+
+/* Returns TRUE if the EXPRESSION is value-dependent. */
+
+static bool
+value_dependent_expression_p (tree expression)
+{
+ if (!processing_template_decl)
+ return false;
+
+ /* A name declared with a dependent type. */
+ if (DECL_P (expression)
+ && dependent_type_p (TREE_TYPE (expression)))
+ return true;
+ /* A non-type template parameter. */
+ if ((TREE_CODE (expression) == CONST_DECL
+ && DECL_TEMPLATE_PARM_P (expression))
+ || TREE_CODE (expression) == TEMPLATE_PARM_INDEX)
+ return true;
+ /* A constant with integral or enumeration type and is initialized
+ with an expression that is value-dependent. */
+ if (TREE_CODE (expression) == VAR_DECL
+ && DECL_INITIAL (expression)
+ && (CP_INTEGRAL_TYPE_P (TREE_TYPE (expression))
+ || TREE_CODE (TREE_TYPE (expression)) == ENUMERAL_TYPE)
+ && value_dependent_expression_p (DECL_INITIAL (expression)))
+ return true;
+ /* These expressions are value-dependent if the type to which the
+ cast occurs is dependent. */
+ if ((TREE_CODE (expression) == DYNAMIC_CAST_EXPR
+ || TREE_CODE (expression) == STATIC_CAST_EXPR
+ || TREE_CODE (expression) == CONST_CAST_EXPR
+ || TREE_CODE (expression) == REINTERPRET_CAST_EXPR
+ || TREE_CODE (expression) == CAST_EXPR)
+ && dependent_type_p (TREE_TYPE (expression)))
+ return true;
+ /* A `sizeof' expression where the sizeof operand is a type is
+ value-dependent if the type is dependent. If the type was not
+ dependent, we would no longer have a SIZEOF_EXPR, so any
+ SIZEOF_EXPR is dependent. */
+ if (TREE_CODE (expression) == SIZEOF_EXPR)
+ return true;
+ /* A constant expression is value-dependent if any subexpression is
+ value-dependent. */
+ if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression))))
+ {
+ switch (TREE_CODE_CLASS (TREE_CODE (expression)))
+ {
+ case '1':
+ return (value_dependent_expression_p
+ (TREE_OPERAND (expression, 0)));
+ case '<':
+ case '2':
+ return ((value_dependent_expression_p
+ (TREE_OPERAND (expression, 0)))
+ || (value_dependent_expression_p
+ (TREE_OPERAND (expression, 1))));
+ case 'e':
+ {
+ int i;
+ for (i = 0;
+ i < TREE_CODE_LENGTH (TREE_CODE (expression));
+ ++i)
+ if (value_dependent_expression_p
+ (TREE_OPERAND (expression, i)))
+ return true;
+ return false;
+ }
+ }
+ }
+
+ /* The expression is not value-dependent. */
+ return false;
+}
+
+/* Returns TRUE if the EXPRESSION is type-dependent, in the sense of
+ [temp.dep.expr]. */
+
+bool
+type_dependent_expression_p (expression)
+ tree expression;
+{
+ if (!processing_template_decl)
+ return false;
+
+ /* Some expression forms are never type-dependent. */
+ if (TREE_CODE (expression) == PSEUDO_DTOR_EXPR
+ || TREE_CODE (expression) == SIZEOF_EXPR
+ || TREE_CODE (expression) == ALIGNOF_EXPR
+ || TREE_CODE (expression) == TYPEID_EXPR
+ || TREE_CODE (expression) == DELETE_EXPR
+ || TREE_CODE (expression) == VEC_DELETE_EXPR
+ || TREE_CODE (expression) == THROW_EXPR)
+ return false;
+
+ /* The types of these expressions depends only on the type to which
+ the cast occurs. */
+ if (TREE_CODE (expression) == DYNAMIC_CAST_EXPR
+ || TREE_CODE (expression) == STATIC_CAST_EXPR
+ || TREE_CODE (expression) == CONST_CAST_EXPR
+ || TREE_CODE (expression) == REINTERPRET_CAST_EXPR
+ || TREE_CODE (expression) == CAST_EXPR)
+ return dependent_type_p (TREE_TYPE (expression));
+ /* The types of these expressions depends only on the type created
+ by the expression. */
+ else if (TREE_CODE (expression) == NEW_EXPR
+ || TREE_CODE (expression) == VEC_NEW_EXPR)
+ return dependent_type_p (TREE_OPERAND (expression, 1));
+
+ if (TREE_CODE (expression) == FUNCTION_DECL
+ && DECL_LANG_SPECIFIC (expression)
+ && DECL_TEMPLATE_INFO (expression)
+ && (dependent_template_id_p
+ (DECL_TI_TEMPLATE (expression),
+ INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
+ return true;
+
+ return (dependent_type_p (TREE_TYPE (expression)));
+}
+
+/* Returns TRUE if the ARG (a template argument) is dependent. */
+
+bool
+dependent_template_arg_p (tree arg)
+{
+ if (!processing_template_decl)
+ return false;
+
+ if (TREE_CODE (arg) == TEMPLATE_DECL
+ || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+ return dependent_template_p (arg);
+ else if (TYPE_P (arg))
+ return dependent_type_p (arg);
+ else
+ return (type_dependent_expression_p (arg)
+ || value_dependent_expression_p (arg));
+}
+
+/* Returns TRUE if the specialization TMPL<ARGS> is dependent. */
+
+static bool
+dependent_template_id_p (tree tmpl, tree args)
+{
+ int i;
+
+ if (dependent_template_p (tmpl))
+ return true;
+ for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
+ if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
+ return true;
+ return false;
+}
+
+/* Returns TRUE if the template TMPL is dependent. */
+
+bool
+dependent_template_p (tree tmpl)
+{
+ /* Template template parameters are dependent. */
+ if (DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)
+ || TREE_CODE (tmpl) == TEMPLATE_TEMPLATE_PARM)
+ return true;
+ /* So are member templates of dependent classes. */
+ if (TYPE_P (CP_DECL_CONTEXT (tmpl)))
+ return dependent_type_p (DECL_CONTEXT (tmpl));
+ return false;
+}
+
#include "gt-cp-pt.h"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6144f2d..cbf0ad9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2003-01-22 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/9285
+ PR c++/9294
+ * g++.dg/parse/expr2.C: New test.
+
+ PR c++/9388
+ * g++.dg/parse/lookup2.C: Likewise.
+
Tue Jan 21 18:01:35 CET 2003 Jan Hubicka <jh@suse.cz>
* gcc.c-torture/execute/990208-1.c: Add noinline attributes as needed.
diff --git a/gcc/testsuite/g++.dg/parse/expr2.C b/gcc/testsuite/g++.dg/parse/expr2.C
new file mode 100644
index 0000000..32800e4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/expr2.C
@@ -0,0 +1,8 @@
+struct X {
+ X(double *data, double d0, double d1);
+};
+
+int foo(double d0) {
+ double * data;
+ X(data,d0,d0);
+}
diff --git a/gcc/testsuite/g++.dg/parse/lookup2.C b/gcc/testsuite/g++.dg/parse/lookup2.C
new file mode 100644
index 0000000..fcf17cd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/lookup2.C
@@ -0,0 +1,21 @@
+template <typename T> struct A
+{
+ typedef int X;
+};
+
+template <typename T> struct B
+{
+ typename A<T>::X x;
+};
+
+template <typename T> struct C
+{
+ void foo(int);
+ B<A<T>*> b;
+};
+
+template <typename T> struct D
+{
+ enum { e };
+ void bar() { C<T*>::foo(e); }
+};