forked from OSchip/llvm-project
When mangling a qualified array type, push the qualifiers down to the
element type. Fixes rdar://problem/8913416. llvm-svn: 124315
This commit is contained in:
parent
b9b2422e89
commit
5143d646b9
|
@ -1191,21 +1191,35 @@ void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
|
||||||
Out << Buffer;
|
Out << Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXXNameMangler::mangleType(QualType T) {
|
void CXXNameMangler::mangleType(QualType nonCanon) {
|
||||||
// Only operate on the canonical type!
|
// Only operate on the canonical type!
|
||||||
T = Context.getASTContext().getCanonicalType(T);
|
QualType canon = nonCanon.getCanonicalType();
|
||||||
|
|
||||||
bool IsSubstitutable = T.hasLocalQualifiers() || !isa<BuiltinType>(T);
|
SplitQualType split = canon.split();
|
||||||
if (IsSubstitutable && mangleSubstitution(T))
|
Qualifiers quals = split.second;
|
||||||
|
const Type *ty = split.first;
|
||||||
|
|
||||||
|
bool isSubstitutable = quals || !isa<BuiltinType>(ty);
|
||||||
|
if (isSubstitutable && mangleSubstitution(canon))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Qualifiers Quals = T.getLocalQualifiers()) {
|
// If we're mangling a qualified array type, push the qualifiers to
|
||||||
mangleQualifiers(Quals);
|
// the element type.
|
||||||
|
if (quals && isa<ArrayType>(ty)) {
|
||||||
|
ty = Context.getASTContext().getAsArrayType(canon);
|
||||||
|
quals = Qualifiers();
|
||||||
|
|
||||||
|
// Note that we don't update canon: we want to add the
|
||||||
|
// substitution at the canonical type.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quals) {
|
||||||
|
mangleQualifiers(quals);
|
||||||
// Recurse: even if the qualified type isn't yet substitutable,
|
// Recurse: even if the qualified type isn't yet substitutable,
|
||||||
// the unqualified type might be.
|
// the unqualified type might be.
|
||||||
mangleType(T.getLocalUnqualifiedType());
|
mangleType(QualType(ty, 0));
|
||||||
} else {
|
} else {
|
||||||
switch (T->getTypeClass()) {
|
switch (ty->getTypeClass()) {
|
||||||
#define ABSTRACT_TYPE(CLASS, PARENT)
|
#define ABSTRACT_TYPE(CLASS, PARENT)
|
||||||
#define NON_CANONICAL_TYPE(CLASS, PARENT) \
|
#define NON_CANONICAL_TYPE(CLASS, PARENT) \
|
||||||
case Type::CLASS: \
|
case Type::CLASS: \
|
||||||
|
@ -1213,15 +1227,15 @@ void CXXNameMangler::mangleType(QualType T) {
|
||||||
return;
|
return;
|
||||||
#define TYPE(CLASS, PARENT) \
|
#define TYPE(CLASS, PARENT) \
|
||||||
case Type::CLASS: \
|
case Type::CLASS: \
|
||||||
mangleType(static_cast<const CLASS##Type*>(T.getTypePtr())); \
|
mangleType(static_cast<const CLASS##Type*>(ty)); \
|
||||||
break;
|
break;
|
||||||
#include "clang/AST/TypeNodes.def"
|
#include "clang/AST/TypeNodes.def"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the substitution.
|
// Add the substitution.
|
||||||
if (IsSubstitutable)
|
if (isSubstitutable)
|
||||||
addSubstitution(T);
|
addSubstitution(canon);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CXXNameMangler::mangleNameOrStandardSubstitution(const NamedDecl *ND) {
|
void CXXNameMangler::mangleNameOrStandardSubstitution(const NamedDecl *ND) {
|
||||||
|
|
|
@ -635,3 +635,15 @@ namespace test22 {
|
||||||
// CHECK: define void @_ZN6test221fEDn(
|
// CHECK: define void @_ZN6test221fEDn(
|
||||||
void f(decltype(nullptr)) { }
|
void f(decltype(nullptr)) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rdar://problem/8913416
|
||||||
|
namespace test23 {
|
||||||
|
typedef void * const vpc;
|
||||||
|
|
||||||
|
// CHECK: define void @_ZN6test231fERA10_KPv(
|
||||||
|
void f(vpc (&)[10]) {}
|
||||||
|
|
||||||
|
typedef vpc vpca5[5];
|
||||||
|
void f(vpca5 volatile (&)[10]) {}
|
||||||
|
// CHECK: define void @_ZN6test231fERA10_A5_VKPv(
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue