From 108f5a274848a7e8ed375c10fc55c85d7398e1f3 Mon Sep 17 00:00:00 2001 From: Charles Davis Date: Fri, 18 Jun 2010 07:51:00 +0000 Subject: [PATCH] Mangle tag types (unions, structs, classes, enums) in the Microsoft C++ Mangler. Also, test that static members with default visibility in a struct have the right mangling. llvm-svn: 106276 --- clang/lib/CodeGen/MicrosoftCXXABI.cpp | 63 +++++++++++++++++++++++++++ clang/test/CodeGenCXX/mangle-ms.cpp | 23 ++++++++++ 2 files changed, 86 insertions(+) diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 957b0f4d6dc2..3823c9dc20a2 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -47,6 +47,7 @@ public: void mangleName(const NamedDecl *ND); void mangleFunctionEncoding(const FunctionDecl *FD); void mangleVariableEncoding(const VarDecl *VD); + void mangleNumber(int64_t Number); void mangleType(QualType T); private: @@ -67,6 +68,7 @@ private: #define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T); #include "clang/AST/TypeNodes.def" + void mangleType(const TagType*); void mangleType(const FunctionType *T, bool IsStructor); void mangleFunctionClass(const FunctionDecl *FD); void mangleCallingConvention(const FunctionType *T); @@ -285,6 +287,30 @@ void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) { Out << '@'; } +void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) { + // ::= [?] # <= 9 + // ::= [?] + @ # > 9; A = 0, B = 1, etc... + if (Number < 0) { + Out << '?'; + Number = -Number; + } + if (Number <= 9) { + Out << Number; + } else { + // We have to build up the encoding in reverse order, so it will come + // out right when we write it out. + char Encoding[16]; + char *EndPtr = Encoding+sizeof(Encoding); + char *CurPtr = EndPtr; + while (Number) { + *--CurPtr = 'A' + (Number % 16); + Number /= 16; + } + Out.write(CurPtr, EndPtr-CurPtr); + Out << '@'; + } +} + void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name) { @@ -627,6 +653,12 @@ return; case Type::Builtin: mangleType(static_cast(T.getTypePtr())); break; + case Type::Enum: + mangleType(static_cast(T.getTypePtr())); + break; + case Type::Record: + mangleType(static_cast(T.getTypePtr())); + break; default: assert(false && "Don't know how to mangle this type!"); break; @@ -850,6 +882,37 @@ void MicrosoftCXXNameMangler::mangleThrowSpecification( } } +// ::= | | | +// ::= T +// ::= U +// ::= V +// ::= W +void MicrosoftCXXNameMangler::mangleType(const EnumType *T) { + mangleType(static_cast(T)); +} +void MicrosoftCXXNameMangler::mangleType(const RecordType *T) { + mangleType(static_cast(T)); +} +void MicrosoftCXXNameMangler::mangleType(const TagType *T) { + switch (T->getDecl()->getTagKind()) { + case TTK_Union: + Out << 'T'; + break; + case TTK_Struct: + Out << 'U'; + break; + case TTK_Class: + Out << 'V'; + break; + case TTK_Enum: + Out << 'W'; + mangleNumber(getASTContext().getTypeSizeInChars( + cast(T->getDecl())->getIntegerType()).getQuantity()); + break; + } + mangleName(T->getDecl()); +} + void MicrosoftMangleContext::mangleName(const NamedDecl *D, llvm::SmallVectorImpl &Name) { assert((isa(D) || isa(D)) && diff --git a/clang/test/CodeGenCXX/mangle-ms.cpp b/clang/test/CodeGenCXX/mangle-ms.cpp index 6787b6bd34f2..a528054d8d09 100644 --- a/clang/test/CodeGenCXX/mangle-ms.cpp +++ b/clang/test/CodeGenCXX/mangle-ms.cpp @@ -6,6 +6,7 @@ // CHECK: @"\01?d@foo@@0FB" // CHECK: @"\01?e@foo@@1JC" // CHECK: @"\01?f@foo@@2DD" +// CHECK: @"\01?g@bar@@2HA" int a; @@ -24,6 +25,22 @@ public: int operator+(int a); }; +struct bar { + static int g; +}; + +union baz { + int a; + char b; + double c; +}; + +enum quux { + qone, + qtwo, + qthree +}; + int foo::operator+(int a) {return a;} // CHECK: @"\01??Hfoo@@QAAHH@Z" @@ -31,6 +48,8 @@ const short foo::d = 0; volatile long foo::e; const volatile char foo::f = 'C'; +int bar::g; + // Static functions are mangled, too. // Also make sure calling conventions, arglists, and throw specs work. static void __stdcall alpha(float a, double b) throw() {} @@ -42,3 +61,7 @@ bool __fastcall beta(long long a, wchar_t b) throw(signed char, unsigned char) { // CHECK: @"\01?alpha@@YGXMN@@" +// Make sure tag-type mangling works. +void gamma(class foo, struct bar, union baz, enum quux) {} +// CHECK: @"\01?gamma@@YAXVfoo@@Ubar@@Tbaz@@W4quux@@@Z" +