diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 5 | ||||
-rwxr-xr-x | clang/lib/Sema/SemaTemplate.cpp | 42 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 28 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 1 |
9 files changed, 85 insertions, 17 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 1f2ce30398c..ab4e961dcd4 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -6724,8 +6724,9 @@ ExpectedStmt ASTNodeImporter::VisitStmtExpr(StmtExpr *E) { SourceLocation ToLParenLoc, ToRParenLoc; std::tie(ToSubStmt, ToType, ToLParenLoc, ToRParenLoc) = *Imp; - return new (Importer.getToContext()) StmtExpr( - ToSubStmt, ToType, ToLParenLoc, ToRParenLoc); + return new (Importer.getToContext()) + StmtExpr(ToSubStmt, ToType, ToLParenLoc, ToRParenLoc, + E->getTemplateDepth()); } ExpectedStmt ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) { diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 1eb3ad6afd1..ad9627a2425 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -2655,7 +2655,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // If the substmt parsed correctly, build the AST node. if (!Stmt.isInvalid()) { - Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.get(), Tok.getLocation()); + Result = Actions.ActOnStmtExpr(getCurScope(), OpenLoc, Stmt.get(), + Tok.getLocation()); } else { Actions.ActOnStmtExprError(); } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 29562615e58..04a7038d675 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13908,9 +13908,13 @@ void Sema::ActOnStmtExprError() { PopExpressionEvaluationContext(); } -ExprResult -Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, - SourceLocation RPLoc) { // "({..})" +ExprResult Sema::ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt, + SourceLocation RPLoc) { + return BuildStmtExpr(LPLoc, SubStmt, RPLoc, getTemplateDepth(S)); +} + +ExprResult Sema::BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, + SourceLocation RPLoc, unsigned TemplateDepth) { assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!"); CompoundStmt *Compound = cast<CompoundStmt>(SubStmt); @@ -13941,7 +13945,8 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, // FIXME: Check that expression type is complete/non-abstract; statement // expressions are not lvalues. - Expr *ResStmtExpr = new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc); + Expr *ResStmtExpr = + new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc, TemplateDepth); if (StmtExprMayBindToTemp) return MaybeBindToTemporary(ResStmtExpr); return ResStmtExpr; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 98af7fb73ec..e97171b6334 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -6800,8 +6800,9 @@ Stmt *Sema::MaybeCreateStmtWithCleanups(Stmt *SubStmt) { // a new AsmStmtWithTemporaries. CompoundStmt *CompStmt = CompoundStmt::Create( Context, SubStmt, SourceLocation(), SourceLocation()); - Expr *E = new (Context) StmtExpr(CompStmt, Context.VoidTy, SourceLocation(), - SourceLocation()); + Expr *E = new (Context) + StmtExpr(CompStmt, Context.VoidTy, SourceLocation(), SourceLocation(), + /*FIXME TemplateDepth=*/0); return MaybeCreateExprWithCleanups(E); } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index b2f0b96b3e6..4f577a3cf74 100755 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -46,6 +46,48 @@ clang::getTemplateParamsRange(TemplateParameterList const * const *Ps, return SourceRange(Ps[0]->getTemplateLoc(), Ps[N-1]->getRAngleLoc()); } +unsigned Sema::getTemplateDepth(Scope *S) const { + unsigned Depth = 0; + + // Each template parameter scope represents one level of template parameter + // depth. + for (Scope *TempParamScope = S->getTemplateParamParent(); + TempParamScope && !Depth; + TempParamScope = TempParamScope->getParent()->getTemplateParamParent()) { + ++Depth; + } + + // Note that there are template parameters with the given depth. + auto ParamsAtDepth = [&](unsigned D) { Depth = std::max(Depth, D + 1); }; + + // Look for parameters of an enclosing generic lambda. We don't create a + // template parameter scope for these. + for (FunctionScopeInfo *FSI : getFunctionScopes()) { + if (auto *LSI = dyn_cast<LambdaScopeInfo>(FSI)) { + if (!LSI->TemplateParams.empty()) { + ParamsAtDepth(LSI->AutoTemplateParameterDepth); + break; + } + if (LSI->GLTemplateParameterList) { + ParamsAtDepth(LSI->GLTemplateParameterList->getDepth()); + break; + } + } + } + + // Look for parameters of an enclosing terse function template. We don't + // create a template parameter scope for these either. + for (const InventedTemplateParameterInfo &Info : + getInventedParameterInfos()) { + if (!Info.TemplateParams.empty()) { + ParamsAtDepth(Info.AutoTemplateParameterDepth); + break; + } + } + + return Depth; +} + /// \brief Determine whether the declaration found is acceptable as the name /// of a template and, if so, return that template declaration. Otherwise, /// returns null. diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index ce9a0263bd5..b5d2ab1f31f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -922,6 +922,10 @@ namespace { this->Entity = Entity; } + unsigned TransformTemplateDepth(unsigned Depth) { + return TemplateArgs.getNewDepth(Depth); + } + bool TryExpandParameterPacks(SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef<UnexpandedParameterPack> Unexpanded, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index d6105353bbd..805fe668420 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -212,6 +212,14 @@ public: return T.isNull(); } + /// Transform a template parameter depth level. + /// + /// During a transformation that transforms template parameters, this maps + /// an old template parameter depth to a new depth. + unsigned TransformTemplateDepth(unsigned Depth) { + return Depth; + } + /// Determine whether the given call argument should be dropped, e.g., /// because it is a default argument. /// @@ -2526,10 +2534,10 @@ public: /// /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildStmtExpr(SourceLocation LParenLoc, - Stmt *SubStmt, - SourceLocation RParenLoc) { - return getSema().ActOnStmtExpr(LParenLoc, SubStmt, RParenLoc); + ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt, + SourceLocation RParenLoc, unsigned TemplateDepth) { + return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc, + TemplateDepth); } /// Build a new __builtin_choose_expr expression. @@ -10346,16 +10354,18 @@ TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) { return ExprError(); } - if (!getDerived().AlwaysRebuild() && + unsigned OldDepth = E->getTemplateDepth(); + unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth); + + if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth && SubStmt.get() == E->getSubStmt()) { // Calling this an 'error' is unintuitive, but it does the right thing. SemaRef.ActOnStmtExprError(); return SemaRef.MaybeBindToTemporary(E); } - return getDerived().RebuildStmtExpr(E->getLParenLoc(), - SubStmt.get(), - E->getRParenLoc()); + return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(), + E->getRParenLoc(), NewDepth); } template<typename Derived> @@ -11801,6 +11811,8 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { NewTrailingRequiresClause = getDerived().TransformExpr(TRC); // Create the local class that will describe the lambda. + // FIXME: KnownDependent below is wrong when substituting inside a templated + // context that isn't a DeclContext (such as a variable template). CXXRecordDecl *OldClass = E->getLambdaClass(); CXXRecordDecl *Class = getSema().createLambdaClosureType(E->getIntroducerRange(), diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index db879f3004f..c38b3ad1846 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -1191,6 +1191,7 @@ void ASTStmtReader::VisitStmtExpr(StmtExpr *E) { E->setLParenLoc(readSourceLocation()); E->setRParenLoc(readSourceLocation()); E->setSubStmt(cast_or_null<CompoundStmt>(Record.readSubStmt())); + E->StmtExprBits.TemplateDepth = Record.readInt(); } void ASTStmtReader::VisitChooseExpr(ChooseExpr *E) { diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index f81e940a6db..8519a4df019 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1069,6 +1069,7 @@ void ASTStmtWriter::VisitStmtExpr(StmtExpr *E) { Record.AddStmt(E->getSubStmt()); Record.AddSourceLocation(E->getLParenLoc()); Record.AddSourceLocation(E->getRParenLoc()); + Record.push_back(E->getTemplateDepth()); Code = serialization::EXPR_STMT; } |