From: Richard Smith Date: Wed, 23 Aug 2017 22:12:08 +0000 (+0000) Subject: Fix mangling for dependent "type { expr-list }" expressions, and add mangling for... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=919ae5fc042719d9f21b2d569e9425b948f7b1f1;p=clang Fix mangling for dependent "type { expr-list }" expressions, and add mangling for designated initializers matching recent cxx-abi-dev discussion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@311612 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 79d2c58099..a2cf961269 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -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; } diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index b92df75520..7f66154878 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -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"; } diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 4e7c6c4edf..294e180b59 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -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(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(E)->getExpr(), Arity); break; @@ -3578,6 +3598,16 @@ recurse: const CXXUnresolvedConstructExpr *CE = cast(E); unsigned N = CE->arg_size(); + if (CE->isListInitialization()) { + assert(N == 1 && "unexpected form for list initialization"); + auto *IL = cast(CE->getArg(0)); + Out << "tl"; + mangleType(CE->getType()); + mangleInitListElements(IL); + Out << "E"; + return; + } + Out << "cv"; mangleType(CE->getType()); if (N != 1) Out << '_'; diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index c1ba1e8e94..9ec92cebc1 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -1701,6 +1701,7 @@ void StmtProfiler::VisitCXXUnresolvedConstructExpr( const CXXUnresolvedConstructExpr *S) { VisitExpr(S); VisitType(S->getTypeAsWritten()); + ID.AddInteger(S->isListInitialization()); } void StmtProfiler::VisitCXXDependentScopeMemberExpr( diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp index ee7594b2fd..6c46402694 100644 --- a/test/CodeGenCXX/mangle-exprs.cpp +++ b/test/CodeGenCXX/mangle-exprs.cpp @@ -314,6 +314,19 @@ namespace test7 { template decltype(F{{1,2}},T()) fF1(T t) {} template decltype(F({1,2}),T()) fF2(T t) {} + template decltype(T{}) fT1(T t) {} + template decltype(T()) fT2(T t) {} + template decltype(T{1}) fT3(T t) {} + template decltype(T(1)) fT4(T t) {} + template decltype(T{1,2}) fT5(T t) {} + template decltype(T(1,2)) fT6(T t) {} + template decltype(T{{}}) fT7(T t) {} + template decltype(T({})) fT8(T t) {} + template decltype(T{{1}}) fT9(T t) {} + template decltype(T({1})) fTA(T t) {} + template decltype(T{{1,2}}) fTB(T t) {} + template 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(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fTBINS_1CEEEDTtlT_ilLi1ELi2EEEES2_( + fTC(b); // CHECK-LABEL: define {{.*}} @_ZN5test73fTCINS_1CEEEDTcvT_ilLi1ELi2EEES2_( } } @@ -341,3 +366,10 @@ namespace test8 { // CHECK-LABEL: define weak_odr i32 @_ZNK5test81XIiE3barIiEEDTcl3fooIT_EEEv template int X::bar() const; } + +namespace designated_init { + struct A { struct B { int b[5][5]; } a; }; + // CHECK-LABEL: define {{.*}} @_ZN15designated_init1fINS_1AEEEvDTtlT_di1adi1bdxLi3EdXLi1ELi4ELi9EEE( + template void f(decltype(T{.a.b[3][1 ... 4] = 9}) x) {} + void use_f(A a) { f(a); } +} diff --git a/test/CodeGenCXX/mangle-fail.cpp b/test/CodeGenCXX/mangle-fail.cpp index 02548964ef..b588d57749 100644 --- a/test/CodeGenCXX/mangle-fail.cpp +++ b/test/CodeGenCXX/mangle-fail.cpp @@ -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 (&)[sizeof(int)]); template void test(int (&)[sizeof((A){}, T())]) {} // expected-error {{cannot yet mangle}} template void test(int (&)[sizeof(A)]); -#elif N == 3 -// DesignatedInitExpr -template void test(int (&)[sizeof(A{.a = 10}, T())]) {} // expected-error {{cannot yet mangle}} -template void test(int (&)[sizeof(A)]); - // FIXME: There are several more cases we can't yet mangle. #else