1 //===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_MC_MCOBJECTSTREAMER_H
11 #define LLVM_MC_MCOBJECTSTREAMER_H
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/MC/MCAssembler.h"
15 #include "llvm/MC/MCStreamer.h"
21 class MCSubtargetInfo
;
28 /// \brief Streaming object file generation interface.
30 /// This class provides an implementation of the MCStreamer interface which is
31 /// suitable for use with the assembler backend. Specific object file formats
32 /// are expected to subclass this interface to implement directives specific
33 /// to that file format or custom semantics expected by the object writer
35 class MCObjectStreamer
: public MCStreamer
{
36 MCAssembler
*Assembler
;
37 MCSectionData
*CurSectionData
;
38 MCSectionData::iterator CurInsertionPoint
;
41 SmallVector
<MCSymbolData
*, 2> PendingLabels
;
43 virtual void EmitInstToData(const MCInst
&Inst
, const MCSubtargetInfo
&) = 0;
44 void EmitCFIStartProcImpl(MCDwarfFrameInfo
&Frame
) override
;
45 void EmitCFIEndProcImpl(MCDwarfFrameInfo
&Frame
) override
;
47 // If any labels have been emitted but not assigned fragments, ensure that
48 // they get assigned, either to F if possible or to a new data fragment.
49 void flushPendingLabels(MCFragment
*F
);
52 MCObjectStreamer(MCContext
&Context
, MCAsmBackend
&TAB
, raw_ostream
&_OS
,
53 MCCodeEmitter
*_Emitter
);
54 MCObjectStreamer(MCContext
&Context
, MCAsmBackend
&TAB
, raw_ostream
&_OS
,
55 MCCodeEmitter
*_Emitter
, MCAssembler
*_Assembler
);
60 void reset() override
;
62 /// Object streamers require the integrated assembler.
63 bool isIntegratedAssemblerRequired() const override
{ return true; }
65 MCSymbolData
&getOrCreateSymbolData(const MCSymbol
*Symbol
) {
66 return getAssembler().getOrCreateSymbolData(*Symbol
);
68 void EmitFrames(MCAsmBackend
*MAB
);
69 void EmitCFISections(bool EH
, bool Debug
) override
;
72 MCSectionData
*getCurrentSectionData() const {
73 return CurSectionData
;
76 MCFragment
*getCurrentFragment() const;
78 void insert(MCFragment
*F
) {
79 flushPendingLabels(F
);
80 CurSectionData
->getFragmentList().insert(CurInsertionPoint
, F
);
81 F
->setParent(CurSectionData
);
84 /// Get a data fragment to write into, creating a new one if the current
85 /// fragment is not a data fragment.
86 MCDataFragment
*getOrCreateDataFragment();
89 void visitUsedSymbol(const MCSymbol
&Sym
) override
;
91 MCAssembler
&getAssembler() { return *Assembler
; }
93 /// @name MCStreamer Interface
96 void EmitLabel(MCSymbol
*Symbol
) override
;
97 void EmitAssignment(MCSymbol
*Symbol
, const MCExpr
*Value
) override
;
98 void EmitValueImpl(const MCExpr
*Value
, unsigned Size
,
99 const SMLoc
&Loc
= SMLoc()) override
;
100 void EmitULEB128Value(const MCExpr
*Value
) override
;
101 void EmitSLEB128Value(const MCExpr
*Value
) override
;
102 void EmitWeakReference(MCSymbol
*Alias
, const MCSymbol
*Symbol
) override
;
103 void ChangeSection(const MCSection
*Section
,
104 const MCExpr
*Subsection
) override
;
105 void EmitInstruction(const MCInst
&Inst
, const MCSubtargetInfo
& STI
) override
;
107 /// \brief Emit an instruction to a special fragment, because this instruction
108 /// can change its size during relaxation.
109 virtual void EmitInstToFragment(const MCInst
&Inst
, const MCSubtargetInfo
&);
111 void EmitBundleAlignMode(unsigned AlignPow2
) override
;
112 void EmitBundleLock(bool AlignToEnd
) override
;
113 void EmitBundleUnlock() override
;
114 void EmitBytes(StringRef Data
) override
;
115 void EmitValueToAlignment(unsigned ByteAlignment
, int64_t Value
= 0,
116 unsigned ValueSize
= 1,
117 unsigned MaxBytesToEmit
= 0) override
;
118 void EmitCodeAlignment(unsigned ByteAlignment
,
119 unsigned MaxBytesToEmit
= 0) override
;
120 bool EmitValueToOffset(const MCExpr
*Offset
, unsigned char Value
) override
;
121 void EmitDwarfLocDirective(unsigned FileNo
, unsigned Line
,
122 unsigned Column
, unsigned Flags
,
123 unsigned Isa
, unsigned Discriminator
,
124 StringRef FileName
) override
;
125 void EmitDwarfAdvanceLineAddr(int64_t LineDelta
, const MCSymbol
*LastLabel
,
126 const MCSymbol
*Label
,
127 unsigned PointerSize
);
128 void EmitDwarfAdvanceFrameAddr(const MCSymbol
*LastLabel
,
129 const MCSymbol
*Label
);
130 void EmitGPRel32Value(const MCExpr
*Value
) override
;
131 void EmitGPRel64Value(const MCExpr
*Value
) override
;
132 void EmitFill(uint64_t NumBytes
, uint8_t FillValue
) override
;
133 void EmitZeros(uint64_t NumBytes
) override
;
134 void FinishImpl() override
;
136 bool mayHaveInstructions() const override
{
137 return getCurrentSectionData()->hasInstructions();
141 } // end namespace llvm