]> granicus.if.org Git - clang/commitdiff
When mangling a qualified array type, push the qualifiers down to the
authorJohn McCall <rjmccall@apple.com>
Wed, 26 Jan 2011 20:05:40 +0000 (20:05 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 26 Jan 2011 20:05:40 +0000 (20:05 +0000)
element type.  Fixes rdar://problem/8913416.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124315 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ItaniumMangle.cpp
test/CodeGenCXX/mangle.cpp

index 3c7191a8e128596bacd3edf752a9dc3a28a99272..a84df1210d64c9b0a2684f2bc2b6b7a1bf05ee69 100644 (file)
@@ -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<BuiltinType>(T);
-  if (IsSubstitutable && mangleSubstitution(T))
+  SplitQualType split = canon.split();
+  Qualifiers quals = split.second;
+  const Type *ty = split.first;
+
+  bool isSubstitutable = quals || !isa<BuiltinType>(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<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,
     // 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<const CLASS##Type*>(T.getTypePtr())); \
+      mangleType(static_cast<const CLASS##Type*>(ty)); \
       break;
 #include "clang/AST/TypeNodes.def"
     }
   }
 
   // Add the substitution.
-  if (IsSubstitutable)
-    addSubstitution(T);
+  if (isSubstitutable)
+    addSubstitution(canon);
 }
 
 void CXXNameMangler::mangleNameOrStandardSubstitution(const NamedDecl *ND) {
index b5207a1712f402747b8b01fbfc2b7d72d3a07c59..ec496fe1f753d1f2495f97cb0f2440aa456bb4dd 100644 (file)
@@ -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(
+}