Microsoft C++ Mangler:

- Don't mangle static variables at global scope.
- Add support for mangling builtin types. This will be used later.

llvm-svn: 105881
This commit is contained in:
Charles Davis 2010-06-12 08:11:16 +00:00
parent 8075c85230
commit 7dacc95299
2 changed files with 118 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 mangleType(QualType T);
private:
void mangleUnqualifiedName(const NamedDecl *ND) {
@ -56,6 +57,12 @@ private:
void mangleObjCMethodName(const ObjCMethodDecl *MD);
// Declare manglers for every type class.
#define ABSTRACT_TYPE(CLASS, PARENT)
#define NON_CANONICAL_TYPE(CLASS, PARENT)
#define TYPE(CLASS, PARENT) void mangleType(const CLASS##Type *T);
#include "clang/AST/TypeNodes.def"
};
/// MicrosoftMangleContext - Overrides the default MangleContext for the
@ -109,7 +116,7 @@ static bool isInCLinkageSpecification(const Decl *D) {
if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC))
return Linkage->getLanguage() == LinkageSpecDecl::lang_c;
}
return false;
}
@ -135,6 +142,13 @@ bool MicrosoftMangleContext::shouldMangleDeclName(const NamedDecl *D) {
if (!getASTContext().getLangOptions().CPlusPlus)
return false;
// Variables at global scope with internal linkage are not mangled.
if (!FD) {
const DeclContext *DC = D->getDeclContext();
if (DC->isTranslationUnit() && D->getLinkage() == InternalLinkage)
return false;
}
// C functions and "main" are not mangled.
if ((FD && FD->isMain()) || isInCLinkageSpecification(D))
return false;
@ -299,6 +313,101 @@ void MicrosoftCXXNameMangler::mangleObjCMethodName(const ObjCMethodDecl *MD) {
Out << Buffer;
}
void MicrosoftCXXNameMangler::mangleType(QualType T) {
// Only operate on the canonical type!
T = getASTContext().getCanonicalType(T);
switch (T->getTypeClass()) {
#define ABSTRACT_TYPE(CLASS, PARENT)
#define NON_CANONICAL_TYPE(CLASS, PARENT) \
case Type::CLASS: \
llvm_unreachable("can't mangle non-canonical type " #CLASS "Type"); \
return;
#define TYPE(CLASS, PARENT)
#include "clang/AST/TypeNodes.def"
case Type::Builtin:
mangleType(static_cast<BuiltinType *>(T.getTypePtr()));
break;
default:
assert(false && "Don't know how to mangle this type!");
break;
}
}
void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T) {
// <type> ::= <builtin-type>
// <builtin-type> ::= X # void
// ::= C # signed char
// ::= D # char
// ::= E # unsigned char
// ::= F # short
// ::= G # unsigned short (or wchar_t if it's not a builtin)
// ::= H # int
// ::= I # unsigned int
// ::= J # long
// ::= K # unsigned long
// L # <none>
// ::= M # float
// ::= N # double
// ::= O # long double (__float80 is mangled differently)
// ::= _D # __int8 (yup, it's a distinct type in MSVC)
// ::= _E # unsigned __int8
// ::= _F # __int16
// ::= _G # unsigned __int16
// ::= _H # __int32
// ::= _I # unsigned __int32
// ::= _J # long long, __int64
// ::= _K # unsigned long long, __int64
// ::= _L # __int128
// ::= _M # unsigned __int128
// ::= _N # bool
// _O # <array in parameter>
// ::= _T # __float80 (Intel)
// ::= _W # wchar_t
// ::= _Z # __float80 (Digital Mars)
switch (T->getKind()) {
case BuiltinType::Void: Out << 'X'; break;
case BuiltinType::SChar: Out << 'C'; break;
case BuiltinType::Char_U: case BuiltinType::Char_S: Out << 'D'; break;
case BuiltinType::UChar: Out << 'E'; break;
case BuiltinType::Short: Out << 'F'; break;
case BuiltinType::UShort: Out << 'G'; break;
case BuiltinType::Int: Out << 'H'; break;
case BuiltinType::UInt: Out << 'I'; break;
case BuiltinType::Long: Out << 'J'; break;
case BuiltinType::ULong: Out << 'K'; break;
case BuiltinType::Float: Out << 'M'; break;
case BuiltinType::Double: Out << 'N'; break;
// TODO: Determine size and mangle accordingly
case BuiltinType::LongDouble: Out << 'O'; break;
// TODO: __int8 and friends
case BuiltinType::LongLong: Out << "_J"; break;
case BuiltinType::ULongLong: Out << "_K"; break;
case BuiltinType::Int128: Out << "_L"; break;
case BuiltinType::UInt128: Out << "_M"; break;
case BuiltinType::Bool: Out << "_N"; break;
case BuiltinType::WChar: Out << "_W"; break;
case BuiltinType::Overload:
case BuiltinType::Dependent:
assert(false &&
"Overloaded and dependent types shouldn't get to name mangling");
break;
case BuiltinType::UndeducedAuto:
assert(0 && "Should not see undeduced auto here");
break;
case BuiltinType::ObjCId: Out << "PAUobjc_object@@"; break;
case BuiltinType::ObjCClass: Out << "PAUobjc_class@@"; break;
case BuiltinType::ObjCSel: Out << "PAUobjc_selector@@"; break;
case BuiltinType::Char16:
case BuiltinType::Char32:
case BuiltinType::NullPtr:
assert(false && "Don't know how to mangle this type");
break;
}
}
void MicrosoftMangleContext::mangleName(const NamedDecl *D,
llvm::SmallVectorImpl<char> &Name) {
assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&

View File

@ -1,7 +1,13 @@
// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-apple-darwin10 | FileCheck %s
int a;
// CHECK: @"\01?a@@"
// CHECK: @"\01?b@N@@"
// CHECK: @c
int a;
namespace N { int b; }
// CHECK: @"\01?b@N@@"
static int c;
int _c(void) {return c;}