diff --git lib/AST/MicrosoftMangle.cpp lib/AST/MicrosoftMangle.cpp
index d9fa057..30e6fab 100644
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -1043,8 +1043,15 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionType *T,
   else {
     QualType Result = Proto->getResultType();
     const Type* RT = Result.getTypePtr();
-    if(isa<TagType>(RT) && !RT->isAnyPointerType() && !RT->isReferenceType())
-        Out << "?A";
+    if(!RT->isAnyPointerType() && !RT->isReferenceType()) {
+       if (!Result.isConstQualified() && !Result.isVolatileQualified()) {
+         if (!RT->isBuiltinType())
+           Out << "?A";
+       } else {
+         // The B/C/D for const/volatile cases are added in mangleType.
+         Out << "?";
+       }
+    }
     // FIXME: Get the source range for the result type. Or, better yet,
     // implement the unimplemented stuff so we don't need accurate source
     // location info anymore :).
diff --git test/CodeGenCXX/mangle-ms-return-qualifiers.cpp test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
new file mode 100644
index 0000000..2ff7387
--- /dev/null
+++ test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+
+void a1() {}
+// CHECK: "\01?a1@@YAXXZ"
+
+int a2() { return 0; }
+// CHECK: "\01?a2@@YAHXZ"
+
+const int a3() { return 0; }
+// CHECK: "\01?a3@@YA?BHXZ"
+
+volatile int a4() { return 0; }
+// CHECK: "\01?a4@@YA?CHXZ"
+
+const volatile int a5() { return 0; }
+// CHECK: "\01?a5@@YA?DHXZ"
+
+float a6() { return 0.0f; }
+// CHECK: "\01?a6@@YAMXZ"
+
+int *b1() { return 0; }
+// CHECK: "\01?b1@@YAPAHXZ"
+
+float *b2() { return 0; }
+// CHECK: "\01?b2@@YAPAMXZ"
+
+const char *b3() { return 0; }
+// CHECK: "\01?b3@@YAPBDXZ"
+
+class A {};
+
+A c1() { return A(); }
+// CHECK: "\01?c1@@YA?AVA@@XZ"
+
+const A c2() { return A(); }
+// CHECK: "\01?c2@@YA?BVA@@XZ"
+
+volatile A c3() { return A(); }
+// CHECK: "\01?c3@@YA?CVA@@XZ"
+
+const volatile A c4() { return A(); }
+// CHECK: "\01?c4@@YA?DVA@@XZ"
+
+const A* c5() { return 0; }
+// CHECK: "\01?c5@@YAPBVA@@XZ"
+
+volatile A* c6() { return 0; }
+// CHECK: "\01?c6@@YAPCVA@@XZ"
+
+const volatile A* c7() { return 0; }
+// CHECK: "\01?c7@@YAPDVA@@XZ"
+
+template<typename T> class B {};
+
+B<int> d1() { return B<int>(); }
+// CHECK: "\01?d1@@YA?AV?$B@H@@XZ"
+
+B<const char*> d2() {return B<const char*>(); }
+// CHECK: "\01?d2@@YA?AV?$B@PBD@@XZ"
+
+B<A> d3() {return B<A>(); }
+// CHECK: "\01?d3@@YA?AV?$B@VA@@@@XZ"
+
+const B<A>* d4() { return 0; }
+// CHECK: "\01?d4@@YAPBV?$B@VA@@@@XZ"
+
+volatile B<A>* d5() { return 0; }
+// CHECK: "\01?d5@@YAPCV?$B@VA@@@@XZ"
+
+const volatile B<A>* d6() { return 0; }
+// CHECK: "\01?d6@@YAPDV?$B@VA@@@@XZ"
