diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-01-26 17:36:28 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-01-26 17:36:28 +0000 |
commit | 0a9a6d68979619a621fedc5089674487f720f765 (patch) | |
tree | e00fb3abc819917dde97db76c2e9561d8094a20d | |
parent | e3c7a7ca66c02567543dbb5ec493818e00e8b177 (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.h | 14 | ||||
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 32 | ||||
-rw-r--r-- | test/CodeGenCXX/mangle-ref-qualifiers.cpp | 16 |
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&&) { } |