From 7dacc95299399ba41de26fbd1e848e2557956a68 Mon Sep 17 00:00:00 2001 From: Charles Davis Date: Sat, 12 Jun 2010 08:11:16 +0000 Subject: [PATCH] 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 --- clang/lib/CodeGen/MicrosoftCXXABI.cpp | 111 +++++++++++++++++++++++++- clang/test/CodeGenCXX/mangle-ms.cpp | 10 ++- 2 files changed, 118 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 012ef23c1c4f..5a3f2283733b 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -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(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(T.getTypePtr())); + break; + default: + assert(false && "Don't know how to mangle this type!"); + break; + } +} + +void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T) { + // ::= + // ::= 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 # + // ::= 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 # + // ::= _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 &Name) { assert((isa(D) || isa(D)) && diff --git a/clang/test/CodeGenCXX/mangle-ms.cpp b/clang/test/CodeGenCXX/mangle-ms.cpp index 68640ca2924f..de482085ba1f 100644 --- a/clang/test/CodeGenCXX/mangle-ms.cpp +++ b/clang/test/CodeGenCXX/mangle-ms.cpp @@ -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;} +