X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FMangler.cpp;h=50fa3c1885b9c94db263acb98af008fde1eb311d;hb=629c1a3f78494d0dd769fe82bd2bd17df0555843;hp=418eb9a71a35c4c0fe79422ca333edd359c311c2;hpb=ac8c83428886adcd6b6b2290252db87be184c71c;p=oota-llvm.git diff --git a/lib/VMCore/Mangler.cpp b/lib/VMCore/Mangler.cpp index 418eb9a71a3..50fa3c1885b 100644 --- a/lib/VMCore/Mangler.cpp +++ b/lib/VMCore/Mangler.cpp @@ -2,8 +2,8 @@ // // 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. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -14,6 +14,7 @@ #include "llvm/Support/Mangler.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; @@ -22,7 +23,8 @@ static char HexDigit(int V) { } static std::string MangleLetter(unsigned char C) { - return std::string("_")+HexDigit(C >> 4) + HexDigit(C & 15) + "_"; + char Result[] = { '_', HexDigit(C >> 4), HexDigit(C & 15), '_', 0 }; + return Result; } /// makeNameProper - We don't want identifier names non-C-identifier characters @@ -30,6 +32,11 @@ static std::string MangleLetter(unsigned char C) { /// 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 PreserveAsmNames is set, names with asm identifiers are not modified. + if (PreserveAsmNames && X[0] == 1) + return X; if (!UseQuotes) { // If X does not start with (char)1, add the prefix. @@ -39,41 +46,62 @@ std::string Mangler::makeNameProper(const std::string &X, const char *Prefix) { else ++I; // Skip over the marker. - // Mangle the first letter specially, don't allow numbers... + // 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 ((*I < 'a' || *I > 'z') && (*I < 'A' || *I > 'Z') && - (*I < '0' || *I > '9') && *I != '_' && *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 + if (*I == 1) ++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) + // Do an initial scan of the string, checking to see if we need quotes or + // to escape a '"' or not. + if (!NeedsQuotes) + for (std::string::const_iterator E = X.end(); I != E; ++I) + if (!isCharAcceptable(*I)) { + NeedsQuotes = true; + break; + } + + // In the common case, we don't need quotes. Handle this quickly. + if (!NeedsQuotes) { + if (*X.begin() != 1) + return Prefix+X; + else + return X.substr(1); + } + + // Otherwise, construct the string the expensive way. + I = X.begin(); + + // If X does not start with (char)1, add the prefix. + if (*I != 1) + Result = Prefix; + else + ++I; // Skip the marker if present. + + for (std::string::const_iterator E = X.end(); I != E; ++I) { if (*I == '"') Result += "_QQ_"; - else { - if ((*I < 'a' || *I > 'z') && (*I < 'A' || *I > 'Z') && - (*I < '0' || *I > '9') && *I != '_' && *I != '$' && *I != '.') - NeedsQuotes = true; + else if (*I == '\n') + Result += "_NL_"; + else Result += *I; - } - if (NeedsQuotes) - Result = '"' + Result + '"'; + } + Result = '"' + Result + '"'; } return Result; } @@ -100,7 +128,7 @@ std::string Mangler::getValueName(const Value *V) { } -std::string Mangler::getValueName(const GlobalValue *GV) { +std::string Mangler::getValueName(const GlobalValue *GV, const char * Suffix) { // Check to see whether we've already named V. std::string &Name = Memo[GV]; if (!Name.empty()) @@ -109,10 +137,15 @@ std::string Mangler::getValueName(const GlobalValue *GV) { // 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(GV) && cast(GV)->getIntrinsicID()) { + if (isa(GV) && cast(GV)->isIntrinsic()) { Name = GV->getName(); // Is an intrinsic function + } else if (!GV->hasName()) { + // Must mangle the global into a unique ID. + unsigned TypeUniqueID = getTypeID(GV->getType()); + static unsigned GlobalID = 0; + Name = "__unnamed_" + utostr(TypeUniqueID) + "_" + utostr(GlobalID++); } else if (!MangledGlobals.count(GV)) { - Name = makeNameProper(GV->getName(), Prefix); + Name = makeNameProper(GV->getName() + Suffix, Prefix); } else { unsigned TypeUniqueID = getTypeID(GV->getType()); Name = "l" + utostr(TypeUniqueID) + "_" + makeNameProper(GV->getName()); @@ -123,10 +156,8 @@ std::string Mangler::getValueName(const GlobalValue *GV) { void Mangler::InsertName(GlobalValue *GV, std::map &Names) { - if (!GV->hasName()) { // We must mangle unnamed globals. - MangledGlobals.insert(GV); + if (!GV->hasName()) // We must mangle unnamed globals. return; - } // Figure out if this is already used. GlobalValue *&ExistingValue = Names[GV->getName()]; @@ -134,9 +165,19 @@ void Mangler::InsertName(GlobalValue *GV, ExistingValue = GV; } else { // If GV is external but the existing one is static, mangle the existing one - if (GV->hasExternalLinkage() && !ExistingValue->hasExternalLinkage()) { + if ((GV->hasExternalLinkage() || GV->hasDLLImportLinkage()) && + !(ExistingValue->hasExternalLinkage() + || ExistingValue->hasDLLImportLinkage())) { MangledGlobals.insert(ExistingValue); ExistingValue = GV; + } else if ((GV->hasExternalLinkage() || + GV->hasDLLImportLinkage()) && + (ExistingValue->hasExternalLinkage() || + ExistingValue->hasDLLImportLinkage()) && + GV->isDeclaration() && + ExistingValue->isDeclaration()) { + // If the two globals both have external inkage, and are both external, + // don't mangle either of them, we just have some silly type mismatch. } else { // Otherwise, mangle GV MangledGlobals.insert(GV); @@ -146,12 +187,30 @@ void Mangler::InsertName(GlobalValue *GV, Mangler::Mangler(Module &M, const char *prefix) - : Prefix(prefix), UseQuotes(false), Count(0), TypeCounter(0) { + : Prefix(prefix), UseQuotes(false), PreserveAsmNames(false), + Count(0), TypeCounter(0) { + 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('.'); + // Calculate which global values have names that will collide when we throw // away type information. std::map 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) + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; + ++I) InsertName(I, Names); }