r205282 - MS ABI: Support mangling of return-types deducing to local types

David Majnemer david.majnemer at gmail.com
Mon Mar 31 22:29:47 PDT 2014


Author: majnemer
Date: Tue Apr  1 00:29:46 2014
New Revision: 205282

URL: http://llvm.org/viewvc/llvm-project?rev=205282&view=rev
Log:
MS ABI: Support mangling of return-types deducing to local types

The MS ABI forces us into catch-22 when it comes to functions which
return types which are local:

 - A function is mangled with it's return type.
 - A type is mangled with it's surrounding context.

Avoid this by mangling auto and decltype(autp) directly into the
function's return type.  Using this mangling has the double advantage of
being compatible with the C++ standard without crashing the compiler.

N.B. For the curious, the MSVC mangling leads to collisions amongst
template functions and either crashes when faced with local types or is
otherwise incapable of returning them.

Modified:
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/test/CodeGenCXX/mangle-ms-cxx14.cpp

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=205282&r1=205281&r2=205282&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Tue Apr  1 00:29:46 2014
@@ -1545,9 +1545,18 @@ void MicrosoftCXXNameMangler::mangleFunc
     Out << '@';
   } else {
     QualType ResultType = Proto->getReturnType();
-    if (ResultType->isVoidType())
-      ResultType = ResultType.getUnqualifiedType();
-    mangleType(ResultType, Range, QMM_Result);
+    if (const auto *AT =
+            dyn_cast_or_null<AutoType>(ResultType->getContainedAutoType())) {
+      Out << '?';
+      mangleQualifiers(ResultType.getLocalQualifiers(), /*IsMember=*/false);
+      Out << '?';
+      mangleSourceName(AT->isDecltypeAuto() ? "<decltype-auto>" : "<auto>");
+      Out << '@';
+    } else {
+      if (ResultType->isVoidType())
+        ResultType = ResultType.getUnqualifiedType();
+      mangleType(ResultType, Range, QMM_Result);
+    }
   }
 
   // <argument-list> ::= X # void

Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-cxx14.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-cxx14.cpp?rev=205282&r1=205281&r2=205282&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/mangle-ms-cxx14.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/mangle-ms-cxx14.cpp Tue Apr  1 00:29:46 2014
@@ -6,3 +6,35 @@ template <typename> int x = 0;
 template <> int x<void>;
 // CHECK: "\01??$x at H@@3HA"
 template <> int x<int>;
+
+// CHECK: "\01?FunctionWithLocalType@@YA?A?<auto>@@XZ"
+auto FunctionWithLocalType() {
+  struct LocalType {};
+  return LocalType{};
+}
+
+// CHECK: "\01?ValueFromFunctionWithLocalType@@3ULocalType@?0??FunctionWithLocalType@@YA?A?<auto>@@XZ at A"
+auto ValueFromFunctionWithLocalType = FunctionWithLocalType();
+
+// CHECK: "\01??R<lambda_0>@@QBE?A?<auto>@@XZ"
+auto LambdaWithLocalType = [] {
+  struct LocalType {};
+  return LocalType{};
+};
+
+// CHECK: "\01?ValueFromLambdaWithLocalType@@3ULocalType@?0???R<lambda_0>@@QBE?A?<auto>@@XZ at A"
+auto ValueFromLambdaWithLocalType = LambdaWithLocalType();
+
+template <typename T>
+auto TemplateFuncionWithLocalLambda(T) {
+  auto LocalLambdaWithLocalType = []() {
+    struct LocalType {};
+    return LocalType{};
+  };
+  return LocalLambdaWithLocalType();
+}
+
+// CHECK: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z@QBA?A?3 at XZ@A"
+// CHECK: "\01??$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z"
+// CHECK: "\01??R<lambda_1>@??$TemplateFuncionWithLocalLambda at H@@YA?A?<auto>@@H at Z@QBA?A?1 at XZ"
+auto ValueFromTemplateFuncionWithLocalLambda = TemplateFuncionWithLocalLambda(0);





More information about the cfe-commits mailing list