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/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index ad763c3..f546bbe 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -983,6 +983,7 @@
       DRE->getQualifierLoc(),
       SourceLocation(),
       NewBuiltinDecl,
+      /*enclosing*/ false,
       DRE->getLocation(),
       NewBuiltinDecl->getType(),
       DRE->getValueKind());
@@ -4674,12 +4675,6 @@
       return considerVariable(var, ref, owner);
     }
 
-    if (BlockDeclRefExpr *ref = dyn_cast<BlockDeclRefExpr>(e)) {
-      owner.Variable = ref->getDecl();
-      owner.setLocsFrom(ref);
-      return true;
-    }
-
     if (MemberExpr *member = dyn_cast<MemberExpr>(e)) {
       if (member->isArrow()) return false;
 
@@ -4736,11 +4731,6 @@
         Capturer = ref;
     }
 
-    void VisitBlockDeclRefExpr(BlockDeclRefExpr *ref) {
-      if (ref->getDecl() == Variable && !Capturer)
-        Capturer = ref;
-    }
-
     void VisitObjCIvarRefExpr(ObjCIvarRefExpr *ref) {
       if (Capturer) return;
       Visit(ref->getBase());
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index e3527a8..f6e3aa7 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -6721,7 +6721,7 @@
 
     if (type->isStructureOrClassType()) {
       SourceLocation poi = var->getLocation();
-      Expr *varRef = new (Context) DeclRefExpr(var, type, VK_LValue, poi);
+      Expr *varRef =new (Context) DeclRefExpr(var, false, type, VK_LValue, poi);
       ExprResult result =
         PerformCopyInitialization(
                         InitializedEntity::InitializeBlock(poi, type, false),
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index e84f66b..a5b7457 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2415,7 +2415,7 @@
 
     Expr *CopyCtorArg = 
       DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(),
-                          SourceLocation(), Param,
+                          SourceLocation(), Param, false,
                           Constructor->getLocation(), ParamType,
                           VK_LValue, 0);
 
@@ -2491,7 +2491,7 @@
         
     Expr *MemberExprBase = 
       DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(),
-                          SourceLocation(), Param,
+                          SourceLocation(), Param, false,
                           Loc, ParamType, VK_LValue, 0);
 
     SemaRef.MarkDeclRefReferenced(cast<DeclRefExpr>(MemberExprBase));
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 85778e4..a57e2ac 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1266,11 +1266,16 @@
         }
       }
 
+  bool refersToEnclosingScope =
+    (CurContext != D->getDeclContext() &&
+     D->getDeclContext()->isFunctionOrMethod());
+
   DeclRefExpr *E = DeclRefExpr::Create(Context,
                                        SS ? SS->getWithLocInContext(Context)
                                               : NestedNameSpecifierLoc(),
-                                           SourceLocation(),
-                                           D, NameInfo, Ty, VK);
+                                       SourceLocation(),
+                                       D, refersToEnclosingScope,
+                                       NameInfo, Ty, VK);
 
   MarkDeclRefReferenced(E);
 
@@ -2146,42 +2151,6 @@
   return Owned(ULE);
 }
 
-static bool shouldBuildBlockDeclRef(ValueDecl *D, Sema &S) {
-  // Check for a variable with local storage not from the current scope;
-  // we need to create BlockDeclRefExprs for these.
-  // FIXME: BlockDeclRefExpr shouldn't exist!
-  VarDecl *var = dyn_cast<VarDecl>(D);
-  if (!var)
-    return false;
-  if (var->getDeclContext() == S.CurContext)
-    return false;
-  if (!var->hasLocalStorage())
-    return false;
-  return S.getCurBlock() != 0;
-}
-
-static ExprResult BuildBlockDeclRefExpr(Sema &S, ValueDecl *VD,
-                                        const DeclarationNameInfo &NameInfo) {
-  VarDecl *var = cast<VarDecl>(VD);
-  QualType exprType = var->getType().getNonReferenceType();
-
-  bool HasBlockAttr = var->hasAttr<BlocksAttr>();
-  bool ConstAdded = false;
-  if (!HasBlockAttr) {
-    ConstAdded = !exprType.isConstQualified();
-    exprType.addConst();
-  }
-
-  BlockDeclRefExpr *BDRE =
-      new (S.Context) BlockDeclRefExpr(var, exprType, VK_LValue,
-                                       NameInfo.getLoc(), HasBlockAttr,
-                                       ConstAdded);
-
-  S.MarkBlockDeclRefReferenced(BDRE);
-
-  return S.Owned(BDRE);
-}
-
 /// \brief Complete semantic analysis for a reference to the given declaration.
 ExprResult
 Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
@@ -2304,9 +2273,6 @@
       valueKind = VK_LValue;
       type = type.getNonReferenceType();
 
-      if (shouldBuildBlockDeclRef(VD, *this))
-        return BuildBlockDeclRefExpr(*this, VD, NameInfo);
-
       // FIXME: Does the addition of const really only apply in
       // potentially-evaluated contexts? Since the variable isn't actually
       // captured in an unevaluated context, it seems that the answer is no.
@@ -3721,7 +3687,7 @@
   QualType ConfigQTy = ConfigDecl->getType();
 
   DeclRefExpr *ConfigDR = new (Context) DeclRefExpr(
-      ConfigDecl, ConfigQTy, VK_LValue, LLLLoc);
+      ConfigDecl, false, ConfigQTy, VK_LValue, LLLLoc);
   MarkFunctionReferenced(LLLLoc, ConfigDecl);
 
   return ActOnCallExpr(S, ConfigDR, LLLLoc, ExecConfig, GGGLoc, 0,
@@ -9863,7 +9829,8 @@
   // C++ [expr.prim.labda]p12:
   //   An entity captured by a lambda-expression is odr-used (3.2) in
   //   the scope containing the lambda-expression.
-  Expr *Ref = new (S.Context) DeclRefExpr(Var, DeclRefType, VK_LValue, Loc);
+  Expr *Ref = new (S.Context) DeclRefExpr(Var, false, DeclRefType,
+                                          VK_LValue, Loc);
   Var->setReferenced(true);
   Var->setUsed(true);
 
@@ -10109,7 +10076,7 @@
             // According to the blocks spec, the capture of a variable from
             // the stack requires a const copy constructor.  This is not true
             // of the copy/move done to move a __block variable to the heap.
-            Expr *DeclRef = new (Context) DeclRefExpr(Var, 
+            Expr *DeclRef = new (Context) DeclRefExpr(Var, false,
                                                       DeclRefType.withConst(), 
                                                       VK_LValue, Loc);
             ExprResult Result
@@ -10278,10 +10245,7 @@
        i != e; ++i) {
     VarDecl *Var;
     SourceLocation Loc;
-    if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(*i)) {
-      Var = BDRE->getDecl();
-      Loc = BDRE->getLocation();
-    } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*i)) {
+    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*i)) {
       Var = cast<VarDecl>(DRE->getDecl());
       Loc = DRE->getLocation();
     } else if (MemberExpr *ME = dyn_cast<MemberExpr>(*i)) {
@@ -10365,12 +10329,6 @@
   SemaRef.MarkAnyDeclReferenced(Loc, D);
 } 
 
-/// \brief Perform reference-marking and odr-use handling for a
-/// BlockDeclRefExpr.
-void Sema::MarkBlockDeclRefReferenced(BlockDeclRefExpr *E) {
-  MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E);
-}
-
 /// \brief Perform reference-marking and odr-use handling for a DeclRefExpr.
 void Sema::MarkDeclRefReferenced(DeclRefExpr *E) {
   MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E);
@@ -10497,14 +10455,6 @@
       Inherited::VisitCXXConstructExpr(E);
     }
     
-    void VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
-      // If we were asked not to visit local variables, don't.
-      if (SkipLocalVariables && E->getDecl()->hasLocalStorage())
-          return;
-
-      S.MarkBlockDeclRefReferenced(E);
-    }
-    
     void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
       Visit(E->getExpr());
     }
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 0f1db2b..8eeb09e 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -2187,6 +2187,7 @@
     Owned(DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
                               SourceLocation(),
                               ConditionVar,
+                              /*enclosing*/ false,
                               ConditionVar->getLocation(),
                               ConditionVar->getType().getNonReferenceType(),
                               VK_LValue));
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 7c1de21..5de7852 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -3872,16 +3872,11 @@
     }
 
   // If we have a declaration reference, it had better be a local variable.
-  } else if (isa<DeclRefExpr>(e) || isa<BlockDeclRefExpr>(e)) {
+  } else if (isa<DeclRefExpr>(e)) {
     if (!isAddressOf) return IIK_nonlocal;
 
-    VarDecl *var;
-    if (isa<DeclRefExpr>(e)) {
-      var = dyn_cast<VarDecl>(cast<DeclRefExpr>(e)->getDecl());
-      if (!var) return IIK_nonlocal;
-    } else {
-      var = cast<BlockDeclRefExpr>(e)->getDecl();
-    }
+    VarDecl *var = dyn_cast<VarDecl>(cast<DeclRefExpr>(e)->getDecl());
+    if (!var) return IIK_nonlocal;
 
     return (var->hasLocalStorage() ? IIK_okay : IIK_nonlocal);
 
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 77458e0..617460d 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -834,7 +834,7 @@
       // FIXME. Eventually we want to do this for Objective-C as well.
       ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl();
       DeclRefExpr *SelfExpr = 
-        new (Context) DeclRefExpr(SelfDecl, SelfDecl->getType(),
+        new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(),
                                   VK_RValue, SourceLocation());
       Expr *IvarRefExpr =
         new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
@@ -867,7 +867,7 @@
       // FIXME. Eventually we want to do this for Objective-C as well.
       ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl();
       DeclRefExpr *SelfExpr = 
-        new (Context) DeclRefExpr(SelfDecl, SelfDecl->getType(),
+        new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(),
                                   VK_RValue, SourceLocation());
       Expr *lhs =
         new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
@@ -875,7 +875,7 @@
       ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
       ParmVarDecl *Param = (*P);
       QualType T = Param->getType().getNonReferenceType();
-      Expr *rhs = new (Context) DeclRefExpr(Param, T,
+      Expr *rhs = new (Context) DeclRefExpr(Param, false, T,
                                             VK_LValue, SourceLocation());
       ExprResult Res = BuildBinOp(S, lhs->getLocEnd(), 
                                   BO_Assign, lhs, rhs);
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 22b145c..49301c2 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -40,7 +40,7 @@
 CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, bool HadMultipleCandidates,
                       SourceLocation Loc = SourceLocation(), 
                       const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){
-  DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, Fn->getType(),
+  DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, false, Fn->getType(),
                                                  VK_LValue, Loc, LocInfo);
   if (HadMultipleCandidates)
     DRE->setHadMultipleCandidates(true);
@@ -5580,7 +5580,7 @@
   // lvalues/rvalues and the type. Fortunately, we can allocate this
   // call on the stack and we don't need its arguments to be
   // well-formed.
-  DeclRefExpr ConversionRef(Conversion, Conversion->getType(),
+  DeclRefExpr ConversionRef(Conversion, false, Conversion->getType(),
                             VK_LValue, From->getLocStart());
   ImplicitCastExpr ConversionFn(ImplicitCastExpr::OnStack,
                                 Context.getPointerType(Conversion->getType()),
@@ -11053,6 +11053,7 @@
                                            ULE->getQualifierLoc(),
                                            ULE->getTemplateKeywordLoc(),
                                            Fn,
+                                           /*enclosing*/ false, // FIXME?
                                            ULE->getNameLoc(),
                                            Fn->getType(),
                                            VK_LValue,
@@ -11080,6 +11081,7 @@
                                                MemExpr->getQualifierLoc(),
                                                MemExpr->getTemplateKeywordLoc(),
                                                Fn,
+                                               /*enclosing*/ false,
                                                MemExpr->getMemberLoc(),
                                                Fn->getType(),
                                                VK_LValue,
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index d661d86..9528f4c 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -73,15 +73,6 @@
       return true;
     }
     
-    // \brief Record occurrences of function and non-type template parameter
-    // packs in a block-captured expression.
-    bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
-      if (E->getDecl()->isParameterPack())
-        Unexpanded.push_back(std::make_pair(E->getDecl(), E->getLocation()));
-      
-      return true;
-    }
-    
     /// \brief Record occurrences of template template parameter packs.
     bool TraverseTemplateName(TemplateName Template) {
       if (TemplateTemplateParmDecl *TTP 
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 8d4d934..9bb51b4 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -2399,7 +2399,8 @@
     // Build a reference to the __builtin_shufflevector builtin
     FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
     ExprResult Callee
-      = SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
+      = SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(Builtin, false,
+                                                        Builtin->getType(),
                                                         VK_LValue, BuiltinLoc));
     Callee = SemaRef.UsualUnaryConversions(Callee.take());
     if (Callee.isInvalid())
@@ -8770,29 +8771,6 @@
 
 template<typename Derived>
 ExprResult
-TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
-  ValueDecl *ND
-  = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
-                                                       E->getDecl()));
-  if (!ND)
-    return ExprError();
-
-  if (!getDerived().AlwaysRebuild() &&
-      ND == E->getDecl()) {
-    // Mark it referenced in the new context regardless.
-    // FIXME: this is a bit instantiation-specific.
-    SemaRef.MarkBlockDeclRefReferenced(E);
-    
-    return SemaRef.Owned(E);
-  }
-  
-  DeclarationNameInfo NameInfo(E->getDecl()->getDeclName(), E->getLocation());
-  return getDerived().RebuildDeclRefExpr(NestedNameSpecifierLoc(), 
-                                         ND, NameInfo, 0);
-}
-
-template<typename Derived>
-ExprResult
 TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
   llvm_unreachable("Cannot transform asType expressions yet");
 }