From: Charles Davis Date: Mon, 14 Jun 2010 05:29:01 +0000 (+0000) Subject: Microsoft C++ Mangler: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b021f8bd445959e2a5c958624a464ff621253ae4;p=clang Microsoft C++ Mangler: - Mangle qualifiers. - Start mangling variables' types into the name. A variable declared with a builtin type should now mangle properly. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105931 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp index 5a3f228373..e8016a93e3 100644 --- a/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/lib/CodeGen/MicrosoftCXXABI.cpp @@ -45,6 +45,7 @@ public: void mangle(const NamedDecl *D, llvm::StringRef Prefix = "?"); void mangleName(const NamedDecl *ND); + void mangleVariableEncoding(const VarDecl *VD); void mangleType(QualType T); private: @@ -54,6 +55,7 @@ private: void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name); void mangleSourceName(const IdentifierInfo *II); void manglePostfix(const DeclContext *DC, bool NoFunction=false); + void mangleQualifiers(Qualifiers Quals, bool IsMember); void mangleObjCMethodName(const ObjCMethodDecl *MD); @@ -175,7 +177,38 @@ void MicrosoftCXXNameMangler::mangle(const NamedDecl *D, // ::= ? Out << Prefix; mangleName(D); - // TODO: Mangle type. + if (const VarDecl *VD = dyn_cast(D)) + mangleVariableEncoding(VD); + // TODO: Function types. +} + +void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) { + // ::= + // ::= 0 # private static member + // ::= 1 # protected static member + // ::= 2 # public static member + // ::= 3 # global + // ::= 4 # static local + + // The first character in the encoding (after the name) is the storage class. + if (VD->isStaticDataMember()) { + // If it's a static member, it also encodes the access level. + switch (VD->getAccess()) { + default: + case AS_private: Out << '0'; break; + case AS_protected: Out << '1'; break; + case AS_public: Out << '2'; break; + } + } + else if (!VD->isStaticLocal()) + Out << '3'; + else + Out << '4'; + // Now mangle the type. + // ::= + QualType Ty = VD->getType(); + mangleType(Ty.getLocalUnqualifiedType()); + mangleQualifiers(Ty.getLocalQualifiers(), false); } void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) { @@ -313,6 +346,88 @@ void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) { Out << Buffer; } +void MicrosoftCXXNameMangler::mangleQualifiers(Qualifiers Quals, + bool IsMember) { + // ::= [E] [F] [I] + // 'E' means __ptr64 (32-bit only); 'F' means __unaligned (32/64-bit only); + // 'I' means __restrict (32/64-bit). + // Note that the MSVC __restrict keyword isn't the same as the C99 restrict + // keyword! + // ::= A # near + // ::= B # near const + // ::= C # near volatile + // ::= D # near const volatile + // ::= E # far (16-bit) + // ::= F # far const (16-bit) + // ::= G # far volatile (16-bit) + // ::= H # far const volatile (16-bit) + // ::= I # huge (16-bit) + // ::= J # huge const (16-bit) + // ::= K # huge volatile (16-bit) + // ::= L # huge const volatile (16-bit) + // ::= M # based + // ::= N # based const + // ::= O # based volatile + // ::= P # based const volatile + // ::= Q # near member + // ::= R # near const member + // ::= S # near volatile member + // ::= T # near const volatile member + // ::= U # far member (16-bit) + // ::= V # far const member (16-bit) + // ::= W # far volatile member (16-bit) + // ::= X # far const volatile member (16-bit) + // ::= Y # huge member (16-bit) + // ::= Z # huge const member (16-bit) + // ::= 0 # huge volatile member (16-bit) + // ::= 1 # huge const volatile member (16-bit) + // ::= 2 # based member + // ::= 3 # based const member + // ::= 4 # based volatile member + // ::= 5 # based const volatile member + // ::= 6 # near function (pointers only) + // ::= 7 # far function (pointers only) + // ::= 8 # near method (pointers only) + // ::= 9 # far method (pointers only) + // ::= _A # based function (pointers only) + // ::= _B # based function (far?) (pointers only) + // ::= _C # based method (pointers only) + // ::= _D # based method (far?) (pointers only) + // ::= 0 # __based(void) + // ::= 1 # __based(segment)? + // ::= 2 # __based(name) + // ::= 3 # ? + // ::= 4 # ? + // ::= 5 # not really based + if (!IsMember) { + if (!Quals.hasVolatile()) { + if (!Quals.hasConst()) + Out << 'A'; + else + Out << 'B'; + } else { + if (!Quals.hasConst()) + Out << 'C'; + else + Out << 'D'; + } + } else { + if (!Quals.hasVolatile()) { + if (!Quals.hasConst()) + Out << 'Q'; + else + Out << 'R'; + } else { + if (!Quals.hasConst()) + Out << 'S'; + else + Out << 'T'; + } + } + + // FIXME: For now, just drop all extension qualifiers on the floor. +} + void MicrosoftCXXNameMangler::mangleType(QualType T) { // Only operate on the canonical type! T = getASTContext().getCanonicalType(T); diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp index de482085ba..9748c107aa 100644 --- a/test/CodeGenCXX/mangle-ms.cpp +++ b/test/CodeGenCXX/mangle-ms.cpp @@ -1,8 +1,11 @@ // RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-apple-darwin10 | FileCheck %s -// CHECK: @"\01?a@@" -// CHECK: @"\01?b@N@@" +// CHECK: @"\01?a@@3HA" +// CHECK: @"\01?b@N@@3HA" // CHECK: @c +// CHECK: @"\01?d@foo@@0FB" +// CHECK: @"\01?e@foo@@1JC" +// CHECK: @"\01?f@foo@@2DD" int a; @@ -11,3 +14,15 @@ namespace N { int b; } static int c; int _c(void) {return c;} +class foo { + static const short d; +protected: + static volatile long e; +public: + static const volatile char f; +}; + +const short foo::d = 0; +volatile long foo::e; +const volatile char foo::f = 'C'; +