summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2018-07-23 20:04:00 +0000
committerNico Weber <nicolasweber@gmx.de>2018-07-23 20:04:00 +0000
commit3239f13a0671cc2f00b2b4fc06c156849369636f (patch)
treef61a7912d3bc753a85980b1a4b09a52d3544417c
parent384b317c677c4f5f895fe5b43046adc6f3be65b8 (diff)
downloadbcm5719-llvm-3239f13a0671cc2f00b2b4fc06c156849369636f.tar.gz
bcm5719-llvm-3239f13a0671cc2f00b2b4fc06c156849369636f.zip
[ms] Fix mangling of vector types in QMM_Result contexts.
If QMM_Result is set (which it is for return types, RTTI descriptors, and exception type descriptors), tag types (structs, enums, classes, unions) get their qualifiers mangled in. __m64 and friends is a struct/union thingy in MSVC, but not in clang's headers. To make mangling work, we call mangleArtificalTagType(TTK_Union/TTK_Struct for the vector types to mangle them as tag types -- but the isa<TagType> check when mangling in QMM_Result mode isn't true for these vector types. Add an isArtificialTagType() function and check for that too. Fixes PR37276 and some other issues. I tried to audit all references to TagDecl and TagType in MicrosoftMangle.cpp to find other places where we need to call mangleArtificalTagType(), but couldn't find any. I tried to audit all calls to mangleArtificalTagType() to see if isArtificialTagType() needs to handle more than just the vector types, but as far as I can tell all other types we use it for are types that MSVC can't handle at all (Objective-C types etc). https://reviews.llvm.org/D49597 llvm-svn: 337732
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp26
-rw-r--r--clang/test/CodeGenCXX/mangle-ms-vector-types.cpp63
2 files changed, 87 insertions, 2 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index f9cd24ce9ab..e45f9f7902e 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -337,6 +337,8 @@ private:
void mangleArgumentType(QualType T, SourceRange Range);
void manglePassObjectSizeArg(const PassObjectSizeAttr *POSA);
+ bool isArtificialTagType(QualType T) const;
+
// Declare manglers for every type class.
#define ABSTRACT_TYPE(CLASS, PARENT)
#define NON_CANONICAL_TYPE(CLASS, PARENT)
@@ -1751,7 +1753,7 @@ void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
Quals.removeUnaligned();
if (Quals.hasObjCLifetime())
Quals = Quals.withoutObjCLifetime();
- if ((!IsPointer && Quals) || isa<TagType>(T)) {
+ if ((!IsPointer && Quals) || isa<TagType>(T) || isArtificialTagType(T)) {
Out << '?';
mangleQualifiers(Quals, false);
}
@@ -2280,6 +2282,8 @@ void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
mangleTagTypeKind(TD->getTagKind());
mangleName(TD);
}
+
+// If you add a call to this, consider updating isArtificialTagType() too.
void MicrosoftCXXNameMangler::mangleArtificalTagType(
TagTypeKind TK, StringRef UnqualifiedName, ArrayRef<StringRef> NestedNames) {
// <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
@@ -2468,6 +2472,26 @@ void MicrosoftCXXNameMangler::mangleType(const ComplexType *T, Qualifiers,
mangleArtificalTagType(TTK_Struct, TemplateMangling, {"__clang"});
}
+// Returns true for types that mangleArtificalTagType() gets called for with
+// TTK_Union, TTK_Struct, TTK_Class and where compatibility with MSVC's
+// mangling matters.
+// (It doesn't matter for Objective-C types and the like that cl.exe doesn't
+// support.)
+bool MicrosoftCXXNameMangler::isArtificialTagType(QualType T) const {
+ const Type *ty = T.getTypePtr();
+ switch (ty->getTypeClass()) {
+ default:
+ return false;
+
+ case Type::Vector: {
+ // For ABI compatibility only __m64, __m128(id), and __m256(id) matter,
+ // but since mangleType(VectorType*) always calls mangleArtificalTagType()
+ // just always return true (the other vector types are clang-only).
+ return true;
+ }
+ }
+}
+
void MicrosoftCXXNameMangler::mangleType(const VectorType *T, Qualifiers Quals,
SourceRange Range) {
const BuiltinType *ET = T->getElementType()->getAs<BuiltinType>();
diff --git a/clang/test/CodeGenCXX/mangle-ms-vector-types.cpp b/clang/test/CodeGenCXX/mangle-ms-vector-types.cpp
index 5b676284a87..f55713e6c0c 100644
--- a/clang/test/CodeGenCXX/mangle-ms-vector-types.cpp
+++ b/clang/test/CodeGenCXX/mangle-ms-vector-types.cpp
@@ -1,30 +1,91 @@
-// RUN: %clang_cc1 -fms-extensions -ffreestanding -target-feature +avx -emit-llvm %s -o - -triple=i686-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -fcxx-exceptions -ffreestanding -target-feature +avx -emit-llvm %s -o - -triple=i686-pc-win32 | FileCheck %s
#include <xmmintrin.h>
#include <emmintrin.h>
#include <immintrin.h>
+void thow(int i) {
+ switch (i) {
+ case 0: throw __m64();
+ // CHECK: ??_R0?AT__m64@@@8
+ // CHECK: _CT??_R0?AT__m64@@@88
+ // CHECK: _CTA1?AT__m64@@
+ // CHECK: _TI1?AT__m64@@
+ case 1: throw __m128();
+ // CHECK: ??_R0?AT__m128@@@8
+ // CHECK: _CT??_R0?AT__m128@@@816
+ // CHECK: _CTA1?AT__m128@@
+ // CHECK: _TI1?AT__m128@@
+ case 2: throw __m128d();
+ // CHECK: ??_R0?AU__m128d@@@8
+ // CHECK: _CT??_R0?AU__m128d@@@816
+ // CHECK: _CTA1?AU__m128d@@
+ // CHECK: _TI1?AU__m128d@@
+ case 3: throw __m128i();
+ // CHECK: ??_R0?AT__m128i@@@8
+ // CHECK: _CT??_R0?AT__m128i@@@816
+ // CHECK: _CTA1?AT__m128i@@
+ // CHECK: _TI1?AT__m128i@@
+ case 4: throw __m256();
+ // CHECK: ??_R0?AT__m256@@@8
+ // CHECK: _CT??_R0?AT__m256@@@832
+ // CHECK: _CTA1?AT__m256@@
+ // CHECK: _TI1?AT__m256@@
+ case 5: throw __m256d();
+ // CHECK: ??_R0?AU__m256d@@@8
+ // CHECK: _CT??_R0?AU__m256d@@@832
+ // CHECK: _CTA1?AU__m256d@@
+ // CHECK: _TI1?AU__m256d@@
+ case 6: throw __m256i();
+ // CHECK: ??_R0?AT__m256@@@8
+ // CHECK: _CT??_R0?AT__m256@@@832
+ // CHECK: _CTA1?AT__m256@@
+ // CHECK: _TI1?AT__m256@@
+ }
+}
+
void foo64(__m64) {}
// CHECK: define dso_local void @"?foo64@@YAXT__m64@@@Z"
+__m64 rfoo64() { return __m64(); }
+// CHECK: define dso_local <1 x i64> @"?rfoo64@@YA?AT__m64@@XZ"
+
void foo128(__m128) {}
// CHECK: define dso_local void @"?foo128@@YAXT__m128@@@Z"
+const __m128 rfoo128() { return __m128(); }
+// CHECK: define dso_local <4 x float> @"?rfoo128@@YA?BT__m128@@XZ"
+
void foo128d(__m128d) {}
// CHECK: define dso_local void @"?foo128d@@YAXU__m128d@@@Z"
+volatile __m128d rfoo128d() { return __m128d(); }
+// CHECK: define dso_local <2 x double> @"?rfoo128d@@YA?CU__m128d@@XZ"
+
void foo128i(__m128i) {}
// CHECK: define dso_local void @"?foo128i@@YAXT__m128i@@@Z"
+const volatile __m128i rfoo128i() { return __m128i(); }
+// CHECK: define dso_local <2 x i64> @"?rfoo128i@@YA?DT__m128i@@XZ"
+
void foo256(__m256) {}
// CHECK: define dso_local void @"?foo256@@YAXT__m256@@@Z"
+__m256 rfoo256() { return __m256(); }
+// CHECK: define dso_local <8 x float> @"?rfoo256@@YA?AT__m256@@XZ"
+
void foo256d(__m256d) {}
// CHECK: define dso_local void @"?foo256d@@YAXU__m256d@@@Z"
+__m256d rfoo256d() { return __m256d(); }
+// CHECK: define dso_local <4 x double> @"?rfoo256d@@YA?AU__m256d@@XZ"
+
void foo256i(__m256i) {}
// CHECK: define dso_local void @"?foo256i@@YAXT__m256i@@@Z"
+__m256i rfoo256i() { return __m256i(); }
+// CHECK: define dso_local <4 x i64> @"?rfoo256i@@YA?AT__m256i@@XZ"
+
// We have a custom mangling for vector types not standardized by Intel.
void foov8hi(__v8hi) {}
// CHECK: define dso_local void @"?foov8hi@@YAXT?$__vector@F$07@__clang@@@Z"
OpenPOWER on IntegriCloud