diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 71 | ||||
-rw-r--r-- | clang/lib/AST/Stmt.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 11 |
4 files changed, 76 insertions, 19 deletions
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 467bbe1f225..96d4db75e5a 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/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) { // <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; diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index 68c7e727843..64b1897e0b5 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -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; diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 089746725f3..1068b3e7e13 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/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/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 36abbb624af..8cbc75a7ce1 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7834,6 +7834,9 @@ TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) { 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>::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()); |