diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/DeclBase.cpp | 8 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 26 | ||||
-rw-r--r-- | lib/Sema/SemaLambda.cpp | 15 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 3 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 1 |
6 files changed, 45 insertions, 12 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index a507215aa8..efbc5f9923 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -741,10 +741,14 @@ bool DeclContext::isDependentContext() const { if (isa<ClassTemplatePartialSpecializationDecl>(this)) return true; - if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this)) + if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(this)) { if (Record->getDescribedClassTemplate()) return true; - + + if (Record->isDependentLambda()) + return true; + } + if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(this)) { if (Function->getDescribedFunctionTemplate()) return true; diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index a4d8220625..9840cc7820 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -83,11 +83,11 @@ CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK, } CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, - SourceLocation Loc) { + SourceLocation Loc, bool Dependent) { CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TTK_Class, DC, Loc, Loc, 0, 0); R->IsBeingDefined = true; - R->DefinitionData = new (C) struct LambdaDefinitionData(R); + R->DefinitionData = new (C) struct LambdaDefinitionData(R, Dependent); C.getTypeDeclType(R, /*PrevDecl=*/0); return R; } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 1008a3ab43..be3fa6c0dc 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3146,7 +3146,8 @@ ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc, // We already type-checked the argument, so we know it works. // Just mark all of the declarations in this potentially-evaluated expression // as being "referenced". - MarkDeclarationsReferencedInExpr(Param->getDefaultArg()); + MarkDeclarationsReferencedInExpr(Param->getDefaultArg(), + /*SkipLocalVariables=*/true); return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param)); } @@ -10145,13 +10146,22 @@ namespace { /// potentially-evaluated subexpressions as "referenced". class EvaluatedExprMarker : public EvaluatedExprVisitor<EvaluatedExprMarker> { Sema &S; + bool SkipLocalVariables; public: typedef EvaluatedExprVisitor<EvaluatedExprMarker> Inherited; - explicit EvaluatedExprMarker(Sema &S) : Inherited(S.Context), S(S) { } + EvaluatedExprMarker(Sema &S, bool SkipLocalVariables) + : Inherited(S.Context), S(S), SkipLocalVariables(SkipLocalVariables) { } void VisitDeclRefExpr(DeclRefExpr *E) { + // If we were asked not to visit local variables, don't. + if (SkipLocalVariables) { + if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) + if (VD->hasLocalStorage()) + return; + } + S.MarkDeclRefReferenced(E); } @@ -10193,6 +10203,10 @@ namespace { } void VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { + // If we were asked not to visit local variables, don't. + if (SkipLocalVariables && E->getDecl()->hasLocalStorage()) + return; + S.MarkBlockDeclRefReferenced(E); } @@ -10211,8 +10225,12 @@ namespace { /// \brief Mark any declarations that appear within this expression or any /// potentially-evaluated subexpressions as "referenced". -void Sema::MarkDeclarationsReferencedInExpr(Expr *E) { - EvaluatedExprMarker(*this).Visit(E); +/// +/// \param SkipLocalVariables If true, don't mark local variables as +/// 'referenced'. +void Sema::MarkDeclarationsReferencedInExpr(Expr *E, + bool SkipLocalVariables) { + EvaluatedExprMarker(*this, SkipLocalVariables).Visit(E); } /// \brief Emit a diagnostic that describes an effect on the run-time behavior diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 694fee6776..42040084e1 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -21,14 +21,16 @@ using namespace clang; using namespace sema; -CXXRecordDecl *Sema::createLambdaClosureType(SourceRange IntroducerRange) { +CXXRecordDecl *Sema::createLambdaClosureType(SourceRange IntroducerRange, + bool KnownDependent) { DeclContext *DC = CurContext; while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext())) DC = DC->getParent(); // Start constructing the lambda class. CXXRecordDecl *Class = CXXRecordDecl::CreateLambda(Context, DC, - IntroducerRange.getBegin()); + IntroducerRange.getBegin(), + KnownDependent); DC->addDecl(Class); return Class; @@ -142,7 +144,14 @@ void Sema::addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope) { void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, Declarator &ParamInfo, Scope *CurScope) { - CXXRecordDecl *Class = createLambdaClosureType(Intro.Range); + // Determine if we're within a context where we know that the lambda will + // be dependent, because there are template parameters in scope. + bool KnownDependent = false; + if (Scope *TmplScope = CurScope->getTemplateParamParent()) + if (!TmplScope->decl_empty()) + KnownDependent = true; + + CXXRecordDecl *Class = createLambdaClosureType(Intro.Range, KnownDependent); // Determine the signature of the call operator. TypeSourceInfo *MethodTyInfo; diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index c2a93b99fa..fe09cdafa7 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1107,6 +1107,7 @@ void ASTDeclReader::ReadCXXDefinitionData( typedef LambdaExpr::Capture Capture; CXXRecordDecl::LambdaDefinitionData &Lambda = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data); + Lambda.Dependent = Record[Idx++]; Lambda.NumCaptures = Record[Idx++]; Lambda.NumExplicitCaptures = Record[Idx++]; Lambda.ManglingNumber = Record[Idx++]; @@ -1134,7 +1135,7 @@ void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { // allocate the appropriate DefinitionData structure. bool IsLambda = Record[Idx++]; if (IsLambda) - D->DefinitionData = new (C) CXXRecordDecl::LambdaDefinitionData(D); + D->DefinitionData = new (C) CXXRecordDecl::LambdaDefinitionData(D, false); else D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D); diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 5c3a1e93f6..8dbd6e4471 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -4330,6 +4330,7 @@ void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Rec // Add lambda-specific data. if (Data.IsLambda) { CXXRecordDecl::LambdaDefinitionData &Lambda = D->getLambdaData(); + Record.push_back(Lambda.Dependent); Record.push_back(Lambda.NumCaptures); Record.push_back(Lambda.NumExplicitCaptures); Record.push_back(Lambda.ManglingNumber); |