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