diff options
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/CBackend/CBackend.cpp | 9 | ||||
-rw-r--r-- | lib/Target/Mangler.cpp | 99 | ||||
-rw-r--r-- | lib/Target/TargetLoweringObjectFile.cpp | 13 |
3 files changed, 102 insertions, 19 deletions
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 7fd54ad379..6a7643a79b 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -352,10 +352,9 @@ char CWriter::ID = 0; static std::string Mangle(const std::string &S) { - std::string Result; - raw_string_ostream OS(Result); - MCSymbol::printMangledName(S, OS, 0); - return OS.str(); + SmallString<52> Result; + Mangler::appendMangledName(Result, S, 0); + return std::string(Result.begin(), Result.end()); } @@ -1452,7 +1451,7 @@ std::string CWriter::GetValueName(const Value *Operand) { if (const GlobalValue *GV = dyn_cast<GlobalValue>(Operand)) { SmallString<128> Str; Mang->getNameWithPrefix(Str, GV, false); - return Mangle(Str.str().str()); + return Str.str().str(); } std::string Name = Operand->getName(); diff --git a/lib/Target/Mangler.cpp b/lib/Target/Mangler.cpp index 5579bfc5d9..826f950c4a 100644 --- a/lib/Target/Mangler.cpp +++ b/lib/Target/Mangler.cpp @@ -18,6 +18,79 @@ #include "llvm/ADT/Twine.h" using namespace llvm; +static bool isAcceptableChar(char C) { + if ((C < 'a' || C > 'z') && + (C < 'A' || C > 'Z') && + (C < '0' || C > '9') && + C != '_' && C != '$' && C != '.' && C != '@') + return false; + return true; +} + +static char HexDigit(int V) { + return V < 10 ? V+'0' : V+'A'-10; +} + +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('_'); +} + +/// NameNeedsEscaping - Return true if the identifier \arg Str needs quotes +/// for this assembler. +static bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) { + assert(!Str.empty() && "Cannot create an empty MCSymbol"); + + // If the first character is a number and the target does not allow this, we + // need quotes. + if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9') + return true; + + // If any of the characters in the string is an unacceptable character, force + // quotes. + for (unsigned i = 0, e = Str.size(); i != e; ++i) + if (!isAcceptableChar(Str[i])) + return true; + return false; +} + +/// appendMangledName - Add the specified string in mangled form if it uses +/// any unusual characters. +void Mangler::appendMangledName(SmallVectorImpl<char> &OutName, StringRef Str, + const MCAsmInfo *MAI) { + // The first character is not allowed to be a number unless the target + // explicitly allows it. + if ((MAI == 0 || !MAI->doesAllowNameToStartWithDigit()) && + Str[0] >= '0' && Str[0] <= '9') { + MangleLetter(OutName, Str[0]); + Str = Str.substr(1); + } + + for (unsigned i = 0, e = Str.size(); i != e; ++i) { + if (!isAcceptableChar(Str[i])) + MangleLetter(OutName, Str[i]); + else + OutName.push_back(Str[i]); + } +} + + +/// appendMangledQuotedName - On systems that support quoted symbols, we still +/// have to escape some (obscure) characters like " and \n which would break the +/// assembler's lexing. +static void appendMangledQuotedName(SmallVectorImpl<char> &OutName, + StringRef Str) { + for (unsigned i = 0, e = Str.size(); i != e; ++i) { + if (Str[i] == '"' || Str[i] == '\n') + MangleLetter(OutName, Str[i]); + else + OutName.push_back(Str[i]); + } +} + + /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix /// and the specified name as the global variable name. GVName must not be /// empty. @@ -28,7 +101,9 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, 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 (Name[0] == '\1') { + Name = Name.substr(1); + } else { if (PrefixTy == Mangler::Private) { const char *Prefix = MAI.getPrivateGlobalPrefix(); OutName.append(Prefix, Prefix+strlen(Prefix)); @@ -44,11 +119,27 @@ void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName, OutName.push_back(Prefix[0]); // Common, one character prefix. else OutName.append(Prefix, Prefix+strlen(Prefix)); // Arbitrary length prefix. - } else { - Name = Name.substr(1); } - OutName.append(Name.begin(), Name.end()); + // If this is a simple string that doesn't need escaping, just append it. + if (!NameNeedsEscaping(Name, MAI) || + // If quotes are supported, they can be used unless the string contains + // a quote or newline. + (MAI.doesAllowQuotesInName() && + Name.find_first_of("\n\"") == StringRef::npos)) { + OutName.append(Name.begin(), Name.end()); + return; + } + + // On systems that do not allow quoted names, we need to mangle most + // strange characters. + if (!MAI.doesAllowQuotesInName()) + return appendMangledName(OutName, Name, &MAI); + + // Okay, the system allows quoted strings. We can quote most anything, the + // only characters that need escaping are " and \n. + assert(Name.find_first_of("\n\"") != StringRef::npos); + return appendMangledQuotedName(OutName, Name); } diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp index 39c90cd8f9..93cb420d62 100644 --- a/lib/Target/TargetLoweringObjectFile.cpp +++ b/lib/Target/TargetLoweringObjectFile.cpp @@ -579,18 +579,11 @@ 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); - SmallString<128> Name, MangledName; + SmallString<128> Name; Name.append(Prefix, Prefix+strlen(Prefix)); Mang->getNameWithPrefix(Name, GV, false); - - raw_svector_ostream OS(MangledName); - MCSymbol::printMangledName(Name, OS, 0); - OS.flush(); - - return getELFSection(MangledName.str(), - getELFSectionType(MangledName.str(), Kind), - getELFSectionFlags(Kind), - Kind); + return getELFSection(Name.str(), getELFSectionType(Name.str(), Kind), + getELFSectionFlags(Kind), Kind); } if (Kind.isText()) return TextSection; |