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:
// 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) {
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);
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);
// 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;