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