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:
John McCall 2011-01-26 20:05:40 +00:00
parent b9b2422e89
commit 5143d646b9
2 changed files with 37 additions and 11 deletions

View File

@ -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) {

View File

@ -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(
}