MCObjectStreamer.cpp revision 59ff3c913449402ad5447bbe3ae6338402fb84b0
1//===- 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
12#include "llvm/Support/ErrorHandling.h"
13#include "llvm/MC/MCAssembler.h"
14#include "llvm/MC/MCCodeEmitter.h"
15#include "llvm/MC/MCExpr.h"
16#include "llvm/Target/TargetAsmBackend.h"
17using namespace llvm;
18
19MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
20                                   raw_ostream &_OS, MCCodeEmitter *_Emitter,
21                                   bool _PadSectionToAlignment)
22  : MCStreamer(Context), Assembler(new MCAssembler(Context, TAB,
23                                                   *_Emitter,
24                                                   _PadSectionToAlignment,
25                                                   _OS)),
26    CurSectionData(0)
27{
28}
29
30MCObjectStreamer::~MCObjectStreamer() {
31  delete &Assembler->getBackend();
32  delete &Assembler->getEmitter();
33  delete Assembler;
34}
35
36MCFragment *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
77void MCObjectStreamer::SwitchSection(const MCSection *Section) {
78  assert(Section && "Cannot switch to a null section!");
79
80  // If already in this section, then this is a noop.
81  if (Section == CurSection) return;
82
83  PrevSection = CurSection;
84  CurSection = Section;
85  CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
86}
87
88void MCObjectStreamer::Finish() {
89  getAssembler().Finish();
90}
91