diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-09 16:14:37 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-09 16:14:37 +0000 |
commit | d4701f6c1a7673d43ac1687b1c6c856cfbf057cd (patch) | |
tree | af7983d092e390f212209b62a57e8d2eac7d8be6 /gcc/cp/mangle.c | |
parent | bd7fb1f355568e00bec66b46bc3670fbcd007edb (diff) | |
download | gcc-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.c | 68 |
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. */ |