diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-03-19 19:31:48 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-03-19 19:31:48 +0000 |
commit | 527cb890236ba086bd262d3bc6dbe9d5f51f7145 (patch) | |
tree | 1366bd2f145ea6b0f0e6fc74fb3092fea4a40db4 /gcc/cp/mangle.c | |
parent | 1443772f3685beada7aae669875933cb3e8edcde (diff) | |
download | gcc-527cb890236ba086bd262d3bc6dbe9d5f51f7145.tar.gz |
PR c++/65046
Automatically propagate ABI tags to variables and functions
from their (return) type.
* class.c (check_tag): Handle variables and functions.
(mark_or_check_attr_tags): Split out from find_abi_tags_r.
(mark_or_check_tags): Likewise.
(mark_abi_tags): Use it. Rename from mark_type_abi_tags.
(check_abi_tags): Add single argument overload for decls.
Handle inheriting tags for decls.
* mangle.c (write_mangled_name): Call it.
(mangle_return_type_p): Split out from write_encoding.
(unmangled_name_p): Split out from write_mangled_name.
(write_mangled_name): Ignore abi_tag on namespace.
* cp-tree.h (NAMESPACE_IS_INLINE): Replace NAMESPACE_ABI_TAG.
* parser.c (cp_parser_namespace_definition): Set it.
* name-lookup.c (handle_namespace_attrs): Use arguments. Warn
about abi_tag attribute on non-inline namespace.
* tree.c (check_abi_tag_args): Split out from handle_abi_tag_attribute.
(handle_abi_tag_attribute): Allow tags on variables.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@221521 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/mangle.c')
-rw-r--r-- | gcc/cp/mangle.c | 82 |
1 files changed, 59 insertions, 23 deletions
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index fbf4bf27c07..b0f72d1ff14 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -648,6 +648,48 @@ find_substitution (tree node) return 1; } +/* Returns whether DECL's symbol name should be the plain unqualified-id + rather than a more complicated mangled name. */ + +static bool +unmangled_name_p (const tree decl) +{ + if (TREE_CODE (decl) == FUNCTION_DECL) + { + /* The names of `extern "C"' functions are not mangled. */ + return (DECL_EXTERN_C_FUNCTION_P (decl) + /* But overloaded operator names *are* mangled. */ + && !DECL_OVERLOADED_OPERATOR_P (decl)); + } + else if (VAR_P (decl)) + { + /* static variables are mangled. */ + if (!DECL_EXTERNAL_LINKAGE_P (decl)) + return false; + + /* extern "C" declarations aren't mangled. */ + if (DECL_EXTERN_C_P (decl)) + return true; + + /* Other variables at non-global scope are mangled. */ + if (CP_DECL_CONTEXT (decl) != global_namespace) + return false; + + /* Variable template instantiations are mangled. */ + if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) + && variable_template_p (DECL_TI_TEMPLATE (decl))) + return false; + + /* Declarations with ABI tags are mangled. */ + if (lookup_attribute ("abi_tag", DECL_ATTRIBUTES (decl))) + return false; + + /* The names of non-static global variables aren't mangled. */ + return true; + } + + return false; +} /* TOP_LEVEL is true, if this is being called at outermost level of mangling. It should be false when mangling a decl appearing in an @@ -660,13 +702,10 @@ write_mangled_name (const tree decl, bool top_level) { MANGLE_TRACE_TREE ("mangled-name", decl); - if (/* The names of `extern "C"' functions are not mangled. */ - DECL_EXTERN_C_FUNCTION_P (decl) - /* But overloaded operator names *are* mangled. */ - && !DECL_OVERLOADED_OPERATOR_P (decl)) - { - unmangled_name:; + check_abi_tags (decl); + if (unmangled_name_p (decl)) + { if (top_level) write_string (IDENTIFIER_POINTER (DECL_NAME (decl))); else @@ -680,18 +719,6 @@ write_mangled_name (const tree decl, bool top_level) write_source_name (DECL_NAME (decl)); } } - else if (VAR_P (decl) - /* Variable template instantiations are mangled. */ - && !(DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) - && variable_template_p (DECL_TI_TEMPLATE (decl))) - /* The names of non-static global variables aren't mangled. */ - && DECL_EXTERNAL_LINKAGE_P (decl) - && (CP_DECL_CONTEXT (decl) == global_namespace - /* And neither are `extern "C"' variables. */ - || DECL_EXTERN_C_P (decl))) - { - goto unmangled_name; - } else { write_string ("_Z"); @@ -699,6 +726,18 @@ write_mangled_name (const tree decl, bool top_level) } } +/* Returns true if the return type of DECL is part of its signature, and + therefore its mangling. */ + +bool +mangle_return_type_p (tree decl) +{ + return (!DECL_CONSTRUCTOR_P (decl) + && !DECL_DESTRUCTOR_P (decl) + && !DECL_CONV_FN_P (decl) + && decl_is_template_id (decl, NULL)); +} + /* <encoding> ::= <function name> <bare-function-type> ::= <data name> */ @@ -740,10 +779,7 @@ write_encoding (const tree decl) } write_bare_function_type (fn_type, - (!DECL_CONSTRUCTOR_P (decl) - && !DECL_DESTRUCTOR_P (decl) - && !DECL_CONV_FN_P (decl) - && decl_is_template_id (decl, NULL)), + mangle_return_type_p (decl), d); } } @@ -1290,7 +1326,7 @@ write_unqualified_name (tree decl) if (tree tmpl = most_general_template (decl)) decl = DECL_TEMPLATE_RESULT (tmpl); /* Don't crash on an unbound class template. */ - if (decl) + if (decl && TREE_CODE (decl) != NAMESPACE_DECL) { tree attrs = (TREE_CODE (decl) == TYPE_DECL ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) |