зеркало из https://github.com/microsoft/clang-1.git
Mangle std::basic_string<char, std::char_traits<char>, std::allocator<char> > as Ss.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82882 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
189d59cfc7
Коммит
f514b544b2
|
@ -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<RecordType>();
|
||||
if (!RT)
|
||||
return false;
|
||||
|
||||
const ClassTemplateSpecializationDecl *SD =
|
||||
dyn_cast<ClassTemplateSpecializationDecl>(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) {
|
||||
// <substitution> ::= St # ::std::
|
||||
if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
|
||||
|
@ -1157,6 +1196,30 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
|
|||
}
|
||||
}
|
||||
|
||||
if (const ClassTemplateSpecializationDecl *SD =
|
||||
dyn_cast<ClassTemplateSpecializationDecl>(ND)) {
|
||||
// <substitution> ::= Ss # ::std::basic_string<char,
|
||||
// ::std::char_traits<char>,
|
||||
// ::std::allocator<char> >
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,10 +18,19 @@ namespace std {
|
|||
void f(typename std::allocator<char>, typename std::allocator<int>) { }
|
||||
|
||||
namespace std {
|
||||
template<typename T> struct basic_string { };
|
||||
template<typename T, typename U, typename V> 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<char>, typename std::basic_string<int>) { }
|
||||
// CHECK: define void @_Z1fSbIcciE
|
||||
void f(typename std::basic_string<char, char, int>) { }
|
||||
|
||||
namespace std {
|
||||
template<typename T> struct char_traits { };
|
||||
|
||||
typedef std::basic_string<char, std::char_traits<char>, std::allocator<char> > string;
|
||||
}
|
||||
|
||||
// CHECK: _Z1fSs
|
||||
void f(std::string) { }
|
||||
|
|
Загрузка…
Ссылка в новой задаче