Remove BlockDeclRefExpr and introduce a bit on DeclRefExpr to
track whether the referenced declaration comes from an enclosing
local context.  I'm amenable to suggestions about the exact meaning
of this bit.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152491 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Rewrite/RewriteModernObjC.cpp b/lib/Rewrite/RewriteModernObjC.cpp
index 3e6a19c..3099499 100644
--- a/lib/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Rewrite/RewriteModernObjC.cpp
@@ -120,9 +120,9 @@
     // Block expressions.
     SmallVector<BlockExpr *, 32> Blocks;
     SmallVector<int, 32> InnerDeclRefsCount;
-    SmallVector<BlockDeclRefExpr *, 32> InnerDeclRefs;
+    SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
     
-    SmallVector<BlockDeclRefExpr *, 32> BlockDeclRefs;
+    SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
 
     // Block related declarations.
     SmallVector<ValueDecl *, 8> BlockByCopyDecls;
@@ -327,7 +327,7 @@
     // Block specific rewrite rules.
     void RewriteBlockPointerDecl(NamedDecl *VD);
     void RewriteByRefVar(VarDecl *VD);
-    Stmt *RewriteBlockDeclRefExpr(Expr *VD);
+    Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
     Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
     void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
     
@@ -407,7 +407,7 @@
                                  StringRef FunName);
     FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
     Stmt *SynthBlockInitExpr(BlockExpr *Exp,
-            const SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs);
+            const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs);
 
     // Misc. helper routines.
     QualType getProtocolType();
@@ -421,7 +421,7 @@
     void CollectBlockDeclRefInfo(BlockExpr *Exp);
     void GetBlockDeclRefExprs(Stmt *S);
     void GetInnerBlockDeclRefExprs(Stmt *S, 
-                SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
+                SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs,
                 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
 
     // We avoid calling Type::isBlockPointerType(), since it operates on the
@@ -2062,7 +2062,7 @@
 
   // Create a reference to the objc_msgSend() declaration.
   DeclRefExpr *DRE =
-    new (Context) DeclRefExpr(FD, msgSendType, VK_LValue, SourceLocation());
+    new (Context) DeclRefExpr(FD, false, msgSendType, VK_LValue, SourceLocation());
 
   // Now, we cast the reference to a pointer to the objc_msgSend type.
   QualType pToFunc = Context->getPointerType(msgSendType);
@@ -2575,7 +2575,7 @@
   VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
                                    SourceLocation(), &Context->Idents.get(S),
                                    strType, 0, SC_Static, SC_None);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, VK_LValue,
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
                                                SourceLocation());
   Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
                                  Context->getPointerType(DRE->getType()),
@@ -2703,6 +2703,7 @@
       NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
                                CK_BitCast,
                    new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                             false,
                                              Context->getObjCIdType(),
                                              VK_RValue,
                                              SourceLocation()))
@@ -2744,7 +2745,7 @@
       SynthSuperContructorFunctionDecl();
       // Simulate a contructor call...
       DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
-                                                   superType, VK_LValue,
+                                                   false, superType, VK_LValue,
                                                    SourceLocation());
       SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
                                         InitExprs.size(),
@@ -2814,6 +2815,7 @@
       NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
                                CK_BitCast,
                    new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                             false,
                                              Context->getObjCIdType(),
                                              VK_RValue, SourceLocation()))
                         ); // set the 'receiver'.
@@ -2853,7 +2855,7 @@
       SynthSuperContructorFunctionDecl();
       // Simulate a contructor call...
       DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
-                                                   superType, VK_LValue,
+                                                   false, superType, VK_LValue,
                                                    SourceLocation());
       SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
                                         InitExprs.size(),
@@ -3005,7 +3007,7 @@
   QualType msgSendType = MsgSendFlavor->getType();
 
   // Create a reference to the objc_msgSend() declaration.
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType,
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
                                                VK_LValue, SourceLocation());
 
   // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
@@ -3041,7 +3043,8 @@
     // method's return type.
 
     // Create a reference to the objc_msgSend_stret() declaration.
-    DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor, msgSendType,
+    DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor,
+                                                   false, msgSendType,
                                                    VK_LValue, SourceLocation());
     // Need to cast objc_msgSend_stret to "void *" (see above comment).
     cast = NoTypeInfoCStyleCastExpr(Context,
@@ -3129,8 +3132,8 @@
   VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
                                 SourceLocation(), ID, getProtocolType(), 0,
                                 SC_Extern, SC_None);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), VK_LValue,
-                                               SourceLocation());
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
+                                               VK_LValue, SourceLocation());
   Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf,
                              Context->getPointerType(DRE->getType()),
                              VK_RValue, OK_Ordinary, SourceLocation());
@@ -3689,21 +3692,25 @@
     // Need to copy-in the inner copied-in variables not actually used in this
     // block.
     for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
-      BlockDeclRefExpr *Exp = InnerDeclRefs[count++];
+      DeclRefExpr *Exp = InnerDeclRefs[count++];
       ValueDecl *VD = Exp->getDecl();
       BlockDeclRefs.push_back(Exp);
-      if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
-        BlockByCopyDeclsPtrSet.insert(VD);
-        BlockByCopyDecls.push_back(VD);
+      if (!VD->hasAttr<BlocksAttr>()) {
+        if (!BlockByCopyDeclsPtrSet.count(VD)) {
+          BlockByCopyDeclsPtrSet.insert(VD);
+          BlockByCopyDecls.push_back(VD);
+        }
+        continue;
       }
-      if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
+
+      if (!BlockByRefDeclsPtrSet.count(VD)) {
         BlockByRefDeclsPtrSet.insert(VD);
         BlockByRefDecls.push_back(VD);
       }
+
       // imported objects in the inner blocks not used in the outer
       // blocks must be copied/disposed in the outer block as well.
-      if (Exp->isByRef() ||
-          VD->getType()->isObjCObjectPointerType() || 
+      if (VD->getType()->isObjCObjectPointerType() || 
           VD->getType()->isBlockPointerType())
         ImportedBlockDecls.insert(VD);
     }
@@ -3791,25 +3798,17 @@
         GetBlockDeclRefExprs(*CI);
     }
   // Handle specific things.
-  if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) {
-    // FIXME: Handle enums.
-    if (!isa<FunctionDecl>(CDRE->getDecl()))
-      BlockDeclRefs.push_back(CDRE);
-  }
-  else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
-    if (HasLocalVariableExternalStorage(DRE->getDecl())) {
-        BlockDeclRefExpr *BDRE = 
-          new (Context)BlockDeclRefExpr(cast<VarDecl>(DRE->getDecl()),
-                                        DRE->getType(), 
-                                        VK_LValue, DRE->getLocation(), false);
-        BlockDeclRefs.push_back(BDRE);
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
+    if (DRE->refersToEnclosingLocal() &&
+        HasLocalVariableExternalStorage(DRE->getDecl())) {
+      BlockDeclRefs.push_back(DRE);
     }
   
   return;
 }
 
 void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S, 
-                SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
+                SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs,
                 llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
   for (Stmt::child_range CI = S->children(); CI; ++CI)
     if (*CI) {
@@ -3826,15 +3825,15 @@
 
     }
   // Handle specific things.
-  if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) {
-    if (!isa<FunctionDecl>(CDRE->getDecl()) &&
-        !InnerContexts.count(CDRE->getDecl()->getDeclContext()))
-      InnerBlockDeclRefs.push_back(CDRE);
-  }
-  else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
-    if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
-      if (Var->isFunctionOrMethodVarDecl())
-        ImportedLocalExternalDecls.insert(Var);
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    if (DRE->refersToEnclosingLocal()) {
+      if (!isa<FunctionDecl>(DRE->getDecl()) &&
+          !InnerContexts.count(DRE->getDecl()->getDeclContext()))
+        InnerBlockDeclRefs.push_back(DRE);
+      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
+        if (Var->isFunctionOrMethodVarDecl())
+          ImportedLocalExternalDecls.insert(Var);
+    }
   }
   
   return;
@@ -3896,9 +3895,6 @@
 
   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
     CPT = DRE->getType()->getAs<BlockPointerType>();
-  } else if (const BlockDeclRefExpr *CDRE = 
-              dyn_cast<BlockDeclRefExpr>(BlockExp)) {
-    CPT = CDRE->getType()->getAs<BlockPointerType>();
   } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
     CPT = MExpr->getType()->getAs<BlockPointerType>();
   } 
@@ -3999,7 +3995,7 @@
 }
 
 // We need to return the rewritten expression to handle cases where the
-// BlockDeclRefExpr is embedded in another expression being rewritten.
+// DeclRefExpr is embedded in another expression being rewritten.
 // For example:
 //
 // int main() {
@@ -4007,21 +4003,15 @@
 //    __block int i;
 //
 //    void (^myblock)() = ^() {
-//        [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten).
+//        [f test]; // f is a DeclRefExpr embedded in a message (which is being rewritten).
 //        i = 77;
 //    };
 //}
-Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) {
+Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) {
   // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 
   // for each DeclRefExp where BYREFVAR is name of the variable.
-  ValueDecl *VD;
-  bool isArrow = true;
-  if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(DeclRefExp))
-    VD = BDRE->getDecl();
-  else {
-    VD = cast<DeclRefExpr>(DeclRefExp)->getDecl();
-    isArrow = false;
-  }
+  ValueDecl *VD = DeclRefExp->getDecl();
+  bool isArrow = DeclRefExp->refersToEnclosingLocal();
   
   FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
                                     SourceLocation(),
@@ -4515,7 +4505,7 @@
   if (BlockDeclRefs.size()) {
     // Unique all "by copy" declarations.
     for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
-      if (!BlockDeclRefs[i]->isByRef()) {
+      if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
         if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
           BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
           BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
@@ -4523,7 +4513,7 @@
       }
     // Unique all "by ref" declarations.
     for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
-      if (BlockDeclRefs[i]->isByRef()) {
+      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
         if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
           BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
           BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
@@ -4531,7 +4521,7 @@
       }
     // Find any imported blocks...they will need special attention.
     for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
-      if (BlockDeclRefs[i]->isByRef() ||
+      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
           BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
           BlockDeclRefs[i]->getType()->isBlockPointerType())
         ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
@@ -4547,7 +4537,7 @@
 }
 
 Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
-          const SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs) {
+          const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs) {
   const BlockDecl *block = Exp->getBlockDecl();
   Blocks.push_back(Exp);
 
@@ -4557,9 +4547,9 @@
  int countOfInnerDecls = 0;
   if (!InnerBlockDeclRefs.empty()) {
     for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
-      BlockDeclRefExpr *Exp = InnerBlockDeclRefs[i];
+      DeclRefExpr *Exp = InnerBlockDeclRefs[i];
       ValueDecl *VD = Exp->getDecl();
-      if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
+      if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
       // We need to save the copied-in variables in nested
       // blocks because it is needed at the end for some of the API generations.
       // See SynthesizeBlockLiterals routine.
@@ -4568,7 +4558,7 @@
         BlockByCopyDeclsPtrSet.insert(VD);
         BlockByCopyDecls.push_back(VD);
       }
-      if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
+      if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
         InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
         BlockDeclRefs.push_back(Exp);
         BlockByRefDeclsPtrSet.insert(VD);
@@ -4577,7 +4567,7 @@
     }
     // Find any imported blocks...they will need special attention.
     for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
-      if (InnerBlockDeclRefs[i]->isByRef() ||
+      if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
           InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
           InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
         ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
@@ -4607,15 +4597,15 @@
 
   // Simulate a contructor call...
   FD = SynthBlockInitFunctionDecl(Tag);
-  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, FType, VK_RValue,
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
                                                SourceLocation());
 
   SmallVector<Expr*, 4> InitExprs;
 
   // Initialize the block function.
   FD = SynthBlockInitFunctionDecl(Func);
-  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
-                                               SourceLocation());
+  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                               VK_LValue, SourceLocation());
   CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
                                                 CK_BitCast, Arg);
   InitExprs.push_back(castExpr);
@@ -4629,7 +4619,7 @@
                                    Context->VoidPtrTy, 0,
                                    SC_Static, SC_None);
   UnaryOperator *DescRefExpr =
-    new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD,
+    new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
                                                           Context->VoidPtrTy,
                                                           VK_LValue,
                                                           SourceLocation()), 
@@ -4648,8 +4638,8 @@
       if (isObjCType((*I)->getType())) {
         // FIXME: Conform to ABI ([[obj retain] autorelease]).
         FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
-                                        SourceLocation());
+        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                        VK_LValue, SourceLocation());
         if (HasLocalVariableExternalStorage(*I)) {
           QualType QT = (*I)->getType();
           QT = Context->getPointerType(QT);
@@ -4658,14 +4648,14 @@
         }
       } else if (isTopLevelBlockPointerType((*I)->getType())) {
         FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Arg = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
-                                        SourceLocation());
+        Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                        VK_LValue, SourceLocation());
         Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
                                        CK_BitCast, Arg);
       } else {
         FD = SynthBlockInitFunctionDecl((*I)->getName());
-        Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
-                                        SourceLocation());
+        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                        VK_LValue, SourceLocation());
         if (HasLocalVariableExternalStorage(*I)) {
           QualType QT = (*I)->getType();
           QT = Context->getPointerType(QT);
@@ -4692,7 +4682,7 @@
       QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
       
       FD = SynthBlockInitFunctionDecl((*I)->getName());
-      Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
+      Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
                                       SourceLocation());
       bool isNestedCapturedVar = false;
       if (block)
@@ -4786,7 +4776,7 @@
     }
 
   if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
-    SmallVector<BlockDeclRefExpr *, 8> InnerBlockDeclRefs;
+    SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
     llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
     InnerContexts.insert(BE->getBlockDecl());
     ImportedLocalExternalDecls.clear();
@@ -4931,10 +4921,6 @@
     Stmts.pop_back();
   }
   // Handle blocks rewriting.
-  if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
-    if (BDRE->isByRef())
-      return RewriteBlockDeclRefExpr(BDRE);
-  }
   if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
     ValueDecl *VD = DRE->getDecl(); 
     if (VD->hasAttr<BlocksAttr>())
@@ -6551,7 +6537,8 @@
       VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
                                        SourceLocation(), &Context->Idents.get(IvarOffsetName),
                                        Context->UnsignedLongTy, 0, SC_Extern, SC_None);
-      DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, Context->UnsignedLongTy, VK_LValue,
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false,
+                                                   Context->UnsignedLongTy, VK_LValue,
                                                    SourceLocation());
       BinaryOperator *addExpr = 
         new (Context) BinaryOperator(castExpr, DRE, BO_Add,