X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FMangler.cpp;h=46c687b64001dfcf1ded0ca80d261b5ceb2964fb;hb=5f8fd54f0891aa47f467498454f6a3df8ae62704;hp=ef6defc58dc762a26475371c3c2f27def77ce5a0;hpb=0bd58b0e81961313828aa9ac484ab6b0d6c8d970;p=oota-llvm.git diff --git a/lib/Target/Mangler.cpp b/lib/Target/Mangler.cpp index ef6defc58dc..46c687b6400 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,8 +55,9 @@ 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; } @@ -59,17 +65,17 @@ static bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) { /// appendMangledName - Add the specified string in mangled form if it uses /// any unusual characters. static void appendMangledName(SmallVectorImpl &OutName, StringRef Str, - const MCAsmInfo *MAI) { + 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,28 +180,56 @@ 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 -/// and the specified global variable's name. If the global variable doesn't -/// have a name, this fills in a unique name for the global. -std::string Mangler::getNameWithPrefix(const GlobalValue *GV, - bool isImplicitlyPrivate) { - SmallString<64> Buf; - 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()); } + +