From e5dc5fb2a55a771ebad2535e674d93cd13f81c39 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 13 Apr 1999 21:28:25 +0000 Subject: [PATCH] tree.c (cp_valid_lang_attribute): New fn. * tree.c (cp_valid_lang_attribute): New fn. Handle init_priority and com_interface. * cp-tree.h: Add prototype. * decl.c (init_decl_processing): Set valid_lang_attribute. From-SVN: r26421 --- gcc/cp/ChangeLog | 7 +++++ gcc/cp/cp-tree.h | 1 + gcc/cp/decl.c | 2 ++ gcc/cp/tree.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2cc8ffc..6a75f23 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +1999-04-13 Jason Merrill + + * tree.c (cp_valid_lang_attribute): New fn. Handle init_priority + and com_interface. + * cp-tree.h: Add prototype. + * decl.c (init_decl_processing): Set valid_lang_attribute. + 1999-04-13 Mark Mitchell * class.c (finish_struct_1): Look at the const-ness of the field's diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ab36445..240e2b0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3372,6 +3372,7 @@ extern tree build_dummy_object PROTO((tree)); extern tree maybe_dummy_object PROTO((tree, tree *)); extern int is_dummy_object PROTO((tree)); extern tree search_tree PROTO((tree, tree (*)(tree))); +extern int cp_valid_lang_attribute PROTO((tree, tree, tree, tree)); #define scratchalloc expralloc #define scratch_tree_cons expr_tree_cons diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 70f93d2..0fcad72 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -61,6 +61,7 @@ extern tree current_namespace; extern tree global_namespace; extern void (*print_error_function) PROTO((char *)); +extern int (*valid_lang_attribute) PROTO ((tree, tree, tree, tree)); /* Stack of places to restore the search obstack back to. */ @@ -6723,6 +6724,7 @@ init_decl_processing () print_error_function = lang_print_error_function; lang_get_alias_set = &c_get_alias_set; + valid_lang_attribute = cp_valid_lang_attribute; /* Maintain consistency. Perhaps we should just complain if they say -fwritable-strings? */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index d870a6b..7eceff1 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2686,3 +2686,98 @@ pod_type_p (t) return 1; } + +/* A list of objects which have constructors or destructors + which reside in the global scope. The decl is stored in + the TREE_VALUE slot and the initializer is stored + in the TREE_PURPOSE slot. */ +tree static_aggregates_initp; + +/* Return a 1 if ATTR_NAME and ATTR_ARGS denote a valid C++-specific + attribute for either declaration DECL or type TYPE and 0 otherwise. + Plugged into valid_lang_attribute. */ + +int +cp_valid_lang_attribute (attr_name, attr_args, decl, type) + tree attr_name; + tree attr_args ATTRIBUTE_UNUSED; + tree decl ATTRIBUTE_UNUSED; + tree type ATTRIBUTE_UNUSED; +{ + if (attr_name == get_identifier ("com_interface")) + { + if (! flag_vtable_thunks) + { + error ("`com_interface' only supported with -fvtable-thunks"); + return 0; + } + + if (attr_args != NULL_TREE + || decl != NULL_TREE + || ! CLASS_TYPE_P (type) + || type != TYPE_MAIN_VARIANT (type)) + { + warning ("`com_interface' attribute can only be applied to class definitions"); + return 0; + } + + CLASSTYPE_COM_INTERFACE (type) = 1; + return 1; + } + else if (attr_name == get_identifier ("init_priority")) + { + tree initp_expr = (attr_args ? TREE_VALUE (attr_args): NULL_TREE); + int pri; + + if (initp_expr) + STRIP_NOPS (initp_expr); + + if (!initp_expr || TREE_CODE (initp_expr) != INTEGER_CST) + { + error ("requested init_priority is not an integer constant"); + return 0; + } + + pri = TREE_INT_CST_LOW (initp_expr); + + while (TREE_CODE (type) == ARRAY_TYPE) + type = TREE_TYPE (type); + + if (decl == NULL_TREE + || TREE_CODE (decl) != VAR_DECL + || ! TREE_STATIC (decl) + || DECL_EXTERNAL (decl) + || (TREE_CODE (type) != RECORD_TYPE + && TREE_CODE (type) != UNION_TYPE) + /* Static objects in functions are initialized the + first time control passes through that + function. This is not precise enough to pin down an + init_priority value, so don't allow it. */ + || current_function_decl) + { + error ("can only use init_priority attribute on file-scope definitions of objects of class type"); + return 0; + } + + if (pri > MAX_INIT_PRIORITY || pri <= 0) + { + error ("requested init_priority is out of range"); + return 0; + } + + /* Check for init_priorities that are reserved for + language and runtime support implementations.*/ + if (pri <= MAX_RESERVED_INIT_PRIORITY) + { + warning + ("requested init_priority is reserved for internal use"); + } + + static_aggregates_initp + = perm_tree_cons (initp_expr, decl, static_aggregates_initp); + + return 1; + } + + return 0; +} -- 2.7.4