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 + ')';