1eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//===-- CodeGen/AsmPrinter/DwarfException.cpp - Dwarf Exception Impl ------===//
2eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//
3eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//                     The LLVM Compiler Infrastructure
4eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//
5eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// This file is distributed under the University of Illinois Open Source
6eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling// License. See LICENSE.TXT for details.
7eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//
8eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//===----------------------------------------------------------------------===//
9eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//
1028275fdf02885587156da5cb20388b22d5b96557Bill Wendling// This file contains support for writing DWARF exception info into asm files.
11eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//
12eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling//===----------------------------------------------------------------------===//
13eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
14eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "DwarfException.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallString.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/StringExtras.h"
17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Twine.h"
186d7337896f1bcdfbdee90c9c33371c2a373f422aChris Lattner#include "llvm/CodeGen/AsmPrinter.h"
19eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/CodeGen/MachineFrameInfo.h"
20fc4da0cea8a0f6c9c1483b92c2dffda217c0ba24David Greene#include "llvm/CodeGen/MachineFunction.h"
21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineModuleInfo.h"
220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h"
230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
248c6ed05157e9c97ff8f3ccb211dd797e53228da1Chris Lattner#include "llvm/MC/MCAsmInfo.h"
258c6ed05157e9c97ff8f3ccb211dd797e53228da1Chris Lattner#include "llvm/MC/MCContext.h"
268c6ed05157e9c97ff8f3ccb211dd797e53228da1Chris Lattner#include "llvm/MC/MCExpr.h"
2743e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling#include "llvm/MC/MCSection.h"
286c2f9e14fdf14d8c1c687c6bd9918183fa7f8a7fChris Lattner#include "llvm/MC/MCStreamer.h"
297a2ba94d03b43f41b54872dacd7b2250dde4c7bdChris Lattner#include "llvm/MC/MCSymbol.h"
30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/Dwarf.h"
31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ErrorHandling.h"
32d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/FormattedStream.h"
3345111d160cf0910030eeb6a949c69273502e5ad5Chris Lattner#include "llvm/Target/Mangler.h"
3416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "llvm/Target/TargetFrameLowering.h"
35d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner#include "llvm/Target/TargetLoweringObjectFile.h"
36eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling#include "llvm/Target/TargetOptions.h"
37d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner#include "llvm/Target/TargetRegisterInfo.h"
38eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingusing namespace llvm;
39eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
4075f50725c1d7f86ee545337b155b4feac66627f6Chris LattnerDwarfException::DwarfException(AsmPrinter *A)
41d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov  : Asm(A), MMI(Asm->MMI) {}
42bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling
435f017e8086c4481da7f5ead2e1d66159e1cc9255Bill WendlingDwarfException::~DwarfException() {}
44bc0d23afae781c45f92865c1c27bed0ce51fe545Bill Wendling
45eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// SharedTypeIds - How many leading type ids two landing pads have in common.
46eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingunsigned DwarfException::SharedTypeIds(const LandingPadInfo *L,
47eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling                                       const LandingPadInfo *R) {
48eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
49eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  unsigned LSize = LIds.size(), RSize = RIds.size();
50eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  unsigned MinSize = LSize < RSize ? LSize : RSize;
51eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  unsigned Count = 0;
52eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
53eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  for (; Count != MinSize; ++Count)
54eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling    if (LIds[Count] != RIds[Count])
55eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      return Count;
56eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
57eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  return Count;
58eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling}
59eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
60eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// PadLT - Order landing pads lexicographically by type id.
61eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingbool DwarfException::PadLT(const LandingPadInfo *L, const LandingPadInfo *R) {
62eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  const std::vector<int> &LIds = L->TypeIds, &RIds = R->TypeIds;
63eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  unsigned LSize = LIds.size(), RSize = RIds.size();
64eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  unsigned MinSize = LSize < RSize ? LSize : RSize;
65eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
66eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  for (unsigned i = 0; i != MinSize; ++i)
67eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling    if (LIds[i] != RIds[i])
68eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      return LIds[i] < RIds[i];
69eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
70eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  return LSize < RSize;
71eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling}
72eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
73d4609622ade8d0ebaf57fd70700c2fedf0b3d165Bill Wendling/// ComputeActionsTable - Compute the actions table and gather the first action
74d4609622ade8d0ebaf57fd70700c2fedf0b3d165Bill Wendling/// index for each landing pad site.
75ade025c65c12503aba161a4fa399fd97414abaffBill Wendlingunsigned DwarfException::
76ade025c65c12503aba161a4fa399fd97414abaffBill WendlingComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
77ade025c65c12503aba161a4fa399fd97414abaffBill Wendling                    SmallVectorImpl<ActionEntry> &Actions,
78ade025c65c12503aba161a4fa399fd97414abaffBill Wendling                    SmallVectorImpl<unsigned> &FirstActions) {
79a583c55864e83e470333b7be878280b10e175a6eBill Wendling
80a583c55864e83e470333b7be878280b10e175a6eBill Wendling  // The action table follows the call-site table in the LSDA. The individual
81a583c55864e83e470333b7be878280b10e175a6eBill Wendling  // records are of two types:
82a583c55864e83e470333b7be878280b10e175a6eBill Wendling  //
83a583c55864e83e470333b7be878280b10e175a6eBill Wendling  //   * Catch clause
84a583c55864e83e470333b7be878280b10e175a6eBill Wendling  //   * Exception specification
85a583c55864e83e470333b7be878280b10e175a6eBill Wendling  //
86a583c55864e83e470333b7be878280b10e175a6eBill Wendling  // The two record kinds have the same format, with only small differences.
87a583c55864e83e470333b7be878280b10e175a6eBill Wendling  // They are distinguished by the "switch value" field: Catch clauses
88a583c55864e83e470333b7be878280b10e175a6eBill Wendling  // (TypeInfos) have strictly positive switch values, and exception
89a583c55864e83e470333b7be878280b10e175a6eBill Wendling  // specifications (FilterIds) have strictly negative switch values. Value 0
90a583c55864e83e470333b7be878280b10e175a6eBill Wendling  // indicates a catch-all clause.
91a583c55864e83e470333b7be878280b10e175a6eBill Wendling  //
925e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling  // Negative type IDs index into FilterIds. Positive type IDs index into
935e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling  // TypeInfos.  The value written for a positive type ID is just the type ID
945e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling  // itself.  For a negative type ID, however, the value written is the
95eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // (negative) byte offset of the corresponding FilterIds entry.  The byte
965e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling  // offset is usually equal to the type ID (because the FilterIds entries are
975e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling  // written using a variable width encoding, which outputs one byte per entry
985e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling  // as long as the value written is not too large) but can differ.  This kind
995e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling  // of complication does not occur for positive type IDs because type infos are
100eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // output using a fixed width encoding.  FilterOffsets[i] holds the byte
101eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // offset corresponding to FilterIds[i].
102409914b773ffd53d53d214394d5636a76f673186Bill Wendling
103409914b773ffd53d53d214394d5636a76f673186Bill Wendling  const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
104eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  SmallVector<int, 16> FilterOffsets;
105eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  FilterOffsets.reserve(FilterIds.size());
106eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  int Offset = -1;
107409914b773ffd53d53d214394d5636a76f673186Bill Wendling
108409914b773ffd53d53d214394d5636a76f673186Bill Wendling  for (std::vector<unsigned>::const_iterator
109409914b773ffd53d53d214394d5636a76f673186Bill Wendling         I = FilterIds.begin(), E = FilterIds.end(); I != E; ++I) {
110eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling    FilterOffsets.push_back(Offset);
111af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner    Offset -= MCAsmInfo::getULEB128Size(*I);
112eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  }
113eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
114eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  FirstActions.reserve(LandingPads.size());
115eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
116eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  int FirstAction = 0;
117eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  unsigned SizeActions = 0;
1185e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling  const LandingPadInfo *PrevLPI = 0;
119409914b773ffd53d53d214394d5636a76f673186Bill Wendling
1205cff487665097d971067cbede1598e249f673182Bill Wendling  for (SmallVectorImpl<const LandingPadInfo *>::const_iterator
1215e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling         I = LandingPads.begin(), E = LandingPads.end(); I != E; ++I) {
1225e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling    const LandingPadInfo *LPI = *I;
1235e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling    const std::vector<int> &TypeIds = LPI->TypeIds;
1249be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner    unsigned NumShared = PrevLPI ? SharedTypeIds(LPI, PrevLPI) : 0;
125eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling    unsigned SizeSiteActions = 0;
126eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
127eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling    if (NumShared < TypeIds.size()) {
128eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      unsigned SizeAction = 0;
1290a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling      unsigned PrevAction = (unsigned)-1;
130eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
131eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      if (NumShared) {
1329be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner        unsigned SizePrevIds = PrevLPI->TypeIds.size();
133eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        assert(Actions.size());
1340a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling        PrevAction = Actions.size() - 1;
1350a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling        SizeAction =
1360a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling          MCAsmInfo::getSLEB128Size(Actions[PrevAction].NextAction) +
1370a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling          MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID);
138eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
139eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        for (unsigned j = NumShared; j != SizePrevIds; ++j) {
1400a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling          assert(PrevAction != (unsigned)-1 && "PrevAction is invalid!");
141eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling          SizeAction -=
1420a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling            MCAsmInfo::getSLEB128Size(Actions[PrevAction].ValueForTypeID);
1430a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling          SizeAction += -Actions[PrevAction].NextAction;
1440a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling          PrevAction = Actions[PrevAction].Previous;
145eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        }
146eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      }
147eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
148eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      // Compute the actions.
1495e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling      for (unsigned J = NumShared, M = TypeIds.size(); J != M; ++J) {
1505e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling        int TypeID = TypeIds[J];
1515e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling        assert(-1 - TypeID < (int)FilterOffsets.size() && "Unknown filter id!");
152eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        int ValueForTypeID = TypeID < 0 ? FilterOffsets[-1 - TypeID] : TypeID;
153af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner        unsigned SizeTypeID = MCAsmInfo::getSLEB128Size(ValueForTypeID);
154eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
155eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        int NextAction = SizeAction ? -(SizeAction + SizeTypeID) : 0;
156af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner        SizeAction = SizeTypeID + MCAsmInfo::getSLEB128Size(NextAction);
157eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        SizeSiteActions += SizeAction;
158eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
159a583c55864e83e470333b7be878280b10e175a6eBill Wendling        ActionEntry Action = { ValueForTypeID, NextAction, PrevAction };
160eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        Actions.push_back(Action);
1610a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling        PrevAction = Actions.size() - 1;
162eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      }
163eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
164eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      // Record the first action of the landing pad site.
165eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      FirstAction = SizeActions + SizeSiteActions - SizeAction + 1;
166eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling    } // else identical - re-use previous FirstAction
167eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
168a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // Information used when created the call-site table. The action record
169a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // field of the call site record is the offset of the first associated
170a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // action record, relative to the start of the actions table. This value is
1710a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling    // biased by 1 (1 indicating the start of the actions table), and 0
172a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // indicates that there are no actions.
173eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling    FirstActions.push_back(FirstAction);
174eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
175eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling    // Compute this sites contribution to size.
176eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling    SizeActions += SizeSiteActions;
1775e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling
1785e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling    PrevLPI = LPI;
179eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  }
180eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
1815e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling  return SizeActions;
1825e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling}
1835e953ddfa3abdd684c8a43f9c9c144f584ec7d6fBill Wendling
184ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling/// CallToNoUnwindFunction - Return `true' if this is a call to a function
185ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling/// marked `nounwind'. Return `false' otherwise.
186ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendlingbool DwarfException::CallToNoUnwindFunction(const MachineInstr *MI) {
1875a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng  assert(MI->isCall() && "This should be a call instruction!");
188ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling
189ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling  bool MarkedNoUnwind = false;
190ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling  bool SawFunc = false;
191ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling
192ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling  for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
193ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling    const MachineOperand &MO = MI->getOperand(I);
194ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling
195cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner    if (!MO.isGlobal()) continue;
196d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov
19746510a73e977273ec67747eb34cbdb43f815e451Dan Gohman    const Function *F = dyn_cast<Function>(MO.getGlobal());
198cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner    if (F == 0) continue;
199cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner
200cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner    if (SawFunc) {
201cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner      // Be conservative. If we have more than one function operand for this
202cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner      // call, then we can't make the assumption that it's the callee and
203cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner      // not a parameter to the call.
204d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov      //
205cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner      // FIXME: Determine if there's a way to say that `F' is the callee or
206cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner      // parameter.
207cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner      MarkedNoUnwind = false;
208cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner      break;
209ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling    }
210cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner
211cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner    MarkedNoUnwind = F->doesNotThrow();
212cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner    SawFunc = true;
213ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling  }
214ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling
215ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling  return MarkedNoUnwind;
216ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling}
217ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling
218ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// ComputeCallSiteTable - Compute the call-site table.  The entry for an invoke
219a583c55864e83e470333b7be878280b10e175a6eBill Wendling/// has a try-range containing the call, a non-zero landing pad, and an
220ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// appropriate action.  The entry for an ordinary call has a try-range
221ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// containing the call and zero for the landing pad and the action.  Calls
222ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// marked 'nounwind' have no entry and must not be contained in the try-range
223ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// of any entry - they form gaps in the table.  Entries must be ordered by
224ade025c65c12503aba161a4fa399fd97414abaffBill Wendling/// try-range address.
225ade025c65c12503aba161a4fa399fd97414abaffBill Wendlingvoid DwarfException::
226ade025c65c12503aba161a4fa399fd97414abaffBill WendlingComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
227ade025c65c12503aba161a4fa399fd97414abaffBill Wendling                     const RangeMapType &PadMap,
228ade025c65c12503aba161a4fa399fd97414abaffBill Wendling                     const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
229ade025c65c12503aba161a4fa399fd97414abaffBill Wendling                     const SmallVectorImpl<unsigned> &FirstActions) {
230eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // The end label of the previous invoke or nounwind try-range.
2311611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner  MCSymbol *LastLabel = 0;
232eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
233eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // Whether there is a potentially throwing instruction (currently this means
234eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // an ordinary call) between the end of the previous try-range and now.
235eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  bool SawPotentiallyThrowing = false;
236eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
2375cff487665097d971067cbede1598e249f673182Bill Wendling  // Whether the last CallSite entry was for an invoke.
238eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  bool PreviousIsInvoke = false;
239eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
240eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // Visit all instructions in order of address.
24184ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner  for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
242eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling       I != E; ++I) {
243eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling    for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
244eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling         MI != E; ++MI) {
245eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      if (!MI->isLabel()) {
2465a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng        if (MI->isCall())
247ed060dcb5c7e9cb2fd11ff3b0b98203fb53063e7Bill Wendling          SawPotentiallyThrowing |= !CallToNoUnwindFunction(MI);
248eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        continue;
249eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      }
250eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
251eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      // End of the previous try-range?
2520397ada8ae1d1bc71037d8cd4a855d3ff04acbbbChris Lattner      MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol();
253eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      if (BeginLabel == LastLabel)
254eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        SawPotentiallyThrowing = false;
255eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
256eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      // Beginning of a new try-range?
25781cf4325698b48b02eddab921ac333c7f25005c3Jeffrey Yasskin      RangeMapType::const_iterator L = PadMap.find(BeginLabel);
258eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      if (L == PadMap.end())
259eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        // Nope, it was just some random label.
260eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        continue;
261eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
262a583c55864e83e470333b7be878280b10e175a6eBill Wendling      const PadRange &P = L->second;
263eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
264eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
265eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling             "Inconsistent landing pad map!");
266eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
267a583c55864e83e470333b7be878280b10e175a6eBill Wendling      // For Dwarf exception handling (SjLj handling doesn't use this). If some
268a583c55864e83e470333b7be878280b10e175a6eBill Wendling      // instruction between the previous try-range and this one may throw,
269a583c55864e83e470333b7be878280b10e175a6eBill Wendling      // create a call-site entry with no landing pad for the region between the
270a583c55864e83e470333b7be878280b10e175a6eBill Wendling      // try-ranges.
2713965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov      if (SawPotentiallyThrowing && Asm->MAI->isExceptionHandlingDwarf()) {
272a583c55864e83e470333b7be878280b10e175a6eBill Wendling        CallSiteEntry Site = { LastLabel, BeginLabel, 0, 0 };
273eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        CallSites.push_back(Site);
274eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        PreviousIsInvoke = false;
275eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      }
276eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
277eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      LastLabel = LandingPad->EndLabels[P.RangeIndex];
278eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      assert(BeginLabel && LastLabel && "Invalid landing pad!");
279eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
280cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner      if (!LandingPad->LandingPadLabel) {
281cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner        // Create a gap.
282cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner        PreviousIsInvoke = false;
283cfd3188a11dd71a6416f5b7aef29c47129f6df4eChris Lattner      } else {
284eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        // This try-range is for an invoke.
285a583c55864e83e470333b7be878280b10e175a6eBill Wendling        CallSiteEntry Site = {
286a583c55864e83e470333b7be878280b10e175a6eBill Wendling          BeginLabel,
287a583c55864e83e470333b7be878280b10e175a6eBill Wendling          LastLabel,
288a583c55864e83e470333b7be878280b10e175a6eBill Wendling          LandingPad->LandingPadLabel,
289a583c55864e83e470333b7be878280b10e175a6eBill Wendling          FirstActions[P.PadIndex]
290a583c55864e83e470333b7be878280b10e175a6eBill Wendling        };
291eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
29233668c0f1a7e374d4c3c53df34efbdf570e0987bJim Grosbach        // Try to merge with the previous call-site. SJLJ doesn't do this
2933965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov        if (PreviousIsInvoke && Asm->MAI->isExceptionHandlingDwarf()) {
294eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling          CallSiteEntry &Prev = CallSites.back();
295eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling          if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
296eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling            // Extend the range of the previous entry.
297eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling            Prev.EndLabel = Site.EndLabel;
298eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling            continue;
299eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling          }
300eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        }
301eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
302eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        // Otherwise, create a new call-site.
3033965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov        if (Asm->MAI->isExceptionHandlingDwarf())
304ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach          CallSites.push_back(Site);
305ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach        else {
306ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach          // SjLj EH must maintain the call sites in the order assigned
307ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach          // to them by the SjLjPrepare pass.
308ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach          unsigned SiteNo = MMI->getCallSiteBeginLabel(BeginLabel);
309ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach          if (CallSites.size() < SiteNo)
310ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach            CallSites.resize(SiteNo);
311ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach          CallSites[SiteNo - 1] = Site;
312ca752c9020a1b1cf151142bd9e0cbca9af12d807Jim Grosbach        }
313eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling        PreviousIsInvoke = true;
314eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling      }
315eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling    }
316eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  }
317eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
318eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // If some instruction between the previous try-range and the end of the
319eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // function may throw, create a call-site entry with no landing pad for the
320eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // region following the try-range.
3213965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov  if (SawPotentiallyThrowing && Asm->MAI->isExceptionHandlingDwarf()) {
322a583c55864e83e470333b7be878280b10e175a6eBill Wendling    CallSiteEntry Site = { LastLabel, 0, 0, 0 };
323eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling    CallSites.push_back(Site);
324eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  }
325ade025c65c12503aba161a4fa399fd97414abaffBill Wendling}
326ade025c65c12503aba161a4fa399fd97414abaffBill Wendling
3270dafca90761097230f02e655fdd541f59b888315Bill Wendling/// EmitExceptionTable - Emit landing pads and actions.
3280dafca90761097230f02e655fdd541f59b888315Bill Wendling///
3290dafca90761097230f02e655fdd541f59b888315Bill Wendling/// The general organization of the table is complex, but the basic concepts are
3300dafca90761097230f02e655fdd541f59b888315Bill Wendling/// easy.  First there is a header which describes the location and organization
3310dafca90761097230f02e655fdd541f59b888315Bill Wendling/// of the three components that follow.
332dbfcdb976367ad5a9d3541fef90cd9f8dde7e2b4Eric Christopher///
3330dafca90761097230f02e655fdd541f59b888315Bill Wendling///  1. The landing pad site information describes the range of code covered by
3340dafca90761097230f02e655fdd541f59b888315Bill Wendling///     the try.  In our case it's an accumulation of the ranges covered by the
3350dafca90761097230f02e655fdd541f59b888315Bill Wendling///     invokes in the try.  There is also a reference to the landing pad that
3360dafca90761097230f02e655fdd541f59b888315Bill Wendling///     handles the exception once processed.  Finally an index into the actions
3370dafca90761097230f02e655fdd541f59b888315Bill Wendling///     table.
338a583c55864e83e470333b7be878280b10e175a6eBill Wendling///  2. The action table, in our case, is composed of pairs of type IDs and next
3390dafca90761097230f02e655fdd541f59b888315Bill Wendling///     action offset.  Starting with the action index from the landing pad
340a583c55864e83e470333b7be878280b10e175a6eBill Wendling///     site, each type ID is checked for a match to the current exception.  If
3410dafca90761097230f02e655fdd541f59b888315Bill Wendling///     it matches then the exception and type id are passed on to the landing
3420dafca90761097230f02e655fdd541f59b888315Bill Wendling///     pad.  Otherwise the next action is looked up.  This chain is terminated
34328275fdf02885587156da5cb20388b22d5b96557Bill Wendling///     with a next action of zero.  If no type id is found then the frame is
3440dafca90761097230f02e655fdd541f59b888315Bill Wendling///     unwound and handling continues.
345a583c55864e83e470333b7be878280b10e175a6eBill Wendling///  3. Type ID table contains references to all the C++ typeinfo for all
34628275fdf02885587156da5cb20388b22d5b96557Bill Wendling///     catches in the function.  This tables is reverse indexed base 1.
347ade025c65c12503aba161a4fa399fd97414abaffBill Wendlingvoid DwarfException::EmitExceptionTable() {
34846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
349ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
350ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
351ade025c65c12503aba161a4fa399fd97414abaffBill Wendling
352ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  // Sort the landing pads in order of their type ids.  This is used to fold
353ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  // duplicate actions.
354ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  SmallVector<const LandingPadInfo *, 64> LandingPads;
355ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  LandingPads.reserve(PadInfos.size());
356ade025c65c12503aba161a4fa399fd97414abaffBill Wendling
357ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  for (unsigned i = 0, N = PadInfos.size(); i != N; ++i)
358ade025c65c12503aba161a4fa399fd97414abaffBill Wendling    LandingPads.push_back(&PadInfos[i]);
359ade025c65c12503aba161a4fa399fd97414abaffBill Wendling
360ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  std::sort(LandingPads.begin(), LandingPads.end(), PadLT);
361ade025c65c12503aba161a4fa399fd97414abaffBill Wendling
362ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  // Compute the actions table and gather the first action index for each
363ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  // landing pad site.
364ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  SmallVector<ActionEntry, 32> Actions;
365ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  SmallVector<unsigned, 64> FirstActions;
3660a9abcbffed2ccef44138f997c070ba9159b1443Bill Wendling  unsigned SizeActions=ComputeActionsTable(LandingPads, Actions, FirstActions);
367ade025c65c12503aba161a4fa399fd97414abaffBill Wendling
368ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  // Invokes and nounwind calls have entries in PadMap (due to being bracketed
369ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  // by try-range labels when lowered).  Ordinary calls do not, so appropriate
37028275fdf02885587156da5cb20388b22d5b96557Bill Wendling  // try-ranges for them need be deduced when using DWARF exception handling.
371ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  RangeMapType PadMap;
372ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
373ade025c65c12503aba161a4fa399fd97414abaffBill Wendling    const LandingPadInfo *LandingPad = LandingPads[i];
374ade025c65c12503aba161a4fa399fd97414abaffBill Wendling    for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
3751611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner      MCSymbol *BeginLabel = LandingPad->BeginLabels[j];
376ade025c65c12503aba161a4fa399fd97414abaffBill Wendling      assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!");
377ade025c65c12503aba161a4fa399fd97414abaffBill Wendling      PadRange P = { i, j };
378ade025c65c12503aba161a4fa399fd97414abaffBill Wendling      PadMap[BeginLabel] = P;
379ade025c65c12503aba161a4fa399fd97414abaffBill Wendling    }
380ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  }
381ade025c65c12503aba161a4fa399fd97414abaffBill Wendling
382ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  // Compute the call-site table.
383ade025c65c12503aba161a4fa399fd97414abaffBill Wendling  SmallVector<CallSiteEntry, 64> CallSites;
3848b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach  ComputeCallSiteTable(CallSites, PadMap, LandingPads, FirstActions);
385eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
386eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // Final tallies.
387eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
388eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // Call sites.
38984ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner  bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
390d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling  bool HaveTTData = IsSJLJ ? (!TypeInfos.empty() || !FilterIds.empty()) : true;
391d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov
3923dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling  unsigned CallSiteTableLength;
393d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling  if (IsSJLJ)
3943dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling    CallSiteTableLength = 0;
3959be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner  else {
3969be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner    unsigned SiteStartSize  = 4; // dwarf::DW_EH_PE_udata4
3979be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner    unsigned SiteLengthSize = 4; // dwarf::DW_EH_PE_udata4
3989be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner    unsigned LandingPadSize = 4; // dwarf::DW_EH_PE_udata4
399d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov    CallSiteTableLength =
4009be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner      CallSites.size() * (SiteStartSize + SiteLengthSize + LandingPadSize);
4019be49131363f79ad58a5deb4daf175a7b1c0ec66Chris Lattner  }
402d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling
4031b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach  for (unsigned i = 0, e = CallSites.size(); i < e; ++i) {
4043dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling    CallSiteTableLength += MCAsmInfo::getULEB128Size(CallSites[i].Action);
405d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling    if (IsSJLJ)
4063dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling      CallSiteTableLength += MCAsmInfo::getULEB128Size(i);
4071b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach  }
408d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling
409eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  // Type infos.
410d5bbb07ec806e6fa1e804afd7073987fdacc83e4Chris Lattner  const MCSection *LSDASection = Asm->getObjFileLowering().getLSDASection();
4119184b25fa543a900463215c11635c2c014ddb623Anton Korobeynikov  unsigned TTypeEncoding;
412a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  unsigned TypeFormatSize;
413eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
41443e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling  if (!HaveTTData) {
41528275fdf02885587156da5cb20388b22d5b96557Bill Wendling    // For SjLj exceptions, if there is no TypeInfo, then we just explicitly say
41628275fdf02885587156da5cb20388b22d5b96557Bill Wendling    // that we're omitting that bit.
4179184b25fa543a900463215c11635c2c014ddb623Anton Korobeynikov    TTypeEncoding = dwarf::DW_EH_PE_omit;
41884ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner    // dwarf::DW_EH_PE_absptr
419426c2bf5cdd2173e4a33aea8cb92cf684a724f4bChandler Carruth    TypeFormatSize = Asm->getDataLayout().getPointerSize();
42081c9a069377e9474d010f04eebe8325fd11429e3Chris Lattner  } else {
421ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    // Okay, we have actual filters or typeinfos to emit.  As such, we need to
422ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    // pick a type encoding for them.  We're about to emit a list of pointers to
423ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    // typeinfo objects at the end of the LSDA.  However, unless we're in static
424ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    // mode, this reference will require a relocation by the dynamic linker.
42546b754c76bd6a720dd1dd3be248cb93a4e25d3e5Chris Lattner    //
426ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    // Because of this, we have a couple of options:
427d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov    //
428ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //   1) If we are in -static mode, we can always use an absolute reference
429ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //      from the LSDA, because the static linker will resolve it.
430d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov    //
431ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //   2) Otherwise, if the LSDA section is writable, we can output the direct
432ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //      reference to the typeinfo and allow the dynamic linker to relocate
433ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //      it.  Since it is in a writable section, the dynamic linker won't
434ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //      have a problem.
435d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov    //
436ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //   3) Finally, if we're in PIC mode and the LDSA section isn't writable,
437ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //      we need to use some form of indirection.  For example, on Darwin,
438ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //      we can output a statically-relocatable reference to a dyld stub. The
439ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //      offset to the stub is constant, but the contents are in a section
440ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //      that is updated by the dynamic linker.  This is easy enough, but we
441ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //      need to tell the personality function of the unwinder to indirect
442ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //      through the dyld stub.
443ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //
44443e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling    // FIXME: When (3) is actually implemented, we'll have to emit the stubs
445ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    // somewhere.  This predicate should be moved to a shared location that is
446ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    // in target-independent code.
447ad88bc4076d088baad8a5ee9561e46ac08a1c88aChris Lattner    //
4489184b25fa543a900463215c11635c2c014ddb623Anton Korobeynikov    TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding();
449d2af7853e377bce40cbf3e0632a4608484b6aba4Chris Lattner    TypeFormatSize = Asm->GetSizeOfEncodedValue(TTypeEncoding);
450fe220285b5ef1e4480ddd7f7c8bb182b88a33b16Bill Wendling  }
451fe220285b5ef1e4480ddd7f7c8bb182b88a33b16Bill Wendling
452fe220285b5ef1e4480ddd7f7c8bb182b88a33b16Bill Wendling  // Begin the exception table.
453ed299f6fa9f31c6063b9e187e849bca1ae284d12Anton Korobeynikov  // Sometimes we want not to emit the data into separate section (e.g. ARM
454ed299f6fa9f31c6063b9e187e849bca1ae284d12Anton Korobeynikov  // EHABI). In this case LSDASection will be NULL.
455d4e09787526f105f16c11f091ef6ef67c82da5d3Anton Korobeynikov  if (LSDASection)
456d4e09787526f105f16c11f091ef6ef67c82da5d3Anton Korobeynikov    Asm->OutStreamer.SwitchSection(LSDASection);
457059ea138a6e4180de0d70390f7147dac66614517Chris Lattner  Asm->EmitAlignment(2);
45843e484fbcf6a40a70d9a5c7ea142f37416ef1e68Bill Wendling
4593dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling  // Emit the LSDA.
460d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov  MCSymbol *GCCETSym =
461974c0fb4047f7d9f190f6ca5780c7a06e6c40914Chris Lattner    Asm->OutContext.GetOrCreateSymbol(Twine("GCC_except_table")+
46284ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner                                      Twine(Asm->getFunctionNumber()));
463974c0fb4047f7d9f190f6ca5780c7a06e6c40914Chris Lattner  Asm->OutStreamer.EmitLabel(GCCETSym);
46484ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner  Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("exception",
46584ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner                                                Asm->getFunctionNumber()));
4663dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling
467974c0fb4047f7d9f190f6ca5780c7a06e6c40914Chris Lattner  if (IsSJLJ)
468c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner    Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("_LSDA_",
469c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner                                                  Asm->getFunctionNumber()));
4703dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling
4713dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling  // Emit the LSDA header.
472ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner  Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
473ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner  Asm->EmitEncodingByte(TTypeEncoding, "@TType");
474a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling
475a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // The type infos need to be aligned. GCC does this by inserting padding just
476a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // before the type infos. However, this changes the size of the exception
477a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // table, so you need to take this into account when you output the exception
478a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // table size. However, the size is output using a variable length encoding.
479a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // So by increasing the size by inserting padding, you may increase the number
480a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // of bytes used for writing the size. If it increases, say by one byte, then
481a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // you now need to output one less byte of padding to get the type infos
4823dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling  // aligned. However this decreases the size of the exception table. This
483a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // changes the value you have to output for the exception table size. Due to
484a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // the variable length encoding, the number of bytes used for writing the
485a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // length may decrease. If so, you then have to increase the amount of
486a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // padding. And so on. If you look carefully at the GCC code you will see that
487a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // it indeed does this in a loop, going on and on until the values stabilize.
488a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // We chose another solution: don't output padding inside the table like GCC
489a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  // does, instead output it before the table.
490a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  unsigned SizeTypes = TypeInfos.size() * TypeFormatSize;
4913dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling  unsigned CallSiteTableLengthSize =
4923dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling    MCAsmInfo::getULEB128Size(CallSiteTableLength);
4933dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling  unsigned TTypeBaseOffset =
4943dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling    sizeof(int8_t) +                            // Call site format
4953dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling    CallSiteTableLengthSize +                   // Call site table length size
4963dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling    CallSiteTableLength +                       // Call site table length
4973dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling    SizeActions +                               // Actions size
4983dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling    SizeTypes;
4993dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling  unsigned TTypeBaseOffsetSize = MCAsmInfo::getULEB128Size(TTypeBaseOffset);
5003dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling  unsigned TotalSize =
5013dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling    sizeof(int8_t) +                            // LPStart format
5023dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling    sizeof(int8_t) +                            // TType format
5033dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling    (HaveTTData ? TTypeBaseOffsetSize : 0) +    // TType base offset size
5043dc9b4872b28016b38ce31fa4356e17c96420579Bill Wendling    TTypeBaseOffset;                            // TType base offset
505a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling  unsigned SizeAlign = (4 - TotalSize) & 3;
506a2f6449a57fcce73beacc30158aafe39b5349947Bill Wendling
50786f0d33f85c19af294916eacd175f6b0cd81142fBill Wendling  if (HaveTTData) {
5086507eca124883c90cc300c1ff344f79a8b4181a5Bill Wendling    // Account for any extra padding that will be added to the call site table
509f7e90ae2057adcf6fa4b023110611084f28fd6c1Bill Wendling    // length.
5107e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner    Asm->EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign);
5111869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling    SizeAlign = 0;
51286f0d33f85c19af294916eacd175f6b0cd81142fBill Wendling  }
513b0d9c3e7fdc952ae7cbe169b01ccaf1b80329403Bill Wendling
5148fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling  bool VerboseAsm = Asm->OutStreamer.isVerboseAsm();
5158fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling
51628275fdf02885587156da5cb20388b22d5b96557Bill Wendling  // SjLj Exception handling
517d1a5b37a62e829e56b6225e0934a01d9f8823387Bill Wendling  if (IsSJLJ) {
518ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner    Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
5191869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling
5201869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling    // Add extra padding if it wasn't added to the TType base offset.
5217e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner    Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
5221b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach
5231b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach    // Emit the landing pad site information.
5248b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach    unsigned idx = 0;
5258b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach    for (SmallVectorImpl<CallSiteEntry>::const_iterator
5268b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach         I = CallSites.begin(), E = CallSites.end(); I != E; ++I, ++idx) {
5278b818d7e98309125c6058c4ea72a7dc73b031db2Jim Grosbach      const CallSiteEntry &S = *I;
528a583c55864e83e470333b7be878280b10e175a6eBill Wendling
529f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      // Offset of the landing pad, counted in 16-byte bundles relative to the
530f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      // @LPStart address.
5310c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling      if (VerboseAsm) {
53247b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer        Asm->OutStreamer.AddComment(">> Call Site " + Twine(idx) + " <<");
53347b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer        Asm->OutStreamer.AddComment("  On exception at call site "+Twine(idx));
534f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      }
535f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      Asm->EmitULEB128(idx);
5360c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling
537f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      // Offset of the first associated action record, relative to the start of
538f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      // the action table. This value is biased by 1 (1 indicates the start of
539f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      // the action table), and 0 indicates that there are no actions.
540f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      if (VerboseAsm) {
5410c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling        if (S.Action == 0)
5420c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling          Asm->OutStreamer.AddComment("  Action: cleanup");
5430c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling        else
54447b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer          Asm->OutStreamer.AddComment("  Action: " +
54547b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer                                      Twine((S.Action - 1) / 2 + 1));
5460c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling      }
5470c11218f0a38461a3d74c075ee3b76e511c7ccd0Bill Wendling      Asm->EmitULEB128(S.Action);
5481b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach    }
5491b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach  } else {
5501b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach    // DWARF Exception handling
5513965b5e974d57f3e56a2c7f37d76d73e572dfb20Anton Korobeynikov    assert(Asm->MAI->isExceptionHandlingDwarf());
5521b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach
553a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // The call-site table is a list of all call sites that may throw an
554a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // exception (including C++ 'throw' statements) in the procedure
555a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // fragment. It immediately follows the LSDA header. Each entry indicates,
556a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // for a given call, the first corresponding action record and corresponding
557a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // landing pad.
558a583c55864e83e470333b7be878280b10e175a6eBill Wendling    //
559a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // The table begins with the number of bytes, stored as an LEB128
560a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // compressed, unsigned integer. The records immediately follow the record
561a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // count. They are sorted in increasing call-site address. Each record
562a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // indicates:
563a583c55864e83e470333b7be878280b10e175a6eBill Wendling    //
564a583c55864e83e470333b7be878280b10e175a6eBill Wendling    //   * The position of the call-site.
565a583c55864e83e470333b7be878280b10e175a6eBill Wendling    //   * The position of the landing pad.
566a583c55864e83e470333b7be878280b10e175a6eBill Wendling    //   * The first action record for that call site.
567a583c55864e83e470333b7be878280b10e175a6eBill Wendling    //
568a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // A missing entry in the call-site table indicates that a call is not
56928275fdf02885587156da5cb20388b22d5b96557Bill Wendling    // supposed to throw.
570a583c55864e83e470333b7be878280b10e175a6eBill Wendling
571a583c55864e83e470333b7be878280b10e175a6eBill Wendling    // Emit the landing pad call site table.
572ca6190b108aeb4a2eeb6f5c6457bb17509b85d9dChris Lattner    Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
5731869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling
5741869ac8b716da4fdbaaf3e5484238f36881fc14bBill Wendling    // Add extra padding if it wasn't added to the TType base offset.
5757e1a8f882f1baa1c0d5204373d6eb4cb7fc9f3eaChris Lattner    Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
576eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
5778fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling    unsigned Entry = 0;
5781b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach    for (SmallVectorImpl<CallSiteEntry>::const_iterator
5795cff487665097d971067cbede1598e249f673182Bill Wendling         I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
5801b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach      const CallSiteEntry &S = *I;
581d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov
582c021572511f08372ae52fe8e31d3c307cab448fdChris Lattner      MCSymbol *EHFuncBeginSym =
58384ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner        Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber());
584d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov
5851611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner      MCSymbol *BeginLabel = S.BeginLabel;
5861611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner      if (BeginLabel == 0)
5871611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner        BeginLabel = EHFuncBeginSym;
5881611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner      MCSymbol *EndLabel = S.EndLabel;
5891611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner      if (EndLabel == 0)
59084ac8b7f43514eda99b0de27c68fbcb5bfa2f399Chris Lattner        EndLabel = Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber());
591d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov
5928fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling
593a583c55864e83e470333b7be878280b10e175a6eBill Wendling      // Offset of the call site relative to the previous call site, counted in
594a583c55864e83e470333b7be878280b10e175a6eBill Wendling      // number of 16-byte bundles. The first call site is counted relative to
595a583c55864e83e470333b7be878280b10e175a6eBill Wendling      // the start of the procedure fragment.
596f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      if (VerboseAsm)
59747b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer        Asm->OutStreamer.AddComment(">> Call Site " + Twine(++Entry) + " <<");
598f88dce1f89ddb30b2370318284a6b307d7a44a98Chris Lattner      Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4);
599f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      if (VerboseAsm)
600f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin        Asm->OutStreamer.AddComment(Twine("  Call between ") +
601f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin                                    BeginLabel->getName() + " and " +
602f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin                                    EndLabel->getName());
603a64371828e27dcc30d38e7246dda0f35c1dfde40Chris Lattner      Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
604eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
605a583c55864e83e470333b7be878280b10e175a6eBill Wendling      // Offset of the landing pad, counted in 16-byte bundles relative to the
606a583c55864e83e470333b7be878280b10e175a6eBill Wendling      // @LPStart address.
607f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      if (!S.PadLabel) {
608f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin        if (VerboseAsm)
609f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin          Asm->OutStreamer.AddComment("    has no landing pad");
610ca1dd05c3c12e857614ae6837f90894396225dd6Eric Christopher        Asm->OutStreamer.EmitIntValue(0, 4/*size*/);
611f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      } else {
612f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin        if (VerboseAsm)
613f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin          Asm->OutStreamer.AddComment(Twine("    jumps to ") +
614f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin                                      S.PadLabel->getName());
615f88dce1f89ddb30b2370318284a6b307d7a44a98Chris Lattner        Asm->EmitLabelDifference(S.PadLabel, EHFuncBeginSym, 4);
616f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      }
617eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
618a583c55864e83e470333b7be878280b10e175a6eBill Wendling      // Offset of the first associated action record, relative to the start of
619a583c55864e83e470333b7be878280b10e175a6eBill Wendling      // the action table. This value is biased by 1 (1 indicates the start of
620a583c55864e83e470333b7be878280b10e175a6eBill Wendling      // the action table), and 0 indicates that there are no actions.
621f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      if (VerboseAsm) {
622f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin        if (S.Action == 0)
623f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin          Asm->OutStreamer.AddComment("  On action: cleanup");
624f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin        else
62547b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer          Asm->OutStreamer.AddComment("  On action: " +
62647b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer                                      Twine((S.Action - 1) / 2 + 1));
627f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin      }
6288fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling      Asm->EmitULEB128(S.Action);
6291b747ad8a0694b86e8d98a8b9a05ddfe74ec0cd3Jim Grosbach    }
630eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  }
631eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
632a583c55864e83e470333b7be878280b10e175a6eBill Wendling  // Emit the Action Table.
6338fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling  int Entry = 0;
6345cff487665097d971067cbede1598e249f673182Bill Wendling  for (SmallVectorImpl<ActionEntry>::const_iterator
6355cff487665097d971067cbede1598e249f673182Bill Wendling         I = Actions.begin(), E = Actions.end(); I != E; ++I) {
6365cff487665097d971067cbede1598e249f673182Bill Wendling    const ActionEntry &Action = *I;
6378fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling
6388fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling    if (VerboseAsm) {
6398fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling      // Emit comments that decode the action table.
64047b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer      Asm->OutStreamer.AddComment(">> Action Record " + Twine(++Entry) + " <<");
641f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    }
642f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin
643f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    // Type Filter
644f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    //
645f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    //   Used by the runtime to match the type of the thrown exception to the
646f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    //   type of the catch clauses or the types in the exception specification.
647f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    if (VerboseAsm) {
64842e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands      if (Action.ValueForTypeID > 0)
64947b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer        Asm->OutStreamer.AddComment("  Catch TypeInfo " +
65047b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer                                    Twine(Action.ValueForTypeID));
65142e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands      else if (Action.ValueForTypeID < 0)
65247b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer        Asm->OutStreamer.AddComment("  Filter TypeInfo " +
65347b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer                                    Twine(Action.ValueForTypeID));
65442e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands      else
65542e5c799b61ce70620d4d4d4d20e847750a185c3Duncan Sands        Asm->OutStreamer.AddComment("  Cleanup");
656f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    }
657f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    Asm->EmitSLEB128(Action.ValueForTypeID);
6588fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling
659f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    // Action Record
660f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    //
661f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    //   Self-relative signed displacement in bytes of the next action record,
662f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    //   or 0 if there is no next action record.
663f1f6de1c9b658c78baa36c1af7a94c1deba91851Renato Golin    if (VerboseAsm) {
6648fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling      if (Action.NextAction == 0) {
6658fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling        Asm->OutStreamer.AddComment("  No further actions");
6668fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling      } else {
6678fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling        unsigned NextAction = Entry + (Action.NextAction + 1) / 2;
66847b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer        Asm->OutStreamer.AddComment("  Continue to action "+Twine(NextAction));
6698fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling      }
6708fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling    }
6718fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling    Asm->EmitSLEB128(Action.NextAction);
672eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  }
673eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
6742386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov  EmitTypeInfos(TTypeEncoding);
6752386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov
6762386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov  Asm->EmitAlignment(2);
6772386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov}
6782386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov
6792386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikovvoid DwarfException::EmitTypeInfos(unsigned TTypeEncoding) {
6802386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov  const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
6812386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov  const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
6822386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov
6832386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov  bool VerboseAsm = Asm->OutStreamer.isVerboseAsm();
6842386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov
6852386fc8daa682c7b6c2479cd9c9c3113581c41dbAnton Korobeynikov  int Entry = 0;
68648dc29ef911a223a52b099604d0ccb499ecbf703Bill Wendling  // Emit the Catch TypeInfos.
6878fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling  if (VerboseAsm && !TypeInfos.empty()) {
6888fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling    Asm->OutStreamer.AddComment(">> Catch TypeInfos <<");
689233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner    Asm->OutStreamer.AddBlankLine();
6908fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling    Entry = TypeInfos.size();
691233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner  }
6928fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling
69346510a73e977273ec67747eb34cbdb43f815e451Dan Gohman  for (std::vector<const GlobalVariable *>::const_reverse_iterator
69401c69374b508bad0ee71cd3c49414a325238e29aBill Wendling         I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
695fb7634f1c7a804829fc55e3711ba62c8ade818d0Bill Wendling    const GlobalVariable *GV = *I;
6968fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling    if (VerboseAsm)
69747b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer      Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--));
698239938ff77ef43c753881b030438f89a3dfc72c4Anton Korobeynikov    Asm->EmitTTypeReference(GV, TTypeEncoding);
699eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  }
700eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
70148dc29ef911a223a52b099604d0ccb499ecbf703Bill Wendling  // Emit the Exception Specifications.
7028fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling  if (VerboseAsm && !FilterIds.empty()) {
7038fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling    Asm->OutStreamer.AddComment(">> Filter TypeInfos <<");
704233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner    Asm->OutStreamer.AddBlankLine();
7058fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling    Entry = 0;
706233f52be36a6a2ec053b1580fdf89625de256513Chris Lattner  }
7075cff487665097d971067cbede1598e249f673182Bill Wendling  for (std::vector<unsigned>::const_iterator
7085cff487665097d971067cbede1598e249f673182Bill Wendling         I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
7095cff487665097d971067cbede1598e249f673182Bill Wendling    unsigned TypeID = *I;
7108fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling    if (VerboseAsm) {
7118fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling      --Entry;
7128fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling      if (TypeID != 0)
71347b8798c0bf0944b24051bc21d85d93a2732676aBenjamin Kramer        Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry));
7148fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling    }
7158fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling
7168fcd3e620424372af9afeeed7cd941aa8d5435afBill Wendling    Asm->EmitULEB128(TypeID);
717eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling  }
718eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling}
719eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
720eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// EndModule - Emit all exception information that should come after the
721eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// content.
722eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EndModule() {
7235e25ee8a1fcf8288d00d731b0f7ab7976f33b123Craig Topper  llvm_unreachable("Should be implemented");
724eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling}
725eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
72628275fdf02885587156da5cb20388b22d5b96557Bill Wendling/// BeginFunction - Gather pre-function exception information. Assumes it's
72728275fdf02885587156da5cb20388b22d5b96557Bill Wendling/// being emitted immediately after the function entry point.
728eec791afb127ed634ed5d1cdd2e6c47b3b70174cChris Lattnervoid DwarfException::BeginFunction(const MachineFunction *MF) {
7295e25ee8a1fcf8288d00d731b0f7ab7976f33b123Craig Topper  llvm_unreachable("Should be implemented");
730eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling}
731eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling
732eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling/// EndFunction - Gather and emit post-function exception information.
733eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling///
734eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendlingvoid DwarfException::EndFunction() {
7355e25ee8a1fcf8288d00d731b0f7ab7976f33b123Craig Topper  llvm_unreachable("Should be implemented");
736eb9072195ca7d777a71194dcaaaa369d82f24f53Bill Wendling}
737