aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/c-common.c24
-rw-r--r--gcc/c-decl.c12
-rw-r--r--gcc/c-typeck.c4
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c34
-rw-r--r--gcc/cp/parse.y4
-rw-r--r--gcc/cp/typeck.c3
-rw-r--r--gcc/tm.texi16
-rw-r--r--gcc/tree.c30
-rw-r--r--gcc/tree.h11
-rw-r--r--gcc/varasm.c37
12 files changed, 158 insertions, 40 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fd387d1..8b7ca54 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+1998-02-18 Doug Evans <devans@cygnus.com>
+
+ * tree.h (merge_machine_{type,decl}_attributes): Declare.
+ (split_specs_attrs, strip_attrs): Add prototypes.
+ * tree.c (merge_machine_{type,decl}_attributes): New functions.
+ * c-decl.c (duplicate_decls): Call merge_machine_decl_attributes.
+ Update olddecl's attributes too.
+ * c-common.c (strip_attrs): New function.
+ * c-typeck.c (common_type): Call merge_machine_type_attributes.
+ * varasm.c (make_function_rtl): New target macro REDO_SECTION_INFO_P.
+ (make_decl_rtl): Likewise.
+
+1998-02-18 Jim Wilson <wilson@cygnus.com>
+
+ * c-decl.c (shadow_tag_warned): Call split_specs_attrs.
+
Wed Feb 18 09:09:50 1998 Jeffrey A Law (law@cygnus.com)
Remove this change until we can fix it correctly.
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 0feb611..ef5f691 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -928,6 +928,30 @@ split_specs_attrs (specs_attrs, declspecs, prefix_attributes)
*declspecs = specs;
*prefix_attributes = attrs;
}
+
+/* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes.
+ This function is used by the parser when a rule will accept attributes
+ in a particular position, but we don't want to support that just yet.
+
+ A warning is issued for every ignored attribute. */
+
+tree
+strip_attrs (specs_attrs)
+ tree specs_attrs;
+{
+ tree specs, attrs;
+
+ split_specs_attrs (specs_attrs, &specs, &attrs);
+
+ while (attrs)
+ {
+ warning ("`%s' attribute ignored",
+ IDENTIFIER_POINTER (TREE_PURPOSE (attrs)));
+ attrs = TREE_CHAIN (attrs);
+ }
+
+ return specs;
+}
/* Check a printf/fprintf/sprintf/scanf/fscanf/sscanf format against
a parameter list. */
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index ed23500..c3cf4fc 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -1422,7 +1422,8 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
char *errmsg = 0;
if (TREE_CODE_CLASS (TREE_CODE (olddecl)) == 'd')
- DECL_MACHINE_ATTRIBUTES (newdecl) = DECL_MACHINE_ATTRIBUTES (olddecl);
+ DECL_MACHINE_ATTRIBUTES (newdecl)
+ = merge_machine_decl_attributes (olddecl, newdecl);
if (TREE_CODE (newtype) == ERROR_MARK
|| TREE_CODE (oldtype) == ERROR_MARK)
@@ -2000,6 +2001,10 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
DECL_UID (olddecl) = olddecl_uid;
}
+ /* NEWDECL contains the merged attribute lists.
+ Update OLDDECL to be the same. */
+ DECL_MACHINE_ATTRIBUTES (olddecl) = DECL_MACHINE_ATTRIBUTES (newdecl);
+
return 1;
}
@@ -3530,9 +3535,14 @@ shadow_tag_warned (declspecs, warned)
{
int found_tag = 0;
register tree link;
+ tree specs, attrs;
pending_invalid_xref = 0;
+ /* Remove the attributes from declspecs, since they will confuse the
+ following code. */
+ split_specs_attrs (declspecs, &specs, &attrs);
+
for (link = declspecs; link; link = TREE_CHAIN (link))
{
register tree value = TREE_VALUE (link);
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index edfc7fd..791968b 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -209,8 +209,8 @@ common_type (t1, t2)
if (t2 == error_mark_node)
return t1;
- /* Merge the attributes */
- attributes = merge_attributes (TYPE_ATTRIBUTES (t1), TYPE_ATTRIBUTES (t2));
+ /* Merge the attributes. */
+ attributes = merge_machine_type_attributes (t1, t2);
/* Treat an enum type as the unsigned integer type of the same width. */
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f7de854..bf78b63 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+1998-02-18 Doug Evans <devans@cygnus.com>
+
+ * decl.c (duplicate_decls): Call merge_machine_decl_attributes.
+ Update olddecl's attributes too.
+ (strip_attrs): Remove function.
+ * typeck.c (common_type): Call merge_machine_type_attributes.
+
Tue Feb 17 14:07:52 1998 Mark Mitchell <mmitchell@usa.net>
* parse.y (initdcl0_innards): New grammar symbol.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index c9eaeb8..ce35770d 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2444,7 +2444,8 @@ duplicate_decls (newdecl, olddecl)
return 1;
if (TREE_CODE_CLASS (TREE_CODE (olddecl)) == 'd')
- DECL_MACHINE_ATTRIBUTES (newdecl) = DECL_MACHINE_ATTRIBUTES (olddecl);
+ DECL_MACHINE_ATTRIBUTES (newdecl)
+ = merge_machine_decl_attributes (olddecl, newdecl);
types_match = decls_match (newdecl, olddecl);
@@ -3082,6 +3083,10 @@ duplicate_decls (newdecl, olddecl)
if (olddecl_friend)
DECL_FRIEND_P (olddecl) = 1;
+ /* NEWDECL contains the merged attribute lists.
+ Update OLDDECL to be the same. */
+ DECL_MACHINE_ATTRIBUTES (olddecl) = DECL_MACHINE_ATTRIBUTES (newdecl);
+
return 1;
}
@@ -13160,30 +13165,3 @@ in_function_p ()
{
return function_depth != 0;
}
-
-/* FSF LOCAL dje prefix attributes */
-/* Strip attributes from SPECS_ATTRS, a list of declspecs and attributes.
- This function is used by the parser when a rule will accept attributes
- in a particular position, but we don't want to support that just yet.
-
- A warning is issued for every ignored attribute. */
-
-tree
-strip_attrs (specs_attrs)
- tree specs_attrs;
-{
- tree specs, attrs;
-
- split_specs_attrs (specs_attrs, &specs, &attrs);
-
- while (attrs)
- {
- warning ("`%s' attribute ignored",
- IDENTIFIER_POINTER (TREE_PURPOSE (attrs)));
- attrs = TREE_CHAIN (attrs);
- }
-
- return specs;
-}
-/* END FSF LOCAL */
-
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index 9059dba..339e758 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -57,10 +57,6 @@ extern int errno;
extern int end_of_file;
extern int current_class_depth;
-/* FSF LOCAL dje prefix attributes */
-extern tree strip_attrs PROTO((tree));
-/* END FSF LOCAL */
-
/* Like YYERROR but do call yyerror. */
#define YYERROR1 { yyerror ("syntax error"); YYERROR; }
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 311c4bc..f1689a8 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -320,7 +320,8 @@ common_type (t1, t2)
if (t2 == error_mark_node)
return t1;
- /* Merge the attributes */
+ /* Merge the attributes. */
+ attributes = merge_machine_type_attributes (t1, t2);
{ register tree a1, a2;
a1 = TYPE_ATTRIBUTES (t1);
diff --git a/gcc/tm.texi b/gcc/tm.texi
index 981d0f9..d4e6d4e 100644
--- a/gcc/tm.texi
+++ b/gcc/tm.texi
@@ -7150,6 +7150,22 @@ generated).
If defined, a C statement that assigns default attributes to
newly defined @var{type}.
+@findex MERGE_MACHINE_TYPE_ATTRIBUTES
+@item MERGE_MACHINE_TYPE_ATTRIBUTES (@var{type1}, @var{type2})
+Define this macro if the merging of type attributes needs special handling.
+If defined, the result is a list of the combined TYPE_ATTRIBUTES of
+@var{type1} and @var{type2}. It is assumed that comptypes has already been
+called and returned 1.
+
+@findex MERGE_MACHINE_DECL_ATTRIBUTES
+@item MERGE_MACHINE_DECL_ATTRIBUTES (@var{olddecl}, @var{newdecl})
+Define this macro if the merging of decl attributes needs special handling.
+If defined, the result is a list of the combined DECL_MACHINE_ATTRIBUTES of
+@var{olddecl} and @var{newdecl}. @var{newdecl} is a duplicate declaration
+of @var{olddecl}. Examples of when this is needed are when one attribute
+overrides another, or when an attribute is nullified by a subsequent
+definition.
+
@findex DOLLARS_IN_IDENTIFIERS
@item DOLLARS_IN_IDENTIFIERS
Define this macro to control use of the character @samp{$} in identifier
diff --git a/gcc/tree.c b/gcc/tree.c
index 1f13532..d33563b 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -3501,6 +3501,36 @@ merge_attributes (a1, a2)
}
return attributes;
}
+
+/* Given types T1 and T2, merge their attributes and return
+ the result. */
+
+tree
+merge_machine_type_attributes (t1, t2)
+ tree t1, t2;
+{
+#ifdef MERGE_MACHINE_TYPE_ATTRIBUTES
+ return MERGE_MACHINE_TYPE_ATTRIBUTES (t1, t2);
+#else
+ return merge_attributes (TYPE_ATTRIBUTES (t1),
+ TYPE_ATTRIBUTES (t2));
+#endif
+}
+
+/* Given decls OLDDECL and NEWDECL, merge their attributes and return
+ the result. */
+
+tree
+merge_machine_decl_attributes (olddecl, newdecl)
+ tree olddecl, newdecl;
+{
+#ifdef MERGE_MACHINE_DECL_ATTRIBUTES
+ return MERGE_MACHINE_DECL_ATTRIBUTES (olddecl, newdecl);
+#else
+ return merge_attributes (DECL_MACHINE_ATTRIBUTES (olddecl),
+ DECL_MACHINE_ATTRIBUTES (newdecl));
+#endif
+}
/* Return a type like TYPE except that its TYPE_READONLY is CONSTP
and its TYPE_VOLATILE is VOLATILEP.
diff --git a/gcc/tree.h b/gcc/tree.h
index 39ec303..523a750 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1335,6 +1335,17 @@ extern tree make_tree PROTO((tree, struct rtx_def *));
extern tree build_type_attribute_variant PROTO((tree, tree));
extern tree build_decl_attribute_variant PROTO((tree, tree));
+extern tree merge_machine_decl_attributes PROTO((tree, tree));
+extern tree merge_machine_type_attributes PROTO((tree, tree));
+
+/* Split a list of declspecs and attributes into two. */
+
+extern void split_specs_attrs PROTO((tree, tree *, tree *));
+
+/* Strip attributes from a list of combined specs and attrs. */
+
+extern tree strip_attrs PROTO((tree));
+
/* Return 1 if an attribute and its arguments are valid for a decl or type. */
extern int valid_machine_attribute PROTO((tree, tree, tree, tree));
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 011b234..1129007 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -523,6 +523,20 @@ make_function_rtl (decl)
ENCODE_SECTION_INFO (decl);
#endif
}
+ else
+ {
+ /* ??? Another way to do this would be to do what halfpic.c does
+ and maintain a hashed table of such critters. */
+ /* ??? Another way to do this would be to pass a flag bit to
+ ENCODE_SECTION_INFO saying whether this is a new decl or not. */
+ /* Let the target reassign the RTL if it wants.
+ This is necessary, for example, when one machine specific
+ decl attribute overrides another. */
+#ifdef REDO_SECTION_INFO_P
+ if (REDO_SECTION_INFO_P (decl))
+ ENCODE_SECTION_INFO (decl);
+#endif
+ }
/* Record at least one function has been defined. */
function_defined = 1;
@@ -768,11 +782,26 @@ make_decl_rtl (decl, asmspec, top_level)
#endif
}
}
- /* If the old RTL had the wrong mode, fix the mode. */
- else if (GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl))
+ else
{
- rtx rtl = DECL_RTL (decl);
- PUT_MODE (rtl, DECL_MODE (decl));
+ /* If the old RTL had the wrong mode, fix the mode. */
+ if (GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl))
+ {
+ rtx rtl = DECL_RTL (decl);
+ PUT_MODE (rtl, DECL_MODE (decl));
+ }
+
+ /* ??? Another way to do this would be to do what halfpic.c does
+ and maintain a hashed table of such critters. */
+ /* ??? Another way to do this would be to pass a flag bit to
+ ENCODE_SECTION_INFO saying whether this is a new decl or not. */
+ /* Let the target reassign the RTL if it wants.
+ This is necessary, for example, when one machine specific
+ decl attribute overrides another. */
+#ifdef REDO_SECTION_INFO_P
+ if (REDO_SECTION_INFO_P (decl))
+ ENCODE_SECTION_INFO (decl);
+#endif
}
}