Fix mangling of array parameters for functions in the Microsoft C++ Mangler.

Only actual functions get mangled correctly; I don't know how to fix it for
function pointers yet. Thanks to John McCall for the hint.

Also, mangle anonymous tag types. I don't have a suitable testcase yet; I have
a feeling that that's going to need support for static locals, and I haven't
figured out exactly how MSVC's scheme for mangling those works.

llvm-svn: 107561
This commit is contained in:
Charles Davis 2010-07-03 02:41:45 +00:00
parent ca99012ac0
commit 77552766d9
2 changed files with 22 additions and 11 deletions

View File

@ -69,7 +69,8 @@ private:
#include "clang/AST/TypeNodes.def" #include "clang/AST/TypeNodes.def"
void mangleType(const TagType*); void mangleType(const TagType*);
void mangleType(const FunctionType *T, bool IsStructor, bool IsInstMethod); void mangleType(const FunctionType *T, const FunctionDecl *D,
bool IsStructor, bool IsInstMethod);
void mangleType(const ArrayType *T, bool IsGlobal); void mangleType(const ArrayType *T, bool IsGlobal);
void mangleExtraDimensions(QualType T); void mangleExtraDimensions(QualType T);
void mangleFunctionClass(const FunctionDecl *FD); void mangleFunctionClass(const FunctionDecl *FD);
@ -218,7 +219,7 @@ void MicrosoftCXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
// First, the function class. // First, the function class.
mangleFunctionClass(FD); mangleFunctionClass(FD);
mangleType(FT, InStructor, InInstMethod); mangleType(FT, FD, InStructor, InInstMethod);
} }
void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) { void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
@ -339,8 +340,9 @@ MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
break; break;
} }
// TODO: How does VC mangle anonymous structs? // When VC encounters an anonymous type with no tag and no typedef,
assert(false && "Don't know how to mangle anonymous types yet!"); // it literally emits '<unnamed-tag>'.
Out << "<unnamed-tag>";
break; break;
} }
@ -756,13 +758,14 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionProtoType *T) {
// structor type. // structor type.
// I'll probably have mangleType(MemberPointerType) call the mangleType() // I'll probably have mangleType(MemberPointerType) call the mangleType()
// method directly. // method directly.
mangleType(T, false, false); mangleType(T, NULL, false, false);
} }
void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T) { void MicrosoftCXXNameMangler::mangleType(const FunctionNoProtoType *T) {
llvm_unreachable("Can't mangle K&R function prototypes"); llvm_unreachable("Can't mangle K&R function prototypes");
} }
void MicrosoftCXXNameMangler::mangleType(const FunctionType *T, void MicrosoftCXXNameMangler::mangleType(const FunctionType *T,
const FunctionDecl *D,
bool IsStructor, bool IsStructor,
bool IsInstMethod) { bool IsInstMethod) {
// <function-type> ::= <this-cvr-qualifiers> <calling-convention> // <function-type> ::= <this-cvr-qualifiers> <calling-convention>
@ -789,11 +792,19 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionType *T,
if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) { if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {
Out << 'X'; Out << 'X';
} else { } else {
for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(), if (D) {
ArgEnd = Proto->arg_type_end(); // If we got a decl, use the "types-as-written" to make sure arrays
Arg != ArgEnd; ++Arg) // get mangled right.
mangleType(*Arg); for (FunctionDecl::param_const_iterator Parm = D->param_begin(),
ParmEnd = D->param_end();
Parm != ParmEnd; ++Parm)
mangleType((*Parm)->getTypeSourceInfo()->getType());
} else {
for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
ArgEnd = Proto->arg_type_end();
Arg != ArgEnd; ++Arg)
mangleType(*Arg);
}
// <builtin-type> ::= Z # ellipsis // <builtin-type> ::= Z # ellipsis
if (Proto->isVariadic()) if (Proto->isVariadic())
Out << 'Z'; Out << 'Z';

View File

@ -80,4 +80,4 @@ void delta(int * const a, const long &) {}
// Array mangling. (It should be mangled as a const pointer, but that needs // Array mangling. (It should be mangled as a const pointer, but that needs
// to be fixed in Sema.) // to be fixed in Sema.)
void epsilon(int a[][10][20]) {} void epsilon(int a[][10][20]) {}
// CHECK: @"\01?epsilon@@YAXPAY19BD@H@Z" // CHECK: @"\01?epsilon@@YAXQAY19BD@H@Z"