llvm-6502/lib/VMCore/Mangler.cpp
Chris Lattner 91150e5d46 Allow per-character control over what target assemblers allow in symbol
names.  This also changes the default to allow all of "$_." in addition
to letters and numbers as symbol names.  If you don't want this, use
markCharUnacceptable to remove one of these or markCharAcceptable to add
to the set.  This corresponds with what GAS accepts by default.

Also, this includes some minor speedups


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24293 91177308-0d34-0410-b5e6-96231b3b80d8
2005-11-10 21:40:01 +00:00

176 lines
5.3 KiB
C++

//===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Unified name mangler for CWriter and assembly backends.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/Mangler.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/ADT/StringExtras.h"
using namespace llvm;
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;
}
/// 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, const char *Prefix) {
std::string Result;
if (X.empty()) return X; // Empty names are uniqued by the caller.
if (!UseQuotes) {
// If X does not start with (char)1, add the prefix.
std::string::const_iterator I = X.begin();
if (*I != 1)
Result = Prefix;
else
++I; // Skip over the marker.
// Mangle the first letter specially, don't allow numbers.
if (*I >= '0' && *I <= '9')
Result += MangleLetter(*I++);
for (std::string::const_iterator E = X.end(); I != E; ++I) {
if (!isCharAcceptable(*I))
Result += MangleLetter(*I);
else
Result += *I;
}
} else {
bool NeedsQuotes = false;
// If X does not start with (char)1, add the prefix.
std::string::const_iterator I = X.begin();
if (*I != 1)
Result = Prefix;
else
++I; // Skip over the marker.
// If the first character is a number, we need quotes.
if (*I >= '0' && *I <= '9')
NeedsQuotes = true;
for (std::string::const_iterator E = X.end(); I != E; ++I)
if (*I == '"')
Result += "_QQ_";
else {
if (!isCharAcceptable(*I))
NeedsQuotes = true;
Result += *I;
}
if (NeedsQuotes)
Result = '"' + Result + '"';
}
return Result;
}
/// getTypeID - Return a unique ID for the specified LLVM type.
///
unsigned Mangler::getTypeID(const Type *Ty) {
unsigned &E = TypeMap[Ty];
if (E == 0) E = ++TypeCounter;
return E;
}
std::string Mangler::getValueName(const Value *V) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
return getValueName(GV);
std::string &Name = Memo[V];
if (!Name.empty())
return Name; // Return the already-computed name for V.
// Always mangle local names.
Name = "ltmp_" + utostr(Count++) + "_" + utostr(getTypeID(V->getType()));
return Name;
}
std::string Mangler::getValueName(const GlobalValue *GV) {
// Check to see whether we've already named V.
std::string &Name = Memo[GV];
if (!Name.empty())
return Name; // Return the already-computed name for V.
// Name mangling occurs as follows:
// - If V is an intrinsic function, do not change name at all
// - Otherwise, mangling occurs if global collides with existing name.
if (isa<Function>(GV) && cast<Function>(GV)->getIntrinsicID()) {
Name = GV->getName(); // Is an intrinsic function
} else if (!MangledGlobals.count(GV)) {
Name = makeNameProper(GV->getName(), Prefix);
} else {
unsigned TypeUniqueID = getTypeID(GV->getType());
Name = "l" + utostr(TypeUniqueID) + "_" + makeNameProper(GV->getName());
}
return Name;
}
void Mangler::InsertName(GlobalValue *GV,
std::map<std::string, GlobalValue*> &Names) {
if (!GV->hasName()) { // We must mangle unnamed globals.
MangledGlobals.insert(GV);
return;
}
// Figure out if this is already used.
GlobalValue *&ExistingValue = Names[GV->getName()];
if (!ExistingValue) {
ExistingValue = GV;
} else {
// If GV is external but the existing one is static, mangle the existing one
if (GV->hasExternalLinkage() && !ExistingValue->hasExternalLinkage()) {
MangledGlobals.insert(ExistingValue);
ExistingValue = GV;
} else {
// Otherwise, mangle GV
MangledGlobals.insert(GV);
}
}
}
Mangler::Mangler(Module &M, const char *prefix)
: Prefix(prefix), UseQuotes(false), Count(0), TypeCounter(0) {
std::fill(AcceptableChars,
AcceptableChars+sizeof(AcceptableChars)/sizeof(AcceptableChars[0]),
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('.');
// Calculate which global values have names that will collide when we throw
// away type information.
std::map<std::string, GlobalValue*> Names;
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
InsertName(I, Names);
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
InsertName(I, Names);
}