Emit personality function and Dwarf EH data for Win64 SEH.
[oota-llvm.git] / lib / MC / MCModule.cpp
1 //===- lib/MC/MCModule.cpp - MCModule implementation ----------------------===//
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 #include "llvm/MC/MCModule.h"
11 #include "llvm/MC/MCAtom.h"
12 #include "llvm/MC/MCFunction.h"
13 #include <algorithm>
14
15 using namespace llvm;
16
17 static bool AtomComp(const MCAtom *LHS, const MCAtom *RHS) {
18   return LHS->getEndAddr() < RHS->getEndAddr();
19 }
20
21 MCModule::const_atom_iterator MCModule::atom_lower_bound(uint64_t Addr) const {
22   // This is a dummy atom, because VS 2008 doesn't like asymmetric comparators.
23   MCDataAtom AddrAtom(0, Addr, Addr);
24   return std::lower_bound(atom_begin(), atom_end(), &AddrAtom, AtomComp);
25 }
26
27 MCModule::atom_iterator MCModule::atom_lower_bound(uint64_t Addr) {
28   MCDataAtom AddrAtom(0, Addr, Addr);
29   return std::lower_bound(atom_begin(), atom_end(), &AddrAtom, AtomComp);
30 }
31
32 void MCModule::map(MCAtom *NewAtom) {
33   uint64_t Begin = NewAtom->Begin;
34
35   assert(Begin <= NewAtom->End && "Creating MCAtom with endpoints reversed?");
36
37   // Check for atoms already covering this range.
38   AtomListTy::iterator I = atom_lower_bound(Begin);
39   assert((I == atom_end() || (*I)->getBeginAddr() > NewAtom->End)
40          && "Offset range already occupied!");
41
42   // Insert the new atom to the list.
43   Atoms.insert(I, NewAtom);
44 }
45
46 MCTextAtom *MCModule::createTextAtom(uint64_t Begin, uint64_t End) {
47   MCTextAtom *NewAtom = new MCTextAtom(this, Begin, End);
48   map(NewAtom);
49   return NewAtom;
50 }
51
52 MCDataAtom *MCModule::createDataAtom(uint64_t Begin, uint64_t End) {
53   MCDataAtom *NewAtom = new MCDataAtom(this, Begin, End);
54   map(NewAtom);
55   return NewAtom;
56 }
57
58 // remap - Update the interval mapping for an atom.
59 void MCModule::remap(MCAtom *Atom, uint64_t NewBegin, uint64_t NewEnd) {
60   // Find and erase the old mapping.
61   AtomListTy::iterator I = atom_lower_bound(Atom->Begin);
62   assert(I != atom_end() && "Atom offset not found in module!");
63   assert(*I == Atom && "Previous atom mapping was invalid!");
64   Atoms.erase(I);
65
66   // Insert the new mapping.
67   AtomListTy::iterator NewI = atom_lower_bound(NewBegin);
68   Atoms.insert(NewI, Atom);
69
70   // Update the atom internal bounds.
71   Atom->Begin = NewBegin;
72   Atom->End = NewEnd;
73 }
74
75 const MCAtom *MCModule::findAtomContaining(uint64_t Addr) const {
76   AtomListTy::const_iterator I = atom_lower_bound(Addr);
77   if (I != atom_end() && (*I)->getBeginAddr() <= Addr)
78     return *I;
79   return 0;
80 }
81
82 MCAtom *MCModule::findAtomContaining(uint64_t Addr) {
83   AtomListTy::iterator I = atom_lower_bound(Addr);
84   if (I != atom_end() && (*I)->getBeginAddr() <= Addr)
85     return *I;
86   return 0;
87 }
88
89 MCFunction *MCModule::createFunction(const StringRef &Name) {
90   Functions.push_back(new MCFunction(Name));
91   return Functions.back();
92 }
93
94 MCModule::~MCModule() {
95   for (AtomListTy::iterator AI = atom_begin(),
96                             AE = atom_end();
97                             AI != AE; ++AI)
98     delete *AI;
99   for (FunctionListTy::iterator FI = func_begin(),
100                                 FE = func_end();
101                                 FI != FE; ++FI)
102     delete *FI;
103 }