diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index 7d76ab172bd..a69075ddd00 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -72,7 +72,7 @@ public: virtual void ChangeSection(const MCSection *Section); virtual void EmitInstruction(const MCInst &Inst); virtual void EmitInstToFragment(const MCInst &Inst); - virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value); + virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value); virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 31fb6d4bdc5..c141dfbc96e 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -503,7 +503,8 @@ namespace llvm { /// @param Offset - The offset to reach. This may be an expression, but the /// expression must be associated with the current section. /// @param Value - The value to use when filling bytes. - virtual void EmitValueToOffset(const MCExpr *Offset, + /// @return false on success, true if the offset was invalid. + virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value = 0) = 0; /// @} diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index a2fb7a40d43..afad5d530cf 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -199,7 +199,7 @@ public: virtual void EmitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit = 0); - virtual void EmitValueToOffset(const MCExpr *Offset, + virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value = 0); virtual void EmitFileDirective(StringRef Filename); @@ -744,11 +744,12 @@ void MCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment, 1, MaxBytesToEmit); } -void MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset, +bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset, unsigned char Value) { // FIXME: Verify that Offset is associated with the current section. OS << ".org " << *Offset << ", " << (unsigned) Value; EmitEOL(); + return false; } diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index 432974f8d77..ba7f81f722f 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -80,8 +80,8 @@ namespace { virtual void EmitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit = 0) {} - virtual void EmitValueToOffset(const MCExpr *Offset, - unsigned char Value = 0) {} + virtual bool EmitValueToOffset(const MCExpr *Offset, + unsigned char Value = 0) { return false; } virtual void EmitFileDirective(StringRef Filename) {} virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index d8f18268aab..f2911fa07b9 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -232,12 +232,12 @@ void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData()); } -void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, +bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, unsigned char Value) { int64_t Res; if (Offset->EvaluateAsAbsolute(Res, getAssembler())) { new MCOrgFragment(*Offset, Value, getCurrentSectionData()); - return; + return false; } MCSymbol *CurrentPos = getContext().CreateTempSymbol(); @@ -249,8 +249,9 @@ void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext()); if (!Delta->EvaluateAsAbsolute(Res, getAssembler())) - report_fatal_error("expected assembly-time absolute expression"); + return true; EmitFill(Res, Value, 0); + return false; } // Associate GPRel32 fixup with data and resize data area diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 64d0dd8563c..1af7cd9ee0d 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -1970,6 +1970,7 @@ bool AsmParser::ParseDirectiveOrg() { CheckForValidSection(); const MCExpr *Offset; + SMLoc Loc = getTok().getLoc(); if (ParseExpression(Offset)) return true; @@ -1989,9 +1990,11 @@ bool AsmParser::ParseDirectiveOrg() { Lex(); - // FIXME: Only limited forms of relocatable expressions are accepted here, it - // has to be relative to the current section. - getStreamer().EmitValueToOffset(Offset, FillExpr); + // Only limited forms of relocatable expressions are accepted here, it + // has to be relative to the current section. The streamer will return + // 'true' if the expression wasn't evaluatable. + if (getStreamer().EmitValueToOffset(Offset, FillExpr)) + return Error(Loc, "expected assembly-time absolute expression"); return false; } diff --git a/lib/MC/MCPureStreamer.cpp b/lib/MC/MCPureStreamer.cpp index 8a3bf8778f9..a770c974380 100644 --- a/lib/MC/MCPureStreamer.cpp +++ b/lib/MC/MCPureStreamer.cpp @@ -46,7 +46,7 @@ public: unsigned MaxBytesToEmit = 0); virtual void EmitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit = 0); - virtual void EmitValueToOffset(const MCExpr *Offset, + virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value = 0); virtual void FinishImpl(); @@ -184,9 +184,10 @@ void MCPureStreamer::EmitCodeAlignment(unsigned ByteAlignment, getCurrentSectionData()->setAlignment(ByteAlignment); } -void MCPureStreamer::EmitValueToOffset(const MCExpr *Offset, +bool MCPureStreamer::EmitValueToOffset(const MCExpr *Offset, unsigned char Value) { new MCOrgFragment(*Offset, Value, getCurrentSectionData()); + return false; } void MCPureStreamer::EmitInstToFragment(const MCInst &Inst) { diff --git a/lib/Target/PTX/PTXMCAsmStreamer.cpp b/lib/Target/PTX/PTXMCAsmStreamer.cpp index 270ed2d29fd..38ecf5240a8 100644 --- a/lib/Target/PTX/PTXMCAsmStreamer.cpp +++ b/lib/Target/PTX/PTXMCAsmStreamer.cpp @@ -162,7 +162,7 @@ public: virtual void EmitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit = 0); - virtual void EmitValueToOffset(const MCExpr *Offset, + virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value = 0); virtual void EmitFileDirective(StringRef Filename); @@ -478,8 +478,8 @@ void PTXMCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, void PTXMCAsmStreamer::EmitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit) {} -void PTXMCAsmStreamer::EmitValueToOffset(const MCExpr *Offset, - unsigned char Value) {} +bool PTXMCAsmStreamer::EmitValueToOffset(const MCExpr *Offset, + unsigned char Value) {return false;} void PTXMCAsmStreamer::EmitFileDirective(StringRef Filename) { diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index 2b89e6240c9..af5a0a66f51 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -589,8 +589,8 @@ namespace { unsigned MaxBytesToEmit) {} virtual void EmitCodeAlignment(unsigned ByteAlignment, unsigned MaxBytesToEmit) {} - virtual void EmitValueToOffset(const MCExpr *Offset, - unsigned char Value ) {} + virtual bool EmitValueToOffset(const MCExpr *Offset, + unsigned char Value ) { return false; } virtual void EmitFileDirective(StringRef Filename) {} virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,