Add semantic analysis for "blocks".
Highlights...
- 4 new AST nodes, BlockExpr, BlockStmtExpr, BlockExprExpr, BlockDeclRefExpr.
- Sema::ActOnBlockStart(), ActOnBlockError(), ActOnBlockStmtExpr(), ActOnBlockExprExpr(), ActOnBlockReturnStmt().
Next steps...
- hack Sema::ActOnIdentifierExpr() to deal with block decl refs.
- add attribute handler for byref decls.
- add test cases.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55710 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 1ce4d80..faa16ca 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -64,6 +64,7 @@
class ObjCIvarDecl;
class ObjCMethodDecl;
class ObjCPropertyDecl;
+ struct BlockSemaInfo;
/// Sema - This implements semantic analysis and AST building for C.
class Sema : public Action {
@@ -75,6 +76,10 @@
/// CurContext - This is the current declaration context of parsing.
DeclContext *CurContext;
+ /// CurBlock - If inside of a block definition, this contains a pointer to
+ /// the active block object that represents it.
+ BlockSemaInfo *CurBlock;
+
/// LabelMap - This is a mapping from label identifiers to the LabelStmt for
/// it (which acts like the label decl in some ways). Forward referenced
/// labels have a LabelStmt created for them with a null location & SubStmt.
@@ -408,6 +413,7 @@
virtual StmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
ExprTy *RetValExp);
+ StmtResult ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp);
virtual StmtResult ActOnAsmStmt(SourceLocation AsmLoc,
bool IsSimple,
@@ -536,6 +542,27 @@
virtual ExprResult ActOnVAArg(SourceLocation BuiltinLoc,
ExprTy *expr, TypeTy *type,
SourceLocation RPLoc);
+
+ //===------------------------- "Block" Extension ------------------------===//
+
+ /// ActOnBlockStart - This callback is invoked when a block literal is
+ /// started.
+ virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope,
+ Declarator &ParamInfo);
+
+ /// ActOnBlockError - If there is an error parsing a block, this callback
+ /// is invoked to pop the information about the block from the action impl.
+ virtual void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope);
+
+ /// ActOnBlockStmtExpr - This is called when the body of a block statement
+ /// literal was successfully completed. ^(int x){...}
+ virtual ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtTy *Body,
+ Scope *CurScope);
+
+ /// ActOnBlockExprExpr - This is called when the body of a block
+ /// expression literal was successfully completed. ^(int x)[foo bar: x]
+ virtual ExprResult ActOnBlockExprExpr(SourceLocation CaretLoc, ExprTy *Body,
+ Scope *CurScope);
// Act on C++ namespaces
virtual DeclTy *ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
@@ -960,6 +987,27 @@
bool HadError() { return hadError; }
};
+/// BlockSemaInfo - When a block is being parsed, this contains information
+/// about the block. It is pointed to from Sema::CurBlock.
+struct BlockSemaInfo {
+ llvm::SmallVector<ParmVarDecl*, 8> Params;
+ llvm::SmallPtrSet<Decl*, 4> ByRefVars;
+ bool hasPrototype;
+ bool isVariadic;
+
+ /// TheScope - This is the scope for the block itself, which contains
+ /// arguments etc.
+ Scope *TheScope;
+
+ /// ReturnType - This will get set to block result type, by looking at
+ /// return types, if any, in the block body.
+ Type *ReturnType;
+
+ /// PrevBlockInfo - If this is nested inside another block, this points
+ /// to the outer block.
+ BlockSemaInfo *PrevBlockInfo;
+};
+
} // end namespace clang