Mangler.cpp revision 205218
1202878Srdivacky//===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
2202878Srdivacky//
3202878Srdivacky//                     The LLVM Compiler Infrastructure
4202878Srdivacky//
5202878Srdivacky// This file is distributed under the University of Illinois Open Source
6202878Srdivacky// License. See LICENSE.TXT for details.
7202878Srdivacky//
8202878Srdivacky//===----------------------------------------------------------------------===//
9202878Srdivacky//
10202878Srdivacky// Unified name mangler for assembly backends.
11202878Srdivacky//
12202878Srdivacky//===----------------------------------------------------------------------===//
13202878Srdivacky
14202878Srdivacky#include "llvm/Target/Mangler.h"
15205218Srdivacky#include "llvm/DerivedTypes.h"
16205218Srdivacky#include "llvm/Function.h"
17205218Srdivacky#include "llvm/Target/TargetData.h"
18202878Srdivacky#include "llvm/MC/MCAsmInfo.h"
19205218Srdivacky#include "llvm/MC/MCContext.h"
20205218Srdivacky#include "llvm/Support/raw_ostream.h"
21202878Srdivacky#include "llvm/ADT/SmallString.h"
22202878Srdivacky#include "llvm/ADT/Twine.h"
23202878Srdivackyusing namespace llvm;
24202878Srdivacky
25202878Srdivackystatic bool isAcceptableChar(char C) {
26202878Srdivacky  if ((C < 'a' || C > 'z') &&
27202878Srdivacky      (C < 'A' || C > 'Z') &&
28202878Srdivacky      (C < '0' || C > '9') &&
29202878Srdivacky      C != '_' && C != '$' && C != '.' && C != '@')
30202878Srdivacky    return false;
31202878Srdivacky  return true;
32202878Srdivacky}
33202878Srdivacky
34202878Srdivackystatic char HexDigit(int V) {
35202878Srdivacky  return V < 10 ? V+'0' : V+'A'-10;
36202878Srdivacky}
37202878Srdivacky
38202878Srdivackystatic void MangleLetter(SmallVectorImpl<char> &OutName, unsigned char C) {
39202878Srdivacky  OutName.push_back('_');
40202878Srdivacky  OutName.push_back(HexDigit(C >> 4));
41202878Srdivacky  OutName.push_back(HexDigit(C & 15));
42202878Srdivacky  OutName.push_back('_');
43202878Srdivacky}
44202878Srdivacky
45202878Srdivacky/// NameNeedsEscaping - Return true if the identifier \arg Str needs quotes
46202878Srdivacky/// for this assembler.
47202878Srdivackystatic bool NameNeedsEscaping(StringRef Str, const MCAsmInfo &MAI) {
48202878Srdivacky  assert(!Str.empty() && "Cannot create an empty MCSymbol");
49202878Srdivacky
50202878Srdivacky  // If the first character is a number and the target does not allow this, we
51202878Srdivacky  // need quotes.
52202878Srdivacky  if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9')
53202878Srdivacky    return true;
54202878Srdivacky
55202878Srdivacky  // If any of the characters in the string is an unacceptable character, force
56202878Srdivacky  // quotes.
57202878Srdivacky  for (unsigned i = 0, e = Str.size(); i != e; ++i)
58202878Srdivacky    if (!isAcceptableChar(Str[i]))
59202878Srdivacky      return true;
60202878Srdivacky  return false;
61202878Srdivacky}
62202878Srdivacky
63202878Srdivacky/// appendMangledName - Add the specified string in mangled form if it uses
64202878Srdivacky/// any unusual characters.
65202878Srdivackystatic void appendMangledName(SmallVectorImpl<char> &OutName, StringRef Str,
66205218Srdivacky                              const MCAsmInfo &MAI) {
67202878Srdivacky  // The first character is not allowed to be a number unless the target
68202878Srdivacky  // explicitly allows it.
69205218Srdivacky  if (!MAI.doesAllowNameToStartWithDigit() && Str[0] >= '0' && Str[0] <= '9') {
70202878Srdivacky    MangleLetter(OutName, Str[0]);
71202878Srdivacky    Str = Str.substr(1);
72202878Srdivacky  }
73202878Srdivacky
74202878Srdivacky  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
75202878Srdivacky    if (!isAcceptableChar(Str[i]))
76202878Srdivacky      MangleLetter(OutName, Str[i]);
77202878Srdivacky    else
78202878Srdivacky      OutName.push_back(Str[i]);
79202878Srdivacky  }
80202878Srdivacky}
81202878Srdivacky
82202878Srdivacky
83202878Srdivacky/// appendMangledQuotedName - On systems that support quoted symbols, we still
84202878Srdivacky/// have to escape some (obscure) characters like " and \n which would break the
85202878Srdivacky/// assembler's lexing.
86202878Srdivackystatic void appendMangledQuotedName(SmallVectorImpl<char> &OutName,
87202878Srdivacky                                   StringRef Str) {
88202878Srdivacky  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
89202878Srdivacky    if (Str[i] == '"' || Str[i] == '\n')
90202878Srdivacky      MangleLetter(OutName, Str[i]);
91202878Srdivacky    else
92202878Srdivacky      OutName.push_back(Str[i]);
93202878Srdivacky  }
94202878Srdivacky}
95202878Srdivacky
96202878Srdivacky
97202878Srdivacky/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
98202878Srdivacky/// and the specified name as the global variable name.  GVName must not be
99202878Srdivacky/// empty.
100202878Srdivackyvoid Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
101202878Srdivacky                                const Twine &GVName, ManglerPrefixTy PrefixTy) {
102202878Srdivacky  SmallString<256> TmpData;
103202878Srdivacky  StringRef Name = GVName.toStringRef(TmpData);
104202878Srdivacky  assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
105202878Srdivacky
106205218Srdivacky  const MCAsmInfo &MAI = Context.getAsmInfo();
107205218Srdivacky
108202878Srdivacky  // If the global name is not led with \1, add the appropriate prefixes.
109202878Srdivacky  if (Name[0] == '\1') {
110202878Srdivacky    Name = Name.substr(1);
111202878Srdivacky  } else {
112202878Srdivacky    if (PrefixTy == Mangler::Private) {
113202878Srdivacky      const char *Prefix = MAI.getPrivateGlobalPrefix();
114202878Srdivacky      OutName.append(Prefix, Prefix+strlen(Prefix));
115202878Srdivacky    } else if (PrefixTy == Mangler::LinkerPrivate) {
116202878Srdivacky      const char *Prefix = MAI.getLinkerPrivateGlobalPrefix();
117202878Srdivacky      OutName.append(Prefix, Prefix+strlen(Prefix));
118202878Srdivacky    }
119202878Srdivacky
120202878Srdivacky    const char *Prefix = MAI.getGlobalPrefix();
121202878Srdivacky    if (Prefix[0] == 0)
122202878Srdivacky      ; // Common noop, no prefix.
123202878Srdivacky    else if (Prefix[1] == 0)
124202878Srdivacky      OutName.push_back(Prefix[0]);  // Common, one character prefix.
125202878Srdivacky    else
126202878Srdivacky      OutName.append(Prefix, Prefix+strlen(Prefix)); // Arbitrary length prefix.
127202878Srdivacky  }
128202878Srdivacky
129202878Srdivacky  // If this is a simple string that doesn't need escaping, just append it.
130202878Srdivacky  if (!NameNeedsEscaping(Name, MAI) ||
131202878Srdivacky      // If quotes are supported, they can be used unless the string contains
132202878Srdivacky      // a quote or newline.
133202878Srdivacky      (MAI.doesAllowQuotesInName() &&
134202878Srdivacky       Name.find_first_of("\n\"") == StringRef::npos)) {
135202878Srdivacky    OutName.append(Name.begin(), Name.end());
136202878Srdivacky    return;
137202878Srdivacky  }
138202878Srdivacky
139202878Srdivacky  // On systems that do not allow quoted names, we need to mangle most
140202878Srdivacky  // strange characters.
141202878Srdivacky  if (!MAI.doesAllowQuotesInName())
142205218Srdivacky    return appendMangledName(OutName, Name, MAI);
143202878Srdivacky
144202878Srdivacky  // Okay, the system allows quoted strings.  We can quote most anything, the
145202878Srdivacky  // only characters that need escaping are " and \n.
146202878Srdivacky  assert(Name.find_first_of("\n\"") != StringRef::npos);
147202878Srdivacky  return appendMangledQuotedName(OutName, Name);
148202878Srdivacky}
149202878Srdivacky
150205218Srdivacky/// AddFastCallStdCallSuffix - Microsoft fastcall and stdcall functions require
151205218Srdivacky/// a suffix on their name indicating the number of words of arguments they
152205218Srdivacky/// take.
153205218Srdivackystatic void AddFastCallStdCallSuffix(SmallVectorImpl<char> &OutName,
154205218Srdivacky                                     const Function *F, const TargetData &TD) {
155205218Srdivacky  // Calculate arguments size total.
156205218Srdivacky  unsigned ArgWords = 0;
157205218Srdivacky  for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
158205218Srdivacky       AI != AE; ++AI) {
159205218Srdivacky    const Type *Ty = AI->getType();
160205218Srdivacky    // 'Dereference' type in case of byval parameter attribute
161205218Srdivacky    if (AI->hasByValAttr())
162205218Srdivacky      Ty = cast<PointerType>(Ty)->getElementType();
163205218Srdivacky    // Size should be aligned to DWORD boundary
164205218Srdivacky    ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4;
165205218Srdivacky  }
166205218Srdivacky
167205218Srdivacky  raw_svector_ostream(OutName) << '@' << ArgWords;
168205218Srdivacky}
169202878Srdivacky
170205218Srdivacky
171202878Srdivacky/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
172202878Srdivacky/// and the specified global variable's name.  If the global variable doesn't
173202878Srdivacky/// have a name, this fills in a unique name for the global.
174202878Srdivackyvoid Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
175202878Srdivacky                                const GlobalValue *GV,
176202878Srdivacky                                bool isImplicitlyPrivate) {
177202878Srdivacky  ManglerPrefixTy PrefixTy = Mangler::Default;
178202878Srdivacky  if (GV->hasPrivateLinkage() || isImplicitlyPrivate)
179202878Srdivacky    PrefixTy = Mangler::Private;
180202878Srdivacky  else if (GV->hasLinkerPrivateLinkage())
181202878Srdivacky    PrefixTy = Mangler::LinkerPrivate;
182202878Srdivacky
183202878Srdivacky  // If this global has a name, handle it simply.
184205218Srdivacky  if (GV->hasName()) {
185205218Srdivacky    getNameWithPrefix(OutName, GV->getName(), PrefixTy);
186205218Srdivacky  } else {
187205218Srdivacky    // Get the ID for the global, assigning a new one if we haven't got one
188205218Srdivacky    // already.
189205218Srdivacky    unsigned &ID = AnonGlobalIDs[GV];
190205218Srdivacky    if (ID == 0) ID = NextAnonGlobalID++;
191202878Srdivacky
192205218Srdivacky    // Must mangle the global into a unique ID.
193205218Srdivacky    getNameWithPrefix(OutName, "__unnamed_" + Twine(ID), PrefixTy);
194205218Srdivacky  }
195202878Srdivacky
196205218Srdivacky  // If we are supposed to add a microsoft-style suffix for stdcall/fastcall,
197205218Srdivacky  // add it.
198205218Srdivacky  if (Context.getAsmInfo().hasMicrosoftFastStdCallMangling()) {
199205218Srdivacky    if (const Function *F = dyn_cast<Function>(GV)) {
200205218Srdivacky      CallingConv::ID CC = F->getCallingConv();
201205218Srdivacky
202205218Srdivacky      // fastcall functions need to start with @.
203205218Srdivacky      // FIXME: This logic seems unlikely to be right.
204205218Srdivacky      if (CC == CallingConv::X86_FastCall) {
205205218Srdivacky        if (OutName[0] == '_')
206205218Srdivacky          OutName[0] = '@';
207205218Srdivacky        else
208205218Srdivacky          OutName.insert(OutName.begin(), '@');
209205218Srdivacky      }
210205218Srdivacky
211205218Srdivacky      // fastcall and stdcall functions usually need @42 at the end to specify
212205218Srdivacky      // the argument info.
213205218Srdivacky      const FunctionType *FT = F->getFunctionType();
214205218Srdivacky      if ((CC == CallingConv::X86_FastCall || CC == CallingConv::X86_StdCall) &&
215205218Srdivacky          // "Pure" variadic functions do not receive @0 suffix.
216205218Srdivacky          (!FT->isVarArg() || FT->getNumParams() == 0 ||
217205218Srdivacky           (FT->getNumParams() == 1 && F->hasStructRetAttr())))
218205218Srdivacky        AddFastCallStdCallSuffix(OutName, F, TD);
219205218Srdivacky    }
220205218Srdivacky  }
221202878Srdivacky}
222202878Srdivacky
223202878Srdivacky/// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
224202878Srdivacky/// and the specified global variable's name.  If the global variable doesn't
225202878Srdivacky/// have a name, this fills in a unique name for the global.
226202878Srdivackystd::string Mangler::getNameWithPrefix(const GlobalValue *GV,
227202878Srdivacky                                       bool isImplicitlyPrivate) {
228202878Srdivacky  SmallString<64> Buf;
229202878Srdivacky  getNameWithPrefix(Buf, GV, isImplicitlyPrivate);
230202878Srdivacky  return std::string(Buf.begin(), Buf.end());
231202878Srdivacky}
232205218Srdivacky
233205218Srdivacky/// getSymbol - Return the MCSymbol for the specified global value.  This
234205218Srdivacky/// symbol is the main label that is the address of the global.
235205218SrdivackyMCSymbol *Mangler::getSymbol(const GlobalValue *GV) {
236205218Srdivacky  SmallString<60> NameStr;
237205218Srdivacky  getNameWithPrefix(NameStr, GV, false);
238205218Srdivacky  if (!GV->hasPrivateLinkage())
239205218Srdivacky    return Context.GetOrCreateSymbol(NameStr.str());
240205218Srdivacky
241205218Srdivacky  return Context.GetOrCreateTemporarySymbol(NameStr.str());
242205218Srdivacky}
243205218Srdivacky
244205218Srdivacky
245