Almost complete implementation of rvalue references. One bug, and a few unclear areas. Maybe Doug can shed some light on some of the fixmes.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67059 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index fc71097..1714e84 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -117,7 +117,8 @@
   case IncompleteArray:
   case FunctionProto:
   case FunctionNoProto:
-  case Reference:
+  case LValueReference:
+  case RValueReference:
   case Record:
     return true;
   default:
@@ -264,9 +265,9 @@
   // If this is directly a reference type, return it.
   if (const ReferenceType *RTy = dyn_cast<ReferenceType>(this))
     return RTy;
-  
+
   // If the canonical form of this type isn't the right kind, reject it.
-  if (!isa<ReferenceType>(CanonicalType)) {    
+  if (!isa<ReferenceType>(CanonicalType)) {
     // Look through type qualifiers
     if (isa<ReferenceType>(CanonicalType.getUnqualifiedType()))
       return CanonicalType.getUnqualifiedType()->getAsReferenceType();
@@ -278,6 +279,42 @@
   return getDesugaredType()->getAsReferenceType();
 }
 
+const LValueReferenceType *Type::getAsLValueReferenceType() const {
+  // If this is directly an lvalue reference type, return it.
+  if (const LValueReferenceType *RTy = dyn_cast<LValueReferenceType>(this))
+    return RTy;
+
+  // If the canonical form of this type isn't the right kind, reject it.
+  if (!isa<LValueReferenceType>(CanonicalType)) {
+    // Look through type qualifiers
+    if (isa<LValueReferenceType>(CanonicalType.getUnqualifiedType()))
+      return CanonicalType.getUnqualifiedType()->getAsLValueReferenceType();
+    return 0;
+  }
+
+  // If this is a typedef for an lvalue reference type, strip the typedef off
+  // without losing all typedef information.
+  return getDesugaredType()->getAsLValueReferenceType();
+}
+
+const RValueReferenceType *Type::getAsRValueReferenceType() const {
+  // If this is directly an rvalue reference type, return it.
+  if (const RValueReferenceType *RTy = dyn_cast<RValueReferenceType>(this))
+    return RTy;
+
+  // If the canonical form of this type isn't the right kind, reject it.
+  if (!isa<RValueReferenceType>(CanonicalType)) {
+    // Look through type qualifiers
+    if (isa<RValueReferenceType>(CanonicalType.getUnqualifiedType()))
+      return CanonicalType.getUnqualifiedType()->getAsRValueReferenceType();
+    return 0;
+  }
+
+  // If this is a typedef for an rvalue reference type, strip the typedef off
+  // without losing all typedef information.
+  return getDesugaredType()->getAsRValueReferenceType();
+}
+
 const MemberPointerType *Type::getAsMemberPointerType() const {
   // If this is directly a member pointer type, return it.
   if (const MemberPointerType *MTy = dyn_cast<MemberPointerType>(this))
@@ -1116,14 +1153,25 @@
   PointeeType.getAsStringInternal(S);
 }
 
-void ReferenceType::getAsStringInternal(std::string &S) const {
+void LValueReferenceType::getAsStringInternal(std::string &S) const {
   S = '&' + S;
-  
+
   // Handle things like 'int (&A)[4];' correctly.
   // FIXME: this should include vectors, but vectors use attributes I guess.
   if (isa<ArrayType>(getPointeeType()))
     S = '(' + S + ')';
-  
+
+  getPointeeType().getAsStringInternal(S);
+}
+
+void RValueReferenceType::getAsStringInternal(std::string &S) const {
+  S = "&&" + S;
+
+  // Handle things like 'int (&&A)[4];' correctly.
+  // FIXME: this should include vectors, but vectors use attributes I guess.
+  if (isa<ArrayType>(getPointeeType()))
+    S = '(' + S + ')';
+
   getPointeeType().getAsStringInternal(S);
 }
 
@@ -1133,7 +1181,7 @@
   C += "::*";
   S = C + S;
 
-  // Handle things like 'int (&A)[4];' correctly.
+  // Handle things like 'int (Cls::*A)[4];' correctly.
   // FIXME: this should include vectors, but vectors use attributes I guess.
   if (isa<ArrayType>(getPointeeType()))
     S = '(' + S + ')';