diff options
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index fa51aa4c09f..5997abe0296 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -15,6 +15,7 @@ #include "TypeLocBuilder.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTLambda.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h" #include "clang/AST/CommentDiagnostic.h" @@ -8975,6 +8976,7 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { const DeclSpec &DS = D.getDeclSpec(); // Verify C99 6.7.5.3p2: The only SCS allowed is 'register'. + // C++03 [dcl.stc]p2 also permits 'auto'. VarDecl::StorageClass StorageClass = SC_None; if (DS.getStorageClassSpec() == DeclSpec::SCS_register) { @@ -9334,9 +9336,37 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { FD = FunTmpl->getTemplatedDecl(); else FD = cast<FunctionDecl>(D); - - // Enter a new function scope - PushFunctionScope(); + // If we are instantiating a generic lambda call operator, push + // a LambdaScopeInfo onto the function stack. But use the information + // that's already been calculated (ActOnLambdaExpr) when analyzing the + // template version, to prime the current LambdaScopeInfo. + if (isGenericLambdaCallOperatorSpecialization(D)) { + CXXMethodDecl *CallOperator = cast<CXXMethodDecl>(D); + CXXRecordDecl *LambdaClass = CallOperator->getParent(); + LambdaExpr *LE = LambdaClass->getLambdaExpr(); + assert(LE && + "No LambdaExpr of closure class when instantiating a generic lambda!"); + assert(ActiveTemplateInstantiations.size() && + "There should be an active template instantiation on the stack " + "when instantiating a generic lambda!"); + PushLambdaScope(); + LambdaScopeInfo *LSI = getCurLambda(); + LSI->CallOperator = CallOperator; + LSI->Lambda = LambdaClass; + LSI->ReturnType = CallOperator->getResultType(); + + if (LE->getCaptureDefault() == LCD_None) + LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_None; + else if (LE->getCaptureDefault() == LCD_ByCopy) + LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByval; + else if (LE->getCaptureDefault() == LCD_ByRef) + LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByref; + + LSI->IntroducerRange = LE->getIntroducerRange(); + } + else + // Enter a new function scope + PushFunctionScope(); // See if this is a redefinition. if (!FD->isLateTemplateParsed()) |