From 789175b49aa1bb509ac47e81e3f603e97fa6f36b Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 5 Feb 2015 06:15:50 +0000 Subject: [PATCH] Various fixes to mangling of list-initialization. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@228274 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ItaniumMangle.cpp | 71 +++++++++++++++++++++++++------- lib/AST/Stmt.cpp | 10 ++++- lib/Sema/SemaInit.cpp | 3 ++ lib/Sema/TreeTransform.h | 11 ++++- test/CodeGenCXX/mangle-exprs.cpp | 26 ++++++++++++ 5 files changed, 102 insertions(+), 19 deletions(-) diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 467bbe1f22..96d4db75e5 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -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::mangleCastExpression(const Expr *E, StringRef CastEncoding) 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) { // ::= // ::= @@ -2715,9 +2723,7 @@ recurse: case Expr::InitListExprClass: { Out << "il"; - const InitListExpr *InitList = cast(E); - for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i) - mangleExpression(InitList->getInit(i)); + mangleInitListElements(cast(E)); Out << "E"; break; } @@ -2795,9 +2801,7 @@ recurse: } else if (New->getInitializationStyle() == CXXNewExpr::ListInit && isa(Init)) { // Only take InitListExprs apart for list-initialization. - const InitListExpr *InitList = cast(Init); - for (unsigned i = 0, e = InitList->getNumInits(); i != e; ++i) - mangleExpression(InitList->getInit(i)); + mangleInitListElements(cast(Init)); } else mangleExpression(Init); } @@ -2858,26 +2862,45 @@ recurse: break; } - case Expr::CXXTemporaryObjectExprClass: case Expr::CXXConstructExprClass: { - const CXXConstructExpr *CE = cast(E); + const auto *CE = cast(E); + if (!CE->isListInitialization()) { + assert( + CE->getNumArgs() >= 1 && + (CE->getNumArgs() == 1 || isa(CE->getArg(1))) && + "implicit CXXConstructExpr must have one argument"); + return mangleExpression(cast(E)->getArg(0)); + } + Out << "il"; + for (auto *E : CE->arguments()) + mangleExpression(E); + Out << "E"; + break; + } + + case Expr::CXXTemporaryObjectExprClass: { + const auto *CE = cast(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(E)->getSubExpr()->IgnoreImplicit(); + // FIXME: Add isImplicit to CXXConstructExpr. + if (auto *CCE = dyn_cast(Sub)) + if (CCE->getParenOrBraceRange().isInvalid()) + Sub = CCE->getArg(0)->IgnoreImplicit(); + if (auto *StdInitList = dyn_cast(Sub)) + Sub = StdInitList->getSubExpr()->IgnoreImplicit(); + if (auto *IL = dyn_cast(Sub)) { + Out << "tl"; + mangleType(E->getType()); + mangleInitListElements(IL); + Out << "E"; + } else { + mangleCastExpression(E, "cv"); + } + break; + } + case Expr::CXXStaticCastExprClass: mangleCastExpression(E, "sc"); break; diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 68c7e72784..64b1897e0b 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -95,10 +95,16 @@ void Stmt::EnableStatistics() { Stmt *Stmt::IgnoreImplicit() { Stmt *s = this; - if (ExprWithCleanups *ewc = dyn_cast(s)) + if (auto *ewc = dyn_cast(s)) s = ewc->getSubExpr(); - while (ImplicitCastExpr *ice = dyn_cast(s)) + if (auto *mte = dyn_cast(s)) + s = mte->GetTemporaryExpr(); + + if (auto *bte = dyn_cast(s)) + s = bte->getSubExpr(); + + while (auto *ice = dyn_cast(s)) s = ice->getSubExpr(); return s; diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 089746725f..1068b3e7e1 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -640,6 +640,9 @@ InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity, 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 = diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 36abbb624a..8cbc75a7ce 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -7834,6 +7834,9 @@ TreeTransform::TransformExtVectorElementExpr(ExtVectorElementExpr *E) { template ExprResult TreeTransform::TransformInitListExpr(InitListExpr *E) { + if (InitListExpr *Syntactic = E->getSyntacticForm()) + E = Syntactic; + bool InitChanged = false; SmallVector Inits; @@ -7841,8 +7844,12 @@ TreeTransform::TransformInitListExpr(InitListExpr *E) { 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()); diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp index ee7f24466b..1048a31dbb 100644 --- a/test/CodeGenCXX/mangle-exprs.cpp +++ b/test/CodeGenCXX/mangle-exprs.cpp @@ -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 decltype(A{1,2},T()) fA1(T t) {} + template decltype(A({1,2}),T()) fA2(T t) {} + template decltype(B{1,2},T()) fB1(T t) {} + template decltype(B({1,2}),T()) fB2(T t) {} + template decltype(C{{1,2}},T()) fC1(T t) {} + template decltype(C({1,2}),T()) fC2(T t) {} + template decltype(D{b},T()) fD1(T t) {} + template 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_ + } +} -- 2.40.0