summaryrefslogtreecommitdiff
path: root/gcc/cp/mangle.c
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-09 16:14:37 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-09 16:14:37 +0000
commitd4701f6c1a7673d43ac1687b1c6c856cfbf057cd (patch)
treeaf7983d092e390f212209b62a57e8d2eac7d8be6 /gcc/cp/mangle.c
parentbd7fb1f355568e00bec66b46bc3670fbcd007edb (diff)
downloadgcc-d4701f6c1a7673d43ac1687b1c6c856cfbf057cd.tar.gz
Add C++ attribute abi_tag and -Wabi-tag option.
gcc/ * attribs.c (lookup_attribute_spec): Handle getting a TREE_LIST. gcc/c-family/ * c.opt (Wabi-tag): New. gcc/cp/ * tree.c (cxx_attribute_table): Add abi_tag attribute. (check_abi_tag_redeclaration, handle_abi_tag_attribute): New. * class.c (find_abi_tags_r, check_abi_tags): New. (check_bases, check_field_decl): Call check_abi_tags. * decl.c (redeclaration_error_message): Call check_abi_tag_redeclaration. * mangle.c (tree_string_cmp, write_abi_tags): New. (write_unqualified_name): Call write_abi_tags. include/ * demangle.h (enum demangle_component_type): Add DEMANGLE_COMPONENT_TAGGED_NAME. libiberty/ * cp-demangle.c (d_dump): Handle DEMANGLE_COMPONENT_TAGGED_NAME. (d_make_comp, d_find_pack, d_print_comp): Likewise. (d_abi_tags): New. (d_name): Call it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193367 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/mangle.c')
-rw-r--r--gcc/cp/mangle.c68
1 files changed, 60 insertions, 8 deletions
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index f448932e6ea..54a4c9c4bca 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -173,6 +173,7 @@ static void mangle_call_offset (const tree, const tree);
static void write_mangled_name (const tree, bool);
static void write_encoding (const tree);
static void write_name (tree, const int);
+static void write_abi_tags (tree);
static void write_unscoped_name (const tree);
static void write_unscoped_template_name (const tree);
static void write_nested_name (const tree);
@@ -1192,15 +1193,17 @@ write_unqualified_name (const tree decl)
return;
}
+ bool found = false;
+
if (DECL_NAME (decl) == NULL_TREE)
{
+ found = true;
gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
write_source_name (DECL_ASSEMBLER_NAME (decl));
- return;
}
else if (DECL_DECLARES_FUNCTION_P (decl))
{
- bool found = true;
+ found = true;
if (DECL_CONSTRUCTOR_P (decl))
write_special_name_constructor (decl);
else if (DECL_DESTRUCTOR_P (decl))
@@ -1234,14 +1237,13 @@ write_unqualified_name (const tree decl)
write_literal_operator_name (DECL_NAME (decl));
else
found = false;
-
- if (found)
- return;
}
- if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
- && DECL_NAMESPACE_SCOPE_P (decl)
- && decl_linkage (decl) == lk_internal)
+ if (found)
+ /* OK */;
+ else if (VAR_OR_FUNCTION_DECL_P (decl) && ! TREE_PUBLIC (decl)
+ && DECL_NAMESPACE_SCOPE_P (decl)
+ && decl_linkage (decl) == lk_internal)
{
MANGLE_TRACE_TREE ("local-source-name", decl);
write_char ('L');
@@ -1262,6 +1264,11 @@ write_unqualified_name (const tree decl)
else
write_source_name (DECL_NAME (decl));
}
+
+ tree attrs = (TREE_CODE (decl) == TYPE_DECL
+ ? TYPE_ATTRIBUTES (TREE_TYPE (decl))
+ : DECL_ATTRIBUTES (decl));
+ write_abi_tags (lookup_attribute ("abi_tag", attrs));
}
/* Write the unqualified-name for a conversion operator to TYPE. */
@@ -1291,6 +1298,51 @@ write_source_name (tree identifier)
write_identifier (IDENTIFIER_POINTER (identifier));
}
+/* Compare two TREE_STRINGs like strcmp. */
+
+int
+tree_string_cmp (const void *p1, const void *p2)
+{
+ if (p1 == p2)
+ return 0;
+ tree s1 = *(const tree*)p1;
+ tree s2 = *(const tree*)p2;
+ return strcmp (TREE_STRING_POINTER (s1),
+ TREE_STRING_POINTER (s2));
+}
+
+/* ID is the name of a function or type with abi_tags attribute TAGS.
+ Write out the name, suitably decorated. */
+
+static void
+write_abi_tags (tree tags)
+{
+ if (tags == NULL_TREE)
+ return;
+
+ tags = TREE_VALUE (tags);
+
+ VEC(tree,gc)* vec = make_tree_vector();
+
+ for (tree t = tags; t; t = TREE_CHAIN (t))
+ {
+ tree str = TREE_VALUE (t);
+ VEC_safe_push (tree, gc, vec, str);
+ }
+
+ VEC_qsort (tree, vec, tree_string_cmp);
+
+ unsigned i; tree str;
+ FOR_EACH_VEC_ELT (tree, vec, i, str)
+ {
+ write_string ("B");
+ write_unsigned_number (TREE_STRING_LENGTH (str) - 1);
+ write_identifier (TREE_STRING_POINTER (str));
+ }
+
+ release_tree_vector (vec);
+}
+
/* Write a user-defined literal operator.
::= li <source-name> # "" <source-name>
IDENTIFIER is an LITERAL_IDENTIFIER_NODE. */