[cfe-commits] r163110 - in /cfe/trunk: lib/AST/MicrosoftMangle.cpp test/CodeGenCXX/mangle-ms-return-qualifiers.cpp test/CodeGenCXX/mangle-ms.cpp

Timur Iskhodzhanov timurrrr at google.com
Mon Sep 3 02:08:10 PDT 2012


Author: timurrrr
Date: Mon Sep  3 04:08:10 2012
New Revision: 163110

URL: http://llvm.org/viewvc/llvm-project?rev=163110&view=rev
Log:
Fix PR13444 - wrong mangling of "const char * const *" and friends with "-cxx-abi microsoft"

Modified:
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms.cpp

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=163110&r1=163109&r2=163110&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Mon Sep  3 04:08:10 2012
@@ -56,7 +56,7 @@
   void mangleVariableEncoding(const VarDecl *VD);
   void mangleNumber(int64_t Number);
   void mangleNumber(const llvm::APSInt &Value);
-  void mangleType(QualType T, SourceRange Range);
+  void mangleType(QualType T, SourceRange Range, bool MangleQualifiers = true);
 
 private:
   void disableBackReferences() { UseNameBackReferences = false; }
@@ -68,6 +68,7 @@
   void manglePostfix(const DeclContext *DC, bool NoFunction=false);
   void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc);
   void mangleQualifiers(Qualifiers Quals, bool IsMember);
+  void manglePointerQualifiers(Qualifiers Quals);
 
   void mangleUnscopedTemplateName(const TemplateDecl *ND);
   void mangleTemplateInstantiationName(const TemplateDecl *TD,
@@ -75,7 +76,7 @@
   void mangleObjCMethodName(const ObjCMethodDecl *MD);
   void mangleLocalName(const FunctionDecl *FD);
 
-  void mangleTypeRepeated(QualType T, SourceRange Range);
+  void mangleArgumentType(QualType T, SourceRange Range);
 
   // Declare manglers for every type class.
 #define ABSTRACT_TYPE(CLASS, PARENT)
@@ -266,18 +267,18 @@
     Out << '4';
   // Now mangle the type.
   // <variable-type> ::= <type> <cvr-qualifiers>
-  //                 ::= <type> A # pointers, references, arrays
+  //                 ::= <type> <pointee-cvr-qualifiers> # pointers, references
   // Pointers and references are odd. The type of 'int * const foo;' gets
   // mangled as 'QAHA' instead of 'PAHB', for example.
   TypeLoc TL = VD->getTypeSourceInfo()->getTypeLoc();
   QualType Ty = TL.getType();
   if (Ty->isPointerType() || Ty->isReferenceType()) {
     mangleType(Ty, TL.getSourceRange());
-    Out << 'A';
+    mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);
   } else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
     // Global arrays are funny, too.
     mangleType(AT, true);
-    Out << 'A';
+    mangleQualifiers(Ty.getQualifiers(), false);
   } else {
     mangleType(Ty.getLocalUnqualifiedType(), TL.getSourceRange());
     mangleQualifiers(Ty.getLocalQualifiers(), false);
@@ -879,43 +880,60 @@
   //         ::= 3 # ?
   //         ::= 4 # ?
   //         ::= 5 # not really based
+  bool HasConst = Quals.hasConst(),
+       HasVolatile = Quals.hasVolatile();
   if (!IsMember) {
-    if (!Quals.hasVolatile()) {
-      if (!Quals.hasConst())
-        Out << 'A';
-      else
-        Out << 'B';
+    if (HasConst && HasVolatile) {
+      Out << 'D';
+    } else if (HasVolatile) {
+      Out << 'C';
+    } else if (HasConst) {
+      Out << 'B';
     } else {
-      if (!Quals.hasConst())
-        Out << 'C';
-      else
-        Out << 'D';
+      Out << 'A';
     }
   } else {
-    if (!Quals.hasVolatile()) {
-      if (!Quals.hasConst())
-        Out << 'Q';
-      else
-        Out << 'R';
+    if (HasConst && HasVolatile) {
+      Out << 'T';
+    } else if (HasVolatile) {
+      Out << 'S';
+    } else if (HasConst) {
+      Out << 'R';
     } else {
-      if (!Quals.hasConst())
-        Out << 'S';
-      else
-        Out << 'T';
+      Out << 'Q';
     }
   }
 
   // FIXME: For now, just drop all extension qualifiers on the floor.
 }
 
-void MicrosoftCXXNameMangler::mangleTypeRepeated(QualType T, SourceRange Range) {
+void MicrosoftCXXNameMangler::manglePointerQualifiers(Qualifiers Quals) {
+  // <pointer-cvr-qualifiers> ::= P  # no qualifiers
+  //                          ::= Q  # const
+  //                          ::= R  # volatile
+  //                          ::= S  # const volatile
+  bool HasConst = Quals.hasConst(),
+       HasVolatile = Quals.hasVolatile();
+  if (HasConst && HasVolatile) {
+    Out << 'S';
+  } else if (HasVolatile) {
+    Out << 'R';
+  } else if (HasConst) {
+    Out << 'Q';
+  } else {
+    Out << 'P';
+  }
+}
+
+void MicrosoftCXXNameMangler::mangleArgumentType(QualType T,
+                                                 SourceRange Range) {
   void *TypePtr = getASTContext().getCanonicalType(T).getAsOpaquePtr();
   ArgBackRefMap::iterator Found = TypeBackReferences.find(TypePtr);
 
   if (Found == TypeBackReferences.end()) {
     size_t OutSizeBefore = Out.GetNumBytesInBuffer();
 
-    mangleType(T,Range);
+    mangleType(T, Range, false);
 
     // See if it's worth creating a back reference.
     // Only types longer than 1 character are considered
@@ -930,38 +948,30 @@
   }
 }
 
-void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range) {
+void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
+                                         bool MangleQualifiers) {
   // Only operate on the canonical type!
   T = getASTContext().getCanonicalType(T);
-  
+
   Qualifiers Quals = T.getLocalQualifiers();
-  if (Quals) {
-    // We have to mangle these now, while we still have enough information.
-    // <pointer-cvr-qualifiers> ::= P  # pointer
-    //                          ::= Q  # const pointer
-    //                          ::= R  # volatile pointer
-    //                          ::= S  # const volatile pointer
-    if (T->isAnyPointerType() || T->isMemberPointerType() ||
-        T->isBlockPointerType()) {
-      if (!Quals.hasVolatile())
-        Out << 'Q';
-      else {
-        if (!Quals.hasConst())
-          Out << 'R';
-        else
-          Out << 'S';
-      }
-    } else
-      // Just emit qualifiers like normal.
-      // NB: When we mangle a pointer/reference type, and the pointee
-      // type has no qualifiers, the lack of qualifier gets mangled
-      // in there.
-      mangleQualifiers(Quals, false);
-  } else if (T->isAnyPointerType() || T->isMemberPointerType() ||
-             T->isBlockPointerType()) {
-    Out << 'P';
+  // We have to mangle these now, while we still have enough information.
+  if (T->isAnyPointerType() || T->isMemberPointerType() ||
+      T->isBlockPointerType()) {
+    manglePointerQualifiers(Quals);
+  } else if (Quals && MangleQualifiers) {
+    mangleQualifiers(Quals, false);
+  }
+
+  SplitQualType split = T.split();
+  const Type *ty = split.Ty;
+
+  // If we're mangling a qualified array type, push the qualifiers to
+  // the element type.
+  if (split.Quals && isa<ArrayType>(T)) {
+    ty = Context.getASTContext().getAsArrayType(T);
   }
-  switch (T->getTypeClass()) {
+
+  switch (ty->getTypeClass()) {
 #define ABSTRACT_TYPE(CLASS, PARENT)
 #define NON_CANONICAL_TYPE(CLASS, PARENT) \
   case Type::CLASS: \
@@ -969,7 +979,7 @@
     return;
 #define TYPE(CLASS, PARENT) \
   case Type::CLASS: \
-    mangleType(cast<CLASS##Type>(T), Range); \
+    mangleType(cast<CLASS##Type>(ty), Range); \
     break;
 #include "clang/AST/TypeNodes.def"
 #undef ABSTRACT_TYPE
@@ -1119,14 +1129,14 @@
              ParmEnd = D->param_end(); Parm != ParmEnd; ++Parm) {
         TypeSourceInfo *TSI = (*Parm)->getTypeSourceInfo();
         QualType Type = TSI ? TSI->getType() : (*Parm)->getType();
-        mangleTypeRepeated(Type, (*Parm)->getSourceRange());
+        mangleArgumentType(Type, (*Parm)->getSourceRange());
       }
     } else {
       // Happens for function pointer type arguments for example.
       for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
            ArgEnd = Proto->arg_type_end();
            Arg != ArgEnd; ++Arg)
-        mangleTypeRepeated(*Arg, SourceRange());
+        mangleArgumentType(*Arg, SourceRange());
     }
     // <builtin-type>      ::= Z  # ellipsis
     if (Proto->isVariadic())
@@ -1289,20 +1299,22 @@
 }
 
 // <type>       ::= <array-type>
-// <array-type> ::= P <cvr-qualifiers> [Y <dimension-count> <dimension>+]
-//                                                  <element-type> # as global
+// <array-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
+//                  [Y <dimension-count> <dimension>+]
+//                  <element-type> # as global
 //              ::= Q <cvr-qualifiers> [Y <dimension-count> <dimension>+]
-//                                                  <element-type> # as param
+//                  <element-type> # as param
 // It's supposed to be the other way around, but for some strange reason, it
 // isn't. Today this behavior is retained for the sole purpose of backwards
 // compatibility.
 void MicrosoftCXXNameMangler::mangleType(const ArrayType *T, bool IsGlobal) {
   // This isn't a recursive mangling, so now we have to do it all in this
   // one call.
-  if (IsGlobal)
-    Out << 'P';
-  else
+  if (IsGlobal) {
+    manglePointerQualifiers(T->getElementType().getQualifiers());
+  } else {
     Out << 'Q';
+  }
   mangleExtraDimensions(T->getElementType());
 }
 void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T,
@@ -1412,10 +1424,8 @@
     Out << '6';
     mangleType(FT, NULL, false, false);
   } else {
-    if (!PointeeTy.hasQualifiers())
-      // Lack of qualifiers is mangled as 'A'.
-      Out << 'A';
-    mangleType(PointeeTy, Range);
+    mangleQualifiers(PointeeTy.getQualifiers(), false);
+    mangleType(PointeeTy, Range, false);
   }
 }
 void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp?rev=163110&r1=163109&r2=163110&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp Mon Sep  3 04:08:10 2012
@@ -167,7 +167,4 @@
 // CHECK: "\01?g3@@YAPAP6AHH at ZXZ"
 
 const function_pointer* g4() { return 0; }
-// The mangling of g4 is currently "\01?g4@@YAPQ6AHH at ZXZ" which is wrong.
-// This looks related to http://llvm.org/PR13444
-// FIXME: replace CHECK-NOT with CHECK once it is fixed.
-// CHECK-NOT: "\01?g4@@YAPBQ6AHH at ZXZ"
+// CHECK: "\01?g4@@YAPBQ6AHH at ZXZ"

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms.cpp?rev=163110&r1=163109&r2=163110&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms.cpp Mon Sep  3 04:08:10 2012
@@ -7,16 +7,17 @@
 // CHECK: @"\01?e at foo@@1JC"
 // CHECK: @"\01?f at foo@@2DD"
 // CHECK: @"\01?g at bar@@2HA"
-// CHECK: @"\01?h@@3QAHA"
+// CHECK: @"\01?h1@@3QAHA"
+// CHECK: @"\01?h2@@3QBHB"
 // CHECK: @"\01?i@@3PAY0BE at HA"
 // CHECK: @"\01?j@@3P6GHCE at ZA"
 // CHECK: @"\01?k@@3PTfoo@@DA"
 // CHECK: @"\01?l@@3P8foo@@AEHH at ZA"
 // CHECK: @"\01?color1@@3PANA"
+// CHECK: @"\01?color2@@3QBNB"
 
-// FIXME: The following three tests currently fail, see PR13182.
+// FIXME: The following three tests currently fail, see http://llvm.org/PR13182
 // Replace "CHECK-NOT" with "CHECK" when it is fixed.
-// CHECK-NOT: @"\01?color2@@3QBNB"
 // CHECK-NOT: @"\01?color3@@3QAY02$$CBNA"
 // CHECK-NOT: @"\01?color4@@3QAY02$$CBNA"
 
@@ -87,7 +88,8 @@
 
 int bar::g;
 
-extern int * const h = &a;
+extern int * const h1 = &a;
+extern const int * const h2 = &a;
 
 int i[10][20];
 
@@ -151,7 +153,7 @@
 void redundant_parens_use() { redundant_parens(); }
 // CHECK: @"\01?redundant_parens@@YAXXZ"
 
-// PR13182, PR13047
+// PR13047
 typedef double RGB[3];
 RGB color1;
 extern const RGB color2 = {};
@@ -166,3 +168,24 @@
 class X {};
 // CHECK: "\01?fooX@@YA?AVX@@XZ"
 X fooX() { return X(); }
+
+namespace PR13182 {
+  extern char s0[];
+  // CHECK: @"\01?s0 at PR13182@@3PADA"
+  extern char s1[42];
+  // CHECK: @"\01?s1 at PR13182@@3PADA"
+  extern const char s2[];
+  // CHECK: @"\01?s2 at PR13182@@3QBDB"
+  extern const char s3[42];
+  // CHECK: @"\01?s3 at PR13182@@3QBDB"
+  extern volatile char s4[];
+  // CHECK: @"\01?s4 at PR13182@@3RCDC"
+  extern const volatile char s5[];
+  // CHECK: @"\01?s5 at PR13182@@3SDDD"
+  extern const char* const* s6;
+  // CHECK: @"\01?s6 at PR13182@@3PBQBDB"
+
+  char foo() {
+    return s0[0] + s1[0] + s2[0] + s3[0] + s4[0] + s5[0] + s6[0][0];
+  }
+}





More information about the cfe-commits mailing list