blob: 2b2385ef9156d8b89fb27f002f3630ec8c3f91e1 [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,
20 raw_ostream &_OS, MCCodeEmitter *_Emitter)
Daniel Dunbar83b46712010-06-16 20:04:25 +000021 : MCStreamer(Context), Assembler(new MCAssembler(Context, TAB,
22 *_Emitter, _OS)),
23 CurSectionData(0)
Daniel Dunbar8dc68ab2010-06-16 20:04:22 +000024{
25}
26
27MCObjectStreamer::~MCObjectStreamer() {
Benjamin Kramer1abcd062010-07-29 17:48:06 +000028 delete &Assembler->getBackend();
29 delete &Assembler->getEmitter();
Daniel Dunbar8dc68ab2010-06-16 20:04:22 +000030 delete Assembler;
31}
Daniel Dunbar83b46712010-06-16 20:04:25 +000032
Michael J. Spencer8067adc2010-07-19 06:13:10 +000033MCFragment *MCObjectStreamer::getCurrentFragment() const {
34 assert(getCurrentSectionData() && "No current section!");
35
36 if (!getCurrentSectionData()->empty())
37 return &getCurrentSectionData()->getFragmentList().back();
38
39 return 0;
40}
41
42MCDataFragment *MCObjectStreamer::getOrCreateDataFragment() const {
43 MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
44 if (!F)
45 F = new MCDataFragment(getCurrentSectionData());
46 return F;
47}
48
49const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
50 switch (Value->getKind()) {
51 case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!");
52 case MCExpr::Constant:
53 break;
54
55 case MCExpr::Binary: {
56 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Value);
57 AddValueSymbols(BE->getLHS());
58 AddValueSymbols(BE->getRHS());
59 break;
60 }
61
62 case MCExpr::SymbolRef:
63 Assembler->getOrCreateSymbolData(cast<MCSymbolRefExpr>(Value)->getSymbol());
64 break;
65
66 case MCExpr::Unary:
67 AddValueSymbols(cast<MCUnaryExpr>(Value)->getSubExpr());
68 break;
69 }
70
71 return Value;
72}
73
Daniel Dunbar83b46712010-06-16 20:04:25 +000074void MCObjectStreamer::SwitchSection(const MCSection *Section) {
75 assert(Section && "Cannot switch to a null section!");
76
77 // If already in this section, then this is a noop.
78 if (Section == CurSection) return;
79
Benjamin Kramer1674b0b2010-09-02 18:53:37 +000080 PrevSection = CurSection;
Daniel Dunbar83b46712010-06-16 20:04:25 +000081 CurSection = Section;
82 CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
83}
84
85void MCObjectStreamer::Finish() {
86 getAssembler().Finish();
87}