AST: Implement mangling support for function types without a prototype.

Function types without prototypes can arise when mangling a function type
within an overloadable function in C. We mangle these as the absence of
any parameter types (not even an empty parameter list).

Differential Revision: http://reviews.llvm.org/D11848

llvm-svn: 244374
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 5c2b68c..a5f75ec 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1620,7 +1620,8 @@
 }
 void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T,
                                          Qualifiers, SourceRange) {
-  llvm_unreachable("Can't mangle K&R function prototypes");
+  Out << "$$A6";
+  mangleFunctionType(T);
 }
 
 void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
@@ -1628,7 +1629,7 @@
                                                  bool ForceThisQuals) {
   // <function-type> ::= <this-cvr-qualifiers> <calling-convention>
   //                     <return-type> <argument-list> <throw-spec>
-  const FunctionProtoType *Proto = cast<FunctionProtoType>(T);
+  const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(T);
 
   SourceRange Range;
   if (D) Range = D->getSourceRange();
@@ -1699,7 +1700,7 @@
     }
     Out << '@';
   } else {
-    QualType ResultType = Proto->getReturnType();
+    QualType ResultType = T->getReturnType();
     if (const auto *AT =
             dyn_cast_or_null<AutoType>(ResultType->getContainedAutoType())) {
       Out << '?';
@@ -1717,7 +1718,12 @@
   // <argument-list> ::= X # void
   //                 ::= <type>+ @
   //                 ::= <type>* Z # varargs
-  if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
+  if (!Proto) {
+    // Function types without prototypes can arise when mangling a function type
+    // within an overloadable function in C. We mangle these as the absence of
+    // any parameter types (not even an empty parameter list).
+    Out << '@';
+  } else if (Proto->getNumParams() == 0 && !Proto->isVariadic()) {
     Out << 'X';
   } else {
     // Happens for function pointer type arguments for example.