[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
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index f9cd24c..e45f9f7 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -337,6 +337,8 @@
   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 @@
     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 @@
   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 @@
   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>();