aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Type.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2009-03-16 23:22:08 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2009-03-16 23:22:08 +0000
commit7c80bd64032e610c0dbd74fc0ef6ea334447f2fd (patch)
tree063757ae5ba5bc99323c26d4590654ed2f82a1b4 /lib/AST/Type.cpp
parenta393e9eedcc28b25f521a4feceb3b56e3d0d360f (diff)
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
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r--lib/AST/Type.cpp62
1 files changed, 55 insertions, 7 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index fc71097c12..1714e84129 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -117,7 +117,8 @@ bool Type::isDerivedType() const {
case IncompleteArray:
case FunctionProto:
case FunctionNoProto:
- case Reference:
+ case LValueReference:
+ case RValueReference:
case Record:
return true;
default:
@@ -264,9 +265,9 @@ const ReferenceType *Type::getAsReferenceType() const {
// 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 @@ const ReferenceType *Type::getAsReferenceType() const {
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 @@ void BlockPointerType::getAsStringInternal(std::string &S) const {
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 @@ void MemberPointerType::getAsStringInternal(std::string &S) const {
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 + ')';