[cfe-commits] r108000 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/TreeTransform.h test/CodeGenCXX/instantiate-blocks.cpp

Fariborz Jahanian fjahanian at apple.com
Fri Jul 9 11:44:03 PDT 2010


Author: fjahanian
Date: Fri Jul  9 13:44:02 2010
New Revision: 108000

URL: http://llvm.org/viewvc/llvm-project?rev=108000&view=rev
Log:
Instantiation of block literal expressions. wip.


Added:
    cfe/trunk/test/CodeGenCXX/instantiate-blocks.cpp
Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/TreeTransform.h

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=108000&r1=107999&r2=108000&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Jul  9 13:44:02 2010
@@ -158,7 +158,7 @@
   bool hasBlockDeclRefExprs;
 
   BlockDecl *TheDecl;
-
+  
   /// TheScope - This is the scope for the block itself, which contains
   /// arguments etc.
   Scope *TheScope;

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=108000&r1=107999&r2=108000&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jul  9 13:44:02 2010
@@ -7074,7 +7074,10 @@
   BlockDecl *Block = BlockDecl::Create(Context, CurContext, CaretLoc);
   PushBlockScope(BlockScope, Block);
   CurContext->addDecl(Block);
-  PushDeclContext(BlockScope, Block);
+  if (BlockScope)
+    PushDeclContext(BlockScope, Block);
+  else
+    CurContext = Block;
 }
 
 void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
@@ -7199,7 +7202,7 @@
     Diag(CaretLoc, diag::err_blocks_disable);
 
   BlockScopeInfo *BSI = cast<BlockScopeInfo>(FunctionScopes.back());
-
+  
   PopDeclContext();
 
   QualType RetTy = Context.VoidTy;

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=108000&r1=107999&r2=108000&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri Jul  9 13:44:02 2010
@@ -4198,6 +4198,10 @@
   if (!ND)
     return SemaRef.ExprError();
 
+  // Set DeclContext if inside a Block.
+  if (BlockScopeInfo *CurBlock = SemaRef.getCurBlock())
+    ND->setDeclContext(CurBlock->TheDecl);
+  
   if (!getDerived().AlwaysRebuild() && 
       Qualifier == E->getQualifier() &&
       ND == E->getDecl() &&
@@ -6217,17 +6221,75 @@
 template<typename Derived>
 Sema::OwningExprResult
 TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
-  // FIXME: Implement this!
-  assert(false && "Cannot transform block expressions yet");
-  return SemaRef.Owned(E->Retain());
+  SourceLocation CaretLoc(E->getExprLoc());
+  
+  SemaRef.ActOnBlockStart(CaretLoc, /*Scope=*/0);
+  BlockScopeInfo *CurBlock = SemaRef.getCurBlock();
+  CurBlock->TheDecl->setIsVariadic(E->getBlockDecl()->isVariadic());
+  llvm::SmallVector<ParmVarDecl*, 4> Params;
+  llvm::SmallVector<QualType, 4> ParamTypes;
+  
+  // Parameter substitution.
+  const BlockDecl *BD = E->getBlockDecl();
+  for (BlockDecl::param_const_iterator P = BD->param_begin(),
+       EN = BD->param_end(); P != EN; ++P) {
+    ParmVarDecl *OldParm = (*P);
+    ParmVarDecl *NewParm = getDerived().TransformFunctionTypeParam(OldParm);
+    QualType NewType = NewParm->getType();
+    Params.push_back(NewParm);
+    ParamTypes.push_back(NewParm->getType());
+  }
+  
+  const FunctionType *BExprFunctionType = E->getFunctionType();
+  QualType BExprResultType = BExprFunctionType->getResultType();
+  if (!BExprResultType.isNull()) {
+    if (!BExprResultType->isDependentType())
+      CurBlock->ReturnType = BExprResultType;
+    else if (BExprResultType != SemaRef.Context.DependentTy)
+      CurBlock->ReturnType = getDerived().TransformType(BExprResultType);
+  }
+    
+  // Transform the body
+  OwningStmtResult Body = getDerived().TransformStmt(E->getBody());
+  if (Body.isInvalid())
+    return SemaRef.ExprError();
+  // Set the parameters on the block decl.
+  if (!Params.empty())
+    CurBlock->TheDecl->setParams(Params.data(), Params.size());
+    
+  QualType FunctionType = getDerived().RebuildFunctionProtoType(
+                                                        CurBlock->ReturnType,
+                                                        ParamTypes.data(),
+                                                        ParamTypes.size(),
+                                                        BD->isVariadic(),
+                                                        0);
+  
+  CurBlock->FunctionType = FunctionType;
+  return SemaRef.ActOnBlockStmtExpr(CaretLoc, move(Body), /*Scope=*/0);
 }
 
 template<typename Derived>
 Sema::OwningExprResult
 TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
-  // FIXME: Implement this!
-  assert(false && "Cannot transform block-related expressions yet");
-  return SemaRef.Owned(E->Retain());
+  NestedNameSpecifier *Qualifier = 0;
+    
+  ValueDecl *ND
+  = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
+                                                       E->getDecl()));
+  if (!ND)
+    return SemaRef.ExprError();
+  
+  if (!getDerived().AlwaysRebuild() &&
+      ND == E->getDecl()) {
+    // Mark it referenced in the new context regardless.
+    // FIXME: this is a bit instantiation-specific.
+    SemaRef.MarkDeclarationReferenced(E->getLocation(), ND);
+    
+    return SemaRef.Owned(E->Retain());
+  }
+  
+  return getDerived().RebuildDeclRefExpr(Qualifier, SourceLocation(),
+                                         ND, E->getLocation(), 0);
 }
 
 //===----------------------------------------------------------------------===//

Added: cfe/trunk/test/CodeGenCXX/instantiate-blocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/instantiate-blocks.cpp?rev=108000&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/instantiate-blocks.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/instantiate-blocks.cpp Fri Jul  9 13:44:02 2010
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fblocks -emit-llvm -o - %s
+// rdar : // 6182276
+
+template <typename T> T foo(T t)
+{
+    void (^block)(int);
+    return 1;
+}
+
+int test1(void)
+{
+    int i = 1;
+    int b = 2;
+    i = foo(b);
+    return 0;
+}
+
+template <typename T, typename T1> void foo(T t, T1 r)
+{
+    T block_arg;
+    T1 (^block)(char, T, T1, double) =  ^ T1 (char ch, T arg, T1 arg2, double d1) { return block_arg+arg; };
+
+    void (^block2)() = ^{};
+}
+
+void test2(void)
+{
+    foo(100, 'a');
+}





More information about the cfe-commits mailing list