1 //===- EHPersonalities.h - Compute EH-related information -----------------===//
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 #ifndef LLVM_ANALYSIS_EHPERSONALITIES_H
10 #define LLVM_ANALYSIS_EHPERSONALITIES_H
11 
12 #include "llvm/ADT/DenseMap.h"
13 #include "llvm/ADT/TinyPtrVector.h"
14 #include "llvm/Support/ErrorHandling.h"
15 
16 namespace llvm {
17 class BasicBlock;
18 class Function;
19 class Triple;
20 class Value;
21 
22 enum class EHPersonality {
23   Unknown,
24   GNU_Ada,
25   GNU_C,
26   GNU_C_SjLj,
27   GNU_CXX,
28   GNU_CXX_SjLj,
29   GNU_ObjC,
30   MSVC_X86SEH,
31   MSVC_TableSEH,
32   MSVC_CXX,
33   CoreCLR,
34   Rust,
35   Wasm_CXX,
36   XL_CXX
37 };
38 
39 /// See if the given exception handling personality function is one
40 /// that we understand.  If so, return a description of it; otherwise return
41 /// Unknown.
42 EHPersonality classifyEHPersonality(const Value *Pers);
43 
44 StringRef getEHPersonalityName(EHPersonality Pers);
45 
46 EHPersonality getDefaultEHPersonality(const Triple &T);
47 
48 /// Returns true if this personality function catches asynchronous
49 /// exceptions.
isAsynchronousEHPersonality(EHPersonality Pers)50 inline bool isAsynchronousEHPersonality(EHPersonality Pers) {
51   // The two SEH personality functions can catch asynch exceptions. We assume
52   // unknown personalities don't catch asynch exceptions.
53   switch (Pers) {
54   case EHPersonality::MSVC_X86SEH:
55   case EHPersonality::MSVC_TableSEH:
56     return true;
57   default:
58     return false;
59   }
60   llvm_unreachable("invalid enum");
61 }
62 
63 /// Returns true if this is a personality function that invokes
64 /// handler funclets (which must return to it).
isFuncletEHPersonality(EHPersonality Pers)65 inline bool isFuncletEHPersonality(EHPersonality Pers) {
66   switch (Pers) {
67   case EHPersonality::MSVC_CXX:
68   case EHPersonality::MSVC_X86SEH:
69   case EHPersonality::MSVC_TableSEH:
70   case EHPersonality::CoreCLR:
71     return true;
72   default:
73     return false;
74   }
75   llvm_unreachable("invalid enum");
76 }
77 
78 /// Returns true if this personality uses scope-style EH IR instructions:
79 /// catchswitch, catchpad/ret, and cleanuppad/ret.
isScopedEHPersonality(EHPersonality Pers)80 inline bool isScopedEHPersonality(EHPersonality Pers) {
81   switch (Pers) {
82   case EHPersonality::MSVC_CXX:
83   case EHPersonality::MSVC_X86SEH:
84   case EHPersonality::MSVC_TableSEH:
85   case EHPersonality::CoreCLR:
86   case EHPersonality::Wasm_CXX:
87     return true;
88   default:
89     return false;
90   }
91   llvm_unreachable("invalid enum");
92 }
93 
94 /// Return true if this personality may be safely removed if there
95 /// are no invoke instructions remaining in the current function.
isNoOpWithoutInvoke(EHPersonality Pers)96 inline bool isNoOpWithoutInvoke(EHPersonality Pers) {
97   switch (Pers) {
98   case EHPersonality::Unknown:
99     return false;
100   // All known personalities currently have this behavior
101   default:
102     return true;
103   }
104   llvm_unreachable("invalid enum");
105 }
106 
107 bool canSimplifyInvokeNoUnwind(const Function *F);
108 
109 typedef TinyPtrVector<BasicBlock *> ColorVector;
110 
111 /// If an EH funclet personality is in use (see isFuncletEHPersonality),
112 /// this will recompute which blocks are in which funclet. It is possible that
113 /// some blocks are in multiple funclets. Consider this analysis to be
114 /// expensive.
115 DenseMap<BasicBlock *, ColorVector> colorEHFunclets(Function &F);
116 
117 } // end namespace llvm
118 
119 #endif
120