1274955Ssvnmir//===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
2274955Ssvnmir//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6274955Ssvnmir//
7274955Ssvnmir//===----------------------------------------------------------------------===//
8274955Ssvnmir//
9274955Ssvnmir// Unified name mangler for assembly backends.
10274955Ssvnmir//
11274955Ssvnmir//===----------------------------------------------------------------------===//
12274955Ssvnmir
13274955Ssvnmir#include "llvm/IR/Mangler.h"
14274955Ssvnmir#include "llvm/ADT/SmallString.h"
15321369Sdim#include "llvm/ADT/Triple.h"
16274955Ssvnmir#include "llvm/ADT/Twine.h"
17274955Ssvnmir#include "llvm/IR/DataLayout.h"
18274955Ssvnmir#include "llvm/IR/DerivedTypes.h"
19274955Ssvnmir#include "llvm/IR/Function.h"
20288943Sdim#include "llvm/IR/Module.h"
21274955Ssvnmir#include "llvm/Support/raw_ostream.h"
22274955Ssvnmirusing namespace llvm;
23274955Ssvnmir
24288943Sdimnamespace {
25288943Sdimenum ManglerPrefixTy {
26288943Sdim  Default,      ///< Emit default string before each symbol.
27288943Sdim  Private,      ///< Emit "private" prefix before each symbol.
28288943Sdim  LinkerPrivate ///< Emit "linker private" prefix before each symbol.
29288943Sdim};
30288943Sdim}
31288943Sdim
32288943Sdimstatic void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName,
33288943Sdim                                  ManglerPrefixTy PrefixTy,
34288943Sdim                                  const DataLayout &DL, char Prefix) {
35274955Ssvnmir  SmallString<256> TmpData;
36274955Ssvnmir  StringRef Name = GVName.toStringRef(TmpData);
37274955Ssvnmir  assert(!Name.empty() && "getNameWithPrefix requires non-empty name");
38274955Ssvnmir
39280031Sdim  // No need to do anything special if the global has the special "do not
40280031Sdim  // mangle" flag in the name.
41280031Sdim  if (Name[0] == '\1') {
42280031Sdim    OS << Name.substr(1);
43280031Sdim    return;
44280031Sdim  }
45280031Sdim
46341825Sdim  if (DL.doNotMangleLeadingQuestionMark() && Name[0] == '?')
47341825Sdim    Prefix = '\0';
48341825Sdim
49288943Sdim  if (PrefixTy == Private)
50274955Ssvnmir    OS << DL.getPrivateGlobalPrefix();
51288943Sdim  else if (PrefixTy == LinkerPrivate)
52274955Ssvnmir    OS << DL.getLinkerPrivateGlobalPrefix();
53274955Ssvnmir
54280031Sdim  if (Prefix != '\0')
55280031Sdim    OS << Prefix;
56274955Ssvnmir
57274955Ssvnmir  // If this is a simple string that doesn't need escaping, just append it.
58274955Ssvnmir  OS << Name;
59274955Ssvnmir}
60274955Ssvnmir
61288943Sdimstatic void getNameWithPrefixImpl(raw_ostream &OS, const Twine &GVName,
62288943Sdim                                  const DataLayout &DL,
63288943Sdim                                  ManglerPrefixTy PrefixTy) {
64288943Sdim  char Prefix = DL.getGlobalPrefix();
65288943Sdim  return getNameWithPrefixImpl(OS, GVName, PrefixTy, DL, Prefix);
66288943Sdim}
67288943Sdim
68274955Ssvnmirvoid Mangler::getNameWithPrefix(raw_ostream &OS, const Twine &GVName,
69288943Sdim                                const DataLayout &DL) {
70288943Sdim  return getNameWithPrefixImpl(OS, GVName, DL, Default);
71274955Ssvnmir}
72274955Ssvnmir
73274955Ssvnmirvoid Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
74288943Sdim                                const Twine &GVName, const DataLayout &DL) {
75274955Ssvnmir  raw_svector_ostream OS(OutName);
76288943Sdim  char Prefix = DL.getGlobalPrefix();
77288943Sdim  return getNameWithPrefixImpl(OS, GVName, Default, DL, Prefix);
78274955Ssvnmir}
79274955Ssvnmir
80280031Sdimstatic bool hasByteCountSuffix(CallingConv::ID CC) {
81280031Sdim  switch (CC) {
82280031Sdim  case CallingConv::X86_FastCall:
83280031Sdim  case CallingConv::X86_StdCall:
84280031Sdim  case CallingConv::X86_VectorCall:
85280031Sdim    return true;
86280031Sdim  default:
87280031Sdim    return false;
88280031Sdim  }
89280031Sdim}
90280031Sdim
91280031Sdim/// Microsoft fastcall and stdcall functions require a suffix on their name
92280031Sdim/// indicating the number of words of arguments they take.
93280031Sdimstatic void addByteCountSuffix(raw_ostream &OS, const Function *F,
94288943Sdim                               const DataLayout &DL) {
95274955Ssvnmir  // Calculate arguments size total.
96274955Ssvnmir  unsigned ArgWords = 0;
97274955Ssvnmir  for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
98274955Ssvnmir       AI != AE; ++AI) {
99274955Ssvnmir    Type *Ty = AI->getType();
100274955Ssvnmir    // 'Dereference' type in case of byval or inalloca parameter attribute.
101274955Ssvnmir    if (AI->hasByValOrInAllocaAttr())
102274955Ssvnmir      Ty = cast<PointerType>(Ty)->getElementType();
103280031Sdim    // Size should be aligned to pointer size.
104288943Sdim    unsigned PtrSize = DL.getPointerSize();
105309124Sdim    ArgWords += alignTo(DL.getTypeAllocSize(Ty), PtrSize);
106274955Ssvnmir  }
107274955Ssvnmir
108274955Ssvnmir  OS << '@' << ArgWords;
109274955Ssvnmir}
110274955Ssvnmir
111274955Ssvnmirvoid Mangler::getNameWithPrefix(raw_ostream &OS, const GlobalValue *GV,
112274955Ssvnmir                                bool CannotUsePrivateLabel) const {
113288943Sdim  ManglerPrefixTy PrefixTy = Default;
114274955Ssvnmir  if (GV->hasPrivateLinkage()) {
115274955Ssvnmir    if (CannotUsePrivateLabel)
116288943Sdim      PrefixTy = LinkerPrivate;
117274955Ssvnmir    else
118288943Sdim      PrefixTy = Private;
119274955Ssvnmir  }
120274955Ssvnmir
121288943Sdim  const DataLayout &DL = GV->getParent()->getDataLayout();
122274955Ssvnmir  if (!GV->hasName()) {
123274955Ssvnmir    // Get the ID for the global, assigning a new one if we haven't got one
124274955Ssvnmir    // already.
125274955Ssvnmir    unsigned &ID = AnonGlobalIDs[GV];
126274955Ssvnmir    if (ID == 0)
127314564Sdim      ID = AnonGlobalIDs.size();
128274955Ssvnmir
129274955Ssvnmir    // Must mangle the global into a unique ID.
130288943Sdim    getNameWithPrefixImpl(OS, "__unnamed_" + Twine(ID), DL, PrefixTy);
131274955Ssvnmir    return;
132274955Ssvnmir  }
133274955Ssvnmir
134274955Ssvnmir  StringRef Name = GV->getName();
135288943Sdim  char Prefix = DL.getGlobalPrefix();
136274955Ssvnmir
137280031Sdim  // Mangle functions with Microsoft calling conventions specially.  Only do
138280031Sdim  // this mangling for x86_64 vectorcall and 32-bit x86.
139280031Sdim  const Function *MSFunc = dyn_cast<Function>(GV);
140341825Sdim
141341825Sdim  // Don't add byte count suffixes when '\01' or '?' are in the first
142341825Sdim  // character.
143341825Sdim  if (Name.startswith("\01") ||
144341825Sdim      (DL.doNotMangleLeadingQuestionMark() && Name.startswith("?")))
145341825Sdim    MSFunc = nullptr;
146341825Sdim
147280031Sdim  CallingConv::ID CC =
148280031Sdim      MSFunc ? MSFunc->getCallingConv() : (unsigned)CallingConv::C;
149288943Sdim  if (!DL.hasMicrosoftFastStdCallMangling() &&
150280031Sdim      CC != CallingConv::X86_VectorCall)
151280031Sdim    MSFunc = nullptr;
152280031Sdim  if (MSFunc) {
153280031Sdim    if (CC == CallingConv::X86_FastCall)
154280031Sdim      Prefix = '@'; // fastcall functions have an @ prefix instead of _.
155280031Sdim    else if (CC == CallingConv::X86_VectorCall)
156280031Sdim      Prefix = '\0'; // vectorcall functions have no prefix.
157274955Ssvnmir  }
158274955Ssvnmir
159288943Sdim  getNameWithPrefixImpl(OS, Name, PrefixTy, DL, Prefix);
160274955Ssvnmir
161274955Ssvnmir  if (!MSFunc)
162274955Ssvnmir    return;
163274955Ssvnmir
164280031Sdim  // If we are supposed to add a microsoft-style suffix for stdcall, fastcall,
165280031Sdim  // or vectorcall, add it.  These functions have a suffix of @N where N is the
166280031Sdim  // cumulative byte size of all of the parameters to the function in decimal.
167280031Sdim  if (CC == CallingConv::X86_VectorCall)
168280031Sdim    OS << '@'; // vectorcall functions use a double @ suffix.
169274955Ssvnmir  FunctionType *FT = MSFunc->getFunctionType();
170280031Sdim  if (hasByteCountSuffix(CC) &&
171274955Ssvnmir      // "Pure" variadic functions do not receive @0 suffix.
172274955Ssvnmir      (!FT->isVarArg() || FT->getNumParams() == 0 ||
173274955Ssvnmir       (FT->getNumParams() == 1 && MSFunc->hasStructRetAttr())))
174288943Sdim    addByteCountSuffix(OS, MSFunc, DL);
175274955Ssvnmir}
176274955Ssvnmir
177274955Ssvnmirvoid Mangler::getNameWithPrefix(SmallVectorImpl<char> &OutName,
178274955Ssvnmir                                const GlobalValue *GV,
179274955Ssvnmir                                bool CannotUsePrivateLabel) const {
180274955Ssvnmir  raw_svector_ostream OS(OutName);
181274955Ssvnmir  getNameWithPrefix(OS, GV, CannotUsePrivateLabel);
182274955Ssvnmir}
183321369Sdim
184321369Sdimvoid llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
185321369Sdim                                        const Triple &TT, Mangler &Mangler) {
186321369Sdim  if (!GV->hasDLLExportStorageClass() || GV->isDeclaration())
187321369Sdim    return;
188321369Sdim
189353358Sdim  if (TT.isWindowsMSVCEnvironment())
190321369Sdim    OS << " /EXPORT:";
191321369Sdim  else
192321369Sdim    OS << " -export:";
193321369Sdim
194321369Sdim  if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
195321369Sdim    std::string Flag;
196321369Sdim    raw_string_ostream FlagOS(Flag);
197321369Sdim    Mangler.getNameWithPrefix(FlagOS, GV, false);
198321369Sdim    FlagOS.flush();
199321369Sdim    if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix())
200321369Sdim      OS << Flag.substr(1);
201321369Sdim    else
202321369Sdim      OS << Flag;
203321369Sdim  } else {
204321369Sdim    Mangler.getNameWithPrefix(OS, GV, false);
205321369Sdim  }
206321369Sdim
207321369Sdim  if (!GV->getValueType()->isFunctionTy()) {
208353358Sdim    if (TT.isWindowsMSVCEnvironment())
209321369Sdim      OS << ",DATA";
210321369Sdim    else
211321369Sdim      OS << ",data";
212321369Sdim  }
213321369Sdim}
214341825Sdim
215341825Sdimvoid llvm::emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV,
216341825Sdim                                      const Triple &T, Mangler &M) {
217353358Sdim  if (!T.isWindowsMSVCEnvironment())
218341825Sdim    return;
219341825Sdim
220341825Sdim  OS << " /INCLUDE:";
221341825Sdim  M.getNameWithPrefix(OS, GV, false);
222341825Sdim}
223341825Sdim
224