From 4813035b726e7f0a3fd17bec437185fc72a50988 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 13 Jan 2010 06:38:18 +0000 Subject: [PATCH] change Mangler::makeNameProper to return its result in a SmallVector instead of returning it in an std::string. Based on this change: 1. Change TargetLoweringObjectFileCOFF::getCOFFSection to take a StringRef 2. Change a bunch of targets to call makeNameProper with a smallstring, making several of them *much* more efficient. 3. Rewrite Mangler::makeNameProper to not build names and then prepend prefixes, not use temporary std::strings, and to avoid other crimes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93298 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/Mangler.h | 5 +- .../llvm/Target/TargetLoweringObjectFile.h | 2 +- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 13 +- lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp | 25 ++-- .../AsmPrinter/BlackfinAsmPrinter.cpp | 8 +- lib/Target/CBackend/CBackend.cpp | 20 ++- .../PowerPC/AsmPrinter/PPCAsmPrinter.cpp | 24 ++-- lib/Target/TargetLoweringObjectFile.cpp | 24 ++-- lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp | 56 ++++---- lib/VMCore/Mangler.cpp | 125 ++++++++++-------- 10 files changed, 170 insertions(+), 132 deletions(-) diff --git a/include/llvm/Support/Mangler.h b/include/llvm/Support/Mangler.h index 3fe88c1126a..1467d672abf 100644 --- a/include/llvm/Support/Mangler.h +++ b/include/llvm/Support/Mangler.h @@ -112,8 +112,9 @@ public: /// does this for you, so there's no point calling it on the result /// from getValueName. /// - std::string makeNameProper(const Twine &Name, - ManglerPrefixTy PrefixTy = Mangler::Default); + void makeNameProper(SmallVectorImpl &OutName, + const Twine &Name, + ManglerPrefixTy PrefixTy = Mangler::Default); /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix /// and the specified global variable's name. If the global variable doesn't diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h index 9a641914af6..3dd747175b4 100644 --- a/include/llvm/Target/TargetLoweringObjectFile.h +++ b/include/llvm/Target/TargetLoweringObjectFile.h @@ -352,7 +352,7 @@ public: /// getCOFFSection - Return the MCSection for the specified COFF section. /// FIXME: Switch this to a semantic view eventually. - const MCSection *getCOFFSection(const char *Name, bool isDirective, + const MCSection *getCOFFSection(StringRef Name, bool isDirective, SectionKind K) const; }; diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 96019bf7326..b1957bb0da2 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1679,13 +1679,14 @@ MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F, // functions. std::string FuncName = Mang->getMangledName(F); - SmallString<60> Name; - raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BA" - << FuncName.size() << '_' << FuncName << '_' - << Mang->makeNameProper(BB->getName()) - << Suffix; + SmallString<60> NameResult; + raw_svector_ostream(NameResult) << MAI->getPrivateGlobalPrefix() << "BA" + << FuncName.size() << '_' << FuncName << '_'; + Mang->makeNameProper(NameResult, BB->getName()); + if (Suffix[0]) + NameResult += Suffix; - return OutContext.GetOrCreateSymbol(Name.str()); + return OutContext.GetOrCreateSymbol(NameResult.str()); } MCSymbol *AsmPrinter::GetMBBSymbol(unsigned MBBID) const { diff --git a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp index 931d8df0317..56be0ce77ec 100644 --- a/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp @@ -175,16 +175,16 @@ namespace { printDataDirective(MCPV->getType()); ARMConstantPoolValue *ACPV = static_cast(MCPV); - std::string Name; + SmallString<128> TmpNameStr; if (ACPV->isLSDA()) { - SmallString<16> LSDAName; - raw_svector_ostream(LSDAName) << MAI->getPrivateGlobalPrefix() << + raw_svector_ostream(TmpNameStr) << MAI->getPrivateGlobalPrefix() << "_LSDA_" << getFunctionNumber(); - Name = LSDAName.str(); + O << TmpNameStr.str(); } else if (ACPV->isBlockAddress()) { - Name = GetBlockAddressSymbol(ACPV->getBlockAddress())->getName(); + O << GetBlockAddressSymbol(ACPV->getBlockAddress())->getName(); } else if (ACPV->isGlobalValue()) { + std::string Name; GlobalValue *GV = ACPV->getGV(); bool isIndirect = Subtarget->isTargetDarwin() && Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel()); @@ -201,16 +201,16 @@ namespace { GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(Sym) : MMIMachO.getGVStubEntry(Sym); if (StubSym == 0) { - SmallString<128> NameStr; - Mang->getNameWithPrefix(NameStr, GV, false); - StubSym = OutContext.GetOrCreateSymbol(NameStr.str()); + Mang->getNameWithPrefix(TmpNameStr, GV, false); + StubSym = OutContext.GetOrCreateSymbol(TmpNameStr.str()); } } + O << Name; } else { assert(ACPV->isExtSymbol() && "unrecognized constant pool value"); - Name = Mang->makeNameProper(ACPV->getSymbol()); + Mang->makeNameProper(TmpNameStr, ACPV->getSymbol()); + O << TmpNameStr.str(); } - O << Name; if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")"; if (ACPV->getPCAdjustment() != 0) { @@ -392,9 +392,10 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, } case MachineOperand::MO_ExternalSymbol: { bool isCallOp = Modifier && !strcmp(Modifier, "call"); - std::string Name = Mang->makeNameProper(MO.getSymbolName()); + SmallString<128> NameStr; + Mang->makeNameProper(NameStr, MO.getSymbolName()); - O << Name; + O << NameStr.str(); if (isCallOp && Subtarget->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_) O << "(PLT)"; diff --git a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp index 917f7f54fb1..1c6f08962ba 100644 --- a/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp +++ b/lib/Target/Blackfin/AsmPrinter/BlackfinAsmPrinter.cpp @@ -31,6 +31,7 @@ #include "llvm/Target/TargetRegistry.h" #include "llvm/Support/Mangler.h" #include "llvm/ADT/Statistic.h" +#include "llvm/ADT/SmallString.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" using namespace llvm; @@ -179,9 +180,12 @@ void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum) { O << Mang->getMangledName(MO.getGlobal()); printOffset(MO.getOffset()); break; - case MachineOperand::MO_ExternalSymbol: - O << Mang->makeNameProper(MO.getSymbolName()); + case MachineOperand::MO_ExternalSymbol: { + SmallString<60> NameStr; + Mang->makeNameProper(NameStr, MO.getSymbolName()); + O << NameStr.str(); break; + } case MachineOperand::MO_ConstantPoolIndex: O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_" << MO.getIndex(); diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index ba1a377a92b..914af53c995 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -25,6 +25,7 @@ #include "llvm/IntrinsicInst.h" #include "llvm/InlineAsm.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Analysis/ConstantsScanner.h" #include "llvm/Analysis/FindUsedTypes.h" @@ -2207,12 +2208,17 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) { // If there are no type names, exit early. if (I == End) return; + SmallString<128> TempName; + // Print out forward declarations for structure types before anything else! Out << "/* Structure forward decls */\n"; for (; I != End; ++I) { - std::string Name = "struct l_" + Mang->makeNameProper(I->first); - Out << Name << ";\n"; - TypeNames.insert(std::make_pair(I->second, Name)); + const char *Prefix = "struct l_"; + TempName.append(Prefix, Prefix+strlen(Prefix)); + Mang->makeNameProper(TempName, I->first); + Out << TempName.str() << ";\n"; + TypeNames.insert(std::make_pair(I->second, TempName.str())); + TempName.clear(); } Out << '\n'; @@ -2221,10 +2227,14 @@ void CWriter::printModuleTypes(const TypeSymbolTable &TST) { // for struct or opaque types. Out << "/* Typedefs */\n"; for (I = TST.begin(); I != End; ++I) { - std::string Name = "l_" + Mang->makeNameProper(I->first); + const char *Prefix = "l_"; + TempName.append(Prefix, Prefix+strlen(Prefix)); + Mang->makeNameProper(TempName, I->first); + Out << "typedef "; - printType(Out, I->second, false, Name); + printType(Out, I->second, false, TempName.str()); Out << ";\n"; + TempName.clear(); } Out << '\n'; diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp index 358a67730af..6fff961c465 100644 --- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp @@ -49,6 +49,7 @@ #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" +#include "llvm/ADT/SmallString.h" using namespace llvm; STATISTIC(EmittedInsts, "Number of machine instrs printed"); @@ -69,15 +70,20 @@ namespace { AnonSymbol = Mang->getMangledName(GV, "$stub$tmp", true); } - void Init(const std::string &GV, Mangler *Mang) { + void Init(StringRef GVName, Mangler *Mang) { // Already initialized. if (!Stub.empty()) return; - Stub = Mang->makeNameProper(GV + "$stub", - Mangler::Private); - LazyPtr = Mang->makeNameProper(GV + "$lazy_ptr", - Mangler::Private); - AnonSymbol = Mang->makeNameProper(GV + "$stub$tmp", - Mangler::Private); + SmallString<128> TmpStr; + Mang->makeNameProper(TmpStr, GVName + "$stub", Mangler::Private); + Stub = TmpStr.str(); + TmpStr.clear(); + + Mang->makeNameProper(TmpStr, GVName + "$lazy_ptr", Mangler::Private); + LazyPtr = TmpStr.str(); + TmpStr.clear(); + + Mang->makeNameProper(TmpStr, GVName + "$stub$tmp", Mangler::Private); + AnonSymbol = TmpStr.str(); } }; @@ -230,7 +236,9 @@ namespace { } } if (MO.getType() == MachineOperand::MO_ExternalSymbol) { - FnStubInfo &FnInfo =FnStubs[Mang->makeNameProper(MO.getSymbolName())]; + SmallString<128> MangledName; + Mang->makeNameProper(MangledName, MO.getSymbolName()); + FnStubInfo &FnInfo = FnStubs[MangledName.str()]; FnInfo.Init(MO.getSymbolName(), Mang); O << FnInfo.Stub; return; diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp index 229b1d52c5e..49e266c6d7f 100644 --- a/lib/Target/TargetLoweringObjectFile.cpp +++ b/lib/Target/TargetLoweringObjectFile.cpp @@ -492,16 +492,15 @@ getELFKindForNamedSection(const char *Name, SectionKind K) { } -static unsigned -getELFSectionType(const char *Name, SectionKind K) { +static unsigned getELFSectionType(StringRef Name, SectionKind K) { - if (strcmp(Name, ".init_array") == 0) + if (Name == ".init_array") return MCSectionELF::SHT_INIT_ARRAY; - if (strcmp(Name, ".fini_array") == 0) + if (Name == ".fini_array") return MCSectionELF::SHT_FINI_ARRAY; - if (strcmp(Name, ".preinit_array") == 0) + if (Name == ".preinit_array") return MCSectionELF::SHT_PREINIT_ARRAY; if (K.isBSS() || K.isThreadBSS()) @@ -577,10 +576,12 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, // into a 'uniqued' section name, create and return the section now. if (GV->isWeakForLinker()) { const char *Prefix = getSectionPrefixForUniqueGlobal(Kind); - std::string Name = Mang->makeNameProper(GV->getNameStr()); + SmallString<128> Name; + Name.append(Prefix, Prefix+strlen(Prefix)); + Mang->makeNameProper(Name, GV->getName()); - return getELFSection((Prefix+Name).c_str(), - getELFSectionType((Prefix+Name).c_str(), Kind), + return getELFSection(Name.str(), + getELFSectionType(Name.str(), Kind), getELFSectionFlags(Kind), Kind); } @@ -983,7 +984,7 @@ TargetLoweringObjectFileCOFF::~TargetLoweringObjectFileCOFF() { const MCSection *TargetLoweringObjectFileCOFF:: -getCOFFSection(const char *Name, bool isDirective, SectionKind Kind) const { +getCOFFSection(StringRef Name, bool isDirective, SectionKind Kind) const { // Create the map if it doesn't already exist. if (UniquingMap == 0) UniquingMap = new MachOUniqueMapTy(); @@ -1078,8 +1079,9 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, // into a 'uniqued' section name, create and return the section now. if (GV->isWeakForLinker()) { const char *Prefix = getCOFFSectionPrefixForUniqueGlobal(Kind); - std::string Name = Mang->makeNameProper(GV->getNameStr()); - return getCOFFSection((Prefix+Name).c_str(), false, Kind); + SmallString<128> Name(Prefix, Prefix+strlen(Prefix)); + Mang->makeNameProper(Name, GV->getNameStr()); + return getCOFFSection(Name.str(), false, Kind); } if (Kind.isText()) diff --git a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp index b88063f9ce7..6058698ca0c 100644 --- a/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86AsmPrinter.cpp @@ -201,6 +201,7 @@ bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) { /// jump tables, constant pools, global address and external symbols, all of /// which print to a label with various suffixes for relocation types etc. void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) { + SmallString<128> TempNameStr; switch (MO.getType()) { default: llvm_unreachable("unknown symbol type!"); case MachineOperand::MO_JumpTableIndex: @@ -236,41 +237,38 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) { if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY || MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) { - SmallString<128> NameStr; - Mang->getNameWithPrefix(NameStr, GV, true); - NameStr += "$non_lazy_ptr"; - MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str()); + Mang->getNameWithPrefix(TempNameStr, GV, true); + TempNameStr += "$non_lazy_ptr"; + MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str()); const MCSymbol *&StubSym = MMI->getObjFileInfo().getGVStubEntry(Sym); if (StubSym == 0) { - NameStr.clear(); - Mang->getNameWithPrefix(NameStr, GV, false); - StubSym = OutContext.GetOrCreateSymbol(NameStr.str()); + TempNameStr.clear(); + Mang->getNameWithPrefix(TempNameStr, GV, false); + StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str()); } } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){ - SmallString<128> NameStr; - Mang->getNameWithPrefix(NameStr, GV, true); - NameStr += "$non_lazy_ptr"; - MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str()); + Mang->getNameWithPrefix(TempNameStr, GV, true); + TempNameStr += "$non_lazy_ptr"; + MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str()); const MCSymbol *&StubSym = MMI->getObjFileInfo().getHiddenGVStubEntry(Sym); if (StubSym == 0) { - NameStr.clear(); - Mang->getNameWithPrefix(NameStr, GV, false); - StubSym = OutContext.GetOrCreateSymbol(NameStr.str()); + TempNameStr.clear(); + Mang->getNameWithPrefix(TempNameStr, GV, false); + StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str()); } } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { - SmallString<128> NameStr; - Mang->getNameWithPrefix(NameStr, GV, true); - NameStr += "$stub"; - MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str()); + Mang->getNameWithPrefix(TempNameStr, GV, true); + TempNameStr += "$stub"; + MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str()); const MCSymbol *&StubSym = MMI->getObjFileInfo().getFnStubEntry(Sym); if (StubSym == 0) { - NameStr.clear(); - Mang->getNameWithPrefix(NameStr, GV, false); - StubSym = OutContext.GetOrCreateSymbol(NameStr.str()); + TempNameStr.clear(); + Mang->getNameWithPrefix(TempNameStr, GV, false); + StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str()); } } @@ -285,24 +283,24 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO) { break; } case MachineOperand::MO_ExternalSymbol: { - std::string Name = Mang->makeNameProper(MO.getSymbolName()); + Mang->makeNameProper(TempNameStr, MO.getSymbolName()); if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) { - Name += "$stub"; - MCSymbol *Sym = OutContext.GetOrCreateSymbol(StringRef(Name)); + TempNameStr += "$stub"; + MCSymbol *Sym = OutContext.GetOrCreateSymbol(TempNameStr.str()); const MCSymbol *&StubSym = MMI->getObjFileInfo().getFnStubEntry(Sym); if (StubSym == 0) { - Name.erase(Name.end()-5, Name.end()); - StubSym = OutContext.GetOrCreateSymbol(StringRef(Name)); + TempNameStr.erase(TempNameStr.end()-5, TempNameStr.end()); + StubSym = OutContext.GetOrCreateSymbol(TempNameStr.str()); } } // If the name begins with a dollar-sign, enclose it in parens. We do this // to avoid having it look like an integer immediate to the assembler. - if (Name[0] == '$') - O << '(' << Name << ')'; + if (TempNameStr[0] == '$') + O << '(' << TempNameStr << ')'; else - O << Name; + O << TempNameStr; break; } } diff --git a/lib/VMCore/Mangler.cpp b/lib/VMCore/Mangler.cpp index 5783ddfba94..da95fb93e02 100644 --- a/lib/VMCore/Mangler.cpp +++ b/lib/VMCore/Mangler.cpp @@ -24,59 +24,54 @@ static char HexDigit(int V) { return V < 10 ? V+'0' : V+'A'-10; } -static std::string MangleLetter(unsigned char C) { - char Result[] = { '_', HexDigit(C >> 4), HexDigit(C & 15), '_', 0 }; - return Result; +static void MangleLetter(SmallVectorImpl &OutName, unsigned char C) { + OutName.push_back('_'); + OutName.push_back(HexDigit(C >> 4)); + OutName.push_back(HexDigit(C & 15)); + OutName.push_back('_'); } /// makeNameProper - We don't want identifier names non-C-identifier characters /// in them, so mangle them as appropriate. /// -std::string Mangler::makeNameProper(const Twine &TheName, - ManglerPrefixTy PrefixTy) { +void Mangler::makeNameProper(SmallVectorImpl &OutName, + const Twine &TheName, + ManglerPrefixTy PrefixTy) { SmallString<256> TmpData; TheName.toVector(TmpData); StringRef X = TmpData.str(); assert(!X.empty() && "Cannot mangle empty strings"); if (!UseQuotes) { - std::string Result; - // If X does not start with (char)1, add the prefix. - bool NeedPrefix = true; StringRef::iterator I = X.begin(); if (*I == 1) { - NeedPrefix = false; - ++I; // Skip over the marker. + ++I; // Skip over the no-prefix marker. + } else { + if (PrefixTy == Mangler::Private) + OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix)); + else if (PrefixTy == Mangler::LinkerPrivate) + OutName.append(LinkerPrivatePrefix, + LinkerPrivatePrefix+strlen(LinkerPrivatePrefix)); + OutName.append(Prefix, Prefix+strlen(Prefix)); } // Mangle the first letter specially, don't allow numbers unless the target // explicitly allows them. if (!SymbolsCanStartWithDigit && *I >= '0' && *I <= '9') - Result += MangleLetter(*I++); + MangleLetter(OutName, *I++); for (StringRef::iterator E = X.end(); I != E; ++I) { if (!isCharAcceptable(*I)) - Result += MangleLetter(*I); + MangleLetter(OutName, *I); else - Result += *I; + OutName.push_back(*I); } - - if (NeedPrefix) { - Result = Prefix + Result; - - if (PrefixTy == Mangler::Private) - Result = PrivatePrefix + Result; - else if (PrefixTy == Mangler::LinkerPrivate) - Result = LinkerPrivatePrefix + Result; - } - - return Result; + return; } bool NeedPrefix = true; bool NeedQuotes = false; - std::string Result; StringRef::iterator I = X.begin(); if (*I == 1) { NeedPrefix = false; @@ -98,43 +93,57 @@ std::string Mangler::makeNameProper(const Twine &TheName, // In the common case, we don't need quotes. Handle this quickly. if (!NeedQuotes) { - if (!NeedPrefix) - return X.substr(1); // Strip off the \001. - - Result = Prefix + X.str(); + if (!NeedPrefix) { + OutName.append(X.begin()+1, X.end()); // Strip off the \001. + return; + } if (PrefixTy == Mangler::Private) - Result = PrivatePrefix + Result; + OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix)); else if (PrefixTy == Mangler::LinkerPrivate) - Result = LinkerPrivatePrefix + Result; - - return Result; + OutName.append(LinkerPrivatePrefix, + LinkerPrivatePrefix+strlen(LinkerPrivatePrefix)); + + if (Prefix[0] == 0) + ; // Common noop, no prefix. + else if (Prefix[1] == 0) + OutName.push_back(Prefix[0]); // Common, one character prefix. + else + OutName.append(Prefix, Prefix+strlen(Prefix)); // Arbitrary prefix. + OutName.append(X.begin(), X.end()); + return; } - if (NeedPrefix) - Result = X.substr(0, I-X.begin()).str(); - + // Add leading quote. + OutName.push_back('"'); + + // Add prefixes unless disabled. + if (NeedPrefix) { + if (PrefixTy == Mangler::Private) + OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix)); + else if (PrefixTy == Mangler::LinkerPrivate) + OutName.append(LinkerPrivatePrefix, + LinkerPrivatePrefix+strlen(LinkerPrivatePrefix)); + OutName.append(Prefix, Prefix+strlen(Prefix)); + } + + // Add the piece that we already scanned through. + OutName.append(X.begin(), I); + // Otherwise, construct the string the expensive way. for (StringRef::iterator E = X.end(); I != E; ++I) { - if (*I == '"') - Result += "_QQ_"; - else if (*I == '\n') - Result += "_NL_"; - else - Result += *I; + if (*I == '"') { + const char *Quote = "_QQ_"; + OutName.append(Quote, Quote+4); + } else if (*I == '\n') { + const char *Newline = "_NL_"; + OutName.append(Newline, Newline+4); + } else + OutName.push_back(*I); } - if (NeedPrefix) { - Result = Prefix + Result; - - if (PrefixTy == Mangler::Private) - Result = PrivatePrefix + Result; - else if (PrefixTy == Mangler::LinkerPrivate) - Result = LinkerPrivatePrefix + Result; - } - - Result = '"' + Result + '"'; - return Result; + // Add trailing quote. + OutName.push_back('"'); } /// getMangledName - Returns the mangled name of V, an LLVM Value, @@ -151,8 +160,11 @@ std::string Mangler::getMangledName(const GlobalValue *GV, const char *Suffix, (GV->hasPrivateLinkage() || ForcePrivate) ? Mangler::Private : GV->hasLinkerPrivateLinkage() ? Mangler::LinkerPrivate : Mangler::Default; - if (GV->hasName()) - return makeNameProper(GV->getNameStr() + Suffix, PrefixTy); + SmallString<128> Result; + if (GV->hasName()) { + makeNameProper(Result, GV->getNameStr() + Suffix, PrefixTy); + return Result.str().str(); + } // Get the ID for the global, assigning a new one if we haven't got one // already. @@ -160,7 +172,8 @@ std::string Mangler::getMangledName(const GlobalValue *GV, const char *Suffix, if (ID == 0) ID = NextAnonGlobalID++; // Must mangle the global into a unique ID. - return makeNameProper("__unnamed_" + utostr(ID) + Suffix, PrefixTy); + makeNameProper(Result, "__unnamed_" + utostr(ID) + Suffix, PrefixTy); + return Result.str().str(); }