Skip to content

Commit

Permalink
AST: Implement mangling support for function types without a prototype.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
pcc committed Aug 7, 2015
1 parent 0f51d14 commit eeebc41
Showing 4 changed files with 32 additions and 5 deletions.
16 changes: 15 additions & 1 deletion clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
@@ -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.
14 changes: 10 additions & 4 deletions clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
@@ -1620,15 +1620,16 @@ 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,
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 @@ 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.
4 changes: 4 additions & 0 deletions clang/test/CodeGen/mangle-ms.c
Original file line number Diff line number Diff line change
@@ -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)()) {}
3 changes: 3 additions & 0 deletions clang/test/CodeGen/overloadable.c
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit eeebc41

Please sign in to comment.