]> granicus.if.org Git - clang/commitdiff
Fix mangling for dependent "type { expr-list }" expressions, and add mangling for...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 23 Aug 2017 22:12:08 +0000 (22:12 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 23 Aug 2017 22:12:08 +0000 (22:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@311612 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExprCXX.h
lib/AST/ASTDumper.cpp
lib/AST/ItaniumMangle.cpp
lib/AST/StmtProfile.cpp
test/CodeGenCXX/mangle-exprs.cpp
test/CodeGenCXX/mangle-fail.cpp

index 79d2c58099c4cea336af226d9f2d592bd4ef6746..a2cf9612698cdd0f0b7a225447bd7bcfcab5d216 100644 (file)
@@ -3056,6 +3056,11 @@ public:
   SourceLocation getRParenLoc() const { return RParenLoc; }
   void setRParenLoc(SourceLocation L) { RParenLoc = L; }
 
+  /// Determine whether this expression models list-initialization.
+  /// If so, there will be exactly one subexpression, which will be
+  /// an InitListExpr.
+  bool isListInitialization() const { return LParenLoc.isInvalid(); }
+
   /// \brief Retrieve the number of arguments.
   unsigned arg_size() const { return NumArgs; }
 
index b92df75520f59d61f306acb12e78d4ff8b19ea40..7f661548780a9ff32874952a6cf335ba7482d5ae 100644 (file)
@@ -537,6 +537,7 @@ namespace  {
     void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
     void VisitCXXThisExpr(const CXXThisExpr *Node);
     void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
+    void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node);
     void VisitCXXConstructExpr(const CXXConstructExpr *Node);
     void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
     void VisitCXXNewExpr(const CXXNewExpr *Node);
@@ -2169,12 +2170,24 @@ void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) {
      << " <" << Node->getCastKindName() << ">";
 }
 
+void ASTDumper::VisitCXXUnresolvedConstructExpr(
+    const CXXUnresolvedConstructExpr *Node) {
+  VisitExpr(Node);
+  dumpType(Node->getTypeAsWritten());
+  if (Node->isListInitialization())
+    OS << " list";
+}
+
 void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
   VisitExpr(Node);
   CXXConstructorDecl *Ctor = Node->getConstructor();
   dumpType(Ctor->getType());
   if (Node->isElidable())
     OS << " elidable";
+  if (Node->isListInitialization())
+    OS << " list";
+  if (Node->isStdInitListInitialization())
+    OS << " std::initializer_list";
   if (Node->requiresZeroInitialization())
     OS << " zeroing";
 }
index 4e7c6c4edf3707a359d9c13383bcc44fcb1b4499..294e180b59b2ec52fb605714a7899f401c6bedce 100644 (file)
@@ -3343,7 +3343,6 @@ recurse:
   case Expr::BlockExprClass:
   case Expr::ChooseExprClass:
   case Expr::CompoundLiteralExprClass:
-  case Expr::DesignatedInitExprClass:
   case Expr::ExtVectorElementExprClass:
   case Expr::GenericSelectionExprClass:
   case Expr::ObjCEncodeExprClass:
@@ -3421,6 +3420,27 @@ recurse:
     break;
   }
 
+  case Expr::DesignatedInitExprClass: {
+    auto *DIE = cast<DesignatedInitExpr>(E);
+    for (const auto &Designator : DIE->designators()) {
+      if (Designator.isFieldDesignator()) {
+        Out << "di";
+        mangleSourceName(Designator.getFieldName());
+      } else if (Designator.isArrayDesignator()) {
+        Out << "dx";
+        mangleExpression(DIE->getArrayIndex(Designator));
+      } else {
+        assert(Designator.isArrayRangeDesignator() &&
+               "unknown designator kind");
+        Out << "dX";
+        mangleExpression(DIE->getArrayRangeStart(Designator));
+        mangleExpression(DIE->getArrayRangeEnd(Designator));
+      }
+    }
+    mangleExpression(DIE->getInit());
+    break;
+  }
+
   case Expr::CXXDefaultArgExprClass:
     mangleExpression(cast<CXXDefaultArgExpr>(E)->getExpr(), Arity);
     break;
@@ -3578,6 +3598,16 @@ recurse:
     const CXXUnresolvedConstructExpr *CE = cast<CXXUnresolvedConstructExpr>(E);
     unsigned N = CE->arg_size();
 
+    if (CE->isListInitialization()) {
+      assert(N == 1 && "unexpected form for list initialization");
+      auto *IL = cast<InitListExpr>(CE->getArg(0));
+      Out << "tl";
+      mangleType(CE->getType());
+      mangleInitListElements(IL);
+      Out << "E";
+      return;
+    }
+
     Out << "cv";
     mangleType(CE->getType());
     if (N != 1) Out << '_';
index c1ba1e8e948b99e72c12d0681c1089843acab47c..9ec92cebc1d30390be8f68c1f43378ecaaf6ba7c 100644 (file)
@@ -1701,6 +1701,7 @@ void StmtProfiler::VisitCXXUnresolvedConstructExpr(
     const CXXUnresolvedConstructExpr *S) {
   VisitExpr(S);
   VisitType(S->getTypeAsWritten());
+  ID.AddInteger(S->isListInitialization());
 }
 
 void StmtProfiler::VisitCXXDependentScopeMemberExpr(
index ee7594b2fdd27da2778ca4d5f67d71529242636d..6c46402694036e10f4b72777354888a913f4020b 100644 (file)
@@ -314,6 +314,19 @@ namespace test7 {
   template<class T> decltype(F{{1,2}},T()) fF1(T t) {}
   template<class T> decltype(F({1,2}),T()) fF2(T t) {}
 
+  template<class T> decltype(T{}) fT1(T t) {}
+  template<class T> decltype(T()) fT2(T t) {}
+  template<class T> decltype(T{1}) fT3(T t) {}
+  template<class T> decltype(T(1)) fT4(T t) {}
+  template<class T> decltype(T{1,2}) fT5(T t) {}
+  template<class T> decltype(T(1,2)) fT6(T t) {}
+  template<class T> decltype(T{{}}) fT7(T t) {}
+  template<class T> decltype(T({})) fT8(T t) {}
+  template<class T> decltype(T{{1}}) fT9(T t) {}
+  template<class T> decltype(T({1})) fTA(T t) {}
+  template<class T> decltype(T{{1,2}}) fTB(T t) {}
+  template<class T> decltype(T({1,2})) fTC(T t) {}
+
   int main() {
     fA1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA1IiEEDTcmtlNS_1AELi1ELi2EEcvT__EES2_
     fA2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA2IiEEDTcmcvNS_1AEilLi1ELi2EEcvT__EES2_
@@ -327,6 +340,18 @@ namespace test7 {
     fE2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE2IiEEDTcmcvNS_1EEilLi1ELi2EEcvT__EES2_
     fF1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF1IiEEDTcmtlNS_1FEilLi1ELi2EEEcvT__EES2_
     fF2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF2IiEEDTcmcvNS_1FEilLi1ELi2EEcvT__EES2_
+    fT1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT1IiEEDTtlT_EES1_(
+    fT2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT2IiEEDTcvT__EES1_(
+    fT3(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT3IiEEDTtlT_Li1EEES1_(
+    fT4(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fT4IiEEDTcvT_Li1EES1_(
+    fT5(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fT5INS_1BEEEDTtlT_Li1ELi2EEES2_(
+    fT6(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fT6INS_1BEEEDTcvT__Li1ELi2EEES2_(
+    fT7(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT7INS_1AEEEDTtlT_ilEEES2_(
+    fT8(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT8INS_1AEEEDTcvT_ilEES2_(
+    fT9(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fT9INS_1AEEEDTtlT_ilLi1EEEES2_(
+    fTA(A{}); // CHECK-LABEL: define {{.*}} @_ZN5test73fTAINS_1AEEEDTcvT_ilLi1EEES2_(
+    fTB<C>(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fTBINS_1CEEEDTtlT_ilLi1ELi2EEEES2_(
+    fTC<C>(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fTCINS_1CEEEDTcvT_ilLi1ELi2EEES2_(
   }
 }
 
@@ -341,3 +366,10 @@ namespace test8 {
   // CHECK-LABEL: define weak_odr i32 @_ZNK5test81XIiE3barIiEEDTcl3fooIT_EEEv
   template int X<int>::bar<int>() const;
 }
+
+namespace designated_init {
+  struct A { struct B { int b[5][5]; } a; };
+  // CHECK-LABEL: define {{.*}} @_ZN15designated_init1fINS_1AEEEvDTtlT_di1adi1bdxLi3EdXLi1ELi4ELi9EEE(
+  template<typename T> void f(decltype(T{.a.b[3][1 ... 4] = 9}) x) {}
+  void use_f(A a) { f<A>(a); }
+}
index 02548964efc964bc491384a427e6e9d3ffaaa580..b588d57749fa3d09fc1fc32e54e0349ccf37f3e2 100644 (file)
@@ -1,6 +1,5 @@
 // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=1
 // RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=2
-// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=3
 
 struct A { int a; };
 
@@ -14,11 +13,6 @@ template void test<int>(int (&)[sizeof(int)]);
 template<class T> void test(int (&)[sizeof((A){}, T())]) {} // expected-error {{cannot yet mangle}}
 template void test<int>(int (&)[sizeof(A)]);
 
-#elif N == 3
-// DesignatedInitExpr
-template<class T> void test(int (&)[sizeof(A{.a = 10}, T())]) {} // expected-error {{cannot yet mangle}}
-template void test<int>(int (&)[sizeof(A)]);
-
 // FIXME: There are several more cases we can't yet mangle.
 
 #else