From 4d0e9cd03f641e6c4411a6807ae0fcde9d7dbe34 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 12 Aug 2014 17:53:10 +0000 Subject: [PATCH] MS ABI: Mangle this qualifiers on function types 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 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 | 23 ++++++++----- test/CodeGenCXX/mangle-ms-cxx11.cpp | 53 +++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 9 deletions(-) diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index bc07e3c2dc..7a159f4296 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -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) { // ::= // const FunctionProtoType *Proto = cast(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(D)) { if (MD->isInstance()) - IsInstMethod = true; + HasThisQuals = true; if (isa(MD) || isa(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); diff --git a/test/CodeGenCXX/mangle-ms-cxx11.cpp b/test/CodeGenCXX/mangle-ms-cxx11.cpp index 1b892864c6..ff1692d019 100644 --- a/test/CodeGenCXX/mangle-ms-cxx11.cpp +++ b/test/CodeGenCXX/mangle-ms-cxx11.cpp @@ -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 +struct S {}; + +using A = int () const; +S a; +// CHECK-DAG: @"\01?a@FTypeWithQuals@@3U?$S@$$A8@@BAHXZ@1@A" + +using B = int () volatile; +S b; +// CHECK-DAG: @"\01?b@FTypeWithQuals@@3U?$S@$$A8@@CAHXZ@1@A" + +using C = int () __restrict; +S c; +// CHECK-DAG: @"\01?c@FTypeWithQuals@@3U?$S@$$A8@@IAAHXZ@1@A" + +using D = int () const &; +S d; +// CHECK-DAG: @"\01?d@FTypeWithQuals@@3U?$S@$$A8@@GBAHXZ@1@A" + +using E = int () volatile &; +S e; +// CHECK-DAG: @"\01?e@FTypeWithQuals@@3U?$S@$$A8@@GCAHXZ@1@A" + +using F = int () __restrict &; +S f; +// CHECK-DAG: @"\01?f@FTypeWithQuals@@3U?$S@$$A8@@IGAAHXZ@1@A" + +using G = int () const &&; +S g; +// CHECK-DAG: @"\01?g@FTypeWithQuals@@3U?$S@$$A8@@HBAHXZ@1@A" + +using H = int () volatile &&; +S h; +// CHECK-DAG: @"\01?h@FTypeWithQuals@@3U?$S@$$A8@@HCAHXZ@1@A" + +using I = int () __restrict &&; +S i; +// CHECK-DAG: @"\01?i@FTypeWithQuals@@3U?$S@$$A8@@IHAAHXZ@1@A" + +using J = int (); +S j; +// CHECK-DAG: @"\01?j@FTypeWithQuals@@3U?$S@$$A6AHXZ@1@A" + +using K = int () &; +S k; +// CHECK-DAG: @"\01?k@FTypeWithQuals@@3U?$S@$$A8@@GAAHXZ@1@A" + +using L = int () &&; +S l; +// CHECK-DAG: @"\01?l@FTypeWithQuals@@3U?$S@$$A8@@HAAHXZ@1@A" +} + // CHECK: "\01?DeducedType@@3HA" auto DeducedType = 30; -- 2.50.1