MC: Move MCAlignFragment::EmitNops value out of the constructor.
[oota-llvm.git] / include / llvm / MC / MCAssembler.h
1 //===- MCAssembler.h - Object File Generation -------------------*- C++ -*-===//
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 #ifndef LLVM_MC_MCASSEMBLER_H
11 #define LLVM_MC_MCASSEMBLER_H
12
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/SmallString.h"
15 #include "llvm/ADT/ilist.h"
16 #include "llvm/ADT/ilist_node.h"
17 #include "llvm/Support/Casting.h"
18 #include "llvm/MC/MCFixup.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/System/DataTypes.h"
21 #include <vector> // FIXME: Shouldn't be needed.
22
23 namespace llvm {
24 class raw_ostream;
25 class MCAsmLayout;
26 class MCAssembler;
27 class MCContext;
28 class MCCodeEmitter;
29 class MCExpr;
30 class MCFragment;
31 class MCObjectWriter;
32 class MCSection;
33 class MCSectionData;
34 class MCSymbol;
35 class MCSymbolData;
36 class MCValue;
37 class TargetAsmBackend;
38
39 /// MCAsmFixup - Represent a fixed size region of bytes inside some fragment
40 /// which needs to be rewritten. This region will either be rewritten by the
41 /// assembler or cause a relocation entry to be generated.
42 //
43 // FIXME: This should probably just be merged with MCFixup.
44 class MCAsmFixup {
45 public:
46   /// Offset - The offset inside the fragment which needs to be rewritten.
47   uint64_t Offset;
48
49   /// Value - The expression to eventually write into the fragment.
50   const MCExpr *Value;
51
52   /// Kind - The fixup kind.
53   MCFixupKind Kind;
54
55 public:
56   MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind)
57     : Offset(_Offset), Value(&_Value), Kind(_Kind) {}
58 };
59
60 class MCFragment : public ilist_node<MCFragment> {
61   friend class MCAsmLayout;
62
63   MCFragment(const MCFragment&);     // DO NOT IMPLEMENT
64   void operator=(const MCFragment&); // DO NOT IMPLEMENT
65
66 public:
67   enum FragmentType {
68     FT_Align,
69     FT_Data,
70     FT_Fill,
71     FT_Inst,
72     FT_Org
73   };
74
75 private:
76   FragmentType Kind;
77
78   /// Parent - The data for the section this fragment is in.
79   MCSectionData *Parent;
80
81   /// Atom - The atom this fragment is in, as represented by it's defining
82   /// symbol. Atom's are only used by backends which set
83   /// \see MCAsmBackend::hasReliableSymbolDifference().
84   MCSymbolData *Atom;
85
86   /// @name Assembler Backend Data
87   /// @{
88   //
89   // FIXME: This could all be kept private to the assembler implementation.
90
91   /// Offset - The offset of this fragment in its section. This is ~0 until
92   /// initialized.
93   uint64_t Offset;
94
95   /// EffectiveSize - The compute size of this section. This is ~0 until
96   /// initialized.
97   uint64_t EffectiveSize;
98
99   /// Ordinal - The global index of this fragment. This is the index across all
100   /// sections, not just the parent section.
101   unsigned Ordinal;
102
103   /// @}
104
105 protected:
106   MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
107
108 public:
109   // Only for sentinel.
110   MCFragment();
111   virtual ~MCFragment();
112
113   FragmentType getKind() const { return Kind; }
114
115   MCSectionData *getParent() const { return Parent; }
116   void setParent(MCSectionData *Value) { Parent = Value; }
117
118   MCSymbolData *getAtom() const { return Atom; }
119   void setAtom(MCSymbolData *Value) { Atom = Value; }
120
121   unsigned getOrdinal() const { return Ordinal; }
122   void setOrdinal(unsigned Value) { Ordinal = Value; }
123
124   static bool classof(const MCFragment *O) { return true; }
125
126   virtual void dump();
127 };
128
129 class MCDataFragment : public MCFragment {
130   SmallString<32> Contents;
131
132   /// Fixups - The list of fixups in this fragment.
133   std::vector<MCAsmFixup> Fixups;
134
135 public:
136   typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator;
137   typedef std::vector<MCAsmFixup>::iterator fixup_iterator;
138
139 public:
140   MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
141
142   /// @name Accessors
143   /// @{
144
145   SmallString<32> &getContents() { return Contents; }
146   const SmallString<32> &getContents() const { return Contents; }
147
148   /// @}
149   /// @name Fixup Access
150   /// @{
151
152   void addFixup(MCAsmFixup Fixup) {
153     // Enforce invariant that fixups are in offset order.
154     assert((Fixups.empty() || Fixup.Offset > Fixups.back().Offset) &&
155            "Fixups must be added in order!");
156     Fixups.push_back(Fixup);
157   }
158
159   std::vector<MCAsmFixup> &getFixups() { return Fixups; }
160   const std::vector<MCAsmFixup> &getFixups() const { return Fixups; }
161
162   fixup_iterator fixup_begin() { return Fixups.begin(); }
163   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
164
165   fixup_iterator fixup_end() {return Fixups.end();}
166   const_fixup_iterator fixup_end() const {return Fixups.end();}
167
168   size_t fixup_size() const { return Fixups.size(); }
169
170   /// @}
171
172   static bool classof(const MCFragment *F) {
173     return F->getKind() == MCFragment::FT_Data;
174   }
175   static bool classof(const MCDataFragment *) { return true; }
176
177   virtual void dump();
178 };
179
180 // FIXME: This current incarnation of MCInstFragment doesn't make much sense, as
181 // it is almost entirely a duplicate of MCDataFragment. If we decide to stick
182 // with this approach (as opposed to making MCInstFragment a very light weight
183 // object with just the MCInst and a code size, then we should just change
184 // MCDataFragment to have an optional MCInst at its end.
185 class MCInstFragment : public MCFragment {
186   /// Inst - The instruction this is a fragment for.
187   MCInst Inst;
188
189   /// InstSize - The size of the currently encoded instruction.
190   SmallString<8> Code;
191
192   /// Fixups - The list of fixups in this fragment.
193   SmallVector<MCAsmFixup, 1> Fixups;
194
195 public:
196   typedef SmallVectorImpl<MCAsmFixup>::const_iterator const_fixup_iterator;
197   typedef SmallVectorImpl<MCAsmFixup>::iterator fixup_iterator;
198
199 public:
200   MCInstFragment(MCInst _Inst, MCSectionData *SD = 0)
201     : MCFragment(FT_Inst, SD), Inst(_Inst) {
202   }
203
204   /// @name Accessors
205   /// @{
206
207   SmallVectorImpl<char> &getCode() { return Code; }
208   const SmallVectorImpl<char> &getCode() const { return Code; }
209
210   unsigned getInstSize() const { return Code.size(); }
211
212   MCInst &getInst() { return Inst; }
213   const MCInst &getInst() const { return Inst; }
214
215   void setInst(MCInst Value) { Inst = Value; }
216
217   /// @}
218   /// @name Fixup Access
219   /// @{
220
221   SmallVectorImpl<MCAsmFixup> &getFixups() { return Fixups; }
222   const SmallVectorImpl<MCAsmFixup> &getFixups() const { return Fixups; }
223
224   fixup_iterator fixup_begin() { return Fixups.begin(); }
225   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
226
227   fixup_iterator fixup_end() {return Fixups.end();}
228   const_fixup_iterator fixup_end() const {return Fixups.end();}
229
230   size_t fixup_size() const { return Fixups.size(); }
231
232   /// @}
233
234   static bool classof(const MCFragment *F) {
235     return F->getKind() == MCFragment::FT_Inst;
236   }
237   static bool classof(const MCInstFragment *) { return true; }
238
239   virtual void dump();
240 };
241
242 class MCAlignFragment : public MCFragment {
243   /// Alignment - The alignment to ensure, in bytes.
244   unsigned Alignment;
245
246   /// Value - Value to use for filling padding bytes.
247   int64_t Value;
248
249   /// ValueSize - The size of the integer (in bytes) of \arg Value.
250   unsigned ValueSize;
251
252   /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
253   /// cannot be satisfied in this width then this fragment is ignored.
254   unsigned MaxBytesToEmit;
255
256   /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
257   /// of using the provided value. The exact interpretation of this flag is
258   /// target dependent.
259   bool EmitNops : 1;
260
261 public:
262   MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
263                   unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
264     : MCFragment(FT_Align, SD), Alignment(_Alignment),
265       Value(_Value),ValueSize(_ValueSize),
266       MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
267
268   /// @name Accessors
269   /// @{
270
271   unsigned getAlignment() const { return Alignment; }
272
273   int64_t getValue() const { return Value; }
274
275   unsigned getValueSize() const { return ValueSize; }
276
277   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
278
279   bool hasEmitNops() const { return EmitNops; }
280   void setEmitNops(bool Value) { EmitNops = Value; }
281
282   /// @}
283
284   static bool classof(const MCFragment *F) {
285     return F->getKind() == MCFragment::FT_Align;
286   }
287   static bool classof(const MCAlignFragment *) { return true; }
288
289   virtual void dump();
290 };
291
292 class MCFillFragment : public MCFragment {
293   /// Value - Value to use for filling bytes.
294   int64_t Value;
295
296   /// ValueSize - The size (in bytes) of \arg Value to use when filling, or 0 if
297   /// this is a virtual fill fragment.
298   unsigned ValueSize;
299
300   /// Size - The number of bytes to insert.
301   uint64_t Size;
302
303 public:
304   MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
305                  MCSectionData *SD = 0)
306     : MCFragment(FT_Fill, SD),
307       Value(_Value), ValueSize(_ValueSize), Size(_Size) {
308     assert((!ValueSize || (Size % ValueSize) == 0) &&
309            "Fill size must be a multiple of the value size!");
310   }
311
312   /// @name Accessors
313   /// @{
314
315   int64_t getValue() const { return Value; }
316
317   unsigned getValueSize() const { return ValueSize; }
318
319   uint64_t getSize() const { return Size; }
320
321   /// @}
322
323   static bool classof(const MCFragment *F) {
324     return F->getKind() == MCFragment::FT_Fill;
325   }
326   static bool classof(const MCFillFragment *) { return true; }
327
328   virtual void dump();
329 };
330
331 class MCOrgFragment : public MCFragment {
332   /// Offset - The offset this fragment should start at.
333   const MCExpr *Offset;
334
335   /// Value - Value to use for filling bytes.
336   int8_t Value;
337
338 public:
339   MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
340     : MCFragment(FT_Org, SD),
341       Offset(&_Offset), Value(_Value) {}
342
343   /// @name Accessors
344   /// @{
345
346   const MCExpr &getOffset() const { return *Offset; }
347
348   uint8_t getValue() const { return Value; }
349
350   /// @}
351
352   static bool classof(const MCFragment *F) {
353     return F->getKind() == MCFragment::FT_Org;
354   }
355   static bool classof(const MCOrgFragment *) { return true; }
356
357   virtual void dump();
358 };
359
360 // FIXME: Should this be a separate class, or just merged into MCSection? Since
361 // we anticipate the fast path being through an MCAssembler, the only reason to
362 // keep it out is for API abstraction.
363 class MCSectionData : public ilist_node<MCSectionData> {
364   friend class MCAsmLayout;
365
366   MCSectionData(const MCSectionData&);  // DO NOT IMPLEMENT
367   void operator=(const MCSectionData&); // DO NOT IMPLEMENT
368
369 public:
370   typedef iplist<MCFragment> FragmentListType;
371
372   typedef FragmentListType::const_iterator const_iterator;
373   typedef FragmentListType::iterator iterator;
374
375   typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
376   typedef FragmentListType::reverse_iterator reverse_iterator;
377
378 private:
379   iplist<MCFragment> Fragments;
380   const MCSection *Section;
381
382   /// Ordinal - The section index in the assemblers section list.
383   unsigned Ordinal;
384
385   /// Alignment - The maximum alignment seen in this section.
386   unsigned Alignment;
387
388   /// @name Assembler Backend Data
389   /// @{
390   //
391   // FIXME: This could all be kept private to the assembler implementation.
392
393   /// Address - The computed address of this section. This is ~0 until
394   /// initialized.
395   uint64_t Address;
396
397   /// Size - The content size of this section. This is ~0 until initialized.
398   uint64_t Size;
399
400   /// FileSize - The size of this section in the object file. This is ~0 until
401   /// initialized.
402   uint64_t FileSize;
403
404   /// HasInstructions - Whether this section has had instructions emitted into
405   /// it.
406   unsigned HasInstructions : 1;
407
408   /// @}
409
410 public:
411   // Only for use as sentinel.
412   MCSectionData();
413   MCSectionData(const MCSection &Section, MCAssembler *A = 0);
414
415   const MCSection &getSection() const { return *Section; }
416
417   unsigned getAlignment() const { return Alignment; }
418   void setAlignment(unsigned Value) { Alignment = Value; }
419
420   bool hasInstructions() const { return HasInstructions; }
421   void setHasInstructions(bool Value) { HasInstructions = Value; }
422
423   unsigned getOrdinal() const { return Ordinal; }
424   void setOrdinal(unsigned Value) { Ordinal = Value; }
425
426   /// @name Fragment Access
427   /// @{
428
429   const FragmentListType &getFragmentList() const { return Fragments; }
430   FragmentListType &getFragmentList() { return Fragments; }
431
432   iterator begin() { return Fragments.begin(); }
433   const_iterator begin() const { return Fragments.begin(); }
434
435   iterator end() { return Fragments.end(); }
436   const_iterator end() const { return Fragments.end(); }
437
438   reverse_iterator rbegin() { return Fragments.rbegin(); }
439   const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
440
441   reverse_iterator rend() { return Fragments.rend(); }
442   const_reverse_iterator rend() const { return Fragments.rend(); }
443
444   size_t size() const { return Fragments.size(); }
445
446   bool empty() const { return Fragments.empty(); }
447
448   void dump();
449
450   /// @}
451 };
452
453 // FIXME: Same concerns as with SectionData.
454 class MCSymbolData : public ilist_node<MCSymbolData> {
455 public:
456   const MCSymbol *Symbol;
457
458   /// Fragment - The fragment this symbol's value is relative to, if any.
459   MCFragment *Fragment;
460
461   /// Offset - The offset to apply to the fragment address to form this symbol's
462   /// value.
463   uint64_t Offset;
464
465   /// IsExternal - True if this symbol is visible outside this translation
466   /// unit.
467   unsigned IsExternal : 1;
468
469   /// IsPrivateExtern - True if this symbol is private extern.
470   unsigned IsPrivateExtern : 1;
471
472   /// CommonSize - The size of the symbol, if it is 'common', or 0.
473   //
474   // FIXME: Pack this in with other fields? We could put it in offset, since a
475   // common symbol can never get a definition.
476   uint64_t CommonSize;
477
478   /// CommonAlign - The alignment of the symbol, if it is 'common'.
479   //
480   // FIXME: Pack this in with other fields?
481   unsigned CommonAlign;
482
483   /// Flags - The Flags field is used by object file implementations to store
484   /// additional per symbol information which is not easily classified.
485   uint32_t Flags;
486
487   /// Index - Index field, for use by the object file implementation.
488   uint64_t Index;
489
490 public:
491   // Only for use as sentinel.
492   MCSymbolData();
493   MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
494                MCAssembler *A = 0);
495
496   /// @name Accessors
497   /// @{
498
499   const MCSymbol &getSymbol() const { return *Symbol; }
500
501   MCFragment *getFragment() const { return Fragment; }
502   void setFragment(MCFragment *Value) { Fragment = Value; }
503
504   uint64_t getOffset() const { return Offset; }
505   void setOffset(uint64_t Value) { Offset = Value; }
506
507   /// @}
508   /// @name Symbol Attributes
509   /// @{
510
511   bool isExternal() const { return IsExternal; }
512   void setExternal(bool Value) { IsExternal = Value; }
513
514   bool isPrivateExtern() const { return IsPrivateExtern; }
515   void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
516
517   /// isCommon - Is this a 'common' symbol.
518   bool isCommon() const { return CommonSize != 0; }
519
520   /// setCommon - Mark this symbol as being 'common'.
521   ///
522   /// \param Size - The size of the symbol.
523   /// \param Align - The alignment of the symbol.
524   void setCommon(uint64_t Size, unsigned Align) {
525     CommonSize = Size;
526     CommonAlign = Align;
527   }
528
529   /// getCommonSize - Return the size of a 'common' symbol.
530   uint64_t getCommonSize() const {
531     assert(isCommon() && "Not a 'common' symbol!");
532     return CommonSize;
533   }
534
535   /// getCommonAlignment - Return the alignment of a 'common' symbol.
536   unsigned getCommonAlignment() const {
537     assert(isCommon() && "Not a 'common' symbol!");
538     return CommonAlign;
539   }
540
541   /// getFlags - Get the (implementation defined) symbol flags.
542   uint32_t getFlags() const { return Flags; }
543
544   /// setFlags - Set the (implementation defined) symbol flags.
545   void setFlags(uint32_t Value) { Flags = Value; }
546
547   /// modifyFlags - Modify the flags via a mask
548   void modifyFlags(uint32_t Value, uint32_t Mask) {
549     Flags = (Flags & ~Mask) | Value;
550   }
551
552   /// getIndex - Get the (implementation defined) index.
553   uint64_t getIndex() const { return Index; }
554
555   /// setIndex - Set the (implementation defined) index.
556   void setIndex(uint64_t Value) { Index = Value; }
557
558   /// @}
559
560   void dump();
561 };
562
563 // FIXME: This really doesn't belong here. See comments below.
564 struct IndirectSymbolData {
565   MCSymbol *Symbol;
566   MCSectionData *SectionData;
567 };
568
569 class MCAssembler {
570   friend class MCAsmLayout;
571
572 public:
573   typedef iplist<MCSectionData> SectionDataListType;
574   typedef iplist<MCSymbolData> SymbolDataListType;
575
576   typedef SectionDataListType::const_iterator const_iterator;
577   typedef SectionDataListType::iterator iterator;
578
579   typedef SymbolDataListType::const_iterator const_symbol_iterator;
580   typedef SymbolDataListType::iterator symbol_iterator;
581
582   typedef std::vector<IndirectSymbolData>::const_iterator
583     const_indirect_symbol_iterator;
584   typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
585
586 private:
587   MCAssembler(const MCAssembler&);    // DO NOT IMPLEMENT
588   void operator=(const MCAssembler&); // DO NOT IMPLEMENT
589
590   MCContext &Context;
591
592   TargetAsmBackend &Backend;
593
594   MCCodeEmitter &Emitter;
595
596   raw_ostream &OS;
597
598   iplist<MCSectionData> Sections;
599
600   iplist<MCSymbolData> Symbols;
601
602   /// The map of sections to their associated assembler backend data.
603   //
604   // FIXME: Avoid this indirection?
605   DenseMap<const MCSection*, MCSectionData*> SectionMap;
606
607   /// The map of symbols to their associated assembler backend data.
608   //
609   // FIXME: Avoid this indirection?
610   DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
611
612   std::vector<IndirectSymbolData> IndirectSymbols;
613
614   unsigned RelaxAll : 1;
615   unsigned SubsectionsViaSymbols : 1;
616
617 private:
618   /// Evaluate a fixup to a relocatable expression and the value which should be
619   /// placed into the fixup.
620   ///
621   /// \param Layout The layout to use for evaluation.
622   /// \param Fixup The fixup to evaluate.
623   /// \param DF The fragment the fixup is inside.
624   /// \param Target [out] On return, the relocatable expression the fixup
625   /// evaluates to.
626   /// \param Value [out] On return, the value of the fixup as currently layed
627   /// out.
628   /// \return Whether the fixup value was fully resolved. This is true if the
629   /// \arg Value result is fixed, otherwise the value may change due to
630   /// relocation.
631   bool EvaluateFixup(const MCAsmLayout &Layout,
632                      const MCAsmFixup &Fixup, const MCFragment *DF,
633                      MCValue &Target, uint64_t &Value) const;
634
635   /// Check whether a fixup can be satisfied, or whether it needs to be relaxed
636   /// (increased in size, in order to hold its value correctly).
637   bool FixupNeedsRelaxation(const MCAsmFixup &Fixup, const MCFragment *DF,
638                             const MCAsmLayout &Layout) const;
639
640   /// Check whether the given fragment needs relaxation.
641   bool FragmentNeedsRelaxation(const MCInstFragment *IF,
642                                const MCAsmLayout &Layout) const;
643
644   /// LayoutFragment - Performs layout of the given \arg Fragment; assuming that
645   /// the previous fragment has already been layed out correctly, and the parent
646   /// section has been initialized.
647   void LayoutFragment(MCAsmLayout &Layout, MCFragment &Fragment);
648
649   /// LayoutSection - Performs layout of the section referenced by the given
650   /// \arg SectionOrderIndex. The layout assumes that the previous section has
651   /// already been layed out correctly.
652   void LayoutSection(MCAsmLayout &Layout, unsigned SectionOrderIndex);
653
654   /// LayoutOnce - Perform one layout iteration and return true if any offsets
655   /// were adjusted.
656   bool LayoutOnce(MCAsmLayout &Layout);
657
658   /// FinishLayout - Finalize a layout, including fragment lowering.
659   void FinishLayout(MCAsmLayout &Layout);
660
661 public:
662   /// Find the symbol which defines the atom containing the given symbol, or
663   /// null if there is no such symbol.
664   const MCSymbolData *getAtom(const MCAsmLayout &Layout,
665                               const MCSymbolData *Symbol) const;
666
667   /// Check whether a particular symbol is visible to the linker and is required
668   /// in the symbol table, or whether it can be discarded by the assembler. This
669   /// also effects whether the assembler treats the label as potentially
670   /// defining a separate atom.
671   bool isSymbolLinkerVisible(const MCSymbolData *SD) const;
672
673   /// Emit the section contents using the given object writer.
674   //
675   // FIXME: Should MCAssembler always have a reference to the object writer?
676   void WriteSectionData(const MCSectionData *Section, const MCAsmLayout &Layout,
677                         MCObjectWriter *OW) const;
678
679 public:
680   /// Construct a new assembler instance.
681   ///
682   /// \arg OS - The stream to output to.
683   //
684   // FIXME: How are we going to parameterize this? Two obvious options are stay
685   // concrete and require clients to pass in a target like object. The other
686   // option is to make this abstract, and have targets provide concrete
687   // implementations as we do with AsmParser.
688   MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend,
689               MCCodeEmitter &_Emitter, raw_ostream &OS);
690   ~MCAssembler();
691
692   MCContext &getContext() const { return Context; }
693
694   TargetAsmBackend &getBackend() const { return Backend; }
695
696   MCCodeEmitter &getEmitter() const { return Emitter; }
697
698   /// Finish - Do final processing and write the object to the output stream.
699   void Finish();
700
701   // FIXME: This does not belong here.
702   bool getSubsectionsViaSymbols() const {
703     return SubsectionsViaSymbols;
704   }
705   void setSubsectionsViaSymbols(bool Value) {
706     SubsectionsViaSymbols = Value;
707   }
708
709   bool getRelaxAll() const { return RelaxAll; }
710   void setRelaxAll(bool Value) { RelaxAll = Value; }
711
712   /// @name Section List Access
713   /// @{
714
715   const SectionDataListType &getSectionList() const { return Sections; }
716   SectionDataListType &getSectionList() { return Sections; }
717
718   iterator begin() { return Sections.begin(); }
719   const_iterator begin() const { return Sections.begin(); }
720
721   iterator end() { return Sections.end(); }
722   const_iterator end() const { return Sections.end(); }
723
724   size_t size() const { return Sections.size(); }
725
726   /// @}
727   /// @name Symbol List Access
728   /// @{
729
730   const SymbolDataListType &getSymbolList() const { return Symbols; }
731   SymbolDataListType &getSymbolList() { return Symbols; }
732
733   symbol_iterator symbol_begin() { return Symbols.begin(); }
734   const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
735
736   symbol_iterator symbol_end() { return Symbols.end(); }
737   const_symbol_iterator symbol_end() const { return Symbols.end(); }
738
739   size_t symbol_size() const { return Symbols.size(); }
740
741   /// @}
742   /// @name Indirect Symbol List Access
743   /// @{
744
745   // FIXME: This is a total hack, this should not be here. Once things are
746   // factored so that the streamer has direct access to the .o writer, it can
747   // disappear.
748   std::vector<IndirectSymbolData> &getIndirectSymbols() {
749     return IndirectSymbols;
750   }
751
752   indirect_symbol_iterator indirect_symbol_begin() {
753     return IndirectSymbols.begin();
754   }
755   const_indirect_symbol_iterator indirect_symbol_begin() const {
756     return IndirectSymbols.begin();
757   }
758
759   indirect_symbol_iterator indirect_symbol_end() {
760     return IndirectSymbols.end();
761   }
762   const_indirect_symbol_iterator indirect_symbol_end() const {
763     return IndirectSymbols.end();
764   }
765
766   size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
767
768   /// @}
769   /// @name Backend Data Access
770   /// @{
771
772   MCSectionData &getSectionData(const MCSection &Section) const {
773     MCSectionData *Entry = SectionMap.lookup(&Section);
774     assert(Entry && "Missing section data!");
775     return *Entry;
776   }
777
778   MCSectionData &getOrCreateSectionData(const MCSection &Section,
779                                         bool *Created = 0) {
780     MCSectionData *&Entry = SectionMap[&Section];
781
782     if (Created) *Created = !Entry;
783     if (!Entry)
784       Entry = new MCSectionData(Section, this);
785
786     return *Entry;
787   }
788
789   MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
790     MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
791     assert(Entry && "Missing symbol data!");
792     return *Entry;
793   }
794
795   MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
796                                       bool *Created = 0) {
797     MCSymbolData *&Entry = SymbolMap[&Symbol];
798
799     if (Created) *Created = !Entry;
800     if (!Entry)
801       Entry = new MCSymbolData(Symbol, 0, 0, this);
802
803     return *Entry;
804   }
805
806   /// @}
807
808   void dump();
809 };
810
811 } // end namespace llvm
812
813 #endif