CGException.cpp revision fcd5c0c62ef3d86ecd991753bb43c88c861470e7
1756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//===--- CGException.cpp - Emit LLVM Code for C++ exceptions --------------===//
2756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//
3756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//                     The LLVM Compiler Infrastructure
4756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//
5756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// This file is distributed under the University of Illinois Open Source
6756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// License. See LICENSE.TXT for details.
7756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//
8756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//===----------------------------------------------------------------------===//
9756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//
10756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson// This contains code dealing with C++ exception related code generation.
11756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//
12756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson//===----------------------------------------------------------------------===//
13756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson
142bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump#include "clang/AST/StmtCXX.h"
152bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
162bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump#include "llvm/Intrinsics.h"
17f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall#include "llvm/Support/CallSite.h"
182bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
19756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson#include "CodeGenFunction.h"
20f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall#include "CGException.h"
21f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
22756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonusing namespace clang;
23756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonusing namespace CodeGen;
24756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson
25f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Push an entry of the given size onto this protected-scope stack.
26f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallchar *EHScopeStack::allocate(size_t Size) {
27f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (!StartOfBuffer) {
28f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    unsigned Capacity = 1024;
29f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    while (Capacity < Size) Capacity *= 2;
30f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    StartOfBuffer = new char[Capacity];
31f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    StartOfData = EndOfBuffer = StartOfBuffer + Capacity;
32f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else if (static_cast<size_t>(StartOfData - StartOfBuffer) < Size) {
33f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    unsigned CurrentCapacity = EndOfBuffer - StartOfBuffer;
34f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    unsigned UsedCapacity = CurrentCapacity - (StartOfData - StartOfBuffer);
35f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
36f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    unsigned NewCapacity = CurrentCapacity;
37f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    do {
38f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      NewCapacity *= 2;
39f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    } while (NewCapacity < UsedCapacity + Size);
40f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
41f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    char *NewStartOfBuffer = new char[NewCapacity];
42f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    char *NewEndOfBuffer = NewStartOfBuffer + NewCapacity;
43f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    char *NewStartOfData = NewEndOfBuffer - UsedCapacity;
44f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    memcpy(NewStartOfData, StartOfData, UsedCapacity);
45f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    delete [] StartOfBuffer;
46f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    StartOfBuffer = NewStartOfBuffer;
47f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EndOfBuffer = NewEndOfBuffer;
48f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    StartOfData = NewStartOfData;
49f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
50f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
51f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(StartOfBuffer + Size <= StartOfData);
52f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  StartOfData -= Size;
53f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return StartOfData;
54f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
55f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
56f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallEHScopeStack::stable_iterator
57f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallEHScopeStack::getEnclosingEHCleanup(iterator it) const {
58f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(it != end());
59f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  do {
60f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (isa<EHCleanupScope>(*it)) {
61f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      if (cast<EHCleanupScope>(*it).isEHCleanup())
62f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        return stabilize(it);
63f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      return cast<EHCleanupScope>(*it).getEnclosingEHCleanup();
64f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
65da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    if (isa<EHLazyCleanupScope>(*it)) {
66da65ea86482bc116906edfb9ba1d7124f76cc867John McCall      if (cast<EHLazyCleanupScope>(*it).isEHCleanup())
67da65ea86482bc116906edfb9ba1d7124f76cc867John McCall        return stabilize(it);
68da65ea86482bc116906edfb9ba1d7124f76cc867John McCall      return cast<EHLazyCleanupScope>(*it).getEnclosingEHCleanup();
69da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    }
70f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    ++it;
71f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } while (it != end());
72f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return stable_end();
73f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
74f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
75f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
76da65ea86482bc116906edfb9ba1d7124f76cc867John McCallvoid *EHScopeStack::pushLazyCleanup(CleanupKind Kind, size_t Size) {
77da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  assert(((Size % sizeof(void*)) == 0) && "cleanup type is misaligned");
78da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  char *Buffer = allocate(EHLazyCleanupScope::getSizeForCleanupSize(Size));
79da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  bool IsNormalCleanup = Kind != EHCleanup;
80da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  bool IsEHCleanup = Kind != NormalCleanup;
81da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  EHLazyCleanupScope *Scope =
82da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    new (Buffer) EHLazyCleanupScope(IsNormalCleanup,
83da65ea86482bc116906edfb9ba1d7124f76cc867John McCall                                    IsEHCleanup,
84da65ea86482bc116906edfb9ba1d7124f76cc867John McCall                                    Size,
85da65ea86482bc116906edfb9ba1d7124f76cc867John McCall                                    BranchFixups.size(),
86da65ea86482bc116906edfb9ba1d7124f76cc867John McCall                                    InnermostNormalCleanup,
87da65ea86482bc116906edfb9ba1d7124f76cc867John McCall                                    InnermostEHCleanup);
88da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  if (IsNormalCleanup)
89da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    InnermostNormalCleanup = stable_begin();
90da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  if (IsEHCleanup)
91da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    InnermostEHCleanup = stable_begin();
92da65ea86482bc116906edfb9ba1d7124f76cc867John McCall
93da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  return Scope->getCleanupBuffer();
94da65ea86482bc116906edfb9ba1d7124f76cc867John McCall}
95da65ea86482bc116906edfb9ba1d7124f76cc867John McCall
96f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid EHScopeStack::pushCleanup(llvm::BasicBlock *NormalEntry,
97f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                               llvm::BasicBlock *NormalExit,
98f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                               llvm::BasicBlock *EHEntry,
99f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                               llvm::BasicBlock *EHExit) {
100f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  char *Buffer = allocate(EHCleanupScope::getSize());
101f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  new (Buffer) EHCleanupScope(BranchFixups.size(),
102f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                              InnermostNormalCleanup,
103f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                              InnermostEHCleanup,
104f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                              NormalEntry, NormalExit, EHEntry, EHExit);
105f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (NormalEntry)
106f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    InnermostNormalCleanup = stable_begin();
107f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (EHEntry)
108f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    InnermostEHCleanup = stable_begin();
109f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
110f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
111f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid EHScopeStack::popCleanup() {
112f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(!empty() && "popping exception stack when not empty");
113f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
114da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  if (isa<EHLazyCleanupScope>(*begin())) {
115da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    EHLazyCleanupScope &Cleanup = cast<EHLazyCleanupScope>(*begin());
116da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    InnermostNormalCleanup = Cleanup.getEnclosingNormalCleanup();
117da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    InnermostEHCleanup = Cleanup.getEnclosingEHCleanup();
118da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    StartOfData += Cleanup.getAllocatedSize();
119da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  } else {
120da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    assert(isa<EHCleanupScope>(*begin()));
121da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    EHCleanupScope &Cleanup = cast<EHCleanupScope>(*begin());
122da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    InnermostNormalCleanup = Cleanup.getEnclosingNormalCleanup();
123da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    InnermostEHCleanup = Cleanup.getEnclosingEHCleanup();
124da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    StartOfData += EHCleanupScope::getSize();
125da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  }
126f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
127f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Check whether we can shrink the branch-fixups stack.
128f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (!BranchFixups.empty()) {
129f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // If we no longer have any normal cleanups, all the fixups are
130f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // complete.
131f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (!hasNormalCleanups())
132f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      BranchFixups.clear();
133f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
134f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Otherwise we can still trim out unnecessary nulls.
135f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    else
136f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      popNullFixups();
137f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
138f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
139f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
140f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallEHFilterScope *EHScopeStack::pushFilter(unsigned NumFilters) {
141f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  char *Buffer = allocate(EHFilterScope::getSizeForNumFilters(NumFilters));
142f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CatchDepth++;
143f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return new (Buffer) EHFilterScope(NumFilters);
144f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
145f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
146f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid EHScopeStack::popFilter() {
147f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(!empty() && "popping exception stack when not empty");
148f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
149f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHFilterScope &Filter = cast<EHFilterScope>(*begin());
150f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  StartOfData += EHFilterScope::getSizeForNumFilters(Filter.getNumFilters());
151f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
152f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(CatchDepth > 0 && "mismatched filter push/pop");
153f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CatchDepth--;
154f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
155f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
156f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallEHCatchScope *EHScopeStack::pushCatch(unsigned NumHandlers) {
157f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  char *Buffer = allocate(EHCatchScope::getSizeForNumHandlers(NumHandlers));
158f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CatchDepth++;
159f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return new (Buffer) EHCatchScope(NumHandlers);
160f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
161f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
162f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid EHScopeStack::pushTerminate() {
163f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  char *Buffer = allocate(EHTerminateScope::getSize());
164f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CatchDepth++;
165f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  new (Buffer) EHTerminateScope();
166f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
167f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
168f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Remove any 'null' fixups on the stack.  However, we can't pop more
169f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// fixups than the fixup depth on the innermost normal cleanup, or
170f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// else fixups that we try to add to that cleanup will end up in the
171f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// wrong place.  We *could* try to shrink fixup depths, but that's
172f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// actually a lot of work for little benefit.
173f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid EHScopeStack::popNullFixups() {
174f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // We expect this to only be called when there's still an innermost
175f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // normal cleanup;  otherwise there really shouldn't be any fixups.
176f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(hasNormalCleanups());
177f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
178f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHScopeStack::iterator it = find(InnermostNormalCleanup);
179da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  unsigned MinSize;
180da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  if (isa<EHCleanupScope>(*it))
181da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    MinSize = cast<EHCleanupScope>(*it).getFixupDepth();
182da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  else
183da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    MinSize = cast<EHLazyCleanupScope>(*it).getFixupDepth();
184f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(BranchFixups.size() >= MinSize && "fixup stack out of order");
185f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
186f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  while (BranchFixups.size() > MinSize &&
187f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall         BranchFixups.back().Destination == 0)
188f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    BranchFixups.pop_back();
189f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
190f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
191f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid EHScopeStack::resolveBranchFixups(llvm::BasicBlock *Dest) {
192f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(Dest && "null block passed to resolveBranchFixups");
193f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
194f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (BranchFixups.empty()) return;
195f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(hasNormalCleanups() &&
196f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall         "branch fixups exist with no normal cleanups on stack");
197f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
198f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (unsigned I = 0, E = BranchFixups.size(); I != E; ++I)
199f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (BranchFixups[I].Destination == Dest)
200f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      BranchFixups[I].Destination = 0;
201f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
202f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  popNullFixups();
203f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
204f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
205d3379292f90e1381d3236c68891bb725b02464b6Anders Carlssonstatic llvm::Constant *getAllocateExceptionFn(CodeGenFunction &CGF) {
206d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  // void *__cxa_allocate_exception(size_t thrown_size);
207d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  const llvm::Type *SizeTy = CGF.ConvertType(CGF.getContext().getSizeType());
208d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  std::vector<const llvm::Type*> Args(1, SizeTy);
2098755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
2108755ec336108839b9621c3b18f0e175f8a3b671cMike Stump  const llvm::FunctionType *FTy =
211d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  llvm::FunctionType::get(llvm::Type::getInt8PtrTy(CGF.getLLVMContext()),
212d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson                          Args, false);
2138755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
214d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_allocate_exception");
215d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson}
216d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson
21799533834ba8f3658559f334e68a518ebb6388ceaMike Stumpstatic llvm::Constant *getFreeExceptionFn(CodeGenFunction &CGF) {
21899533834ba8f3658559f334e68a518ebb6388ceaMike Stump  // void __cxa_free_exception(void *thrown_exception);
21999533834ba8f3658559f334e68a518ebb6388ceaMike Stump  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
22099533834ba8f3658559f334e68a518ebb6388ceaMike Stump  std::vector<const llvm::Type*> Args(1, Int8PtrTy);
2218755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
2228755ec336108839b9621c3b18f0e175f8a3b671cMike Stump  const llvm::FunctionType *FTy =
22399533834ba8f3658559f334e68a518ebb6388ceaMike Stump  llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
22499533834ba8f3658559f334e68a518ebb6388ceaMike Stump                          Args, false);
2258755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
22699533834ba8f3658559f334e68a518ebb6388ceaMike Stump  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception");
22799533834ba8f3658559f334e68a518ebb6388ceaMike Stump}
22899533834ba8f3658559f334e68a518ebb6388ceaMike Stump
229d3379292f90e1381d3236c68891bb725b02464b6Anders Carlssonstatic llvm::Constant *getThrowFn(CodeGenFunction &CGF) {
2308755ec336108839b9621c3b18f0e175f8a3b671cMike Stump  // void __cxa_throw(void *thrown_exception, std::type_info *tinfo,
23199533834ba8f3658559f334e68a518ebb6388ceaMike Stump  //                  void (*dest) (void *));
232d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson
233d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
234d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  std::vector<const llvm::Type*> Args(3, Int8PtrTy);
2358755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
2368755ec336108839b9621c3b18f0e175f8a3b671cMike Stump  const llvm::FunctionType *FTy =
237b4eea691866a3fa75722da9eba735c44f140398aMike Stump    llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
238b4eea691866a3fa75722da9eba735c44f140398aMike Stump                            Args, false);
2398755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
240d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_throw");
241d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson}
242d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson
243b4eea691866a3fa75722da9eba735c44f140398aMike Stumpstatic llvm::Constant *getReThrowFn(CodeGenFunction &CGF) {
24499533834ba8f3658559f334e68a518ebb6388ceaMike Stump  // void __cxa_rethrow();
245b4eea691866a3fa75722da9eba735c44f140398aMike Stump
2468755ec336108839b9621c3b18f0e175f8a3b671cMike Stump  const llvm::FunctionType *FTy =
247b4eea691866a3fa75722da9eba735c44f140398aMike Stump    llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false);
2488755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
249b4eea691866a3fa75722da9eba735c44f140398aMike Stump  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_rethrow");
250b4eea691866a3fa75722da9eba735c44f140398aMike Stump}
251b4eea691866a3fa75722da9eba735c44f140398aMike Stump
252f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic llvm::Constant *getGetExceptionPtrFn(CodeGenFunction &CGF) {
253f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // void *__cxa_get_exception_ptr(void*);
254f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
255f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  std::vector<const llvm::Type*> Args(1, Int8PtrTy);
256f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
257f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  const llvm::FunctionType *FTy =
258f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::FunctionType::get(Int8PtrTy, Args, false);
259f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
260f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_get_exception_ptr");
261f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
262f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
2632bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stumpstatic llvm::Constant *getBeginCatchFn(CodeGenFunction &CGF) {
264f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // void *__cxa_begin_catch(void*);
2652bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
2662bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
2672bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump  std::vector<const llvm::Type*> Args(1, Int8PtrTy);
2688755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
2698755ec336108839b9621c3b18f0e175f8a3b671cMike Stump  const llvm::FunctionType *FTy =
2700f590be3808365e851352543faa6acbece50b686Mike Stump    llvm::FunctionType::get(Int8PtrTy, Args, false);
2718755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
2722bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
2732bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump}
2742bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
2752bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stumpstatic llvm::Constant *getEndCatchFn(CodeGenFunction &CGF) {
27699533834ba8f3658559f334e68a518ebb6388ceaMike Stump  // void __cxa_end_catch();
2772bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
2788755ec336108839b9621c3b18f0e175f8a3b671cMike Stump  const llvm::FunctionType *FTy =
2792bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump    llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false);
2808755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
2812bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
2822bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump}
2832bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
284cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpstatic llvm::Constant *getUnexpectedFn(CodeGenFunction &CGF) {
285cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  // void __cxa_call_unexepcted(void *thrown_exception);
286cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
287cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
288cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  std::vector<const llvm::Type*> Args(1, Int8PtrTy);
2898755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
2908755ec336108839b9621c3b18f0e175f8a3b671cMike Stump  const llvm::FunctionType *FTy =
291cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
292cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump                            Args, false);
2938755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
294cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
295cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump}
296cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
29786a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregorllvm::Constant *CodeGenFunction::getUnwindResumeOrRethrowFn() {
29886a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
2990f590be3808365e851352543faa6acbece50b686Mike Stump  std::vector<const llvm::Type*> Args(1, Int8PtrTy);
3008755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
3018755ec336108839b9621c3b18f0e175f8a3b671cMike Stump  const llvm::FunctionType *FTy =
30286a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor    llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), Args,
3030f590be3808365e851352543faa6acbece50b686Mike Stump                            false);
3048755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
30586a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor  if (CGM.getLangOptions().SjLjExceptions)
30686a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor    return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume");
30786a3a03667bdb0dcab7e6a2877dfd234b07a6d43Douglas Gregor  return CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume_or_Rethrow");
3080f590be3808365e851352543faa6acbece50b686Mike Stump}
3090f590be3808365e851352543faa6acbece50b686Mike Stump
31099533834ba8f3658559f334e68a518ebb6388ceaMike Stumpstatic llvm::Constant *getTerminateFn(CodeGenFunction &CGF) {
31199533834ba8f3658559f334e68a518ebb6388ceaMike Stump  // void __terminate();
31299533834ba8f3658559f334e68a518ebb6388ceaMike Stump
3138755ec336108839b9621c3b18f0e175f8a3b671cMike Stump  const llvm::FunctionType *FTy =
31499533834ba8f3658559f334e68a518ebb6388ceaMike Stump    llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()), false);
3158755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
31679a9ad8e5eec3696989354be13a74a1106f64f72David Chisnall  return CGF.CGM.CreateRuntimeFunction(FTy,
31779a9ad8e5eec3696989354be13a74a1106f64f72David Chisnall      CGF.CGM.getLangOptions().CPlusPlus ? "_ZSt9terminatev" : "abort");
31879a9ad8e5eec3696989354be13a74a1106f64f72David Chisnall}
31979a9ad8e5eec3696989354be13a74a1106f64f72David Chisnall
320f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic const char *getCPersonalityFn(CodeGenFunction &CGF) {
321f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return "__gcc_personality_v0";
322f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
323f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
324f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic const char *getObjCPersonalityFn(CodeGenFunction &CGF) {
325f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (CGF.CGM.getLangOptions().NeXTRuntime) {
326f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (CGF.CGM.getLangOptions().ObjCNonFragileABI)
327f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      return "__objc_personality_v0";
328f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    else
329f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      return getCPersonalityFn(CGF);
330f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else {
331f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return "__gnu_objc_personality_v0";
332f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
333f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
334f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
335f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic const char *getCXXPersonalityFn(CodeGenFunction &CGF) {
336f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (CGF.CGM.getLangOptions().SjLjExceptions)
337f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return "__gxx_personality_sj0";
338f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  else
339f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return "__gxx_personality_v0";
340f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
341f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
342f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Determines the personality function to use when both C++
343f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// and Objective-C exceptions are being caught.
344f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic const char *getObjCXXPersonalityFn(CodeGenFunction &CGF) {
345f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The ObjC personality defers to the C++ personality for non-ObjC
346f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // handlers.  Unlike the C++ case, we use the same personality
347f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // function on targets using (backend-driven) SJLJ EH.
348f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (CGF.CGM.getLangOptions().NeXTRuntime) {
349f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (CGF.CGM.getLangOptions().ObjCNonFragileABI)
350f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      return "__objc_personality_v0";
351f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
352f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // In the fragile ABI, just use C++ exception handling and hope
353f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // they're not doing crazy exception mixing.
3548019c45024be3026f854e3d22bfd89842be82266Daniel Dunbar    else
355f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      return getCXXPersonalityFn(CGF);
356dcf22ad88fdb6c4dd74f9065262cde8bac4f807bChandler Carruth  }
35779a9ad8e5eec3696989354be13a74a1106f64f72David Chisnall
358f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // I'm pretty sure the GNU runtime doesn't support mixed EH.
359f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // TODO: we don't necessarily need mixed EH here;  remember what
360f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // kind of exceptions we actually try to catch in this function.
361f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.CGM.ErrorUnsupported(CGF.CurCodeDecl,
362f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           "the GNU Objective C runtime does not support "
363f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           "catching C++ and Objective C exceptions in the "
364f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           "same function");
365f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Use the C++ personality just to avoid returning null.
366f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return getCXXPersonalityFn(CGF);
367f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
368f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
369f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic llvm::Constant *getPersonalityFn(CodeGenFunction &CGF) {
370f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  const char *Name;
371f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  const LangOptions &Opts = CGF.CGM.getLangOptions();
372f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (Opts.CPlusPlus && Opts.ObjC1)
373f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Name = getObjCXXPersonalityFn(CGF);
374f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  else if (Opts.CPlusPlus)
375f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Name = getCXXPersonalityFn(CGF);
376f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  else if (Opts.ObjC1)
377f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Name = getObjCPersonalityFn(CGF);
378f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  else
379f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Name = getCPersonalityFn(CGF);
380f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
38179a9ad8e5eec3696989354be13a74a1106f64f72David Chisnall  llvm::Constant *Personality =
382f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.CGM.CreateRuntimeFunction(llvm::FunctionType::get(
383f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                    llvm::Type::getInt32Ty(
384f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                      CGF.CGM.getLLVMContext()),
385f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                    true),
386f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                            Name);
387f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return llvm::ConstantExpr::getBitCast(Personality, CGF.CGM.PtrToInt8Ty);
388f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
389f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
390f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Returns the value to inject into a selector to indicate the
391f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// presence of a catch-all.
392f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) {
393f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Possibly we should use @llvm.eh.catch.all.value here.
394f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return llvm::ConstantPointerNull::get(CGF.CGM.PtrToInt8Ty);
395f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
396f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
397f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Returns the value to inject into a selector to indicate the
398f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// presence of a cleanup.
399f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic llvm::Constant *getCleanupValue(CodeGenFunction &CGF) {
400f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return llvm::ConstantInt::get(CGF.Builder.getInt32Ty(), 0);
40199533834ba8f3658559f334e68a518ebb6388ceaMike Stump}
40299533834ba8f3658559f334e68a518ebb6388ceaMike Stump
40309faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCallnamespace {
40409faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  /// A cleanup to free the exception object if its initialization
40509faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  /// throws.
40609faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  struct FreeExceptionCleanup : EHScopeStack::LazyCleanup {
40709faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall    FreeExceptionCleanup(llvm::Value *ShouldFreeVar,
40809faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall                         llvm::Value *ExnLocVar)
40909faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall      : ShouldFreeVar(ShouldFreeVar), ExnLocVar(ExnLocVar) {}
41009faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall
41109faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall    llvm::Value *ShouldFreeVar;
41209faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall    llvm::Value *ExnLocVar;
41309faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall
41409faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall    void Emit(CodeGenFunction &CGF, bool IsForEH) {
41509faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall      llvm::BasicBlock *FreeBB = CGF.createBasicBlock("free-exnobj");
41609faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall      llvm::BasicBlock *DoneBB = CGF.createBasicBlock("free-exnobj.done");
41709faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall
41809faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall      llvm::Value *ShouldFree = CGF.Builder.CreateLoad(ShouldFreeVar,
41909faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall                                                       "should-free-exnobj");
42009faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall      CGF.Builder.CreateCondBr(ShouldFree, FreeBB, DoneBB);
42109faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall      CGF.EmitBlock(FreeBB);
42209faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall      llvm::Value *ExnLocLocal = CGF.Builder.CreateLoad(ExnLocVar, "exnobj");
42309faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall      CGF.Builder.CreateCall(getFreeExceptionFn(CGF), ExnLocLocal)
42409faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall        ->setDoesNotThrow();
42509faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall      CGF.EmitBlock(DoneBB);
42609faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall    }
42709faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  };
42809faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall}
42909faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall
430ac418162692a951ca3796d6830496a85a2d12493John McCall// Emits an exception expression into the given location.  This
431ac418162692a951ca3796d6830496a85a2d12493John McCall// differs from EmitAnyExprToMem only in that, if a final copy-ctor
432ac418162692a951ca3796d6830496a85a2d12493John McCall// call is required, an exception within that copy ctor causes
433ac418162692a951ca3796d6830496a85a2d12493John McCall// std::terminate to be invoked.
434ac418162692a951ca3796d6830496a85a2d12493John McCallstatic void EmitAnyExprToExn(CodeGenFunction &CGF, const Expr *E,
435ac418162692a951ca3796d6830496a85a2d12493John McCall                             llvm::Value *ExnLoc) {
436ac418162692a951ca3796d6830496a85a2d12493John McCall  // We want to release the allocated exception object if this
437ac418162692a951ca3796d6830496a85a2d12493John McCall  // expression throws.  We do this by pushing an EH-only cleanup
438ac418162692a951ca3796d6830496a85a2d12493John McCall  // block which, furthermore, deactivates itself after the expression
439ac418162692a951ca3796d6830496a85a2d12493John McCall  // is complete.
440ac418162692a951ca3796d6830496a85a2d12493John McCall  llvm::AllocaInst *ShouldFreeVar =
441ac418162692a951ca3796d6830496a85a2d12493John McCall    CGF.CreateTempAlloca(llvm::Type::getInt1Ty(CGF.getLLVMContext()),
442ac418162692a951ca3796d6830496a85a2d12493John McCall                         "should-free-exnobj.var");
443ac418162692a951ca3796d6830496a85a2d12493John McCall  CGF.InitTempAlloca(ShouldFreeVar,
444ac418162692a951ca3796d6830496a85a2d12493John McCall                     llvm::ConstantInt::getFalse(CGF.getLLVMContext()));
445ac418162692a951ca3796d6830496a85a2d12493John McCall
446ac418162692a951ca3796d6830496a85a2d12493John McCall  // A variable holding the exception pointer.  This is necessary
447ac418162692a951ca3796d6830496a85a2d12493John McCall  // because the throw expression does not necessarily dominate the
448ac418162692a951ca3796d6830496a85a2d12493John McCall  // cleanup, for example if it appears in a conditional expression.
449ac418162692a951ca3796d6830496a85a2d12493John McCall  llvm::AllocaInst *ExnLocVar =
450ac418162692a951ca3796d6830496a85a2d12493John McCall    CGF.CreateTempAlloca(ExnLoc->getType(), "exnobj.var");
451ac418162692a951ca3796d6830496a85a2d12493John McCall
452f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Make sure the exception object is cleaned up if there's an
453f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // exception during initialization.
45409faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  // FIXME: stmt expressions might require this to be a normal
45509faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  // cleanup, too.
45609faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall  CGF.EHStack.pushLazyCleanup<FreeExceptionCleanup>(EHCleanup,
45709faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall                                                    ShouldFreeVar,
45809faeabf39a6fab2e2beb6bf03da970c17d2049aJohn McCall                                                    ExnLocVar);
459f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHScopeStack::stable_iterator Cleanup = CGF.EHStack.stable_begin();
460ac418162692a951ca3796d6830496a85a2d12493John McCall
461ac418162692a951ca3796d6830496a85a2d12493John McCall  CGF.Builder.CreateStore(ExnLoc, ExnLocVar);
462ac418162692a951ca3796d6830496a85a2d12493John McCall  CGF.Builder.CreateStore(llvm::ConstantInt::getTrue(CGF.getLLVMContext()),
463ac418162692a951ca3796d6830496a85a2d12493John McCall                          ShouldFreeVar);
464ac418162692a951ca3796d6830496a85a2d12493John McCall
465ac418162692a951ca3796d6830496a85a2d12493John McCall  // __cxa_allocate_exception returns a void*;  we need to cast this
466ac418162692a951ca3796d6830496a85a2d12493John McCall  // to the appropriate type for the object.
467ac418162692a951ca3796d6830496a85a2d12493John McCall  const llvm::Type *Ty = CGF.ConvertType(E->getType())->getPointerTo();
468ac418162692a951ca3796d6830496a85a2d12493John McCall  llvm::Value *TypedExnLoc = CGF.Builder.CreateBitCast(ExnLoc, Ty);
469ac418162692a951ca3796d6830496a85a2d12493John McCall
470ac418162692a951ca3796d6830496a85a2d12493John McCall  // FIXME: this isn't quite right!  If there's a final unelided call
471ac418162692a951ca3796d6830496a85a2d12493John McCall  // to a copy constructor, then according to [except.terminate]p1 we
472ac418162692a951ca3796d6830496a85a2d12493John McCall  // must call std::terminate() if that constructor throws, because
473ac418162692a951ca3796d6830496a85a2d12493John McCall  // technically that copy occurs after the exception expression is
474ac418162692a951ca3796d6830496a85a2d12493John McCall  // evaluated but before the exception is caught.  But the best way
475ac418162692a951ca3796d6830496a85a2d12493John McCall  // to handle that is to teach EmitAggExpr to do the final copy
476ac418162692a951ca3796d6830496a85a2d12493John McCall  // differently if it can't be elided.
477ac418162692a951ca3796d6830496a85a2d12493John McCall  CGF.EmitAnyExprToMem(E, TypedExnLoc, /*Volatile*/ false);
478ac418162692a951ca3796d6830496a85a2d12493John McCall
479ac418162692a951ca3796d6830496a85a2d12493John McCall  CGF.Builder.CreateStore(llvm::ConstantInt::getFalse(CGF.getLLVMContext()),
480ac418162692a951ca3796d6830496a85a2d12493John McCall                          ShouldFreeVar);
481ac418162692a951ca3796d6830496a85a2d12493John McCall
482f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Technically, the exception object is like a temporary; it has to
483f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // be cleaned up when its full-expression is complete.
484f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Unfortunately, the AST represents full-expressions by creating a
485f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // CXXExprWithTemporaries, which it only does when there are actually
486f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // temporaries.
487f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //
488f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // If any cleanups have been added since we pushed ours, they must
489f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // be from temporaries;  this will get popped at the same time.
490f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Otherwise we need to pop ours off.  FIXME: this is very brittle.
491f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (Cleanup == CGF.EHStack.stable_begin())
492f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.PopCleanupBlock();
493f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
494f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
495f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::Value *CodeGenFunction::getExceptionSlot() {
496f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (!ExceptionSlot) {
497f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    const llvm::Type *i8p = llvm::Type::getInt8PtrTy(getLLVMContext());
498f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    ExceptionSlot = CreateTempAlloca(i8p, "exn.slot");
4990f590be3808365e851352543faa6acbece50b686Mike Stump  }
500f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return ExceptionSlot;
5010f590be3808365e851352543faa6acbece50b686Mike Stump}
5020f590be3808365e851352543faa6acbece50b686Mike Stump
503756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlssonvoid CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E) {
504d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  if (!E->getSubExpr()) {
5051eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor    if (getInvokeDest()) {
506f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateInvoke(getReThrowFn(*this),
507f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           getUnreachableBlock(),
508f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           getInvokeDest())
5091eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor        ->setDoesNotReturn();
510f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    } else {
5111eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor      Builder.CreateCall(getReThrowFn(*this))->setDoesNotReturn();
512f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateUnreachable();
513f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
5141eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor
5151eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor    // Clear the insertion point to indicate we are in unreachable code.
5161eb2e59338c4b9c0429fc39ca98662adc9e7a3f2Douglas Gregor    Builder.ClearInsertionPoint();
517d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson    return;
518d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  }
5198755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
520d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  QualType ThrowType = E->getSubExpr()->getType();
5218755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
522d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  // Now allocate the exception object.
523d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  const llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
5243d3ec1c099ec8bfac3aa1fb0126fe515b7c7fa05John McCall  uint64_t TypeSize = getContext().getTypeSizeInChars(ThrowType).getQuantity();
5258755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
526d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  llvm::Constant *AllocExceptionFn = getAllocateExceptionFn(*this);
527f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *ExceptionPtr =
5288755ec336108839b9621c3b18f0e175f8a3b671cMike Stump    Builder.CreateCall(AllocExceptionFn,
529d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson                       llvm::ConstantInt::get(SizeTy, TypeSize),
530d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson                       "exception");
531f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  ExceptionPtr->setDoesNotThrow();
5328370c58b9295b32bee50443fe3ac43a47a2047e8Anders Carlsson
533ac418162692a951ca3796d6830496a85a2d12493John McCall  EmitAnyExprToExn(*this, E->getSubExpr(), ExceptionPtr);
5348755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
535d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  // Now throw the exception.
536d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(getLLVMContext());
5379dffe6f51c676c1e423c382c62d1648746e36cd4John McCall  llvm::Constant *TypeInfo = CGM.GetAddrOfRTTIDescriptor(ThrowType, true);
538ac418162692a951ca3796d6830496a85a2d12493John McCall
539ac418162692a951ca3796d6830496a85a2d12493John McCall  // The address of the destructor.  If the exception type has a
540ac418162692a951ca3796d6830496a85a2d12493John McCall  // trivial destructor (or isn't a record), we just pass null.
541ac418162692a951ca3796d6830496a85a2d12493John McCall  llvm::Constant *Dtor = 0;
542ac418162692a951ca3796d6830496a85a2d12493John McCall  if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) {
543ac418162692a951ca3796d6830496a85a2d12493John McCall    CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
544ac418162692a951ca3796d6830496a85a2d12493John McCall    if (!Record->hasTrivialDestructor()) {
5451d110e05e0ff48c1c7a483d6b7fd094cdf28316aDouglas Gregor      CXXDestructorDecl *DtorD = Record->getDestructor();
546ac418162692a951ca3796d6830496a85a2d12493John McCall      Dtor = CGM.GetAddrOfCXXDestructor(DtorD, Dtor_Complete);
547ac418162692a951ca3796d6830496a85a2d12493John McCall      Dtor = llvm::ConstantExpr::getBitCast(Dtor, Int8PtrTy);
548ac418162692a951ca3796d6830496a85a2d12493John McCall    }
549ac418162692a951ca3796d6830496a85a2d12493John McCall  }
550ac418162692a951ca3796d6830496a85a2d12493John McCall  if (!Dtor) Dtor = llvm::Constant::getNullValue(Int8PtrTy);
5518755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
5520a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump  if (getInvokeDest()) {
5538755ec336108839b9621c3b18f0e175f8a3b671cMike Stump    llvm::InvokeInst *ThrowCall =
554f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateInvoke3(getThrowFn(*this),
555f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                            getUnreachableBlock(), getInvokeDest(),
5560a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump                            ExceptionPtr, TypeInfo, Dtor);
5570a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump    ThrowCall->setDoesNotReturn();
5580a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump  } else {
5598755ec336108839b9621c3b18f0e175f8a3b671cMike Stump    llvm::CallInst *ThrowCall =
5600a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump      Builder.CreateCall3(getThrowFn(*this), ExceptionPtr, TypeInfo, Dtor);
5610a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump    ThrowCall->setDoesNotReturn();
562f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateUnreachable();
5630a3816e566db7cd6084310a2f5a3167d0ec30b31Mike Stump  }
5648755ec336108839b9621c3b18f0e175f8a3b671cMike Stump
565d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  // Clear the insertion point to indicate we are in unreachable code.
566d3379292f90e1381d3236c68891bb725b02464b6Anders Carlsson  Builder.ClearInsertionPoint();
567c2ab48698094f3e6f3acebc38a19b8cb04069b41Mike Stump
568c2ab48698094f3e6f3acebc38a19b8cb04069b41Mike Stump  // FIXME: For now, emit a dummy basic block because expr emitters in generally
569c2ab48698094f3e6f3acebc38a19b8cb04069b41Mike Stump  // are not ready to handle emitting expressions at unreachable points.
570c2ab48698094f3e6f3acebc38a19b8cb04069b41Mike Stump  EnsureInsertPoint();
571756b5c4f9d52642d87d1948bee58f97a4f795b24Anders Carlsson}
5722bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
573cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpvoid CodeGenFunction::EmitStartEHSpec(const Decl *D) {
574a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson  if (!Exceptions)
575a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson    return;
576a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson
577cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
578cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  if (FD == 0)
579cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
580cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
581cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  if (Proto == 0)
582cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
583cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
584cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  assert(!Proto->hasAnyExceptionSpec() && "function with parameter pack");
585cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
586cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  if (!Proto->hasExceptionSpec())
587cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
588cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
589f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  unsigned NumExceptions = Proto->getNumExceptions();
590f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);
591cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
592f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (unsigned I = 0; I != NumExceptions; ++I) {
593f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    QualType Ty = Proto->getExceptionType(I);
594f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType();
595f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType, true);
596f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Filter->setFilter(I, EHType);
597cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  }
598cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump}
599cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
600cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stumpvoid CodeGenFunction::EmitEndEHSpec(const Decl *D) {
601a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson  if (!Exceptions)
602a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson    return;
603a994ee4b197554282ae6b222c3284ccaa3a6484cAnders Carlsson
604cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
605cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  if (FD == 0)
606cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
607cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
608cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  if (Proto == 0)
609cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
610cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
611cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump  if (!Proto->hasExceptionSpec())
612cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump    return;
613cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
614f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHStack.popFilter();
615cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump}
616cce3d4f9812182ed4e551b7cf0fc86576be8d9c5Mike Stump
6172bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stumpvoid CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
61859a7000a79118e4c140885ccbb2ac6a686a73092John McCall  EnterCXXTryStmt(S);
6199fc6a7774643a810c8501dae2323e863fefb623eJohn McCall  EmitStmt(S.getTryBlock());
62059a7000a79118e4c140885ccbb2ac6a686a73092John McCall  ExitCXXTryStmt(S);
6219fc6a7774643a810c8501dae2323e863fefb623eJohn McCall}
6229fc6a7774643a810c8501dae2323e863fefb623eJohn McCall
62359a7000a79118e4c140885ccbb2ac6a686a73092John McCallvoid CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
624f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  unsigned NumHandlers = S.getNumHandlers();
625f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers);
626f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
627f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (unsigned I = 0; I != NumHandlers; ++I) {
628f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    const CXXCatchStmt *C = S.getHandler(I);
629f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
630f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::BasicBlock *Handler = createBasicBlock("catch");
631f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (C->getExceptionDecl()) {
632f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // FIXME: Dropping the reference type on the type into makes it
633f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // impossible to correctly implement catch-by-reference
634f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // semantics for pointers.  Unfortunately, this is what all
635f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // existing compilers do, and it's not clear that the standard
636f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // personality routine is capable of doing this right.  See C++ DR 388:
637f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      //   http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#388
638f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      QualType CaughtType = C->getCaughtType();
639f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CaughtType = CaughtType.getNonReferenceType().getUnqualifiedType();
640f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::Value *TypeInfo = CGM.GetAddrOfRTTIDescriptor(CaughtType, true);
641f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CatchScope->setHandler(I, TypeInfo, Handler);
642f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    } else {
643f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // No exception decl indicates '...', a catch-all.
644f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CatchScope->setCatchAllHandler(I, Handler);
645f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
646f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
647f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
648f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
649f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Check whether this is a non-EH scope, i.e. a scope which doesn't
650f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// affect exception handling.  Currently, the only non-EH scopes are
651f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// normal-only cleanup scopes.
652f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic bool isNonEHScope(const EHScope &S) {
653da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  switch (S.getKind()) {
654da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  case EHScope::Cleanup:
655da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    return !cast<EHCleanupScope>(S).isEHCleanup();
656da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  case EHScope::LazyCleanup:
657da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    return !cast<EHLazyCleanupScope>(S).isEHCleanup();
658da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  case EHScope::Filter:
659da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  case EHScope::Catch:
660da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  case EHScope::Terminate:
661da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    return false;
662da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  }
663da65ea86482bc116906edfb9ba1d7124f76cc867John McCall
664da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  // Suppress warning.
665da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  return false;
666f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
6679fc6a7774643a810c8501dae2323e863fefb623eJohn McCall
668f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() {
669f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(EHStack.requiresLandingPad());
670f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(!EHStack.empty());
6719fc6a7774643a810c8501dae2323e863fefb623eJohn McCall
672da65ea86482bc116906edfb9ba1d7124f76cc867John McCall  if (!Exceptions)
673da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    return 0;
674da65ea86482bc116906edfb9ba1d7124f76cc867John McCall
675f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Check the innermost scope for a cached landing pad.  If this is
676f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.
677f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();
678f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (LP) return LP;
679f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
680f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Build the landing pad for this scope.
681f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  LP = EmitLandingPad();
682f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(LP);
683f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
684f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Cache the landing pad on the innermost scope.  If this is a
685f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // non-EH scope, cache the landing pad on the enclosing scope, too.
686f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (EHScopeStack::iterator ir = EHStack.begin(); true; ++ir) {
687f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    ir->setCachedLandingPad(LP);
688f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (!isNonEHScope(*ir)) break;
689f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
690f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
691f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return LP;
6929fc6a7774643a810c8501dae2323e863fefb623eJohn McCall}
6939fc6a7774643a810c8501dae2323e863fefb623eJohn McCall
694f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
695f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(EHStack.requiresLandingPad());
696f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
697f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // This function contains a hack to work around a design flaw in
698f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // LLVM's EH IR which breaks semantics after inlining.  This same
699f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // hack is implemented in llvm-gcc.
700f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //
701f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The LLVM EH abstraction is basically a thin veneer over the
702f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // traditional GCC zero-cost design: for each range of instructions
703f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // in the function, there is (at most) one "landing pad" with an
704f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // associated chain of EH actions.  A language-specific personality
705f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // function interprets this chain of actions and (1) decides whether
706f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // or not to resume execution at the landing pad and (2) if so,
707f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // provides an integer indicating why it's stopping.  In LLVM IR,
708f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // the association of a landing pad with a range of instructions is
709f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // achieved via an invoke instruction, the chain of actions becomes
710f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // the arguments to the @llvm.eh.selector call, and the selector
711f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // call returns the integer indicator.  Other than the required
712f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // presence of two intrinsic function calls in the landing pad,
713f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // the IR exactly describes the layout of the output code.
714f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //
715f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // A principal advantage of this design is that it is completely
716f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // language-agnostic; in theory, the LLVM optimizers can treat
717f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // landing pads neutrally, and targets need only know how to lower
718f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // the intrinsics to have a functioning exceptions system (assuming
719f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // that platform exceptions follow something approximately like the
720f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // GCC design).  Unfortunately, landing pads cannot be combined in a
721f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // language-agnostic way: given selectors A and B, there is no way
722f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // to make a single landing pad which faithfully represents the
723f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // semantics of propagating an exception first through A, then
724f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // through B, without knowing how the personality will interpret the
725f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // (lowered form of the) selectors.  This means that inlining has no
726f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // choice but to crudely chain invokes (i.e., to ignore invokes in
727f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // the inlined function, but to turn all unwindable calls into
728f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // invokes), which is only semantically valid if every unwind stops
729f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // at every landing pad.
730f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //
731f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Therefore, the invoke-inline hack is to guarantee that every
732f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // landing pad has a catch-all.
733f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  const bool UseInvokeInlineHack = true;
734f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
735f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (EHScopeStack::iterator ir = EHStack.begin(); ; ) {
736f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    assert(ir != EHStack.end() &&
737f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall           "stack requiring landing pad is nothing but non-EH scopes?");
738f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
739f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // If this is a terminate scope, just use the singleton terminate
740f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // landing pad.
741f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (isa<EHTerminateScope>(*ir))
742f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      return getTerminateLandingPad();
743f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
744f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // If this isn't an EH scope, iterate; otherwise break out.
745f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (!isNonEHScope(*ir)) break;
746f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    ++ir;
747f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
748f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // We haven't checked this scope for a cached landing pad yet.
749f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (llvm::BasicBlock *LP = ir->getCachedLandingPad())
750f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      return LP;
751f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
752f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
753f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Save the current IR generation state.
754f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
755f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
756f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Create and configure the landing pad.
757f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::BasicBlock *LP = createBasicBlock("lpad");
758f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EmitBlock(LP);
759f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
760f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Save the exception pointer.  It's safe to use a single exception
761f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // pointer per function because EH cleanups can never have nested
762f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // try/catches.
763f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *Exn =
764f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_exception), "exn");
765f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Exn->setDoesNotThrow();
766f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.CreateStore(Exn, getExceptionSlot());
767f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
768f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Build the selector arguments.
769f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::SmallVector<llvm::Value*, 8> EHSelector;
770f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHSelector.push_back(Exn);
771f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHSelector.push_back(getPersonalityFn(*this));
772f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
773f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Accumulate all the handlers in scope.
774f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::DenseMap<llvm::Value*, JumpDest> EHHandlers;
775f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  JumpDest CatchAll;
776f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  bool HasEHCleanup = false;
777f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  bool HasEHFilter = false;
778f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::SmallVector<llvm::Value*, 8> EHFilters;
779f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end();
780f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall         I != E; ++I) {
781f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
782f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    switch (I->getKind()) {
783da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    case EHScope::LazyCleanup:
784da65ea86482bc116906edfb9ba1d7124f76cc867John McCall      if (!HasEHCleanup)
785da65ea86482bc116906edfb9ba1d7124f76cc867John McCall        HasEHCleanup = cast<EHLazyCleanupScope>(*I).isEHCleanup();
786da65ea86482bc116906edfb9ba1d7124f76cc867John McCall      // We otherwise don't care about cleanups.
787da65ea86482bc116906edfb9ba1d7124f76cc867John McCall      continue;
788da65ea86482bc116906edfb9ba1d7124f76cc867John McCall
789f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    case EHScope::Cleanup:
790f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      if (!HasEHCleanup)
791f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        HasEHCleanup = cast<EHCleanupScope>(*I).isEHCleanup();
792f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // We otherwise don't care about cleanups.
793f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      continue;
794f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
795f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    case EHScope::Filter: {
796f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      assert(I.next() == EHStack.end() && "EH filter is not end of EH stack");
797f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      assert(!CatchAll.Block && "EH filter reached after catch-all");
798f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
799f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Filter scopes get added to the selector in wierd ways.
800f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EHFilterScope &Filter = cast<EHFilterScope>(*I);
801f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      HasEHFilter = true;
802f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
803f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Add all the filter values which we aren't already explicitly
804f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // catching.
805f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      for (unsigned I = 0, E = Filter.getNumFilters(); I != E; ++I) {
806f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        llvm::Value *FV = Filter.getFilter(I);
807f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        if (!EHHandlers.count(FV))
808f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall          EHFilters.push_back(FV);
809f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      }
810f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      goto done;
811f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
812f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
813f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    case EHScope::Terminate:
814f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Terminate scopes are basically catch-alls.
815f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      assert(!CatchAll.Block);
816f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CatchAll.Block = getTerminateHandler();
817f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CatchAll.ScopeDepth = EHStack.getEnclosingEHCleanup(I);
818f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      goto done;
819f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
820f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    case EHScope::Catch:
821f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      break;
822f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
823f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
824f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EHCatchScope &Catch = cast<EHCatchScope>(*I);
825f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    for (unsigned HI = 0, HE = Catch.getNumHandlers(); HI != HE; ++HI) {
826f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EHCatchScope::Handler Handler = Catch.getHandler(HI);
827f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
828f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Catch-all.  We should only have one of these per catch.
829f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      if (!Handler.Type) {
830f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        assert(!CatchAll.Block);
831f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        CatchAll.Block = Handler.Block;
832f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        CatchAll.ScopeDepth = EHStack.getEnclosingEHCleanup(I);
833f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        continue;
834f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      }
835f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
836f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // Check whether we already have a handler for this type.
837f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      JumpDest &Dest = EHHandlers[Handler.Type];
838f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      if (Dest.Block) continue;
839f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
840f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EHSelector.push_back(Handler.Type);
841f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Dest.Block = Handler.Block;
842f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Dest.ScopeDepth = EHStack.getEnclosingEHCleanup(I);
8432bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump    }
844f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
845f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Stop if we found a catch-all.
846f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (CatchAll.Block) break;
8472bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump  }
8482bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
849f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall done:
850f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  unsigned LastToEmitInLoop = EHSelector.size();
851f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
852f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // If we have a catch-all, add null to the selector.
853f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (CatchAll.Block) {
854f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EHSelector.push_back(getCatchAllValue(CGF));
855f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
856f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // If we have an EH filter, we need to add those handlers in the
857f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // right place in the selector, which is to say, at the end.
858f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else if (HasEHFilter) {
859f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Create a filter expression: an integer constant saying how many
860f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // filters there are (+1 to avoid ambiguity with 0 for cleanup),
861f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // followed by the filter types.  The personality routine only
862f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // lands here if the filter doesn't match.
863f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EHSelector.push_back(llvm::ConstantInt::get(Builder.getInt32Ty(),
864f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                                EHFilters.size() + 1));
865f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EHSelector.append(EHFilters.begin(), EHFilters.end());
866f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
867f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Also check whether we need a cleanup.
868f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (UseInvokeInlineHack || HasEHCleanup)
869f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EHSelector.push_back(UseInvokeInlineHack
870f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           ? getCatchAllValue(CGF)
871f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           : getCleanupValue(CGF));
872f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
873f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Otherwise, signal that we at least have cleanups.
874f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else if (UseInvokeInlineHack || HasEHCleanup) {
875f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EHSelector.push_back(UseInvokeInlineHack
876f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                         ? getCatchAllValue(CGF)
877f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                         : getCleanupValue(CGF));
878f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else {
879f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    assert(LastToEmitInLoop > 2);
880f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    LastToEmitInLoop--;
8810f590be3808365e851352543faa6acbece50b686Mike Stump  }
8822bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
883f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(EHSelector.size() >= 3 && "selector call has only two arguments!");
884f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
885f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Tell the backend how to generate the landing pad.
886f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *Selection =
887f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector),
888f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                       EHSelector.begin(), EHSelector.end(), "eh.selector");
889f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Selection->setDoesNotThrow();
890f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
891f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Select the right handler.
892f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *llvm_eh_typeid_for =
893f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
894f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
895f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The results of llvm_eh_typeid_for aren't reliable --- at least
896f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // not locally --- so we basically have to do this as an 'if' chain.
897f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // We walk through the first N-1 catch clauses, testing and chaining,
898f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // and then fall into the final clause (which is either a cleanup, a
899f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // filter (possibly with a cleanup), a catch-all, or another catch).
900f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (unsigned I = 2; I != LastToEmitInLoop; ++I) {
901f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::Value *Type = EHSelector[I];
902f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    JumpDest Dest = EHHandlers[Type];
903f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    assert(Dest.Block && "no handler entry for value in selector?");
904f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
905f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Figure out where to branch on a match.  As a debug code-size
906f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // optimization, if the scope depth matches the innermost cleanup,
907f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // we branch directly to the catch handler.
908f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::BasicBlock *Match = Dest.Block;
909f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    bool MatchNeedsCleanup = Dest.ScopeDepth != EHStack.getInnermostEHCleanup();
910f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (MatchNeedsCleanup)
911f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Match = createBasicBlock("eh.match");
912f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
913f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::BasicBlock *Next = createBasicBlock("eh.next");
914f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
915f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Check whether the exception matches.
916f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::CallInst *Id
917f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      = Builder.CreateCall(llvm_eh_typeid_for,
918f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           Builder.CreateBitCast(Type, CGM.PtrToInt8Ty));
919f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Id->setDoesNotThrow();
920f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateCondBr(Builder.CreateICmpEQ(Selection, Id),
921f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                         Match, Next);
922f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
923f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Emit match code if necessary.
924f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (MatchNeedsCleanup) {
9250f590be3808365e851352543faa6acbece50b686Mike Stump      EmitBlock(Match);
926f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EmitBranchThroughEHCleanup(Dest);
9270f590be3808365e851352543faa6acbece50b686Mike Stump    }
9280f590be3808365e851352543faa6acbece50b686Mike Stump
929f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Continue to the next match.
930f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EmitBlock(Next);
931f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
932f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
933f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Emit the final case in the selector.
934f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // This might be a catch-all....
935f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (CatchAll.Block) {
936f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    assert(isa<llvm::ConstantPointerNull>(EHSelector.back()));
937f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EmitBranchThroughEHCleanup(CatchAll);
938f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
939f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // ...or an EH filter...
940f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else if (HasEHFilter) {
941f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::Value *SavedSelection = Selection;
942f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
943f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // First, unwind out to the outermost scope if necessary.
944f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (EHStack.hasEHCleanups()) {
945f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // The end here might not dominate the beginning, so we might need to
946f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // save the selector if we need it.
947f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::AllocaInst *SelectorVar = 0;
948f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      if (HasEHCleanup) {
949f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        SelectorVar = CreateTempAlloca(Builder.getInt32Ty(), "selector.var");
950f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        Builder.CreateStore(Selection, SelectorVar);
951f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump      }
952f7f74675d4e63c4529a4b890c0dd62cf6dc4c476Mike Stump
953f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::BasicBlock *CleanupContBB = createBasicBlock("ehspec.cleanup.cont");
954f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EmitBranchThroughEHCleanup(JumpDest(CleanupContBB, EHStack.stable_end()));
955f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EmitBlock(CleanupContBB);
956f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
957f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      if (HasEHCleanup)
958f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        SavedSelection = Builder.CreateLoad(SelectorVar, "ehspec.saved-selector");
9590f590be3808365e851352543faa6acbece50b686Mike Stump    }
9600f590be3808365e851352543faa6acbece50b686Mike Stump
961f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // If there was a cleanup, we'll need to actually check whether we
962f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // landed here because the filter triggered.
963f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (UseInvokeInlineHack || HasEHCleanup) {
964f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::BasicBlock *RethrowBB = createBasicBlock("cleanup");
965f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::BasicBlock *UnexpectedBB = createBasicBlock("ehspec.unexpected");
966f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
967f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::Constant *Zero = llvm::ConstantInt::get(Builder.getInt32Ty(), 0);
968f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::Value *FailsFilter =
969f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        Builder.CreateICmpSLT(SavedSelection, Zero, "ehspec.fails");
970f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateCondBr(FailsFilter, UnexpectedBB, RethrowBB);
971f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
972f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // The rethrow block is where we land if this was a cleanup.
973f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      // TODO: can this be _Unwind_Resume if the InvokeInlineHack is off?
974f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EmitBlock(RethrowBB);
975f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateCall(getUnwindResumeOrRethrowFn(),
976f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                         Builder.CreateLoad(getExceptionSlot()))
977f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        ->setDoesNotReturn();
978f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateUnreachable();
9790f590be3808365e851352543faa6acbece50b686Mike Stump
980f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EmitBlock(UnexpectedBB);
981f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
9820f590be3808365e851352543faa6acbece50b686Mike Stump
983f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Call __cxa_call_unexpected.  This doesn't need to be an invoke
984f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // because __cxa_call_unexpected magically filters exceptions
985f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // according to the last landing pad the exception was thrown
986f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // into.  Seriously.
987f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateCall(getUnexpectedFn(*this),
988f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                       Builder.CreateLoad(getExceptionSlot()))
989f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      ->setDoesNotReturn();
990f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateUnreachable();
9910f590be3808365e851352543faa6acbece50b686Mike Stump
992f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // ...or a normal catch handler...
993f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else if (!UseInvokeInlineHack && !HasEHCleanup) {
994f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::Value *Type = EHSelector.back();
995f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EmitBranchThroughEHCleanup(EHHandlers[Type]);
9960f590be3808365e851352543faa6acbece50b686Mike Stump
997f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // ...or a cleanup.
998f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else {
999f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // We emit a jump to a notional label at the outermost unwind state.
1000f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::BasicBlock *Unwind = createBasicBlock("eh.resume");
1001f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    JumpDest Dest(Unwind, EHStack.stable_end());
1002f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EmitBranchThroughEHCleanup(Dest);
1003f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1004f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // The unwind block.  We have to reload the exception here because
1005f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // we might have unwound through arbitrary blocks, so the landing
1006f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // pad might not dominate.
1007f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EmitBlock(Unwind);
10080f590be3808365e851352543faa6acbece50b686Mike Stump
1009f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // This can always be a call because we necessarily didn't find
1010f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // anything on the EH stack which needs our help.
1011f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateCall(getUnwindResumeOrRethrowFn(),
1012f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                       Builder.CreateLoad(getExceptionSlot()))
1013f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      ->setDoesNotReturn();
1014f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateUnreachable();
1015f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
1016f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1017f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Restore the old IR generation state.
1018f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.restoreIP(SavedIP);
1019f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1020f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return LP;
1021f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
10220f590be3808365e851352543faa6acbece50b686Mike Stump
10238e3f86193995c47ee0d229e4336c3382410f09f5John McCallnamespace {
10248e3f86193995c47ee0d229e4336c3382410f09f5John McCall  /// A cleanup to call __cxa_end_catch.  In many cases, the caught
10258e3f86193995c47ee0d229e4336c3382410f09f5John McCall  /// exception type lets us state definitively that the thrown exception
10268e3f86193995c47ee0d229e4336c3382410f09f5John McCall  /// type does not have a destructor.  In particular:
10278e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///   - Catch-alls tell us nothing, so we have to conservatively
10288e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///     assume that the thrown exception might have a destructor.
10298e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///   - Catches by reference behave according to their base types.
10308e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///   - Catches of non-record types will only trigger for exceptions
10318e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///     of non-record types, which never have destructors.
10328e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///   - Catches of record types can trigger for arbitrary subclasses
10338e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///     of the caught type, so we have to assume the actual thrown
10348e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///     exception type might have a throwing destructor, even if the
10358e3f86193995c47ee0d229e4336c3382410f09f5John McCall  ///     caught type's destructor is trivial or nothrow.
10368e3f86193995c47ee0d229e4336c3382410f09f5John McCall  struct CallEndCatch : EHScopeStack::LazyCleanup {
10378e3f86193995c47ee0d229e4336c3382410f09f5John McCall    CallEndCatch(bool MightThrow) : MightThrow(MightThrow) {}
10388e3f86193995c47ee0d229e4336c3382410f09f5John McCall    bool MightThrow;
10398e3f86193995c47ee0d229e4336c3382410f09f5John McCall
10408e3f86193995c47ee0d229e4336c3382410f09f5John McCall    void Emit(CodeGenFunction &CGF, bool IsForEH) {
10418e3f86193995c47ee0d229e4336c3382410f09f5John McCall      if (!MightThrow) {
10428e3f86193995c47ee0d229e4336c3382410f09f5John McCall        CGF.Builder.CreateCall(getEndCatchFn(CGF))->setDoesNotThrow();
10438e3f86193995c47ee0d229e4336c3382410f09f5John McCall        return;
10448e3f86193995c47ee0d229e4336c3382410f09f5John McCall      }
10458e3f86193995c47ee0d229e4336c3382410f09f5John McCall
10468e3f86193995c47ee0d229e4336c3382410f09f5John McCall      CGF.EmitCallOrInvoke(getEndCatchFn(CGF), 0, 0);
10478e3f86193995c47ee0d229e4336c3382410f09f5John McCall    }
10488e3f86193995c47ee0d229e4336c3382410f09f5John McCall  };
10498e3f86193995c47ee0d229e4336c3382410f09f5John McCall}
10508e3f86193995c47ee0d229e4336c3382410f09f5John McCall
1051f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Emits a call to __cxa_begin_catch and enters a cleanup to call
1052f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// __cxa_end_catch.
10538e3f86193995c47ee0d229e4336c3382410f09f5John McCall///
10548e3f86193995c47ee0d229e4336c3382410f09f5John McCall/// \param EndMightThrow - true if __cxa_end_catch might throw
10558e3f86193995c47ee0d229e4336c3382410f09f5John McCallstatic llvm::Value *CallBeginCatch(CodeGenFunction &CGF,
10568e3f86193995c47ee0d229e4336c3382410f09f5John McCall                                   llvm::Value *Exn,
10578e3f86193995c47ee0d229e4336c3382410f09f5John McCall                                   bool EndMightThrow) {
1058f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *Call = CGF.Builder.CreateCall(getBeginCatchFn(CGF), Exn);
1059f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Call->setDoesNotThrow();
10600f590be3808365e851352543faa6acbece50b686Mike Stump
10618e3f86193995c47ee0d229e4336c3382410f09f5John McCall  CGF.EHStack.pushLazyCleanup<CallEndCatch>(NormalAndEHCleanup, EndMightThrow);
1062f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1063f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return Call;
1064f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1065f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1066f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// A "special initializer" callback for initializing a catch
1067f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// parameter during catch initialization.
1068f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic void InitCatchParam(CodeGenFunction &CGF,
1069f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           const VarDecl &CatchParam,
1070f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           llvm::Value *ParamAddr) {
1071f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Load the exception from where the landing pad saved it.
1072f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *Exn = CGF.Builder.CreateLoad(CGF.getExceptionSlot(), "exn");
1073f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1074f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CanQualType CatchType =
1075f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.CGM.getContext().getCanonicalType(CatchParam.getType());
1076f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  const llvm::Type *LLVMCatchTy = CGF.ConvertTypeForMem(CatchType);
1077f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1078f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // If we're catching by reference, we can just cast the object
1079f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // pointer to the appropriate pointer.
1080f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (isa<ReferenceType>(CatchType)) {
10818e3f86193995c47ee0d229e4336c3382410f09f5John McCall    bool EndCatchMightThrow = cast<ReferenceType>(CatchType)->getPointeeType()
10828e3f86193995c47ee0d229e4336c3382410f09f5John McCall      ->isRecordType();
10838e3f86193995c47ee0d229e4336c3382410f09f5John McCall
1084f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // __cxa_begin_catch returns the adjusted object pointer.
10858e3f86193995c47ee0d229e4336c3382410f09f5John McCall    llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, EndCatchMightThrow);
1086f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::Value *ExnCast =
1087f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.byref");
1088f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.Builder.CreateStore(ExnCast, ParamAddr);
1089f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return;
1090a086783570f76062a345e761811296dc8df571c8Mike Stump  }
10912bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
1092f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Non-aggregates (plus complexes).
1093f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  bool IsComplex = false;
1094f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (!CGF.hasAggregateLLVMType(CatchType) ||
1095f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      (IsComplex = CatchType->isAnyComplexType())) {
10968e3f86193995c47ee0d229e4336c3382410f09f5John McCall    llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, false);
1097f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1098f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // If the catch type is a pointer type, __cxa_begin_catch returns
1099f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // the pointer by value.
1100f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (CatchType->hasPointerRepresentation()) {
1101f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::Value *CastExn =
1102f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        CGF.Builder.CreateBitCast(AdjustedExn, LLVMCatchTy, "exn.casted");
1103f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CGF.Builder.CreateStore(CastExn, ParamAddr);
1104f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      return;
1105f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
11062bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
1107f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Otherwise, it returns a pointer into the exception object.
11082bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
1109f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    const llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok
1110f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
11112bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
1112f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (IsComplex) {
1113f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CGF.StoreComplexToAddr(CGF.LoadComplexFromAddr(Cast, /*volatile*/ false),
1114f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                             ParamAddr, /*volatile*/ false);
1115f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    } else {
1116f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::Value *ExnLoad = CGF.Builder.CreateLoad(Cast, "exn.scalar");
1117f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CGF.EmitStoreOfScalar(ExnLoad, ParamAddr, /*volatile*/ false, CatchType);
1118f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
1119f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return;
1120f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
11210f590be3808365e851352543faa6acbece50b686Mike Stump
1122f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // FIXME: this *really* needs to be done via a proper, Sema-emitted
1123f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // initializer expression.
11242bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
1125f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CXXRecordDecl *RD = CatchType.getTypePtr()->getAsCXXRecordDecl();
1126f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(RD && "aggregate catch type was not a record!");
1127b2c9c0b1c5e25cfbee1403cde12b98f180e6b315Mike Stump
1128f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  const llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok
1129f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1130f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (RD->hasTrivialCopyConstructor()) {
11318e3f86193995c47ee0d229e4336c3382410f09f5John McCall    llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, true);
1132f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
1133f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.EmitAggregateCopy(ParamAddr, Cast, CatchType);
1134f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return;
1135f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
1136f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1137f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // We have to call __cxa_get_exception_ptr to get the adjusted
1138f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // pointer before copying.
1139f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *AdjustedExn =
1140f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.Builder.CreateCall(getGetExceptionPtrFn(CGF), Exn);
1141f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  AdjustedExn->setDoesNotThrow();
1142f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy);
1143f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1144f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CXXConstructorDecl *CD = RD->getCopyConstructor(CGF.getContext(), 0);
1145f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(CD && "record has no copy constructor!");
1146f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *CopyCtor = CGF.CGM.GetAddrOfCXXConstructor(CD, Ctor_Complete);
1147f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1148f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CallArgList CallArgs;
1149f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CallArgs.push_back(std::make_pair(RValue::get(ParamAddr),
1150f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                    CD->getThisType(CGF.getContext())));
1151f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CallArgs.push_back(std::make_pair(RValue::get(Cast),
1152f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                    CD->getParamDecl(0)->getType()));
1153f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1154f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  const FunctionProtoType *FPT
1155f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    = CD->getType()->getAs<FunctionProtoType>();
1156f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1157f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Call the copy ctor in a terminate scope.
1158f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.EHStack.pushTerminate();
1159f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(CallArgs, FPT),
1160f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall               CopyCtor, ReturnValueSlot(), CallArgs, CD);
1161f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.EHStack.popTerminate();
1162f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1163f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Finally we can call __cxa_begin_catch.
11648e3f86193995c47ee0d229e4336c3382410f09f5John McCall  CallBeginCatch(CGF, Exn, true);
1165f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1166f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1167f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Begins a catch statement by initializing the catch variable and
1168f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// calling __cxa_begin_catch.
1169f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallstatic void BeginCatch(CodeGenFunction &CGF,
1170f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                       const CXXCatchStmt *S) {
1171f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // We have to be very careful with the ordering of cleanups here:
1172f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   C++ [except.throw]p4:
1173f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //     The destruction [of the exception temporary] occurs
1174f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //     immediately after the destruction of the object declared in
1175f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //     the exception-declaration in the handler.
1176f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //
1177f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // So the precise ordering is:
1178f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   1.  Construct catch variable.
1179f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   2.  __cxa_begin_catch
1180f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   3.  Enter __cxa_end_catch cleanup
1181f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   4.  Enter dtor cleanup
1182f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //
1183f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // We do this by initializing the exception variable with a
1184f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // "special initializer", InitCatchParam.  Delegation sequence:
1185f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   - ExitCXXTryStmt opens a RunCleanupsScope
1186f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //     - EmitLocalBlockVarDecl creates the variable and debug info
1187f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //       - InitCatchParam initializes the variable from the exception
1188f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //         - CallBeginCatch calls __cxa_begin_catch
1189f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //         - CallBeginCatch enters the __cxa_end_catch cleanup
1190f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //     - EmitLocalBlockVarDecl enters the variable destructor cleanup
1191f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   - EmitCXXTryStmt emits the code for the catch body
1192f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   - EmitCXXTryStmt close the RunCleanupsScope
1193f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1194f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  VarDecl *CatchParam = S->getExceptionDecl();
1195f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (!CatchParam) {
1196f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::Value *Exn = CGF.Builder.CreateLoad(CGF.getExceptionSlot(), "exn");
11978e3f86193995c47ee0d229e4336c3382410f09f5John McCall    CallBeginCatch(CGF, Exn, true);
1198f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return;
1199f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
1200f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1201f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Emit the local.
1202f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.EmitLocalBlockVarDecl(*CatchParam, &InitCatchParam);
1203f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1204f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1205fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCallnamespace {
1206fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall  struct CallRethrow : EHScopeStack::LazyCleanup {
1207fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall    void Emit(CodeGenFunction &CGF, bool IsForEH) {
1208fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall      CGF.EmitCallOrInvoke(getReThrowFn(CGF), 0, 0);
1209fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall    }
1210fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall  };
1211fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall}
1212fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall
121359a7000a79118e4c140885ccbb2ac6a686a73092John McCallvoid CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
1214f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  unsigned NumHandlers = S.getNumHandlers();
1215f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
1216f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(CatchScope.getNumHandlers() == NumHandlers);
1217f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1218f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Copy the handler blocks off before we pop the EH stack.  Emitting
1219f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // the handlers might scribble on this memory.
1220f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::SmallVector<EHCatchScope::Handler, 8> Handlers(NumHandlers);
1221f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  memcpy(Handlers.data(), CatchScope.begin(),
1222f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall         NumHandlers * sizeof(EHCatchScope::Handler));
1223f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHStack.popCatch();
1224f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1225f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The fall-through block.
1226f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::BasicBlock *ContBB = createBasicBlock("try.cont");
1227f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1228f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // We just emitted the body of the try; jump to the continue block.
1229f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (HaveInsertPoint())
1230f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateBr(ContBB);
1231f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
123259a7000a79118e4c140885ccbb2ac6a686a73092John McCall  // Determine if we need an implicit rethrow for all these catch handlers.
123359a7000a79118e4c140885ccbb2ac6a686a73092John McCall  bool ImplicitRethrow = false;
123459a7000a79118e4c140885ccbb2ac6a686a73092John McCall  if (IsFnTryBlock)
123559a7000a79118e4c140885ccbb2ac6a686a73092John McCall    ImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) ||
123659a7000a79118e4c140885ccbb2ac6a686a73092John McCall                      isa<CXXConstructorDecl>(CurCodeDecl);
123759a7000a79118e4c140885ccbb2ac6a686a73092John McCall
1238f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  for (unsigned I = 0; I != NumHandlers; ++I) {
1239f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::BasicBlock *CatchBlock = Handlers[I].Block;
1240f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EmitBlock(CatchBlock);
1241f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1242f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Catch the exception if this isn't a catch-all.
1243f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    const CXXCatchStmt *C = S.getHandler(I);
1244f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1245f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Enter a cleanup scope, including the catch variable and the
1246f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // end-catch.
1247f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    RunCleanupsScope CatchScope(*this);
1248f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1249f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Initialize the catch variable and set up the cleanups.
1250f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    BeginCatch(*this, C);
1251f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
125259a7000a79118e4c140885ccbb2ac6a686a73092John McCall    // If there's an implicit rethrow, push a normal "cleanup" to call
1253fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall    // _cxa_rethrow.  This needs to happen before __cxa_end_catch is
1254fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall    // called, and so it is pushed after BeginCatch.
1255fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall    if (ImplicitRethrow)
1256fcd5c0c62ef3d86ecd991753bb43c88c861470e7John McCall      EHStack.pushLazyCleanup<CallRethrow>(NormalCleanup);
125759a7000a79118e4c140885ccbb2ac6a686a73092John McCall
1258f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Perform the body of the catch.
1259f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EmitStmt(C->getHandlerBlock());
1260f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1261f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Fall out through the catch cleanups.
1262f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CatchScope.ForceCleanup();
1263f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1264f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Branch out of the try.
1265f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (HaveInsertPoint())
1266f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateBr(ContBB);
1267f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
12682bf701ee4babb5c4a9ea99ca4675c5ef040bd402Mike Stump
1269f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EmitBlock(ContBB);
1270f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1271f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1272f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// Enters a finally block for an implementation using zero-cost
1273f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// exceptions.  This is mostly general, but hard-codes some
1274f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall/// language/ABI-specific behavior in the catch-all sections.
1275f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallCodeGenFunction::FinallyInfo
1276f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallCodeGenFunction::EnterFinallyBlock(const Stmt *Body,
1277f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                   llvm::Constant *BeginCatchFn,
1278f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                   llvm::Constant *EndCatchFn,
1279f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                   llvm::Constant *RethrowFn) {
1280f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert((BeginCatchFn != 0) == (EndCatchFn != 0) &&
1281f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall         "begin/end catch functions not paired");
1282f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(RethrowFn && "rethrow function is required");
1283f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1284f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The rethrow function has one of the following two types:
1285f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   void (*)()
1286f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  //   void (*)(void*)
1287f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // In the latter case we need to pass it the exception object.
1288f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // But we can't use the exception slot because the @finally might
1289f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // have a landing pad (which would overwrite the exception slot).
1290f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  const llvm::FunctionType *RethrowFnTy =
1291f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    cast<llvm::FunctionType>(
1292f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      cast<llvm::PointerType>(RethrowFn->getType())
1293f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      ->getElementType());
1294f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *SavedExnVar = 0;
1295f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (RethrowFnTy->getNumParams())
1296f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    SavedExnVar = CreateTempAlloca(Builder.getInt8PtrTy(), "finally.exn");
1297f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1298f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // A finally block is a statement which must be executed on any edge
1299f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // out of a given scope.  Unlike a cleanup, the finally block may
1300f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // contain arbitrary control flow leading out of itself.  In
1301f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // addition, finally blocks should always be executed, even if there
1302f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // are no catch handlers higher on the stack.  Therefore, we
1303f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // surround the protected scope with a combination of a normal
1304f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // cleanup (to catch attempts to break out of the block via normal
1305f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // control flow) and an EH catch-all (semantically "outside" any try
1306f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // statement to which the finally block might have been attached).
1307f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // The finally block itself is generated in the context of a cleanup
1308f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // which conditionally leaves the catch-all.
1309f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1310f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  FinallyInfo Info;
1311f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1312f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Jump destination for performing the finally block on an exception
1313f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // edge.  We'll never actually reach this block, so unreachable is
1314f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // fine.
1315f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  JumpDest RethrowDest = getJumpDestInCurrentScope(getUnreachableBlock());
1316f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1317f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Whether the finally block is being executed for EH purposes.
1318f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::AllocaInst *ForEHVar = CreateTempAlloca(CGF.Builder.getInt1Ty(),
1319f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                                "finally.for-eh");
1320f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  InitTempAlloca(ForEHVar, llvm::ConstantInt::getFalse(getLLVMContext()));
1321f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1322f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Enter a normal cleanup which will perform the @finally block.
1323f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  {
1324da65ea86482bc116906edfb9ba1d7124f76cc867John McCall    CodeGenFunction::CleanupBlock Cleanup(*this, NormalCleanup);
1325f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1326f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Enter a cleanup to call the end-catch function if one was provided.
1327f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (EndCatchFn) {
1328da65ea86482bc116906edfb9ba1d7124f76cc867John McCall      CodeGenFunction::CleanupBlock FinallyExitCleanup(CGF, NormalAndEHCleanup);
1329f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1330f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::BasicBlock *EndCatchBB = createBasicBlock("finally.endcatch");
1331f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::BasicBlock *CleanupContBB = createBasicBlock("finally.cleanup.cont");
1332f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1333f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::Value *ShouldEndCatch =
1334f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        Builder.CreateLoad(ForEHVar, "finally.endcatch");
1335f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1336f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EmitBlock(EndCatchBB);
13378e3f86193995c47ee0d229e4336c3382410f09f5John McCall      EmitCallOrInvoke(EndCatchFn, 0, 0); // catch-all, so might throw
1338f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EmitBlock(CleanupContBB);
1339f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
1340f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1341f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Emit the finally block.
1342f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EmitStmt(Body);
1343f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1344f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // If the end of the finally is reachable, check whether this was
1345f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // for EH.  If so, rethrow.
1346f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (HaveInsertPoint()) {
1347f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::BasicBlock *RethrowBB = createBasicBlock("finally.rethrow");
1348f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::BasicBlock *ContBB = createBasicBlock("finally.cont");
1349f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1350f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      llvm::Value *ShouldRethrow =
1351f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        Builder.CreateLoad(ForEHVar, "finally.shouldthrow");
1352f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1353f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1354f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EmitBlock(RethrowBB);
1355f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      if (SavedExnVar) {
1356f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        llvm::Value *Args[] = { Builder.CreateLoad(SavedExnVar) };
1357f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        EmitCallOrInvoke(RethrowFn, Args, Args+1);
1358f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      } else {
1359f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall        EmitCallOrInvoke(RethrowFn, 0, 0);
1360f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      }
1361f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.CreateUnreachable();
1362f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1363f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      EmitBlock(ContBB);
1364f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
1365f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1366f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Leave the end-catch cleanup.  As an optimization, pretend that
1367f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // the fallthrough path was inaccessible; we've dynamically proven
1368f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // that we're not in the EH case along that path.
1369f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (EndCatchFn) {
1370f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1371f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      PopCleanupBlock();
1372f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      Builder.restoreIP(SavedIP);
1373f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    }
1374f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1375f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Now make sure we actually have an insertion point or the
1376f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // cleanup gods will hate us.
1377f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EnsureInsertPoint();
1378f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
1379f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1380f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Enter a catch-all scope.
1381f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::BasicBlock *CatchAllBB = createBasicBlock("finally.catchall");
1382f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
1383f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.SetInsertPoint(CatchAllBB);
1384f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1385f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // If there's a begin-catch function, call it.
1386f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (BeginCatchFn) {
1387f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateCall(BeginCatchFn, Builder.CreateLoad(getExceptionSlot()))
1388f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      ->setDoesNotThrow();
1389f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
1390f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1391f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // If we need to remember the exception pointer to rethrow later, do so.
1392f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (SavedExnVar) {
1393f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    llvm::Value *SavedExn = Builder.CreateLoad(getExceptionSlot());
1394f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateStore(SavedExn, SavedExnVar);
1395f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
1396f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1397f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Tell the finally block that we're in EH.
1398f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.CreateStore(llvm::ConstantInt::getTrue(getLLVMContext()), ForEHVar);
1399f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1400f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Thread a jump through the finally cleanup.
1401f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EmitBranchThroughCleanup(RethrowDest);
1402f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1403f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.restoreIP(SavedIP);
1404f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1405f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHCatchScope *CatchScope = EHStack.pushCatch(1);
1406f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CatchScope->setCatchAllHandler(0, CatchAllBB);
1407f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1408f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return Info;
1409f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1410f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1411f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CodeGenFunction::ExitFinallyBlock(FinallyInfo &Info) {
1412f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Leave the finally catch-all.
1413f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHCatchScope &Catch = cast<EHCatchScope>(*EHStack.begin());
1414f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::BasicBlock *CatchAllBB = Catch.getHandler(0).Block;
1415f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHStack.popCatch();
1416f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1417f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // And leave the normal cleanup.
1418f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  PopCleanupBlock();
1419f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1420f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1421f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EmitBlock(CatchAllBB, true);
1422f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1423f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.restoreIP(SavedIP);
1424f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1425f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1426f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallllvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
1427f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (TerminateLandingPad)
1428f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    return TerminateLandingPad;
1429f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1430f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1431f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1432f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // This will get inserted at the end of the function.
1433f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  TerminateLandingPad = createBasicBlock("terminate.lpad");
1434f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.SetInsertPoint(TerminateLandingPad);
1435f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1436f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Tell the backend that this is a landing pad.
1437f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *Exn =
1438f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_exception), "exn");
1439f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Exn->setDoesNotThrow();
1440f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1441f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Tell the backend what the exception table should be:
1442f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // nothing but a catch-all.
1443f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::Value *Args[3] = { Exn, getPersonalityFn(*this),
1444f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                           getCatchAllValue(*this) };
1445f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::eh_selector),
1446f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                     Args, Args+3, "eh.selector")
1447f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    ->setDoesNotThrow();
1448f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1449f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(*this));
1450f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  TerminateCall->setDoesNotReturn();
1451f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  TerminateCall->setDoesNotThrow();
1452d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump  CGF.Builder.CreateUnreachable();
1453d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump
1454f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Restore the saved insertion state.
1455f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.restoreIP(SavedIP);
1456891f80ec2fb2d1730b769467d602689e1080845bJohn McCall
1457f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  return TerminateLandingPad;
1458d88ea5687968640ada2bc5a10211cbeb68a671ecMike Stump}
14599b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump
14609b39c51ae3c547568ac42325f94b4197618f6b18Mike Stumpllvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
1461182f383db1782af752ecaf607fdff72a8542088bMike Stump  if (TerminateHandler)
1462182f383db1782af752ecaf607fdff72a8542088bMike Stump    return TerminateHandler;
1463182f383db1782af752ecaf607fdff72a8542088bMike Stump
1464f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
14659b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump
1466f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Set up the terminate handler.  This block is inserted at the very
1467f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // end of the function by FinishFunction.
1468182f383db1782af752ecaf607fdff72a8542088bMike Stump  TerminateHandler = createBasicBlock("terminate.handler");
1469f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.SetInsertPoint(TerminateHandler);
1470f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::CallInst *TerminateCall = Builder.CreateCall(getTerminateFn(*this));
14719b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump  TerminateCall->setDoesNotReturn();
14729b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump  TerminateCall->setDoesNotThrow();
14739b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump  Builder.CreateUnreachable();
14749b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump
14753d3ec1c099ec8bfac3aa1fb0126fe515b7c7fa05John McCall  // Restore the saved insertion state.
1476f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  Builder.restoreIP(SavedIP);
147776958099828bac6ebd45abef9f76934b3e99e397Mike Stump
14789b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump  return TerminateHandler;
14799b39c51ae3c547568ac42325f94b4197618f6b18Mike Stump}
1480f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1481f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallCodeGenFunction::CleanupBlock::CleanupBlock(CodeGenFunction &CGF,
1482f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                                            CleanupKind Kind)
1483f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  : CGF(CGF), SavedIP(CGF.Builder.saveIP()), NormalCleanupExitBB(0) {
1484f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::BasicBlock *EntryBB = CGF.createBasicBlock("cleanup");
1485f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.Builder.SetInsertPoint(EntryBB);
1486f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1487f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  switch (Kind) {
1488f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  case NormalAndEHCleanup:
1489f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    NormalCleanupEntryBB = EHCleanupEntryBB = EntryBB;
1490f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    break;
1491f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1492f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  case NormalCleanup:
1493f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    NormalCleanupEntryBB = EntryBB;
1494f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EHCleanupEntryBB = 0;
1495f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    break;
1496f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1497f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  case EHCleanup:
1498f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    NormalCleanupEntryBB = 0;
1499f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EHCleanupEntryBB = EntryBB;
1500f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    CGF.EHStack.pushTerminate();
1501f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    break;
1502f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
1503f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1504f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1505f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallvoid CodeGenFunction::CleanupBlock::beginEHCleanup() {
1506f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(EHCleanupEntryBB == 0 && "already started an EH cleanup");
1507f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  NormalCleanupExitBB = CGF.Builder.GetInsertBlock();
1508f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  assert(NormalCleanupExitBB && "end of normal cleanup is unreachable");
1509f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1510f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  EHCleanupEntryBB = CGF.createBasicBlock("eh.cleanup");
1511f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.Builder.SetInsertPoint(EHCleanupEntryBB);
1512f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.EHStack.pushTerminate();
1513f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1514f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1515f1549f66a8216a78112286e3978cea2c29d6334cJohn McCallCodeGenFunction::CleanupBlock::~CleanupBlock() {
1516f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  llvm::BasicBlock *EHCleanupExitBB = 0;
1517f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1518f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // If we're currently writing the EH cleanup...
1519f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  if (EHCleanupEntryBB) {
1520f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Set the EH cleanup exit block.
1521f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    EHCleanupExitBB = CGF.Builder.GetInsertBlock();
1522f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    assert(EHCleanupExitBB && "end of EH cleanup is unreachable");
1523f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1524f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // If we're actually writing both at once, set the normal exit, too.
1525f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    if (EHCleanupEntryBB == NormalCleanupEntryBB)
1526f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      NormalCleanupExitBB = EHCleanupExitBB;
1527f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1528f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    // Otherwise, we must have pushed a terminate handler.
1529f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    else
1530f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall      CGF.EHStack.popTerminate();
1531f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1532f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  // Otherwise, just set the normal cleanup exit block.
1533f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  } else {
1534f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    NormalCleanupExitBB = CGF.Builder.GetInsertBlock();
1535f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall    assert(NormalCleanupExitBB && "end of normal cleanup is unreachable");
1536f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  }
1537f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1538f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.EHStack.pushCleanup(NormalCleanupEntryBB, NormalCleanupExitBB,
1539f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall                          EHCleanupEntryBB, EHCleanupExitBB);
1540f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1541f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall  CGF.Builder.restoreIP(SavedIP);
1542f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall}
1543f1549f66a8216a78112286e3978cea2c29d6334cJohn McCall
1544da65ea86482bc116906edfb9ba1d7124f76cc867John McCallvoid EHScopeStack::LazyCleanup::_anchor() {}
1545