Microsoft C++ Mangler:

- Mangle qualifiers.
- Start mangling variables' types into the name. A variable declared with a
  builtin type should now mangle properly.

llvm-svn: 105931
This commit is contained in:
Charles Davis 2010-06-14 05:29:01 +00:00
parent 91e1feab7a
commit 2d7b10cc97
2 changed files with 133 additions and 3 deletions

View File

@ -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,
// <mangled-name> ::= ? <name> <type>
Out << Prefix;
mangleName(D);
// TODO: Mangle type.
if (const VarDecl *VD = dyn_cast<VarDecl>(D))
mangleVariableEncoding(VD);
// TODO: Function types.
}
void MicrosoftCXXNameMangler::mangleVariableEncoding(const VarDecl *VD) {
// <encoding> ::= <variable name> <storage-class> <variable-type>
// <storage-class> ::= 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.
// <variable-type> ::= <type> <cvr-qualifiers>
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) {
// <cvr-qualifiers> ::= [E] [F] [I] <base-cvr-qualifiers>
// '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!
// <base-cvr-qualifiers> ::= 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 <basis> # based
// ::= N <basis> # based const
// ::= O <basis> # based volatile
// ::= P <basis> # 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 <basis> # based member
// ::= 3 <basis> # based const member
// ::= 4 <basis> # based volatile member
// ::= 5 <basis> # 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 <basis> # based function (pointers only)
// ::= _B <basis> # based function (far?) (pointers only)
// ::= _C <basis> # based method (pointers only)
// ::= _D <basis> # based method (far?) (pointers only)
// <basis> ::= 0 # __based(void)
// ::= 1 # __based(segment)?
// ::= 2 <name> # __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);

View File

@ -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';