diff options
Diffstat (limited to 'clang/include')
-rw-r--r-- | clang/include/clang/AST/Expr.h | 22 | ||||
-rw-r--r-- | clang/include/clang/AST/Stmt.h | 15 | ||||
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 41 | ||||
-rw-r--r-- | clang/include/clang/Sema/Template.h | 10 |
4 files changed, 78 insertions, 10 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index bcb960540001..7ff53ef7c653 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -3955,14 +3955,18 @@ class StmtExpr : public Expr { Stmt *SubStmt; SourceLocation LParenLoc, RParenLoc; public: - StmtExpr(CompoundStmt *substmt, QualType T, - SourceLocation lp, SourceLocation rp, bool InDependentContext) : - // Note: we treat a statement-expression in a dependent context as always - // being value- and instantiation-dependent. This matches the behavior of - // lambda-expressions and GCC. - Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, - T->isDependentType(), InDependentContext, InDependentContext, false), - SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) {} + StmtExpr(CompoundStmt *SubStmt, QualType T, SourceLocation LParenLoc, + SourceLocation RParenLoc, unsigned TemplateDepth) + : // We treat a statement-expression in a dependent context as + // always being value- and instantiation-dependent. This matches the + // behavior of lambda-expressions and GCC. + Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, T->isDependentType(), + TemplateDepth != 0, TemplateDepth != 0, false), + SubStmt(SubStmt), LParenLoc(LParenLoc), RParenLoc(RParenLoc) { + // FIXME: A templated statement expression should have an associated + // DeclContext so that nested declarations always have a dependent context. + StmtExprBits.TemplateDepth = TemplateDepth; + } /// Build an empty statement expression. explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) { } @@ -3979,6 +3983,8 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } + unsigned getTemplateDepth() const { return StmtExprBits.TemplateDepth; } + static bool classof(const Stmt *T) { return T->getStmtClass() == StmtExprClass; } diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 253b76941991..3aa2745937b1 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -588,6 +588,18 @@ protected: unsigned Kind : 2; }; + class StmtExprBitfields { + friend class ASTStmtReader; + friend class StmtExpr; + + unsigned : NumExprBits; + + /// The number of levels of template parameters enclosing this statement + /// expression. Used to determine if a statement expression remains + /// dependent after instantiation. + unsigned TemplateDepth; + }; + //===--- C++ Expression bitfields classes ---===// class CXXOperatorCallExprBitfields { @@ -996,6 +1008,9 @@ protected: PseudoObjectExprBitfields PseudoObjectExprBits; SourceLocExprBitfields SourceLocExprBits; + // GNU Extensions. + StmtExprBitfields StmtExprBits; + // C++ Expressions CXXOperatorCallExprBitfields CXXOperatorCallExprBits; CXXRewrittenBinaryOperatorBitfields CXXRewrittenBinaryOperatorBits; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 2b5f7c1a7203..033f7af6f2f3 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -620,6 +620,15 @@ public: /// function, block, and method scopes that are currently active. SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes; + /// The index of the first FunctionScope that corresponds to the current + /// context. + unsigned FunctionScopesStart = 0; + + ArrayRef<sema::FunctionScopeInfo*> getFunctionScopes() const { + return llvm::makeArrayRef(FunctionScopes.begin() + FunctionScopesStart, + FunctionScopes.end()); + } + /// Stack containing information needed when in C++2a an 'auto' is encountered /// in a function declaration parameter type specifier in order to invent a /// corresponding template parameter in the enclosing abbreviated function @@ -627,6 +636,16 @@ public: /// the FunctionScopes stack. SmallVector<InventedTemplateParameterInfo, 4> InventedParameterInfos; + /// The index of the first InventedParameterInfo that refers to the current + /// context. + unsigned InventedParameterInfosStart = 0; + + ArrayRef<InventedTemplateParameterInfo> getInventedParameterInfos() const { + return llvm::makeArrayRef(InventedParameterInfos.begin() + + InventedParameterInfosStart, + InventedParameterInfos.end()); + } + typedef LazyVector<TypedefNameDecl *, ExternalSemaSource, &ExternalSemaSource::ReadExtVectorDecls, 2, 2> ExtVectorDeclsType; @@ -800,17 +819,24 @@ public: DeclContext *SavedContext; ProcessingContextState SavedContextState; QualType SavedCXXThisTypeOverride; + unsigned SavedFunctionScopesStart; + unsigned SavedInventedParameterInfosStart; public: ContextRAII(Sema &S, DeclContext *ContextToPush, bool NewThisContext = true) : S(S), SavedContext(S.CurContext), SavedContextState(S.DelayedDiagnostics.pushUndelayed()), - SavedCXXThisTypeOverride(S.CXXThisTypeOverride) + SavedCXXThisTypeOverride(S.CXXThisTypeOverride), + SavedFunctionScopesStart(S.FunctionScopesStart), + SavedInventedParameterInfosStart(S.InventedParameterInfosStart) { assert(ContextToPush && "pushing null context"); S.CurContext = ContextToPush; if (NewThisContext) S.CXXThisTypeOverride = QualType(); + // Any saved FunctionScopes do not refer to this context. + S.FunctionScopesStart = S.FunctionScopes.size(); + S.InventedParameterInfosStart = S.InventedParameterInfos.size(); } void pop() { @@ -818,6 +844,8 @@ public: S.CurContext = SavedContext; S.DelayedDiagnostics.popUndelayed(SavedContextState); S.CXXThisTypeOverride = SavedCXXThisTypeOverride; + S.FunctionScopesStart = SavedFunctionScopesStart; + S.InventedParameterInfosStart = SavedInventedParameterInfosStart; SavedContext = nullptr; } @@ -4924,7 +4952,9 @@ public: void ActOnStartStmtExpr(); ExprResult ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt, - SourceLocation RPLoc); // "({..})" + SourceLocation RPLoc); + ExprResult BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, + SourceLocation RPLoc, unsigned TemplateDepth); // Handle the final expression in a statement expression. ExprResult ActOnStmtExprResult(ExprResult E); void ActOnStmtExprError(); @@ -11924,6 +11954,13 @@ public: return DC; } + /// Determine the number of levels of enclosing template parameters. This is + /// only usable while parsing. Note that this does not include dependent + /// contexts in which no template parameters have yet been declared, such as + /// in a terse function template or generic lambda before the first 'auto' is + /// encountered. + unsigned getTemplateDepth(Scope *S) const; + /// To be used for checking whether the arguments being passed to /// function exceeds the number of parameters expected for it. static bool TooManyArguments(size_t NumParams, size_t NumArgs, diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h index 4c1cfecd4de6..47d6143bdc9a 100644 --- a/clang/include/clang/Sema/Template.h +++ b/clang/include/clang/Sema/Template.h @@ -95,6 +95,16 @@ class VarDecl; return TemplateArgumentLists.size(); } + /// Determine how many of the \p OldDepth outermost template parameter + /// lists would be removed by substituting these arguments. + unsigned getNewDepth(unsigned OldDepth) const { + if (OldDepth < NumRetainedOuterLevels) + return OldDepth; + if (OldDepth < getNumLevels()) + return NumRetainedOuterLevels; + return OldDepth - TemplateArgumentLists.size(); + } + /// Retrieve the template argument at a given depth and index. const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); |