119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//                     The LLVM Compiler Infrastructure
419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source
619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details.
719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Unified name mangler for assembly backends.
1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/Mangler.h"
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/DerivedTypes.h"
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Function.h"
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetData.h"
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCAsmInfo.h"
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCContext.h"
2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/raw_ostream.h"
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/SmallString.h"
2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/Twine.h"
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm;
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool isAcceptableChar(char C, bool AllowPeriod) {
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if ((C < 'a' || C > 'z') &&
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      (C < 'A' || C > 'Z') &&
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      (C < '0' || C > '9') &&
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      C != '_' && C != '$' && C != '@' &&
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      !(AllowPeriod && C == '.'))
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic char HexDigit(int V) {
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return V < 10 ? V+'0' : V+'A'-10;
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void MangleLetter(SmallVectorImpl<char> &OutName, unsigned char C) {
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  OutName.push_back('_');
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  OutName.push_back(HexDigit(C >> 4));
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  OutName.push_back(HexDigit(C & 15));
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  OutName.push_back('_');
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// NameNeedsEscaping - Return true if the identifier \arg Str needs quotes
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// for this assembler.
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) {
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(!Str.empty() && "Cannot create an empty MCSymbol");
5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If the first character is a number and the target does not allow this, we
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // need quotes.
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9')
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If any of the characters in the string is an unacceptable character, force
5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // quotes.
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool AllowPeriod = MAI.doesAllowPeriodsInName();
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = Str.size(); i != e; ++i)
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!isAcceptableChar(Str[i], AllowPeriod))
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// appendMangledName - Add the specified string in mangled form if it uses
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// any unusual characters.
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void appendMangledName(SmallVectorImpl<char> &OutName, StringRef Str,
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                              const MCAsmInfo &MAI) {
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // The first character is not allowed to be a number unless the target
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // explicitly allows it.
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9') {
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MangleLetter(OutName, Str[0]);
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Str = Str.substr(1);
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool AllowPeriod = MAI.doesAllowPeriodsInName();
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!isAcceptableChar(Str[i], AllowPeriod))
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MangleLetter(OutName, Str[i]);
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OutName.push_back(Str[i]);
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// appendMangledQuotedName - On systems that support quoted symbols, we still
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// have to escape some (obscure) characters like " and \n which would break the
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// assembler's lexing.
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void appendMangledQuotedName(SmallVectorImpl<char> &OutName,
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   StringRef Str) {
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Str[i] == '"' || Str[i] == '\n')
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MangleLetter(OutName, Str[i]);
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OutName.push_back(Str[i]);
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// and the specified name as the global variable name.  GVName must not be
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// empty.
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                const Twine &GVName, ManglerPrefixTy PrefixTy) {
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallString<256> TmpData;
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StringRef Name = GVName.toStringRef(TmpData);
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MCAsmInfo &MAI = Context.getAsmInfo();
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If the global name is not led with \1, add the appropriate prefixes.
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Name[0] == '\1') {
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Name = Name.substr(1);
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (PrefixTy == Mangler::Private) {
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const char *Prefix = MAI.getPrivateGlobalPrefix();
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OutName.append(Prefix, Prefix+strlen(Prefix));
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else if (PrefixTy == Mangler::LinkerPrivate) {
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const char *Prefix = MAI.getLinkerPrivateGlobalPrefix();
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OutName.append(Prefix, Prefix+strlen(Prefix));
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const char *Prefix = MAI.getGlobalPrefix();
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Prefix[0] == 0)
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ; // Common noop, no prefix.
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else if (Prefix[1] == 0)
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OutName.push_back(Prefix[0]);  // Common, one character prefix.
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    else
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OutName.append(Prefix, Prefix+strlen(Prefix)); // Arbitrary length prefix.
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If this is a simple string that doesn't need escaping, just append it.
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!NameNeedsEscaping(Name, MAI) ||
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If quotes are supported, they can be used unless the string contains
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // a quote or newline.
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      (MAI.doesAllowQuotesInName() &&
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       Name.find_first_of("\n\"") == StringRef::npos)) {
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OutName.append(Name.begin(), Name.end());
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return;
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // On systems that do not allow quoted names, we need to mangle most
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // strange characters.
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!MAI.doesAllowQuotesInName())
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return appendMangledName(OutName, Name, MAI);
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Okay, the system allows quoted strings.  We can quote most anything, the
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // only characters that need escaping are " and \n.
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(Name.find_first_of("\n\"") != StringRef::npos);
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return appendMangledQuotedName(OutName, Name);
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// AddFastCallStdCallSuffix - Microsoft fastcall and stdcall functions require
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// a suffix on their name indicating the number of words of arguments they
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// take.
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void AddFastCallStdCallSuffix(SmallVectorImpl<char> &OutName,
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                     const Function *F, const TargetData &TD) {
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Calculate arguments size total.
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned ArgWords = 0;
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       AI != AE; ++AI) {
16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type *Ty = AI->getType();
16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // 'Dereference' type in case of byval parameter attribute
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (AI->hasByValAttr())
16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Ty = cast<PointerType>(Ty)->getElementType();
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Size should be aligned to DWORD boundary
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4;
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  raw_svector_ostream(OutName) << '@' << ArgWords;
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// and the specified global variable's name.  If the global variable doesn't
17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// have a name, this fills in a unique name for the global.
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                const GlobalValue *GV,
17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                bool isImplicitlyPrivate) {
18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ManglerPrefixTy PrefixTy = Mangler::Default;
18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (GV->hasPrivateLinkage() || isImplicitlyPrivate)
18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PrefixTy = Mangler::Private;
18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else if (GV->hasLinkerPrivateLinkage() || GV->hasLinkerPrivateWeakLinkage() ||
18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           GV->hasLinkerPrivateWeakDefAutoLinkage())
18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PrefixTy = Mangler::LinkerPrivate;
18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If this global has a name, handle it simply.
18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (GV->hasName()) {
18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getNameWithPrefix(OutName, GV->getName(), PrefixTy);
19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Get the ID for the global, assigning a new one if we haven't got one
19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // already.
19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned &ID = AnonGlobalIDs[GV];
19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (ID == 0) ID = NextAnonGlobalID++;
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Must mangle the global into a unique ID.
19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    getNameWithPrefix(OutName, "__unnamed_" + Twine(ID), PrefixTy);
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If we are supposed to add a microsoft-style suffix for stdcall/fastcall,
20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // add it.
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Context.getAsmInfo().hasMicrosoftFastStdCallMangling()) {
20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (const Function *F = dyn_cast<Function>(GV)) {
20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      CallingConv::ID CC = F->getCallingConv();
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // fastcall functions need to start with @.
20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // FIXME: This logic seems unlikely to be right.
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (CC == CallingConv::X86_FastCall) {
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (OutName[0] == '_')
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          OutName[0] = '@';
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        else
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          OutName.insert(OutName.begin(), '@');
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // fastcall and stdcall functions usually need @42 at the end to specify
21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // the argument info.
21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FunctionType *FT = F->getFunctionType();
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if ((CC == CallingConv::X86_FastCall || CC == CallingConv::X86_StdCall) &&
21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // "Pure" variadic functions do not receive @0 suffix.
22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          (!FT->isVarArg() || FT->getNumParams() == 0 ||
22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           (FT->getNumParams() == 1 && F->hasStructRetAttr())))
22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        AddFastCallStdCallSuffix(OutName, F, TD);
22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// getSymbol - Return the MCSymbol for the specified global value.  This
22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// symbol is the main label that is the address of the global.
22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanMCSymbol *Mangler::getSymbol(const GlobalValue *GV) {
23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallString<60> NameStr;
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  getNameWithPrefix(NameStr, GV, false);
23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Context.GetOrCreateSymbol(NameStr.str());
23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
236