1 //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains support for writing DWARF exception info into asm files.
11 //===----------------------------------------------------------------------===//
13 #include "DwarfException.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/CodeGen/AsmPrinter.h"
16 #include "llvm/CodeGen/MachineFunction.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCStreamer.h"
22 ARMException::ARMException(AsmPrinter
*A
) : DwarfCFIExceptionBase(A
) {}
24 ARMException::~ARMException() = default;
26 ARMTargetStreamer
&ARMException::getTargetStreamer() {
27 MCTargetStreamer
&TS
= *Asm
->OutStreamer
->getTargetStreamer();
28 return static_cast<ARMTargetStreamer
&>(TS
);
31 void ARMException::beginFunction(const MachineFunction
*MF
) {
32 if (Asm
->MAI
->getExceptionHandlingType() == ExceptionHandling::ARM
)
33 getTargetStreamer().emitFnStart();
34 // See if we need call frame info.
35 AsmPrinter::CFISection CFISecType
= Asm
->getFunctionCFISectionType(*MF
);
36 assert(CFISecType
!= AsmPrinter::CFISection::EH
&&
37 "non-EH CFI not yet supported in prologue with EHABI lowering");
39 if (CFISecType
== AsmPrinter::CFISection::Debug
) {
40 if (!hasEmittedCFISections
) {
41 if (Asm
->getModuleCFISectionType() == AsmPrinter::CFISection::Debug
)
42 Asm
->OutStreamer
->emitCFISections(false, true);
43 hasEmittedCFISections
= true;
47 Asm
->OutStreamer
->emitCFIStartProc(false);
51 /// endFunction - Gather and emit post-function exception information.
53 void ARMException::endFunction(const MachineFunction
*MF
) {
54 ARMTargetStreamer
&ATS
= getTargetStreamer();
55 const Function
&F
= MF
->getFunction();
56 const Function
*Per
= nullptr;
57 if (F
.hasPersonalityFn())
58 Per
= dyn_cast
<Function
>(F
.getPersonalityFn()->stripPointerCasts());
59 bool forceEmitPersonality
=
60 F
.hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per
)) &&
61 F
.needsUnwindTableEntry();
62 bool shouldEmitPersonality
= forceEmitPersonality
||
63 !MF
->getLandingPads().empty();
64 if (!Asm
->MF
->getFunction().needsUnwindTableEntry() &&
65 !shouldEmitPersonality
)
67 else if (shouldEmitPersonality
) {
68 // Emit references to personality.
70 MCSymbol
*PerSym
= Asm
->getSymbol(Per
);
71 ATS
.emitPersonality(PerSym
);
74 // Emit .handlerdata directive.
75 ATS
.emitHandlerData();
77 // Emit actual exception table
81 if (Asm
->MAI
->getExceptionHandlingType() == ExceptionHandling::ARM
)
85 void ARMException::emitTypeInfos(unsigned TTypeEncoding
,
86 MCSymbol
*TTBaseLabel
) {
87 const MachineFunction
*MF
= Asm
->MF
;
88 const std::vector
<const GlobalValue
*> &TypeInfos
= MF
->getTypeInfos();
89 const std::vector
<unsigned> &FilterIds
= MF
->getFilterIds();
91 bool VerboseAsm
= Asm
->OutStreamer
->isVerboseAsm();
94 // Emit the Catch TypeInfos.
95 if (VerboseAsm
&& !TypeInfos
.empty()) {
96 Asm
->OutStreamer
->AddComment(">> Catch TypeInfos <<");
97 Asm
->OutStreamer
->addBlankLine();
98 Entry
= TypeInfos
.size();
101 for (const GlobalValue
*GV
: reverse(TypeInfos
)) {
103 Asm
->OutStreamer
->AddComment("TypeInfo " + Twine(Entry
--));
104 Asm
->emitTTypeReference(GV
, TTypeEncoding
);
107 Asm
->OutStreamer
->emitLabel(TTBaseLabel
);
109 // Emit the Exception Specifications.
110 if (VerboseAsm
&& !FilterIds
.empty()) {
111 Asm
->OutStreamer
->AddComment(">> Filter TypeInfos <<");
112 Asm
->OutStreamer
->addBlankLine();
115 for (std::vector
<unsigned>::const_iterator
116 I
= FilterIds
.begin(), E
= FilterIds
.end(); I
< E
; ++I
) {
117 unsigned TypeID
= *I
;
121 Asm
->OutStreamer
->AddComment("FilterInfo " + Twine(Entry
));
124 Asm
->emitTTypeReference((TypeID
== 0 ? nullptr : TypeInfos
[TypeID
- 1]),