1 //===- EHPersonalities.h - Compute EH-related information -----------------===//
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 #ifndef LLVM_ANALYSIS_EHPERSONALITIES_H
11 #define LLVM_ANALYSIS_EHPERSONALITIES_H
12 
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/TinyPtrVector.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_CXX,
27   GNU_ObjC,
28   MSVC_X86SEH,
29   MSVC_Win64SEH,
30   MSVC_CXX,
31   CoreCLR
32 };
33 
34 /// \brief See if the given exception handling personality function is one
35 /// that we understand.  If so, return a description of it; otherwise return
36 /// Unknown.
37 EHPersonality classifyEHPersonality(const Value *Pers);
38 
39 /// \brief Returns true if this personality function catches asynchronous
40 /// exceptions.
isAsynchronousEHPersonality(EHPersonality Pers)41 inline bool isAsynchronousEHPersonality(EHPersonality Pers) {
42   // The two SEH personality functions can catch asynch exceptions. We assume
43   // unknown personalities don't catch asynch exceptions.
44   switch (Pers) {
45   case EHPersonality::MSVC_X86SEH:
46   case EHPersonality::MSVC_Win64SEH:
47     return true;
48   default:
49     return false;
50   }
51   llvm_unreachable("invalid enum");
52 }
53 
54 /// \brief Returns true if this is a personality function that invokes
55 /// handler funclets (which must return to it).
isFuncletEHPersonality(EHPersonality Pers)56 inline bool isFuncletEHPersonality(EHPersonality Pers) {
57   switch (Pers) {
58   case EHPersonality::MSVC_CXX:
59   case EHPersonality::MSVC_X86SEH:
60   case EHPersonality::MSVC_Win64SEH:
61   case EHPersonality::CoreCLR:
62     return true;
63   default:
64     return false;
65   }
66   llvm_unreachable("invalid enum");
67 }
68 
69 /// \brief Return true if this personality may be safely removed if there
70 /// are no invoke instructions remaining in the current function.
isNoOpWithoutInvoke(EHPersonality Pers)71 inline bool isNoOpWithoutInvoke(EHPersonality Pers) {
72   switch (Pers) {
73   case EHPersonality::Unknown:
74     return false;
75   // All known personalities currently have this behavior
76   default:
77     return true;
78   }
79   llvm_unreachable("invalid enum");
80 }
81 
82 bool canSimplifyInvokeNoUnwind(const Function *F);
83 
84 typedef TinyPtrVector<BasicBlock *> ColorVector;
85 
86 /// \brief If an EH funclet personality is in use (see isFuncletEHPersonality),
87 /// this will recompute which blocks are in which funclet. It is possible that
88 /// some blocks are in multiple funclets. Consider this analysis to be
89 /// expensive.
90 DenseMap<BasicBlock *, ColorVector> colorEHFunclets(Function &F);
91 
92 } // end namespace llvm
93 
94 #endif
95