Improve "assignment to cast" diagnostic.
 - Strip off extra parens when looking for casts.
 - Change the location info to point at the cast (instead of the
   assignment).

For example, on
  
  int *b;
  #define a ((void*) b)
  void f0() {
    a = 10;
  }
  
we now emit:
  
  /tmp/t.c:4:3: error: assignment to cast is illegal, lvalue casts are not supported
    a = 10;
    ^ ~
  /tmp/t.c:2:12: note: instantiated from:
  #define a ((void*) b)
            ~^~~~~~~~~~
  
instead of:
  
  /tmp/t.c:4:5: error: expression is not assignable
    a = 10;
    ~ ^


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69114 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 973e662..dd34617 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -756,7 +756,8 @@
 /// if it is a structure or union, does not have any member (including, 
 /// recursively, any member or element of all contained aggregates or unions)
 /// with a const-qualified type.
-Expr::isModifiableLvalueResult Expr::isModifiableLvalue(ASTContext &Ctx) const {
+Expr::isModifiableLvalueResult 
+Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const {
   isLvalueResult lvalResult = isLvalue(Ctx);
     
   switch (lvalResult) {
@@ -775,9 +776,13 @@
     // lvalue, then this is probably a use of the old-school "cast as lvalue"
     // GCC extension.  We don't support it, but we want to produce good
     // diagnostics when it happens so that the user knows why.
-    if (const CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(IgnoreParens()))
-      if (CE->getSubExpr()->isLvalue(Ctx) == LV_Valid)
+    if (const CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(IgnoreParens())) {
+      if (CE->getSubExpr()->isLvalue(Ctx) == LV_Valid) {
+        if (Loc)
+          *Loc = CE->getLParenLoc();
         return MLV_LValueCast;
+      }
+    }
     return MLV_InvalidExpression;
   case LV_MemberFunction: return MLV_MemberFunction;
   }