r228274 - Various fixes to mangling of list-initialization.

Richard Smith richard-llvm at metafoo.co.uk
Wed Feb 4 22:15:50 PST 2015


Author: rsmith
Date: Thu Feb  5 00:15:50 2015
New Revision: 228274

URL: http://llvm.org/viewvc/llvm-project?rev=228274&view=rev
Log:
Various fixes to mangling of list-initialization.

Modified:
    cfe/trunk/lib/AST/ItaniumMangle.cpp
    cfe/trunk/lib/AST/Stmt.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    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=228274&r1=228273&r2=228274&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Thu Feb  5 00:15:50 2015
@@ -378,6 +378,7 @@ private:
                         DeclarationName name,
                         unsigned knownArity);
   void mangleCastExpression(const Expr *E, StringRef CastEncoding);
+  void mangleInitListElements(const InitListExpr *InitList);
   void mangleExpression(const Expr *E, unsigned Arity = UnknownArity);
   void mangleCXXCtorType(CXXCtorType T);
   void mangleCXXDtorType(CXXDtorType T);
@@ -2594,6 +2595,13 @@ void CXXNameMangler::mangleCastExpressio
   mangleExpression(ECE->getSubExpr());
 }
 
+void CXXNameMangler::mangleInitListElements(const InitListExpr *InitList) {
+  if (auto *Syntactic = InitList->getSyntacticForm())
+    InitList = Syntactic;
+  for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i)
+    mangleExpression(InitList->getInit(i));
+}
+
 void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity) {
   // <expression> ::= <unary operator-name> <expression>
   //              ::= <binary operator-name> <expression> <expression>
@@ -2715,9 +2723,7 @@ recurse:
 
   case Expr::InitListExprClass: {
     Out << "il";
-    const InitListExpr *InitList = cast<InitListExpr>(E);
-    for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i)
-      mangleExpression(InitList->getInit(i));
+    mangleInitListElements(cast<InitListExpr>(E));
     Out << "E";
     break;
   }
@@ -2795,9 +2801,7 @@ recurse:
       } else if (New->getInitializationStyle() == CXXNewExpr::ListInit &&
                  isa<InitListExpr>(Init)) {
         // Only take InitListExprs apart for list-initialization.
-        const InitListExpr *InitList = cast<InitListExpr>(Init);
-        for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i)
-          mangleExpression(InitList->getInit(i));
+        mangleInitListElements(cast<InitListExpr>(Init));
       } else
         mangleExpression(Init);
     }
@@ -2858,26 +2862,45 @@ recurse:
     break;
   }
 
-  case Expr::CXXTemporaryObjectExprClass:
   case Expr::CXXConstructExprClass: {
-    const CXXConstructExpr *CE = cast<CXXConstructExpr>(E);
+    const auto *CE = cast<CXXConstructExpr>(E);
+    if (!CE->isListInitialization()) {
+      assert(
+          CE->getNumArgs() >= 1 &&
+          (CE->getNumArgs() == 1 || isa<CXXDefaultArgExpr>(CE->getArg(1))) &&
+          "implicit CXXConstructExpr must have one argument");
+      return mangleExpression(cast<CXXConstructExpr>(E)->getArg(0));
+    }
+    Out << "il";
+    for (auto *E : CE->arguments())
+      mangleExpression(E);
+    Out << "E";
+    break;
+  }
+
+  case Expr::CXXTemporaryObjectExprClass: {
+    const auto *CE = cast<CXXTemporaryObjectExpr>(E);
     unsigned N = CE->getNumArgs();
+    bool List = CE->isListInitialization();
 
-    if (CE->isListInitialization())
+    if (List)
       Out << "tl";
     else
       Out << "cv";
     mangleType(CE->getType());
-    if (N != 1) Out << '_';
-    for (unsigned I = 0; I != N; ++I) mangleExpression(CE->getArg(I));
-    if (N != 1) Out << 'E';
+    if (!List && N != 1)
+      Out << '_';
+    for (auto *E : CE->arguments())
+      mangleExpression(E);
+    if (List || N != 1)
+      Out << 'E';
     break;
   }
 
   case Expr::CXXScalarValueInitExprClass:
-    Out <<"cv";
+    Out << "cv";
     mangleType(E->getType());
-    Out <<"_E";
+    Out << "_E";
     break;
 
   case Expr::CXXNoexceptExprClass:
@@ -3022,10 +3045,28 @@ recurse:
   // Fall through to mangle the cast itself.
       
   case Expr::CStyleCastExprClass:
-  case Expr::CXXFunctionalCastExprClass:
     mangleCastExpression(E, "cv");
     break;
 
+  case Expr::CXXFunctionalCastExprClass: {
+    auto *Sub = cast<ExplicitCastExpr>(E)->getSubExpr()->IgnoreImplicit();
+    // FIXME: Add isImplicit to CXXConstructExpr.
+    if (auto *CCE = dyn_cast<CXXConstructExpr>(Sub))
+      if (CCE->getParenOrBraceRange().isInvalid())
+        Sub = CCE->getArg(0)->IgnoreImplicit();
+    if (auto *StdInitList = dyn_cast<CXXStdInitializerListExpr>(Sub))
+      Sub = StdInitList->getSubExpr()->IgnoreImplicit();
+    if (auto *IL = dyn_cast<InitListExpr>(Sub)) {
+      Out << "tl";
+      mangleType(E->getType());
+      mangleInitListElements(IL);
+      Out << "E";
+    } else {
+      mangleCastExpression(E, "cv");
+    }
+    break;
+  }
+
   case Expr::CXXStaticCastExprClass:
     mangleCastExpression(E, "sc");
     break;

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=228274&r1=228273&r2=228274&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Thu Feb  5 00:15:50 2015
@@ -95,10 +95,16 @@ void Stmt::EnableStatistics() {
 Stmt *Stmt::IgnoreImplicit() {
   Stmt *s = this;
 
-  if (ExprWithCleanups *ewc = dyn_cast<ExprWithCleanups>(s))
+  if (auto *ewc = dyn_cast<ExprWithCleanups>(s))
     s = ewc->getSubExpr();
 
-  while (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(s))
+  if (auto *mte = dyn_cast<MaterializeTemporaryExpr>(s))
+    s = mte->GetTemporaryExpr();
+
+  if (auto *bte = dyn_cast<CXXBindTemporaryExpr>(s))
+    s = bte->getSubExpr();
+
+  while (auto *ice = dyn_cast<ImplicitCastExpr>(s))
     s = ice->getSubExpr();
 
   return s;

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=228274&r1=228273&r2=228274&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Feb  5 00:15:50 2015
@@ -640,6 +640,9 @@ InitListChecker::InitListChecker(Sema &S
                                  InitListExpr *IL, QualType &T,
                                  bool VerifyOnly)
   : SemaRef(S), VerifyOnly(VerifyOnly) {
+  // FIXME: Check that IL isn't already the semantic form of some other
+  // InitListExpr. If it is, we'd create a broken AST.
+
   hadError = false;
 
   FullyStructuredList =

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=228274&r1=228273&r2=228274&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Feb  5 00:15:50 2015
@@ -7834,6 +7834,9 @@ TreeTransform<Derived>::TransformExtVect
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
+  if (InitListExpr *Syntactic = E->getSyntacticForm())
+    E = Syntactic;
+
   bool InitChanged = false;
 
   SmallVector<Expr*, 4> Inits;
@@ -7841,8 +7844,12 @@ TreeTransform<Derived>::TransformInitLis
                                   Inits, &InitChanged))
     return ExprError();
 
-  if (!getDerived().AlwaysRebuild() && !InitChanged)
-    return E;
+  if (!getDerived().AlwaysRebuild() && !InitChanged) {
+    // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
+    // in some cases. We can't reuse it in general, because the syntactic and
+    // semantic forms are linked, and we can't know that semantic form will
+    // match even if the syntactic form does.
+  }
 
   return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
                                       E->getRBraceLoc(), E->getType());

Modified: cfe/trunk/test/CodeGenCXX/mangle-exprs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-exprs.cpp?rev=228274&r1=228273&r2=228274&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-exprs.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-exprs.cpp Thu Feb  5 00:15:50 2015
@@ -293,3 +293,29 @@ namespace test6 {
   // CHECK-LABEL: define weak_odr void @_ZN5test62f8IiEEvDTcvT_dtptL_ZNS_2zpEE4uuss1iE
 }
 
+namespace test7 {
+  struct A { int x[3]; };
+  struct B { B(int, int); } extern b;
+  struct C { C(B); };
+  struct D { D(C); };
+
+  template<class T> decltype(A{1,2},T()) fA1(T t) {}
+  template<class T> decltype(A({1,2}),T()) fA2(T t) {}
+  template<class T> decltype(B{1,2},T()) fB1(T t) {}
+  template<class T> decltype(B({1,2}),T()) fB2(T t) {}
+  template<class T> decltype(C{{1,2}},T()) fC1(T t) {}
+  template<class T> decltype(C({1,2}),T()) fC2(T t) {}
+  template<class T> decltype(D{b},T()) fD1(T t) {}
+  template<class T> decltype(D(b),T()) fD2(T t) {}
+
+  int main() {
+    fA1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA1IiEEDTcmtlNS_1AELi1ELi2EEcvT__EES2_
+    fA2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA2IiEEDTcmcvNS_1AEilLi1ELi2EEcvT__EES2_
+    fB1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fB1IiEEDTcmtlNS_1BELi1ELi2EEcvT__EES2_
+    fB2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fB2IiEEDTcmcvNS_1BEilLi1ELi2EEcvT__EES2_
+    fC1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fC1IiEEDTcmtlNS_1CEilLi1ELi2EEEcvT__EES2_
+    fC2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fC2IiEEDTcmcvNS_1CEilLi1ELi2EEcvT__EES2_
+    fD1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fD1IiEEDTcmtlNS_1DEL_ZNS_1bEEEcvT__EES2_
+    fD2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fD2IiEEDTcmcvNS_1DEL_ZNS_1bEEcvT__EES2_
+  }
+}





More information about the cfe-commits mailing list