diff options
-rw-r--r-- | include/clang/Sema/Sema.h | 14 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 3 | ||||
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 3 | ||||
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 9 | ||||
-rw-r--r-- | test/CodeGenCXX/mangle-lambdas.cpp | 13 |
7 files changed, 46 insertions, 7 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 676f52953f..97d425ceae 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2721,7 +2721,10 @@ public: void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl = 0, bool IsDecltype = false); - + enum ReuseLambdaContextDecl_t { ReuseLambdaContextDecl }; + void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, + ReuseLambdaContextDecl_t, + bool IsDecltype = false); void PopExpressionEvaluationContext(); void DiscardCleanupsInEvaluationContext(); @@ -7295,6 +7298,15 @@ public: Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl, IsDecltype); } + EnterExpressionEvaluationContext(Sema &Actions, + Sema::ExpressionEvaluationContext NewContext, + Sema::ReuseLambdaContextDecl_t, + bool IsDecltype = false) + : Actions(Actions) { + Actions.PushExpressionEvaluationContext(NewContext, + Sema::ReuseLambdaContextDecl, + IsDecltype); + } ~EnterExpressionEvaluationContext() { Actions.PopExpressionEvaluationContext(); diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index f8a20c3b53..674cd2d22f 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -5078,7 +5078,8 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) { const bool hasParens = Tok.is(tok::l_paren); - EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, + Sema::ReuseLambdaContextDecl); bool isCastExpr; ParsedType CastTy; diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 37cdd14407..90373920c5 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -1723,7 +1723,8 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() { if (OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw__Alignof)) Diag(OpTok, diag::warn_cxx98_compat_alignof); - EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, + Sema::ReuseLambdaContextDecl); bool isCastExpr; ParsedType CastTy; diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 3039368cf7..41bf1b623f 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -1001,7 +1001,8 @@ ExprResult Parser::ParseCXXTypeid() { // We enter the unevaluated context before trying to determine whether we // have a type-id, because the tentative parse logic will try to resolve // names, and must treat them as unevaluated. - EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated, + Sema::ReuseLambdaContextDecl); if (isTypeIdInParens()) { TypeResult Ty = ParseTypeName(); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 41985328bb..630281a424 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -10135,6 +10135,14 @@ Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs); } +void +Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, + ReuseLambdaContextDecl_t, + bool IsDecltype) { + Decl *LambdaContextDecl = ExprEvalContexts.back().LambdaContextDecl; + PushExpressionEvaluationContext(NewContext, LambdaContextDecl, IsDecltype); +} + void Sema::PopExpressionEvaluationContext() { ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back(); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 975895dc8e..e0451c4c49 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -4275,7 +4275,8 @@ template<typename Derived> QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB, TypeOfExprTypeLoc TL) { // typeof expressions are not potentially evaluated contexts - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated, + Sema::ReuseLambdaContextDecl); ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr()); if (E.isInvalid()) @@ -6266,7 +6267,8 @@ TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr( // C++0x [expr.sizeof]p1: // The operand is either an expression, which is an unevaluated operand // [...] - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated, + Sema::ReuseLambdaContextDecl); ExprResult SubExpr = getDerived().TransformExpr(E->getArgumentExpr()); if (SubExpr.isInvalid()) @@ -7002,7 +7004,8 @@ TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) { // after we perform semantic analysis. We speculatively assume it is // unevaluated; it will get fixed later if the subexpression is in fact // potentially evaluated. - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated, + Sema::ReuseLambdaContextDecl); ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand()); if (SubExpr.isInvalid()) diff --git a/test/CodeGenCXX/mangle-lambdas.cpp b/test/CodeGenCXX/mangle-lambdas.cpp index 979760dab9..0bd5ad2a02 100644 --- a/test/CodeGenCXX/mangle-lambdas.cpp +++ b/test/CodeGenCXX/mangle-lambdas.cpp @@ -172,6 +172,19 @@ template<typename...T> int PR12917<T...>::n[3] = { PR12917<int, char, double> pr12917; int *pr12917_p = PR12917<int, int>::n; +namespace std { + struct type_info; +} +namespace PR12123 { + struct A { virtual ~A(); } g; + struct B { + void f(const std::type_info& x = typeid([]()->A& { return g; }())); + void h(); + }; + void B::h() { f(); } +} +// CHECK: define linkonce_odr %"struct.PR12123::A"* @_ZZN7PR121231B1fERKSt9type_infoEd_NKUlvE_clEv + namespace PR12808 { template <typename> struct B { int a; |