Initial step toward supporting qualification conversions (C++ 4.4).

Changes:
  - Sema::IsQualificationConversion determines whether we have a qualification
    conversion.
  - Sema::CheckSingleAssignment constraints now follows the C++ rules in C++,
    performing an implicit conversion from the right-hand side to the type of
    the left-hand side rather than checking based on the C notion of 
    "compatibility". We now rely on the implicit-conversion code to
    determine whether the conversion can happen or
    not. Sema::TryCopyInitialization has an ugly reference-related
    hack to cope with the initialization of references, for now.
  - When building DeclRefExprs, strip away the reference type, since
    there are no expressions whose type is a reference. We'll need to
    do this throughout Sema.
  - Expr::isLvalue now permits functions to be lvalues in C++ (but not
  in C).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57935 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 7a3c6bd..3ead430 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -450,7 +450,7 @@
   }
   // If this reference is not in a block or if the referenced variable is
   // within the block, create a normal DeclRefExpr.
-  return new DeclRefExpr(VD, VD->getType(), Loc);
+  return new DeclRefExpr(VD, GetNonReferenceType(VD->getType()), Loc);
 }
 
 Sema::ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
@@ -1565,8 +1565,7 @@
   // 3 & 4 (below). ...and the type *pointed to* by the left has all the 
   // qualifiers of the type *pointed to* by the right; 
   // FIXME: Handle ASQualType
-  if ((lhptee.getCVRQualifiers() & rhptee.getCVRQualifiers()) != 
-       rhptee.getCVRQualifiers())
+  if (!lhptee.isAtLeastAsQualifiedAs(rhptee))
     ConvTy = CompatiblePointerDiscardsQualifiers;
 
   // C99 6.5.16.1p1 (constraint 4): If one operand is a pointer to an object or 
@@ -1766,6 +1765,28 @@
 
 Sema::AssignConvertType
 Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
+  if (getLangOptions().CPlusPlus) {
+    if (!lhsType->isRecordType()) {
+      // C++ 5.17p3: If the left operand is not of class type, the
+      // expression is implicitly converted (C++ 4) to the
+      // cv-unqualified type of the left operand.
+      ImplicitConversionSequence ICS 
+        = TryCopyInitialization(rExpr, lhsType.getUnqualifiedType());
+      if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) {
+        // No implicit conversion available; we cannot perform this
+        // assignment.
+        return Incompatible;
+      } else {
+        // Perform the appropriate cast to the right-handle side.
+        ImpCastExprToType(rExpr, lhsType.getUnqualifiedType());
+        return Compatible;
+      }
+    }
+
+    // FIXME: Currently, we fall through and treat C++ classes like C
+    // structures.
+  }
+
   // C99 6.5.16.1p1: the left operand is a pointer and the right is
   // a null pointer constant.
   if ((lhsType->isPointerType() || lhsType->isObjCQualifiedIdType() ||