From: John McCall Date: Wed, 26 Jan 2011 20:05:40 +0000 (+0000) Subject: When mangling a qualified array type, push the qualifiers down to the X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b47f74818094fabd8f150fb4d6d0fa8a6c52cde1;p=clang When mangling a qualified array type, push the qualifiers down to the element type. Fixes rdar://problem/8913416. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124315 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 3c7191a8e1..a84df1210d 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -1191,21 +1191,35 @@ void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) { Out << Buffer; } -void CXXNameMangler::mangleType(QualType T) { +void CXXNameMangler::mangleType(QualType nonCanon) { // Only operate on the canonical type! - T = Context.getASTContext().getCanonicalType(T); + QualType canon = nonCanon.getCanonicalType(); - bool IsSubstitutable = T.hasLocalQualifiers() || !isa(T); - if (IsSubstitutable && mangleSubstitution(T)) + SplitQualType split = canon.split(); + Qualifiers quals = split.second; + const Type *ty = split.first; + + bool isSubstitutable = quals || !isa(ty); + if (isSubstitutable && mangleSubstitution(canon)) return; - if (Qualifiers Quals = T.getLocalQualifiers()) { - mangleQualifiers(Quals); + // If we're mangling a qualified array type, push the qualifiers to + // the element type. + if (quals && isa(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, // the unqualified type might be. - mangleType(T.getLocalUnqualifiedType()); + mangleType(QualType(ty, 0)); } else { - switch (T->getTypeClass()) { + switch (ty->getTypeClass()) { #define ABSTRACT_TYPE(CLASS, PARENT) #define NON_CANONICAL_TYPE(CLASS, PARENT) \ case Type::CLASS: \ @@ -1213,15 +1227,15 @@ void CXXNameMangler::mangleType(QualType T) { return; #define TYPE(CLASS, PARENT) \ case Type::CLASS: \ - mangleType(static_cast(T.getTypePtr())); \ + mangleType(static_cast(ty)); \ break; #include "clang/AST/TypeNodes.def" } } // Add the substitution. - if (IsSubstitutable) - addSubstitution(T); + if (isSubstitutable) + addSubstitution(canon); } void CXXNameMangler::mangleNameOrStandardSubstitution(const NamedDecl *ND) { diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index b5207a1712..ec496fe1f7 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -635,3 +635,15 @@ namespace test22 { // CHECK: define void @_ZN6test221fEDn( 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( +}