aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-09-26 15:57:37 -0400
committerJason Merrill <jason@gcc.gnu.org>2014-09-26 15:57:37 -0400
commit00eaaa505695d75765f570ec3e18680cc394a377 (patch)
treef0ac17ea8372dfc4024ad89e42ad2b268f33402f /gcc
parent20ee26901f9bd834fa221f751c7baa5bf07137b5 (diff)
downloadgcc-00eaaa505695d75765f570ec3e18680cc394a377.zip
gcc-00eaaa505695d75765f570ec3e18680cc394a377.tar.gz
gcc-00eaaa505695d75765f570ec3e18680cc394a377.tar.bz2
mangle.c (is_std_substitution): Check for abi_tag.
gcc/cp/ * mangle.c (is_std_substitution): Check for abi_tag. libiberty/ * cp-demangle.c (d_substitution): Handle abi tags on abbreviation. From-SVN: r215647
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/mangle.c65
-rw-r--r--gcc/testsuite/g++.dg/abi/abi-tag9.C11
3 files changed, 46 insertions, 34 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a11a520..126c148 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,7 @@
+2014-09-26 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (find_substitution): Use write_abi_tags.
+
2014-09-25 Marek Polacek <polacek@redhat.com>
PR c++/61945
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 9703d1c..6e6aa8a 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -512,6 +512,7 @@ find_substitution (tree node)
const int size = vec_safe_length (G.substitutions);
tree decl;
tree type;
+ const char *abbr = NULL;
if (DEBUG_MANGLE)
fprintf (stderr, " ++ find_substitution (%s at %p)\n",
@@ -530,13 +531,10 @@ find_substitution (tree node)
if (decl
&& is_std_substitution (decl, SUBID_ALLOCATOR)
&& !CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)))
- {
- write_string ("Sa");
- return 1;
- }
+ abbr = "Sa";
/* Check for std::basic_string. */
- if (decl && is_std_substitution (decl, SUBID_BASIC_STRING))
+ else if (decl && is_std_substitution (decl, SUBID_BASIC_STRING))
{
if (TYPE_P (node))
{
@@ -555,26 +553,20 @@ find_substitution (tree node)
SUBID_CHAR_TRAITS)
&& is_std_substitution_char (TREE_VEC_ELT (args, 2),
SUBID_ALLOCATOR))
- {
- write_string ("Ss");
- return 1;
- }
+ abbr = "Ss";
}
}
else
/* Substitute for the template name only if this isn't a type. */
- {
- write_string ("Sb");
- return 1;
- }
+ abbr = "Sb";
}
/* Check for basic_{i,o,io}stream. */
- if (TYPE_P (node)
- && cp_type_quals (type) == TYPE_UNQUALIFIED
- && CLASS_TYPE_P (type)
- && CLASSTYPE_USE_TEMPLATE (type)
- && CLASSTYPE_TEMPLATE_INFO (type) != NULL)
+ else if (TYPE_P (node)
+ && cp_type_quals (type) == TYPE_UNQUALIFIED
+ && CLASS_TYPE_P (type)
+ && CLASSTYPE_USE_TEMPLATE (type)
+ && CLASSTYPE_TEMPLATE_INFO (type) != NULL)
{
/* First, check for the template
args <char, std::char_traits<char> > . */
@@ -587,35 +579,29 @@ find_substitution (tree node)
{
/* Got them. Is this basic_istream? */
if (is_std_substitution (decl, SUBID_BASIC_ISTREAM))
- {
- write_string ("Si");
- return 1;
- }
+ abbr = "Si";
/* Or basic_ostream? */
else if (is_std_substitution (decl, SUBID_BASIC_OSTREAM))
- {
- write_string ("So");
- return 1;
- }
+ abbr = "So";
/* Or basic_iostream? */
else if (is_std_substitution (decl, SUBID_BASIC_IOSTREAM))
- {
- write_string ("Sd");
- return 1;
- }
+ abbr = "Sd";
}
}
/* Check for namespace std. */
- if (decl && DECL_NAMESPACE_STD_P (decl))
+ else if (decl && DECL_NAMESPACE_STD_P (decl))
{
write_string ("St");
return 1;
}
+ tree tags = NULL_TREE;
+ if (OVERLOAD_TYPE_P (node))
+ tags = lookup_attribute ("abi_tag", TYPE_ATTRIBUTES (type));
/* Now check the list of available substitutions for this mangling
operation. */
- for (i = 0; i < size; ++i)
+ if (!abbr || tags) for (i = 0; i < size; ++i)
{
tree candidate = (*G.substitutions)[i];
/* NODE is a matched to a candidate if it's the same decl node or
@@ -630,8 +616,19 @@ find_substitution (tree node)
}
}
- /* No substitution found. */
- return 0;
+ if (!abbr)
+ /* No substitution found. */
+ return 0;
+
+ write_string (abbr);
+ if (tags)
+ {
+ /* If there are ABI tags on the abbreviation, it becomes
+ a substitution candidate. */
+ write_abi_tags (tags);
+ add_substitution (node);
+ }
+ return 1;
}
diff --git a/gcc/testsuite/g++.dg/abi/abi-tag9.C b/gcc/testsuite/g++.dg/abi/abi-tag9.C
new file mode 100644
index 0000000..9ec78a9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/abi-tag9.C
@@ -0,0 +1,11 @@
+// { dg-final { scan-assembler "_Z1fSsB3fooS_" } }
+
+namespace std {
+ template <class T> struct char_traits {};
+ template <class T> struct allocator {};
+ template <class T, class U, class V>
+ struct __attribute ((abi_tag ("foo"))) basic_string { };
+ typedef basic_string<char,char_traits<char>,allocator<char> > string;
+}
+
+void f(std::string,std::string) {}