diff options
Diffstat (limited to 'lib/VMCore/Mangler.cpp')
-rw-r--r-- | lib/VMCore/Mangler.cpp | 200 |
1 files changed, 123 insertions, 77 deletions
diff --git a/lib/VMCore/Mangler.cpp b/lib/VMCore/Mangler.cpp index 33eb044..7d9f330 100644 --- a/lib/VMCore/Mangler.cpp +++ b/lib/VMCore/Mangler.cpp @@ -16,7 +16,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" -#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/SmallString.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -24,57 +24,57 @@ 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<char> &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 std::string &X, - ManglerPrefixTy PrefixTy) { +/// FIXME: This is deprecated, new code should use getNameWithPrefix and use +/// MCSymbol printing to handle quotes or not etc. +/// +void Mangler::makeNameProper(SmallVectorImpl<char> &OutName, + const Twine &TheName, + ManglerPrefixTy PrefixTy) { + SmallString<256> TmpData; + StringRef X = TheName.toStringRef(TmpData); 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; - std::string::const_iterator I = X.begin(); + 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 (std::string::const_iterator E = X.end(); I != E; ++I) { + for (StringRef::iterator E = X.end(); I != E; ++I) { if (!isCharAcceptable(*I)) - Result += MangleLetter(*I); + MangleLetter(OutName, *I); else - Result += *I; - } - - if (NeedPrefix) { - Result = Prefix + Result; - - if (PrefixTy == Mangler::Private) - Result = PrivatePrefix + Result; - else if (PrefixTy == Mangler::LinkerPrivate) - Result = LinkerPrivatePrefix + Result; + OutName.push_back(*I); } - - return Result; + return; } bool NeedPrefix = true; bool NeedQuotes = false; - std::string Result; - std::string::const_iterator I = X.begin(); + StringRef::iterator I = X.begin(); if (*I == 1) { NeedPrefix = false; ++I; // Skip over the marker. @@ -87,7 +87,7 @@ std::string Mangler::makeNameProper(const std::string &X, // Do an initial scan of the string, checking to see if we need quotes or // to escape a '"' or not. if (!NeedQuotes) - for (std::string::const_iterator E = X.end(); I != E; ++I) + for (StringRef::iterator E = X.end(); I != E; ++I) if (!isCharAcceptable(*I)) { NeedQuotes = true; break; @@ -95,43 +95,57 @@ std::string Mangler::makeNameProper(const std::string &X, // 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; + 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; - } - - if (NeedPrefix) - Result = X.substr(0, I-X.begin()); + OutName.append(LinkerPrivatePrefix, + LinkerPrivatePrefix+strlen(LinkerPrivatePrefix)); - // Otherwise, construct the string the expensive way. - for (std::string::const_iterator E = X.end(); I != E; ++I) { - if (*I == '"') - Result += "_QQ_"; - else if (*I == '\n') - Result += "_NL_"; + if (Prefix[0] == 0) + ; // Common noop, no prefix. + else if (Prefix[1] == 0) + OutName.push_back(Prefix[0]); // Common, one character prefix. else - Result += *I; + OutName.append(Prefix, Prefix+strlen(Prefix)); // Arbitrary prefix. + OutName.append(X.begin(), X.end()); + return; } + // Add leading quote. + OutName.push_back('"'); + + // Add prefixes unless disabled. if (NeedPrefix) { - Result = Prefix + Result; - if (PrefixTy == Mangler::Private) - Result = PrivatePrefix + Result; + OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix)); else if (PrefixTy == Mangler::LinkerPrivate) - Result = LinkerPrivatePrefix + Result; + OutName.append(LinkerPrivatePrefix, + LinkerPrivatePrefix+strlen(LinkerPrivatePrefix)); + OutName.append(Prefix, Prefix+strlen(Prefix)); + } + + // Add the piece that we already scanned through. + OutName.append(X.begin()+!NeedPrefix, I); + + // Otherwise, construct the string the expensive way. + for (StringRef::iterator E = X.end(); I != E; ++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); } - Result = '"' + Result + '"'; - return Result; + // Add trailing quote. + OutName.push_back('"'); } /// getMangledName - Returns the mangled name of V, an LLVM Value, @@ -139,6 +153,9 @@ std::string Mangler::makeNameProper(const std::string &X, /// specified suffix. If 'ForcePrivate' is specified, the label is specified /// to have a private label prefix. /// +/// FIXME: This is deprecated, new code should use getNameWithPrefix and use +/// MCSymbol printing to handle quotes or not etc. +/// std::string Mangler::getMangledName(const GlobalValue *GV, const char *Suffix, bool ForcePrivate) { assert((!isa<Function>(GV) || !cast<Function>(GV)->isIntrinsic()) && @@ -148,8 +165,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. @@ -157,7 +177,38 @@ 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(); +} + +/// 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<char> &OutName, + const Twine &GVName, ManglerPrefixTy PrefixTy) { + 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. + if (Name[0] != '\1') { + if (PrefixTy == Mangler::Private) + OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix)); + else if (PrefixTy == Mangler::LinkerPrivate) + 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. + } else { + Name = Name.substr(1); + } + + OutName.append(Name.begin(), Name.end()); } @@ -167,33 +218,28 @@ std::string Mangler::getMangledName(const GlobalValue *GV, const char *Suffix, void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV, bool isImplicitlyPrivate) { - - // If the global is anonymous or not led with \1, then add the appropriate - // prefix. - if (!GV->hasName() || GV->getName()[0] != '\1') { + // If this global has a name, handle it simply. + if (GV->hasName()) { + ManglerPrefixTy PrefixTy = Mangler::Default; if (GV->hasPrivateLinkage() || isImplicitlyPrivate) - OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix)); + PrefixTy = Mangler::Private; else if (GV->hasLinkerPrivateLinkage()) - OutName.append(LinkerPrivatePrefix, - LinkerPrivatePrefix+strlen(LinkerPrivatePrefix));; - OutName.append(Prefix, Prefix+strlen(Prefix)); - } - - // If the global has a name, just append it now. - if (GV->hasName()) { - StringRef Name = GV->getName(); + PrefixTy = Mangler::LinkerPrivate; - // Strip off the prefix marker if present. - if (Name[0] != '\1') - OutName.append(Name.begin(), Name.end()); - else - OutName.append(Name.begin()+1, Name.end()); - return; + return getNameWithPrefix(OutName, GV->getName(), PrefixTy); } // If the global variable doesn't have a name, return a unique name for the // global based on a numbering. + // Anonymous names always get prefixes. + if (GV->hasPrivateLinkage() || isImplicitlyPrivate) + OutName.append(PrivatePrefix, PrivatePrefix+strlen(PrivatePrefix)); + else if (GV->hasLinkerPrivateLinkage()) + OutName.append(LinkerPrivatePrefix, + LinkerPrivatePrefix+strlen(LinkerPrivatePrefix));; + OutName.append(Prefix, Prefix+strlen(Prefix)); + // Get the ID for the global, assigning a new one if we haven't got one // already. unsigned &ID = AnonGlobalIDs[GV]; |