From: Anders Carlsson Date: Sun, 27 Sep 2009 00:12:57 +0000 (+0000) Subject: Mangle std::basic_string, std::allocator > as Ss. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f514b544b24926834adbfe8265a72ed8b9b09d81;p=clang Mangle std::basic_string, std::allocator > as Ss. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82882 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index ff2388e798..9ee9a3da88 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -1130,6 +1130,45 @@ bool CXXNameMangler::mangleSubstitution(uintptr_t Ptr) { return true; } +static bool isCharType(QualType T) { + if (T.isNull()) + return false; + + return T->isSpecificBuiltinType(BuiltinType::Char_S) || + T->isSpecificBuiltinType(BuiltinType::Char_U); +} + +/// isCharSpecialization - Returns whether a given type is a template +/// specialization of a given name with a single argument of type char. +static bool isCharSpecialization(QualType T, const char *Name) { + if (T.isNull()) + return false; + + const RecordType *RT = T->getAs(); + if (!RT) + return false; + + const ClassTemplateSpecializationDecl *SD = + dyn_cast(RT->getDecl()); + if (!SD) + return false; + + if (!isStdNamespace(SD->getDeclContext())) + return false; + + const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs(); + if (TemplateArgs.size() != 1) + return false; + + if (!isCharType(TemplateArgs[0].getAsType())) + return false; + + if (strcmp(SD->getIdentifier()->getName(), Name) != 0) + return false; + + return true; +} + bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) { // ::= St # ::std:: if (const NamespaceDecl *NS = dyn_cast(ND)) { @@ -1157,6 +1196,30 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) { } } + if (const ClassTemplateSpecializationDecl *SD = + dyn_cast(ND)) { + // ::= Ss # ::std::basic_string, + // ::std::allocator > + if (SD->getIdentifier()->isStr("basic_string")) { + const TemplateArgumentList &TemplateArgs = SD->getTemplateArgs(); + + if (TemplateArgs.size() != 3) + return false; + + if (!isCharType(TemplateArgs[0].getAsType())) + return false; + + if (!isCharSpecialization(TemplateArgs[1].getAsType(), "char_traits")) + return false; + + if (!isCharSpecialization(TemplateArgs[2].getAsType(), "allocator")) + return false; + + Out << "Ss"; + return true; + } + } return false; } diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp index c35804e2d3..cc66607acd 100644 --- a/test/CodeGenCXX/mangle-subst-std.cpp +++ b/test/CodeGenCXX/mangle-subst-std.cpp @@ -18,10 +18,19 @@ namespace std { void f(typename std::allocator, typename std::allocator) { } namespace std { - template struct basic_string { }; + template struct basic_string { }; } // FIXME: typename is really not allowed here, but it's kept // as a workaround for PR5061. -// CHECK: define void @_Z1fSbIcESbIiE -void f(typename std::basic_string, typename std::basic_string) { } +// CHECK: define void @_Z1fSbIcciE +void f(typename std::basic_string) { } + +namespace std { + template struct char_traits { }; + + typedef std::basic_string, std::allocator > string; +} + +// CHECK: _Z1fSs +void f(std::string) { }