* decl2.c (merge_functions): Remove duplicates.
* decl2.c: Add -f{no-,}implicit-inline-templates.
(lang_decode_option): Unset it if -frepo.
(import_export_decl): Check it.
* decl.c (lookup_name_real): Template parms also take precedence
over implicit typename. Only warn if yylex.
From-SVN: r22800
1998-10-03 Jason Merrill <jason@yorick.cygnus.com>
+ * decl2.c (merge_functions): Remove duplicates.
+
+ * decl2.c: Add -f{no-,}implicit-inline-templates.
+ (lang_decode_option): Unset it if -frepo.
+ (import_export_decl): Check it.
+
+ * decl.c (lookup_name_real): Template parms also take precedence
+ over implicit typename. Only warn if yylex.
+
* typeck.c (build_conditional_expr): Only fold if ifexp is an
INTEGER_CST.
else
val = unqualified_namespace_lookup (name, flags);
+ /* Any other name takes precedence over an implicit typename. Warn the
+ user about this potentially confusing lookup. */
if (classval && TREE_CODE (val) == TYPE_DECL
&& TREE_CODE (TREE_TYPE (val)) == TYPENAME_TYPE
&& TREE_TYPE (TREE_TYPE (val)))
{
- tree nsval = unqualified_namespace_lookup (name, flags);
+ if (locval == NULL_TREE)
+ locval = unqualified_namespace_lookup (name, flags);
- if (val && nsval && TREE_CODE (nsval) == TYPE_DECL)
+ if (locval && val != locval)
{
- static int explained;
- cp_warning ("namespace-scope type `%#D'", nsval);
- cp_warning
- (" is used instead of `%D' from dependent base class", val);
- if (! explained)
+ tree subtype;
+
+ val = locval;
+
+ /* To avoid redundant warnings, only warn when lexing, and the
+ decls are significantly different. */
+ subtype = TREE_TYPE (TREE_TYPE (classval));
+ if (yylex
+ && ! (TREE_CODE (locval) == TEMPLATE_DECL
+ && CLASSTYPE_TEMPLATE_INFO (subtype)
+ && CLASSTYPE_TI_TEMPLATE (subtype) == locval)
+ && ! (TREE_CODE (locval) == TYPE_DECL
+ && comptypes (TREE_TYPE (locval), subtype, 1)))
{
- explained = 1;
- cp_warning (" (use `typename %D' if that's what you meant)",
- val);
+ static int explained;
+
+ cp_warning ("lookup of `%D' finds `%#D'", name, locval);
+ cp_warning
+ (" instead of `%D' from dependent base class", classval);
+ if (! explained)
+ {
+ explained = 1;
+ cp_warning (" (use `typename %D' if that's what you meant)",
+ classval);
+ }
}
- val = nsval;
}
}
tree string_ftype_ptr_ptr, int_ftype_string_string;
tree sizetype_endlink;
tree ptr_ftype, ptr_ftype_unsigned, ptr_ftype_sizetype;
- tree void_ftype, void_ftype_int, void_ftype_ptr, ptr_ftype_void;
+ tree void_ftype, void_ftype_int, void_ftype_ptr;
/* Have to make these distinct before we try using them. */
lang_name_cplusplus = get_identifier ("C++");
int flag_implicit_templates = 1;
+/* Nonzero means that implicit instantiations of inline templates will be
+ emitted if needed, even if instantiations of non-inline templates
+ aren't. */
+
+int flag_implicit_inline_templates = 1;
+
/* Nonzero means allow numerical priorities on constructors. */
#ifdef USE_INIT_PRIORITY
{"implement-inlines", &flag_implement_inlines, 1},
{"external-templates", &flag_external_templates, 1},
{"implicit-templates", &flag_implicit_templates, 1},
+ {"implicit-inline-templates", &flag_implicit_inline_templates, 1},
{"init-priority", &flag_init_priority, 1},
{"huge-objects", &flag_huge_objects, 1},
{"conserve-space", &flag_conserve_space, 1},
DECL_NOT_REALLY_EXTERN (decl) = 1;
if ((DECL_IMPLICIT_INSTANTIATION (decl)
|| DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl))
- && (flag_implicit_templates || DECL_THIS_INLINE (decl)))
+ && (flag_implicit_templates
+ || (flag_implicit_inline_templates && DECL_THIS_INLINE (decl))))
{
if (!TREE_PUBLIC (decl))
/* Templates are allowed to have internal linkage. See
add_using_namespace (TREE_PURPOSE (t), used, 1);
}
-/* Combines two sets of overloaded functions into an OVERLOAD chain.
- The first list becomes the tail of the result. */
+/* Combines two sets of overloaded functions into an OVERLOAD chain, removing
+ duplicates. The first list becomes the tail of the result.
+
+ The algorithm is O(n^2). */
static tree
merge_functions (s1, s2)
tree s1;
tree s2;
{
- if (TREE_CODE (s2) == OVERLOAD)
- while (s2)
- {
- s1 = build_overload (OVL_FUNCTION (s2), s1);
- s2 = OVL_CHAIN (s2);
- }
- else
- s1 = build_overload (s2, s1);
+ for (; s2; s2 = OVL_NEXT (s2))
+ {
+ tree fn = OVL_CURRENT (s2);
+ if (! ovl_member (fn, s1))
+ s1 = build_overload (fn, s1);
+ }
return s1;
}