aboutsummaryrefslogtreecommitdiff
path: root/lib/MC
diff options
context:
space:
mode:
authorEli Bendersky <eliben@chromium.org>2013-03-11 15:16:37 -0700
committerEli Bendersky <eliben@chromium.org>2013-03-11 15:16:37 -0700
commit23c00401dad33ca247d2818e71540079bed63c5b (patch)
treedf9f25d60f9538fbde84b78cf3c4e4a00eb6c3db /lib/MC
parent79da56afe68a0c5b2c2227681014dd13705d78cc (diff)
parent279b9184c2ff4fea93b198a3519b8cb3a1d8d195 (diff)
Merge commit '279b9184c2ff4fea93b198a3519b8cb3a1d8d195'
Conflicts: include/llvm/CodeGen/LexicalScopes.h include/llvm/MC/MCAsmInfo.h lib/Linker/LinkArchives.cpp lib/Linker/LinkItems.cpp lib/MC/MCAsmInfo.cpp lib/MC/MCDwarf.cpp lib/Target/ARM/ARMInstrInfo.td lib/Target/ARM/ARMSubtarget.cpp lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp lib/Target/Mips/MipsAsmPrinter.cpp lib/Target/Mips/MipsDelaySlotFiller.cpp lib/Target/Mips/MipsISelDAGToDAG.cpp lib/Target/Mips/MipsSubtarget.cpp lib/Target/Mips/MipsSubtarget.h lib/Target/Mips/MipsTargetObjectFile.cpp lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp lib/Target/X86/X86FastISel.cpp lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86TargetMachine.cpp lib/Transforms/CMakeLists.txt lib/Transforms/LLVMBuild.txt lib/Transforms/Makefile test/MC/ARM/arm_instructions.s test/MC/X86/AlignedBundling/pad-align-to-bundle-end.s
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/ELFObjectWriter.cpp48
-rw-r--r--lib/MC/MCAsmInfo.cpp3
-rw-r--r--lib/MC/MCAsmStreamer.cpp17
-rw-r--r--lib/MC/MCAssembler.cpp20
-rw-r--r--lib/MC/MCContext.cpp4
-rw-r--r--lib/MC/MCDwarf.cpp70
-rw-r--r--lib/MC/MCELF.cpp15
-rw-r--r--lib/MC/MCELFObjectTargetWriter.cpp5
-rw-r--r--lib/MC/MCELFStreamer.cpp21
-rw-r--r--lib/MC/MCMachOStreamer.cpp15
-rw-r--r--lib/MC/MCNullStreamer.cpp7
-rw-r--r--lib/MC/MCObjectFileInfo.cpp34
-rw-r--r--lib/MC/MCObjectStreamer.cpp31
-rw-r--r--lib/MC/MCParser/AsmLexer.cpp80
-rw-r--r--lib/MC/MCParser/AsmParser.cpp698
-rw-r--r--lib/MC/MCParser/COFFAsmParser.cpp81
-rw-r--r--lib/MC/MCParser/DarwinAsmParser.cpp239
-rw-r--r--lib/MC/MCParser/ELFAsmParser.cpp99
-rw-r--r--lib/MC/MCParser/MCAsmParser.cpp4
-rw-r--r--lib/MC/MCPureStreamer.cpp10
-rw-r--r--lib/MC/MCSectionMachO.cpp4
-rw-r--r--lib/MC/MCStreamer.cpp16
-rw-r--r--lib/MC/MachObjectWriter.cpp57
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp29
-rw-r--r--lib/MC/WinCOFFStreamer.cpp54
25 files changed, 1087 insertions, 574 deletions
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 00724465f6..0b97f2700b 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -135,16 +135,14 @@ class ELFObjectWriter : public MCObjectWriter {
const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
const MCFixup &Fixup,
bool IsPCRel) const {
- return TargetObjectWriter->undefinedExplicitRelSym(Target, Fixup, IsPCRel);
+ return TargetObjectWriter->undefinedExplicitRelSym(Target, Fixup,
+ IsPCRel);
}
bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
bool hasRelocationAddend() const {
return TargetObjectWriter->hasRelocationAddend();
}
- unsigned getEFlags() const {
- return TargetObjectWriter->getEFlags();
- }
unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel, bool IsRelocWithSymbol,
int64_t Addend) const {
@@ -152,7 +150,6 @@ class ELFObjectWriter : public MCObjectWriter {
IsRelocWithSymbol, Addend);
}
-
public:
ELFObjectWriter(MCELFObjectTargetWriter *MOTW,
raw_ostream &_OS, bool IsLittleEndian)
@@ -233,7 +230,8 @@ class ELFObjectWriter : public MCObjectWriter {
F.getContents().append(&buf[0], &buf[8]);
}
- void WriteHeader(uint64_t SectionDataSize,
+ void WriteHeader(const MCAssembler &Asm,
+ uint64_t SectionDataSize,
unsigned NumberOfSections);
void WriteSymbolEntry(MCDataFragment *SymtabF,
@@ -373,7 +371,8 @@ ELFObjectWriter::~ELFObjectWriter()
{}
// Emit the ELF header.
-void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
+void ELFObjectWriter::WriteHeader(const MCAssembler &Asm,
+ uint64_t SectionDataSize,
unsigned NumberOfSections) {
// ELF Header
// ----------
@@ -411,7 +410,7 @@ void ELFObjectWriter::WriteHeader(uint64_t SectionDataSize,
sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes
// e_flags = whatever the target wants
- Write32(getEFlags());
+ Write32(Asm.getELFHeaderEFlags());
// e_ehsize = ELF header size
Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
@@ -547,12 +546,17 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
Data.getSymbol().isVariable();
+ // Binding and Type share the same byte as upper and lower nibbles
uint8_t Binding = MCELF::GetBinding(OrigData);
- uint8_t Visibility = MCELF::GetVisibility(OrigData);
uint8_t Type = MCELF::GetType(Data);
-
uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
- uint8_t Other = Visibility;
+
+ // Other and Visibility share the same byte with Visability using the lower
+ // 2 bits
+ uint8_t Visibility = MCELF::GetVisibility(OrigData);
+ uint8_t Other = MCELF::getOther(OrigData) <<
+ (ELF_Other_Shift - ELF_STV_Shift);
+ Other |= Visibility;
uint64_t Value = SymbolValue(Data, Layout);
uint64_t Size = 0;
@@ -1319,6 +1323,8 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
case ELF::SHT_FINI_ARRAY:
case ELF::SHT_PREINIT_ARRAY:
case ELF::SHT_X86_64_UNWIND:
+ case ELF::SHT_MIPS_REGINFO:
+ case ELF::SHT_MIPS_OPTIONS:
// Nothing to do.
break;
@@ -1332,6 +1338,24 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm,
break;
}
+ if (TargetObjectWriter->getEMachine() == ELF::EM_ARM &&
+ Section.getType() == ELF::SHT_ARM_EXIDX) {
+ StringRef SecName(Section.getSectionName());
+ if (SecName == ".ARM.exidx") {
+ sh_link = SectionIndexMap.lookup(
+ Asm.getContext().getELFSection(".text",
+ ELF::SHT_PROGBITS,
+ ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
+ SectionKind::getText()));
+ } else if (SecName.startswith(".ARM.exidx")) {
+ sh_link = SectionIndexMap.lookup(
+ Asm.getContext().getELFSection(SecName.substr(sizeof(".ARM.exidx") - 1),
+ ELF::SHT_PROGBITS,
+ ELF::SHF_EXECINSTR | ELF::SHF_ALLOC,
+ SectionKind::getText()));
+ }
+ }
+
WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(),
Section.getFlags(), 0, Offset, Size, sh_link, sh_info,
Alignment, Section.getEntrySize());
@@ -1532,7 +1556,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
}
// Write out the ELF header ...
- WriteHeader(SectionHeaderOffset, NumSections + 1);
+ WriteHeader(Asm, SectionHeaderOffset, NumSections + 1);
// ... then the regular sections ...
// + because of .shstrtab
diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp
index ffe1b0c50d..51bb435710 100644
--- a/lib/MC/MCAsmInfo.cpp
+++ b/lib/MC/MCAsmInfo.cpp
@@ -24,7 +24,8 @@ using namespace llvm;
MCAsmInfo::MCAsmInfo() {
PointerSize = 4;
- StackSlotSize = 4; // @LOCALMOD
+ CalleeSaveStackSlotSize = 4;
+
IsLittleEndian = true;
StackGrowsUp = false;
HasSubsectionsViaSymbols = false;
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index dd5112c771..7eb7202332 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -71,7 +71,7 @@ public:
MCInstPrinter *printer, MCCodeEmitter *emitter,
MCAsmBackend *asmbackend,
bool showInst)
- : MCStreamer(Context), OS(os), MAI(Context.getAsmInfo()),
+ : MCStreamer(SK_AsmStreamer, Context), OS(os), MAI(Context.getAsmInfo()),
InstPrinter(printer), Emitter(emitter), AsmBackend(asmbackend),
CommentStream(CommentToEmit), IsVerboseAsm(isVerboseAsm),
ShowInst(showInst), UseLoc(useLoc), UseCFI(useCFI),
@@ -145,6 +145,7 @@ public:
virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol);
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
+ virtual void EmitLinkerOptions(ArrayRef<std::string> Options);
virtual void EmitDataRegion(MCDataRegionType Kind);
virtual void EmitThumbFunc(MCSymbol *Func);
@@ -276,6 +277,10 @@ public:
virtual void FinishImpl();
/// @}
+
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() == SK_AsmStreamer;
+ }
};
} // end anonymous namespace.
@@ -375,6 +380,16 @@ void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
EmitEOL();
}
+void MCAsmStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
+ assert(!Options.empty() && "At least one option is required!");
+ OS << "\t.linker_option \"" << Options[0] << '"';
+ for (ArrayRef<std::string>::iterator it = Options.begin() + 1,
+ ie = Options.end(); it != ie; ++it) {
+ OS << ", " << '"' << *it << '"';
+ }
+ OS << "\n";
+}
+
void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
MCContext &Ctx = getContext();
const MCAsmInfo &MAI = Ctx.getAsmInfo();
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 416af8b46f..a394d532d6 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -88,7 +88,8 @@ void MCAsmLayout::invalidateFragmentsFrom(MCFragment *F) {
if (!isFragmentValid(F))
return;
- // Otherwise, reset the last valid fragment to this fragment.
+ // Otherwise, reset the last valid fragment to the previous fragment
+ // (if this is the first fragment, it will be NULL).
const MCSectionData &SD = *F->getParent();
LastValidFragment[&SD] = F->getPrevNode();
}
@@ -273,7 +274,7 @@ MCAssembler::MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
raw_ostream &OS_)
: Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
OS(OS_), BundleAlignSize(0), RelaxAll(false), NoExecStack(false),
- SubsectionsViaSymbols(false) {
+ SubsectionsViaSymbols(false), ELFHeaderEFlags(0) {
}
MCAssembler::~MCAssembler() {
@@ -290,6 +291,7 @@ void MCAssembler::reset() {
RelaxAll = false;
NoExecStack = false;
SubsectionsViaSymbols = false;
+ ELFHeaderEFlags = 0;
// reset objects owned by us
getBackend().reset();
@@ -428,7 +430,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
}
case MCFragment::FT_Org: {
- MCOrgFragment &OF = cast<MCOrgFragment>(F);
+ const MCOrgFragment &OF = cast<MCOrgFragment>(F);
int64_t TargetLocation;
if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, Layout))
report_fatal_error("expected assembly-time absolute expression");
@@ -505,7 +507,7 @@ void MCAsmLayout::layoutFragment(MCFragment *F) {
/// \brief Write the contents of a fragment to the given object writer. Expects
/// a MCEncodedFragment.
static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) {
- MCEncodedFragment &EF = cast<MCEncodedFragment>(F);
+ const MCEncodedFragment &EF = cast<MCEncodedFragment>(F);
OW->WriteBytes(EF.getContents());
}
@@ -556,7 +558,7 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
switch (F.getKind()) {
case MCFragment::FT_Align: {
++stats::EmittedAlignFragments;
- MCAlignFragment &AF = cast<MCAlignFragment>(F);
+ const MCAlignFragment &AF = cast<MCAlignFragment>(F);
uint64_t Count = FragmentSize / AF.getValueSize();
assert(AF.getValueSize() && "Invalid virtual align in concrete fragment!");
@@ -611,7 +613,7 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
case MCFragment::FT_Fill: {
++stats::EmittedFillFragments;
- MCFillFragment &FF = cast<MCFillFragment>(F);
+ const MCFillFragment &FF = cast<MCFillFragment>(F);
assert(FF.getValueSize() && "Invalid virtual align in concrete fragment!");
@@ -628,14 +630,14 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
}
case MCFragment::FT_LEB: {
- MCLEBFragment &LF = cast<MCLEBFragment>(F);
+ const MCLEBFragment &LF = cast<MCLEBFragment>(F);
OW->WriteBytes(LF.getContents().str());
break;
}
case MCFragment::FT_Org: {
++stats::EmittedOrgFragments;
- MCOrgFragment &OF = cast<MCOrgFragment>(F);
+ const MCOrgFragment &OF = cast<MCOrgFragment>(F);
for (uint64_t i = 0, e = FragmentSize; i != e; ++i)
OW->Write8(uint8_t(OF.getValue()));
@@ -674,7 +676,7 @@ void MCAssembler::writeSectionData(const MCSectionData *SD,
// Check that we aren't trying to write a non-zero contents (or fixups)
// into a virtual section. This is to support clients which use standard
// directives to fill the contents of virtual sections.
- MCDataFragment &DF = cast<MCDataFragment>(*it);
+ const MCDataFragment &DF = cast<MCDataFragment>(*it);
assert(DF.fixup_begin() == DF.fixup_end() &&
"Cannot have fixups in virtual section!");
for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i)
diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp
index aa52b49047..1a7df6041e 100644
--- a/lib/MC/MCContext.cpp
+++ b/lib/MC/MCContext.cpp
@@ -40,7 +40,7 @@ MCContext::MCContext(const MCAsmInfo &mai, const MCRegisterInfo &mri,
CompilationDir(llvm::sys::Path::GetCurrentDirectory().str()),
CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0),
DwarfLocSeen(false), GenDwarfForAssembly(false), GenDwarfFileNumber(0),
- AllowTemporaryLabels(true), AutoReset(DoAutoReset) {
+ AllowTemporaryLabels(true), DwarfCompileUnitID(0), AutoReset(DoAutoReset) {
MachOUniquingMap = 0;
ELFUniquingMap = 0;
@@ -83,6 +83,8 @@ void MCContext::reset() {
DwarfDebugFlags = StringRef();
MCLineSections.clear();
MCLineSectionOrder.clear();
+ DwarfCompileUnitID = 0;
+ MCLineTableSymbols.clear();
CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0);
// If we have the MachO uniquing map, free it.
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index a28d3525f9..fea057af3e 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/lib/MC/MCDwarf.cpp
@@ -101,7 +101,8 @@ void MCLineEntry::Make(MCStreamer *MCOS, const MCSection *Section) {
}
// Add the line entry to this section's entries.
- LineSection->addLineEntry(LineEntry);
+ LineSection->addLineEntry(LineEntry,
+ MCOS->getContext().getDwarfCompileUnitID());
}
//
@@ -131,7 +132,12 @@ static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS,
//
static inline void EmitDwarfLineTable(MCStreamer *MCOS,
const MCSection *Section,
- const MCLineSection *LineSection) {
+ const MCLineSection *LineSection,
+ unsigned CUID) {
+ // This LineSection does not contain any LineEntry for the given Compile Unit.
+ if (!LineSection->containEntriesForID(CUID))
+ return;
+
unsigned FileNum = 1;
unsigned LastLine = 1;
unsigned Column = 0;
@@ -141,8 +147,8 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS,
// Loop through each MCLineEntry and encode the dwarf line number table.
for (MCLineSection::const_iterator
- it = LineSection->getMCLineEntries()->begin(),
- ie = LineSection->getMCLineEntries()->end(); it != ie; ++it) {
+ it = LineSection->getMCLineEntries(CUID).begin(),
+ ie = LineSection->getMCLineEntries(CUID).end(); it != ie; ++it) {
if (FileNum != it->getFileNum()) {
FileNum = it->getFileNum();
@@ -215,9 +221,36 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
// Switch to the section where the table will be emitted into.
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
- // Create a symbol at the beginning of this section.
- MCSymbol *LineStartSym = context.CreateTempSymbol();
- // Set the value of the symbol, as we are at the start of the section.
+ const DenseMap<unsigned, MCSymbol *> &MCLineTableSymbols =
+ MCOS->getContext().getMCLineTableSymbols();
+ // CUID and MCLineTableSymbols are set in DwarfDebug, when DwarfDebug does
+ // not exist, CUID will be 0 and MCLineTableSymbols will be empty.
+ // Handle Compile Unit 0, the line table start symbol is the section symbol.
+ const MCSymbol *LineStartSym = EmitCU(MCOS, 0);
+ // Handle the rest of the Compile Units.
+ for (unsigned Is = 1, Ie = MCLineTableSymbols.size(); Is < Ie; Is++)
+ EmitCU(MCOS, Is);
+
+ // Now delete the MCLineSections that were created in MCLineEntry::Make()
+ // and used to emit the line table.
+ const DenseMap<const MCSection *, MCLineSection *> &MCLineSections =
+ MCOS->getContext().getMCLineSections();
+ for (DenseMap<const MCSection *, MCLineSection *>::const_iterator it =
+ MCLineSections.begin(), ie = MCLineSections.end(); it != ie;
+ ++it)
+ delete it->second;
+
+ return LineStartSym;
+}
+
+const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
+ MCContext &context = MCOS->getContext();
+
+ // Create a symbol at the beginning of the line table.
+ MCSymbol *LineStartSym = MCOS->getContext().getMCLineTableSymbol(CUID);
+ if (!LineStartSym)
+ LineStartSym = context.CreateTempSymbol();
+ // Set the value of the symbol, as we are at the start of the line table.
MCOS->EmitLabel(LineStartSym);
// Create a symbol for the end of the section (to be set when we get there).
@@ -239,8 +272,7 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
// total length, the 2 bytes for the version, and these 4 bytes for the
// length of the prologue.
MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym,
- (4 + 2 + 4)),
- 4, 0);
+ (4 + 2 + 4)), 4, 0);
// Parameters of the state machine, are next.
MCOS->EmitIntValue(DWARF2_LINE_MIN_INSN_LENGTH, 1);
@@ -301,11 +333,7 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
++it) {
const MCSection *Sec = *it;
const MCLineSection *Line = MCLineSections.lookup(Sec);
- EmitDwarfLineTable(MCOS, Sec, Line);
-
- // Now delete the MCLineSections that were created in MCLineEntry::Make()
- // and used to emit the line table.
- delete Line;
+ EmitDwarfLineTable(MCOS, Sec, Line, CUID);
}
if (MCOS->getContext().getAsmInfo().getLinkerRequiresNonEmptyDwarfLines()
@@ -638,9 +666,15 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS,
}
// AT_producer, the version of the assembler tool.
- MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM "));
- MCOS->EmitBytes(StringRef(PACKAGE_VERSION));
- MCOS->EmitBytes(StringRef(")"));
+ StringRef DwarfDebugProducer = context.getDwarfDebugProducer();
+ if (!DwarfDebugProducer.empty()){
+ MCOS->EmitBytes(DwarfDebugProducer);
+ }
+ else {
+ MCOS->EmitBytes(StringRef("llvm-mc (based on LLVM "));
+ MCOS->EmitBytes(StringRef(PACKAGE_VERSION));
+ MCOS->EmitBytes(StringRef(")"));
+ }
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
// AT_language, a 4 byte value. We use DW_LANG_Mips_Assembler as the dwarf2
@@ -786,7 +820,7 @@ void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS,
static int getDataAlignmentFactor(MCStreamer &streamer) {
MCContext &context = streamer.getContext();
const MCAsmInfo &asmInfo = context.getAsmInfo();
- int size = asmInfo.getStackSlotSize(); // @LOCALMOD
+ int size = asmInfo.getCalleeSaveStackSlotSize();
if (asmInfo.isStackGrowthDirectionUp())
return size;
else
diff --git a/lib/MC/MCELF.cpp b/lib/MC/MCELF.cpp
index 4db2846bc3..560cdbc6ab 100644
--- a/lib/MC/MCELF.cpp
+++ b/lib/MC/MCELF.cpp
@@ -52,6 +52,8 @@ unsigned MCELF::GetType(const MCSymbolData &SD) {
return Type;
}
+// Visibility is stored in the first two bits of st_other
+// st_other values are stored in the second byte of get/setFlags
void MCELF::SetVisibility(MCSymbolData &SD, unsigned Visibility) {
assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
@@ -68,4 +70,17 @@ unsigned MCELF::GetVisibility(MCSymbolData &SD) {
return Visibility;
}
+// Other is stored in the last six bits of st_other
+// st_other values are stored in the second byte of get/setFlags
+void MCELF::setOther(MCSymbolData &SD, unsigned Other) {
+ uint32_t OtherFlags = SD.getFlags() & ~(0x3f << ELF_Other_Shift);
+ SD.setFlags(OtherFlags | (Other << ELF_Other_Shift));
+}
+
+unsigned MCELF::getOther(MCSymbolData &SD) {
+ unsigned Other =
+ (SD.getFlags() & (0x3f << ELF_Other_Shift)) >> ELF_Other_Shift;
+ return Other;
+}
+
}
diff --git a/lib/MC/MCELFObjectTargetWriter.cpp b/lib/MC/MCELFObjectTargetWriter.cpp
index 74cd042a0f..4cac84d666 100644
--- a/lib/MC/MCELFObjectTargetWriter.cpp
+++ b/lib/MC/MCELFObjectTargetWriter.cpp
@@ -24,11 +24,6 @@ MCELFObjectTargetWriter::MCELFObjectTargetWriter(bool Is64Bit_,
IsN64(IsN64_){
}
-/// Default e_flags = 0
-unsigned MCELFObjectTargetWriter::getEFlags() const {
- return 0;
-}
-
const MCSymbol *MCELFObjectTargetWriter::ExplicitRelSym(const MCAssembler &Asm,
const MCValue &Target,
const MCFragment &F,
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index 27587d312a..c1428d8587 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -300,7 +300,9 @@ void MCELFStreamer::EmitFileDirective(StringRef Filename) {
void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
switch (expr->getKind()) {
- case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!");
+ case MCExpr::Target:
+ cast<MCTargetExpr>(expr)->fixELFSymbolsInTLSFixups(getAssembler());
+ break;
case MCExpr::Constant:
break;
@@ -332,6 +334,19 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
case MCSymbolRefExpr::VK_Mips_GOTTPREL:
case MCSymbolRefExpr::VK_Mips_TPREL_HI:
case MCSymbolRefExpr::VK_Mips_TPREL_LO:
+ case MCSymbolRefExpr::VK_PPC_TPREL16_HA:
+ case MCSymbolRefExpr::VK_PPC_TPREL16_LO:
+ case MCSymbolRefExpr::VK_PPC_DTPREL16_HA:
+ case MCSymbolRefExpr::VK_PPC_DTPREL16_LO:
+ case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_HA:
+ case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO:
+ case MCSymbolRefExpr::VK_PPC_TLS:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_LO:
+ case MCSymbolRefExpr::VK_PPC_TLSGD:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_HA:
+ case MCSymbolRefExpr::VK_PPC_GOT_TLSLD16_LO:
+ case MCSymbolRefExpr::VK_PPC_TLSLD:
break;
}
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(symRef.getSymbol());
@@ -502,6 +517,10 @@ void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
llvm_unreachable("Generic ELF doesn't support this directive");
}
+MCSymbolData &MCELFStreamer::getOrCreateSymbolData(MCSymbol *Symbol) {
+ return getAssembler().getOrCreateSymbolData(*Symbol);
+}
+
void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
llvm_unreachable("ELF doesn't support this directive");
}
diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp
index f947dda83d..7d08d0ecd5 100644
--- a/lib/MC/MCMachOStreamer.cpp
+++ b/lib/MC/MCMachOStreamer.cpp
@@ -34,9 +34,9 @@ private:
void EmitDataRegion(DataRegionData::KindTy Kind);
void EmitDataRegionEnd();
public:
- MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
- raw_ostream &OS, MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, MAB, OS, Emitter) {}
+ MCMachOStreamer(MCContext &Context, MCAsmBackend &MAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter)
+ : MCObjectStreamer(SK_MachOStreamer, Context, MAB, OS, Emitter) {}
/// @name MCStreamer Interface
/// @{
@@ -48,6 +48,7 @@ public:
virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol);
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
+ virtual void EmitLinkerOptions(ArrayRef<std::string> Options);
virtual void EmitDataRegion(MCDataRegionType Kind);
virtual void EmitThumbFunc(MCSymbol *Func);
virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
@@ -86,6 +87,10 @@ public:
virtual void FinishImpl();
/// @}
+
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() == SK_MachOStreamer;
+ }
};
} // end anonymous namespace.
@@ -178,6 +183,10 @@ void MCMachOStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {
}
}
+void MCMachOStreamer::EmitLinkerOptions(ArrayRef<std::string> Options) {
+ getAssembler().getLinkerOptions().push_back(Options);
+}
+
void MCMachOStreamer::EmitDataRegion(MCDataRegionType Kind) {
switch (Kind) {
case MCDR_DataRegion:
diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp
index 3eee5caf6f..89f74c1709 100644
--- a/lib/MC/MCNullStreamer.cpp
+++ b/lib/MC/MCNullStreamer.cpp
@@ -19,7 +19,7 @@ namespace {
class MCNullStreamer : public MCStreamer {
public:
- MCNullStreamer(MCContext &Context) : MCStreamer(Context) {}
+ MCNullStreamer(MCContext &Context) : MCStreamer(SK_NullStreamer, Context) {}
/// @name MCStreamer Interface
/// @{
@@ -109,6 +109,11 @@ namespace {
}
/// @}
+
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() == SK_NullStreamer;
+ }
+
};
}
diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp
index e34bc2653d..1e2086e565 100644
--- a/lib/MC/MCObjectFileInfo.cpp
+++ b/lib/MC/MCObjectFileInfo.cpp
@@ -186,6 +186,10 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
Ctx->getMachOSection("__DWARF", "__debug_frame",
MCSectionMachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
+ DwarfPubNamesSection =
+ Ctx->getMachOSection("__DWARF", "__debug_pubnames",
+ MCSectionMachO::S_ATTR_DEBUG,
+ SectionKind::getMetadata());
DwarfPubTypesSection =
Ctx->getMachOSection("__DWARF", "__debug_pubtypes",
MCSectionMachO::S_ATTR_DEBUG,
@@ -256,6 +260,25 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
TTypeEncoding = (CMModel == CodeModel::Small)
? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
}
+ } else if (T.getArch() == Triple::aarch64) {
+ FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+
+ // The small model guarantees static code/data size < 4GB, but not where it
+ // will be in memory. Most of these could end up >2GB away so even a signed
+ // pc-relative 32-bit address is insufficient, theoretically.
+ if (RelocM == Reloc::PIC_) {
+ PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata8;
+ LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8;
+ FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
+ TTypeEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
+ dwarf::DW_EH_PE_sdata8;
+ } else {
+ PersonalityEncoding = dwarf::DW_EH_PE_absptr;
+ LSDAEncoding = dwarf::DW_EH_PE_absptr;
+ FDEEncoding = dwarf::DW_EH_PE_udata4;
+ TTypeEncoding = dwarf::DW_EH_PE_absptr;
+ }
} else if (T.getArch() == Triple::ppc64) {
PersonalityEncoding = dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |
dwarf::DW_EH_PE_udata8;
@@ -381,6 +404,9 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
DwarfFrameSection =
Ctx->getELFSection(".debug_frame", ELF::SHT_PROGBITS, 0,
SectionKind::getMetadata());
+ DwarfPubNamesSection =
+ Ctx->getELFSection(".debug_pubnames", ELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
DwarfPubTypesSection =
Ctx->getELFSection(".debug_pubtypes", ELF::SHT_PROGBITS, 0,
SectionKind::getMetadata());
@@ -437,6 +463,9 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
DwarfStrOffDWOSection =
Ctx->getELFSection(".debug_str_offsets.dwo", ELF::SHT_PROGBITS, 0,
SectionKind::getMetadata());
+ DwarfAddrSection =
+ Ctx->getELFSection(".debug_addr", ELF::SHT_PROGBITS, 0,
+ SectionKind::getMetadata());
}
@@ -521,6 +550,11 @@ void MCObjectFileInfo::InitCOFFMCObjectFileInfo(Triple T) {
COFF::IMAGE_SCN_MEM_DISCARDABLE |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
+ DwarfPubNamesSection =
+ Ctx->getCOFFSection(".debug_pubnames",
+ COFF::IMAGE_SCN_MEM_DISCARDABLE |
+ COFF::IMAGE_SCN_MEM_READ,
+ SectionKind::getMetadata());
DwarfPubTypesSection =
Ctx->getCOFFSection(".debug_pubtypes",
COFF::IMAGE_SCN_MEM_DISCARDABLE |
diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index 8130c9b532..e835eea7df 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/lib/MC/MCObjectStreamer.cpp
@@ -20,22 +20,19 @@
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
-MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter_)
- : MCStreamer(Context),
- Assembler(new MCAssembler(Context, TAB,
- *Emitter_, *TAB.createObjectWriter(OS),
- OS)),
- CurSectionData(0)
-{
-}
-
-MCObjectStreamer::MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter_,
+MCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context,
+ MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter_)
+ : MCStreamer(Kind, Context),
+ Assembler(new MCAssembler(Context, TAB, *Emitter_,
+ *TAB.createObjectWriter(OS), OS)),
+ CurSectionData(0) {}
+
+MCObjectStreamer::MCObjectStreamer(StreamerKind Kind, MCContext &Context,
+ MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter_,
MCAssembler *_Assembler)
- : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0)
-{
-}
+ : MCStreamer(Kind, Context), Assembler(_Assembler), CurSectionData(0) {}
MCObjectStreamer::~MCObjectStreamer() {
delete &Assembler->getBackend();
@@ -235,8 +232,10 @@ void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
IF->getContents().append(Code.begin(), Code.end());
}
-const char *BundlingNotImplementedMsg =
+#ifndef NDEBUG
+static const char *BundlingNotImplementedMsg =
"Aligned bundling is not implemented for this object format";
+#endif
void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
llvm_unreachable(BundlingNotImplementedMsg);
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp
index d0492fd16c..c1c594a746 100644
--- a/lib/MC/MCParser/AsmLexer.cpp
+++ b/lib/MC/MCParser/AsmLexer.cpp
@@ -156,10 +156,36 @@ AsmToken AsmLexer::LexLineComment() {
}
static void SkipIgnoredIntegerSuffix(const char *&CurPtr) {
- if (CurPtr[0] == 'L' && CurPtr[1] == 'L')
- CurPtr += 2;
- if (CurPtr[0] == 'U' && CurPtr[1] == 'L' && CurPtr[2] == 'L')
- CurPtr += 3;
+ // Skip ULL, UL, U, L and LL suffices.
+ if (CurPtr[0] == 'U')
+ ++CurPtr;
+ if (CurPtr[0] == 'L')
+ ++CurPtr;
+ if (CurPtr[0] == 'L')
+ ++CurPtr;
+}
+
+// Look ahead to search for first non-hex digit, if it's [hH], then we treat the
+// integer as a hexadecimal, possibly with leading zeroes.
+static unsigned doLookAhead(const char *&CurPtr, unsigned DefaultRadix) {
+ const char *FirstHex = 0;
+ const char *LookAhead = CurPtr;
+ while (1) {
+ if (isdigit(*LookAhead)) {
+ ++LookAhead;
+ } else if (isxdigit(*LookAhead)) {
+ if (!FirstHex)
+ FirstHex = LookAhead;
+ ++LookAhead;
+ } else {
+ break;
+ }
+ }
+ bool isHex = *LookAhead == 'h' || *LookAhead == 'H';
+ CurPtr = isHex || !FirstHex ? LookAhead : FirstHex;
+ if (isHex)
+ return 16;
+ return DefaultRadix;
}
/// LexDigit: First character is [0-9].
@@ -167,16 +193,15 @@ static void SkipIgnoredIntegerSuffix(const char *&CurPtr) {
/// Forward/Backward Label: [0-9][fb]
/// Binary integer: 0b[01]+
/// Octal integer: 0[0-7]+
-/// Hex integer: 0x[0-9a-fA-F]+
+/// Hex integer: 0x[0-9a-fA-F]+ or [0x]?[0-9][0-9a-fA-F]*[hH]
/// Decimal integer: [1-9][0-9]*
AsmToken AsmLexer::LexDigit() {
// Decimal integer: [1-9][0-9]*
if (CurPtr[-1] != '0' || CurPtr[0] == '.') {
- while (isdigit(*CurPtr))
- ++CurPtr;
-
+ unsigned Radix = doLookAhead(CurPtr, 10);
+ bool isHex = Radix == 16;
// Check for floating point literals.
- if (*CurPtr == '.' || *CurPtr == 'e') {
+ if (!isHex && (*CurPtr == '.' || *CurPtr == 'e')) {
++CurPtr;
return LexFloatLiteral();
}
@@ -184,17 +209,22 @@ AsmToken AsmLexer::LexDigit() {
StringRef Result(TokStart, CurPtr - TokStart);
long long Value;
- if (Result.getAsInteger(10, Value)) {
+ if (Result.getAsInteger(Radix, Value)) {
// Allow positive values that are too large to fit into a signed 64-bit
// integer, but that do fit in an unsigned one, we just convert them over.
unsigned long long UValue;
- if (Result.getAsInteger(10, UValue))
- return ReturnError(TokStart, "invalid decimal number");
+ if (Result.getAsInteger(Radix, UValue))
+ return ReturnError(TokStart, !isHex ? "invalid decimal number" :
+ "invalid hexdecimal number");
Value = (long long)UValue;
}
- // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
- // suffixes on integer literals.
+ // Consume the [bB][hH].
+ if (Radix == 2 || Radix == 16)
+ ++CurPtr;
+
+ // The darwin/x86 (and x86-64) assembler accepts and ignores type
+ // suffices on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
return AsmToken(AsmToken::Integer, Result, Value);
@@ -243,6 +273,10 @@ AsmToken AsmLexer::LexDigit() {
if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result))
return ReturnError(TokStart, "invalid hexadecimal number");
+ // Consume the optional [hH].
+ if (*CurPtr == 'h' || *CurPtr == 'H')
+ ++CurPtr;
+
// The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
@@ -251,14 +285,18 @@ AsmToken AsmLexer::LexDigit() {
(int64_t)Result);
}
- // Must be an octal number, it starts with 0.
- while (*CurPtr >= '0' && *CurPtr <= '9')
- ++CurPtr;
-
- StringRef Result(TokStart, CurPtr - TokStart);
+ // Either octal or hexadecimal.
long long Value;
- if (Result.getAsInteger(8, Value))
- return ReturnError(TokStart, "invalid octal number");
+ unsigned Radix = doLookAhead(CurPtr, 8);
+ bool isHex = Radix == 16;
+ StringRef Result(TokStart, CurPtr - TokStart);
+ if (Result.getAsInteger(Radix, Value))
+ return ReturnError(TokStart, !isHex ? "invalid octal number" :
+ "invalid hexdecimal number");
+
+ // Consume the [hH].
+ if (Radix == 16)
+ ++CurPtr;
// The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
// suffixes on integer literals.
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 43c872b809..6ab49ec92c 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -13,6 +13,7 @@
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -50,6 +51,25 @@ MCAsmParserSemaCallback::~MCAsmParserSemaCallback() {}
namespace {
+/// \brief Helper types for tracking macro definitions.
+typedef std::vector<AsmToken> MCAsmMacroArgument;
+typedef std::vector<MCAsmMacroArgument> MCAsmMacroArguments;
+typedef std::pair<StringRef, MCAsmMacroArgument> MCAsmMacroParameter;
+typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters;
+
+struct MCAsmMacro {
+ StringRef Name;
+ StringRef Body;
+ MCAsmMacroParameters Parameters;
+
+public:
+ MCAsmMacro(StringRef N, StringRef B, const MCAsmMacroParameters &P) :
+ Name(N), Body(B), Parameters(P) {}
+
+ MCAsmMacro(const MCAsmMacro& Other)
+ : Name(Other.Name), Body(Other.Body), Parameters(Other.Parameters) {}
+};
+
/// \brief Helper class for storing information about an active macro
/// instantiation.
struct MacroInstantiation {
@@ -73,7 +93,6 @@ public:
MemoryBuffer *I);
};
-//struct AsmRewrite;
struct ParseStatementInfo {
/// ParsedOperands - The parsed operands from the last parsed statement.
SmallVector<MCParsedAsmOperand*, 8> ParsedOperands;
@@ -121,9 +140,7 @@ private:
/// ExtensionDirectiveMap - maps directive names to handler methods in parser
/// extensions. Extensions register themselves in this map by calling
- /// AddDirectiveHandler.
- typedef std::pair<MCAsmParserExtension*, DirectiveHandler>
- ExtensionDirectiveHandler;
+ /// addDirectiveHandler.
StringMap<ExtensionDirectiveHandler> ExtensionDirectiveMap;
/// MacroMap - Map of currently defined macros.
@@ -160,10 +177,9 @@ public:
virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false);
- virtual void AddDirectiveHandler(MCAsmParserExtension *Object,
- StringRef Directive,
- DirectiveHandler Handler) {
- ExtensionDirectiveMap[Directive] = std::make_pair(Object, Handler);
+ virtual void addDirectiveHandler(StringRef Directive,
+ ExtensionDirectiveHandler Handler) {
+ ExtensionDirectiveMap[Directive] = Handler;
}
public:
@@ -194,7 +210,7 @@ public:
void setParsingInlineAsm(bool V) { ParsingInlineAsm = V; }
bool isParsingInlineAsm() { return ParsingInlineAsm; }
- bool ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
+ bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
unsigned &NumOutputs, unsigned &NumInputs,
SmallVectorImpl<std::pair<void *,bool> > &OpDecls,
SmallVectorImpl<std::string> &Constraints,
@@ -203,31 +219,17 @@ public:
const MCInstPrinter *IP,
MCAsmParserSemaCallback &SI);
- bool ParseExpression(const MCExpr *&Res);
- virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc);
- virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
- virtual bool ParseAbsoluteExpression(int64_t &Res);
-
- bool ParseMacroArgument(MCAsmMacroArgument &MA,
- AsmToken::TokenKind &ArgumentDelimiter);
+ bool parseExpression(const MCExpr *&Res);
+ virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc);
+ virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc);
+ virtual bool parseAbsoluteExpression(int64_t &Res);
- /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
+ /// parseIdentifier - Parse an identifier or string (as a quoted identifier)
/// and set \p Res to the identifier contents.
- virtual bool ParseIdentifier(StringRef &Res);
- virtual void EatToEndOfStatement();
-
- virtual bool MacrosEnabled() {return MacrosEnabledFlag;}
- virtual void SetMacrosEnabled(bool flag) {MacrosEnabledFlag = flag;}
+ virtual bool parseIdentifier(StringRef &Res);
+ virtual void eatToEndOfStatement();
- virtual const MCAsmMacro* LookupMacro(StringRef Name);
- virtual void DefineMacro(StringRef Name, const MCAsmMacro& Macro);
- virtual void UndefineMacro(StringRef Name);
-
- virtual bool InsideMacroInstantiation() {return !ActiveMacros.empty();}
- virtual bool HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc);
- void HandleMacroExit();
-
- virtual void CheckForValidSection();
+ virtual void checkForValidSection();
/// }
private:
@@ -236,11 +238,51 @@ private:
void EatToEndOfLine();
bool ParseCppHashLineFilenameComment(const SMLoc &L);
+ void CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
+ MCAsmMacroParameters Parameters);
bool expandMacro(raw_svector_ostream &OS, StringRef Body,
const MCAsmMacroParameters &Parameters,
const MCAsmMacroArguments &A,
const SMLoc &L);
+ /// \brief Are macros enabled in the parser?
+ bool MacrosEnabled() {return MacrosEnabledFlag;}
+
+ /// \brief Control a flag in the parser that enables or disables macros.
+ void SetMacrosEnabled(bool Flag) {MacrosEnabledFlag = Flag;}
+
+ /// \brief Lookup a previously defined macro.
+ /// \param Name Macro name.
+ /// \returns Pointer to macro. NULL if no such macro was defined.
+ const MCAsmMacro* LookupMacro(StringRef Name);
+
+ /// \brief Define a new macro with the given name and information.
+ void DefineMacro(StringRef Name, const MCAsmMacro& Macro);
+
+ /// \brief Undefine a macro. If no such macro was defined, it's a no-op.
+ void UndefineMacro(StringRef Name);
+
+ /// \brief Are we inside a macro instantiation?
+ bool InsideMacroInstantiation() {return !ActiveMacros.empty();}
+
+ /// \brief Handle entry to macro instantiation.
+ ///
+ /// \param M The macro.
+ /// \param NameLoc Instantiation location.
+ bool HandleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc);
+
+ /// \brief Handle exit from macro instantiation.
+ void HandleMacroExit();
+
+ /// \brief Extract AsmTokens for a macro argument. If the argument delimiter
+ /// is initially unknown, set it to AsmToken::Eof. It will be set to the
+ /// correct delimiter by the method.
+ bool ParseMacroArgument(MCAsmMacroArgument &MA,
+ AsmToken::TokenKind &ArgumentDelimiter);
+
+ /// \brief Parse all macro arguments for a given macro.
+ bool ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
+
void PrintMacroInstantiations();
void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const {
@@ -262,12 +304,10 @@ private:
/// location.
void JumpToLoc(SMLoc Loc, int InBuffer=-1);
- bool ParseMacroArguments(const MCAsmMacro *M, MCAsmMacroArguments &A);
-
/// \brief Parse up to the end of statement and a return the contents from the
/// current token until the end of the statement; the current token on exit
/// will be either the EndOfStatement or EOF.
- virtual StringRef ParseStringToEndOfStatement();
+ virtual StringRef parseStringToEndOfStatement();
/// \brief Parse until the end of a statement or a comma is encountered,
/// return the contents from the current token up to the end or comma.
@@ -390,10 +430,7 @@ private:
bool ParseDirectiveElseIf(SMLoc DirectiveLoc); // ".elseif"
bool ParseDirectiveElse(SMLoc DirectiveLoc); // ".else"
bool ParseDirectiveEndIf(SMLoc DirectiveLoc); // .endif
-
- /// ParseEscapedString - Parse the current token as a string which may include
- /// escaped characters and return the string contents.
- bool ParseEscapedString(std::string &Data);
+ virtual bool parseEscapedString(std::string &Data);
const MCExpr *ApplyModifierToExpr(const MCExpr *E,
MCSymbolRefExpr::VariantKind Variant);
@@ -407,8 +444,12 @@ private:
bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc"
bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr"
- // "_emit"
- bool ParseDirectiveEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info);
+ // "_emit" or "__emit"
+ bool ParseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
+ size_t Len);
+
+ // "align"
+ bool ParseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
void initializeDirectiveKindMap();
};
@@ -577,7 +618,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// We had an error, validate that one was emitted and recover by skipping to
// the next line.
assert(HadError && "Parse statement returned an error, but none emitted!");
- EatToEndOfStatement();
+ eatToEndOfStatement();
}
if (TheCondState.TheCond != StartingCondState.TheCond ||
@@ -624,15 +665,15 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
return HadError;
}
-void AsmParser::CheckForValidSection() {
+void AsmParser::checkForValidSection() {
if (!ParsingInlineAsm && !getStreamer().getCurrentSection()) {
TokError("expected section directive before assembly directive");
Out.InitToTextSection();
}
}
-/// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
-void AsmParser::EatToEndOfStatement() {
+/// eatToEndOfStatement - Throw away the rest of the line for testing purposes.
+void AsmParser::eatToEndOfStatement() {
while (Lexer.isNot(AsmToken::EndOfStatement) &&
Lexer.isNot(AsmToken::Eof))
Lex();
@@ -642,7 +683,7 @@ void AsmParser::EatToEndOfStatement() {
Lex();
}
-StringRef AsmParser::ParseStringToEndOfStatement() {
+StringRef AsmParser::parseStringToEndOfStatement() {
const char *Start = getTok().getLoc().getPointer();
while (Lexer.isNot(AsmToken::EndOfStatement) &&
@@ -671,7 +712,7 @@ StringRef AsmParser::ParseStringToComma() {
/// parenexpr ::= expr)
///
bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
- if (ParseExpression(Res)) return true;
+ if (parseExpression(Res)) return true;
if (Lexer.isNot(AsmToken::RParen))
return TokError("expected ')' in parentheses expression");
EndLoc = Lexer.getTok().getEndLoc();
@@ -685,7 +726,7 @@ bool AsmParser::ParseParenExpr(const MCExpr *&Res, SMLoc &EndLoc) {
/// bracketexpr ::= expr]
///
bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
- if (ParseExpression(Res)) return true;
+ if (parseExpression(Res)) return true;
if (Lexer.isNot(AsmToken::RBrac))
return TokError("expected ']' in brackets expression");
EndLoc = Lexer.getTok().getEndLoc();
@@ -700,7 +741,9 @@ bool AsmParser::ParseBracketExpr(const MCExpr *&Res, SMLoc &EndLoc) {
/// primaryexpr ::= '.'
/// primaryexpr ::= ~,+,- primaryexpr
bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
- switch (Lexer.getKind()) {
+ SMLoc FirstTokenLoc = getLexer().getLoc();
+ AsmToken::TokenKind FirstTokenKind = Lexer.getKind();
+ switch (FirstTokenKind) {
default:
return TokError("unknown token in expression");
// If we have an error assume that we've already handled it.
@@ -716,8 +759,11 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
case AsmToken::String:
case AsmToken::Identifier: {
StringRef Identifier;
- if (ParseIdentifier(Identifier))
+ if (parseIdentifier(Identifier)) {
+ if (FirstTokenKind == AsmToken::Dollar)
+ return Error(FirstTokenLoc, "invalid token in expression");
return true;
+ }
EndLoc = SMLoc::getFromPointer(Identifier.end());
@@ -818,9 +864,9 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
}
}
-bool AsmParser::ParseExpression(const MCExpr *&Res) {
+bool AsmParser::parseExpression(const MCExpr *&Res) {
SMLoc EndLoc;
- return ParseExpression(Res, EndLoc);
+ return parseExpression(Res, EndLoc);
}
const MCExpr *
@@ -871,7 +917,7 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E,
llvm_unreachable("Invalid expression kind!");
}
-/// ParseExpression - Parse an expression and return it.
+/// parseExpression - Parse an expression and return it.
///
/// expr ::= expr &&,|| expr -> lowest.
/// expr ::= expr |,^,&,! expr
@@ -881,7 +927,7 @@ AsmParser::ApplyModifierToExpr(const MCExpr *E,
/// expr ::= expr *,/,% expr -> highest.
/// expr ::= primaryexpr
///
-bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
+bool AsmParser::parseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
// Parse the expression.
Res = 0;
if (ParsePrimaryExpr(Res, EndLoc) || ParseBinOpRHS(1, Res, EndLoc))
@@ -919,17 +965,17 @@ bool AsmParser::ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
return false;
}
-bool AsmParser::ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
+bool AsmParser::parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
Res = 0;
return ParseParenExpr(Res, EndLoc) ||
ParseBinOpRHS(1, Res, EndLoc);
}
-bool AsmParser::ParseAbsoluteExpression(int64_t &Res) {
+bool AsmParser::parseAbsoluteExpression(int64_t &Res) {
const MCExpr *Expr;
SMLoc StartLoc = Lexer.getLoc();
- if (ParseExpression(Expr))
+ if (parseExpression(Expr))
return true;
if (!Expr->EvaluateAsAbsolute(Res))
@@ -1076,8 +1122,7 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
if (!TheCondState.Ignore)
return TokError("unexpected token at start of statement");
IDVal = "";
- }
- else {
+ } else {
IDVal = getTok().getString();
Lex(); // Consume the integer token to be used as an identifier token.
if (Lexer.getKind() != AsmToken::Colon) {
@@ -1085,13 +1130,11 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
return TokError("unexpected token at start of statement");
}
}
-
} else if (Lexer.is(AsmToken::Dot)) {
// Treat '.' as a valid identifier in this context.
Lex();
IDVal = ".";
-
- } else if (ParseIdentifier(IDVal)) {
+ } else if (parseIdentifier(IDVal)) {
if (!TheCondState.Ignore)
return TokError("unexpected token at start of statement");
IDVal = "";
@@ -1131,9 +1174,10 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
return ParseDirectiveEndIf(IDLoc);
}
- // If we are in a ".if 0" block, ignore this statement.
+ // Ignore the statement if in the middle of inactive conditional
+ // (e.g. ".if 0").
if (TheCondState.Ignore) {
- EatToEndOfStatement();
+ eatToEndOfStatement();
return false;
}
@@ -1142,7 +1186,7 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
// See what kind of statement we have.
switch (Lexer.getKind()) {
case AsmToken::Colon: {
- CheckForValidSection();
+ checkForValidSection();
// identifier ':' -> Label.
Lex();
@@ -1288,7 +1332,7 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
case DK_ZERO:
return ParseDirectiveZero();
case DK_EXTERN:
- EatToEndOfStatement(); // .extern is the default, ignore it.
+ eatToEndOfStatement(); // .extern is the default, ignore it.
return false;
case DK_GLOBL:
case DK_GLOBAL:
@@ -1407,20 +1451,22 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
return Error(IDLoc, "unknown directive");
}
- // _emit
- if (ParsingInlineAsm && IDVal == "_emit")
- return ParseDirectiveEmit(IDLoc, Info);
+ // __asm _emit or __asm __emit
+ if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
+ IDVal == "_EMIT" || IDVal == "__EMIT"))
+ return ParseDirectiveMSEmit(IDLoc, Info, IDVal.size());
- CheckForValidSection();
+ // __asm align
+ if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
+ return ParseDirectiveMSAlign(IDLoc, Info);
- // Canonicalize the opcode to lower case.
- SmallString<128> OpcodeStr;
- for (unsigned i = 0, e = IDVal.size(); i != e; ++i)
- OpcodeStr.push_back(tolower(IDVal[i]));
+ checkForValidSection();
+ // Canonicalize the opcode to lower case.
+ std::string OpcodeStr = IDVal.lower();
ParseInstructionInfo IInfo(Info.AsmRewrites);
- bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr.str(),
- IDLoc,Info.ParsedOperands);
+ bool HadError = getTargetParser().ParseInstruction(IInfo, OpcodeStr,
+ IDLoc, Info.ParsedOperands);
Info.ParseError = HadError;
// Dump the parsed representation, if requested.
@@ -1444,22 +1490,22 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
if (!HadError && getContext().getGenDwarfForAssembly() &&
getContext().getGenDwarfSection() == getStreamer().getCurrentSection()) {
- unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
+ unsigned Line = SrcMgr.FindLineNumber(IDLoc, CurBuffer);
- // If we previously parsed a cpp hash file line comment then make sure the
- // current Dwarf File is for the CppHashFilename if not then emit the
- // Dwarf File table for it and adjust the line number for the .loc.
- const std::vector<MCDwarfFile *> &MCDwarfFiles =
- getContext().getMCDwarfFiles();
- if (CppHashFilename.size() != 0) {
- if(MCDwarfFiles[getContext().getGenDwarfFileNumber()]->getName() !=
+ // If we previously parsed a cpp hash file line comment then make sure the
+ // current Dwarf File is for the CppHashFilename if not then emit the
+ // Dwarf File table for it and adjust the line number for the .loc.
+ const std::vector<MCDwarfFile *> &MCDwarfFiles =
+ getContext().getMCDwarfFiles();
+ if (CppHashFilename.size() != 0) {
+ if (MCDwarfFiles[getContext().getGenDwarfFileNumber()]->getName() !=
CppHashFilename)
- getStreamer().EmitDwarfFileDirective(
- getContext().nextGenDwarfFileNumber(), StringRef(), CppHashFilename);
+ getStreamer().EmitDwarfFileDirective(
+ getContext().nextGenDwarfFileNumber(), StringRef(), CppHashFilename);
unsigned CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc,CppHashBuf);
Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo);
- }
+ }
getStreamer().EmitDwarfLocDirective(getContext().getGenDwarfFileNumber(),
Line, 0, DWARF2_LINE_DEFAULT_IS_STMT ?
@@ -1585,7 +1631,8 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
// we can't do that. AsmLexer.cpp should probably be changed to handle
// '@' as a special case when needed.
static bool isIdentifierChar(char c) {
- return isalnum(c) || c == '_' || c == '$' || c == '.';
+ return isalnum(static_cast<unsigned char>(c)) || c == '_' || c == '$' ||
+ c == '.';
}
bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
@@ -1609,7 +1656,8 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
continue;
char Next = Body[Pos + 1];
- if (Next == '$' || Next == 'n' || isdigit(Next))
+ if (Next == '$' || Next == 'n' ||
+ isdigit(static_cast<unsigned char>(Next)))
break;
} else {
// This macro has parameters, look for \foo, \bar, etc.
@@ -1954,7 +2002,7 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef,
SMLoc EqualLoc = Lexer.getLoc();
const MCExpr *Value;
- if (ParseExpression(Value))
+ if (parseExpression(Value))
return true;
// Note: we don't count b as used in "a = b". This is to allow
@@ -2011,10 +2059,10 @@ bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef,
return false;
}
-/// ParseIdentifier:
+/// parseIdentifier:
/// ::= identifier
/// ::= string
-bool AsmParser::ParseIdentifier(StringRef &Res) {
+bool AsmParser::parseIdentifier(StringRef &Res) {
// The assembler has relaxed rules for accepting identifiers, in particular we
// allow things like '.globl $foo', which would normally be separate
// tokens. At this level, we have already lexed so we cannot (currently)
@@ -2057,7 +2105,7 @@ bool AsmParser::ParseIdentifier(StringRef &Res) {
bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) {
StringRef Name;
- if (ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("expected identifier after '" + Twine(IDVal) + "'");
if (getLexer().isNot(AsmToken::Comma))
@@ -2067,7 +2115,7 @@ bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) {
return ParseAssignment(Name, allow_redef, true);
}
-bool AsmParser::ParseEscapedString(std::string &Data) {
+bool AsmParser::parseEscapedString(std::string &Data) {
assert(getLexer().is(AsmToken::String) && "Unexpected current token!");
Data = "";
@@ -2129,14 +2177,14 @@ bool AsmParser::ParseEscapedString(std::string &Data) {
/// ::= ( .ascii | .asciz | .string ) [ "string" ( , "string" )* ]
bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- CheckForValidSection();
+ checkForValidSection();
for (;;) {
if (getLexer().isNot(AsmToken::String))
return TokError("expected string in '" + Twine(IDVal) + "' directive");
std::string Data;
- if (ParseEscapedString(Data))
+ if (parseEscapedString(Data))
return true;
getStreamer().EmitBytes(Data, DEFAULT_ADDRSPACE);
@@ -2162,12 +2210,12 @@ bool AsmParser::ParseDirectiveAscii(StringRef IDVal, bool ZeroTerminated) {
/// ::= (.byte | .short | ... ) [ expression (, expression)* ]
bool AsmParser::ParseDirectiveValue(unsigned Size) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- CheckForValidSection();
+ checkForValidSection();
for (;;) {
const MCExpr *Value;
SMLoc ExprLoc = getLexer().getLoc();
- if (ParseExpression(Value))
+ if (parseExpression(Value))
return true;
// Special case constant expressions to match code generator.
@@ -2198,7 +2246,7 @@ bool AsmParser::ParseDirectiveValue(unsigned Size) {
/// ::= (.single | .double) [ expression (, expression)* ]
bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
- CheckForValidSection();
+ checkForValidSection();
for (;;) {
// We don't truly support arithmetic on floating point expressions, so we
@@ -2255,16 +2303,16 @@ bool AsmParser::ParseDirectiveRealValue(const fltSemantics &Semantics) {
/// ParseDirectiveZero
/// ::= .zero expression
bool AsmParser::ParseDirectiveZero() {
- CheckForValidSection();
+ checkForValidSection();
int64_t NumBytes;
- if (ParseAbsoluteExpression(NumBytes))
+ if (parseAbsoluteExpression(NumBytes))
return true;
int64_t Val = 0;
if (getLexer().is(AsmToken::Comma)) {
Lex();
- if (ParseAbsoluteExpression(Val))
+ if (parseAbsoluteExpression(Val))
return true;
}
@@ -2281,10 +2329,10 @@ bool AsmParser::ParseDirectiveZero() {
/// ParseDirectiveFill
/// ::= .fill expression , expression , expression
bool AsmParser::ParseDirectiveFill() {
- CheckForValidSection();
+ checkForValidSection();
int64_t NumValues;
- if (ParseAbsoluteExpression(NumValues))
+ if (parseAbsoluteExpression(NumValues))
return true;
if (getLexer().isNot(AsmToken::Comma))
@@ -2292,7 +2340,7 @@ bool AsmParser::ParseDirectiveFill() {
Lex();
int64_t FillSize;
- if (ParseAbsoluteExpression(FillSize))
+ if (parseAbsoluteExpression(FillSize))
return true;
if (getLexer().isNot(AsmToken::Comma))
@@ -2300,7 +2348,7 @@ bool AsmParser::ParseDirectiveFill() {
Lex();
int64_t FillExpr;
- if (ParseAbsoluteExpression(FillExpr))
+ if (parseAbsoluteExpression(FillExpr))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -2320,11 +2368,11 @@ bool AsmParser::ParseDirectiveFill() {
/// ParseDirectiveOrg
/// ::= .org expression [ , expression ]
bool AsmParser::ParseDirectiveOrg() {
- CheckForValidSection();
+ checkForValidSection();
const MCExpr *Offset;
SMLoc Loc = getTok().getLoc();
- if (ParseExpression(Offset))
+ if (parseExpression(Offset))
return true;
// Parse optional fill expression.
@@ -2334,7 +2382,7 @@ bool AsmParser::ParseDirectiveOrg() {
return TokError("unexpected token in '.org' directive");
Lex();
- if (ParseAbsoluteExpression(FillExpr))
+ if (parseAbsoluteExpression(FillExpr))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -2355,11 +2403,11 @@ bool AsmParser::ParseDirectiveOrg() {
/// ParseDirectiveAlign
/// ::= {.align, ...} expression [ , expression [ , expression ]]
bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
- CheckForValidSection();
+ checkForValidSection();
SMLoc AlignmentLoc = getLexer().getLoc();
int64_t Alignment;
- if (ParseAbsoluteExpression(Alignment))
+ if (parseAbsoluteExpression(Alignment))
return true;
SMLoc MaxBytesLoc;
@@ -2376,7 +2424,7 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
// .align 3,,4
if (getLexer().isNot(AsmToken::Comma)) {
HasFillExpr = true;
- if (ParseAbsoluteExpression(FillExpr))
+ if (parseAbsoluteExpression(FillExpr))
return true;
}
@@ -2386,7 +2434,7 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
Lex();
MaxBytesLoc = getLexer().getLoc();
- if (ParseAbsoluteExpression(MaxBytesToFill))
+ if (parseAbsoluteExpression(MaxBytesToFill))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -2408,6 +2456,10 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
}
Alignment = 1ULL << Alignment;
+ } else {
+ // Reject alignments that aren't a power of two, for gas compatibility.
+ if (!isPowerOf2_64(Alignment))
+ Error(AlignmentLoc, "alignment must be a power of 2");
}
// Diagnose non-sensical max bytes to align.
@@ -2556,7 +2608,7 @@ bool AsmParser::ParseDirectiveLoc() {
StringRef Name;
SMLoc Loc = getTok().getLoc();
- if (ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("unexpected token in '.loc' directive");
if (Name == "basic_block")
@@ -2568,7 +2620,7 @@ bool AsmParser::ParseDirectiveLoc() {
else if (Name == "is_stmt") {
Loc = getTok().getLoc();
const MCExpr *Value;
- if (ParseExpression(Value))
+ if (parseExpression(Value))
return true;
// The expression must be the constant 0 or 1.
if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
@@ -2587,7 +2639,7 @@ bool AsmParser::ParseDirectiveLoc() {
else if (Name == "isa") {
Loc = getTok().getLoc();
const MCExpr *Value;
- if (ParseExpression(Value))
+ if (parseExpression(Value))
return true;
// The expression must be a constant greater or equal to 0.
if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
@@ -2601,7 +2653,7 @@ bool AsmParser::ParseDirectiveLoc() {
}
}
else if (Name == "discriminator") {
- if (ParseAbsoluteExpression(Discriminator))
+ if (parseAbsoluteExpression(Discriminator))
return true;
}
else {
@@ -2632,7 +2684,7 @@ bool AsmParser::ParseDirectiveCFISections() {
bool EH = false;
bool Debug = false;
- if (ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("Expected an identifier");
if (Name == ".eh_frame")
@@ -2643,7 +2695,7 @@ bool AsmParser::ParseDirectiveCFISections() {
if (getLexer().is(AsmToken::Comma)) {
Lex();
- if (ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("Expected an identifier");
if (Name == ".eh_frame")
@@ -2680,7 +2732,7 @@ bool AsmParser::ParseRegisterOrRegisterNumber(int64_t &Register,
return true;
Register = getContext().getRegisterInfo().getDwarfRegNum(RegNo, true);
} else
- return ParseAbsoluteExpression(Register);
+ return parseAbsoluteExpression(Register);
return false;
}
@@ -2697,7 +2749,7 @@ bool AsmParser::ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
Lex();
int64_t Offset = 0;
- if (ParseAbsoluteExpression(Offset))
+ if (parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIDefCfa(Register, Offset);
@@ -2708,7 +2760,7 @@ bool AsmParser::ParseDirectiveCFIDefCfa(SMLoc DirectiveLoc) {
/// ::= .cfi_def_cfa_offset offset
bool AsmParser::ParseDirectiveCFIDefCfaOffset() {
int64_t Offset = 0;
- if (ParseAbsoluteExpression(Offset))
+ if (parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIDefCfaOffset(Offset);
@@ -2738,7 +2790,7 @@ bool AsmParser::ParseDirectiveCFIRegister(SMLoc DirectiveLoc) {
/// ::= .cfi_adjust_cfa_offset adjustment
bool AsmParser::ParseDirectiveCFIAdjustCfaOffset() {
int64_t Adjustment = 0;
- if (ParseAbsoluteExpression(Adjustment))
+ if (parseAbsoluteExpression(Adjustment))
return true;
getStreamer().EmitCFIAdjustCfaOffset(Adjustment);
@@ -2769,7 +2821,7 @@ bool AsmParser::ParseDirectiveCFIOffset(SMLoc DirectiveLoc) {
return TokError("unexpected token in directive");
Lex();
- if (ParseAbsoluteExpression(Offset))
+ if (parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIOffset(Register, Offset);
@@ -2789,7 +2841,7 @@ bool AsmParser::ParseDirectiveCFIRelOffset(SMLoc DirectiveLoc) {
Lex();
int64_t Offset = 0;
- if (ParseAbsoluteExpression(Offset))
+ if (parseAbsoluteExpression(Offset))
return true;
getStreamer().EmitCFIRelOffset(Register, Offset);
@@ -2824,7 +2876,7 @@ static bool isValidEncoding(int64_t Encoding) {
/// ::= .cfi_lsda encoding, [symbol_name]
bool AsmParser::ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
int64_t Encoding = 0;
- if (ParseAbsoluteExpression(Encoding))
+ if (parseAbsoluteExpression(Encoding))
return true;
if (Encoding == dwarf::DW_EH_PE_omit)
return false;
@@ -2837,7 +2889,7 @@ bool AsmParser::ParseDirectiveCFIPersonalityOrLsda(bool IsPersonality) {
Lex();
StringRef Name;
- if (ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("expected identifier in directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
@@ -2891,7 +2943,7 @@ bool AsmParser::ParseDirectiveCFIRestore(SMLoc DirectiveLoc) {
bool AsmParser::ParseDirectiveCFIEscape() {
std::string Values;
int64_t CurrValue;
- if (ParseAbsoluteExpression(CurrValue))
+ if (parseAbsoluteExpression(CurrValue))
return true;
Values.push_back((uint8_t)CurrValue);
@@ -2899,7 +2951,7 @@ bool AsmParser::ParseDirectiveCFIEscape() {
while (getLexer().is(AsmToken::Comma)) {
Lex();
- if (ParseAbsoluteExpression(CurrValue))
+ if (parseAbsoluteExpression(CurrValue))
return true;
Values.push_back((uint8_t)CurrValue);
@@ -2948,7 +3000,7 @@ bool AsmParser::ParseDirectiveMacrosOnOff(StringRef Directive) {
/// ::= .macro name [parameters]
bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) {
StringRef Name;
- if (ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("expected identifier in '.macro' directive");
MCAsmMacroParameters Parameters;
@@ -2958,7 +3010,7 @@ bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
MCAsmMacroParameter Parameter;
- if (ParseIdentifier(Parameter.first))
+ if (parseIdentifier(Parameter.first))
return TokError("expected identifier in '.macro' directive");
if (getLexer().is(AsmToken::Equal)) {
@@ -3000,7 +3052,7 @@ bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) {
}
// Otherwise, scan til the end of the statement.
- EatToEndOfStatement();
+ eatToEndOfStatement();
}
if (LookupMacro(Name)) {
@@ -3010,10 +3062,113 @@ bool AsmParser::ParseDirectiveMacro(SMLoc DirectiveLoc) {
const char *BodyStart = StartToken.getLoc().getPointer();
const char *BodyEnd = EndToken.getLoc().getPointer();
StringRef Body = StringRef(BodyStart, BodyEnd - BodyStart);
+ CheckForBadMacro(DirectiveLoc, Name, Body, Parameters);
DefineMacro(Name, MCAsmMacro(Name, Body, Parameters));
return false;
}
+/// CheckForBadMacro
+///
+/// With the support added for named parameters there may be code out there that
+/// is transitioning from positional parameters. In versions of gas that did
+/// not support named parameters they would be ignored on the macro defintion.
+/// But to support both styles of parameters this is not possible so if a macro
+/// defintion has named parameters but does not use them and has what appears
+/// to be positional parameters, strings like $1, $2, ... and $n, then issue a
+/// warning that the positional parameter found in body which have no effect.
+/// Hoping the developer will either remove the named parameters from the macro
+/// definiton so the positional parameters get used if that was what was
+/// intended or change the macro to use the named parameters. It is possible
+/// this warning will trigger when the none of the named parameters are used
+/// and the strings like $1 are infact to simply to be passed trough unchanged.
+void AsmParser::CheckForBadMacro(SMLoc DirectiveLoc, StringRef Name,
+ StringRef Body,
+ MCAsmMacroParameters Parameters) {
+ // If this macro is not defined with named parameters the warning we are
+ // checking for here doesn't apply.
+ unsigned NParameters = Parameters.size();
+ if (NParameters == 0)
+ return;
+
+ bool NamedParametersFound = false;
+ bool PositionalParametersFound = false;
+
+ // Look at the body of the macro for use of both the named parameters and what
+ // are likely to be positional parameters. This is what expandMacro() is
+ // doing when it finds the parameters in the body.
+ while (!Body.empty()) {
+ // Scan for the next possible parameter.
+ std::size_t End = Body.size(), Pos = 0;
+ for (; Pos != End; ++Pos) {
+ // Check for a substitution or escape.
+ // This macro is defined with parameters, look for \foo, \bar, etc.
+ if (Body[Pos] == '\\' && Pos + 1 != End)
+ break;
+
+ // This macro should have parameters, but look for $0, $1, ..., $n too.
+ if (Body[Pos] != '$' || Pos + 1 == End)
+ continue;
+ char Next = Body[Pos + 1];
+ if (Next == '$' || Next == 'n' ||
+ isdigit(static_cast<unsigned char>(Next)))
+ break;
+ }
+
+ // Check if we reached the end.
+ if (Pos == End)
+ break;
+
+ if (Body[Pos] == '$') {
+ switch (Body[Pos+1]) {
+ // $$ => $
+ case '$':
+ break;
+
+ // $n => number of arguments
+ case 'n':
+ PositionalParametersFound = true;
+ break;
+
+ // $[0-9] => argument
+ default: {
+ PositionalParametersFound = true;
+ break;
+ }
+ }
+ Pos += 2;
+ } else {
+ unsigned I = Pos + 1;
+ while (isIdentifierChar(Body[I]) && I + 1 != End)
+ ++I;
+
+ const char *Begin = Body.data() + Pos +1;
+ StringRef Argument(Begin, I - (Pos +1));
+ unsigned Index = 0;
+ for (; Index < NParameters; ++Index)
+ if (Parameters[Index].first == Argument)
+ break;
+
+ if (Index == NParameters) {
+ if (Body[Pos+1] == '(' && Body[Pos+2] == ')')
+ Pos += 3;
+ else {
+ Pos = I;
+ }
+ } else {
+ NamedParametersFound = true;
+ Pos += 1 + Argument.size();
+ }
+ }
+ // Update the scan point.
+ Body = Body.substr(Pos);
+ }
+
+ if (!NamedParametersFound && PositionalParametersFound)
+ Warning(DirectiveLoc, "macro defined with named parameters which are not "
+ "used in macro body, possible positional parameter "
+ "found in body which will have no effect");
+}
+
/// ParseDirectiveEndMacro
/// ::= .endm
/// ::= .endmacro
@@ -3038,7 +3193,7 @@ bool AsmParser::ParseDirectiveEndMacro(StringRef Directive) {
/// ::= .purgem
bool AsmParser::ParseDirectivePurgeMacro(SMLoc DirectiveLoc) {
StringRef Name;
- if (ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("expected identifier in '.purgem' directive");
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -3054,13 +3209,13 @@ bool AsmParser::ParseDirectivePurgeMacro(SMLoc DirectiveLoc) {
/// ParseDirectiveBundleAlignMode
/// ::= {.bundle_align_mode} expression
bool AsmParser::ParseDirectiveBundleAlignMode() {
- CheckForValidSection();
+ checkForValidSection();
// Expect a single argument: an expression that evaluates to a constant
// in the inclusive range 0-30.
SMLoc ExprLoc = getLexer().getLoc();
int64_t AlignSizePow2;
- if (ParseAbsoluteExpression(AlignSizePow2))
+ if (parseAbsoluteExpression(AlignSizePow2))
return true;
else if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token after expression in"
@@ -3080,7 +3235,7 @@ bool AsmParser::ParseDirectiveBundleAlignMode() {
/// ParseDirectiveBundleLock
/// ::= {.bundle_lock} [align_to_end]
bool AsmParser::ParseDirectiveBundleLock() {
- CheckForValidSection();
+ checkForValidSection();
bool AlignToEnd = false;
if (getLexer().isNot(AsmToken::EndOfStatement)) {
@@ -3089,7 +3244,7 @@ bool AsmParser::ParseDirectiveBundleLock() {
const char *kInvalidOptionError =
"invalid option for '.bundle_lock' directive";
- if (ParseIdentifier(Option))
+ if (parseIdentifier(Option))
return Error(Loc, kInvalidOptionError);
if (Option != "align_to_end")
@@ -3109,7 +3264,7 @@ bool AsmParser::ParseDirectiveBundleLock() {
/// ParseDirectiveBundleLock
/// ::= {.bundle_lock}
bool AsmParser::ParseDirectiveBundleUnlock() {
- CheckForValidSection();
+ checkForValidSection();
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.bundle_unlock' directive");
@@ -3122,10 +3277,10 @@ bool AsmParser::ParseDirectiveBundleUnlock() {
/// ParseDirectiveSpace
/// ::= (.skip | .space) expression [ , expression ]
bool AsmParser::ParseDirectiveSpace(StringRef IDVal) {
- CheckForValidSection();
+ checkForValidSection();
int64_t NumBytes;
- if (ParseAbsoluteExpression(NumBytes))
+ if (parseAbsoluteExpression(NumBytes))
return true;
int64_t FillExpr = 0;
@@ -3134,7 +3289,7 @@ bool AsmParser::ParseDirectiveSpace(StringRef IDVal) {
return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
Lex();
- if (ParseAbsoluteExpression(FillExpr))
+ if (parseAbsoluteExpression(FillExpr))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -3156,10 +3311,10 @@ bool AsmParser::ParseDirectiveSpace(StringRef IDVal) {
/// ParseDirectiveLEB128
/// ::= (.sleb128 | .uleb128) expression
bool AsmParser::ParseDirectiveLEB128(bool Signed) {
- CheckForValidSection();
+ checkForValidSection();
const MCExpr *Value;
- if (ParseExpression(Value))
+ if (parseExpression(Value))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -3181,7 +3336,7 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
StringRef Name;
SMLoc Loc = getTok().getLoc();
- if (ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return Error(Loc, "expected identifier in directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
@@ -3208,11 +3363,11 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
/// ParseDirectiveComm
/// ::= ( .comm | .lcomm ) identifier , size_expression [ , align_expression ]
bool AsmParser::ParseDirectiveComm(bool IsLocal) {
- CheckForValidSection();
+ checkForValidSection();
SMLoc IDLoc = getLexer().getLoc();
StringRef Name;
- if (ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("expected identifier in directive");
// Handle the identifier as the key symbol.
@@ -3224,7 +3379,7 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) {
int64_t Size;
SMLoc SizeLoc = getLexer().getLoc();
- if (ParseAbsoluteExpression(Size))
+ if (parseAbsoluteExpression(Size))
return true;
int64_t Pow2Alignment = 0;
@@ -3232,7 +3387,7 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) {
if (getLexer().is(AsmToken::Comma)) {
Lex();
Pow2AlignmentLoc = getLexer().getLoc();
- if (ParseAbsoluteExpression(Pow2Alignment))
+ if (parseAbsoluteExpression(Pow2Alignment))
return true;
LCOMM::LCOMMType LCOMM = Lexer.getMAI().getLCOMMDirectiveAlignmentType();
@@ -3285,7 +3440,7 @@ bool AsmParser::ParseDirectiveAbort() {
// FIXME: Use loc from directive.
SMLoc Loc = getLexer().getLoc();
- StringRef Str = ParseStringToEndOfStatement();
+ StringRef Str = parseStringToEndOfStatement();
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.abort' directive");
@@ -3357,10 +3512,10 @@ bool AsmParser::ParseDirectiveIf(SMLoc DirectiveLoc) {
TheCondStack.push_back(TheCondState);
TheCondState.TheCond = AsmCond::IfCond;
if (TheCondState.Ignore) {
- EatToEndOfStatement();
+ eatToEndOfStatement();
} else {
int64_t ExprValue;
- if (ParseAbsoluteExpression(ExprValue))
+ if (parseAbsoluteExpression(ExprValue))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -3382,9 +3537,9 @@ bool AsmParser::ParseDirectiveIfb(SMLoc DirectiveLoc, bool ExpectBlank) {
TheCondState.TheCond = AsmCond::IfCond;
if (TheCondState.Ignore) {
- EatToEndOfStatement();
+ eatToEndOfStatement();
} else {
- StringRef Str = ParseStringToEndOfStatement();
+ StringRef Str = parseStringToEndOfStatement();
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.ifb' directive");
@@ -3405,7 +3560,7 @@ bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
TheCondState.TheCond = AsmCond::IfCond;
if (TheCondState.Ignore) {
- EatToEndOfStatement();
+ eatToEndOfStatement();
} else {
StringRef Str1 = ParseStringToComma();
@@ -3414,7 +3569,7 @@ bool AsmParser::ParseDirectiveIfc(SMLoc DirectiveLoc, bool ExpectEqual) {
Lex();
- StringRef Str2 = ParseStringToEndOfStatement();
+ StringRef Str2 = parseStringToEndOfStatement();
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.ifc' directive");
@@ -3436,9 +3591,9 @@ bool AsmParser::ParseDirectiveIfdef(SMLoc DirectiveLoc, bool expect_defined) {
TheCondState.TheCond = AsmCond::IfCond;
if (TheCondState.Ignore) {
- EatToEndOfStatement();
+ eatToEndOfStatement();
} else {
- if (ParseIdentifier(Name))
+ if (parseIdentifier(Name))
return TokError("expected identifier after '.ifdef'");
Lex();
@@ -3469,11 +3624,11 @@ bool AsmParser::ParseDirectiveElseIf(SMLoc DirectiveLoc) {
LastIgnoreState = TheCondStack.back().Ignore;
if (LastIgnoreState || TheCondState.CondMet) {
TheCondState.Ignore = true;
- EatToEndOfStatement();
+ eatToEndOfStatement();
}
else {
int64_t ExprValue;
- if (ParseAbsoluteExpression(ExprValue))
+ if (parseAbsoluteExpression(ExprValue))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -3667,7 +3822,7 @@ MCAsmMacro *AsmParser::ParseMacroLikeBody(SMLoc DirectiveLoc) {
}
// Otherwise, scan till the end of the statement.
- EatToEndOfStatement();
+ eatToEndOfStatement();
}
const char *BodyStart = StartToken.getLoc().getPointer();
@@ -3703,7 +3858,7 @@ void AsmParser::InstantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
bool AsmParser::ParseDirectiveRept(SMLoc DirectiveLoc) {
int64_t Count;
- if (ParseAbsoluteExpression(Count))
+ if (parseAbsoluteExpression(Count))
return TokError("unexpected token in '.rept' directive");
if (Count < 0)
@@ -3741,7 +3896,7 @@ bool AsmParser::ParseDirectiveIrp(SMLoc DirectiveLoc) {
MCAsmMacroParameters Parameters;
MCAsmMacroParameter Parameter;
- if (ParseIdentifier(Parameter.first))
+ if (parseIdentifier(Parameter.first))
return TokError("expected identifier in '.irp' directive");
Parameters.push_back(Parameter);
@@ -3787,7 +3942,7 @@ bool AsmParser::ParseDirectiveIrpc(SMLoc DirectiveLoc) {
MCAsmMacroParameters Parameters;
MCAsmMacroParameter Parameter;
- if (ParseIdentifier(Parameter.first))
+ if (parseIdentifier(Parameter.first))
return TokError("expected identifier in '.irpc' directive");
Parameters.push_back(Parameter);
@@ -3847,10 +4002,11 @@ bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) {
return false;
}
-bool AsmParser::ParseDirectiveEmit(SMLoc IDLoc, ParseStatementInfo &Info) {
+bool AsmParser::ParseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info,
+ size_t Len) {
const MCExpr *Value;
SMLoc ExprLoc = getLexer().getLoc();
- if (ParseExpression(Value))
+ if (parseExpression(Value))
return true;
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
if (!MCE)
@@ -3859,27 +4015,71 @@ bool AsmParser::ParseDirectiveEmit(SMLoc IDLoc, ParseStatementInfo &Info) {
if (!isUIntN(8, IntValue) && !isIntN(8, IntValue))
return Error(ExprLoc, "literal value out of range for directive");
- Info.AsmRewrites->push_back(AsmRewrite(AOK_Emit, IDLoc, 5));
+ Info.AsmRewrites->push_back(AsmRewrite(AOK_Emit, IDLoc, Len));
return false;
}
-bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
- unsigned &NumOutputs, unsigned &NumInputs,
- SmallVectorImpl<std::pair<void *, bool> > &OpDecls,
- SmallVectorImpl<std::string> &Constraints,
- SmallVectorImpl<std::string> &Clobbers,
- const MCInstrInfo *MII,
- const MCInstPrinter *IP,
- MCAsmParserSemaCallback &SI) {
+bool AsmParser::ParseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
+ const MCExpr *Value;
+ SMLoc ExprLoc = getLexer().getLoc();
+ if (parseExpression(Value))
+ return true;
+ const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
+ if (!MCE)
+ return Error(ExprLoc, "unexpected expression in align");
+ uint64_t IntValue = MCE->getValue();
+ if (!isPowerOf2_64(IntValue))
+ return Error(ExprLoc, "literal value not a power of two greater then zero");
+
+ Info.AsmRewrites->push_back(AsmRewrite(AOK_Align, IDLoc, 5,
+ Log2_64(IntValue)));
+ return false;
+}
+
+// We are comparing pointers, but the pointers are relative to a single string.
+// Thus, this should always be deterministic.
+static int RewritesSort(const void *A, const void *B) {
+ const AsmRewrite *AsmRewriteA = static_cast<const AsmRewrite *>(A);
+ const AsmRewrite *AsmRewriteB = static_cast<const AsmRewrite *>(B);
+ if (AsmRewriteA->Loc.getPointer() < AsmRewriteB->Loc.getPointer())
+ return -1;
+ if (AsmRewriteB->Loc.getPointer() < AsmRewriteA->Loc.getPointer())
+ return 1;
+
+ // It's possible to have a SizeDirective rewrite and an Input/Output rewrite
+ // to the same location. Make sure the SizeDirective rewrite is performed
+ // first. This also ensure the sort algorithm is stable.
+ if (AsmRewriteA->Kind == AOK_SizeDirective) {
+ assert ((AsmRewriteB->Kind == AOK_Input || AsmRewriteB->Kind == AOK_Output) &&
+ "Expected an Input/Output rewrite!");
+ return -1;
+ }
+ if (AsmRewriteB->Kind == AOK_SizeDirective) {
+ assert ((AsmRewriteA->Kind == AOK_Input || AsmRewriteA->Kind == AOK_Output) &&
+ "Expected an Input/Output rewrite!");
+ return 1;
+ }
+ llvm_unreachable ("Unstable rewrite sort.");
+}
+
+bool
+AsmParser::parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
+ unsigned &NumOutputs, unsigned &NumInputs,
+ SmallVectorImpl<std::pair<void *, bool> > &OpDecls,
+ SmallVectorImpl<std::string> &Constraints,
+ SmallVectorImpl<std::string> &Clobbers,
+ const MCInstrInfo *MII,
+ const MCInstPrinter *IP,
+ MCAsmParserSemaCallback &SI) {
SmallVector<void *, 4> InputDecls;
SmallVector<void *, 4> OutputDecls;
SmallVector<bool, 4> InputDeclsAddressOf;
SmallVector<bool, 4> OutputDeclsAddressOf;
SmallVector<std::string, 4> InputConstraints;
SmallVector<std::string, 4> OutputConstraints;
- std::set<std::string> ClobberRegs;
+ SmallVector<unsigned, 4> ClobberRegs;
- SmallVector<struct AsmRewrite, 4> AsmStrRewrites;
+ SmallVector<AsmRewrite, 4> AsmStrRewrites;
// Prime the lexer.
Lex();
@@ -3895,65 +4095,60 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
if (Info.ParseError)
return true;
- if (Info.Opcode != ~0U) {
- const MCInstrDesc &Desc = MII->get(Info.Opcode);
+ if (Info.Opcode == ~0U)
+ continue;
- // Build the list of clobbers, outputs and inputs.
- for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
- MCParsedAsmOperand *Operand = Info.ParsedOperands[i];
+ const MCInstrDesc &Desc = MII->get(Info.Opcode);
- // Immediate.
- if (Operand->isImm()) {
- if (Operand->needAsmRewrite())
- AsmStrRewrites.push_back(AsmRewrite(AOK_ImmPrefix,
- Operand->getStartLoc()));
- continue;
- }
+ // Build the list of clobbers, outputs and inputs.
+ for (unsigned i = 1, e = Info.ParsedOperands.size(); i != e; ++i) {
+ MCParsedAsmOperand *Operand = Info.ParsedOperands[i];
- // Register operand.
- if (Operand->isReg() && !Operand->needAddressOf()) {
- unsigned NumDefs = Desc.getNumDefs();
- // Clobber.
- if (NumDefs && Operand->getMCOperandNum() < NumDefs) {
- std::string Reg;
- raw_string_ostream OS(Reg);
- IP->printRegName(OS, Operand->getReg());
- ClobberRegs.insert(StringRef(OS.str()));
- }
- continue;
- }
+ // Immediate.
+ if (Operand->isImm()) {
+ if (Operand->needAsmRewrite())
+ AsmStrRewrites.push_back(AsmRewrite(AOK_ImmPrefix,
+ Operand->getStartLoc()));
+ continue;
+ }
- // Expr/Input or Output.
- unsigned Size;
- bool IsVarDecl;
- void *OpDecl = SI.LookupInlineAsmIdentifier(Operand->getName(), AsmLoc,
- Size, IsVarDecl);
- if (OpDecl) {
- bool isOutput = (i == 1) && Desc.mayStore();
- if (Operand->isMem() && Operand->needSizeDirective())
- AsmStrRewrites.push_back(AsmRewrite(AOK_SizeDirective,
- Operand->getStartLoc(),
- /*Len*/0,
- Operand->getMemSize()));
- if (isOutput) {
- std::string Constraint = "=";
- ++InputIdx;
- OutputDecls.push_back(OpDecl);
- OutputDeclsAddressOf.push_back(Operand->needAddressOf());
- Constraint += Operand->getConstraint().str();
- OutputConstraints.push_back(Constraint);
- AsmStrRewrites.push_back(AsmRewrite(AOK_Output,
- Operand->getStartLoc(),
- Operand->getNameLen()));
- } else {
- InputDecls.push_back(OpDecl);
- InputDeclsAddressOf.push_back(Operand->needAddressOf());
- InputConstraints.push_back(Operand->getConstraint().str());
- AsmStrRewrites.push_back(AsmRewrite(AOK_Input,
- Operand->getStartLoc(),
- Operand->getNameLen()));
- }
- }
+ // Register operand.
+ if (Operand->isReg() && !Operand->needAddressOf()) {
+ unsigned NumDefs = Desc.getNumDefs();
+ // Clobber.
+ if (NumDefs && Operand->getMCOperandNum() < NumDefs)
+ ClobberRegs.push_back(Operand->getReg());
+ continue;
+ }
+
+ // Expr/Input or Output.
+ bool IsVarDecl;
+ unsigned Length, Size, Type;
+ void *OpDecl = SI.LookupInlineAsmIdentifier(Operand->getName(), AsmLoc,
+ Length, Size, Type,
+ IsVarDecl);
+ if (!OpDecl)
+ continue;
+
+ bool isOutput = (i == 1) && Desc.mayStore();
+ if (Operand->isMem() && Operand->needSizeDirective())
+ AsmStrRewrites.push_back(AsmRewrite(AOK_SizeDirective,
+ Operand->getStartLoc(), /*Len*/0,
+ Operand->getMemSize()));
+
+ if (isOutput) {
+ ++InputIdx;
+ OutputDecls.push_back(OpDecl);
+ OutputDeclsAddressOf.push_back(Operand->needAddressOf());
+ OutputConstraints.push_back('=' + Operand->getConstraint().str());
+ AsmStrRewrites.push_back(AsmRewrite(AOK_Output, Operand->getStartLoc(),
+ Operand->getNameLen()));
+ } else {
+ InputDecls.push_back(OpDecl);
+ InputDeclsAddressOf.push_back(Operand->needAddressOf());
+ InputConstraints.push_back(Operand->getConstraint().str());
+ AsmStrRewrites.push_back(AsmRewrite(AOK_Input, Operand->getStartLoc(),
+ Operand->getNameLen()));
}
}
}
@@ -3963,9 +4158,14 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
NumInputs = InputDecls.size();
// Set the unique clobbers.
- for (std::set<std::string>::iterator I = ClobberRegs.begin(),
- E = ClobberRegs.end(); I != E; ++I)
- Clobbers.push_back(*I);
+ array_pod_sort(ClobberRegs.begin(), ClobberRegs.end());
+ ClobberRegs.erase(std::unique(ClobberRegs.begin(), ClobberRegs.end()),
+ ClobberRegs.end());
+ Clobbers.assign(ClobberRegs.size(), std::string());
+ for (unsigned I = 0, E = ClobberRegs.size(); I != E; ++I) {
+ raw_string_ostream OS(Clobbers[I]);
+ IP->printRegName(OS, ClobberRegs[I]);
+ }
// Merge the various outputs and inputs. Output are expected first.
if (NumOutputs || NumInputs) {
@@ -3987,10 +4187,14 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
AsmRewriteKind PrevKind = AOK_Imm;
raw_string_ostream OS(AsmStringIR);
const char *Start = SrcMgr.getMemoryBuffer(0)->getBufferStart();
- for (SmallVectorImpl<struct AsmRewrite>::iterator
- I = AsmStrRewrites.begin(), E = AsmStrRewrites.end(); I != E; ++I) {
+ array_pod_sort(AsmStrRewrites.begin(), AsmStrRewrites.end(), RewritesSort);
+ for (SmallVectorImpl<AsmRewrite>::iterator I = AsmStrRewrites.begin(),
+ E = AsmStrRewrites.end();
+ I != E; ++I) {
const char *Loc = (*I).Loc.getPointer();
+ assert(Loc >= Start && "Expected Loc to be after Start!");
+ unsigned AdditionalSkip = 0;
AsmRewriteKind Kind = (*I).Kind;
// Emit everything up to the immediate/expression. If the previous rewrite
@@ -4009,22 +4213,19 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
switch (Kind) {
default: break;
case AOK_Imm:
- OS << Twine("$$");
- OS << (*I).Val;
+ OS << "$$" << (*I).Val;
break;
case AOK_ImmPrefix:
- OS << Twine("$$");
+ OS << "$$";
break;
case AOK_Input:
- OS << '$';
- OS << InputIdx++;
+ OS << '$' << InputIdx++;
break;
case AOK_Output:
- OS << '$';
- OS << OutputIdx++;
+ OS << '$' << OutputIdx++;
break;
case AOK_SizeDirective:
- switch((*I).Val) {
+ switch ((*I).Val) {
default: break;
case 8: OS << "byte ptr "; break;
case 16: OS << "word ptr "; break;
@@ -4038,6 +4239,15 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
case AOK_Emit:
OS << ".byte";
break;
+ case AOK_Align: {
+ unsigned Val = (*I).Val;
+ OS << ".align " << Val;
+
+ // Skip the original immediate.
+ assert(Val < 10 && "Expected alignment less then 2^10.");
+ AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
+ break;
+ }
case AOK_DotOperator:
OS << (*I).Val;
break;
@@ -4045,7 +4255,7 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
// Skip the original expression.
if (Kind != AOK_SizeDirective)
- Start = Loc + (*I).Len;
+ Start = Loc + (*I).Len + AdditionalSkip;
}
// Emit the remainder of the asm string.
diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp
index e7c564a243..a50eab217d 100644
--- a/lib/MC/MCParser/COFFAsmParser.cpp
+++ b/lib/MC/MCParser/COFFAsmParser.cpp
@@ -24,10 +24,11 @@ using namespace llvm;
namespace {
class COFFAsmParser : public MCAsmParserExtension {
- template<bool (COFFAsmParser::*Handler)(StringRef, SMLoc)>
- void AddDirectiveHandler(StringRef Directive) {
- getParser().AddDirectiveHandler(this, Directive,
- HandleDirective<COFFAsmParser, Handler>);
+ template<bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
+ void addDirectiveHandler(StringRef Directive) {
+ MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
+ this, HandleDirective<COFFAsmParser, HandlerMethod>);
+ getParser().addDirectiveHandler(Directive, Handler);
}
bool ParseSectionSwitch(StringRef Section,
@@ -38,43 +39,43 @@ class COFFAsmParser : public MCAsmParserExtension {
// Call the base implementation.
MCAsmParserExtension::Initialize(Parser);
- AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
- AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
- AddDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
+ addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
+ addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
+ addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
// Win64 EH directives.
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
".seh_proc");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
".seh_endproc");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
".seh_startchained");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
".seh_endchained");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
".seh_handler");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
".seh_handlerdata");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
".seh_pushreg");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
".seh_setframe");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
".seh_stackalloc");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
".seh_savereg");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
".seh_savexmm");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
".seh_pushframe");
- AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
+ addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
".seh_endprologue");
- AddDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
+ addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
}
bool ParseSectionDirectiveText(StringRef, SMLoc) {
@@ -140,7 +141,7 @@ bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
for (;;) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
@@ -176,7 +177,7 @@ bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
StringRef SymbolName;
- if (getParser().ParseIdentifier(SymbolName))
+ if (getParser().parseIdentifier(SymbolName))
return TokError("expected identifier in directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
@@ -189,7 +190,7 @@ bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
int64_t SymbolStorageClass;
- if (getParser().ParseAbsoluteExpression(SymbolStorageClass))
+ if (getParser().parseAbsoluteExpression(SymbolStorageClass))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -202,7 +203,7 @@ bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
int64_t Type;
- if (getParser().ParseAbsoluteExpression(Type))
+ if (getParser().parseAbsoluteExpression(Type))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -221,7 +222,7 @@ bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
StringRef SymbolID;
- if (getParser().ParseIdentifier(SymbolID))
+ if (getParser().parseIdentifier(SymbolID))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -236,7 +237,7 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
StringRef SymbolID;
- if (getParser().ParseIdentifier(SymbolID))
+ if (getParser().parseIdentifier(SymbolID))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -269,7 +270,7 @@ bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
StringRef SymbolID;
- if (getParser().ParseIdentifier(SymbolID))
+ if (getParser().parseIdentifier(SymbolID))
return true;
if (getLexer().isNot(AsmToken::Comma))
@@ -322,7 +323,7 @@ bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
Lex();
SMLoc startLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Off))
+ if (getParser().parseAbsoluteExpression(Off))
return true;
if (Off & 0x0F)
@@ -339,7 +340,7 @@ bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
int64_t Size;
SMLoc startLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Size))
+ if (getParser().parseAbsoluteExpression(Size))
return true;
if (Size & 7)
@@ -363,7 +364,7 @@ bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
Lex();
SMLoc startLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Off))
+ if (getParser().parseAbsoluteExpression(Off))
return true;
if (Off & 7)
@@ -390,7 +391,7 @@ bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
Lex();
SMLoc startLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Off))
+ if (getParser().parseAbsoluteExpression(Off))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -411,7 +412,7 @@ bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) {
if (getLexer().is(AsmToken::At)) {
SMLoc startLoc = getLexer().getLoc();
Lex();
- if (!getParser().ParseIdentifier(CodeID)) {
+ if (!getParser().parseIdentifier(CodeID)) {
if (CodeID != "code")
return Error(startLoc, "expected @code");
Code = true;
@@ -438,7 +439,7 @@ bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
return TokError("a handler attribute must begin with '@'");
SMLoc startLoc = getLexer().getLoc();
Lex();
- if (getParser().ParseIdentifier(identifier))
+ if (getParser().parseIdentifier(identifier))
return Error(startLoc, "expected @unwind or @except");
if (identifier == "unwind")
unwind = true;
@@ -479,7 +480,7 @@ bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
}
else {
int64_t n;
- if (getParser().ParseAbsoluteExpression(n))
+ if (getParser().parseAbsoluteExpression(n))
return true;
if (n > 15)
return Error(startLoc, "register number is too high");
diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp
index 7b042df292..6d6409fb69 100644
--- a/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -26,10 +26,11 @@ namespace {
/// \brief Implementation of directive handling which is shared across all
/// Darwin targets.
class DarwinAsmParser : public MCAsmParserExtension {
- template<bool (DarwinAsmParser::*Handler)(StringRef, SMLoc)>
- void AddDirectiveHandler(StringRef Directive) {
- getParser().AddDirectiveHandler(this, Directive,
- HandleDirective<DarwinAsmParser, Handler>);
+ template<bool (DarwinAsmParser::*HandlerMethod)(StringRef, SMLoc)>
+ void addDirectiveHandler(StringRef Directive) {
+ MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
+ this, HandleDirective<DarwinAsmParser, HandlerMethod>);
+ getParser().addDirectiveHandler(Directive, Handler);
}
bool ParseSectionSwitch(const char *Segment, const char *Section,
@@ -43,77 +44,128 @@ public:
// Call the base implementation.
this->MCAsmParserExtension::Initialize(Parser);
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
".subsections_via_symbols");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(".pushsection");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(".popsection");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".dump");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDumpOrLoad>(".load");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSection>(".section");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectivePushSection>(
+ ".pushsection");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectivePopSection>(
+ ".popsection");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectivePrevious>(".previous");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogUnique>(
".secure_log_unique");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSecureLogReset>(
".secure_log_reset");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveTBSS>(".tbss");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveZerofill>(".zerofill");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(".data_region");
- AddDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(".end_data_region");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegion>(
+ ".data_region");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDataRegionEnd>(
+ ".end_data_region");
// Special section directives.
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(".const_data");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(".constructor");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(".cstring");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(".destructor");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(".fvmlib_init0");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(".fvmlib_init1");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(".lazy_symbol_pointer");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(".literal16");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(".literal4");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(".literal8");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(".mod_init_func");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(".mod_term_func");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(".non_lazy_symbol_pointer");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(".objc_cat_cls_meth");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(".objc_cat_inst_meth");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(".objc_category");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(".objc_class");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(".objc_class_names");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(".objc_class_vars");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(".objc_cls_meth");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(".objc_cls_refs");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(".objc_inst_meth");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(".objc_instance_vars");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(".objc_message_refs");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(".objc_meta_class");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(".objc_meth_var_names");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(".objc_meth_var_types");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(".objc_module_info");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(".objc_protocol");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(".objc_selector_strs");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(".objc_string_object");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(".objc_symbols");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(".picsymbol_stub");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(".static_const");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(".static_data");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(".symbol_stub");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(".thread_init_func");
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
-
- AddDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConst>(".const");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstData>(
+ ".const_data");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveConstructor>(
+ ".constructor");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveCString>(
+ ".cstring");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveData>(".data");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDestructor>(
+ ".destructor");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveDyld>(".dyld");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit0>(
+ ".fvmlib_init0");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveFVMLibInit1>(
+ ".fvmlib_init1");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveLazySymbolPointers>(
+ ".lazy_symbol_pointer");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLinkerOption>(
+ ".linker_option");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral16>(
+ ".literal16");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral4>(
+ ".literal4");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveLiteral8>(
+ ".literal8");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModInitFunc>(
+ ".mod_init_func");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveModTermFunc>(
+ ".mod_term_func");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveNonLazySymbolPointers>(
+ ".non_lazy_symbol_pointer");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatClsMeth>(
+ ".objc_cat_cls_meth");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCatInstMeth>(
+ ".objc_cat_inst_meth");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCCategory>(
+ ".objc_category");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClass>(
+ ".objc_class");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassNames>(
+ ".objc_class_names");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClassVars>(
+ ".objc_class_vars");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsMeth>(
+ ".objc_cls_meth");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCClsRefs>(
+ ".objc_cls_refs");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCInstMeth>(
+ ".objc_inst_meth");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveObjCInstanceVars>(
+ ".objc_instance_vars");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMessageRefs>(
+ ".objc_message_refs");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCMetaClass>(
+ ".objc_meta_class");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveObjCMethVarNames>(
+ ".objc_meth_var_names");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveObjCMethVarTypes>(
+ ".objc_meth_var_types");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCModuleInfo>(
+ ".objc_module_info");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCProtocol>(
+ ".objc_protocol");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveObjCSelectorStrs>(
+ ".objc_selector_strs");
+ addDirectiveHandler<
+ &DarwinAsmParser::ParseSectionDirectiveObjCStringObject>(
+ ".objc_string_object");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveObjCSymbols>(
+ ".objc_symbols");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectivePICSymbolStub>(
+ ".picsymbol_stub");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticConst>(
+ ".static_const");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveStaticData>(
+ ".static_data");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveSymbolStub>(
+ ".symbol_stub");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTData>(".tdata");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveText>(".text");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveThreadInitFunc>(
+ ".thread_init_func");
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveTLV>(".tlv");
+
+ addDirectiveHandler<&DarwinAsmParser::ParseSectionDirectiveIdent>(".ident");
}
bool ParseDirectiveDesc(StringRef, SMLoc);
bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
bool ParseDirectiveLsym(StringRef, SMLoc);
+ bool ParseDirectiveLinkerOption(StringRef, SMLoc);
bool ParseDirectiveSection(StringRef, SMLoc);
bool ParseDirectivePushSection(StringRef, SMLoc);
bool ParseDirectivePopSection(StringRef, SMLoc);
@@ -293,7 +345,7 @@ public:
}
bool ParseSectionDirectiveIdent(StringRef, SMLoc) {
// Darwin silently ignores the .ident directive.
- getParser().EatToEndOfStatement();
+ getParser().eatToEndOfStatement();
return false;
}
bool ParseSectionDirectiveThreadInitFunc(StringRef, SMLoc) {
@@ -338,7 +390,7 @@ bool DarwinAsmParser::ParseSectionSwitch(const char *Segment,
/// ::= .desc identifier , expression
bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
// Handle the identifier as the key symbol.
@@ -349,7 +401,7 @@ bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
Lex();
int64_t DescValue;
- if (getParser().ParseAbsoluteExpression(DescValue))
+ if (getParser().parseAbsoluteExpression(DescValue))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -386,11 +438,38 @@ bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,
return Warning(IDLoc, "ignoring directive .load for now");
}
+/// ParseDirectiveLinkerOption
+/// ::= .linker_option "string" ( , "string" )*
+bool DarwinAsmParser::ParseDirectiveLinkerOption(StringRef IDVal, SMLoc) {
+ SmallVector<std::string, 4> Args;
+ for (;;) {
+ if (getLexer().isNot(AsmToken::String))
+ return TokError("expected string in '" + Twine(IDVal) + "' directive");
+
+ std::string Data;
+ if (getParser().parseEscapedString(Data))
+ return true;
+
+ Args.push_back(Data);
+
+ Lex();
+ if (getLexer().is(AsmToken::EndOfStatement))
+ break;
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("unexpected token in '" + Twine(IDVal) + "' directive");
+ Lex();
+ }
+
+ getStreamer().EmitLinkerOptions(Args);
+ return false;
+}
+
/// ParseDirectiveLsym
/// ::= .lsym identifier , expression
bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
// Handle the identifier as the key symbol.
@@ -401,7 +480,7 @@ bool DarwinAsmParser::ParseDirectiveLsym(StringRef, SMLoc) {
Lex();
const MCExpr *Value;
- if (getParser().ParseExpression(Value))
+ if (getParser().parseExpression(Value))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -422,7 +501,7 @@ bool DarwinAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
SMLoc Loc = getLexer().getLoc();
StringRef SectionName;
- if (getParser().ParseIdentifier(SectionName))
+ if (getParser().parseIdentifier(SectionName))
return Error(Loc, "expected identifier after '.section' directive");
// Verify there is a following comma.
@@ -497,7 +576,7 @@ bool DarwinAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
/// ParseDirectiveSecureLogUnique
/// ::= .secure_log_unique ... message ...
bool DarwinAsmParser::ParseDirectiveSecureLogUnique(StringRef, SMLoc IDLoc) {
- StringRef LogMessage = getParser().ParseStringToEndOfStatement();
+ StringRef LogMessage = getParser().parseStringToEndOfStatement();
if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.secure_log_unique' directive");
@@ -565,7 +644,7 @@ bool DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols(StringRef, SMLoc) {
bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
SMLoc IDLoc = getLexer().getLoc();
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
// Handle the identifier as the key symbol.
@@ -577,7 +656,7 @@ bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
int64_t Size;
SMLoc SizeLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Size))
+ if (getParser().parseAbsoluteExpression(Size))
return true;
int64_t Pow2Alignment = 0;
@@ -585,7 +664,7 @@ bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
if (getLexer().is(AsmToken::Comma)) {
Lex();
Pow2AlignmentLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Pow2Alignment))
+ if (getParser().parseAbsoluteExpression(Pow2Alignment))
return true;
}
@@ -620,7 +699,7 @@ bool DarwinAsmParser::ParseDirectiveTBSS(StringRef, SMLoc) {
/// , align_expression ]]
bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
StringRef Segment;
- if (getParser().ParseIdentifier(Segment))
+ if (getParser().parseIdentifier(Segment))
return TokError("expected segment name after '.zerofill' directive");
if (getLexer().isNot(AsmToken::Comma))
@@ -628,7 +707,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
Lex();
StringRef Section;
- if (getParser().ParseIdentifier(Section))
+ if (getParser().parseIdentifier(Section))
return TokError("expected section name after comma in '.zerofill' "
"directive");
@@ -648,7 +727,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
SMLoc IDLoc = getLexer().getLoc();
StringRef IDStr;
- if (getParser().ParseIdentifier(IDStr))
+ if (getParser().parseIdentifier(IDStr))
return TokError("expected identifier in directive");
// handle the identifier as the key symbol.
@@ -660,7 +739,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
int64_t Size;
SMLoc SizeLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Size))
+ if (getParser().parseAbsoluteExpression(Size))
return true;
int64_t Pow2Alignment = 0;
@@ -668,7 +747,7 @@ bool DarwinAsmParser::ParseDirectiveZerofill(StringRef, SMLoc) {
if (getLexer().is(AsmToken::Comma)) {
Lex();
Pow2AlignmentLoc = getLexer().getLoc();
- if (getParser().ParseAbsoluteExpression(Pow2Alignment))
+ if (getParser().parseAbsoluteExpression(Pow2Alignment))
return true;
}
@@ -712,7 +791,7 @@ bool DarwinAsmParser::ParseDirectiveDataRegion(StringRef, SMLoc) {
}
StringRef RegionType;
SMLoc Loc = getParser().getTok().getLoc();
- if (getParser().ParseIdentifier(RegionType))
+ if (getParser().parseIdentifier(RegionType))
return TokError("expected region type after '.data_region' directive");
int Kind = StringSwitch<int>(RegionType)
.Case("jt8", MCDR_DataRegionJT8)
diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp
index 87126f0e3e..4c45e08744 100644
--- a/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/lib/MC/MCParser/ELFAsmParser.cpp
@@ -22,10 +22,12 @@ using namespace llvm;
namespace {
class ELFAsmParser : public MCAsmParserExtension {
- template<bool (ELFAsmParser::*Handler)(StringRef, SMLoc)>
- void AddDirectiveHandler(StringRef Directive) {
- getParser().AddDirectiveHandler(this, Directive,
- HandleDirective<ELFAsmParser, Handler>);
+ template<bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
+ void addDirectiveHandler(StringRef Directive) {
+ MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
+ this, HandleDirective<ELFAsmParser, HandlerMethod>);
+
+ getParser().addDirectiveHandler(Directive, Handler);
}
bool ParseSectionSwitch(StringRef Section, unsigned Type,
@@ -41,38 +43,38 @@ public:
// Call the base implementation.
this->MCAsmParserExtension::Initialize(Parser);
- AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data");
- AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text");
- AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss");
- AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata");
- AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata");
- AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss");
- AddDirectiveHandler<
+ addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data");
+ addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text");
+ addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss");
+ addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata");
+ addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata");
+ addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss");
+ addDirectiveHandler<
&ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel");
- AddDirectiveHandler<
+ addDirectiveHandler<
&ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro");
- AddDirectiveHandler<
+ addDirectiveHandler<
&ELFAsmParser::ParseSectionDirectiveDataRelRoLocal>(".data.rel.ro.local");
- AddDirectiveHandler<
+ addDirectiveHandler<
&ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section");
- AddDirectiveHandler<
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section");
+ addDirectiveHandler<
&ELFAsmParser::ParseDirectivePushSection>(".pushsection");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
- AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local");
- AddDirectiveHandler<
+ addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local");
+ addDirectiveHandler<
&ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected");
- AddDirectiveHandler<
+ addDirectiveHandler<
&ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal");
- AddDirectiveHandler<
+ addDirectiveHandler<
&ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden");
}
@@ -167,7 +169,7 @@ bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
for (;;) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
@@ -201,7 +203,7 @@ bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
@@ -210,7 +212,7 @@ bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
Lex();
const MCExpr *Expr;
- if (getParser().ParseExpression(Expr))
+ if (getParser().parseExpression(Expr))
return true;
if (getLexer().isNot(AsmToken::EndOfStatement))
@@ -222,7 +224,7 @@ bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
// A section name can contain -, so we cannot just use
- // ParseIdentifier.
+ // parseIdentifier.
SMLoc FirstLoc = getLexer().getLoc();
unsigned Size = 0;
@@ -375,14 +377,14 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
return TokError("expected '@' or '%' before type");
Lex();
- if (getParser().ParseIdentifier(TypeName))
+ if (getParser().parseIdentifier(TypeName))
return TokError("expected identifier in directive");
if (Mergeable) {
if (getLexer().isNot(AsmToken::Comma))
return TokError("expected the entry size");
Lex();
- if (getParser().ParseAbsoluteExpression(Size))
+ if (getParser().parseAbsoluteExpression(Size))
return true;
if (Size <= 0)
return TokError("entry size must be positive");
@@ -392,12 +394,12 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
if (getLexer().isNot(AsmToken::Comma))
return TokError("expected group name");
Lex();
- if (getParser().ParseIdentifier(GroupName))
+ if (getParser().parseIdentifier(GroupName))
return true;
if (getLexer().is(AsmToken::Comma)) {
Lex();
StringRef Linkage;
- if (getParser().ParseIdentifier(Linkage))
+ if (getParser().parseIdentifier(Linkage))
return true;
if (Linkage != "comdat")
return TokError("Linkage must be 'comdat'");
@@ -411,7 +413,16 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
unsigned Type = ELF::SHT_PROGBITS;
- if (!TypeName.empty()) {
+ if (TypeName.empty()) {
+ if (SectionName.startswith(".note"))
+ Type = ELF::SHT_NOTE;
+ else if (SectionName == ".init_array")
+ Type = ELF::SHT_INIT_ARRAY;
+ else if (SectionName == ".fini_array")
+ Type = ELF::SHT_FINI_ARRAY;
+ else if (SectionName == ".preinit_array")
+ Type = ELF::SHT_PREINIT_ARRAY;
+ } else {
if (TypeName == "init_array")
Type = ELF::SHT_INIT_ARRAY;
else if (TypeName == "fini_array")
@@ -450,7 +461,7 @@ bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
/// ::= .type identifier , @attribute
bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
// Handle the identifier as the key symbol.
@@ -468,7 +479,7 @@ bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
SMLoc TypeLoc;
TypeLoc = getLexer().getLoc();
- if (getParser().ParseIdentifier(Type))
+ if (getParser().parseIdentifier(Type))
return TokError("expected symbol type in directive");
MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type)
@@ -527,7 +538,7 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
/// ::= .symver foo, bar2@zed
bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
if (getLexer().isNot(AsmToken::Comma))
@@ -536,7 +547,7 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
Lex();
StringRef AliasName;
- if (getParser().ParseIdentifier(AliasName))
+ if (getParser().parseIdentifier(AliasName))
return TokError("expected identifier in directive");
if (AliasName.find('@') == StringRef::npos)
@@ -582,7 +593,7 @@ bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
// FIXME: Share code with the other alias building directives.
StringRef AliasName;
- if (getParser().ParseIdentifier(AliasName))
+ if (getParser().parseIdentifier(AliasName))
return TokError("expected identifier in directive");
if (getLexer().isNot(AsmToken::Comma))
@@ -591,7 +602,7 @@ bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
Lex();
StringRef Name;
- if (getParser().ParseIdentifier(Name))
+ if (getParser().parseIdentifier(Name))
return TokError("expected identifier in directive");
MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName);
diff --git a/lib/MC/MCParser/MCAsmParser.cpp b/lib/MC/MCParser/MCAsmParser.cpp
index a8b00cd84a..6e1ebad36c 100644
--- a/lib/MC/MCParser/MCAsmParser.cpp
+++ b/lib/MC/MCParser/MCAsmParser.cpp
@@ -38,9 +38,9 @@ bool MCAsmParser::TokError(const Twine &Msg, ArrayRef<SMRange> Ranges) {
return true;
}
-bool MCAsmParser::ParseExpression(const MCExpr *&Res) {
+bool MCAsmParser::parseExpression(const MCExpr *&Res) {
SMLoc L;
- return ParseExpression(Res, L);
+ return parseExpression(Res, L);
}
void MCParsedAsmOperand::dump() const {
diff --git a/lib/MC/MCPureStreamer.cpp b/lib/MC/MCPureStreamer.cpp
index 6ce7ae81d5..573308abb8 100644
--- a/lib/MC/MCPureStreamer.cpp
+++ b/lib/MC/MCPureStreamer.cpp
@@ -28,9 +28,9 @@ private:
virtual void EmitInstToData(const MCInst &Inst);
public:
- MCPureStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TAB, OS, Emitter) {}
+ MCPureStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter)
+ : MCObjectStreamer(SK_PureStreamer, Context, TAB, OS, Emitter) {}
/// @name MCStreamer Interface
/// @{
@@ -100,6 +100,10 @@ public:
}
/// @}
+
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() == SK_PureStreamer;
+ }
};
} // end anonymous namespace.
diff --git a/lib/MC/MCSectionMachO.cpp b/lib/MC/MCSectionMachO.cpp
index e771556262..fc323155be 100644
--- a/lib/MC/MCSectionMachO.cpp
+++ b/lib/MC/MCSectionMachO.cpp
@@ -165,9 +165,9 @@ bool MCSectionMachO::isVirtualSection() const {
/// StripSpaces - This removes leading and trailing spaces from the StringRef.
static void StripSpaces(StringRef &Str) {
- while (!Str.empty() && isspace(Str[0]))
+ while (!Str.empty() && isspace(static_cast<unsigned char>(Str[0])))
Str = Str.substr(1);
- while (!Str.empty() && isspace(Str.back()))
+ while (!Str.empty() && isspace(static_cast<unsigned char>(Str.back())))
Str = Str.substr(0, Str.size()-1);
}
diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp
index 00ebde3c40..9857f7bb08 100644
--- a/lib/MC/MCStreamer.cpp
+++ b/lib/MC/MCStreamer.cpp
@@ -21,10 +21,9 @@
#include <cstdlib>
using namespace llvm;
-MCStreamer::MCStreamer(MCContext &Ctx)
- : Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false),
- CurrentW64UnwindInfo(0), LastSymbol(0),
- AutoInitSections(false) {
+MCStreamer::MCStreamer(StreamerKind Kind, MCContext &Ctx)
+ : Kind(Kind), Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false),
+ CurrentW64UnwindInfo(0), LastSymbol(0), AutoInitSections(false) {
const MCSection *section = NULL;
SectionStack.push_back(std::make_pair(section, section));
}
@@ -43,7 +42,7 @@ void MCStreamer::reset() {
LastSymbol = 0;
const MCSection *section = NULL;
SectionStack.clear();
- SectionStack.push_back(std::make_pair(section, section));
+ SectionStack.push_back(std::make_pair(section, section));
}
const MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context,
@@ -105,7 +104,7 @@ void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size,
/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned Padding,
- unsigned AddrSpace) {
+ unsigned AddrSpace) {
SmallString<128> Tmp;
raw_svector_ostream OSE(Tmp);
encodeULEB128(Value, OSE, Padding);
@@ -621,3 +620,8 @@ void MCStreamer::Finish() {
FinishImpl();
}
+
+MCSymbolData &MCStreamer::getOrCreateSymbolData(MCSymbol *Symbol) {
+ report_fatal_error("Not supported!");
+ return *(static_cast<MCSymbolData*> (NULL));
+}
diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp
index 0098bead45..a5ba3c3653 100644
--- a/lib/MC/MachObjectWriter.cpp
+++ b/lib/MC/MachObjectWriter.cpp
@@ -376,6 +376,39 @@ void MachObjectWriter::WriteLinkeditLoadCommand(uint32_t Type,
assert(OS.tell() - Start == macho::LinkeditLoadCommandSize);
}
+static unsigned ComputeLinkerOptionsLoadCommandSize(
+ const std::vector<std::string> &Options, bool is64Bit)
+{
+ unsigned Size = sizeof(macho::LinkerOptionsLoadCommand);
+ for (unsigned i = 0, e = Options.size(); i != e; ++i)
+ Size += Options[i].size() + 1;
+ return RoundUpToAlignment(Size, is64Bit ? 8 : 4);
+}
+
+void MachObjectWriter::WriteLinkerOptionsLoadCommand(
+ const std::vector<std::string> &Options)
+{
+ unsigned Size = ComputeLinkerOptionsLoadCommandSize(Options, is64Bit());
+ uint64_t Start = OS.tell();
+ (void) Start;
+
+ Write32(macho::LCT_LinkerOptions);
+ Write32(Size);
+ Write32(Options.size());
+ uint64_t BytesWritten = sizeof(macho::LinkerOptionsLoadCommand);
+ for (unsigned i = 0, e = Options.size(); i != e; ++i) {
+ // Write each string, including the null byte.
+ const std::string &Option = Options[i];
+ WriteBytes(Option.c_str(), Option.size() + 1);
+ BytesWritten += Option.size() + 1;
+ }
+
+ // Pad to a multiple of the pointer size.
+ WriteBytes("", OffsetToAlignment(BytesWritten, is64Bit() ? 8 : 4));
+
+ assert(OS.tell() - Start == Size);
+}
+
void MachObjectWriter::RecordRelocation(const MCAssembler &Asm,
const MCAsmLayout &Layout,
@@ -693,6 +726,13 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
macho::SegmentLoadCommand64Size + NumSections * macho::Section64Size :
macho::SegmentLoadCommand32Size + NumSections * macho::Section32Size;
+ // Add the data-in-code load command size, if used.
+ unsigned NumDataRegions = Asm.getDataRegions().size();
+ if (NumDataRegions) {
+ ++NumLoadCommands;
+ LoadCommandsSize += macho::LinkeditLoadCommandSize;
+ }
+
// Add the symbol table load command sizes, if used.
unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
UndefinedSymbolData.size();
@@ -702,13 +742,15 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
macho::DysymtabLoadCommandSize);
}
- // Add the data-in-code load command size, if used.
- unsigned NumDataRegions = Asm.getDataRegions().size();
- if (NumDataRegions) {
+ // Add the linker option load commands sizes.
+ const std::vector<std::vector<std::string> > &LinkerOptions =
+ Asm.getLinkerOptions();
+ for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
++NumLoadCommands;
- LoadCommandsSize += macho::LinkeditLoadCommandSize;
+ LoadCommandsSize += ComputeLinkerOptionsLoadCommandSize(LinkerOptions[i],
+ is64Bit());
}
-
+
// Compute the total size of the section data, as well as its file size and vm
// size.
uint64_t SectionDataStart = (is64Bit() ? macho::Header64Size :
@@ -799,6 +841,11 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
IndirectSymbolOffset, NumIndirectSymbols);
}
+ // Write the linker options load commands.
+ for (unsigned i = 0, e = LinkerOptions.size(); i != e; ++i) {
+ WriteLinkerOptionsLoadCommand(LinkerOptions[i]);
+ }
+
// Write the actual section data.
for (MCAssembler::const_iterator it = Asm.begin(),
ie = Asm.end(); it != ie; ++it) {
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp
index e1d65387a1..6dffed73df 100644
--- a/lib/MC/WinCOFFObjectWriter.cpp
+++ b/lib/MC/WinCOFFObjectWriter.cpp
@@ -147,7 +147,9 @@ public:
object_t *createCOFFEntity(StringRef Name, list_t &List);
void DefineSection(MCSectionData const &SectionData);
- void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler);
+ void DefineSymbol(MCSymbol const &Symbol,
+ MCSymbolData const &SymbolData,
+ MCAssembler &Assembler);
void MakeSymbolReal(COFFSymbol &S, size_t Index);
void MakeSectionReal(COFFSection &S, size_t Number);
@@ -408,9 +410,10 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) {
/// This function takes a section data object from the assembler
/// and creates the associated COFF symbol staging object.
-void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
+void WinCOFFObjectWriter::DefineSymbol(MCSymbol const &Symbol,
+ MCSymbolData const &SymbolData,
MCAssembler &Assembler) {
- COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&SymbolData.getSymbol());
+ COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
coff_symbol->Data.Type = (SymbolData.getFlags() & 0x0000FFFF) >> 0;
coff_symbol->Data.StorageClass = (SymbolData.getFlags() & 0x00FF0000) >> 16;
@@ -418,20 +421,17 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
if (SymbolData.getFlags() & COFF::SF_WeakExternal) {
coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
- if (SymbolData.getSymbol().isVariable()) {
+ if (Symbol.isVariable()) {
coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
- const MCExpr *Value = SymbolData.getSymbol().getVariableValue();
// FIXME: This assert message isn't very good.
- assert(Value->getKind() == MCExpr::SymbolRef &&
+ assert(Symbol.getVariableValue()->getKind() == MCExpr::SymbolRef &&
"Value must be a SymbolRef!");
- const MCSymbolRefExpr *SymbolRef =
- static_cast<const MCSymbolRefExpr *>(Value);
- coff_symbol->Other = GetOrCreateCOFFSymbol(&SymbolRef->getSymbol());
+ coff_symbol->Other = GetOrCreateCOFFSymbol(&Symbol);
} else {
std::string WeakName = std::string(".weak.")
- + SymbolData.getSymbol().getName().str()
+ + Symbol.getName().str()
+ ".default";
COFFSymbol *WeakDefault = createSymbol(WeakName);
WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
@@ -464,7 +464,7 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
// Bind internal COFF symbol to MC symbol.
coff_symbol->MCData = &SymbolData;
- SymbolMap[&SymbolData.getSymbol()] = coff_symbol;
+ SymbolMap[&Symbol] = coff_symbol;
}
/// making a section real involves assigned it a number and putting
@@ -619,8 +619,11 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(),
e = Asm.symbol_end(); i != e; i++) {
- if (ExportSymbol(*i, Asm))
- DefineSymbol(*i, Asm);
+ if (ExportSymbol(*i, Asm)) {
+ const MCSymbol &Alias = i->getSymbol();
+ const MCSymbol &Symbol = Alias.AliasedSymbol();
+ DefineSymbol(Alias, Asm.getSymbolData(Symbol), Asm);
+ }
}
}
diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp
index cc2c272f38..75f343c421 100644
--- a/lib/MC/WinCOFFStreamer.cpp
+++ b/lib/MC/WinCOFFStreamer.cpp
@@ -55,7 +55,6 @@ public:
virtual void EmitDebugLabel(MCSymbol *Symbol);
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
virtual void EmitThumbFunc(MCSymbol *Func);
- virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
virtual void BeginCOFFSymbolDef(MCSymbol const *Symbol);
@@ -76,6 +75,10 @@ public:
virtual void EmitWin64EHHandlerData();
virtual void FinishImpl();
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() == SK_WinCOFFStreamer;
+ }
+
private:
virtual void EmitInstToData(const MCInst &Inst) {
MCDataFragment *DF = getOrCreateDataFragment();
@@ -129,13 +132,10 @@ private:
};
} // end anonymous namespace.
-WinCOFFStreamer::WinCOFFStreamer(MCContext &Context,
- MCAsmBackend &MAB,
- MCCodeEmitter &CE,
- raw_ostream &OS)
- : MCObjectStreamer(Context, MAB, OS, &CE)
- , CurSymbol(NULL) {
-}
+WinCOFFStreamer::WinCOFFStreamer(MCContext &Context, MCAsmBackend &MAB,
+ MCCodeEmitter &CE, raw_ostream &OS)
+ : MCObjectStreamer(SK_WinCOFFStreamer, Context, MAB, OS, &CE),
+ CurSymbol(NULL) {}
void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment, bool External) {
@@ -201,44 +201,6 @@ void WinCOFFStreamer::EmitThumbFunc(MCSymbol *Func) {
llvm_unreachable("not implemented");
}
-void WinCOFFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
- assert((Symbol->isInSection()
- ? Symbol->getSection().getVariant() == MCSection::SV_COFF
- : true) && "Got non COFF section in the COFF backend!");
- // FIXME: This is all very ugly and depressing. What needs to happen here
- // depends on quite a few things that are all part of relaxation, which we
- // don't really even do.
-
- if (Value->getKind() != MCExpr::SymbolRef) {
- MCObjectStreamer::EmitAssignment(Symbol, Value);
- } else {
- // FIXME: This is a horrible way to do this :(. This should really be
- // handled after we are done with the MC* objects and immediately before
- // writing out the object file when we know exactly what the symbol should
- // look like in the coff symbol table. I'm not doing that now because the
- // COFF object writer doesn't have a clearly defined separation between MC
- // data structures, the object writers data structures, and the raw, POD,
- // data structures that get written to disk.
-
- // Copy over the aliased data.
- MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
- const MCSymbolData &RealSD = getAssembler().getOrCreateSymbolData(
- dyn_cast<const MCSymbolRefExpr>(Value)->getSymbol());
-
- // FIXME: This is particularly nasty because it breaks as soon as any data
- // members of MCSymbolData change.
- SD.CommonAlign = RealSD.CommonAlign;
- SD.CommonSize = RealSD.CommonSize;
- SD.Flags = RealSD.Flags;
- SD.Fragment = RealSD.Fragment;
- SD.Index = RealSD.Index;
- SD.IsExternal = RealSD.IsExternal;
- SD.IsPrivateExtern = RealSD.IsPrivateExtern;
- SD.Offset = RealSD.Offset;
- SD.SymbolSize = RealSD.SymbolSize;
- }
-}
-
void WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) {
assert(Symbol && "Symbol must be non-null!");