From 3ebc5c52e85c509f8f5a167b1eda51e0bbb01507 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 25 May 1999 15:31:38 +0000 Subject: [PATCH] class.c (finish_vtbls): Copy BINFO_VIRTUALs before using it to intialize a vtable. * class.c (finish_vtbls): Copy BINFO_VIRTUALs before using it to intialize a vtable. * cp-tree.h (NAMESPACE_LEVEL): Reformat. (lang_decl_flags): Document MEMFUNC_POINTER_TO. Save four bytes by combining TEMPLATE_INFO and LEVEL into a single union. (DECL_TEMPLATE_INFO): Reformat. (DECL_SAVED_TREE): Document. (DECL_TEMPLATE_INJECT): Remove. * class.c (finish_struct): Remove code to deal with DECL_TEMPLATE_INJECT. * decl.c (maybe_process_template_type_declaration): Handle all new types in templates uniformly. * method.c (bulid_overload_identifier): Use CP_DECL_CONTEXT, not DECL_CONTEXT. * pt.c (lookup_template_class): Inject template instantiations of forward-declarations. (instantiate_class_template): Remove code processing DECL_TEMPLATE_INJECT. * pt.c (lookup_template_class): Tweak lookup to find member templates. * pt.c (tsubst_expr, case ASM_STMT): Don't tsubst into ASM_CV_QUAL. * semantics.c (finish_asm_stmt): Make strings permanent if they're used in a template. From-SVN: r27144 --- gcc/cp/ChangeLog | 31 ++++++++++++ gcc/cp/class.c | 29 +++-------- gcc/cp/cp-tree.h | 24 +++++++-- gcc/cp/decl.c | 20 +------- gcc/cp/method.c | 4 +- gcc/cp/pt.c | 50 ++++++++----------- gcc/cp/semantics.c | 17 ++++++- gcc/testsuite/g++.old-deja/g++.pt/asm1.C | 16 ++++++ gcc/testsuite/g++.old-deja/g++.pt/asm2.C | 23 +++++++++ gcc/testsuite/g++.old-deja/g++.pt/inject1.C | 11 ++++ gcc/testsuite/g++.old-deja/g++.pt/inject2.C | 15 ++++++ .../g++.old-deja/g++.pt/memclass21.C | 11 ++++ 12 files changed, 172 insertions(+), 79 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/asm1.C create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/asm2.C create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/inject1.C create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/inject2.C create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/memclass21.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 36cb365fee5..32de5b16c04 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,34 @@ +1999-05-25 Mark Mitchell + + * class.c (finish_vtbls): Copy BINFO_VIRTUALs before using it to + intialize a vtable. + + * cp-tree.h (NAMESPACE_LEVEL): Reformat. + (lang_decl_flags): Document MEMFUNC_POINTER_TO. Save four bytes + by combining TEMPLATE_INFO and LEVEL into a single union. + (DECL_TEMPLATE_INFO): Reformat. + (DECL_SAVED_TREE): Document. + (DECL_TEMPLATE_INJECT): Remove. + * class.c (finish_struct): Remove code to deal with + DECL_TEMPLATE_INJECT. + + * decl.c (maybe_process_template_type_declaration): Handle all new + types in templates uniformly. + * method.c (bulid_overload_identifier): Use CP_DECL_CONTEXT, not + DECL_CONTEXT. + * pt.c (lookup_template_class): Inject template instantiations of + forward-declarations. + (instantiate_class_template): Remove code processing + DECL_TEMPLATE_INJECT. + + * pt.c (lookup_template_class): Tweak lookup to find member + templates. + + * pt.c (tsubst_expr, case ASM_STMT): Don't tsubst into + ASM_CV_QUAL. + * semantics.c (finish_asm_stmt): Make strings permanent if they're + used in a template. + 1999-05-25 Jason Merrill * typeck.c (casts_away_constness, casts_away_constness_r): Strip both diff --git a/gcc/cp/class.c b/gcc/cp/class.c index e3d5bb95490..c6d6bcc84e8 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -2170,9 +2170,14 @@ finish_vtbls (binfo, do_self, t) decl = BINFO_VTABLE (binfo); context = DECL_CONTEXT (decl); DECL_CONTEXT (decl) = 0; - if (DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo)) - DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, - BINFO_VIRTUALS (binfo)); + + /* We make a copy here in case we need to replace pure + virtual functions with __pure_virtual. We don't want to + mess up BINFO_VIRTUALS when we do this. */ + DECL_INITIAL (decl) = copy_list (BINFO_VIRTUALS (binfo)); + DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, + DECL_INITIAL (decl)); + cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0, 0); DECL_CONTEXT (decl) = context; } @@ -4197,24 +4202,6 @@ finish_struct (t, attributes, warn_anon) if (processing_template_decl) { - tree d = getdecls (); - for (; d; d = TREE_CHAIN (d)) - { - /* If this is the decl for the class or one of the template - parms, we've seen all the injected decls. */ - if ((TREE_CODE (d) == TYPE_DECL - && (TREE_TYPE (d) == t - || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TYPE_PARM - || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TEMPLATE_PARM)) - || TREE_CODE (d) == CONST_DECL) - break; - /* Don't inject cache decls. */ - else if (IDENTIFIER_TEMPLATE (DECL_NAME (d))) - continue; - DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)) - = tree_cons (NULL_TREE, d, - DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t))); - } finish_struct_methods (t); TYPE_SIZE (t) = integer_zero_node; } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a482824c15e..4971b7999d4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1136,7 +1136,8 @@ struct lang_type && TREE_VALUE (TYPE_RAISES_EXCEPTIONS (NODE)) == NULL_TREE) /* The binding level associated with the namespace. */ -#define NAMESPACE_LEVEL(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.level) +#define NAMESPACE_LEVEL(NODE) \ + (DECL_LANG_SPECIFIC(NODE)->decl_flags.u.level) /* If a DECL has DECL_LANG_SPECIFIC, it is either a lang_decl_flags or @@ -1180,9 +1181,19 @@ struct lang_decl_flags tree access; tree context; + + /* In a template FUNCTION_DECL, this is DECL_SAVED_TREE. + In a non-template FUNCTION_DECL, this is DECL_MEMFUNC_POINTER_TO. + In a FIELD_DECL, this is DECL_MEMFUNC_POINTING_TO. */ tree memfunc_pointer_to; - tree template_info; - struct binding_level *level; + + union { + /* In a FUNCTION_DECL, this is DECL_TEMPLATE_INFO. */ + tree template_info; + + /* In a NAMESPACE_DECL, this is NAMESPACE_LEVEL. */ + struct binding_level *level; + } u; }; struct lang_decl @@ -1392,7 +1403,8 @@ struct lang_decl #define DECL_MEMFUNC_POINTING_TO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.memfunc_pointer_to) /* For a VAR_DECL or FUNCTION_DECL: template-specific information. */ -#define DECL_TEMPLATE_INFO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.template_info) +#define DECL_TEMPLATE_INFO(NODE) \ + (DECL_LANG_SPECIFIC(NODE)->decl_flags.u.template_info) /* Template information for a RECORD_TYPE or UNION_TYPE. */ #define CLASSTYPE_TEMPLATE_INFO(NODE) (TYPE_LANG_SPECIFIC(NODE)->template_info) @@ -1475,7 +1487,10 @@ struct lang_decl the class definition is complete. */ #define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE) +/* In a template FUNCTION_DECL, the tree structure that will be + substituted into to obtain instantiations. */ #define DECL_SAVED_TREE(NODE) DECL_MEMFUNC_POINTER_TO (NODE) + #define COMPOUND_STMT_NO_SCOPE(NODE) TREE_LANG_FLAG_0 (NODE) #define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) #define DELETE_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) @@ -1898,7 +1913,6 @@ extern int flag_new_for_scope; This list is not used for static variable templates. */ #define DECL_TEMPLATE_SPECIALIZATIONS(NODE) DECL_SIZE(NODE) -#define DECL_TEMPLATE_INJECT(NODE) DECL_INITIAL(NODE) /* Nonzero for a DECL which is actually a template parameter. */ #define DECL_TEMPLATE_PARM_P(NODE) \ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index cd9955536b9..d990a82f715 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2783,25 +2783,7 @@ maybe_process_template_type_declaration (type, globalize, b) || TREE_CODE (type) == ENUMERAL_TYPE, 0); - if (/* If !GLOBALIZE then we are looking at a definition. - It may not be a primary template. (For example, in: - - template - struct S1 { class S2 {}; } - - we have to push_template_decl for S2.) */ - (processing_template_decl && !globalize) - /* If we are declaring a friend template class, we will - have GLOBALIZE set, since something like: - - template - struct S1 { - template - friend class S2; - }; - - declares S2 to be at global scope. */ - || PROCESSING_REAL_TEMPLATE_DECL_P ()) + if (processing_template_decl) { /* This may change after the call to push_template_decl_real, but we want the original value. */ diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 48701696bbd..873ccd411d2 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -999,8 +999,8 @@ build_overload_identifier (name) && CLASS_TYPE_P (TREE_TYPE (name)) && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name)) && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name))) - || (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE - (TREE_TYPE (name)))) + || (TREE_CODE (CP_DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE + (TREE_TYPE (name)))) == FUNCTION_DECL))) { /* NAME is the TYPE_DECL for a template specialization. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 702c48fab12..2592ab44598 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3613,12 +3613,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) { if (context) push_decl_namespace (context); - if (current_class_type != NULL_TREE) - template = - maybe_get_template_decl_from_type_decl - (IDENTIFIER_CLASS_VALUE (d1)); - if (template == NULL_TREE) - template = lookup_name_nonclass (d1); + template = lookup_name (d1, /*prefer_type=*/0); + template = maybe_get_template_decl_from_type_decl (template); if (context) pop_decl_namespace (); } @@ -3834,24 +3830,35 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) if (found) found = TREE_VALUE (found); } - + if (found) { pop_momentary (); return found; } - /* Since we didn't find the type, we'll have to create it. - Since we'll be saving this type on the - DECL_TEMPLATE_INSTANTIATIONS list, it must be permanent. */ - push_obstacks (&permanent_obstack, &permanent_obstack); - /* This type is a "partial instantiation" if any of the template arguments still inolve template parameters. Note that we set IS_PARTIAL_INSTANTIATION for partial specializations as well. */ is_partial_instantiation = uses_template_parms (arglist); + if (!is_partial_instantiation + && !PRIMARY_TEMPLATE_P (template) + && TREE_CODE (CP_DECL_CONTEXT (template)) == NAMESPACE_DECL) + { + pop_momentary (); + found = xref_tag_from_type (TREE_TYPE (template), + DECL_NAME (template), + /*globalize=*/1); + return found; + } + + /* Since we didn't find the type, we'll have to create it. + Since we'll be saving this type on the + DECL_TEMPLATE_INSTANTIATIONS list, it must be permanent. */ + push_obstacks (&permanent_obstack, &permanent_obstack); + /* Create the type. */ if (TREE_CODE (template_type) == ENUMERAL_TYPE) { @@ -5111,23 +5118,6 @@ instantiate_class_template (type) --processing_template_decl; } - /* This does injection for friend functions. */ - if (!processing_template_decl) - { - t = tsubst (DECL_TEMPLATE_INJECT (template), args, - /*complain=*/1, NULL_TREE); - - for (; t; t = TREE_CHAIN (t)) - { - tree d = TREE_VALUE (t); - - if (TREE_CODE (d) == TYPE_DECL) - /* Already injected. */; - else - pushdecl (d); - } - } - for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t)) if (TREE_CODE (t) == FIELD_DECL) { @@ -7200,7 +7190,7 @@ tsubst_expr (t, args, complain, in_decl) case ASM_STMT: lineno = TREE_COMPLEXITY (t); - finish_asm_stmt (tsubst_expr (ASM_CV_QUAL (t), args, complain, in_decl), + finish_asm_stmt (ASM_CV_QUAL (t), tsubst_expr (ASM_STRING (t), args, complain, in_decl), tsubst_expr (ASM_OUTPUTS (t), args, complain, in_decl), tsubst_expr (ASM_INPUTS (t), args, complain, in_decl), diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 847a982e260..5be0ae18326 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -718,7 +718,7 @@ finish_compound_stmt (has_no_scope, compound_stmt) void finish_asm_stmt (cv_qualifier, string, output_operands, - input_operands, clobbers) + input_operands, clobbers) tree cv_qualifier; tree string; tree output_operands; @@ -726,7 +726,20 @@ finish_asm_stmt (cv_qualifier, string, output_operands, tree clobbers; { if (TREE_CHAIN (string)) - string = combine_strings (string); + { + if (processing_template_decl) + { + /* We need to build the combined string on the permanent + obstack so that we can use it during instantiations. */ + push_obstacks_nochange (); + end_temporary_allocation (); + } + + string = combine_strings (string); + + if (processing_template_decl) + pop_obstacks (); + } if (processing_template_decl) { diff --git a/gcc/testsuite/g++.old-deja/g++.pt/asm1.C b/gcc/testsuite/g++.old-deja/g++.pt/asm1.C new file mode 100644 index 00000000000..d093002ff8f --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/asm1.C @@ -0,0 +1,16 @@ +// Build don't link: +// Origin: "Weidmann, Nicholas" +// Skip if not target: i?86-*-linux* + +template int foo(int v) +{ + __asm__ __volatile__("addl %1, %0" : "=a" (v) : "b" (i)); + + return v; +} + +int bar(int i) +{ + return foo<123>(i); +} + diff --git a/gcc/testsuite/g++.old-deja/g++.pt/asm2.C b/gcc/testsuite/g++.old-deja/g++.pt/asm2.C new file mode 100644 index 00000000000..4f6bd0aa856 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/asm2.C @@ -0,0 +1,23 @@ +// Build don't link: +// Origin: "Weidmann, Nicholas" +// Skip if not target: i?86-*-linux* + +typedef void (function_ptr)(int); + +void foo(int) +{ +} + +template void doit(int i) +{ + __asm__("pushl %0\n\t" + "call *%1\n\t" + "popl %0" + : + : "a" (i), "b" (ptr)); +} + +void bar() +{ + doit(123); +} diff --git a/gcc/testsuite/g++.old-deja/g++.pt/inject1.C b/gcc/testsuite/g++.old-deja/g++.pt/inject1.C new file mode 100644 index 00000000000..8d351202c2f --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/inject1.C @@ -0,0 +1,11 @@ +// Build don't link: +// Origin: Mark Mitchell + +template +struct S { + struct T* x; +}; + +template struct S<2>; + +T* t; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/inject2.C b/gcc/testsuite/g++.old-deja/g++.pt/inject2.C new file mode 100644 index 00000000000..e94ac1c5693 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/inject2.C @@ -0,0 +1,15 @@ +// Build don't link: +// Origin: Mark Mitchell +// Special g++ Options: -Wno-non-template-friend + +template +class C { + friend void f(struct X *); +}; + +template class C<0>; + +class D { + friend void f(struct X*); +}; + diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memclass21.C b/gcc/testsuite/g++.old-deja/g++.pt/memclass21.C new file mode 100644 index 00000000000..a3217e62128 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/memclass21.C @@ -0,0 +1,11 @@ +// Build don't link: +// Origin: kosak@cs.cmu.edu + +struct moo { + template struct cow {}; + + template + struct moo2 { + void func(cow &c) { } + }; +}; -- 2.30.2