Final phase of converting BlockDecls over to DeclContext. This is unfortunately a largish/complex diff, however it was necessry to pass all the current block tests.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57337 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index bb8c14c..575daa5 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -990,24 +990,30 @@
 class BlockDecl : public Decl, public DeclContext {
   llvm::SmallVector<ParmVarDecl*, 8> Args;
   Stmt *Body;
+  
+  // Since BlockDecl's aren't named/scoped, we need to store the context.
+  DeclContext *ParentContext;
 protected:
-  BlockDecl(DeclContext *DC, SourceLocation CaretLoc,
-            ParmVarDecl **args, unsigned numargs)
-    : Decl(Block, CaretLoc), DeclContext(Block), 
-      Args(args, args+numargs), Body(0) {}
+  BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
+    : Decl(Block, CaretLoc), DeclContext(Block), Body(0), ParentContext(DC) {}
 
   virtual ~BlockDecl();
   virtual void Destroy(ASTContext& C);
 
 public:
-  static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
-                           ParmVarDecl **args, unsigned numargs);
+  static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
 
   SourceLocation getCaretLocation() const { return getLocation(); }
 
   Stmt *getBody() const { return Body; }
   void setBody(Stmt *B) { Body = B; }
 
+  void setArgs(ParmVarDecl **args, unsigned numargs) {
+    Args.clear(); 
+    Args.insert(Args.begin(), args, args+numargs);
+  }
+  DeclContext *getParentContext() { return ParentContext; }
+  
   /// arg_iterator - Iterate over the ParmVarDecl's for this block.
   typedef llvm::SmallVector<ParmVarDecl*, 8>::const_iterator param_iterator;
   bool param_empty() const { return Args.empty(); }
@@ -1016,7 +1022,7 @@
     
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return D->getKind() == Block; }
-  static bool classof(const TranslationUnitDecl *D) { return true; }  
+  static bool classof(const BlockDecl *D) { return true; }  
 
 protected:
   /// EmitImpl - Serialize this BlockDecl. Called by Decl::Emit.
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 1ebd25c..b165991 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -267,6 +267,8 @@
   static To *CastTo(const From *D) {
     Decl::Kind DK = KindTrait<From>::getKind(D);
     switch(DK) {
+      case Decl::Block:
+        return static_cast<BlockDecl*>(const_cast<From*>(D));
       case Decl::TranslationUnit:
         return static_cast<TranslationUnitDecl*>(const_cast<From*>(D));
       case Decl::Namespace:
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index ee7b7a9..a327292 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -538,8 +538,11 @@
 
   /// ActOnBlockStart - This callback is invoked when a block literal is
   /// started.  The result pointer is passed into the block finalizers.
-  virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope,
-                               Declarator &ParamInfo) {}
+  virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) {}
+
+  /// ActOnBlockArguments - This callback allows processing of block arguments.
+  /// If there are no arguments, this is still invoked.
+  virtual void ActOnBlockArguments(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.