[cfe-commits] r156794 - in /cfe/trunk: lib/AST/ItaniumMangle.cpp test/CodeGenCXX/mangle-ref-qualifiers.cpp

John McCall rjmccall at apple.com
Mon May 14 19:01:59 PDT 2012


Author: rjmccall
Date: Mon May 14 21:01:59 2012
New Revision: 156794

URL: http://llvm.org/viewvc/llvm-project?rev=156794&view=rev
Log:
Change the mangling of a ref-qualifier on a function type so that
it is placed in a position which is never ambiguous with a
reference-to-function type.  This follows some recent discussion
and ensuing proposal on cxx-abi-dev.  It is not necessary to
change the mangling of CV-qualifiers because you cannot
apply CV-qualification in the normal sense to a function type.
It is not necessary to change the mangling of ref-qualifiers on
method declarations because they appear in an unambiguous
location.

In addition, mangle CV-qualifiers and ref-qualifiers on function
types when they occur in positions other than member pointers
(that is, when they appear as template arguments).

This is a minor ABI break with previous releases of clang.  It
is not considered critical because (1) ref-qualifiers are
relatively rare, since AFAIK we're the only implementing compiler,
and (2) they're particularly likely to come up in contexts that
do not rely on the ODR for correctness.  We apologize for any
inconvenience;  this is the right thing to do.

Modified:
    cfe/trunk/lib/AST/ItaniumMangle.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ref-qualifiers.cpp

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=156794&r1=156793&r2=156794&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Mon May 14 21:01:59 2012
@@ -1892,12 +1892,23 @@
 }
 
 // <type>          ::= <function-type>
-// <function-type> ::= F [Y] <bare-function-type> E
+// <function-type> ::= [<CV-qualifiers>] F [Y]
+//                      <bare-function-type> [<ref-qualifier>] E
+// (Proposal to cxx-abi-dev, 2012-05-11)
 void CXXNameMangler::mangleType(const FunctionProtoType *T) {
+  // Mangle CV-qualifiers, if present.  These are 'this' qualifiers,
+  // e.g. "const" in "int (A::*)() const".
+  mangleQualifiers(Qualifiers::fromCVRMask(T->getTypeQuals()));
+
   Out << 'F';
+
   // FIXME: We don't have enough information in the AST to produce the 'Y'
   // encoding for extern "C" function types.
   mangleBareFunctionType(T, /*MangleReturnType=*/true);
+
+  // Mangle the ref-qualifier, if present.
+  mangleRefQualifier(T->getRefQualifier());
+
   Out << 'E';
 }
 void CXXNameMangler::mangleType(const FunctionNoProtoType *T) {
@@ -1990,8 +2001,6 @@
   mangleType(QualType(T->getClass(), 0));
   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:
@@ -2005,9 +2014,11 @@
     //   which the function is a member is considered part of the type of 
     //   function.
 
+    // Given that we already substitute member function pointers as a
+    // whole, the net effect of this rule is just to unconditionally
+    // suppress substitution on the function type in a member pointer.
     // We increment the SeqID here to emulate adding an entry to the
-    // substitution table. We can't actually add it because we don't want this
-    // particular function type to be substituted.
+    // substitution table.
     ++SeqID;
   } else
     mangleType(PointeeType);

Modified: cfe/trunk/test/CodeGenCXX/mangle-ref-qualifiers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ref-qualifiers.cpp?rev=156794&r1=156793&r2=156794&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ref-qualifiers.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ref-qualifiers.cpp Mon May 14 21:01:59 2012
@@ -12,5 +12,11 @@
 // CHECK: define i32 @_ZNKO1X1hEv
 int X::h() const && { return 0; }
 
-// CHECK: define void @_Z1fM1XRFivEMS_OFivEMS_KOFivE
+// CHECK: define void @_Z1fM1XFivREMS_FivOEMS_KFivOE
 void f(int (X::*)() &, int (X::*)() &&, int (X::*)() const&&) { }
+
+// CHECK: define void @_Z1g1AIFivEES_IFivREES_IFivOEES_IKFivEES_IKFivREES_IKFivOEES_IVKFivEES_IVKFivREES_IVKFivOEE()
+template <class T> struct A {};
+void g(A<int()>, A<int()&>, A<int()&&>,
+       A<int() const>, A<int() const &>, A<int() const &&>,
+       A<int() const volatile>, A<int() const volatile &>, A<int() const volatile &&>) {}





More information about the cfe-commits mailing list