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