[MS ABI] Improve our mangling of pass_object_size

We didn't add the artificial pass_object_size arguments to the
backreference map which bloated the size of manglings which involved
pass_object_size with duplicate types.

This lets us go from:
?qux@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@0W4__pass_object_size1@3@@Z

to:
?qux@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@01@Z

llvm-svn: 256622
This commit is contained in:
David Majnemer 2015-12-30 05:13:03 +00:00
parent d57bcda1cb
commit 5f177620c3
2 changed files with 34 additions and 4 deletions

View File

@ -224,6 +224,9 @@ class MicrosoftCXXNameMangler {
typedef llvm::DenseMap<void *, unsigned> ArgBackRefMap;
ArgBackRefMap TypeBackReferences;
typedef std::set<int> PassObjectSizeArgsSet;
PassObjectSizeArgsSet PassObjectSizeArgs;
ASTContext &getASTContext() const { return Context.getASTContext(); }
// FIXME: If we add support for __ptr32/64 qualifiers, then we should push
@ -293,6 +296,7 @@ private:
void mangleObjCMethodName(const ObjCMethodDecl *MD);
void mangleArgumentType(QualType T, SourceRange Range);
void manglePassObjectSizeArg(const PassObjectSizeAttr *POSA);
// Declare manglers for every type class.
#define ABSTRACT_TYPE(CLASS, PARENT)
@ -1083,8 +1087,10 @@ void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
// Templates have their own context for back references.
ArgBackRefMap OuterArgsContext;
BackRefVec OuterTemplateContext;
PassObjectSizeArgsSet OuterPassObjectSizeArgs;
NameBackReferences.swap(OuterTemplateContext);
TypeBackReferences.swap(OuterArgsContext);
PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
mangleUnscopedTemplateName(TD);
mangleTemplateArgs(TD, TemplateArgs);
@ -1092,6 +1098,7 @@ void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
// Restore the previous back reference contexts.
NameBackReferences.swap(OuterTemplateContext);
TypeBackReferences.swap(OuterArgsContext);
PassObjectSizeArgs.swap(OuterPassObjectSizeArgs);
}
void
@ -1477,6 +1484,27 @@ void MicrosoftCXXNameMangler::mangleArgumentType(QualType T,
}
}
void MicrosoftCXXNameMangler::manglePassObjectSizeArg(
const PassObjectSizeAttr *POSA) {
int Type = POSA->getType();
auto Iter = PassObjectSizeArgs.insert(Type).first;
void *TypePtr = (void *)&*Iter;
ArgBackRefMap::iterator Found = TypeBackReferences.find(TypePtr);
if (Found == TypeBackReferences.end()) {
mangleArtificalTagType(TTK_Enum, "__pass_object_size" + llvm::utostr(Type),
{"__clang"});
if (TypeBackReferences.size() < 10) {
size_t Size = TypeBackReferences.size();
TypeBackReferences[TypePtr] = Size;
}
} else {
Out << Found->second;
}
}
void MicrosoftCXXNameMangler::mangleType(QualType T, SourceRange Range,
QualifierMangleMode QMM) {
// Don't use the canonical types. MSVC includes things like 'const' on
@ -1879,10 +1907,8 @@ void MicrosoftCXXNameMangler::mangleFunctionType(const FunctionType *T,
// necessary to just cross our fingers and hope this type+namespace
// combination doesn't conflict with anything?
if (D)
if (auto *P = D->getParamDecl(I)->getAttr<PassObjectSizeAttr>())
mangleArtificalTagType(TTK_Enum, "__pass_object_size" +
llvm::utostr(P->getType()),
{"__clang"});
if (const auto *P = D->getParamDecl(I)->getAttr<PassObjectSizeAttr>())
manglePassObjectSizeArg(P);
}
// <builtin-type> ::= Z # ellipsis
if (Proto->isVariadic())

View File

@ -440,6 +440,10 @@ namespace PassObjectSize {
int foo(int *const i __attribute__((pass_object_size(0)))) { return 0; }
// CHECK-DAG: define i32 @"\01?bar@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@@Z"
int bar(int *const i __attribute__((pass_object_size(1)))) { return 0; }
// CHECK-DAG: define i32 @"\01?qux@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@0W4__pass_object_size0@3@@Z"
int qux(int *const i __attribute__((pass_object_size(1))), int *const j __attribute__((pass_object_size(0)))) { return 0; }
// CHECK-DAG: define i32 @"\01?zot@PassObjectSize@@YAHQAHW4__pass_object_size1@__clang@@01@Z"
int zot(int *const i __attribute__((pass_object_size(1))), int *const j __attribute__((pass_object_size(1)))) { return 0; }
}
namespace Atomic {