X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FMangler.cpp;h=575141aed85bdf1f74d9283607a278375fd325bc;hb=9f52e1da3c6a6e798733704b0acf6920d00eb3d2;hp=faa4c8fe71ee0ee39e253e2a16f168a57fbea38b;hpb=b56c57bcbb8b87dca05a18c284155fa75285470b;p=oota-llvm.git diff --git a/lib/IR/Mangler.cpp b/lib/IR/Mangler.cpp index faa4c8fe71e..575141aed85 100644 --- a/lib/IR/Mangler.cpp +++ b/lib/IR/Mangler.cpp @@ -17,113 +17,131 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" -#include "llvm/MC/MCContext.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; -/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix -/// and the specified name as the global variable name. GVName must not be -/// empty. -void Mangler::getNameWithPrefix(SmallVectorImpl &OutName, - const Twine &GVName, ManglerPrefixTy PrefixTy) { +static void getNameWithPrefixx(raw_ostream &OS, const Twine &GVName, + Mangler::ManglerPrefixTy PrefixTy, + const DataLayout &DL, bool UseAt) { SmallString<256> TmpData; StringRef Name = GVName.toStringRef(TmpData); assert(!Name.empty() && "getNameWithPrefix requires non-empty name"); - // If the global name is not led with \1, add the appropriate prefixes. + // No need to do anything special if the global has the special "do not + // mangle" flag in the name. if (Name[0] == '\1') { - Name = Name.substr(1); - } else { - if (PrefixTy == Mangler::Private) { - const char *Prefix = DL->getPrivateGlobalPrefix(); - OutName.append(Prefix, Prefix+strlen(Prefix)); - } else if (PrefixTy == Mangler::LinkerPrivate) { - const char *Prefix = DL->getLinkerPrivateGlobalPrefix(); - OutName.append(Prefix, Prefix+strlen(Prefix)); - } + OS << Name.substr(1); + return; + } - char Prefix = DL->getGlobalPrefix(); + if (PrefixTy == Mangler::Private) + OS << DL.getPrivateGlobalPrefix(); + else if (PrefixTy == Mangler::LinkerPrivate) + OS << DL.getLinkerPrivateGlobalPrefix(); + + if (UseAt) { + OS << '@'; + } else { + char Prefix = DL.getGlobalPrefix(); if (Prefix != '\0') - OutName.push_back(Prefix); + OS << Prefix; } // If this is a simple string that doesn't need escaping, just append it. - OutName.append(Name.begin(), Name.end()); + OS << Name; +} + +void Mangler::getNameWithPrefix(raw_ostream &OS, const Twine &GVName, + ManglerPrefixTy PrefixTy) const { + return getNameWithPrefixx(OS, GVName, PrefixTy, *DL, false); +} + +void Mangler::getNameWithPrefix(SmallVectorImpl &OutName, + const Twine &GVName, + ManglerPrefixTy PrefixTy) const { + raw_svector_ostream OS(OutName); + return getNameWithPrefix(OS, GVName, PrefixTy); } /// 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 DataLayout &TD) { +static void AddFastCallStdCallSuffix(raw_ostream &OS, const Function *F, + const DataLayout &TD) { // Calculate arguments size total. unsigned ArgWords = 0; for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI) { + // Skip arguments in registers to handle typical fastcall lowering. + if (F->getAttributes().hasAttribute(AI->getArgNo() + 1, Attribute::InReg)) + continue; Type *Ty = AI->getType(); - // 'Dereference' type in case of byval parameter attribute - if (AI->hasByValAttr()) + // 'Dereference' type in case of byval or inalloca parameter attribute. + if (AI->hasByValOrInAllocaAttr()) Ty = cast(Ty)->getElementType(); // Size should be aligned to DWORD boundary ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4; } - - raw_svector_ostream(OutName) << '@' << ArgWords; -} + OS << '@' << ArgWords; +} -/// 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. -void Mangler::getNameWithPrefix(SmallVectorImpl &OutName, - const GlobalValue *GV) { +void Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV, + bool CannotUsePrivateLabel) const { ManglerPrefixTy PrefixTy = Mangler::Default; - if (GV->hasPrivateLinkage()) - PrefixTy = Mangler::Private; - else if (GV->hasLinkerPrivateLinkage() || GV->hasLinkerPrivateWeakLinkage()) - PrefixTy = Mangler::LinkerPrivate; - - // If this global has a name, handle it simply. - if (GV->hasName()) { - StringRef Name = GV->getName(); - getNameWithPrefix(OutName, Name, PrefixTy); - // No need to do anything else if the global has the special "do not mangle" - // flag in the name. - if (Name[0] == 1) - return; - } else { + if (GV->hasPrivateLinkage()) { + if (CannotUsePrivateLabel) + PrefixTy = Mangler::LinkerPrivate; + else + PrefixTy = Mangler::Private; + } + + if (!GV->hasName()) { // 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++; - + if (ID == 0) + ID = NextAnonGlobalID++; + // Must mangle the global into a unique ID. - getNameWithPrefix(OutName, "__unnamed_" + Twine(ID), PrefixTy); + getNameWithPrefix(OS, "__unnamed_" + Twine(ID), PrefixTy); + return; } - // If we are supposed to add a microsoft-style suffix for stdcall/fastcall, - // add it. - if (DL->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. - 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, *DL); + StringRef Name = GV->getName(); + + bool UseAt = false; + const Function *MSFunc = nullptr; + CallingConv::ID CC; + if (Name[0] != '\1' && DL->hasMicrosoftFastStdCallMangling()) { + if ((MSFunc = dyn_cast(GV))) { + CC = MSFunc->getCallingConv(); + // fastcall functions need to start with @ instead of _. + if (CC == CallingConv::X86_FastCall) + UseAt = true; } } + + getNameWithPrefixx(OS, Name, PrefixTy, *DL, UseAt); + + if (!MSFunc) + return; + + // If we are supposed to add a microsoft-style suffix for stdcall/fastcall, + // add it. + // fastcall and stdcall functions usually need @42 at the end to specify + // the argument info. + FunctionType *FT = MSFunc->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 && MSFunc->hasStructRetAttr()))) + AddFastCallStdCallSuffix(OS, MSFunc, *DL); +} + +void Mangler::getNameWithPrefix(SmallVectorImpl &OutName, + const GlobalValue *GV, + bool CannotUsePrivateLabel) const { + raw_svector_ostream OS(OutName); + getNameWithPrefix(OS, GV, CannotUsePrivateLabel); }