summaryrefslogtreecommitdiff
path: root/lib/Target/X86/X86COFFMachineModuleInfo.cpp
blob: 2988e4f91d07ff6f0f8d44bb64b65f4ffaf0dd7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//===-- llvm/CodeGen/X86COFFMachineModuleInfo.cpp -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is an MMI implementation for X86 COFF (windows) targets.
//
//===----------------------------------------------------------------------===//

#include "X86COFFMachineModuleInfo.h"
#include "X86MachineFunctionInfo.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;


X86COFFMachineModuleInfo::~X86COFFMachineModuleInfo() {
}

/// DecorateCygMingName - Query FunctionInfoMap and use this information for
/// various name decorations for Cygwin and MingW.
MCSymbol *X86COFFMachineModuleInfo::DecorateCygMingName(MCSymbol *NameSym,
                                                        MCContext &Ctx,
                                                        const Function *F,
                                                        const TargetData &TD) {
  // We don't want to decorate non-stdcall or non-fastcall functions right now
  CallingConv::ID CC = F->getCallingConv();
  if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall)
    return NameSym;
  
  unsigned ArgWords = 0;
  
  // Calculate arguments sizes
  for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
       AI != AE; ++AI) {
    const Type *Ty = AI->getType();
    
    // 'Dereference' type in case of byval parameter attribute
    if (AI->hasByValAttr())
      Ty = cast<PointerType>(Ty)->getElementType();
    
    // Size should be aligned to DWORD boundary
    ArgWords += ((TD.getTypeAllocSize(Ty) + 3)/4)*4;
  }
  
  const FunctionType *FT = F->getFunctionType();
  
  SmallString<128> Name(NameSym->getName().begin(), NameSym->getName().end());

  // "Pure" variadic functions do not receive @0 suffix.
  if (!FT->isVarArg() || FT->getNumParams() == 0 ||
      (FT->getNumParams() == 1 && F->hasStructRetAttr()))
    raw_svector_ostream(Name) << '@' << ArgWords;
  
  if (CC == CallingConv::X86_FastCall) {
    if (Name[0] == '_')
      Name[0] = '@';
    else
      Name.insert(Name.begin(), '@');
  }
  
  return Ctx.GetOrCreateSymbol(Name.str());
}