r180250 - [ms-cxxabi] Fix a number of bugs in the mangler.

Peter Collingbourne peter at pcc.me.uk
Wed Apr 24 21:25:40 PDT 2013


Author: pcc
Date: Wed Apr 24 23:25:40 2013
New Revision: 180250

URL: http://llvm.org/viewvc/llvm-project?rev=180250&view=rev
Log:
[ms-cxxabi] Fix a number of bugs in the mangler.

This includes the following fixes:
 - Implement 4 subtly different variants of qualifier mangling and use them
   in what I believe are the right places.
 - Fix handling of array types.  Previously we were always decaying them,
   which is wrong if the type appears as a template argument, pointee,
   referent etc.
Fixes PR13182.

Differential Revision: http://llvm-reviews.chandlerc.com/D709

Modified:
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-templates.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=180250&r1=180249&r2=180250&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Wed Apr 24 23:25:40 2013
@@ -59,6 +59,8 @@ class MicrosoftCXXNameMangler {
   ASTContext &getASTContext() const { return Context.getASTContext(); }
 
 public:
+  enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
+
   MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_)
     : Context(C), Out(Out_),
       Structor(0), StructorType(-1),
@@ -78,7 +80,8 @@ public:
   void mangleVariableEncoding(const VarDecl *VD);
   void mangleNumber(int64_t Number);
   void mangleNumber(const llvm::APSInt &Value);
-  void mangleType(QualType T, SourceRange Range, bool MangleQualifiers = true);
+  void mangleType(QualType T, SourceRange Range,
+                  QualifierMangleMode QMM = QMM_Mangle);
 
 private:
   void disableBackReferences() { UseNameBackReferences = false; }
@@ -112,10 +115,10 @@ private:
 #undef TYPE
   
   void mangleType(const TagType*);
-  void mangleType(const FunctionType *T, const FunctionDecl *D,
-                  bool IsStructor, bool IsInstMethod);
-  void mangleType(const ArrayType *T, bool IsGlobal);
-  void mangleExtraDimensions(QualType T);
+  void mangleFunctionType(const FunctionType *T, const FunctionDecl *D,
+                          bool IsStructor, bool IsInstMethod);
+  void mangleDecayedArrayType(const ArrayType *T, bool IsGlobal);
+  void mangleArrayType(const ArrayType *T, Qualifiers Quals);
   void mangleFunctionClass(const FunctionDecl *FD);
   void mangleCallingConvention(const FunctionType *T, bool IsInstMethod = false);
   void mangleIntegerLiteral(const llvm::APSInt &Number, bool IsBoolean);
@@ -264,7 +267,7 @@ void MicrosoftCXXNameMangler::mangleFunc
   // First, the function class.
   mangleFunctionClass(FD);
 
-  mangleType(FT, FD, InStructor, InInstMethod);
+  mangleFunctionType(FT, FD, InStructor, InInstMethod);
 }
 
 void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
@@ -297,14 +300,17 @@ void MicrosoftCXXNameMangler::mangleVari
   TypeLoc TL = VD->getTypeSourceInfo()->getTypeLoc();
   QualType Ty = TL.getType();
   if (Ty->isPointerType() || Ty->isReferenceType()) {
-    mangleType(Ty, TL.getSourceRange());
+    mangleType(Ty, TL.getSourceRange(), QMM_Drop);
     mangleQualifiers(Ty->getPointeeType().getQualifiers(), false);
   } else if (const ArrayType *AT = getASTContext().getAsArrayType(Ty)) {
     // Global arrays are funny, too.
-    mangleType(AT, true);
-    mangleQualifiers(Ty.getQualifiers(), false);
+    mangleDecayedArrayType(AT, true);
+    if (AT->getElementType()->isArrayType())
+      Out << 'A';
+    else
+      mangleQualifiers(Ty.getQualifiers(), false);
   } else {
-    mangleType(Ty.getLocalUnqualifiedType(), TL.getSourceRange());
+    mangleType(Ty, TL.getSourceRange(), QMM_Drop);
     mangleQualifiers(Ty.getLocalQualifiers(), false);
   }
 }
@@ -826,9 +832,7 @@ MicrosoftCXXNameMangler::mangleTemplateA
       llvm_unreachable("Can't mangle null template arguments!");
     case TemplateArgument::Type: {
       QualType T = TA.getAsType();
-      if (T.hasQualifiers())
-        Out << "$$C";
-      mangleType(T, SourceRange());
+      mangleType(T, SourceRange(), QMM_Escape);
       break;
     }
     case TemplateArgument::Declaration:
@@ -968,7 +972,14 @@ void MicrosoftCXXNameMangler::mangleArgu
   if (Found == TypeBackReferences.end()) {
     size_t OutSizeBefore = Out.GetNumBytesInBuffer();
 
-    mangleType(T, Range, false);
+    if (const ArrayType *AT = getASTContext().getAsArrayType(T)) {
+      mangleDecayedArrayType(AT, false);
+    } else if (const FunctionType *FT = T->getAs<FunctionType>()) {
+      Out << "P6";
+      mangleFunctionType(FT, 0, false, false);
+    } else {
+      mangleType(T, Range, QMM_Drop);
+    }
 
     // See if it's worth creating a back reference.
     // Only types longer than 1 character are considered
@@ -984,28 +995,53 @@ void MicrosoftCXXNameMangler::mangleArgu
 }
 
 void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
-                                         bool MangleQualifiers) {
+                                         QualifierMangleMode QMM) {
   // Only operate on the canonical type!
   T = getASTContext().getCanonicalType(T);
-
   Qualifiers Quals = T.getLocalQualifiers();
-  // 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);
+
+  if (const ArrayType *AT = dyn_cast<ArrayType>(T)) {
+    if (QMM == QMM_Mangle)
+      Out << 'A';
+    else if (QMM == QMM_Escape || QMM == QMM_Result)
+      Out << "$$B";
+    mangleArrayType(AT, Quals);
+    return;
   }
 
-  SplitQualType split = T.split();
-  const Type *ty = split.Ty;
+  bool IsPointer = T->isAnyPointerType() || T->isMemberPointerType() ||
+                   T->isBlockPointerType();
 
-  // 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 (QMM) {
+  case QMM_Drop:
+    break;
+  case QMM_Mangle:
+    if (const FunctionType *FT = dyn_cast<FunctionType>(T)) {
+      Out << '6';
+      mangleFunctionType(FT, 0, false, false);
+      return;
+    }
+    mangleQualifiers(Quals, false);
+    break;
+  case QMM_Escape:
+    if (!IsPointer && Quals) {
+      Out << "$$C";
+      mangleQualifiers(Quals, false);
+    }
+    break;
+  case QMM_Result:
+    if ((!IsPointer && Quals) || isa<TagType>(T)) {
+      Out << '?';
+      mangleQualifiers(Quals, false);
+    }
+    break;
   }
 
+  // We have to mangle these now, while we still have enough information.
+  if (IsPointer)
+    manglePointerQualifiers(Quals);
+  const Type *ty = T.getTypePtr();
+
   switch (ty->getTypeClass()) {
 #define ABSTRACT_TYPE(CLASS, PARENT)
 #define NON_CANONICAL_TYPE(CLASS, PARENT) \
@@ -1115,17 +1151,17 @@ void MicrosoftCXXNameMangler::mangleType
   // structor type.
   // FIXME: This may not be lambda-friendly.
   Out << "$$A6";
-  mangleType(T, NULL, false, false);
+  mangleFunctionType(T, NULL, false, false);
 }
 void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,
                                          SourceRange) {
   llvm_unreachable("Can't mangle K&R function prototypes");
 }
 
-void MicrosoftCXXNameMangler::mangleType(const FunctionType *T,
-                                         const FunctionDecl *D,
-                                         bool IsStructor,
-                                         bool IsInstMethod) {
+void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
+                                                 const FunctionDecl *D,
+                                                 bool IsStructor,
+                                                 bool IsInstMethod) {
   // <function-type> ::= <this-cvr-qualifiers> <calling-convention>
   //                     <return-type> <argument-list> <throw-spec>
   const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
@@ -1151,21 +1187,7 @@ void MicrosoftCXXNameMangler::mangleType
     }
     Out << '@';
   } else {
-    QualType Result = Proto->getResultType();
-    const Type* RT = Result.getTypePtr();
-    if (!RT->isAnyPointerType() && !RT->isReferenceType()) {
-      if (Result.hasQualifiers() || !RT->isBuiltinType())
-        Out << '?';
-      if (!RT->isBuiltinType() && !Result.hasQualifiers()) {
-        // Lack of qualifiers for user types is mangled as 'A'.
-        Out << 'A';
-      }
-    }
-
-    // FIXME: Get the source range for the result type. Or, better yet,
-    // implement the unimplemented stuff so we don't need accurate source
-    // location info anymore :).
-    mangleType(Result, SourceRange());
+    mangleType(Proto->getResultType(), SourceRange(), QMM_Result);
   }
 
   // <argument-list> ::= X # void
@@ -1360,7 +1382,8 @@ void MicrosoftCXXNameMangler::mangleType
 // 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) {
+void MicrosoftCXXNameMangler::mangleDecayedArrayType(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) {
@@ -1368,25 +1391,27 @@ void MicrosoftCXXNameMangler::mangleType
   } else {
     Out << 'Q';
   }
-  mangleExtraDimensions(T->getElementType());
+  mangleType(T->getElementType(), SourceRange());
 }
 void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T,
                                          SourceRange) {
-  mangleType(cast<ArrayType>(T), false);
+  llvm_unreachable("Should have been special cased");
 }
 void MicrosoftCXXNameMangler::mangleType(const VariableArrayType *T,
                                          SourceRange) {
-  mangleType(cast<ArrayType>(T), false);
+  llvm_unreachable("Should have been special cased");
 }
 void MicrosoftCXXNameMangler::mangleType(const DependentSizedArrayType *T,
                                          SourceRange) {
-  mangleType(cast<ArrayType>(T), false);
+  llvm_unreachable("Should have been special cased");
 }
 void MicrosoftCXXNameMangler::mangleType(const IncompleteArrayType *T,
                                          SourceRange) {
-  mangleType(cast<ArrayType>(T), false);
+  llvm_unreachable("Should have been special cased");
 }
-void MicrosoftCXXNameMangler::mangleExtraDimensions(QualType ElementTy) {
+void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T,
+                                              Qualifiers Quals) {
+  QualType ElementTy(T, 0);
   SmallVector<llvm::APInt, 3> Dimensions;
   for (;;) {
     if (const ConstantArrayType *CAT =
@@ -1412,20 +1437,20 @@ void MicrosoftCXXNameMangler::mangleExtr
       Diags.Report(DSAT->getSizeExpr()->getExprLoc(), DiagID)
         << DSAT->getBracketsRange();
       return;
-    } else if (ElementTy->isIncompleteArrayType()) continue;
-    else break;
-  }
-  mangleQualifiers(ElementTy.getQualifiers(), false);
-  // If there are any additional dimensions, mangle them now.
-  if (Dimensions.size() > 0) {
-    Out << 'Y';
-    // <dimension-count> ::= <number> # number of extra dimensions
-    mangleNumber(Dimensions.size());
-    for (unsigned Dim = 0; Dim < Dimensions.size(); ++Dim) {
-      mangleNumber(Dimensions[Dim].getLimitedValue());
+    } else if (const IncompleteArrayType *IAT =
+          getASTContext().getAsIncompleteArrayType(ElementTy)) {
+      Dimensions.push_back(llvm::APInt(32, 0));
+      ElementTy = IAT->getElementType();
     }
+    else break;
   }
-  mangleType(ElementTy.getLocalUnqualifiedType(), SourceRange());
+  Out << 'Y';
+  // <dimension-count> ::= <number> # number of extra dimensions
+  mangleNumber(Dimensions.size());
+  for (unsigned Dim = 0; Dim < Dimensions.size(); ++Dim)
+    mangleNumber(Dimensions[Dim].getLimitedValue());
+  mangleType(getASTContext().getQualifiedType(ElementTy.getTypePtr(), Quals),
+             SourceRange(), QMM_Escape);
 }
 
 // <type>                   ::= <pointer-to-member-type>
@@ -1437,11 +1462,11 @@ void MicrosoftCXXNameMangler::mangleType
   if (const FunctionProtoType *FPT = PointeeType->getAs<FunctionProtoType>()) {
     Out << '8';
     mangleName(T->getClass()->castAs<RecordType>()->getDecl());
-    mangleType(FPT, NULL, false, true);
+    mangleFunctionType(FPT, NULL, false, true);
   } else {
     mangleQualifiers(PointeeType.getQualifiers(), true);
     mangleName(T->getClass()->castAs<RecordType>()->getDecl());
-    mangleType(PointeeType.getLocalUnqualifiedType(), Range);
+    mangleType(PointeeType, Range, QMM_Drop);
   }
 }
 
@@ -1469,17 +1494,7 @@ void MicrosoftCXXNameMangler::mangleType
 void MicrosoftCXXNameMangler::mangleType(const PointerType *T,
                                          SourceRange Range) {
   QualType PointeeTy = T->getPointeeType();
-  if (PointeeTy->isArrayType()) {
-    // Pointers to arrays are mangled like arrays.
-    mangleExtraDimensions(PointeeTy);
-  } else if (const FunctionType *FT = PointeeTy->getAs<FunctionType>()) {
-    // Function pointers are special.
-    Out << '6';
-    mangleType(FT, NULL, false, false);
-  } else {
-    mangleQualifiers(PointeeTy.getQualifiers(), false);
-    mangleType(PointeeTy, Range, false);
-  }
+  mangleType(PointeeTy, Range);
 }
 void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,
                                          SourceRange Range) {
@@ -1493,11 +1508,7 @@ void MicrosoftCXXNameMangler::mangleType
 void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T,
                                          SourceRange Range) {
   Out << 'A';
-  QualType PointeeTy = T->getPointeeType();
-  if (!PointeeTy.hasQualifiers())
-    // Lack of qualifiers is mangled as 'A'.
-    Out << 'A';
-  mangleType(PointeeTy, Range);
+  mangleType(T->getPointeeType(), Range);
 }
 
 // <type> ::= <r-value-reference-type>
@@ -1505,11 +1516,7 @@ void MicrosoftCXXNameMangler::mangleType
 void MicrosoftCXXNameMangler::mangleType(const RValueReferenceType *T,
                                          SourceRange Range) {
   Out << "$$Q";
-  QualType PointeeTy = T->getPointeeType();
-  if (!PointeeTy.hasQualifiers())
-    // Lack of qualifiers is mangled as 'A'.
-    Out << 'A';
-  mangleType(PointeeTy, Range);
+  mangleType(T->getPointeeType(), Range);
 }
 
 void MicrosoftCXXNameMangler::mangleType(const ComplexType *T,
@@ -1591,7 +1598,7 @@ void MicrosoftCXXNameMangler::mangleType
   Out << "_E";
 
   QualType pointee = T->getPointeeType();
-  mangleType(pointee->castAs<FunctionProtoType>(), NULL, false, false);
+  mangleFunctionType(pointee->castAs<FunctionProtoType>(), NULL, false, false);
 }
 
 void MicrosoftCXXNameMangler::mangleType(const InjectedClassNameType *T,

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp?rev=180250&r1=180249&r2=180250&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp Wed Apr 24 23:25:40 2013
@@ -60,6 +60,51 @@ void foo_pcrbd(const char * volatile* x)
 void foo_pcrcd(volatile char * volatile* x) {}
 // CHECK: "\01?foo_pcrcd@@YAXPCRCD at Z"
 
+void foo_aad(char &x) {}
+// CHECK: "\01?foo_aad@@YAXAAD at Z"
+
+void foo_abd(const char &x) {}
+// CHECK: "\01?foo_abd@@YAXABD at Z"
+
+void foo_aapad(char *&x) {}
+// CHECK: "\01?foo_aapad@@YAXAAPAD at Z"
+
+void foo_aapbd(const char *&x) {}
+// CHECK: "\01?foo_aapbd@@YAXAAPBD at Z"
+
+void foo_abqad(char * const &x) {}
+// CHECK: "\01?foo_abqad@@YAXABQAD at Z"
+
+void foo_abqbd(const char * const &x) {}
+// CHECK: "\01?foo_abqbd@@YAXABQBD at Z"
+
+void foo_aay144h(int (&x)[5][5]) {}
+// CHECK: "\01?foo_aay144h@@YAXAAY144H at Z"
+
+void foo_aay144cbh(const int (&x)[5][5]) {}
+// CHECK: "\01?foo_aay144cbh@@YAXAAY144$$CBH at Z"
+
+void foo_qay144h(int (&&x)[5][5]) {}
+// CHECK: "\01?foo_qay144h@@YAX$$QAY144H at Z"
+
+void foo_qay144cbh(const int (&&x)[5][5]) {}
+// CHECK: "\01?foo_qay144cbh@@YAX$$QAY144$$CBH at Z"
+
+void foo_p6ahxz(int x()) {}
+// CHECK: "\01?foo_p6ahxz@@YAXP6AHXZ at Z"
+
+void foo_a6ahxz(int (&x)()) {}
+// CHECK: "\01?foo_a6ahxz@@YAXA6AHXZ at Z"
+
+void foo_q6ahxz(int (&&x)()) {}
+// CHECK: "\01?foo_q6ahxz@@YAX$$Q6AHXZ at Z"
+
+void foo_qay04h(int x[5][5]) {}
+// CHECK: "\01?foo_qay04h@@YAXQAY04H at Z"
+
+void foo_qay04cbh(const int x[5][5]) {}
+// CHECK: "\01?foo_qay04cbh@@YAXQAY04$$CBH at Z"
+
 typedef double Vector[3];
 
 void foo(Vector*) {}

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=180250&r1=180249&r2=180250&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp Wed Apr 24 23:25:40 2013
@@ -155,6 +155,15 @@ const volatile struct S* f5() { return 0
 struct S& f6() { return *(struct S*)0; }
 // CHECK: "\01?f6@@YAAAUS@@XZ"
 
+struct S* const f7() { return 0; }
+// CHECK: "\01?f7@@YAQAUS@@XZ"
+
+int S::* f8() { return 0; }
+// CHECK: "\01?f8@@YAPQS@@HXZ"
+
+int S::* const f9() { return 0; }
+// CHECK: "\01?f9@@YAQQS@@HXZ"
+
 typedef int (*function_pointer)(int);
 
 function_pointer g1() { return 0; }

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp?rev=180250&r1=180249&r2=180250&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-templates.cpp Wed Apr 24 23:25:40 2013
@@ -3,7 +3,7 @@
 template<typename T>
 class Class {
  public:
-  void method() {}
+  Class() {}
 };
 
 class Typename { };
@@ -32,24 +32,30 @@ class BoolTemplate<true> {
 
 void template_mangling() {
   Class<Typename> c1;
-  c1.method();
-// CHECK: call {{.*}} @"\01?method@?$Class at VTypename@@@@QAEXXZ"
+// CHECK: call {{.*}} @"\01??0?$Class at VTypename@@@@QAE at XZ"
 
   Class<const Typename> c1_const;
+// CHECK: call {{.*}} @"\01??0?$Class@$$CBVTypename@@@@QAE at XZ"
   Class<volatile Typename> c1_volatile;
+// CHECK: call {{.*}} @"\01??0?$Class@$$CCVTypename@@@@QAE at XZ"
   Class<const volatile Typename> c1_cv;
-  c1_const.method();
-  c1_volatile.method();
-  c1_cv.method();
-// Types with qualifiers have an extra $$C escape when used as template
-// arguments.  Not sure why.
-// CHECK: call {{.*}} @"\01?method@?$Class@$$CBVTypename@@@@QAEXXZ"
-// CHECK: call {{.*}} @"\01?method@?$Class@$$CCVTypename@@@@QAEXXZ"
-// CHECK: call {{.*}} @"\01?method@?$Class@$$CDVTypename@@@@QAEXXZ"
+// CHECK: call {{.*}} @"\01??0?$Class@$$CDVTypename@@@@QAE at XZ"
 
   Class<Nested<Typename> > c2;
-  c2.method();
-// CHECK: call {{.*}} @"\01?method@?$Class at V?$Nested at VTypename@@@@@@QAEXXZ"
+// CHECK: call {{.*}} @"\01??0?$Class at V?$Nested at VTypename@@@@@@QAE at XZ"
+
+  Class<int * const> c_intpc;
+// CHECK: call {{.*}} @"\01??0?$Class at QAH@@QAE at XZ"
+  Class<int()> c_ft;
+// CHECK: call {{.*}} @"\01??0?$Class@$$A6AHXZ@@QAE at XZ"
+  Class<int[]> c_inti;
+// CHECK: call {{.*}} @"\01??0?$Class@$$BY0A at H@@QAE at XZ"
+  Class<int[5]> c_int5;
+// CHECK: call {{.*}} @"\01??0?$Class@$$BY04H@@QAE at XZ"
+  Class<const int[5]> c_intc5;
+// CHECK: call {{.*}} @"\01??0?$Class@$$BY04$$CBH@@QAE at XZ"
+  Class<int * const[5]> c_intpc5;
+// CHECK: call {{.*}} @"\01??0?$Class@$$BY04QAH@@QAE at XZ"
 
   BoolTemplate<false> _false;
 // CHECK: call {{.*}} @"\01??0?$BoolTemplate@$0A@@@QAE at XZ"

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms.cpp?rev=180250&r1=180249&r2=180250&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms.cpp Wed Apr 24 23:25:40 2013
@@ -17,11 +17,8 @@
 // CHECK: @"\01?l@@3P8foo@@AEHH at ZA"
 // CHECK: @"\01?color1@@3PANA"
 // CHECK: @"\01?color2@@3QBNB"
-
-// FIXME: The following three tests currently fail, see http://llvm.org/PR13182
-// Replace "CHECK-NOT" with "CHECK" when it is fixed.
-// CHECK-NOT: @"\01?color3@@3QAY02$$CBNA"
-// CHECK-NOT: @"\01?color4@@3QAY02$$CBNA"
+// CHECK: @"\01?color3@@3QAY02$$CBNA"
+// CHECK: @"\01?color4@@3QAY02$$CBNA"
 
 int a;
 





More information about the cfe-commits mailing list