This revision was automatically updated to reflect the committed changes.
Closed by commit rL244374: AST: Implement mangling support for function types 
without a prototype. (authored by pcc).

Changed prior to commit:
  http://reviews.llvm.org/D11848?vs=31546&id=31557#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D11848

Files:
  cfe/trunk/lib/AST/ItaniumMangle.cpp
  cfe/trunk/lib/AST/MicrosoftMangle.cpp
  cfe/trunk/test/CodeGen/mangle-ms.c
  cfe/trunk/test/CodeGen/overloadable.c

Index: cfe/trunk/lib/AST/ItaniumMangle.cpp
===================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp
@@ -2055,9 +2055,23 @@
 
   Out << 'E';
 }
+
 void CXXNameMangler::mangleType(const FunctionNoProtoType *T) {
-  llvm_unreachable("Can't mangle K&R function prototypes");
+  // 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 << 'F';
+
+  FunctionTypeDepthState saved = FunctionTypeDepth.push();
+
+  FunctionTypeDepth.enterResultType();
+  mangleType(T->getReturnType());
+  FunctionTypeDepth.leaveResultType();
+
+  FunctionTypeDepth.pop(saved);
+  Out << 'E';
 }
+
 void CXXNameMangler::mangleBareFunctionType(const FunctionType *T,
                                             bool MangleReturnType) {
   // We should never be mangling something without a prototype.
Index: cfe/trunk/lib/AST/MicrosoftMangle.cpp
===================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp
@@ -1620,15 +1620,16 @@
 }
 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,
                                                  const FunctionDecl *D,
                                                  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.
Index: cfe/trunk/test/CodeGen/mangle-ms.c
===================================================================
--- cfe/trunk/test/CodeGen/mangle-ms.c
+++ cfe/trunk/test/CodeGen/mangle-ms.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s
+
+// CHECK: define void @"\01?f@@$$J0YAXP6AX@Z@Z"
+__attribute__((overloadable)) void f(void (*x)()) {}
Index: cfe/trunk/test/CodeGen/overloadable.c
===================================================================
--- cfe/trunk/test/CodeGen/overloadable.c
+++ cfe/trunk/test/CodeGen/overloadable.c
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
 // CHECK: _Z1fPA10_1X
+// CHECK: _Z1fPFvE
 
 int __attribute__((overloadable)) f(int x) { return x; }
 float __attribute__((overloadable)) f(float x) { return x; }
@@ -13,6 +14,8 @@
 
 void __attribute__((overloadable)) f(int x, int y, ...) { }
 
+void __attribute__((overloadable)) f(void (*x)()) {}
+
 int main() {
   int iv = 17;
   float fv = 3.0f;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to