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
This commit is contained in:
Peter Collingbourne 2015-08-07 23:25:47 +00:00
parent 0f51d14957
commit eeebc41b58
4 changed files with 32 additions and 5 deletions

View File

@ -2055,9 +2055,23 @@ void CXXNameMangler::mangleType(const FunctionProtoType *T) {
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.

View File

@ -1620,7 +1620,8 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T, Qualifiers,
}
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::mangleFunctionType(const FunctionType *T,
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::mangleFunctionType(const FunctionType *T,
}
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::mangleFunctionType(const FunctionType *T,
// <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.

View File

@ -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)()) {}

View File

@ -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(struct X (*ptr)[10]) { }
void __attribute__((overloadable)) f(int x, int y, ...) { }
void __attribute__((overloadable)) f(void (*x)()) {}
int main() {
int iv = 17;
float fv = 3.0f;