forked from OSchip/llvm-project
[Windows] Fix mangling of repeated types in the presence of bool and function pointers PR13176,PR13177
llvm-svn: 159059
This commit is contained in:
parent
a3088f09b3
commit
9137c399bd
|
@ -31,8 +31,8 @@ class MicrosoftCXXNameMangler {
|
|||
MangleContext &Context;
|
||||
raw_ostream &Out;
|
||||
|
||||
typedef llvm::DenseMap<const IdentifierInfo*, unsigned> BackRefMap;
|
||||
BackRefMap BackReferences;
|
||||
typedef llvm::DenseMap<void*, unsigned> BackRefMap;
|
||||
BackRefMap NameBackReferences, TypeBackReferences;
|
||||
|
||||
ASTContext &getASTContext() const { return Context.getASTContext(); }
|
||||
|
||||
|
@ -66,6 +66,8 @@ private:
|
|||
void mangleObjCMethodName(const ObjCMethodDecl *MD);
|
||||
void mangleLocalName(const FunctionDecl *FD);
|
||||
|
||||
void mangleTypeRepeated(QualType T, SourceRange Range);
|
||||
|
||||
// Declare manglers for every type class.
|
||||
#define ABSTRACT_TYPE(CLASS, PARENT)
|
||||
#define NON_CANONICAL_TYPE(CLASS, PARENT)
|
||||
|
@ -644,12 +646,12 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
|
|||
|
||||
void MicrosoftCXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
|
||||
// <source name> ::= <identifier> @
|
||||
BackRefMap::iterator Found = BackReferences.find(II);
|
||||
if (Found == BackReferences.end()) {
|
||||
BackRefMap::iterator Found = NameBackReferences.find((void*)II);
|
||||
if (Found == NameBackReferences.end()) {
|
||||
Out << II->getName() << '@';
|
||||
if (BackReferences.size() < 10) {
|
||||
size_t Size = BackReferences.size();
|
||||
BackReferences[II] = Size;
|
||||
if (NameBackReferences.size() < 10) {
|
||||
size_t Size = NameBackReferences.size();
|
||||
NameBackReferences[(void*)II] = Size;
|
||||
}
|
||||
} else {
|
||||
Out << Found->second;
|
||||
|
@ -852,6 +854,28 @@ void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals,
|
|||
// FIXME: For now, just drop all extension qualifiers on the floor.
|
||||
}
|
||||
|
||||
void MicrosoftCXXNameMangler::mangleTypeRepeated(QualType T, SourceRange Range) {
|
||||
void *TypePtr = getASTContext().getCanonicalType(T).getAsOpaquePtr();
|
||||
BackRefMap::iterator Found = TypeBackReferences.find(TypePtr);
|
||||
|
||||
if (Found == TypeBackReferences.end()) {
|
||||
size_t OutSizeBefore = Out.GetNumBytesInBuffer();
|
||||
|
||||
mangleType(T,Range);
|
||||
|
||||
// See if it's worth creating a back reference.
|
||||
// Only types longer than 1 character are considered
|
||||
// and only 10 back references slots are available:
|
||||
bool LongerThanOneChar = (Out.GetNumBytesInBuffer() - OutSizeBefore > 1);
|
||||
if (LongerThanOneChar && TypeBackReferences.size() < 10) {
|
||||
size_t Size = TypeBackReferences.size();
|
||||
TypeBackReferences[TypePtr] = Size;
|
||||
}
|
||||
} else {
|
||||
Out << Found->second;
|
||||
}
|
||||
}
|
||||
|
||||
void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range) {
|
||||
// Only operate on the canonical type!
|
||||
T = getASTContext().getCanonicalType(T);
|
||||
|
@ -1026,8 +1050,6 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionType *T,
|
|||
if (Proto->getNumArgs() == 0 && !Proto->isVariadic()) {
|
||||
Out << 'X';
|
||||
} else {
|
||||
typedef llvm::DenseMap<void*, unsigned> BackRef;
|
||||
BackRef BackReferences;
|
||||
if (D) {
|
||||
// If we got a decl, use the type-as-written to make sure arrays
|
||||
// get mangled right. Note that we can't rely on the TSI
|
||||
|
@ -1036,24 +1058,14 @@ void MicrosoftCXXNameMangler::mangleType(const FunctionType *T,
|
|||
ParmEnd = D->param_end(); Parm != ParmEnd; ++Parm) {
|
||||
TypeSourceInfo *TSI = (*Parm)->getTypeSourceInfo();
|
||||
QualType Type = TSI ? TSI->getType() : (*Parm)->getType();
|
||||
CanQualType Canonical = getASTContext().getCanonicalType(Type);
|
||||
void *TypePtr = Canonical.getAsOpaquePtr();
|
||||
BackRef::iterator Found = BackReferences.find(TypePtr);
|
||||
if (Found == BackReferences.end()) {
|
||||
mangleType(Type, (*Parm)->getSourceRange());
|
||||
if (BackReferences.size() < 10 && (Canonical->getTypeClass() != Type::Builtin)) {
|
||||
size_t Size = BackReferences.size();
|
||||
BackReferences[TypePtr] = Size;
|
||||
}
|
||||
} else {
|
||||
Out << Found->second;
|
||||
}
|
||||
mangleTypeRepeated(Type, (*Parm)->getSourceRange());
|
||||
}
|
||||
} else {
|
||||
// Happens for function pointer type arguments for example.
|
||||
for (FunctionProtoType::arg_type_iterator Arg = Proto->arg_type_begin(),
|
||||
ArgEnd = Proto->arg_type_end();
|
||||
Arg != ArgEnd; ++Arg)
|
||||
mangleType(*Arg, SourceRange());
|
||||
mangleTypeRepeated(*Arg, SourceRange());
|
||||
}
|
||||
// <builtin-type> ::= Z # ellipsis
|
||||
if (Proto->isVariadic())
|
||||
|
|
|
@ -12,17 +12,35 @@ void f3(int a, const char* b, const char* c) {}
|
|||
const char *f4(const char* a, const char* b) {}
|
||||
// CHECK: "\01?f4@@YAPBDPBD0@Z"
|
||||
|
||||
void f5(char const* a, unsigned int b, char c, void const* d, char const* e, unsigned int f) {}
|
||||
// CHECK: "\01?f5@@YAXPBDIDPBX0I@Z"
|
||||
|
||||
void f6(bool a, bool b) {}
|
||||
// CHECK: "\01?f6@@YAX_N0@Z"
|
||||
|
||||
void f7(int a, int* b, int c, int* d, bool e, bool f, bool* g) {}
|
||||
// CHECK: "\01?f7@@YAXHPAHH0_N1PA_N@Z"
|
||||
|
||||
// FIXME: tests for more than 10 types?
|
||||
|
||||
struct S {};
|
||||
struct S {
|
||||
void mbb(bool a, bool b) {}
|
||||
};
|
||||
|
||||
void g4(const char* a, struct S* b, const char *c, struct S* d) {}
|
||||
void g1(struct S a) {}
|
||||
// CHECK: "\01?g1@@YAXUS@@@Z"
|
||||
|
||||
void g2(struct S a, struct S b) {}
|
||||
// CHECK: "\01?g2@@YAXUS@@0@Z"
|
||||
|
||||
void g3(struct S a, struct S b, struct S* c, struct S* d) {}
|
||||
// CHECK: "\01?g3@@YAXUS@@0PAU1@1@Z"
|
||||
|
||||
void g4(const char* a, struct S* b, const char* c, struct S* d) {
|
||||
// CHECK: "\01?g4@@YAXPBDPAUS@@01@Z"
|
||||
|
||||
typedef void (*VoidFunc)();
|
||||
|
||||
void foo_ptr(const char* a, const char* b, VoidFunc c, VoidFunc d) {}
|
||||
// CHECK: @"\01?foo_ptr@@YAXPBD0P6AXXZ1@Z"
|
||||
b->mbb(false, false);
|
||||
// CHECK: "\01?mbb@S@@QAEX_N0@Z"
|
||||
}
|
||||
|
||||
// Make sure that different aliases of built-in types end up mangled as the
|
||||
// built-ins.
|
||||
|
@ -30,3 +48,16 @@ typedef unsigned int uintptr_t;
|
|||
typedef unsigned int size_t;
|
||||
void *h(size_t a, uintptr_t b) {}
|
||||
// CHECK: "\01?h@@YAPAXII@Z"
|
||||
|
||||
// Function pointers might be mangled in a complex way.
|
||||
typedef void (*VoidFunc)();
|
||||
typedef int* (*PInt3Func)(int* a, int* b);
|
||||
|
||||
void h1(const char* a, const char* b, VoidFunc c, VoidFunc d) {}
|
||||
// CHECK: "\01?h1@@YAXPBD0P6AXXZ1@Z"
|
||||
|
||||
void h2(void (*f_ptr)(void *), void *arg) {}
|
||||
// CHECK: "\01?h2@@YAXP6AXPAX@Z0@Z"
|
||||
|
||||
PInt3Func h3(PInt3Func x, PInt3Func y, int* z) { return 0; }
|
||||
// CHECK: "\01?h3@@YAP6APAHPAH0@ZP6APAH00@Z10@Z"
|
||||
|
|
Loading…
Reference in New Issue