LLVM API Documentation

ARMException.cpp
Go to the documentation of this file.
00001 //===-- CodeGen/AsmPrinter/ARMException.cpp - ARM EHABI Exception Impl ----===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains support for writing DWARF exception info into asm files.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "DwarfException.h"
00015 #include "llvm/ADT/SmallString.h"
00016 #include "llvm/ADT/StringExtras.h"
00017 #include "llvm/ADT/Twine.h"
00018 #include "llvm/CodeGen/AsmPrinter.h"
00019 #include "llvm/CodeGen/MachineFrameInfo.h"
00020 #include "llvm/CodeGen/MachineFunction.h"
00021 #include "llvm/CodeGen/MachineModuleInfo.h"
00022 #include "llvm/IR/DataLayout.h"
00023 #include "llvm/IR/Mangler.h"
00024 #include "llvm/IR/Module.h"
00025 #include "llvm/MC/MCAsmInfo.h"
00026 #include "llvm/MC/MCContext.h"
00027 #include "llvm/MC/MCExpr.h"
00028 #include "llvm/MC/MCSection.h"
00029 #include "llvm/MC/MCStreamer.h"
00030 #include "llvm/MC/MCSymbol.h"
00031 #include "llvm/Support/CommandLine.h"
00032 #include "llvm/Support/Dwarf.h"
00033 #include "llvm/Support/FormattedStream.h"
00034 #include "llvm/Target/TargetFrameLowering.h"
00035 #include "llvm/Target/TargetOptions.h"
00036 #include "llvm/Target/TargetRegisterInfo.h"
00037 using namespace llvm;
00038 
00039 ARMException::ARMException(AsmPrinter *A)
00040   : EHStreamer(A), shouldEmitCFI(false) {}
00041 
00042 ARMException::~ARMException() {}
00043 
00044 ARMTargetStreamer &ARMException::getTargetStreamer() {
00045   MCTargetStreamer &TS = *Asm->OutStreamer.getTargetStreamer();
00046   return static_cast<ARMTargetStreamer &>(TS);
00047 }
00048 
00049 /// endModule - Emit all exception information that should come after the
00050 /// content.
00051 void ARMException::endModule() {
00052   if (shouldEmitCFI)
00053     Asm->OutStreamer.EmitCFISections(false, true);
00054 }
00055 
00056 /// beginFunction - Gather pre-function exception information. Assumes it's
00057 /// being emitted immediately after the function entry point.
00058 void ARMException::beginFunction(const MachineFunction *MF) {
00059   if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
00060     getTargetStreamer().emitFnStart();
00061   Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
00062                                                 Asm->getFunctionNumber()));
00063   // See if we need call frame info.
00064   AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
00065   assert(MoveType != AsmPrinter::CFI_M_EH &&
00066          "non-EH CFI not yet supported in prologue with EHABI lowering");
00067   if (MoveType == AsmPrinter::CFI_M_Debug) {
00068     shouldEmitCFI = true;
00069     Asm->OutStreamer.EmitCFIStartProc(false);
00070   }
00071 }
00072 
00073 /// endFunction - Gather and emit post-function exception information.
00074 ///
00075 void ARMException::endFunction(const MachineFunction *) {
00076   if (shouldEmitCFI)
00077     Asm->OutStreamer.EmitCFIEndProc();
00078 
00079   // Map all labels and get rid of any dead landing pads.
00080   MMI->TidyLandingPads();
00081 
00082   ARMTargetStreamer &ATS = getTargetStreamer();
00083   if (!Asm->MF->getFunction()->needsUnwindTableEntry() &&
00084       MMI->getLandingPads().empty())
00085     ATS.emitCantUnwind();
00086   else {
00087     Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
00088                                                   Asm->getFunctionNumber()));
00089     if (!MMI->getLandingPads().empty()) {
00090       // Emit references to personality.
00091       if (const Function * Personality =
00092           MMI->getPersonalities()[MMI->getPersonalityIndex()]) {
00093         MCSymbol *PerSym = Asm->getSymbol(Personality);
00094         Asm->OutStreamer.EmitSymbolAttribute(PerSym, MCSA_Global);
00095         ATS.emitPersonality(PerSym);
00096       }
00097 
00098       // Emit .handlerdata directive.
00099       ATS.emitHandlerData();
00100 
00101       // Emit actual exception table
00102       emitExceptionTable();
00103     }
00104   }
00105 
00106   if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
00107     ATS.emitFnEnd();
00108 }
00109 
00110 void ARMException::emitTypeInfos(unsigned TTypeEncoding) {
00111   const std::vector<const GlobalVariable *> &TypeInfos = MMI->getTypeInfos();
00112   const std::vector<unsigned> &FilterIds = MMI->getFilterIds();
00113 
00114   bool VerboseAsm = Asm->OutStreamer.isVerboseAsm();
00115 
00116   int Entry = 0;
00117   // Emit the Catch TypeInfos.
00118   if (VerboseAsm && !TypeInfos.empty()) {
00119     Asm->OutStreamer.AddComment(">> Catch TypeInfos <<");
00120     Asm->OutStreamer.AddBlankLine();
00121     Entry = TypeInfos.size();
00122   }
00123 
00124   for (std::vector<const GlobalVariable *>::const_reverse_iterator
00125          I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) {
00126     const GlobalVariable *GV = *I;
00127     if (VerboseAsm)
00128       Asm->OutStreamer.AddComment("TypeInfo " + Twine(Entry--));
00129     Asm->EmitTTypeReference(GV, TTypeEncoding);
00130   }
00131 
00132   // Emit the Exception Specifications.
00133   if (VerboseAsm && !FilterIds.empty()) {
00134     Asm->OutStreamer.AddComment(">> Filter TypeInfos <<");
00135     Asm->OutStreamer.AddBlankLine();
00136     Entry = 0;
00137   }
00138   for (std::vector<unsigned>::const_iterator
00139          I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
00140     unsigned TypeID = *I;
00141     if (VerboseAsm) {
00142       --Entry;
00143       if (TypeID != 0)
00144         Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry));
00145     }
00146 
00147     Asm->EmitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]),
00148                             TTypeEncoding);
00149   }
00150 }