aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-01-05 03:35:19 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-01-05 03:35:19 +0000
commitec9ea7200718478e8a976529defbe21942a11c9c (patch)
tree52de9c7edea7849591dbf5b5438dbc0a46748293 /lib
parentedb9459c43dec5f376020f2b53833dee6549e11d (diff)
More lambda work. Tweak the Sema interface slightly. Start adding the pieces to build the lambda class and its call operator. Create an actual scope for the lambda body.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147595 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Parse/ParseExprCXX.cpp7
-rw-r--r--lib/Sema/Sema.cpp9
-rw-r--r--lib/Sema/SemaDecl.cpp2
-rw-r--r--lib/Sema/SemaDeclCXX.cpp2
-rw-r--r--lib/Sema/SemaExpr.cpp4
-rw-r--r--lib/Sema/SemaExprCXX.cpp72
6 files changed, 73 insertions, 23 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 96f8709ba5..e54858f747 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -711,8 +711,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), LambdaBeginLoc,
"lambda expression parsing");
- Actions.ActOnLambdaStart(LambdaBeginLoc, getCurScope());
-
// Parse lambda-declarator[opt].
DeclSpec DS(AttrFactory);
Declarator D(DS, Declarator::LambdaExprContext);
@@ -792,11 +790,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
DeclLoc, DeclEndLoc, D,
TrailingReturnType),
Attr, DeclEndLoc);
-
- // Inform sema that we are starting a block.
- Actions.ActOnLambdaArguments(D, getCurScope());
}
+ Actions.ActOnStartOfLambdaDefinition(Intro, D, getCurScope());
+
// Parse compound-statement.
if (!Tok.is(tok::l_brace)) {
Diag(Tok, diag::err_expected_lambda_body);
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index c8199042b7..6a77d8c673 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -55,6 +55,7 @@ void FunctionScopeInfo::Clear() {
}
BlockScopeInfo::~BlockScopeInfo() { }
+LambdaScopeInfo::~LambdaScopeInfo() { }
PrintingPolicy Sema::getPrintingPolicy() const {
PrintingPolicy Policy = Context.getPrintingPolicy();
@@ -828,8 +829,12 @@ void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
BlockScope, Block));
}
-void Sema::PopFunctionOrBlockScope(const AnalysisBasedWarnings::Policy *WP,
- const Decl *D, const BlockExpr *blkExpr) {
+void Sema::PushLambdaScope(CXXRecordDecl *Lambda) {
+ FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda));
+}
+
+void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP,
+ const Decl *D, const BlockExpr *blkExpr) {
FunctionScopeInfo *Scope = FunctionScopes.pop_back_val();
assert(!FunctionScopes.empty() && "mismatched push/pop!");
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index f82026f89f..8353c087d5 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -7207,7 +7207,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
if (!IsInstantiation)
PopDeclContext();
- PopFunctionOrBlockScope(ActivePolicy, dcl);
+ PopFunctionScopeInfo(ActivePolicy, dcl);
// If any errors have occurred, clear out any temporaries that may have
// been leftover. This ensures that these temporaries won't be picked up for
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index ad327ac755..46a47a2215 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -6784,7 +6784,7 @@ namespace {
~ImplicitlyDefinedFunctionScope() {
S.PopExpressionEvaluationContext();
- S.PopFunctionOrBlockScope();
+ S.PopFunctionScopeInfo();
}
};
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 126468ee35..8554e78636 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -8839,7 +8839,7 @@ void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {
// Pop off CurBlock, handle nested blocks.
PopDeclContext();
- PopFunctionOrBlockScope();
+ PopFunctionScopeInfo();
}
/// ActOnBlockStmtExpr - This is called when the body of a block statement
@@ -8931,7 +8931,7 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy);
const AnalysisBasedWarnings::Policy &WP = AnalysisWarnings.getDefaultPolicy();
- PopFunctionOrBlockScope(&WP, Result->getBlockDecl(), Result);
+ PopFunctionScopeInfo(&WP, Result->getBlockDecl(), Result);
// If the block isn't obviously global, i.e. it captures anything at
// all, mark this full-expression as needing a cleanup.
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index e53e5cda62..fd47dc75b2 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -4778,20 +4778,68 @@ Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc,
// Lambdas.
//===----------------------------------------------------------------------===//
-void Sema::ActOnLambdaStart(SourceLocation StartLoc, Scope *CurScope) {
- // FIXME: Add lambda-scope
- // FIXME: PushDeclContext
+void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
+ Declarator &ParamInfo,
+ Scope *CurScope) {
+ DeclContext *DC = CurContext;
+ while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isNamespace()))
+ DC = DC->getParent();
+
+ // Start constructing the lambda class.
+ CXXRecordDecl *Class = CXXRecordDecl::Create(Context, TTK_Class, DC,
+ Intro.Range.getBegin(),
+ /*IdLoc=*/SourceLocation(),
+ /*Id=*/0);
+ Class->startDefinition();
+ CurContext->addDecl(Class);
+
+ // Build the call operator; we don't really have all the relevant information
+ // at this point, but we need something to attach child declarations to.
+ TypeSourceInfo *MethodTyInfo;
+ MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
+
+ DeclarationName MethodName
+ = Context.DeclarationNames.getCXXOperatorName(OO_Call);
+ CXXMethodDecl *Method
+ = CXXMethodDecl::Create(Context,
+ Class,
+ ParamInfo.getSourceRange().getEnd(),
+ DeclarationNameInfo(MethodName,
+ /*NameLoc=*/SourceLocation()),
+ MethodTyInfo->getType(),
+ MethodTyInfo,
+ /*isStatic=*/false,
+ SC_None,
+ /*isInline=*/true,
+ /*isConstExpr=*/false,
+ ParamInfo.getSourceRange().getEnd());
+ Method->setAccess(AS_public);
+ Class->addDecl(Method);
+ Method->setLexicalDeclContext(DC); // FIXME: Is this really correct?
+
+ // Set the parameters on the decl, if specified.
+ if (isa<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc())) {
+ FunctionProtoTypeLoc Proto =
+ cast<FunctionProtoTypeLoc>(MethodTyInfo->getTypeLoc());
+ Method->setParams(Proto.getParams());
+ CheckParmsForFunctionDef(Method->param_begin(),
+ Method->param_end(),
+ /*CheckParameterNames=*/false);
+ }
+
+ ProcessDeclAttributes(CurScope, Method, ParamInfo);
+
+ // FIXME: There's a bunch of missing checking etc;
+ // see ActOnBlockArguments
+
+ // Introduce the lambda scope.
+ PushLambdaScope(Class);
// Enter a new evaluation context to insulate the block from any
// cleanups from the enclosing full-expression.
- PushExpressionEvaluationContext(PotentiallyEvaluated);
-}
-
-void Sema::ActOnLambdaArguments(Declarator &ParamInfo, Scope *CurScope) {
- TypeSourceInfo *MethodTyInfo;
- MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
+ PushExpressionEvaluationContext(PotentiallyEvaluated);
- // FIXME: Build CXXMethodDecl
+ PushDeclContext(CurScope, Method);
}
void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope) {
@@ -4800,8 +4848,8 @@ void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope) {
PopExpressionEvaluationContext();
// Leave the context of the lambda.
- // FIXME: PopDeclContext
- // FIXME: Pop lambda-scope
+ PopDeclContext();
+ PopFunctionScopeInfo();
}
ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc,