blob: 3883f12152210208cd94f6c142aced5d0915f6de [file] [log] [blame]
Daniel Dunbar8dc68ab2010-06-16 20:04:22 +00001//===- lib/MC/MCObjectStreamer.cpp - Object File MCStreamer Interface -----===//
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#include "llvm/MC/MCObjectStreamer.h"
11
Michael J. Spencer8067adc2010-07-19 06:13:10 +000012#include "llvm/Support/ErrorHandling.h"
Daniel Dunbar8dc68ab2010-06-16 20:04:22 +000013#include "llvm/MC/MCAssembler.h"
Benjamin Kramer1abcd062010-07-29 17:48:06 +000014#include "llvm/MC/MCCodeEmitter.h"
Michael J. Spencer8067adc2010-07-19 06:13:10 +000015#include "llvm/MC/MCExpr.h"
Benjamin Kramer1abcd062010-07-29 17:48:06 +000016#include "llvm/Target/TargetAsmBackend.h"
Daniel Dunbar8dc68ab2010-06-16 20:04:22 +000017using namespace llvm;
18
19MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
Rafael Espindola59ff3c92010-09-22 22:27:05 +000020 raw_ostream &_OS, MCCodeEmitter *_Emitter,
21 bool _PadSectionToAlignment)
Daniel Dunbar83b46712010-06-16 20:04:25 +000022 : MCStreamer(Context), Assembler(new MCAssembler(Context, TAB,
Rafael Espindola59ff3c92010-09-22 22:27:05 +000023 *_Emitter,
24 _PadSectionToAlignment,
25 _OS)),
Daniel Dunbar83b46712010-06-16 20:04:25 +000026 CurSectionData(0)
Daniel Dunbar8dc68ab2010-06-16 20:04:22 +000027{
28}
29
30MCObjectStreamer::~MCObjectStreamer() {
Benjamin Kramer1abcd062010-07-29 17:48:06 +000031 delete &Assembler->getBackend();
32 delete &Assembler->getEmitter();
Daniel Dunbar8dc68ab2010-06-16 20:04:22 +000033 delete Assembler;
34}
Daniel Dunbar83b46712010-06-16 20:04:25 +000035
Michael J. Spencer8067adc2010-07-19 06:13:10 +000036MCFragment *MCObjectStreamer::getCurrentFragment() const {
37 assert(getCurrentSectionData() && "No current section!");
38
39 if (!getCurrentSectionData()->empty())
40 return &getCurrentSectionData()->getFragmentList().back();
41
42 return 0;
43}
44
45MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
46 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
47 if (!F)
48 F = new MCDataFragment(getCurrentSectionData());
49 return F;
50}
51
52const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
53 switch (Value->getKind()) {
54 case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!");
55 case MCExpr::Constant:
56 break;
57
58 case MCExpr::Binary: {
59 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
60 AddValueSymbols(BE->getLHS());
61 AddValueSymbols(BE->getRHS());
62 break;
63 }
64
65 case MCExpr::SymbolRef:
66 Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
67 break;
68
69 case MCExpr::Unary:
70 AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
71 break;
72 }
73
74 return Value;
75}
76
Rafael Espindola484291c2010-11-01 14:28:48 +000077void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias,
78 const MCSymbol *Symbol) {
79 report_fatal_error("This file format doesn't support weak aliases.");
80}
81
Daniel Dunbar83b46712010-06-16 20:04:25 +000082void MCObjectStreamer::SwitchSection(const MCSection *Section) {
83 assert(Section && "Cannot switch to a null section!");
84
85 // If already in this section, then this is a noop.
86 if (Section == CurSection) return;
87
Benjamin Kramer1674b0b2010-09-02 18:53:37 +000088 PrevSection = CurSection;
Daniel Dunbar83b46712010-06-16 20:04:25 +000089 CurSection = Section;
90 CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
91}
92
93void MCObjectStreamer::Finish() {
94 getAssembler().Finish();
95}