X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMangler.cpp;h=49efe75d79d8f02e51df9aad34c7af69042d3cb0;hb=867fe8570f299a058f155f98646d85cabc27155b;hp=826f950c4a45f4e019b8813cc06f11fc7696c353;hpb=acd03ae6791fc0fb9f1b05247a1dc082b46b8d8b;p=oota-llvm.git diff --git a/lib/Target/Mangler.cpp b/lib/Target/Mangler.cpp index 826f950c4a4..49efe75d79d 100644 --- a/lib/Target/Mangler.cpp +++ b/lib/Target/Mangler.cpp @@ -12,17 +12,22 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/Mangler.h" -#include "llvm/GlobalValue.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Function.h" +#include "llvm/Target/TargetData.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" using namespace llvm; -static bool isAcceptableChar(char C) { +static bool isAcceptableChar(char C, bool AllowPeriod) { if ((C < 'a' || C > 'z') && (C < 'A' || C > 'Z') && (C < '0' || C > '9') && - C != '_' && C != '$' && C != '.' && C != '@') + C != '_' && C != '$' && C != '@' && + !(AllowPeriod && C == '.')) return false; return true; } @@ -50,26 +55,27 @@ static bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) { // If any of the characters in the string is an unacceptable character, force // quotes. + bool AllowPeriod = MAI.doesAllowPeriodsInName(); for (unsigned i = 0, e = Str.size(); i != e; ++i) - if (!isAcceptableChar(Str[i])) + if (!isAcceptableChar(Str[i], AllowPeriod)) return true; return false; } /// appendMangledName - Add the specified string in mangled form if it uses /// any unusual characters. -void Mangler::appendMangledName(SmallVectorImpl &OutName, StringRef Str, - const MCAsmInfo *MAI) { +static void appendMangledName(SmallVectorImpl &OutName, StringRef Str, + const MCAsmInfo &MAI) { // The first character is not allowed to be a number unless the target // explicitly allows it. - if ((MAI == 0 || !MAI->doesAllowNameToStartWithDigit()) && - Str[0] >= '0' && Str[0] <= '9') { + if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9') { MangleLetter(OutName, Str[0]); Str = Str.substr(1); } - + + bool AllowPeriod = MAI.doesAllowPeriodsInName(); for (unsigned i = 0, e = Str.size(); i != e; ++i) { - if (!isAcceptableChar(Str[i])) + if (!isAcceptableChar(Str[i], AllowPeriod)) MangleLetter(OutName, Str[i]); else OutName.push_back(Str[i]); @@ -100,6 +106,8 @@ void Mangler::getNameWithPrefix(SmallVectorImpl &OutName, StringRef Name = GVName.toStringRef(TmpData); assert(!Name.empty() && "getNameWithPrefix requires non-empty name"); + const MCAsmInfo &MAI = Context.getAsmInfo(); + // If the global name is not led with \1, add the appropriate prefixes. if (Name[0] == '\1') { Name = Name.substr(1); @@ -134,7 +142,7 @@ void Mangler::getNameWithPrefix(SmallVectorImpl &OutName, // On systems that do not allow quoted names, we need to mangle most // strange characters. if (!MAI.doesAllowQuotesInName()) - return appendMangledName(OutName, Name, &MAI); + return appendMangledName(OutName, Name, MAI); // Okay, the system allows quoted strings. We can quote most anything, the // only characters that need escaping are " and \n. @@ -142,6 +150,26 @@ void Mangler::getNameWithPrefix(SmallVectorImpl &OutName, return appendMangledQuotedName(OutName, Name); } +/// AddFastCallStdCallSuffix - Microsoft fastcall and stdcall functions require +/// a suffix on their name indicating the number of words of arguments they +/// take. +static void AddFastCallStdCallSuffix(SmallVectorImpl &OutName, + const Function *F, const TargetData &TD) { + // Calculate arguments size total. + unsigned ArgWords = 0; + for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); + AI != AE; ++AI) { + const Type *Ty = AI->getType(); + // 'Dereference' type in case of byval parameter attribute + if (AI->hasByValAttr()) + Ty = cast(Ty)->getElementType(); + // Size should be aligned to DWORD boundary + ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4; + } + + raw_svector_ostream(OutName) << '@' << ArgWords; +} + /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix /// and the specified global variable's name. If the global variable doesn't @@ -152,20 +180,48 @@ void Mangler::getNameWithPrefix(SmallVectorImpl &OutName, ManglerPrefixTy PrefixTy = Mangler::Default; if (GV->hasPrivateLinkage() || isImplicitlyPrivate) PrefixTy = Mangler::Private; - else if (GV->hasLinkerPrivateLinkage()) + else if (GV->hasLinkerPrivateLinkage() || GV->hasLinkerPrivateWeakLinkage() || + GV->hasLinkerPrivateWeakDefAutoLinkage()) PrefixTy = Mangler::LinkerPrivate; // If this global has a name, handle it simply. - if (GV->hasName()) - return getNameWithPrefix(OutName, GV->getName(), PrefixTy); + if (GV->hasName()) { + getNameWithPrefix(OutName, GV->getName(), PrefixTy); + } else { + // Get the ID for the global, assigning a new one if we haven't got one + // already. + unsigned &ID = AnonGlobalIDs[GV]; + if (ID == 0) ID = NextAnonGlobalID++; - // Get the ID for the global, assigning a new one if we haven't got one - // already. - unsigned &ID = AnonGlobalIDs[GV]; - if (ID == 0) ID = NextAnonGlobalID++; + // Must mangle the global into a unique ID. + getNameWithPrefix(OutName, "__unnamed_" + Twine(ID), PrefixTy); + } - // Must mangle the global into a unique ID. - getNameWithPrefix(OutName, "__unnamed_" + Twine(ID), PrefixTy); + // If we are supposed to add a microsoft-style suffix for stdcall/fastcall, + // add it. + if (Context.getAsmInfo().hasMicrosoftFastStdCallMangling()) { + if (const Function *F = dyn_cast(GV)) { + CallingConv::ID CC = F->getCallingConv(); + + // fastcall functions need to start with @. + // FIXME: This logic seems unlikely to be right. + if (CC == CallingConv::X86_FastCall) { + if (OutName[0] == '_') + OutName[0] = '@'; + else + OutName.insert(OutName.begin(), '@'); + } + + // fastcall and stdcall functions usually need @42 at the end to specify + // the argument info. + const FunctionType *FT = F->getFunctionType(); + if ((CC == CallingConv::X86_FastCall || CC == CallingConv::X86_StdCall) && + // "Pure" variadic functions do not receive @0 suffix. + (!FT->isVarArg() || FT->getNumParams() == 0 || + (FT->getNumParams() == 1 && F->hasStructRetAttr()))) + AddFastCallStdCallSuffix(OutName, F, TD); + } + } } /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix @@ -177,3 +233,13 @@ std::string Mangler::getNameWithPrefix(const GlobalValue *GV, getNameWithPrefix(Buf, GV, isImplicitlyPrivate); return std::string(Buf.begin(), Buf.end()); } + +/// getSymbol - Return the MCSymbol for the specified global value. This +/// symbol is the main label that is the address of the global. +MCSymbol *Mangler::getSymbol(const GlobalValue *GV) { + SmallString<60> NameStr; + getNameWithPrefix(NameStr, GV, false); + return Context.GetOrCreateSymbol(NameStr.str()); +} + +