bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
// <substitution> ::= St # ::std::
+ if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
+ if (NS->getParent()->isTranslationUnit() &&
+ NS->getOriginalNamespace()->getIdentifier()->isStr("std")) {
+ Out << "St";
+ return true;
+ }
+ }
+
+ if (const ClassTemplateDecl *TD = dyn_cast<ClassTemplateDecl>(ND)) {
+ if (!isStdNamespace(TD->getDeclContext()))
+ return false;
+
+ // <substitution> ::= Sa # ::std::allocator
+ if (TD->getIdentifier()->isStr("allocator")) {
+ Out << "Sa";
+ return true;
+ }
+ }
- const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND);
- if (!NS)
- return false;
- if (!NS->getParent()->isTranslationUnit())
- return false;
-
- if (!NS->getOriginalNamespace()->getIdentifier()->isStr("std"))
- return false;
-
- Out << "St";
- return true;
+ return false;
}
void CXXNameMangler::addSubstitution(QualType T) {
// CHECK: define void @_ZNSt1AC2Ev
A::A() { }
};
+
+namespace std {
+ template<typename T> struct allocator { allocator(); };
+}
+
+// FIXME: typename is really not allowed here, but it's kept
+// as a workaround for PR5061.
+// CHECK: define void @_Z1fSaIcESaIiE
+void f(typename std::allocator<char>, typename std::allocator<int>) { }