]> granicus.if.org Git - clang/commitdiff
MS ABI: Add support for mangling __restrict
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 18 Feb 2014 12:58:35 +0000 (12:58 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 18 Feb 2014 12:58:35 +0000 (12:58 +0000)
Pointer types in the MSVC ABI are a bit awkward, the width of the
pointer is considered a kind of CVR qualifier.

Restrict is handled similarly to const and volatile but is mangled after
the pointer width qualifier.

This fixes PR18880.

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

lib/AST/MicrosoftMangle.cpp
lib/AST/Type.cpp
test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp
test/CodeGenCXX/mangle-ms.cpp

index a8a09a7e60420615d8a23edad32ae10fe3fcf96f..90df22347e9210ee65a16ebd764f73f2d742b7e9 100644 (file)
@@ -145,7 +145,7 @@ private:
   void mangleOperatorName(OverloadedOperatorKind OO, SourceLocation Loc);
   void mangleCXXDtorType(CXXDtorType T);
   void mangleQualifiers(Qualifiers Quals, bool IsMember);
-  void manglePointerQualifiers(Qualifiers Quals);
+  void manglePointerQualifiers(Qualifiers Quals, const Type *PointeeType);
 
   void mangleUnscopedTemplateName(const TemplateDecl *ND);
   void mangleTemplateInstantiationName(const TemplateDecl *TD,
@@ -1213,13 +1213,16 @@ void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
   // FIXME: For now, just drop all extension qualifiers on the floor.
 }
 
-void MicrosoftCXXNameMangler::manglePointerQualifiers(Qualifiers Quals) {
+void MicrosoftCXXNameMangler::manglePointerQualifiers(Qualifiers Quals,
+                                                      const Type *PointeeType) {
   // <pointer-cvr-qualifiers> ::= P  # no qualifiers
   //                          ::= Q  # const
   //                          ::= R  # volatile
   //                          ::= S  # const volatile
   bool HasConst = Quals.hasConst(),
-       HasVolatile = Quals.hasVolatile();
+       HasVolatile = Quals.hasVolatile(),
+       HasRestrict = Quals.hasRestrict();
+
   if (HasConst && HasVolatile) {
     Out << 'S';
   } else if (HasVolatile) {
@@ -1229,6 +1232,12 @@ void MicrosoftCXXNameMangler::manglePointerQualifiers(Qualifiers Quals) {
   } else {
     Out << 'P';
   }
+
+  if (PointersAre64Bit && PointeeType && !PointeeType->isFunctionType())
+    Out << 'E';
+
+  if (HasRestrict)
+    Out << 'I';
 }
 
 void MicrosoftCXXNameMangler::mangleArgumentType(QualType T,
@@ -1320,7 +1329,7 @@ void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
 
   // We have to mangle these now, while we still have enough information.
   if (IsPointer)
-    manglePointerQualifiers(Quals);
+    manglePointerQualifiers(Quals, T->getPointeeType().getTypePtr());
   const Type *ty = T.getTypePtr();
 
   switch (ty->getTypeClass()) {
@@ -1656,7 +1665,7 @@ void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
 void MicrosoftCXXNameMangler::mangleDecayedArrayType(const ArrayType *T) {
   // This isn't a recursive mangling, so now we have to do it all in this
   // one call.
-  manglePointerQualifiers(T->getElementType().getQualifiers());
+  manglePointerQualifiers(T->getElementType().getQualifiers(), 0);
   mangleType(T->getElementType(), SourceRange());
 }
 void MicrosoftCXXNameMangler::mangleType(const ConstantArrayType *T,
@@ -1728,8 +1737,6 @@ void MicrosoftCXXNameMangler::mangleType(const MemberPointerType *T,
     mangleName(T->getClass()->castAs<RecordType>()->getDecl());
     mangleFunctionType(FPT, 0, true);
   } else {
-    if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
-      Out << 'E';
     mangleQualifiers(PointeeType.getQualifiers(), true);
     mangleName(T->getClass()->castAs<RecordType>()->getDecl());
     mangleType(PointeeType, Range, QMM_Drop);
@@ -1761,8 +1768,6 @@ void MicrosoftCXXNameMangler::mangleType(
 void MicrosoftCXXNameMangler::mangleType(const PointerType *T,
                                          SourceRange Range) {
   QualType PointeeTy = T->getPointeeType();
-  if (PointersAre64Bit && !T->getPointeeType()->isFunctionType())
-    Out << 'E';
   mangleType(PointeeTy, Range);
 }
 void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,
index 26534d7b437b8608e08f9501d84ac8b629b75435..cebdbad4fc961af7ffb09fa70fdcda346c43be00 100644 (file)
@@ -422,6 +422,10 @@ QualType Type::getPointeeType() const {
     return BPT->getPointeeType();
   if (const ReferenceType *RT = getAs<ReferenceType>())
     return RT->getPointeeType();
+  if (const MemberPointerType *MPT = getAs<MemberPointerType>())
+    return MPT->getPointeeType();
+  if (const DecayedType *DT = getAs<DecayedType>())
+    return DT->getPointeeType();
   return QualType();
 }
 
index 58f24d5f14c1ff2c77c3f92fbff981414643c024..fae2e1ab2dfa493dd92b2442bc53144f515ad56f 100644 (file)
@@ -37,6 +37,22 @@ void foo_sad(char * const volatile x) {}
 // CHECK: "\01?foo_sad@@YAXSAD@Z"
 // X64: "\01?foo_sad@@YAXSEAD@Z"
 
+void foo_piad(char * __restrict x) {}
+// CHECK: "\01?foo_piad@@YAXPIAD@Z"
+// X64: "\01?foo_piad@@YAXPEIAD@Z"
+
+void foo_qiad(char * const __restrict x) {}
+// CHECK: "\01?foo_qiad@@YAXQIAD@Z"
+// X64: "\01?foo_qiad@@YAXQEIAD@Z"
+
+void foo_riad(char * volatile __restrict x) {}
+// CHECK: "\01?foo_riad@@YAXRIAD@Z"
+// X64: "\01?foo_riad@@YAXREIAD@Z"
+
+void foo_siad(char * const volatile __restrict x) {}
+// CHECK: "\01?foo_siad@@YAXSIAD@Z"
+// X64: "\01?foo_siad@@YAXSEIAD@Z"
+
 void foo_papad(char ** x) {}
 // CHECK: "\01?foo_papad@@YAXPAPAD@Z"
 // X64: "\01?foo_papad@@YAXPEAPEAD@Z"
@@ -238,3 +254,7 @@ void mangle_yes_backref2(fun_type *const[], ptr_to_fun_type const[]) {}
 void mangle_yes_backref3(ptr_to_fun_type *const, void (**const)(void)) {}
 // CHECK: "\01?mangle_yes_backref3@@YAXQAP6AXXZ0@Z"
 // X64:   "\01?mangle_yes_backref3@@YAXQEAP6AXXZ0@Z"
+
+void mangle_yes_backref4(int *const __restrict, int *const __restrict) {}
+// CHECK: "\01?mangle_yes_backref4@@YAXQIAH0@Z"
+// X64:   "\01?mangle_yes_backref4@@YAXQEIAH0@Z"
index 2b0457f0d01520e863712e61b56e79cf928aaa0d..7207ad9a52be0510c03949b51c0fd64a66e2af03 100644 (file)
@@ -99,6 +99,11 @@ extern const int * const h2 = &a;
 int i[10][20];
 // CHECK-DAG: @"\01?i@@3PAY0BE@HA"
 
+typedef int (*FunT)(int, int);
+FunT FunArr[10][20];
+// CHECK-DAG: @"\01?FunArr@@3PAY0BE@P6AHHH@ZA"
+// X64-DAG: @"\01?FunArr@@3PAY0BE@P6AHHH@ZA"
+
 int (__stdcall *j)(signed char, unsigned char);
 // CHECK-DAG: @"\01?j@@3P6GHCE@ZA"