* cp-tree.h (build_lang_field_decl): Remove.
* class.c (build_vtable): Replace calls to build_lang_field_decl
with build_lang_decl.
(prepare_fresh_vtable): Likewise.
(finish_struct_1): Likewise.
(init_class_processing): Likewise.
* decl.c (push_using_decl): Likewise.
(init_decl_processsing): Likewise.
(grokvardecl): Likewise.
(build_ptrmemfunc_type): Likewise.
(grokdeclarator): Likewise.
(build_enumerator): Likewise.
* decl2.c (grok_x_components): Likewise.
(do_class_using_decl): Likewise.
* except.c (call_eh_info): Likewise.
* init.c (init_init_processing): Likewise.
* rtti.c (expand_class_decl): Likewise.
* tree.c (build_base_fields): Likewise.
(build_vbase_pointer_fields): Likewise.
* lex.c (build_lang_decl): Build declarations on the permanent
obstack if we're building statmeent trees.
(retrofit_lang_decl): Handle both the full lang_decl and also the
smaller lang_decl_flags here.
(build_lang_field_decl): Remove.
* pt.c (push_template_decl_real): Issue errors for variable
declarations that are not static members.
From-SVN: r28755
+1999-08-18 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (build_lang_field_decl): Remove.
+ * class.c (build_vtable): Replace calls to build_lang_field_decl
+ with build_lang_decl.
+ (prepare_fresh_vtable): Likewise.
+ (finish_struct_1): Likewise.
+ (init_class_processing): Likewise.
+ * decl.c (push_using_decl): Likewise.
+ (init_decl_processsing): Likewise.
+ (grokvardecl): Likewise.
+ (build_ptrmemfunc_type): Likewise.
+ (grokdeclarator): Likewise.
+ (build_enumerator): Likewise.
+ * decl2.c (grok_x_components): Likewise.
+ (do_class_using_decl): Likewise.
+ * except.c (call_eh_info): Likewise.
+ * init.c (init_init_processing): Likewise.
+ * rtti.c (expand_class_decl): Likewise.
+ * tree.c (build_base_fields): Likewise.
+ (build_vbase_pointer_fields): Likewise.
+ * lex.c (build_lang_decl): Build declarations on the permanent
+ obstack if we're building statmeent trees.
+ (retrofit_lang_decl): Handle both the full lang_decl and also the
+ smaller lang_decl_flags here.
+ (build_lang_field_decl): Remove.
+ * pt.c (push_template_decl_real): Issue errors for variable
+ declarations that are not static members.
+
1999-08-18 Richard Henderson <rth@cygnus.com>
* tree.c (search_tree): Handle TRUTH_{AND,OR,XOR}_EXPR too.
tree offset;
virtuals = copy_list (BINFO_VIRTUALS (binfo));
- decl = build_lang_field_decl (VAR_DECL, name,
- TREE_TYPE (BINFO_VTABLE (binfo)));
+ decl = build_lang_decl (VAR_DECL, name,
+ TREE_TYPE (BINFO_VTABLE (binfo)));
/* Now do rtti stuff. */
offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE);
else
{
virtuals = NULL_TREE;
- decl = build_lang_field_decl (VAR_DECL, name, void_type_node);
+ decl = build_lang_decl (VAR_DECL, name, void_type_node);
}
#ifdef GATHER_STATISTICS
buf2 = new_buf2;
}
- new_decl = build_lang_field_decl (VAR_DECL, name, TREE_TYPE (orig_decl));
+ new_decl = build_lang_decl (VAR_DECL, name, TREE_TYPE (orig_decl));
/* Remember which class this vtable is really for. */
DECL_CONTEXT (new_decl) = for_type;
bounds. That's better than using `void*' or some such; it's
cleaner, and it let's the alias analysis code know that these
stores cannot alias stores to void*! */
- vfield = build_lang_field_decl (FIELD_DECL, get_vfield_name (t),
+ vfield = build_lang_decl (FIELD_DECL, get_vfield_name (t),
vtbl_ptr_type_node);
/* If you change any of the below, take a look at all the
other VFIELD_BASEs and VTABLE_BASEs in the code, and change
if (empty)
{
/* C++: do not let empty structures exist. */
- tree decl = build_lang_field_decl
+ tree decl = build_lang_decl
(FIELD_DECL, NULL_TREE, char_type_node);
TREE_CHAIN (decl) = fields;
TYPE_FIELDS (t) = decl;
access_private_virtual_node = build_int_2 (7, 0);
/* Keep these values lying around. */
- base_layout_decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, error_mark_node);
+ base_layout_decl = build_lang_decl (FIELD_DECL, NULL_TREE, error_mark_node);
TREE_TYPE (base_layout_decl) = make_node (RECORD_TYPE);
gcc_obstack_init (&class_obstack);
extern int is_rid PROTO((tree));
extern tree build_lang_decl PROTO((enum tree_code, tree, tree));
extern void retrofit_lang_decl PROTO((tree));
-extern tree build_lang_field_decl PROTO((enum tree_code, tree, tree));
extern void copy_lang_decl PROTO((tree));
extern tree make_lang_type PROTO((enum tree_code));
extern void dump_time_statistics PROTO((void));
break;
if (decl)
return NULL_TREE;
- decl = build_lang_field_decl (USING_DECL, name, void_type_node);
+ decl = build_lang_decl (USING_DECL, name, void_type_node);
DECL_INITIAL (decl) = scope;
TREE_CHAIN (decl) = current_binding_level->usings;
current_binding_level->usings = decl;
else
{
vtable_entry_type = make_lang_type (RECORD_TYPE);
- fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier,
- delta_type_node);
- fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier,
- delta_type_node);
- fields[2] = build_lang_field_decl (FIELD_DECL, pfn_identifier,
- ptr_type_node);
+ fields[0] = build_lang_decl (FIELD_DECL, delta_identifier,
+ delta_type_node);
+ fields[1] = build_lang_decl (FIELD_DECL, index_identifier,
+ delta_type_node);
+ fields[2] = build_lang_decl (FIELD_DECL, pfn_identifier,
+ ptr_type_node);
finish_builtin_type (vtable_entry_type, VTBL_PTR_TYPE, fields, 2,
double_type_node);
can be initialized, the code will reach here. */
tree basetype = TYPE_OFFSET_BASETYPE (type);
type = TREE_TYPE (type);
- decl = build_lang_field_decl (VAR_DECL, declarator, type);
+ decl = build_lang_decl (VAR_DECL, declarator, type);
DECL_CONTEXT (decl) = basetype;
DECL_CLASS_CONTEXT (decl) = basetype;
DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype, declarator);
/* If we're in a template, we need DECL_LANG_SPECIFIC so that
we can call push_template_decl. */
push_permanent_obstack ();
- decl = build_lang_field_decl (VAR_DECL, declarator,
+ decl = build_lang_decl (VAR_DECL, declarator,
complete_type (type));
pop_obstacks ();
}
u = make_lang_type (UNION_TYPE);
SET_IS_AGGR_TYPE (u, 0);
- fields[0] = build_lang_field_decl (FIELD_DECL, pfn_identifier, type);
- fields[1] = build_lang_field_decl (FIELD_DECL, delta2_identifier,
- delta_type_node);
+ fields[0] = build_lang_decl (FIELD_DECL, pfn_identifier, type);
+ fields[1] = build_lang_decl (FIELD_DECL, delta2_identifier,
+ delta_type_node);
finish_builtin_type (u, "__ptrmemfunc_type", fields, 1, ptr_type_node);
TYPE_NAME (u) = NULL_TREE;
/* ... and not really an aggregate. */
SET_IS_AGGR_TYPE (t, 0);
- fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier,
- delta_type_node);
- fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier,
- delta_type_node);
- fields[2] = build_lang_field_decl (FIELD_DECL, pfn_or_delta2_identifier, u);
+ fields[0] = build_lang_decl (FIELD_DECL, delta_identifier,
+ delta_type_node);
+ fields[1] = build_lang_decl (FIELD_DECL, index_identifier,
+ delta_type_node);
+ fields[2] = build_lang_decl (FIELD_DECL, pfn_or_delta2_identifier, u);
finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node);
pop_obstacks ();
{
/* C++ allows static class members.
All other work for this is done by grokfield.
- This VAR_DECL is built by build_lang_field_decl.
+ This VAR_DECL is built by build_lang_decl.
All other VAR_DECLs are built by build_decl. */
- decl = build_lang_field_decl (VAR_DECL, declarator, type);
+ decl = build_lang_decl (VAR_DECL, declarator, type);
TREE_STATIC (decl) = 1;
/* In class context, 'static' means public access. */
TREE_PUBLIC (decl) = DECL_EXTERNAL (decl) = 1;
}
else
{
- decl = build_lang_field_decl (FIELD_DECL, declarator, type);
+ decl = build_lang_decl (FIELD_DECL, declarator, type);
if (RIDBIT_SETP (RID_MUTABLE, specbits))
{
DECL_MUTABLE_P (decl) = 1;
context = current_scope ();
if (context && context == current_class_type)
/* This enum declaration is local to the class. */
- decl = build_lang_field_decl (CONST_DECL, name, type);
+ decl = build_lang_decl (CONST_DECL, name, type);
else
/* It's a global enum, or it's local to a function. (Note local to
a function could mean local to a class method. */
return;
fixup_anonymous_aggr (t);
- finish_member_declaration (build_lang_field_decl (FIELD_DECL,
- NULL_TREE,
- t));
+ finish_member_declaration (build_lang_decl (FIELD_DECL, NULL_TREE, t));
/* Ignore any inline function definitions in the anonymous union
since an anonymous union may not have function members. */
my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716);
- value = build_lang_field_decl (USING_DECL, name, void_type_node);
+ value = build_lang_decl (USING_DECL, name, void_type_node);
DECL_INITIAL (value) = TREE_OPERAND (decl, 0);
return value;
}
/* struct cp_eh_info. This must match exception.cc. Note that this
type is not pushed anywhere. */
t1= make_lang_type (RECORD_TYPE);
- fields[0] = build_lang_field_decl (FIELD_DECL,
+ fields[0] = build_lang_decl (FIELD_DECL,
get_identifier ("handler_label"), ptr_type_node);
- fields[1] = build_lang_field_decl (FIELD_DECL,
+ fields[1] = build_lang_decl (FIELD_DECL,
get_identifier ("dynamic_handler_chain"), ptr_type_node);
- fields[2] = build_lang_field_decl (FIELD_DECL,
+ fields[2] = build_lang_decl (FIELD_DECL,
get_identifier ("info"), ptr_type_node);
- fields[3] = build_lang_field_decl (FIELD_DECL,
+ fields[3] = build_lang_decl (FIELD_DECL,
get_identifier ("table_index"), ptr_type_node);
/* N.B.: The fourth field LEN is expected to be
the number of fields - 1, not the total number of fields. */
t1 = build_pointer_type (t1);
t1= make_lang_type (RECORD_TYPE);
- fields[0] = build_lang_field_decl (FIELD_DECL,
+ fields[0] = build_lang_decl (FIELD_DECL,
get_identifier ("match_function"), ptr_type_node);
- fields[1] = build_lang_field_decl (FIELD_DECL,
+ fields[1] = build_lang_decl (FIELD_DECL,
get_identifier ("language"), short_integer_type_node);
- fields[2] = build_lang_field_decl (FIELD_DECL,
+ fields[2] = build_lang_decl (FIELD_DECL,
get_identifier ("version"), short_integer_type_node);
/* N.B.: The fourth field LEN is expected to be
the number of fields - 1, not the total number of fields. */
finish_builtin_type (t1, "__eh_info", fields, 2, ptr_type_node);
t = make_lang_type (RECORD_TYPE);
- fields[0] = build_lang_field_decl (FIELD_DECL,
- get_identifier ("eh_info"), t1);
- fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("value"),
- ptr_type_node);
- fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("type"),
- ptr_type_node);
- fields[3] = build_lang_field_decl
+ fields[0] = build_lang_decl (FIELD_DECL,
+ get_identifier ("eh_info"), t1);
+ fields[1] = build_lang_decl (FIELD_DECL, get_identifier ("value"),
+ ptr_type_node);
+ fields[2] = build_lang_decl (FIELD_DECL, get_identifier ("type"),
+ ptr_type_node);
+ fields[3] = build_lang_decl
(FIELD_DECL, get_identifier ("cleanup"),
build_pointer_type (build_function_type
(ptr_type_node, tree_cons
(NULL_TREE, ptr_type_node, void_list_node))));
- fields[4] = build_lang_field_decl (FIELD_DECL, get_identifier ("caught"),
- boolean_type_node);
- fields[5] = build_lang_field_decl (FIELD_DECL, get_identifier ("next"),
- build_pointer_type (t));
- fields[6] = build_lang_field_decl
+ fields[4] = build_lang_decl (FIELD_DECL, get_identifier ("caught"),
+ boolean_type_node);
+ fields[5] = build_lang_decl (FIELD_DECL, get_identifier ("next"),
+ build_pointer_type (t));
+ fields[6] = build_lang_decl
(FIELD_DECL, get_identifier ("handlers"), long_integer_type_node);
/* N.B.: The fourth field LEN is expected to be
the number of fields - 1, not the total number of fields. */
arrays allocated via operator new. */
BI_header_type = make_lang_type (RECORD_TYPE);
nc_nelts_field_id = get_identifier ("nelts");
- fields[0] = build_lang_field_decl (FIELD_DECL, nc_nelts_field_id, sizetype);
+ fields[0] = build_lang_decl (FIELD_DECL, nc_nelts_field_id, sizetype);
finish_builtin_type (BI_header_type, "__new_cookie", fields,
0, double_type_node);
BI_header_size = size_in_bytes (BI_header_type);
tree name;
tree type;
{
- register tree t = build_decl (code, name, type);
+ tree t;
+
+ /* When we're building statement trees, declarations need to live
+ forever. */
+ if (building_stmt_tree ())
+ push_permanent_obstack ();
+
+ t = build_decl (code, name, type);
retrofit_lang_decl (t);
+
+ if (building_stmt_tree ())
+ pop_obstacks ();
+
return t;
}
{
struct obstack *obstack = current_obstack;
struct lang_decl *ld;
+ size_t size;
- my_friendly_assert (CAN_HAVE_FULL_LANG_DECL_P (t), 19990816);
+ if (CAN_HAVE_FULL_LANG_DECL_P (t))
+ size = sizeof (struct lang_decl);
+ else
+ size = sizeof (struct lang_decl_flags);
if (! TREE_PERMANENT (t))
obstack = saveable_obstack;
/* Could be that saveable is permanent and current is not. */
obstack = &permanent_obstack;
- if (free_lang_decl_chain && obstack == &permanent_obstack)
+ if (CAN_HAVE_FULL_LANG_DECL_P (t) && free_lang_decl_chain
+ && obstack == &permanent_obstack)
{
ld = free_lang_decl_chain;
free_lang_decl_chain = free_lang_decl_chain->u.next;
}
else
- ld = ((struct lang_decl *)
- obstack_alloc (obstack, sizeof (struct lang_decl)));
+ ld = (struct lang_decl *) obstack_alloc (obstack, size);
- bzero (ld, sizeof (struct lang_decl));
+ bzero (ld, size);
DECL_LANG_SPECIFIC (t) = ld;
LANG_DECL_PERMANENT (ld) = obstack == &permanent_obstack;
my_friendly_assert (LANG_DECL_PERMANENT (ld) == TREE_PERMANENT (t), 234);
- DECL_MAIN_VARIANT (t) = t;
if (current_lang_name == lang_name_cplusplus)
DECL_LANGUAGE (t) = lang_cplusplus;
else if (current_lang_name == lang_name_c)
DECL_LANGUAGE (t) = lang_java;
else my_friendly_abort (64);
+ if (CAN_HAVE_FULL_LANG_DECL_P (t))
+ DECL_MAIN_VARIANT (t) = t;
+
#ifdef GATHER_STATISTICS
tree_node_counts[(int)lang_decl] += 1;
- tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl);
+ tree_node_sizes[(int)lang_decl] += size;
#endif
}
-/* Like build_decl, except that a new lang_decl_flags structure is
- placed in DECL_LANG_SPECIFIC. */
-
-tree
-build_lang_field_decl (code, name, type)
- enum tree_code code;
- tree name;
- tree type;
-{
- extern struct obstack *current_obstack, *saveable_obstack;
- register tree t = build_decl (code, name, type);
- struct obstack *obstack = current_obstack;
-
- if (! TREE_PERMANENT (t))
- obstack = saveable_obstack;
- else
- my_friendly_assert (obstack == &permanent_obstack, 235);
-
- my_friendly_assert (!CAN_HAVE_FULL_LANG_DECL_P (t), 19990816);
-
- DECL_LANG_SPECIFIC (t)
- = ((struct lang_decl *)
- obstack_alloc (obstack, sizeof (struct lang_decl_flags)));
- bzero (DECL_LANG_SPECIFIC (t), sizeof (struct lang_decl_flags));
- return t;
-}
-
void
copy_lang_decl (node)
tree node;
{
if (current_lang_name == lang_name_c)
cp_error ("template with C linkage");
- if (TREE_CODE (decl) == TYPE_DECL && ANON_AGGRNAME_P (DECL_NAME (decl)))
+ else if (TREE_CODE (decl) == TYPE_DECL
+ && ANON_AGGRNAME_P (DECL_NAME (decl)))
cp_error ("template class without a name");
- if (TREE_CODE (decl) == TYPE_DECL
+ else if (TREE_CODE (decl) == TYPE_DECL
&& TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
cp_error ("template declaration of `%#T'", TREE_TYPE (decl));
+ else if (TREE_CODE (decl) == VAR_DECL
+ && !CLASS_TYPE_P (CP_DECL_CONTEXT (decl)))
+ cp_error ("template declaration of `%#D'", decl);
}
/* Check to see that the rules regarding the use of default
base_info_type_node = make_lang_type (RECORD_TYPE);
/* Actually const __user_type_info * */
- fields [0] = build_lang_field_decl
+ fields [0] = build_lang_decl
(FIELD_DECL, NULL_TREE,
build_pointer_type (build_qualified_type
(type_info_type_node,
TYPE_QUAL_CONST)));
- fields [1] = build_lang_field_decl
+ fields [1] = build_lang_decl
(FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
DECL_BIT_FIELD (fields[1]) = 1;
DECL_FIELD_SIZE (fields[1]) = 29;
- fields [2] = build_lang_field_decl
+ fields [2] = build_lang_decl
(FIELD_DECL, NULL_TREE, boolean_type_node);
DECL_BIT_FIELD (fields[2]) = 1;
DECL_FIELD_SIZE (fields[2]) = 1;
/* Actually enum access */
- fields [3] = build_lang_field_decl
+ fields [3] = build_lang_decl
(FIELD_DECL, NULL_TREE, integer_type_node);
DECL_BIT_FIELD (fields[3]) = 1;
DECL_FIELD_SIZE (fields[3]) = 2;
if (TREE_VIA_VIRTUAL (base_binfo))
continue;
- decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, basetype);
+ decl = build_lang_decl (FIELD_DECL, NULL_TREE, basetype);
DECL_ARTIFICIAL (decl) = 1;
DECL_FIELD_CONTEXT (decl) = DECL_CLASS_CONTEXT (decl) = rec;
DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype);
goto got_it;
}
FORMAT_VBASE_NAME (name, basetype);
- decl = build_lang_field_decl (FIELD_DECL, get_identifier (name),
- build_pointer_type (basetype));
+ decl = build_lang_decl (FIELD_DECL, get_identifier (name),
+ build_pointer_type (basetype));
/* If you change any of the below, take a look at all the
other VFIELD_BASEs and VTABLE_BASEs in the code, and change
them too. */
--- /dev/null
+// Build don't link:
+// Origin: Jason Merrill <jason@cygnus.com>
+
+template <class T> void f()
+{
+ extern void g ();
+}
+
+int main()
+{
+ f<int>();
+}
+
--- /dev/null
+// Build don't link:
+// Origin: Jason Merrill <jason@cygnus.com>
+
+template <class T> T t; // ERROR - template declaration of t