aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-01-26 17:36:28 +0000
committerDouglas Gregor <dgregor@apple.com>2011-01-26 17:36:28 +0000
commit0a9a6d68979619a621fedc5089674487f720f765 (patch)
treee00fb3abc819917dde97db76c2e9561d8094a20d
parente3c7a7ca66c02567543dbb5ec493818e00e8b177 (diff)
Rvalue references for *this: add name mangling for ref-qualifiers,
using rules that I just made up this morning. This encoding has now been proposed to the Itanium C++ ABI group for inclusion, but of course it's still possible that the mangling will change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124296 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/DeclCXX.h14
-rw-r--r--lib/AST/ItaniumMangle.cpp32
-rw-r--r--test/CodeGenCXX/mangle-ref-qualifiers.cpp16
3 files changed, 58 insertions, 4 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index a09fd6741b..8c66752f42 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1096,6 +1096,20 @@ public:
return getType()->getAs<FunctionProtoType>()->getTypeQuals();
}
+ /// \brief Retrieve the ref-qualifier associated with this method.
+ ///
+ /// In the following example, \c f() has an lvalue ref-qualifier, \c g()
+ /// has an rvalue ref-qualifier, and \c h() has no ref-qualifier.
+ /// \code
+ /// struct X {
+ /// void f() &;
+ /// void g() &&;
+ /// void h();
+ /// };
+ RefQualifierKind getRefQualifier() const {
+ return getType()->getAs<FunctionProtoType>()->getRefQualifier();
+ }
+
bool hasInlineBody() const;
// Implement isa/cast/dyncast/etc.
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index af9e35bbfc..3c7191a8e1 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -228,6 +228,7 @@ private:
void mangleTemplatePrefix(TemplateName Template);
void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
void mangleQualifiers(Qualifiers Quals);
+ void mangleRefQualifier(RefQualifierKind RefQualifier);
void mangleObjCMethodName(const ObjCMethodDecl *MD);
@@ -817,13 +818,17 @@ void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
void CXXNameMangler::mangleNestedName(const NamedDecl *ND,
const DeclContext *DC,
bool NoFunction) {
- // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
- // ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
+ // <nested-name>
+ // ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
+ // ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix>
+ // <template-args> E
Out << 'N';
- if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND))
+ if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(ND)) {
mangleQualifiers(Qualifiers::fromCVRMask(Method->getTypeQualifiers()));
-
+ mangleRefQualifier(Method->getRefQualifier());
+ }
+
// Check if we have a template.
const TemplateArgumentList *TemplateArgs = 0;
if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) {
@@ -1162,6 +1167,24 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
// FIXME: For now, just drop all extension qualifiers on the floor.
}
+void CXXNameMangler::mangleRefQualifier(RefQualifierKind RefQualifier) {
+ // <ref-qualifier> ::= R # lvalue reference
+ // ::= O # rvalue-reference
+ // Proposal to Itanium C++ ABI list on 1/26/11
+ switch (RefQualifier) {
+ case RQ_None:
+ break;
+
+ case RQ_LValue:
+ Out << 'R';
+ break;
+
+ case RQ_RValue:
+ Out << 'O';
+ break;
+ }
+}
+
void CXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
llvm::SmallString<64> Buffer;
Context.mangleObjCMethodName(MD, Buffer);
@@ -1364,6 +1387,7 @@ void CXXNameMangler::mangleType(const MemberPointerType *T) {
QualType PointeeType = T->getPointeeType();
if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {
mangleQualifiers(Qualifiers::fromCVRMask(FPT->getTypeQuals()));
+ mangleRefQualifier(FPT->getRefQualifier());
mangleType(FPT);
// Itanium C++ ABI 5.1.8:
diff --git a/test/CodeGenCXX/mangle-ref-qualifiers.cpp b/test/CodeGenCXX/mangle-ref-qualifiers.cpp
new file mode 100644
index 0000000000..b3f37d7db3
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ref-qualifiers.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+struct X {
+ int f() &;
+ int g() &&;
+ int h() const &&;
+};
+
+// CHECK: define i32 @_ZNR1X1fEv
+int X::f() & { return 0; }
+// CHECK: define i32 @_ZNO1X1gEv
+int X::g() && { return 0; }
+// CHECK: define i32 @_ZNKO1X1hEv
+int X::h() const && { return 0; }
+
+// CHECK: define void @_Z1fM1XRFivEMS_OFivEMS_KOFivE
+void f(int (X::*)() &, int (X::*)() &&, int (X::*)() const&&) { }