eliminate uses of cerr()
[oota-llvm.git] / lib / MC / MCMachOStreamer.cpp
1 //===- lib/MC/MCMachOStreamer.cpp - Mach-O Object Output ------------===//
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/MCStreamer.h"
11
12 #include "llvm/MC/MCAssembler.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCSection.h"
15 #include "llvm/MC/MCSymbol.h"
16 #include "llvm/Support/ErrorHandling.h"
17 using namespace llvm;
18
19 namespace {
20
21 class MCMachOStreamer : public MCStreamer {
22   MCAssembler Assembler;
23
24   MCSectionData *CurSectionData;
25
26   DenseMap<const MCSection*, MCSectionData*> SectionMap;
27   
28   DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
29
30 private:
31   MCFragment *getCurrentFragment() const {
32     assert(CurSectionData && "No current section!");
33
34     if (!CurSectionData->empty())
35       return &CurSectionData->getFragmentList().back();
36
37     return 0;
38   }
39
40   MCSymbolData &getSymbolData(MCSymbol &Symbol) {
41     MCSymbolData *&Entry = SymbolMap[&Symbol];
42
43     if (!Entry)
44       Entry = new MCSymbolData(Symbol, 0, 0, &Assembler);
45
46     return *Entry;
47   }
48
49 public:
50   MCMachOStreamer(MCContext &Context, raw_ostream &_OS)
51     : MCStreamer(Context), Assembler(_OS), CurSectionData(0) {}
52   ~MCMachOStreamer() {}
53
54   /// @name MCStreamer Interface
55   /// @{
56
57   virtual void SwitchSection(const MCSection *Section);
58
59   virtual void EmitLabel(MCSymbol *Symbol);
60
61   virtual void EmitAssemblerFlag(AssemblerFlag Flag);
62
63   virtual void EmitAssignment(MCSymbol *Symbol, const MCValue &Value,
64                               bool MakeAbsolute = false);
65
66   virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute);
67
68   virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
69
70   virtual void EmitLocalSymbol(MCSymbol *Symbol, const MCValue &Value);
71
72   virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
73                                 unsigned Pow2Alignment, bool IsLocal);
74
75   virtual void EmitZerofill(MCSection *Section, MCSymbol *Symbol = NULL,
76                             unsigned Size = 0, unsigned Pow2Alignment = 0);
77
78   virtual void EmitBytes(const StringRef &Data);
79
80   virtual void EmitValue(const MCValue &Value, unsigned Size);
81
82   virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
83                                     unsigned ValueSize = 1,
84                                     unsigned MaxBytesToEmit = 0);
85
86   virtual void EmitValueToOffset(const MCValue &Offset,
87                                  unsigned char Value = 0);
88
89   virtual void EmitInstruction(const MCInst &Inst);
90
91   virtual void Finish();
92
93   /// @}
94 };
95
96 } // end anonymous namespace.
97
98 void MCMachOStreamer::SwitchSection(const MCSection *Section) {
99   assert(Section && "Cannot switch to a null section!");
100   
101   // If already in this section, then this is a noop.
102   if (Section == CurSection) return;
103   
104   CurSection = Section;
105   MCSectionData *&Entry = SectionMap[Section];
106
107   if (!Entry)
108     Entry = new MCSectionData(*Section, &Assembler);
109
110   CurSectionData = Entry;
111 }
112
113 void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) {
114   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
115
116   MCDataFragment *F = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
117   if (!F)
118     F = new MCDataFragment(CurSectionData);
119
120   MCSymbolData &SD = getSymbolData(*Symbol);
121   assert(!SD.getFragment() && "Unexpected fragment on symbol data!");
122   SD.setFragment(F);
123   SD.setOffset(F->getContents().size());
124   
125   Symbol->setSection(*CurSection);
126 }
127
128 void MCMachOStreamer::EmitAssemblerFlag(AssemblerFlag Flag) {
129   llvm_unreachable("FIXME: Not yet implemented!");
130 }
131
132 void MCMachOStreamer::EmitAssignment(MCSymbol *Symbol,
133                                      const MCValue &Value,
134                                      bool MakeAbsolute) {
135   // Only absolute symbols can be redefined.
136   assert((Symbol->isUndefined() || Symbol->isAbsolute()) &&
137          "Cannot define a symbol twice!");
138
139   llvm_unreachable("FIXME: Not yet implemented!");
140 }
141
142 void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
143                                           SymbolAttr Attribute) {
144   switch (Attribute) {
145   default:
146     llvm_unreachable("FIXME: Not yet implemented!");
147
148   case MCStreamer::Global:
149     getSymbolData(*Symbol).setExternal(true);
150     break;
151   }
152 }
153
154 void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
155   llvm_unreachable("FIXME: Not yet implemented!");
156 }
157
158 void MCMachOStreamer::EmitLocalSymbol(MCSymbol *Symbol, const MCValue &Value) {
159   llvm_unreachable("FIXME: Not yet implemented!");
160 }
161
162 void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size,
163                                        unsigned Pow2Alignment,
164                                        bool IsLocal) {
165   llvm_unreachable("FIXME: Not yet implemented!");
166 }
167
168 void MCMachOStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
169                                    unsigned Size, unsigned Pow2Alignment) {
170   llvm_unreachable("FIXME: Not yet implemented!");
171 }
172
173 void MCMachOStreamer::EmitBytes(const StringRef &Data) {
174   MCDataFragment *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
175   if (!DF)
176     DF = new MCDataFragment(CurSectionData);
177   DF->getContents().append(Data.begin(), Data.end());
178 }
179
180 void MCMachOStreamer::EmitValue(const MCValue &Value, unsigned Size) {
181   new MCFillFragment(Value, Size, 1, CurSectionData);
182 }
183
184 void MCMachOStreamer::EmitValueToAlignment(unsigned ByteAlignment,
185                                            int64_t Value, unsigned ValueSize,
186                                            unsigned MaxBytesToEmit) {
187   if (MaxBytesToEmit == 0)
188     MaxBytesToEmit = ByteAlignment;
189   new MCAlignFragment(ByteAlignment, Value, ValueSize, MaxBytesToEmit,
190                       CurSectionData);
191
192   // Update the maximum alignment on the current section if necessary.
193   if (ByteAlignment > CurSectionData->getAlignment())
194     CurSectionData->setAlignment(ByteAlignment);
195 }
196
197 void MCMachOStreamer::EmitValueToOffset(const MCValue &Offset,
198                                         unsigned char Value) {
199   new MCOrgFragment(Offset, Value, CurSectionData);
200 }
201
202 void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
203   llvm_unreachable("FIXME: Not yet implemented!");
204 }
205
206 void MCMachOStreamer::Finish() {
207   Assembler.Finish();
208 }
209
210 MCStreamer *llvm::createMachOStreamer(MCContext &Context, raw_ostream &OS) {
211   return new MCMachOStreamer(Context, OS);
212 }