class raw_ostream;
/// MCSymbol - Instances of this class represent a symbol name in the MC file,
- /// and MCSymbols are created and unique'd by the MCContext class.
+ /// and MCSymbols are created and unique'd by the MCContext class. MCSymbols
+ /// should only be constructed with valid names for the object file.
///
/// If the symbol is defined/emitted into the current translation unit, the
/// Section member is set to indicate what section it lives in. Otherwise, if
/// typically does not survive in the .o file's symbol table. Usually
/// "Lfoo" or ".foo".
unsigned IsTemporary : 1;
-
+
private: // MCContext creates and uniques these.
friend class MCContext;
MCSymbol(StringRef _Name, bool _IsTemporary)
/// dump - Print the value to stderr.
void dump() const;
-
- /// printMangledName - Print the specified string in mangled form if it uses
- /// any unusual characters.
- static void printMangledName(StringRef Str, raw_ostream &OS,
- const MCAsmInfo *MAI);
};
} // end namespace llvm
#include <string>
namespace llvm {
+class StringRef;
class Twine;
class Value;
class GlobalValue;
/// have a name, this fills in a unique name for the global.
std::string getNameWithPrefix(const GlobalValue *GV,
bool isImplicitlyPrivate = false);
+
+ /// appendMangledName - Add the specified string in mangled form if it uses
+ /// any unusual characters.
+ static void appendMangledName(SmallVectorImpl<char> &OutName, StringRef Str,
+ const MCAsmInfo *MAI);
};
} // End llvm namespace
return true;
}
-static char HexDigit(int V) {
- return V < 10 ? V+'0' : V+'A'-10;
-}
-
-static void MangleLetter(raw_ostream &OS, unsigned char C) {
- OS << '_' << HexDigit(C >> 4) << HexDigit(C & 15) << '_';
-}
-
/// NameNeedsEscaping - Return true if the identifier \arg Str needs quotes
/// for this assembler.
static bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) {
// 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)
return false;
}
-/// printMangledName - Print the specified string in mangled form if it uses
-/// any unusual characters.
-void MCSymbol::printMangledName(StringRef Str, raw_ostream &OS,
- 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(OS, Str[0]);
- Str = Str.substr(1);
- }
-
- for (unsigned i = 0, e = Str.size(); i != e; ++i) {
- if (!isAcceptableChar(Str[i]))
- MangleLetter(OS, Str[i]);
- else
- OS << Str[i];
- }
-}
-
-/// PrintMangledQuotedName - 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 PrintMangledQuotedName(raw_ostream &OS, StringRef Str) {
- OS << '"';
-
- for (unsigned i = 0, e = Str.size(); i != e; ++i) {
- if (Str[i] == '"')
- OS << "_QQ_";
- else if (Str[i] == '\n')
- OS << "_NL_";
- else
- OS << Str[i];
- }
- OS << '"';
-}
-
-
void MCSymbol::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
+ // The name for this MCSymbol is required to be a valid target name. However,
+ // some targets support quoting names with funny characters. If the name
+ // contains a funny character, then print it quoted.
if (MAI == 0 || !NameNeedsEscaping(getName(), *MAI)) {
OS << getName();
return;
}
-
- // On systems that do not allow quoted names, print with mangling.
- if (!MAI->doesAllowQuotesInName())
- return printMangledName(getName(), OS, MAI);
-
- // If the string contains a double quote or newline, we still have to mangle
- // it.
- if (getName().find('"') != std::string::npos ||
- getName().find('\n') != std::string::npos)
- return PrintMangledQuotedName(OS, getName());
OS << '"' << getName() << '"';
}
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());
}
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();
#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.
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));
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);
}
// 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;