]> granicus.if.org Git - clang/commitdiff
MS ABI: Mangle this qualifiers on function types
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 12 Aug 2014 17:53:10 +0000 (17:53 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 12 Aug 2014 17:53:10 +0000 (17:53 +0000)
C++11 allows this qualifiers to exist on function types when used in
template arguments.  Previously, I believed it wasn't possible because
MSVC rejected declarations like: S<int () const &> s;

However, it turns out MSVC properly allows them in using declarations;
updated clang to be compatible with this mangling.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@215464 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/MicrosoftMangle.cpp
test/CodeGenCXX/mangle-ms-cxx11.cpp

index bc07e3c2dc8d89dd6bfd8971b43e2db3cea087f0..7a159f42968db60a3246d4b099e2edb6e219a6de 100644 (file)
@@ -234,7 +234,7 @@ public:
                   QualifierMangleMode QMM = QMM_Mangle);
   void mangleFunctionType(const FunctionType *T,
                           const FunctionDecl *D = nullptr,
-                          bool ForceInstMethod = false);
+                          bool ForceThisQuals = false);
   void mangleNestedName(const NamedDecl *ND);
 
 private:
@@ -1538,8 +1538,13 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T,
   // Structors only appear in decls, so at this point we know it's not a
   // structor type.
   // FIXME: This may not be lambda-friendly.
-  Out << "$$A6";
-  mangleFunctionType(T);
+  if (T->getTypeQuals() || T->getRefQualifier() != RQ_None) {
+    Out << "$$A8@@";
+    mangleFunctionType(T, /*D=*/nullptr, /*ForceThisQuals=*/true);
+  } else {
+    Out << "$$A6";
+    mangleFunctionType(T);
+  }
 }
 void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,
                                          SourceRange) {
@@ -1548,7 +1553,7 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,
 
 void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
                                                  const FunctionDecl *D,
-                                                 bool ForceInstMethod) {
+                                                 bool ForceThisQuals) {
   // <function-type> ::= <this-cvr-qualifiers> <calling-convention>
   //                     <return-type> <argument-list> <throw-spec>
   const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
@@ -1556,21 +1561,21 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
   SourceRange Range;
   if (D) Range = D->getSourceRange();
 
-  bool IsStructor = false, IsInstMethod = ForceInstMethod;
+  bool IsStructor = false, HasThisQuals = ForceThisQuals;
   if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
     if (MD->isInstance())
-      IsInstMethod = true;
+      HasThisQuals = true;
     if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD))
       IsStructor = true;
   }
 
   // If this is a C++ instance method, mangle the CVR qualifiers for the
   // this pointer.
-  if (IsInstMethod) {
+  if (HasThisQuals) {
     Qualifiers Quals = Qualifiers::fromCVRMask(Proto->getTypeQuals());
-    manglePointerExtQualifiers(Quals, nullptr);
+    manglePointerExtQualifiers(Quals, /*PointeeType=*/nullptr);
     mangleRefQualifier(Proto->getRefQualifier());
-    mangleQualifiers(Quals, false);
+    mangleQualifiers(Quals, /*IsMember=*/false);
   }
 
   mangleCallingConvention(T);
index 1b892864c65ee5efddd7a1a3a94a5cfb8c86910c..ff1692d01951feb156ee83e5a474ae5f1b2c9875 100644 (file)
@@ -1,5 +1,58 @@
 // RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
 
+namespace FTypeWithQuals {
+template <typename T>
+struct S {};
+
+using A = int () const;
+S<A> a;
+// CHECK-DAG: @"\01?a@FTypeWithQuals@@3U?$S@$$A8@@BAHXZ@1@A"
+
+using B = int () volatile;
+S<B> b;
+// CHECK-DAG: @"\01?b@FTypeWithQuals@@3U?$S@$$A8@@CAHXZ@1@A"
+
+using C = int () __restrict;
+S<C> c;
+// CHECK-DAG: @"\01?c@FTypeWithQuals@@3U?$S@$$A8@@IAAHXZ@1@A"
+
+using D = int () const &;
+S<D> d;
+// CHECK-DAG: @"\01?d@FTypeWithQuals@@3U?$S@$$A8@@GBAHXZ@1@A"
+
+using E = int () volatile &;
+S<E> e;
+// CHECK-DAG: @"\01?e@FTypeWithQuals@@3U?$S@$$A8@@GCAHXZ@1@A"
+
+using F = int () __restrict &;
+S<F> f;
+// CHECK-DAG: @"\01?f@FTypeWithQuals@@3U?$S@$$A8@@IGAAHXZ@1@A"
+
+using G = int () const &&;
+S<G> g;
+// CHECK-DAG: @"\01?g@FTypeWithQuals@@3U?$S@$$A8@@HBAHXZ@1@A"
+
+using H = int () volatile &&;
+S<H> h;
+// CHECK-DAG: @"\01?h@FTypeWithQuals@@3U?$S@$$A8@@HCAHXZ@1@A"
+
+using I = int () __restrict &&;
+S<I> i;
+// CHECK-DAG: @"\01?i@FTypeWithQuals@@3U?$S@$$A8@@IHAAHXZ@1@A"
+
+using J = int ();
+S<J> j;
+// CHECK-DAG: @"\01?j@FTypeWithQuals@@3U?$S@$$A6AHXZ@1@A"
+
+using K = int () &;
+S<K> k;
+// CHECK-DAG: @"\01?k@FTypeWithQuals@@3U?$S@$$A8@@GAAHXZ@1@A"
+
+using L = int () &&;
+S<L> l;
+// CHECK-DAG: @"\01?l@FTypeWithQuals@@3U?$S@$$A8@@HAAHXZ@1@A"
+}
+
 // CHECK: "\01?DeducedType@@3HA"
 auto DeducedType = 30;