diff --git a/include/llvm/Support/Mangler.h b/include/llvm/Support/Mangler.h index deedb6d4292..e0ad6ddede8 100644 --- a/include/llvm/Support/Mangler.h +++ b/include/llvm/Support/Mangler.h @@ -47,6 +47,15 @@ private: /// "linker_private" linkage. const char *LinkerPrivatePrefix; + /// UseQuotes - If this is set, the target accepts global names in quotes, + /// e.g. "foo bar" is a legal name. This syntax is used instead of escaping + /// the space character. By default, this is false. + bool UseQuotes; + + /// SymbolsCanStartWithDigit - If this is set, the target allows symbols to + /// start with digits (e.g., "0x0021"). By default, this is false. + bool SymbolsCanStartWithDigit; + /// AnonGlobalIDs - We need to give global values the same name every time /// they are mangled. This keeps track of the number we give to anonymous /// ones. @@ -57,12 +66,48 @@ private: /// unsigned NextAnonGlobalID; + /// AcceptableChars - This bitfield contains a one for each character that is + /// allowed to be part of an unmangled name. + unsigned AcceptableChars[256 / 32]; + public: // Mangler ctor - if a prefix is specified, it will be prepended onto all // symbols. Mangler(Module &M, const char *Prefix = "", const char *privatePrefix = "", const char *linkerPrivatePrefix = ""); + /// setUseQuotes - If UseQuotes is set to true, this target accepts quoted + /// strings for assembler labels. + void setUseQuotes(bool Val) { UseQuotes = Val; } + + /// setSymbolsCanStartWithDigit - If SymbolsCanStartWithDigit is set to true, + /// this target allows symbols to start with digits. + void setSymbolsCanStartWithDigit(bool Val) { SymbolsCanStartWithDigit = Val; } + + /// Acceptable Characters - This allows the target to specify which characters + /// are acceptable to the assembler without being mangled. By default we + /// allow letters, numbers, '_', '$', '.', which is what GAS accepts, and '@'. + void markCharAcceptable(unsigned char X) { + AcceptableChars[X/32] |= 1 << (X&31); + } + void markCharUnacceptable(unsigned char X) { + AcceptableChars[X/32] &= ~(1 << (X&31)); + } + bool isCharAcceptable(unsigned char X) const { + return (AcceptableChars[X/32] & (1 << (X&31))) != 0; + } + + /// getMangledName - Returns the mangled name of V, an LLVM Value, + /// in the current module. If 'Suffix' is specified, the name ends with the + /// 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 getMangledName(const GlobalValue *V, const char *Suffix = "", + bool ForcePrivate = false); + /// 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. @@ -80,6 +125,22 @@ public: /// have a name, this fills in a unique name for the global. std::string getNameWithPrefix(const GlobalValue *GV, bool isImplicitlyPrivate = false); + +private: + /// makeNameProper - We don't want identifier names with ., space, or + /// - in them, so we mangle these characters into the strings "d_", + /// "s_", and "D_", respectively. This is a very simple mangling that + /// doesn't guarantee unique names for values. getValueName already + /// does this for you, so there's no point calling it on the result + /// from getValueName. + /// + /// FIXME: This is deprecated, new code should use getNameWithPrefix and use + /// MCSymbol printing to handle quotes or not etc. + /// + void makeNameProper(SmallVectorImpl &OutName, + const Twine &Name, + ManglerPrefixTy PrefixTy = Mangler::Default); + }; } // End llvm namespace diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp index 23e5c4bd26c..cab71cea0d5 100644 --- a/lib/CodeGen/MachOWriter.cpp +++ b/lib/CodeGen/MachOWriter.cpp @@ -72,6 +72,12 @@ bool MachOWriter::doInitialization(Module &M) { Mang = new Mangler(M, MAI->getGlobalPrefix(), MAI->getPrivateGlobalPrefix(), MAI->getLinkerPrivateGlobalPrefix()); + if (MAI->doesAllowQuotesInName()) + Mang->setUseQuotes(true); + + if (MAI->doesAllowNameToStartWithDigit()) + Mang->setSymbolsCanStartWithDigit(true); + // Initialize TargetLoweringObjectFile. TM.getTargetLowering()->getObjFileLowering().Initialize(OutContext, TM); diff --git a/lib/VMCore/Mangler.cpp b/lib/VMCore/Mangler.cpp index d68f12bd4f5..9f6c9605076 100644 --- a/lib/VMCore/Mangler.cpp +++ b/lib/VMCore/Mangler.cpp @@ -7,17 +7,180 @@ // //===----------------------------------------------------------------------===// // -// Unified name mangler for assembly backends. +// Unified name mangler for CWriter and assembly backends. // //===----------------------------------------------------------------------===// #include "llvm/Support/Mangler.h" -#include "llvm/GlobalValue.h" +#include "llvm/Function.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/Twine.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; +static char HexDigit(int V) { + return V < 10 ? V+'0' : V+'A'-10; +} + +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. +/// +/// FIXME: This is deprecated, new code should use getNameWithPrefix and use +/// MCSymbol printing to handle quotes or not etc. +/// +void Mangler::makeNameProper(SmallVectorImpl &OutName, + const Twine &TheName, + ManglerPrefixTy PrefixTy) { + SmallString<256> TmpData; + StringRef X = TheName.toStringRef(TmpData); + assert(!X.empty() && "Cannot mangle empty strings"); + + if (!UseQuotes) { + // If X does not start with (char)1, add the prefix. + StringRef::iterator I = X.begin(); + if (*I == 1) { + ++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') + MangleLetter(OutName, *I++); + + for (StringRef::iterator E = X.end(); I != E; ++I) { + if (!isCharAcceptable(*I)) + MangleLetter(OutName, *I); + else + OutName.push_back(*I); + } + return; + } + + bool NeedPrefix = true; + bool NeedQuotes = false; + StringRef::iterator I = X.begin(); + if (*I == 1) { + NeedPrefix = false; + ++I; // Skip over the marker. + } + + // If the first character is a number, we need quotes. + if (*I >= '0' && *I <= '9') + NeedQuotes = true; + + // Do an initial scan of the string, checking to see if we need quotes or + // to escape a '"' or not. + if (!NeedQuotes) + for (StringRef::iterator E = X.end(); I != E; ++I) + if (!isCharAcceptable(*I)) { + NeedQuotes = true; + break; + } + + // In the common case, we don't need quotes. Handle this quickly. + if (!NeedQuotes) { + if (!NeedPrefix) { + OutName.append(X.begin()+1, X.end()); // Strip off the \001. + return; + } + + 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. + OutName.append(X.begin(), X.end()); + return; + } + + // 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()+!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); + } + + // Add trailing quote. + OutName.push_back('"'); +} + +/// getMangledName - Returns the mangled name of V, an LLVM Value, +/// in the current module. If 'Suffix' is specified, the name ends with the +/// 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(GV) || !cast(GV)->isIntrinsic()) && + "Intrinsic functions cannot be mangled by Mangler"); + + ManglerPrefixTy PrefixTy = + (GV->hasPrivateLinkage() || ForcePrivate) ? Mangler::Private : + GV->hasLinkerPrivateLinkage() ? Mangler::LinkerPrivate : Mangler::Default; + + 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. + unsigned &ID = AnonGlobalIDs[GV]; + if (ID == 0) ID = NextAnonGlobalID++; + + // Must mangle the global into a unique ID. + 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. @@ -100,5 +263,21 @@ std::string Mangler::getNameWithPrefix(const GlobalValue *GV, Mangler::Mangler(Module &M, const char *prefix, const char *privatePrefix, const char *linkerPrivatePrefix) : Prefix(prefix), PrivatePrefix(privatePrefix), - LinkerPrivatePrefix(linkerPrivatePrefix), NextAnonGlobalID(1) { + LinkerPrivatePrefix(linkerPrivatePrefix), UseQuotes(false), + SymbolsCanStartWithDigit(false), NextAnonGlobalID(1) { + std::fill(AcceptableChars, array_endof(AcceptableChars), 0); + + // Letters and numbers are acceptable. + for (unsigned char X = 'a'; X <= 'z'; ++X) + markCharAcceptable(X); + for (unsigned char X = 'A'; X <= 'Z'; ++X) + markCharAcceptable(X); + for (unsigned char X = '0'; X <= '9'; ++X) + markCharAcceptable(X); + + // These chars are acceptable. + markCharAcceptable('_'); + markCharAcceptable('$'); + markCharAcceptable('.'); + markCharAcceptable('@'); }