Home | History | Annotate | Download | only in Target
      1 //===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Unified name mangler for assembly backends.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "llvm/Target/Mangler.h"
     15 #include "llvm/DerivedTypes.h"
     16 #include "llvm/Function.h"
     17 #include "llvm/Target/TargetData.h"
     18 #include "llvm/MC/MCAsmInfo.h"
     19 #include "llvm/MC/MCContext.h"
     20 #include "llvm/Support/raw_ostream.h"
     21 #include "llvm/ADT/SmallString.h"
     22 #include "llvm/ADT/Twine.h"
     23 using namespace llvm;
     24 
     25 static bool isAcceptableChar(char C, bool AllowPeriod) {
     26   if ((C < 'a' || C > 'z') &&
     27       (C < 'A' || C > 'Z') &&
     28       (C < '0' || C > '9') &&
     29       C != '_' && C != '$' && C != '@' &&
     30       !(AllowPeriod && C == '.'))
     31     return false;
     32   return true;
     33 }
     34 
     35 static char HexDigit(int V) {
     36   return V < 10 ? V+'0' : V+'A'-10;
     37 }
     38 
     39 static void MangleLetter(SmallVectorImpl<char> &OutName, unsigned char C) {
     40   OutName.push_back('_');
     41   OutName.push_back(HexDigit(C >> 4));
     42   OutName.push_back(HexDigit(C & 15));
     43   OutName.push_back('_');
     44 }
     45 
     46 /// NameNeedsEscaping - Return true if the identifier \arg Str needs quotes
     47 /// for this assembler.
     48 static bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) {
     49   assert(!Str.empty() && "Cannot create an empty MCSymbol");
     50 
     51   // If the first character is a number and the target does not allow this, we
     52   // need quotes.
     53   if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9')
     54     return true;
     55 
     56   // If any of the characters in the string is an unacceptable character, force
     57   // quotes.
     58   bool AllowPeriod = MAI.doesAllowPeriodsInName();
     59   for (unsigned i = 0, e = Str.size(); i != e; ++i)
     60     if (!isAcceptableChar(Str[i], AllowPeriod))
     61       return true;
     62   return false;
     63 }
     64 
     65 /// appendMangledName - Add the specified string in mangled form if it uses
     66 /// any unusual characters.
     67 static void appendMangledName(SmallVectorImpl<char> &OutName, StringRef Str,
     68                               const MCAsmInfo &MAI) {
     69   // The first character is not allowed to be a number unless the target
     70   // explicitly allows it.
     71   if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9') {
     72     MangleLetter(OutName, Str[0]);
     73     Str = Str.substr(1);
     74   }
     75 
     76   bool AllowPeriod = MAI.doesAllowPeriodsInName();
     77   for (unsigned i = 0, e = Str.size(); i != e; ++i) {
     78     if (!isAcceptableChar(Str[i], AllowPeriod))
     79       MangleLetter(OutName, Str[i]);
     80     else
     81       OutName.push_back(Str[i]);
     82   }
     83 }
     84 
     85 
     86 /// appendMangledQuotedName - On systems that support quoted symbols, we still
     87 /// have to escape some (obscure) characters like " and \n which would break the
     88 /// assembler's lexing.
     89 static void appendMangledQuotedName(SmallVectorImpl<char> &OutName,
     90                                    StringRef Str) {
     91   for (unsigned i = 0, e = Str.size(); i != e; ++i) {
     92     if (Str[i] == '"' || Str[i] == '\n')
     93       MangleLetter(OutName, Str[i]);
     94     else
     95       OutName.push_back(Str[i]);
     96   }
     97 }
     98 
     99 
    100 /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
    101 /// and the specified name as the global variable name.  GVName must not be
    102 /// empty.
    103 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
    104                                 const Twine &GVName, ManglerPrefixTy PrefixTy) {
    105   SmallString<256> TmpData;
    106   StringRef Name = GVName.toStringRef(TmpData);
    107   assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
    108 
    109   const MCAsmInfo &MAI = Context.getAsmInfo();
    110 
    111   // If the global name is not led with \1, add the appropriate prefixes.
    112   if (Name[0] == '\1') {
    113     Name = Name.substr(1);
    114   } else {
    115     if (PrefixTy == Mangler::Private) {
    116       const char *Prefix = MAI.getPrivateGlobalPrefix();
    117       OutName.append(Prefix, Prefix+strlen(Prefix));
    118     } else if (PrefixTy == Mangler::LinkerPrivate) {
    119       const char *Prefix = MAI.getLinkerPrivateGlobalPrefix();
    120       OutName.append(Prefix, Prefix+strlen(Prefix));
    121     }
    122 
    123     const char *Prefix = MAI.getGlobalPrefix();
    124     if (Prefix[0] == 0)
    125       ; // Common noop, no prefix.
    126     else if (Prefix[1] == 0)
    127       OutName.push_back(Prefix[0]);  // Common, one character prefix.
    128     else
    129       OutName.append(Prefix, Prefix+strlen(Prefix)); // Arbitrary length prefix.
    130   }
    131 
    132   // If this is a simple string that doesn't need escaping, just append it.
    133   if (!NameNeedsEscaping(Name, MAI) ||
    134       // If quotes are supported, they can be used unless the string contains
    135       // a quote or newline.
    136       (MAI.doesAllowQuotesInName() &&
    137        Name.find_first_of("\n\"") == StringRef::npos)) {
    138     OutName.append(Name.begin(), Name.end());
    139     return;
    140   }
    141 
    142   // On systems that do not allow quoted names, we need to mangle most
    143   // strange characters.
    144   if (!MAI.doesAllowQuotesInName())
    145     return appendMangledName(OutName, Name, MAI);
    146 
    147   // Okay, the system allows quoted strings.  We can quote most anything, the
    148   // only characters that need escaping are " and \n.
    149   assert(Name.find_first_of("\n\"") != StringRef::npos);
    150   return appendMangledQuotedName(OutName, Name);
    151 }
    152 
    153 /// AddFastCallStdCallSuffix - Microsoft fastcall and stdcall functions require
    154 /// a suffix on their name indicating the number of words of arguments they
    155 /// take.
    156 static void AddFastCallStdCallSuffix(SmallVectorImpl<char> &OutName,
    157                                      const Function *F, const TargetData &TD) {
    158   // Calculate arguments size total.
    159   unsigned ArgWords = 0;
    160   for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
    161        AI != AE; ++AI) {
    162     Type *Ty = AI->getType();
    163     // 'Dereference' type in case of byval parameter attribute
    164     if (AI->hasByValAttr())
    165       Ty = cast<PointerType>(Ty)->getElementType();
    166     // Size should be aligned to DWORD boundary
    167     ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4;
    168   }
    169 
    170   raw_svector_ostream(OutName) << '@' << ArgWords;
    171 }
    172 
    173 
    174 /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
    175 /// and the specified global variable's name.  If the global variable doesn't
    176 /// have a name, this fills in a unique name for the global.
    177 void Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
    178                                 const GlobalValue *GV,
    179                                 bool isImplicitlyPrivate) {
    180   ManglerPrefixTy PrefixTy = Mangler::Default;
    181   if (GV->hasPrivateLinkage() || isImplicitlyPrivate)
    182     PrefixTy = Mangler::Private;
    183   else if (GV->hasLinkerPrivateLinkage() || GV->hasLinkerPrivateWeakLinkage() ||
    184            GV->hasLinkerPrivateWeakDefAutoLinkage())
    185     PrefixTy = Mangler::LinkerPrivate;
    186 
    187   // If this global has a name, handle it simply.
    188   if (GV->hasName()) {
    189     getNameWithPrefix(OutName, GV->getName(), PrefixTy);
    190   } else {
    191     // Get the ID for the global, assigning a new one if we haven't got one
    192     // already.
    193     unsigned &ID = AnonGlobalIDs[GV];
    194     if (ID == 0) ID = NextAnonGlobalID++;
    195 
    196     // Must mangle the global into a unique ID.
    197     getNameWithPrefix(OutName, "__unnamed_" + Twine(ID), PrefixTy);
    198   }
    199 
    200   // If we are supposed to add a microsoft-style suffix for stdcall/fastcall,
    201   // add it.
    202   if (Context.getAsmInfo().hasMicrosoftFastStdCallMangling()) {
    203     if (const Function *F = dyn_cast<Function>(GV)) {
    204       CallingConv::ID CC = F->getCallingConv();
    205 
    206       // fastcall functions need to start with @.
    207       // FIXME: This logic seems unlikely to be right.
    208       if (CC == CallingConv::X86_FastCall) {
    209         if (OutName[0] == '_')
    210           OutName[0] = '@';
    211         else
    212           OutName.insert(OutName.begin(), '@');
    213       }
    214 
    215       // fastcall and stdcall functions usually need @42 at the end to specify
    216       // the argument info.
    217       FunctionType *FT = F->getFunctionType();
    218       if ((CC == CallingConv::X86_FastCall || CC == CallingConv::X86_StdCall) &&
    219           // "Pure" variadic functions do not receive @0 suffix.
    220           (!FT->isVarArg() || FT->getNumParams() == 0 ||
    221            (FT->getNumParams() == 1 && F->hasStructRetAttr())))
    222         AddFastCallStdCallSuffix(OutName, F, TD);
    223     }
    224   }
    225 }
    226 
    227 /// getSymbol - Return the MCSymbol for the specified global value.  This
    228 /// symbol is the main label that is the address of the global.
    229 MCSymbol *Mangler::getSymbol(const GlobalValue *GV) {
    230   SmallString<60> NameStr;
    231   getNameWithPrefix(NameStr, GV, false);
    232   return Context.GetOrCreateSymbol(NameStr.str());
    233 }
    234 
    235 
    236