]> granicus.if.org Git - clang/commitdiff
Rvalue references for *this: add name mangling for ref-qualifiers,
authorDouglas Gregor <dgregor@apple.com>
Wed, 26 Jan 2011 17:36:28 +0000 (17:36 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 26 Jan 2011 17:36:28 +0000 (17:36 +0000)
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

include/clang/AST/DeclCXX.h
lib/AST/ItaniumMangle.cpp
test/CodeGenCXX/mangle-ref-qualifiers.cpp [new file with mode: 0644]

index a09fd6741b88c39fd9971831158adad6f2141518..8c66752f429451a6aff8fbfefad9428891da3938 100644 (file)
@@ -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.
index af9e35bbfcd251509dc0de9df11ce24f9a09d459..3c7191a8e128596bacd3edf752a9dc3a28a99272 100644 (file)
@@ -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 (file)
index 0000000..b3f37d7
--- /dev/null
@@ -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&&) { }