+1998-09-01 Jason Merrill <jason@yorick.cygnus.com>
+
+ * decl.c (lookup_name_real): Also do implicit typename thing for
+ artificial TYPE_DECLs.
+ * search.c (lookup_field): Likewise.
+ (lookup_fnfields, lookup_field): Adjust for implicit typename kludge.
+ * semantics.c (begin_constructor_declarator): Use enter_scope_of.
+ (enter_scope_of): Extract type from implicit typename.
+ (begin_class_definition): Likewise.
+ * lex.c (identifier_type): Handle implicit typename when checking
+ for SELFNAME.
+
+ * cp-tree.h: Declare flag_strict_prototype.
+ * lex.c (do_scoped_id, do_identifier): Don't implicitly_declare if
+ -fstrict-prototype.
+ * decl.c (init_decl_processing): If -f{no,-}strict-prototype wasn't
+ specified, set it to the value of pedantic.
+
1998-09-01 Mark Mitchell <mark@markmitchell.com>
* decl2.c (arg_assoc): Handle template-id expressions as arguments.
required. */
extern int flag_optional_diags;
+/* Nonzero means do not consider empty argument prototype to mean function
+ takes no arguments. */
+
+extern int flag_strict_prototype;
+
/* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc. */
extern int flag_vtable_gc;
\f
else if (processing_template_decl
&& classval && TREE_CODE (classval) == TYPE_DECL
&& ! currently_open_class (DECL_CONTEXT (classval))
- && uses_template_parms (current_class_type)
- && ! DECL_ARTIFICIAL (classval))
+ && uses_template_parms (current_class_type))
classval = lookup_field (current_class_type, name, 0, 1);
/* yylex() calls this with -2, since we should never start digging for
int wchar_type_size;
tree temp;
tree array_domain_type;
- extern int flag_strict_prototype;
tree vb_off_identifier = NULL_TREE;
/* Function type `char *(char *, char *)' and similar ones */
tree string_ftype_ptr_ptr, int_ftype_string_string;
current_lang_name = NULL_TREE;
if (flag_strict_prototype == 2)
- {
- if (pedantic)
- strict_prototypes_lang_c = strict_prototypes_lang_cplusplus;
- }
- else
- strict_prototypes_lang_c = flag_strict_prototype;
+ flag_strict_prototype = pedantic;
+
+ strict_prototypes_lang_c = flag_strict_prototype;
/* Initially, C. */
current_lang_name = lang_name_c;
}
-
/* Call this to end a catch block. Its responsible for emitting the
code to handle jumping back to the correct place, and for emitting
the label to jump to if this catch block didn't match. */
/* Definitions for switches for C++.
- Copyright (C) 1995 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1998 Free Software Foundation, Inc.
This file is part of GNU CC.
identifier_type (decl)
tree decl;
{
+ tree t;
if (TREE_CODE (decl) == TEMPLATE_DECL)
{
if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL)
}
if (looking_for_template && really_overloaded_fn (decl))
{
- tree t;
for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t))
if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t)))
return PFUNCNAME;
return NSNAME;
if (TREE_CODE (decl) != TYPE_DECL)
return IDENTIFIER;
- if (((got_scope && TREE_TYPE (decl) == got_scope)
- || TREE_TYPE (decl) == current_class_type)
- && DECL_ARTIFICIAL (decl))
+ if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type)
+ return SELFNAME;
+
+ /* A constructor declarator for a template type will get here as an
+ implicit typename, a TYPENAME_TYPE with a type. */
+ t = got_scope;
+ if (t && TREE_CODE (t) == TYPENAME_TYPE)
+ t = TREE_TYPE (t);
+ decl = TREE_TYPE (decl);
+ if (TREE_CODE (decl) == TYPENAME_TYPE)
+ decl = TREE_TYPE (decl);
+ if (t && t == decl)
return SELFNAME;
+
return TYPENAME;
}
cp_error ("`%D' not defined", token);
id = error_mark_node;
}
- else if (in_call)
+ else if (in_call && ! flag_strict_prototype)
{
id = implicitly_declare (token);
}
LOOKUP_EXPR_GLOBAL (id) = 1;
return id;
}
- if (parsing && (yychar == '(' || yychar == LEFT_RIGHT))
+ if (parsing && (yychar == '(' || yychar == LEFT_RIGHT)
+ && ! flag_strict_prototype)
id = implicitly_declare (token);
else
{
return 1;
}
-
/* Convert the indicated template ARG as necessary to match the
indicated template PARM. Returns the converted ARG, or
error_mark_node if the conversion was unsuccessful. Error messages
basetype_chain = TREE_CHAIN (basetype_chain);
basetype_path = TREE_VALUE (basetype_chain);
if (TREE_CHAIN (basetype_chain))
- my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path)
- == TREE_VALUE (TREE_CHAIN (basetype_chain)),
- 980827);
+ my_friendly_assert
+ ((BINFO_INHERITANCE_CHAIN (basetype_path)
+ == TREE_VALUE (TREE_CHAIN (basetype_chain)))
+ /* We only approximate base info for partial instantiations. */
+ || current_template_parms,
+ 980827);
else
my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path)
== NULL_TREE, 980827);
/* Do implicit typename stuff. */
if (rval && TREE_CODE (rval) == TYPE_DECL
- && ! DECL_ARTIFICIAL (rval)
&& processing_template_decl
&& ! currently_open_class (BINFO_TYPE (rval_binfo))
&& uses_template_parms (type))
basetype_chain = TREE_CHAIN (basetype_chain);
basetype_path = TREE_VALUE (basetype_chain);
if (TREE_CHAIN (basetype_chain))
- my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path)
- == TREE_VALUE (TREE_CHAIN (basetype_chain)),
- 980827);
+ my_friendly_assert
+ ((BINFO_INHERITANCE_CHAIN (basetype_path)
+ == TREE_VALUE (TREE_CHAIN (basetype_chain)))
+ /* We only approximate base info for partial instantiations. */
+ || current_template_parms,
+ 980827);
else
my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path)
== NULL_TREE, 980827);
tree name;
{
tree result = build_parse_node (SCOPE_REF, scope, name);
-
- if (scope != current_class_type)
- {
- push_nested_class (scope, 3);
- TREE_COMPLEXITY (result) = current_class_depth;
- }
-
+ enter_scope_of (result);
return result;
}
begin_class_definition (t)
tree t;
{
- tree new_type = t;
-
push_obstacks_nochange ();
end_temporary_allocation ();
if (t == error_mark_node
|| ! IS_AGGR_TYPE (t))
{
- t = new_type = make_lang_type (RECORD_TYPE);
+ t = make_lang_type (RECORD_TYPE);
pushtag (make_anon_name (), t, 0);
}
+
+ /* In a definition of a member class template, we will get here with an
+ implicit typename, a TYPENAME_TYPE with a type. */
+ if (TREE_CODE (t) == TYPENAME_TYPE)
+ t = TREE_TYPE (t);
+
if (TYPE_SIZE (t))
duplicate_tag_error (t);
if (TYPE_SIZE (t) || TYPE_BEING_DEFINED (t))
{
t = make_lang_type (TREE_CODE (t));
pushtag (TYPE_IDENTIFIER (t), t, 0);
- new_type = t;
}
if (processing_template_decl && TYPE_CONTEXT (t)
&& TREE_CODE (TYPE_CONTEXT (t)) != NAMESPACE_DECL
CLASSTYPE_VTABLE_NEEDS_WRITING (t) = needs_writing;
}
#if 0
- t = TYPE_IDENTIFIER ($<ttype>0);
- if (t && IDENTIFIER_TEMPLATE (t))
- overload_template_name (t, 1);
+ tmp = TYPE_IDENTIFIER ($<ttype>0);
+ if (tmp && IDENTIFIER_TEMPLATE (tmp))
+ overload_template_name (tmp, 1);
#endif
reset_specialization();
that we can get it back later. */
begin_tree ();
- return new_type;
+ return t;
}
/* Finish a class definition T, with the indicated COMPONENTS, and
}
else if (scope != current_class_type)
{
+ if (TREE_CODE (scope) == TYPENAME_TYPE)
+ {
+ /* In a declarator for a template class member, the scope will
+ get here as an implicit typename, a TYPENAME_TYPE with a type. */
+ scope = TREE_TYPE (scope);
+ TREE_OPERAND (sr, 0) = scope;
+ }
push_nested_class (scope, 3);
TREE_COMPLEXITY (sr) = current_class_depth;
}