summaryrefslogtreecommitdiffstats
path: root/lib/VMCore/Mangler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VMCore/Mangler.cpp')
-rw-r--r--lib/VMCore/Mangler.cpp200
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];
OpenPOWER on IntegriCloud