]> granicus.if.org Git - clang/commitdiff
Fix codegen for support for super inside block literal expressions.
authorMike Stump <mrs@apple.com>
Fri, 20 Mar 2009 21:53:12 +0000 (21:53 +0000)
committerMike Stump <mrs@apple.com>
Fri, 20 Mar 2009 21:53:12 +0000 (21:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67406 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGBlocks.cpp
lib/CodeGen/CGDecl.cpp
lib/CodeGen/CGObjC.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGenObjC/blocks.m

index fcda90794e94b67d67e2d84c5eba3ff15805e440..c233ff38545f18f53b6fd3a64646105468846388 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "clang/AST/DeclObjC.h"
 #include "llvm/Module.h"
 #include "llvm/Target/TargetData.h"
 
@@ -155,7 +156,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
     uint64_t subBlockSize, subBlockAlign;
     llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls;
     llvm::Function *Fn
-      = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, LocalDeclMap,
+      = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, CurFuncDecl, LocalDeclMap,
                                                    subBlockSize,
                                                    subBlockAlign,
                                                    subBlockDeclRefDecls,
@@ -525,6 +526,19 @@ llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
   return V;
 }
 
+void CodeGenFunction::BlockForwardSelf() {
+  const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
+  ImplicitParamDecl *SelfDecl = OMD->getSelfDecl();
+  llvm::Value *&DMEntry = LocalDeclMap[SelfDecl];
+  if (DMEntry)
+    return;
+  // FIXME - Eliminate BlockDeclRefExprs, clients don't need/want to care
+  BlockDeclRefExpr *BDRE = new (getContext())
+    BlockDeclRefExpr(SelfDecl,
+                     SelfDecl->getType(), SourceLocation(), false);
+  DMEntry = GetAddrOfBlockDecl(BDRE);
+}
+
 llvm::Constant *
 BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) {
   // Generate the block descriptor.
@@ -561,7 +575,7 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) {
   bool subBlockHasCopyDispose = false;
   llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
   llvm::Function *Fn
-    = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, LocalDeclMap,
+    = CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, 0, LocalDeclMap,
                                                  subBlockSize,
                                                  subBlockAlign,
                                                  subBlockDeclRefDecls,
@@ -605,6 +619,7 @@ llvm::Value *CodeGenFunction::LoadBlockStruct() {
 llvm::Function *
 CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,
                                        const BlockInfo& Info,
+                                       const Decl *OuterFuncDecl,
                                   llvm::DenseMap<const Decl*, llvm::Value*> ldm,
                                        uint64_t &Size,
                                        uint64_t &Align,
@@ -657,6 +672,7 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,
 
   StartFunction(BD, FTy->getResultType(), Fn, Args,
                 BExpr->getBody()->getLocEnd());
+  CurFuncDecl = OuterFuncDecl;
   EmitStmt(BExpr->getBody());
   FinishFunction(cast<CompoundStmt>(BExpr->getBody())->getRBracLoc());
 
index 6646365b45a09496bf49f79d8fed5f5bd5a84e8c..eb2fe4f502054fc05161a98443440bd8525e6c3b 100644 (file)
@@ -89,10 +89,6 @@ CodeGenFunction::CreateStaticBlockVarDecl(const VarDecl &D,
   else if (isa<ObjCMethodDecl>(CurFuncDecl))
     ContextName = std::string(CurFn->getNameStart(), 
                               CurFn->getNameStart() + CurFn->getNameLen());
-  else if (isa<BlockDecl>(CurFuncDecl))
-    // FIXME: We want to traverse up and pick a name based upon where we came
-    // from.
-    ContextName = "block";
   else
     assert(0 && "Unknown context for block var decl");
 
index 7f5262df1d4dde8642cf3199057d054186ce9213..acc07c740a91b193a117122f789fbb97465c9809 100644 (file)
@@ -304,6 +304,8 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
 
 llvm::Value *CodeGenFunction::LoadObjCSelf() {
   const ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(CurFuncDecl);
+  // See if we need to lazily forward self inside a block literal.
+  BlockForwardSelf();
   return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self");
 }
 
index a54e187658b34b203d1258f2f8fdff2ad81f7f90..9771c83d84c15545d31aca7bdebccab4f46d033d 100644 (file)
@@ -72,7 +72,8 @@ public:
   typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
   CGBuilderTy Builder;
 
-  // Holds the Decl for the current function or method
+  /// CurFuncDecl - Holds the Decl for the current function or method.  This
+  /// excludes BlockDecls.
   const Decl *CurFuncDecl;
   const CGFunctionInfo *CurFnInfo;
   QualType FnRetTy;
@@ -272,11 +273,13 @@ public:
 
   llvm::Function *GenerateBlockFunction(const BlockExpr *BExpr,
                                         const BlockInfo& Info,
+                                        const Decl *OuterFuncDecl,
                                   llvm::DenseMap<const Decl*, llvm::Value*> ldm,
                                         uint64_t &Size, uint64_t &Align,
                       llvm::SmallVector<const Expr *, 8> &subBlockDeclRefDecls,
                                         bool &subBlockHasCopyDispose);
 
+  void BlockForwardSelf();
   llvm::Value *LoadBlockStruct();
 
   llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E);
index c32419e42438133d88802ab776bb2e725730e2e6..e9ca2238baba04e1111370038cd00105127fedc5 100644 (file)
@@ -15,3 +15,13 @@ void foo(T *P) {
  [P foo: 0];
 }
 
+@interface A 
+-(void) im0;
+@end
+
+@interface B : A @end
+@implementation B
+-(void) im1 {
+  ^(void) { [super im0]; }();
+}
+@end