re PR c++/9388 ([new parser] ICE in cxx_incomplete_type_diagnostic, at cp/typeck2...
authorMark Mitchell <mark@codesourcery.com>
Wed, 22 Jan 2003 17:39:15 +0000 (17:39 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Wed, 22 Jan 2003 17:39:15 +0000 (17:39 +0000)
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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/expr2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/parse/lookup2.C [new file with mode: 0644]

index 2576d5cb1dc0c5c876263b20d30a1e6f81f973a4..9ba2af9e2d20e7ac0d3cf8bd97844cc7c68805ef 100644 (file)
@@ -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.
index 40dad12a05a46f8ff7e2d4c99ecf2a4b15b8e0b3..456331f3497616e02f35c2c133fc3b4b6e7076e5 100644 (file)
@@ -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;
 
index 57f0621544a7919bfa58caf9a763a0b2135e0776..787ad0251154225294134cb59d703b3e207a9893 100644 (file)
@@ -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);
index 412678c11a50fdcf89e6983347ac5bd761721d0f..df9284c8c4990fc9f2a1e6d2d52eea34c03abeed 100644 (file)
@@ -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;
index c0376765132787aeb6a50c3a0014223991762e5d..9f391ebf0368a57b007c309c5c25e58f7a22675d 100644 (file)
@@ -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"
index 6144f2d3956f9974cfcaea3c3fbba2fe07c706d2..cbf0ad94e93452208e6ba8ecc77b4a0fe2da5944 100644 (file)
@@ -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 (file)
index 0000000..32800e4
--- /dev/null
@@ -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 (file)
index 0000000..fcf17cd
--- /dev/null
@@ -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); }
+};