clang  6.0.0svn
CGCleanup.h
Go to the documentation of this file.
1 //===-- CGCleanup.h - Classes for cleanups IR generation --------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // These classes support the generation of LLVM IR for cleanups.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_LIB_CODEGEN_CGCLEANUP_H
15 #define LLVM_CLANG_LIB_CODEGEN_CGCLEANUP_H
16 
17 #include "EHScopeStack.h"
18 
19 #include "Address.h"
20 #include "llvm/ADT/SmallPtrSet.h"
21 #include "llvm/ADT/SmallVector.h"
22 
23 namespace llvm {
24 class BasicBlock;
25 class Value;
26 class ConstantInt;
27 class AllocaInst;
28 }
29 
30 namespace clang {
31 class FunctionDecl;
32 namespace CodeGen {
33 class CodeGenModule;
34 class CodeGenFunction;
35 
36 /// The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the
37 /// type of a catch handler, so we use this wrapper.
38 struct CatchTypeInfo {
39  llvm::Constant *RTTI;
40  unsigned Flags;
41 };
42 
43 /// A protected scope for zero-cost EH handling.
44 class EHScope {
45  llvm::BasicBlock *CachedLandingPad;
46  llvm::BasicBlock *CachedEHDispatchBlock;
47 
48  EHScopeStack::stable_iterator EnclosingEHScope;
49 
50  class CommonBitFields {
51  friend class EHScope;
52  unsigned Kind : 3;
53  };
54  enum { NumCommonBits = 3 };
55 
56 protected:
58  friend class EHCatchScope;
59  unsigned : NumCommonBits;
60 
61  unsigned NumHandlers : 32 - NumCommonBits;
62  };
63 
65  friend class EHCleanupScope;
66  unsigned : NumCommonBits;
67 
68  /// Whether this cleanup needs to be run along normal edges.
69  unsigned IsNormalCleanup : 1;
70 
71  /// Whether this cleanup needs to be run along exception edges.
72  unsigned IsEHCleanup : 1;
73 
74  /// Whether this cleanup is currently active.
75  unsigned IsActive : 1;
76 
77  /// Whether this cleanup is a lifetime marker
78  unsigned IsLifetimeMarker : 1;
79 
80  /// Whether the normal cleanup should test the activation flag.
81  unsigned TestFlagInNormalCleanup : 1;
82 
83  /// Whether the EH cleanup should test the activation flag.
84  unsigned TestFlagInEHCleanup : 1;
85 
86  /// The amount of extra storage needed by the Cleanup.
87  /// Always a multiple of the scope-stack alignment.
88  unsigned CleanupSize : 12;
89  };
90 
92  friend class EHFilterScope;
93  unsigned : NumCommonBits;
94 
95  unsigned NumFilters : 32 - NumCommonBits;
96  };
97 
98  union {
99  CommonBitFields CommonBits;
103  };
104 
105 public:
106  enum Kind { Cleanup, Catch, Terminate, Filter, PadEnd };
107 
109  : CachedLandingPad(nullptr), CachedEHDispatchBlock(nullptr),
110  EnclosingEHScope(enclosingEHScope) {
111  CommonBits.Kind = kind;
112  }
113 
114  Kind getKind() const { return static_cast<Kind>(CommonBits.Kind); }
115 
116  llvm::BasicBlock *getCachedLandingPad() const {
117  return CachedLandingPad;
118  }
119 
120  void setCachedLandingPad(llvm::BasicBlock *block) {
121  CachedLandingPad = block;
122  }
123 
124  llvm::BasicBlock *getCachedEHDispatchBlock() const {
125  return CachedEHDispatchBlock;
126  }
127 
128  void setCachedEHDispatchBlock(llvm::BasicBlock *block) {
129  CachedEHDispatchBlock = block;
130  }
131 
132  bool hasEHBranches() const {
133  if (llvm::BasicBlock *block = getCachedEHDispatchBlock())
134  return !block->use_empty();
135  return false;
136  }
137 
139  return EnclosingEHScope;
140  }
141 };
142 
143 /// A scope which attempts to handle some, possibly all, types of
144 /// exceptions.
145 ///
146 /// Objective C \@finally blocks are represented using a cleanup scope
147 /// after the catch scope.
148 class EHCatchScope : public EHScope {
149  // In effect, we have a flexible array member
150  // Handler Handlers[0];
151  // But that's only standard in C99, not C++, so we have to do
152  // annoying pointer arithmetic instead.
153 
154 public:
155  struct Handler {
156  /// A type info value, or null (C++ null, not an LLVM null pointer)
157  /// for a catch-all.
159 
160  /// The catch handler for this type.
161  llvm::BasicBlock *Block;
162 
163  bool isCatchAll() const { return Type.RTTI == nullptr; }
164  };
165 
166 private:
167  friend class EHScopeStack;
168 
169  Handler *getHandlers() {
170  return reinterpret_cast<Handler*>(this+1);
171  }
172 
173  const Handler *getHandlers() const {
174  return reinterpret_cast<const Handler*>(this+1);
175  }
176 
177 public:
178  static size_t getSizeForNumHandlers(unsigned N) {
179  return sizeof(EHCatchScope) + N * sizeof(Handler);
180  }
181 
182  EHCatchScope(unsigned numHandlers,
183  EHScopeStack::stable_iterator enclosingEHScope)
184  : EHScope(Catch, enclosingEHScope) {
185  CatchBits.NumHandlers = numHandlers;
186  assert(CatchBits.NumHandlers == numHandlers && "NumHandlers overflow?");
187  }
188 
189  unsigned getNumHandlers() const {
190  return CatchBits.NumHandlers;
191  }
192 
193  void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block) {
194  setHandler(I, CatchTypeInfo{nullptr, 0}, Block);
195  }
196 
197  void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block) {
198  assert(I < getNumHandlers());
199  getHandlers()[I].Type = CatchTypeInfo{Type, 0};
200  getHandlers()[I].Block = Block;
201  }
202 
203  void setHandler(unsigned I, CatchTypeInfo Type, llvm::BasicBlock *Block) {
204  assert(I < getNumHandlers());
205  getHandlers()[I].Type = Type;
206  getHandlers()[I].Block = Block;
207  }
208 
209  const Handler &getHandler(unsigned I) const {
210  assert(I < getNumHandlers());
211  return getHandlers()[I];
212  }
213 
214  // Clear all handler blocks.
215  // FIXME: it's better to always call clearHandlerBlocks in DTOR and have a
216  // 'takeHandler' or some such function which removes ownership from the
217  // EHCatchScope object if the handlers should live longer than EHCatchScope.
219  for (unsigned I = 0, N = getNumHandlers(); I != N; ++I)
220  delete getHandler(I).Block;
221  }
222 
223  typedef const Handler *iterator;
224  iterator begin() const { return getHandlers(); }
225  iterator end() const { return getHandlers() + getNumHandlers(); }
226 
227  static bool classof(const EHScope *Scope) {
228  return Scope->getKind() == Catch;
229  }
230 };
231 
232 /// A cleanup scope which generates the cleanup blocks lazily.
233 class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) EHCleanupScope : public EHScope {
234  /// The nearest normal cleanup scope enclosing this one.
235  EHScopeStack::stable_iterator EnclosingNormal;
236 
237  /// The nearest EH scope enclosing this one.
238  EHScopeStack::stable_iterator EnclosingEH;
239 
240  /// The dual entry/exit block along the normal edge. This is lazily
241  /// created if needed before the cleanup is popped.
242  llvm::BasicBlock *NormalBlock;
243 
244  /// An optional i1 variable indicating whether this cleanup has been
245  /// activated yet.
246  llvm::AllocaInst *ActiveFlag;
247 
248  /// Extra information required for cleanups that have resolved
249  /// branches through them. This has to be allocated on the side
250  /// because everything on the cleanup stack has be trivially
251  /// movable.
252  struct ExtInfo {
253  /// The destinations of normal branch-afters and branch-throughs.
254  llvm::SmallPtrSet<llvm::BasicBlock*, 4> Branches;
255 
256  /// Normal branch-afters.
258  BranchAfters;
259  };
260  mutable struct ExtInfo *ExtInfo;
261 
262  /// The number of fixups required by enclosing scopes (not including
263  /// this one). If this is the top cleanup scope, all the fixups
264  /// from this index onwards belong to this scope.
265  unsigned FixupDepth;
266 
267  struct ExtInfo &getExtInfo() {
268  if (!ExtInfo) ExtInfo = new struct ExtInfo();
269  return *ExtInfo;
270  }
271 
272  const struct ExtInfo &getExtInfo() const {
273  if (!ExtInfo) ExtInfo = new struct ExtInfo();
274  return *ExtInfo;
275  }
276 
277 public:
278  /// Gets the size required for a lazy cleanup scope with the given
279  /// cleanup-data requirements.
280  static size_t getSizeForCleanupSize(size_t Size) {
281  return sizeof(EHCleanupScope) + Size;
282  }
283 
284  size_t getAllocatedSize() const {
285  return sizeof(EHCleanupScope) + CleanupBits.CleanupSize;
286  }
287 
288  EHCleanupScope(bool isNormal, bool isEH, bool isActive,
289  unsigned cleanupSize, unsigned fixupDepth,
290  EHScopeStack::stable_iterator enclosingNormal,
291  EHScopeStack::stable_iterator enclosingEH)
292  : EHScope(EHScope::Cleanup, enclosingEH),
293  EnclosingNormal(enclosingNormal), NormalBlock(nullptr),
294  ActiveFlag(nullptr), ExtInfo(nullptr), FixupDepth(fixupDepth) {
295  CleanupBits.IsNormalCleanup = isNormal;
296  CleanupBits.IsEHCleanup = isEH;
297  CleanupBits.IsActive = isActive;
298  CleanupBits.IsLifetimeMarker = false;
299  CleanupBits.TestFlagInNormalCleanup = false;
300  CleanupBits.TestFlagInEHCleanup = false;
301  CleanupBits.CleanupSize = cleanupSize;
302 
303  assert(CleanupBits.CleanupSize == cleanupSize && "cleanup size overflow");
304  }
305 
306  void Destroy() {
307  delete ExtInfo;
308  }
309  // Objects of EHCleanupScope are not destructed. Use Destroy().
310  ~EHCleanupScope() = delete;
311 
312  bool isNormalCleanup() const { return CleanupBits.IsNormalCleanup; }
313  llvm::BasicBlock *getNormalBlock() const { return NormalBlock; }
314  void setNormalBlock(llvm::BasicBlock *BB) { NormalBlock = BB; }
315 
316  bool isEHCleanup() const { return CleanupBits.IsEHCleanup; }
317 
318  bool isActive() const { return CleanupBits.IsActive; }
319  void setActive(bool A) { CleanupBits.IsActive = A; }
320 
321  bool isLifetimeMarker() const { return CleanupBits.IsLifetimeMarker; }
322  void setLifetimeMarker() { CleanupBits.IsLifetimeMarker = true; }
323 
324  bool hasActiveFlag() const { return ActiveFlag != nullptr; }
326  return Address(ActiveFlag, CharUnits::One());
327  }
328  void setActiveFlag(Address Var) {
329  assert(Var.getAlignment().isOne());
330  ActiveFlag = cast<llvm::AllocaInst>(Var.getPointer());
331  }
332 
334  CleanupBits.TestFlagInNormalCleanup = true;
335  }
337  return CleanupBits.TestFlagInNormalCleanup;
338  }
339 
341  CleanupBits.TestFlagInEHCleanup = true;
342  }
344  return CleanupBits.TestFlagInEHCleanup;
345  }
346 
347  unsigned getFixupDepth() const { return FixupDepth; }
349  return EnclosingNormal;
350  }
351 
352  size_t getCleanupSize() const { return CleanupBits.CleanupSize; }
353  void *getCleanupBuffer() { return this + 1; }
354 
356  return reinterpret_cast<EHScopeStack::Cleanup*>(getCleanupBuffer());
357  }
358 
359  /// True if this cleanup scope has any branch-afters or branch-throughs.
360  bool hasBranches() const { return ExtInfo && !ExtInfo->Branches.empty(); }
361 
362  /// Add a branch-after to this cleanup scope. A branch-after is a
363  /// branch from a point protected by this (normal) cleanup to a
364  /// point in the normal cleanup scope immediately containing it.
365  /// For example,
366  /// for (;;) { A a; break; }
367  /// contains a branch-after.
368  ///
369  /// Branch-afters each have their own destination out of the
370  /// cleanup, guaranteed distinct from anything else threaded through
371  /// it. Therefore branch-afters usually force a switch after the
372  /// cleanup.
373  void addBranchAfter(llvm::ConstantInt *Index,
374  llvm::BasicBlock *Block) {
375  struct ExtInfo &ExtInfo = getExtInfo();
376  if (ExtInfo.Branches.insert(Block).second)
377  ExtInfo.BranchAfters.push_back(std::make_pair(Block, Index));
378  }
379 
380  /// Return the number of unique branch-afters on this scope.
381  unsigned getNumBranchAfters() const {
382  return ExtInfo ? ExtInfo->BranchAfters.size() : 0;
383  }
384 
385  llvm::BasicBlock *getBranchAfterBlock(unsigned I) const {
386  assert(I < getNumBranchAfters());
387  return ExtInfo->BranchAfters[I].first;
388  }
389 
390  llvm::ConstantInt *getBranchAfterIndex(unsigned I) const {
391  assert(I < getNumBranchAfters());
392  return ExtInfo->BranchAfters[I].second;
393  }
394 
395  /// Add a branch-through to this cleanup scope. A branch-through is
396  /// a branch from a scope protected by this (normal) cleanup to an
397  /// enclosing scope other than the immediately-enclosing normal
398  /// cleanup scope.
399  ///
400  /// In the following example, the branch through B's scope is a
401  /// branch-through, while the branch through A's scope is a
402  /// branch-after:
403  /// for (;;) { A a; B b; break; }
404  ///
405  /// All branch-throughs have a common destination out of the
406  /// cleanup, one possibly shared with the fall-through. Therefore
407  /// branch-throughs usually don't force a switch after the cleanup.
408  ///
409  /// \return true if the branch-through was new to this scope
410  bool addBranchThrough(llvm::BasicBlock *Block) {
411  return getExtInfo().Branches.insert(Block).second;
412  }
413 
414  /// Determines if this cleanup scope has any branch throughs.
415  bool hasBranchThroughs() const {
416  if (!ExtInfo) return false;
417  return (ExtInfo->BranchAfters.size() != ExtInfo->Branches.size());
418  }
419 
420  static bool classof(const EHScope *Scope) {
421  return (Scope->getKind() == Cleanup);
422  }
423 };
424 // NOTE: there's a bunch of different data classes tacked on after an
425 // EHCleanupScope. It is asserted (in EHScopeStack::pushCleanup*) that
426 // they don't require greater alignment than ScopeStackAlignment. So,
427 // EHCleanupScope ought to have alignment equal to that -- not more
428 // (would be misaligned by the stack allocator), and not less (would
429 // break the appended classes).
430 static_assert(alignof(EHCleanupScope) == EHScopeStack::ScopeStackAlignment,
431  "EHCleanupScope expected alignment");
432 
433 /// An exceptions scope which filters exceptions thrown through it.
434 /// Only exceptions matching the filter types will be permitted to be
435 /// thrown.
436 ///
437 /// This is used to implement C++ exception specifications.
438 class EHFilterScope : public EHScope {
439  // Essentially ends in a flexible array member:
440  // llvm::Value *FilterTypes[0];
441 
442  llvm::Value **getFilters() {
443  return reinterpret_cast<llvm::Value**>(this+1);
444  }
445 
446  llvm::Value * const *getFilters() const {
447  return reinterpret_cast<llvm::Value* const *>(this+1);
448  }
449 
450 public:
451  EHFilterScope(unsigned numFilters)
452  : EHScope(Filter, EHScopeStack::stable_end()) {
453  FilterBits.NumFilters = numFilters;
454  assert(FilterBits.NumFilters == numFilters && "NumFilters overflow");
455  }
456 
457  static size_t getSizeForNumFilters(unsigned numFilters) {
458  return sizeof(EHFilterScope) + numFilters * sizeof(llvm::Value*);
459  }
460 
461  unsigned getNumFilters() const { return FilterBits.NumFilters; }
462 
463  void setFilter(unsigned i, llvm::Value *filterValue) {
464  assert(i < getNumFilters());
465  getFilters()[i] = filterValue;
466  }
467 
468  llvm::Value *getFilter(unsigned i) const {
469  assert(i < getNumFilters());
470  return getFilters()[i];
471  }
472 
473  static bool classof(const EHScope *scope) {
474  return scope->getKind() == Filter;
475  }
476 };
477 
478 /// An exceptions scope which calls std::terminate if any exception
479 /// reaches it.
480 class EHTerminateScope : public EHScope {
481 public:
483  : EHScope(Terminate, enclosingEHScope) {}
484  static size_t getSize() { return sizeof(EHTerminateScope); }
485 
486  static bool classof(const EHScope *scope) {
487  return scope->getKind() == Terminate;
488  }
489 };
490 
491 class EHPadEndScope : public EHScope {
492 public:
494  : EHScope(PadEnd, enclosingEHScope) {}
495  static size_t getSize() { return sizeof(EHPadEndScope); }
496 
497  static bool classof(const EHScope *scope) {
498  return scope->getKind() == PadEnd;
499  }
500 };
501 
502 /// A non-stable pointer into the scope stack.
504  char *Ptr;
505 
506  friend class EHScopeStack;
507  explicit iterator(char *Ptr) : Ptr(Ptr) {}
508 
509 public:
510  iterator() : Ptr(nullptr) {}
511 
512  EHScope *get() const {
513  return reinterpret_cast<EHScope*>(Ptr);
514  }
515 
516  EHScope *operator->() const { return get(); }
517  EHScope &operator*() const { return *get(); }
518 
520  size_t Size;
521  switch (get()->getKind()) {
522  case EHScope::Catch:
523  Size = EHCatchScope::getSizeForNumHandlers(
524  static_cast<const EHCatchScope *>(get())->getNumHandlers());
525  break;
526 
527  case EHScope::Filter:
528  Size = EHFilterScope::getSizeForNumFilters(
529  static_cast<const EHFilterScope *>(get())->getNumFilters());
530  break;
531 
532  case EHScope::Cleanup:
533  Size = static_cast<const EHCleanupScope *>(get())->getAllocatedSize();
534  break;
535 
536  case EHScope::Terminate:
537  Size = EHTerminateScope::getSize();
538  break;
539 
540  case EHScope::PadEnd:
541  Size = EHPadEndScope::getSize();
542  break;
543  }
544  Ptr += llvm::alignTo(Size, ScopeStackAlignment);
545  return *this;
546  }
547 
549  iterator copy = *this;
550  ++copy;
551  return copy;
552  }
553 
555  iterator copy = *this;
556  operator++();
557  return copy;
558  }
559 
560  bool encloses(iterator other) const { return Ptr >= other.Ptr; }
561  bool strictlyEncloses(iterator other) const { return Ptr > other.Ptr; }
562 
563  bool operator==(iterator other) const { return Ptr == other.Ptr; }
564  bool operator!=(iterator other) const { return Ptr != other.Ptr; }
565 };
566 
567 inline EHScopeStack::iterator EHScopeStack::begin() const {
568  return iterator(StartOfData);
569 }
570 
571 inline EHScopeStack::iterator EHScopeStack::end() const {
572  return iterator(EndOfBuffer);
573 }
574 
575 inline void EHScopeStack::popCatch() {
576  assert(!empty() && "popping exception stack when not empty");
577 
578  EHCatchScope &scope = cast<EHCatchScope>(*begin());
579  InnermostEHScope = scope.getEnclosingEHScope();
580  deallocate(EHCatchScope::getSizeForNumHandlers(scope.getNumHandlers()));
581 }
582 
583 inline void EHScopeStack::popTerminate() {
584  assert(!empty() && "popping exception stack when not empty");
585 
586  EHTerminateScope &scope = cast<EHTerminateScope>(*begin());
587  InnermostEHScope = scope.getEnclosingEHScope();
588  deallocate(EHTerminateScope::getSize());
589 }
590 
591 inline EHScopeStack::iterator EHScopeStack::find(stable_iterator sp) const {
592  assert(sp.isValid() && "finding invalid savepoint");
593  assert(sp.Size <= stable_begin().Size && "finding savepoint after pop");
594  return iterator(EndOfBuffer - sp.Size);
595 }
596 
598 EHScopeStack::stabilize(iterator ir) const {
599  assert(StartOfData <= ir.Ptr && ir.Ptr <= EndOfBuffer);
600  return stable_iterator(EndOfBuffer - ir.Ptr);
601 }
602 
603 /// The exceptions personality for a function.
605  const char *PersonalityFn;
606 
607  // If this is non-null, this personality requires a non-standard
608  // function for rethrowing an exception after a catchall cleanup.
609  // This function must have prototype void(void*).
610  const char *CatchallRethrowFn;
611 
612  static const EHPersonality &get(CodeGenModule &CGM, const FunctionDecl *FD);
613  static const EHPersonality &get(CodeGenFunction &CGF);
614 
615  static const EHPersonality GNU_C;
616  static const EHPersonality GNU_C_SJLJ;
617  static const EHPersonality GNU_C_SEH;
618  static const EHPersonality GNU_ObjC;
622  static const EHPersonality GNU_ObjCXX;
623  static const EHPersonality NeXT_ObjC;
630 
631  /// Does this personality use landingpads or the family of pad instructions
632  /// designed to form funclets?
633  bool usesFuncletPads() const { return isMSVCPersonality(); }
634 
635  bool isMSVCPersonality() const {
636  return this == &MSVC_except_handler || this == &MSVC_C_specific_handler ||
637  this == &MSVC_CxxFrameHandler3;
638  }
639 
640  bool isMSVCXXPersonality() const { return this == &MSVC_CxxFrameHandler3; }
641 };
642 }
643 }
644 
645 #endif
CatchBitFields CatchBits
Definition: CGCleanup.h:100
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Definition: Decl.h:1631
EHScopeStack::stable_iterator getEnclosingEHScope() const
Definition: CGCleanup.h:138
void setCatchAllHandler(unsigned I, llvm::BasicBlock *Block)
Definition: CGCleanup.h:193
bool usesFuncletPads() const
Does this personality use landingpads or the family of pad instructions designed to form funclets...
Definition: CGCleanup.h:633
bool strictlyEncloses(iterator other) const
Definition: CGCleanup.h:561
llvm::BasicBlock * getCachedEHDispatchBlock() const
Definition: CGCleanup.h:124
static const EHPersonality GNU_C_SJLJ
Definition: CGCleanup.h:616
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:26
static const EHPersonality MSVC_C_specific_handler
Definition: CGCleanup.h:628
static const EHPersonality MSVC_CxxFrameHandler3
Definition: CGCleanup.h:629
bool hasEHBranches() const
Definition: CGCleanup.h:132
static const EHPersonality GNU_C
Definition: CGCleanup.h:615
EHCatchScope(unsigned numHandlers, EHScopeStack::stable_iterator enclosingEHScope)
Definition: CGCleanup.h:182
The base class of the type hierarchy.
Definition: Type.h:1300
llvm::BasicBlock * getNormalBlock() const
Definition: CGCleanup.h:313
unsigned getNumFilters() const
Definition: CGCleanup.h:461
bool operator==(iterator other) const
Definition: CGCleanup.h:563
unsigned getNumHandlers() const
Definition: CGCleanup.h:189
llvm::Value * getPointer() const
Definition: Address.h:38
A protected scope for zero-cost EH handling.
Definition: CGCleanup.h:44
A scope which attempts to handle some, possibly all, types of exceptions.
Definition: CGCleanup.h:148
bool addBranchThrough(llvm::BasicBlock *Block)
Add a branch-through to this cleanup scope.
Definition: CGCleanup.h:410
bool operator!=(iterator other) const
Definition: CGCleanup.h:564
static size_t getSizeForCleanupSize(size_t Size)
Gets the size required for a lazy cleanup scope with the given cleanup-data requirements.
Definition: CGCleanup.h:280
An exceptions scope which calls std::terminate if any exception reaches it.
Definition: CGCleanup.h:480
bool isMSVCPersonality() const
Definition: CGCleanup.h:635
const char * CatchallRethrowFn
Definition: CGCleanup.h:610
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
static const EHPersonality GNU_CPlusPlus_SJLJ
Definition: CGCleanup.h:625
iterator end() const
Definition: CGCleanup.h:225
bool shouldTestFlagInNormalCleanup() const
Definition: CGCleanup.h:336
void setFilter(unsigned i, llvm::Value *filterValue)
Definition: CGCleanup.h:463
void setCachedLandingPad(llvm::BasicBlock *block)
Definition: CGCleanup.h:120
void setNormalBlock(llvm::BasicBlock *BB)
Definition: CGCleanup.h:314
bool isOne() const
isOne - Test whether the quantity equals one.
Definition: CharUnits.h:119
iterator begin() const
Definition: CGCleanup.h:224
CharUnits getAlignment() const
Return the alignment of this pointer.
Definition: Address.h:67
static bool classof(const EHScope *scope)
Definition: CGCleanup.h:473
const Handler & getHandler(unsigned I) const
Definition: CGCleanup.h:209
static const EHPersonality GNUstep_ObjC
Definition: CGCleanup.h:621
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:39
A stack of scopes which respond to exceptions, including cleanups and catch blocks.
Definition: EHScopeStack.h:100
EHScope(Kind kind, EHScopeStack::stable_iterator enclosingEHScope)
Definition: CGCleanup.h:108
static size_t getSizeForNumHandlers(unsigned N)
Definition: CGCleanup.h:178
EHFilterScope(unsigned numFilters)
Definition: CGCleanup.h:451
static bool classof(const EHScope *Scope)
Definition: CGCleanup.h:420
unsigned getFixupDepth() const
Definition: CGCleanup.h:347
unsigned getNumBranchAfters() const
Return the number of unique branch-afters on this scope.
Definition: CGCleanup.h:381
static const EHPersonality MSVC_except_handler
Definition: CGCleanup.h:627
EHScopeStack::Cleanup * getCleanup()
Definition: CGCleanup.h:355
CatchTypeInfo Type
A type info value, or null (C++ null, not an LLVM null pointer) for a catch-all.
Definition: CGCleanup.h:158
size_t getCleanupSize() const
Definition: CGCleanup.h:352
static bool classof(const EHScope *Scope)
Definition: CGCleanup.h:227
llvm::BasicBlock * Block
The catch handler for this type.
Definition: CGCleanup.h:161
llvm::ConstantInt * getBranchAfterIndex(unsigned I) const
Definition: CGCleanup.h:390
static const EHPersonality GNU_ObjCXX
Definition: CGCleanup.h:622
static const EHPersonality GNU_ObjC_SEH
Definition: CGCleanup.h:620
void setActiveFlag(Address Var)
Definition: CGCleanup.h:328
CommonBitFields CommonBits
Definition: CGCleanup.h:99
size_t getAllocatedSize() const
Definition: CGCleanup.h:284
llvm::BasicBlock * getCachedLandingPad() const
Definition: CGCleanup.h:116
Kind
CleanupBitFields CleanupBits
Definition: CGCleanup.h:101
A saved depth on the scope stack.
Definition: EHScopeStack.h:107
EHScopeStack::stable_iterator getEnclosingNormalCleanup() const
Definition: CGCleanup.h:348
EHPadEndScope(EHScopeStack::stable_iterator enclosingEHScope)
Definition: CGCleanup.h:493
An aligned address.
Definition: Address.h:25
const Handler * iterator
Definition: CGCleanup.h:223
void setCachedEHDispatchBlock(llvm::BasicBlock *block)
Definition: CGCleanup.h:128
llvm::Value * getFilter(unsigned i) const
Definition: CGCleanup.h:468
The MS C++ ABI needs a pointer to RTTI data plus some flags to describe the type of a catch handler...
Definition: CGCleanup.h:38
static size_t getSizeForNumFilters(unsigned numFilters)
Definition: CGCleanup.h:457
static const EHPersonality NeXT_ObjC
Definition: CGCleanup.h:623
Kind getKind() const
Definition: CGCleanup.h:114
This class organizes the cross-function state that is used while generating LLVM code.
Dataflow Directional Tag Classes.
EHTerminateScope(EHScopeStack::stable_iterator enclosingEHScope)
Definition: CGCleanup.h:482
static const EHPersonality GNU_CPlusPlus_SEH
Definition: CGCleanup.h:626
bool shouldTestFlagInEHCleanup() const
Definition: CGCleanup.h:343
void addBranchAfter(llvm::ConstantInt *Index, llvm::BasicBlock *Block)
Add a branch-after to this cleanup scope.
Definition: CGCleanup.h:373
static const EHPersonality GNU_ObjC
Definition: CGCleanup.h:618
static bool classof(const EHScope *scope)
Definition: CGCleanup.h:497
bool isMSVCXXPersonality() const
Definition: CGCleanup.h:640
static const EHPersonality GNU_CPlusPlus
Definition: CGCleanup.h:624
static const EHPersonality GNU_ObjC_SJLJ
Definition: CGCleanup.h:619
bool hasBranches() const
True if this cleanup scope has any branch-afters or branch-throughs.
Definition: CGCleanup.h:360
Address getActiveFlag() const
Definition: CGCleanup.h:325
bool encloses(iterator other) const
Definition: CGCleanup.h:560
static const EHPersonality GNU_C_SEH
Definition: CGCleanup.h:617
The exceptions personality for a function.
Definition: CGCleanup.h:604
llvm::Constant * RTTI
Definition: CGCleanup.h:39
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:61
llvm::BasicBlock * getBranchAfterBlock(unsigned I) const
Definition: CGCleanup.h:385
A cleanup scope which generates the cleanup blocks lazily.
Definition: CGCleanup.h:233
bool hasBranchThroughs() const
Determines if this cleanup scope has any branch throughs.
Definition: CGCleanup.h:415
EHCleanupScope(bool isNormal, bool isEH, bool isActive, unsigned cleanupSize, unsigned fixupDepth, EHScopeStack::stable_iterator enclosingNormal, EHScopeStack::stable_iterator enclosingEH)
Definition: CGCleanup.h:288
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:896
An exceptions scope which filters exceptions thrown through it.
Definition: CGCleanup.h:438
Information for lazily generating a cleanup.
Definition: EHScopeStack.h:147
A non-stable pointer into the scope stack.
Definition: CGCleanup.h:503
void setHandler(unsigned I, CatchTypeInfo Type, llvm::BasicBlock *Block)
Definition: CGCleanup.h:203
void setHandler(unsigned I, llvm::Constant *Type, llvm::BasicBlock *Block)
Definition: CGCleanup.h:197
FilterBitFields FilterBits
Definition: CGCleanup.h:102
static bool classof(const EHScope *scope)
Definition: CGCleanup.h:486