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

Peter Collingbourne via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 7 16:25:47 PDT 2015


Author: pcc
Date: Fri Aug  7 18:25:47 2015
New Revision: 244374

URL: http://llvm.org/viewvc/llvm-project?rev=244374&view=rev
Log:
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

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

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=244374&r1=244373&r2=244374&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Fri Aug  7 18:25:47 2015
@@ -2055,9 +2055,23 @@ void CXXNameMangler::mangleType(const Fu
 
   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.

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=244374&r1=244373&r2=244374&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Fri Aug  7 18:25:47 2015
@@ -1620,7 +1620,8 @@ void MicrosoftCXXNameMangler::mangleType
 }
 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 @@ void MicrosoftCXXNameMangler::mangleFunc
                                                  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 @@ void MicrosoftCXXNameMangler::mangleFunc
     }
     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 @@ void MicrosoftCXXNameMangler::mangleFunc
   // <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.

Added: cfe/trunk/test/CodeGen/mangle-ms.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/mangle-ms.c?rev=244374&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/mangle-ms.c (added)
+++ cfe/trunk/test/CodeGen/mangle-ms.c Fri Aug  7 18:25:47 2015
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s
+
+// CHECK: define void @"\01?f@@$$J0YAXP6AX at Z@Z"
+__attribute__((overloadable)) void f(void (*x)()) {}

Modified: cfe/trunk/test/CodeGen/overloadable.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/overloadable.c?rev=244374&r1=244373&r2=244374&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/overloadable.c (original)
+++ cfe/trunk/test/CodeGen/overloadable.c Fri Aug  7 18:25:47 2015
@@ -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(st
 
 void __attribute__((overloadable)) f(int x, int y, ...) { }
 
+void __attribute__((overloadable)) f(void (*x)()) {}
+
 int main() {
   int iv = 17;
   float fv = 3.0f;




More information about the cfe-commits mailing list