[cfe-commits] r57298 - in /cfe/trunk: Driver/RewriteBlocks.cpp include/clang/AST/Decl.h include/clang/AST/DeclBase.h include/clang/AST/Expr.h lib/AST/Decl.cpp lib/AST/DeclBase.cpp lib/AST/DeclSerialization.cpp lib/AST/Expr.cpp lib/AST/StmtPrinter.cpp lib/AST/StmtSerialization.cpp lib/Sema/SemaExpr.cpp

Steve Naroff snaroff at apple.com
Wed Oct 8 10:01:14 PDT 2008


Author: snaroff
Date: Wed Oct  8 12:01:13 2008
New Revision: 57298

URL: http://llvm.org/viewvc/llvm-project?rev=57298&view=rev
Log:
- Add BlockDecl AST node.
- Modify BlockExpr to reference the BlockDecl.

This is "cleanup" necessary to improve our lookup semantics for blocks (to fix <rdar://problem/6272905> clang block rewriter: parameter to function not imported into block?).

Still some follow-up work to finish this (forthcoming).


Modified:
    cfe/trunk/Driver/RewriteBlocks.cpp
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/AST/DeclSerialization.cpp
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/AST/StmtSerialization.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/Driver/RewriteBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteBlocks.cpp?rev=57298&r1=57297&r2=57298&view=diff

==============================================================================
--- cfe/trunk/Driver/RewriteBlocks.cpp (original)
+++ cfe/trunk/Driver/RewriteBlocks.cpp Wed Oct  8 12:01:13 2008
@@ -364,9 +364,11 @@
   std::string S = "static " + RT.getAsString() + " __" +
                   funcName + "_" + "block_func_" + utostr(i);
 
+  BlockDecl *BD = CE->getBlockDecl();
+  
   if (isa<FunctionTypeNoProto>(AFT)) {
     S += "()";
-  } else if (CE->arg_empty()) {
+  } else if (BD->param_empty()) {
     S += "(" + StructRef + " *__cself)";
   } else {
     const FunctionTypeProto *FT = cast<FunctionTypeProto>(AFT);
@@ -375,15 +377,15 @@
     // first add the implicit argument.
     S += StructRef + " *__cself, ";
     std::string ParamStr;
-    for (BlockExpr::arg_iterator AI = CE->arg_begin(),
-         E = CE->arg_end(); AI != E; ++AI) {
-      if (AI != CE->arg_begin()) S += ", ";
+    for (BlockDecl::param_iterator AI = BD->param_begin(),
+         E = BD->param_end(); AI != E; ++AI) {
+      if (AI != BD->param_begin()) S += ", ";
       ParamStr = (*AI)->getName();
       (*AI)->getType().getAsStringInternal(ParamStr);
       S += ParamStr;
     }
     if (FT->isVariadic()) {
-      if (!CE->arg_empty()) S += ", ";
+      if (!BD->param_empty()) S += ", ";
       S += "...";
     }
     S += ')';

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=57298&r1=57297&r2=57298&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Wed Oct  8 12:01:13 2008
@@ -16,10 +16,12 @@
 
 #include "clang/AST/DeclBase.h"
 #include "clang/Parse/AccessSpecifier.h"
+#include "llvm/ADT/SmallVector.h"
 
 namespace clang {
 class Expr;
 class Stmt;
+class CompoundStmt;
 class StringLiteral;
 class IdentifierInfo;
 
@@ -981,6 +983,51 @@
   void ReadInRec(llvm::Deserializer& D, ASTContext& C);
 };
 
-}  // end namespace clang
+/// BlockDecl - This represents a block literal declaration, which is like an
+/// unnamed FunctionDecl.  For example:
+/// ^{ statement-body }   or   ^(int arg1, float arg2){ statement-body }
+///
+class BlockDecl : public Decl, public DeclContext {
+  llvm::SmallVector<ParmVarDecl*, 8> Args;
+  Stmt *Body;
+protected:
+  BlockDecl(DeclContext *DC, SourceLocation CaretLoc,
+            ParmVarDecl **args, unsigned numargs, Stmt *body)
+    : Decl(Block, CaretLoc), DeclContext(Block), 
+      Args(args, args+numargs), Body(body) {}
+
+  virtual ~BlockDecl();
+  virtual void Destroy(ASTContext& C);
+
+public:
+  static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+                           ParmVarDecl **args, unsigned numargs, 
+                           CompoundStmt *body);
+
+  SourceLocation getCaretLocation() const { return getLocation(); }
+
+  Stmt *getBody() const { return Body; }
+
+  /// 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(); }
+  param_iterator param_begin() const { return Args.begin(); }
+  param_iterator param_end() const { return Args.end(); }
+    
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return D->getKind() == Block; }
+  static bool classof(const TranslationUnitDecl *D) { return true; }  
 
+protected:
+  /// EmitImpl - Serialize this BlockDecl. Called by Decl::Emit.
+  virtual void EmitImpl(llvm::Serializer& S) const;
+
+  /// CreateImpl - Deserialize a BlockDecl.  Called by Decl::Create.
+  static BlockDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C);
+
+  friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
+};
+
+}  // end namespace clang
+	
 #endif

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=57298&r1=57297&r2=57298&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Wed Oct  8 12:01:13 2008
@@ -27,6 +27,7 @@
 class EnumDecl;
 class ObjCMethodDecl;
 class ObjCInterfaceDecl;
+class BlockDecl;
 
 /// Decl - This represents one declaration (or definition), e.g. a variable, 
 /// typedef, function, struct, etc.  
@@ -81,6 +82,7 @@
            ObjCPropertyImpl,
          LinkageSpec,
          FileScopeAsm,
+	     Block, // [DeclContext]
   
     // For each non-leaf class, we now define a mapping to the first/last member
     // of the class, to allow efficient classof.
@@ -243,6 +245,7 @@
 ///   EnumDecl
 ///   ObjCMethodDecl
 ///   ObjCInterfaceDecl
+///   BlockDecl
 ///
 class DeclContext {
   /// DeclKind - This indicates which class this is.
@@ -295,6 +298,7 @@
 
   bool isFunctionOrMethod() const {
     switch (DeclKind) {
+      case Decl::Block:
       case Decl::Function:
       case Decl::CXXMethod:
       case Decl::ObjCMethod:
@@ -320,6 +324,7 @@
       case Decl::Enum:
       case Decl::ObjCMethod:
       case Decl::ObjCInterface:
+      case Decl::Block:
         return true;
       default:
         if (D->getKind() >= Decl::FunctionFirst &&
@@ -339,6 +344,7 @@
   static bool classof(const EnumDecl *D) { return true; }
   static bool classof(const ObjCMethodDecl *D) { return true; }
   static bool classof(const ObjCInterfaceDecl *D) { return true; }
+  static bool classof(const BlockDecl *D) { return true; }
 
 private:
   void EmitOutRec(llvm::Serializer& S) const;

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=57298&r1=57297&r2=57298&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Wed Oct  8 12:01:13 2008
@@ -28,6 +28,7 @@
   class IdentifierInfo;
   class ParmVarDecl;
   class ValueDecl;
+  class BlockDecl;
     
 /// Expr - This represents one expression.  Note that Expr's are subclasses of
 /// Stmt.  This allows an expression to be transparently used any place a Stmt
@@ -1498,36 +1499,29 @@
 };
 
 
-/// BlockExpr - Represent a block literal with a syntax:
+/// BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
 /// ^{ statement-body }   or   ^(int arg1, float arg2){ statement-body }
 class BlockExpr : public Expr {
-  SourceLocation CaretLocation;
-  llvm::SmallVector<ParmVarDecl*, 8> Args;
-  Stmt *Body;
-public:
-  BlockExpr(SourceLocation caretloc, QualType ty, ParmVarDecl **args, 
-            unsigned numargs, CompoundStmt *body) : Expr(BlockExprClass, ty), 
-            CaretLocation(caretloc), Args(args, args+numargs), Body(body) {}
-
-  SourceLocation getCaretLocation() const { return CaretLocation; }
-
-  /// getFunctionType - Return the underlying function type for this block.
-  const FunctionType *getFunctionType() const;
+protected:
+  BlockDecl *TheBlock;
+public:
+  BlockExpr(BlockDecl *BD, QualType ty) : Expr(BlockExprClass, ty), 
+            TheBlock(BD) {}
 
-  const CompoundStmt *getBody() const { return cast<CompoundStmt>(Body); }
-  CompoundStmt *getBody() { return cast<CompoundStmt>(Body); }
+  BlockDecl *getBlockDecl() { return TheBlock; }
+  
+  // Convenience functions for probing the underlying BlockDecl.
+  SourceLocation getCaretLocation() const;
+  const Stmt *getBody() const;
+  Stmt *getBody();
 
   virtual SourceRange getSourceRange() const {
-    return SourceRange(getCaretLocation(), Body->getLocEnd());
+    return SourceRange(getCaretLocation(), getBody()->getLocEnd());
   }
 
-  /// arg_iterator - Iterate over the ParmVarDecl's for the arguments to this
-  /// block.
-  typedef llvm::SmallVector<ParmVarDecl*, 8>::const_iterator arg_iterator;
-  bool arg_empty() const { return Args.empty(); }
-  arg_iterator arg_begin() const { return Args.begin(); }
-  arg_iterator arg_end() const { return Args.end(); }
-  
+  /// getFunctionType - Return the underlying function type for this block.
+  const FunctionType *getFunctionType() const;
+
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == BlockExprClass;
   }
@@ -1536,7 +1530,7 @@
   // Iterators
   virtual child_iterator child_begin();
   virtual child_iterator child_end();
-    
+
   virtual void EmitImpl(llvm::Serializer& S) const;
   static BlockExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
 };

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=57298&r1=57297&r2=57298&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Wed Oct  8 12:01:13 2008
@@ -76,6 +76,13 @@
                                 TypeSpecStartLoc);
 }
 
+BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 
+                             ParmVarDecl **args, unsigned numargs, 
+                             CompoundStmt *body) {
+  void *Mem = C.getAllocator().Allocate<BlockDecl>();
+  return new (Mem) BlockDecl(DC, L, args, numargs, body);
+}
+
 FieldDecl *FieldDecl::Create(ASTContext &C, SourceLocation L,
                              IdentifierInfo *Id, QualType T, Expr *BW) {
   void *Mem = C.getAllocator().Allocate<FieldDecl>();
@@ -285,3 +292,20 @@
       return Members[i];
   return 0;
 }
+
+//===----------------------------------------------------------------------===//
+// BlockDecl Implementation
+//===----------------------------------------------------------------------===//
+
+BlockDecl::~BlockDecl() {
+}
+
+void BlockDecl::Destroy(ASTContext& C) {
+  if (Body)
+    Body->Destroy(C);
+
+  for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
+    (*I)->Destroy(C);
+    
+  Decl::Destroy(C);
+}

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=57298&r1=57297&r2=57298&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Wed Oct  8 12:01:13 2008
@@ -49,6 +49,7 @@
 static unsigned nObjCPropertyImplDecl = 0;
 static unsigned nLinkageSpecDecl = 0;
 static unsigned nFileScopeAsmDecl = 0;
+static unsigned nBlockDecls = 0;
 
 static bool StatSwitch = false;
 
@@ -77,6 +78,7 @@
   case Union:               return "Union";
   case Class:               return "Class";
   case Enum:                return "Enum";
+  case Block:               return "Block";
   }
 }
 
@@ -221,6 +223,7 @@
   case ObjCPropertyImpl:    nObjCPropertyImplDecl++; break;
   case LinkageSpec:         nLinkageSpecDecl++; break;
   case FileScopeAsm:        nFileScopeAsmDecl++; break;
+  case Block:               nBlockDecls++; break;
   case ImplicitParam:
   case TranslationUnit:     break;
 

Modified: cfe/trunk/lib/AST/DeclSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclSerialization.cpp?rev=57298&r1=57297&r2=57298&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclSerialization.cpp (original)
+++ cfe/trunk/lib/AST/DeclSerialization.cpp Wed Oct  8 12:01:13 2008
@@ -441,6 +441,22 @@
   return decl;
 }
 
+void BlockDecl::EmitImpl(Serializer& S) const {
+  // FIXME: what about arguments?
+  S.Emit(getCaretLocation());
+  S.EmitOwnedPtr(Body);
+}
+
+BlockDecl* BlockDecl::CreateImpl(Deserializer& D, ASTContext& C) {
+  QualType Q = QualType::ReadVal(D);
+  SourceLocation L = SourceLocation::ReadVal(D);
+  /*CompoundStmt* BodyStmt = cast<CompoundStmt>(*/D.ReadOwnedPtr<Stmt>(C)/*)*/;
+  assert(0 && "Cannot deserialize BlockBlockExpr yet");
+  // FIXME: need to handle parameters.
+  //return new BlockBlockExpr(L, Q, BodyStmt);
+  return 0;
+}
+
 //===----------------------------------------------------------------------===//
 //      RecordDecl Serialization.
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=57298&r1=57297&r2=57298&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Wed Oct  8 12:01:13 2008
@@ -217,6 +217,13 @@
                     getPointeeType()->getAsFunctionType();
 }
 
+SourceLocation BlockExpr::getCaretLocation() const { 
+  return TheBlock->getCaretLocation(); 
+}
+const Stmt *BlockExpr::getBody() const { return TheBlock->getBody(); }
+Stmt *BlockExpr::getBody() { return TheBlock->getBody(); }
+
+
 //===----------------------------------------------------------------------===//
 // Generic Expression Routines
 //===----------------------------------------------------------------------===//
@@ -1400,8 +1407,8 @@
 }
 
 // Blocks
-Stmt::child_iterator BlockExpr::child_begin() { return &Body; }
-Stmt::child_iterator BlockExpr::child_end() { return &Body+1; }
+Stmt::child_iterator BlockExpr::child_begin() { return child_iterator(); }
+Stmt::child_iterator BlockExpr::child_end() { return child_iterator(); }
 
 Stmt::child_iterator BlockDeclRefExpr::child_begin() { return child_iterator();}
 Stmt::child_iterator BlockDeclRefExpr::child_end() { return child_iterator(); }

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=57298&r1=57297&r2=57298&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Wed Oct  8 12:01:13 2008
@@ -895,26 +895,27 @@
 }
 
 void StmtPrinter::VisitBlockExpr(BlockExpr *Node) {
+  BlockDecl *BD = Node->getBlockDecl();
   OS << "^";
   
   const FunctionType *AFT = Node->getFunctionType();
   
   if (isa<FunctionTypeNoProto>(AFT)) {
     OS << "()";
-  } else if (!Node->arg_empty() || cast<FunctionTypeProto>(AFT)->isVariadic()) {
-    const FunctionTypeProto *FT = cast<FunctionTypeProto>(AFT);
+  } else if (!BD->param_empty() || cast<FunctionTypeProto>(AFT)->isVariadic()) {
     OS << '(';
     std::string ParamStr;
-    for (BlockExpr::arg_iterator AI = Node->arg_begin(),
-         E = Node->arg_end(); AI != E; ++AI) {
-      if (AI != Node->arg_begin()) OS << ", ";
+    for (BlockDecl::param_iterator AI = BD->param_begin(),
+         E = BD->param_end(); AI != E; ++AI) {
+      if (AI != BD->param_begin()) OS << ", ";
       ParamStr = (*AI)->getName();
       (*AI)->getType().getAsStringInternal(ParamStr);
       OS << ParamStr;
     }
     
+    const FunctionTypeProto *FT = cast<FunctionTypeProto>(AFT);
     if (FT->isVariadic()) {
-      if (!Node->arg_empty()) OS << ", ";
+      if (!BD->param_empty()) OS << ", ";
       OS << "...";
     }
     OS << ')';

Modified: cfe/trunk/lib/AST/StmtSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtSerialization.cpp?rev=57298&r1=57297&r2=57298&view=diff

==============================================================================
--- cfe/trunk/lib/AST/StmtSerialization.cpp (original)
+++ cfe/trunk/lib/AST/StmtSerialization.cpp Wed Oct  8 12:01:13 2008
@@ -1114,18 +1114,12 @@
 
 void BlockExpr::EmitImpl(Serializer& S) const {
   S.Emit(getType());
-  S.Emit(getCaretLocation());
-  S.EmitOwnedPtr(Body);
+  S.EmitOwnedPtr(TheBlock);
 }
 
 BlockExpr* BlockExpr::CreateImpl(Deserializer& D, ASTContext& C) {
-  QualType Q = QualType::ReadVal(D);
-  SourceLocation L = SourceLocation::ReadVal(D);
-  /*CompoundStmt* BodyStmt = cast<CompoundStmt>(*/D.ReadOwnedPtr<Stmt>(C)/*)*/;
-  assert(0 && "Cannot deserialize BlockBlockExpr yet");
-  // FIXME: need to handle parameters.
-  //return new BlockBlockExpr(L, Q, BodyStmt);
-  return 0;
+  QualType T = QualType::ReadVal(D);
+  return new BlockExpr(cast<BlockDecl>(D.ReadOwnedPtr<Decl>(C)),T);
 }
 
 void BlockDeclRefExpr::EmitImpl(Serializer& S) const {

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=57298&r1=57297&r2=57298&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Oct  8 12:01:13 2008
@@ -2931,8 +2931,11 @@
                                       BSI->isVariadic);
   
   BlockTy = Context.getBlockPointerType(BlockTy);
-  return new BlockExpr(CaretLoc, BlockTy, &BSI->Params[0], BSI->Params.size(), 
-                       Body.take());
+  
+  BlockDecl *NewBD = BlockDecl::Create(Context, CurContext, CaretLoc,
+                                       &BSI->Params[0], BSI->Params.size(),
+                                       Body.take());
+  return new BlockExpr(NewBD, BlockTy);
 }
 
 /// ExprsMatchFnType - return true if the Exprs in array Args have





More information about the cfe-commits mailing list