r229255 - ItaniumMangle: Correctly mangle <base-unresolved-name>

David Majnemer david.majnemer at gmail.com
Sat Feb 14 05:23:54 PST 2015


Author: majnemer
Date: Sat Feb 14 07:23:54 2015
New Revision: 229255

URL: http://llvm.org/viewvc/llvm-project?rev=229255&view=rev
Log:
ItaniumMangle: Correctly mangle <base-unresolved-name>

We had two bugs:
- We were missing the "on" prefix for unresolved operators.
- We didn't handle the mangling of destructors at all.

This fixes PR22584.

Modified:
    cfe/trunk/lib/AST/ItaniumMangle.cpp
    cfe/trunk/test/CodeGenCXX/mangle.cpp

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=229255&r1=229254&r2=229255&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Sat Feb 14 07:23:54 2015
@@ -372,6 +372,7 @@ private:
   void mangleAArch64NeonVectorType(const VectorType *T);
 
   void mangleIntegerLiteral(QualType T, const llvm::APSInt &Value);
+  void mangleMemberExprBase(const Expr *base, bool isArrow);
   void mangleMemberExpr(const Expr *base, bool isArrow,
                         NestedNameSpecifier *qualifier,
                         NamedDecl *firstQualifierLookup,
@@ -1050,6 +1051,27 @@ void CXXNameMangler::mangleUnresolvedNam
                                           DeclarationName name,
                                           unsigned knownArity) {
   if (qualifier) mangleUnresolvedPrefix(qualifier, firstQualifierLookup);
+  switch (name.getNameKind()) {
+    // <base-unresolved-name> ::= <simple-id>
+    case DeclarationName::Identifier:
+      break;
+    // <base-unresolved-name> ::= on <operator-name>
+    case DeclarationName::CXXConversionFunctionName:
+    case DeclarationName::CXXLiteralOperatorName:
+    case DeclarationName::CXXOperatorName:
+      Out << "on";
+      break;
+    case DeclarationName::CXXDestructorName:
+      llvm_unreachable("Can't mangle a constructor name!");
+    case DeclarationName::CXXConstructorName:
+      llvm_unreachable("Can't mangle a constructor name!");
+    case DeclarationName::CXXUsingDirective:
+      llvm_unreachable("Can't mangle a using directive name!");
+    case DeclarationName::ObjCMultiArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCZeroArgSelector:
+      llvm_unreachable("Can't mangle Objective-C selector names here!");
+  }
   mangleUnqualifiedName(nullptr, name, knownArity);
 }
 
@@ -1532,7 +1554,8 @@ void CXXNameMangler::mangleTemplatePrefi
    
   DependentTemplateName *Dependent = Template.getAsDependentTemplateName();
   assert(Dependent && "Unknown template name kind?");
-  manglePrefix(Dependent->getQualifier());
+  if (NestedNameSpecifier *Qualifier = Dependent->getQualifier())
+    manglePrefix(Qualifier);
   mangleUnscopedTemplateName(Template);
 }
 
@@ -2522,6 +2545,29 @@ void CXXNameMangler::mangleIntegerLitera
 
 }
 
+void CXXNameMangler::mangleMemberExprBase(const Expr *Base, bool IsArrow) {
+  // Ignore member expressions involving anonymous unions.
+  while (const auto *RT = Base->getType()->getAs<RecordType>()) {
+    if (!RT->getDecl()->isAnonymousStructOrUnion())
+      break;
+    const auto *ME = dyn_cast<MemberExpr>(Base);
+    if (!ME)
+      break;
+    Base = ME->getBase();
+    IsArrow = ME->isArrow();
+  }
+
+  if (Base->isImplicitCXXThis()) {
+    // Note: GCC mangles member expressions to the implicit 'this' as
+    // *this., whereas we represent them as this->. The Itanium C++ ABI
+    // does not specify anything here, so we follow GCC.
+    Out << "dtdefpT";
+  } else {
+    Out << (IsArrow ? "pt" : "dt");
+    mangleExpression(Base);
+  }
+}
+
 /// Mangles a member expression.
 void CXXNameMangler::mangleMemberExpr(const Expr *base,
                                       bool isArrow,
@@ -2531,29 +2577,8 @@ void CXXNameMangler::mangleMemberExpr(co
                                       unsigned arity) {
   // <expression> ::= dt <expression> <unresolved-name>
   //              ::= pt <expression> <unresolved-name>
-  if (base) {
-
-    // Ignore member expressions involving anonymous unions.
-    while (const auto *RT = base->getType()->getAs<RecordType>()) {
-      if (!RT->getDecl()->isAnonymousStructOrUnion())
-        break;
-      const auto *ME = dyn_cast<MemberExpr>(base);
-      if (!ME)
-        break;
-      base = ME->getBase();
-      isArrow = ME->isArrow();
-    }
-
-    if (base->isImplicitCXXThis()) {
-      // Note: GCC mangles member expressions to the implicit 'this' as
-      // *this., whereas we represent them as this->. The Itanium C++ ABI
-      // does not specify anything here, so we follow GCC.
-      Out << "dtdefpT";
-    } else {
-      Out << (isArrow ? "pt" : "dt");
-      mangleExpression(base);
-    }
-  }
+  if (base)
+    mangleMemberExprBase(base, isArrow);
   mangleUnresolvedName(qualifier, firstQualifierLookup, member, arity);
 }
 
@@ -2651,7 +2676,6 @@ recurse:
 
   // FIXME: invent manglings for all these.
   case Expr::BlockExprClass:
-  case Expr::CXXPseudoDestructorExprClass:
   case Expr::ChooseExprClass:
   case Expr::CompoundLiteralExprClass:
   case Expr::ExtVectorElementExprClass:
@@ -2809,6 +2833,20 @@ recurse:
     break;
   }
 
+  case Expr::CXXPseudoDestructorExprClass: {
+    const auto *PDE = cast<CXXPseudoDestructorExpr>(E);
+    if (const Expr *Base = PDE->getBase())
+      mangleMemberExprBase(Base, PDE->isArrow());
+    if (NestedNameSpecifier *Qualifier = PDE->getQualifier())
+      mangleUnresolvedPrefix(Qualifier, /*FirstQualifierLookup=*/nullptr);
+    // <base-unresolved-name> ::= dn <destructor-name>
+    Out << "dn";
+    // <destructor-name> ::= <unresolved-type>
+    //                   ::= <simple-id>
+    manglePrefix(PDE->getDestroyedType());
+    break;
+  }
+
   case Expr::MemberExprClass: {
     const MemberExpr *ME = cast<MemberExpr>(E);
     mangleMemberExpr(ME->getBase(), ME->isArrow(),

Modified: cfe/trunk/test/CodeGenCXX/mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle.cpp?rev=229255&r1=229254&r2=229255&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle.cpp Sat Feb 14 07:23:54 2015
@@ -577,10 +577,10 @@ namespace test18 {
   template <typename T> void f(S<&T::operator&>) {}
   template void f<A>(S<&A::operator&>);
 
-  // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_plEEE
-  // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_miEEE
-  // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_mlEEE
-  // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_anEEE
+  // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onplEEE
+  // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onmiEEE
+  // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onmlEEE
+  // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onanEEE
 }
 
 // rdar://problem/8332117
@@ -601,11 +601,11 @@ namespace test19 {
 
   // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_1fIiEEEE(
   template void g<A>(S<&A::f<int> >);
-  // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_plEEE(
+  // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_onplEEE(
   template void g<A>(S<&A::operator+>);
-  // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_cviEEE(
+  // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_oncviEEE(
   template void g<A>(S<&A::operator int>);
-  // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_miIdEEEE(
+  // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_onmiIdEEEE(
   template void g<A>(S<&A::operator-<double> >);
 }
 
@@ -839,7 +839,7 @@ namespace test35 {
   template<typename T>
   void f1(decltype(sizeof(&T::template operator+<int>))) {}
 
-  // CHECK-LABEL: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_plIiEE
+  // CHECK-LABEL: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_onplIiEE
   template void f1<A>(__SIZE_TYPE__);
 }
 
@@ -1013,3 +1013,27 @@ namespace test50 {
   auto v = fin<S>;
   // CHECK-LABEL: declare void @_ZN6test503finINS_1SEEET_ILi3EES2_ILi4EE()
 }
+
+namespace test51 {
+  template <typename T>
+  decltype(T().~T()) fun() {}
+  template void fun<int>();
+  // CHECK-LABEL: @_ZN6test513funIiEEDTcldtcvT__EdnS1_EEv
+  template void fun<X>();
+  // CHECK-LABEL: @_ZN6test513funI1XEEDTcldtcvT__EdnS2_EEv
+  template void fun<S1<int> >();
+  // CHECK-LABEL: @_ZN6test513funI2S1IiEEEDTcldtcvT__EdnS3_EEv
+
+  template <typename T>
+  decltype(S1<T>().~S1<T>()) fun1() {};
+  template <typename U, typename T>
+  decltype(U().~S1<T>()) fun2() {}
+  template <typename U, typename T>
+  decltype(S1<T>().~U()) fun3() {}
+  template void fun1<int>();
+  // CHECK-LABEL: @_ZN6test514fun1IiEEDTcldtcv2S1IT_E_Edn2S1IS2_EEEv
+  template void fun2<S1<int>, int>();
+  // CHECK-LABEL: @_ZN6test514fun2I2S1IiEiEEDTcldtcvT__Edn2S1IT0_EEEv
+  template void fun3<S1<int>, int>();
+  // CHECK-LABEL: @_ZN6test514fun3I2S1IiEiEEDTcldtcvS1_IT0_E_EdnT_EEv
+}





More information about the cfe-commits mailing list