#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
MCSectionData *Parent;
/// Atom - The atom this fragment is in, as represented by it's defining
- /// symbol. Atom's are only used by backends which set
- /// \see MCAsmBackend::hasReliableSymbolDifference().
+ /// symbol.
MCSymbolData *Atom;
/// @name Assembler Backend Data
/// @}
protected:
- MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
+ MCFragment(FragmentType _Kind, MCSectionData *_Parent = nullptr);
public:
// Only for sentinel.
uint8_t BundlePadding;
public:
- MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
+ MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = nullptr)
: MCFragment(FType, SD), BundlePadding(0)
{
}
public:
MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
- MCSectionData *SD = 0)
+ MCSectionData *SD = nullptr)
: MCEncodedFragment(FType, SD)
{
}
/// Fixups - The list of fixups in this fragment.
SmallVector<MCFixup, 4> Fixups;
public:
- MCDataFragment(MCSectionData *SD = 0)
+ MCDataFragment(MCSectionData *SD = nullptr)
: MCEncodedFragmentWithFixups(FT_Data, SD),
HasInstructions(false), AlignToBundleEnd(false)
{
SmallVector<char, 4> Contents;
public:
- MCCompactEncodedInstFragment(MCSectionData *SD = 0)
+ MCCompactEncodedInstFragment(MCSectionData *SD = nullptr)
: MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false)
{
}
public:
MCRelaxableFragment(const MCInst &_Inst,
const MCSubtargetInfo &_STI,
- MCSectionData *SD = 0)
+ MCSectionData *SD = nullptr)
: MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) {
}
public:
MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
- unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
+ unsigned _MaxBytesToEmit, MCSectionData *SD = nullptr)
: MCFragment(FT_Align, SD), Alignment(_Alignment),
Value(_Value),ValueSize(_ValueSize),
MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
public:
MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
- MCSectionData *SD = 0)
+ MCSectionData *SD = nullptr)
: MCFragment(FT_Fill, SD),
Value(_Value), ValueSize(_ValueSize), Size(_Size) {
assert((!ValueSize || (Size % ValueSize) == 0) &&
int8_t Value;
public:
- MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
+ MCOrgFragment(const MCExpr &_Offset, int8_t _Value,
+ MCSectionData *SD = nullptr)
: MCFragment(FT_Org, SD),
Offset(&_Offset), Value(_Value) {}
SmallString<8> Contents;
public:
- MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD = 0)
+ MCLEBFragment(const MCExpr &Value_, bool IsSigned_,
+ MCSectionData *SD = nullptr)
: MCFragment(FT_LEB, SD),
Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
public:
MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
- MCSectionData *SD = 0)
+ MCSectionData *SD = nullptr)
: MCFragment(FT_Dwarf, SD),
LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
SmallString<8> Contents;
public:
- MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD = 0)
+ MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,
+ MCSectionData *SD = nullptr)
: MCFragment(FT_DwarfFrame, SD),
AddrDelta(&_AddrDelta) { Contents.push_back(0); }
public:
// Only for use as sentinel.
MCSectionData();
- MCSectionData(const MCSection &Section, MCAssembler *A = 0);
+ MCSectionData(const MCSection &Section, MCAssembler *A = nullptr);
const MCSection &getSection() const { return *Section; }
// Only for use as sentinel.
MCSymbolData();
MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
- MCAssembler *A = 0);
+ MCAssembler *A = nullptr);
/// @name Accessors
/// @{
typedef SymbolDataListType::const_iterator const_symbol_iterator;
typedef SymbolDataListType::iterator symbol_iterator;
+ typedef iterator_range<symbol_iterator> symbol_range;
+ typedef iterator_range<const_symbol_iterator> const_symbol_range;
+
typedef std::vector<std::string> FileNameVectorType;
typedef FileNameVectorType::const_iterator const_file_name_iterator;
const_data_region_iterator;
typedef std::vector<DataRegionData>::iterator data_region_iterator;
+ /// MachO specific deployment target version info.
+ // A Major version of 0 indicates that no version information was supplied
+ // and so the corresponding load command should not be emitted.
+ typedef struct {
+ MCVersionMinType Kind;
+ unsigned Major;
+ unsigned Minor;
+ unsigned Update;
+ } VersionMinInfoType;
private:
MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
// here. Maybe when the relocation stuff moves to target specific,
// this can go with it? The streamer would need some target specific
// refactoring too.
- SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
+ mutable SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
/// \brief The bundle alignment size currently set in the assembler.
///
// Access to the flags is necessary in cases where assembler directives affect
// which flags to be set.
unsigned ELFHeaderEFlags;
+
+ /// Used to communicate Linker Optimization Hint information between
+ /// the Streamer and the .o writer
+ MCLOHContainer LOHContainer;
+
+ VersionMinInfoType VersionMinInfo;
private:
/// Evaluate a fixup to a relocatable expression and the value which should be
/// placed into the fixup.
/// finishLayout - Finalize a layout, including fragment lowering.
void finishLayout(MCAsmLayout &Layout);
- uint64_t handleFixup(const MCAsmLayout &Layout,
- MCFragment &F, const MCFixup &Fixup);
+ std::pair<uint64_t, bool> handleFixup(const MCAsmLayout &Layout,
+ MCFragment &F, const MCFixup &Fixup);
public:
/// Compute the effective fragment size assuming it is laid out at the given
const MCAsmLayout &Layout) const;
/// Check whether a given symbol has been flagged with .thumb_func.
- bool isThumbFunc(const MCSymbol *Func) const {
- return ThumbFuncs.count(Func);
- }
+ bool isThumbFunc(const MCSymbol *Func) const;
/// Flag a function symbol as the target of a .thumb_func directive.
void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;}
void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;}
+ /// MachO deployment target version information.
+ const VersionMinInfoType &getVersionMinInfo() const { return VersionMinInfo; }
+ void setVersionMinInfo(MCVersionMinType Kind, unsigned Major, unsigned Minor,
+ unsigned Update) {
+ VersionMinInfo.Kind = Kind;
+ VersionMinInfo.Major = Major;
+ VersionMinInfo.Minor = Minor;
+ VersionMinInfo.Update = Update;
+ }
+
public:
/// Construct a new assembler instance.
///
symbol_iterator symbol_end() { return Symbols.end(); }
const_symbol_iterator symbol_end() const { return Symbols.end(); }
+ symbol_range symbols() { return make_range(symbol_begin(), symbol_end()); }
+ const_symbol_range symbols() const { return make_range(symbol_begin(), symbol_end()); }
+
size_t symbol_size() const { return Symbols.size(); }
/// @}
size_t data_region_size() const { return DataRegions.size(); }
+ /// @}
+ /// @name Data Region List Access
+ /// @{
+
+ // FIXME: This is a total hack, this should not be here. Once things are
+ // factored so that the streamer has direct access to the .o writer, it can
+ // disappear.
+ MCLOHContainer & getLOHContainer() {
+ return LOHContainer;
+ }
+ const MCLOHContainer & getLOHContainer() const {
+ return const_cast<MCAssembler *>(this)->getLOHContainer();
+ }
/// @}
/// @name Backend Data Access
/// @{
}
MCSectionData &getOrCreateSectionData(const MCSection &Section,
- bool *Created = 0) {
+ bool *Created = nullptr) {
MCSectionData *&Entry = SectionMap[&Section];
if (Created) *Created = !Entry;
}
bool hasSymbolData(const MCSymbol &Symbol) const {
- return SymbolMap.lookup(&Symbol) != 0;
+ return SymbolMap.lookup(&Symbol) != nullptr;
+ }
+
+ MCSymbolData &getSymbolData(const MCSymbol &Symbol) {
+ return const_cast<MCSymbolData &>(
+ static_cast<const MCAssembler &>(*this).getSymbolData(Symbol));
}
- MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
+ const MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
assert(Entry && "Missing symbol data!");
return *Entry;
}
MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
- bool *Created = 0) {
+ bool *Created = nullptr) {
MCSymbolData *&Entry = SymbolMap[&Symbol];
if (Created) *Created = !Entry;
if (!Entry)
- Entry = new MCSymbolData(Symbol, 0, 0, this);
+ Entry = new MCSymbolData(Symbol, nullptr, 0, this);
return *Entry;
}