r218293 - AST: Mangle cast expression encoding more accurately

David Majnemer david.majnemer at gmail.com
Mon Sep 22 21:27:56 PDT 2014


Author: majnemer
Date: Mon Sep 22 23:27:55 2014
New Revision: 218293

URL: http://llvm.org/viewvc/llvm-project?rev=218293&view=rev
Log:
AST: Mangle cast expression encoding more accurately

Don't mangle all casts in expressions as "cv", use the appropriate
encoding which corresponds to a specific cast.

This fixes PR21034.

Differential Revision: http://reviews.llvm.org/D5453

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

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=218293&r1=218292&r2=218293&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Mon Sep 22 23:27:55 2014
@@ -375,6 +375,7 @@ private:
                         NamedDecl *firstQualifierLookup,
                         DeclarationName name,
                         unsigned knownArity);
+  void mangleCastExpression(const Expr *E, StringRef CastEncoding);
   void mangleExpression(const Expr *E, unsigned Arity = UnknownArity);
   void mangleCXXCtorType(CXXCtorType T);
   void mangleCXXDtorType(CXXDtorType T);
@@ -2572,12 +2573,23 @@ static bool isParenthesizedADLCallee(con
   return true;
 }
 
+void CXXNameMangler::mangleCastExpression(const Expr *E, StringRef CastEncoding) {
+  const ExplicitCastExpr *ECE = cast<ExplicitCastExpr>(E);
+  Out << CastEncoding;
+  mangleType(ECE->getType());
+  mangleExpression(ECE->getSubExpr());
+}
+
 void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
   // <expression> ::= <unary operator-name> <expression>
   //              ::= <binary operator-name> <expression> <expression>
   //              ::= <trinary operator-name> <expression> <expression> <expression>
   //              ::= cv <type> expression           # conversion with one argument
   //              ::= cv <type> _ <expression>* E # conversion with a different number of arguments
+  //              ::= dc <type> <expression>         # dynamic_cast<type> (expression)
+  //              ::= sc <type> <expression>         # static_cast<type> (expression)
+  //              ::= cc <type> <expression>         # const_cast<type> (expression)
+  //              ::= rc <type> <expression>         # reinterpret_cast<type> (expression)
   //              ::= st <type>                      # sizeof (a type)
   //              ::= at <type>                      # alignof (a type)
   //              ::= <template-param>
@@ -2982,17 +2994,22 @@ recurse:
   // Fall through to mangle the cast itself.
       
   case Expr::CStyleCastExprClass:
+  case Expr::CXXFunctionalCastExprClass:
+    mangleCastExpression(E, "cv");
+    break;
+
   case Expr::CXXStaticCastExprClass:
+    mangleCastExpression(E, "sc");
+    break;
   case Expr::CXXDynamicCastExprClass:
+    mangleCastExpression(E, "dc");
+    break;
   case Expr::CXXReinterpretCastExprClass:
+    mangleCastExpression(E, "rc");
+    break;
   case Expr::CXXConstCastExprClass:
-  case Expr::CXXFunctionalCastExprClass: {
-    const ExplicitCastExpr *ECE = cast<ExplicitCastExpr>(E);
-    Out << "cv";
-    mangleType(ECE->getType());
-    mangleExpression(ECE->getSubExpr());
+    mangleCastExpression(E, "cc");
     break;
-  }
 
   case Expr::CXXOperatorCallExprClass: {
     const CXXOperatorCallExpr *CE = cast<CXXOperatorCallExpr>(E);

Modified: cfe/trunk/test/CodeGenCXX/mangle-exprs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-exprs.cpp?rev=218293&r1=218292&r2=218293&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-exprs.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-exprs.cpp Mon Sep 22 23:27:55 2014
@@ -56,6 +56,18 @@ namespace Casts {
   void static_(typename enable_if< O <= static_cast<unsigned>(4) >::type* = 0) {
   }
 
+  template <unsigned O, typename T>
+  void reinterpret_(typename enable_if<O <= sizeof(reinterpret_cast<T *>(0))>::type * = 0) {
+  }
+
+  template <typename T, T *p>
+  void const_(typename enable_if<0 <= sizeof(const_cast<T *>(p))>::type * = 0) {
+  }
+
+  template <typename T, T *p>
+  void dynamic_(typename enable_if<0 <= sizeof(dynamic_cast<T *>(p))>::type * = 0) {
+  }
+
   template< typename T >
   void auto_(decltype(new auto(T()))) {
   }
@@ -64,11 +76,12 @@ namespace Casts {
   void scalar_(decltype(T(), int())) {
   }
 
-  // FIXME: Test const_cast, reinterpret_cast, dynamic_cast, which are
-  // a bit harder to use in template arguments.
   template <unsigned N> struct T {};
 
   template <int N> T<N> f() { return T<N>(); }
+
+  extern int i;
+  extern struct S {} s;
   
   // CHECK-LABEL: define weak_odr void @_ZN5Casts8implicitILj4EEEvPN9enable_ifIXleT_Li4EEvE4typeE
   template void implicit<4>(void*);
@@ -76,8 +89,14 @@ namespace Casts {
   template void cstyle<4>(void*);
   // CHECK-LABEL: define weak_odr void @_ZN5Casts10functionalILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
   template void functional<4>(void*);
-  // CHECK-LABEL: define weak_odr void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_cvjLi4EEvE4typeE
+  // CHECK-LABEL: define weak_odr void @_ZN5Casts7static_ILj4EEEvPN9enable_ifIXleT_scjLi4EEvE4typeE
   template void static_<4>(void*);
+  // CHECK-LABEL: define weak_odr void @_ZN5Casts12reinterpret_ILj4EiEEvPN9enable_ifIXleT_szrcPT0_Li0EEvE4typeE
+  template void reinterpret_<4, int>(void*);
+  // CHECK-LABEL: define weak_odr void @_ZN5Casts6const_IiXadL_ZNS_1iEEEEEvPN9enable_ifIXleLi0EszccPT_T0_EvE4typeE
+  template void const_<int, &i>(void*);
+  // CHECK-LABEL: define weak_odr void @_ZN5Casts8dynamic_INS_1SEXadL_ZNS_1sEEEEEvPN9enable_ifIXleLi0EszdcPT_T0_EvE4typeE
+  template void dynamic_<struct S, &s>(void*);
 
   // CHECK-LABEL: define weak_odr void @_ZN5Casts1fILi6EEENS_1TIXT_EEEv
   template T<6> f<6>();





More information about the cfe-commits mailing list