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