Get MCSymbol out of the mangling business, and move all the logic
authorChris Lattner <sabre@nondot.org>
Sun, 17 Jan 2010 19:23:46 +0000 (19:23 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 17 Jan 2010 19:23:46 +0000 (19:23 +0000)
to Mangler.  Now MCSymbol just decides whether to slap quotes around
a symbol when printing it.

This also fixes some weirdness where two MCSymbols could be created
for the same symbol, if one needed to be mangled and got mangled to
the other one.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@93690 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCSymbol.h
include/llvm/Target/Mangler.h
lib/MC/MCSymbol.cpp
lib/Target/CBackend/CBackend.cpp
lib/Target/Mangler.cpp
lib/Target/TargetLoweringObjectFile.cpp

index eb594532fe0b49836caf7f2f9540753b97243974..c84babac4a9791e80de3651f18b9a1c0b2b711e3 100644 (file)
@@ -26,7 +26,8 @@ namespace llvm {
   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
@@ -53,7 +54,7 @@ namespace llvm {
     /// 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)
@@ -136,11 +137,6 @@ namespace llvm {
 
     /// 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
index 07ff7e29c0f20e19a55133cca7f9ab25c8c288e8..8caa623043584453a1153d626a0726f1441e9212 100644 (file)
@@ -18,6 +18,7 @@
 #include <string>
 
 namespace llvm {
+class StringRef;
 class Twine;
 class Value;
 class GlobalValue;
@@ -67,6 +68,11 @@ public:
   /// 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
index 265d06cceba129f77e9b6f1f4f124459e0127010..812ee69100b60042120ebda1487f105702e650c4 100644 (file)
@@ -26,14 +26,6 @@ static bool isAcceptableChar(char C) {
   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) {
@@ -43,7 +35,7 @@ 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)
@@ -52,59 +44,14 @@ static bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) {
   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() << '"';
 }
index 7fd54ad37976002e64ee4801a9d28b9f273d3bc7..6a7643a79b6f7536bbe9ff4f18d050611b09b46d 100644 (file)
@@ -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();
index 5579bfc5d9d4b9ac4a97245b9b57556d54d9d806..826f950c4a45f4e019b8813cc06f11fc7696c353 100644 (file)
 #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);
 }
 
 
index 39c90cd8f9b89660dc55350b97f55428dca7a46a..93cb420d6285e06251ce990859ff4f0ad384bd13 100644 (file)
@@ -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;