Fix the assembler to print a better relocatable expression error

diagnostic that includes location information.

Currently if one has this assembly:

	.quad (0x1234 + (4 * SOME_VALUE))

where SOME_VALUE is undefined ones gets the less than
useful error message with no location information:

% clang -c x.s
clang -cc1as: fatal error: error in backend: expected relocatable expression

With this fix one now gets a more useful error message
with location information:

% clang -c x.s 
x.s:5:8: error: expected relocatable expression
 .quad (0x1234 + (4 * SOME_VALUE))
       ^

To do this I plumbed the SMLoc through the MCObjectStreamer
EmitValue() and EmitValueImpl() interfaces so it could be used
when creating the MCFixup.

rdar://12391022


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206906 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Kevin Enderby
2014-04-22 17:27:29 +00:00
parent 795e462cc4
commit 29c96f133e
14 changed files with 40 additions and 19 deletions

View File

@ -72,7 +72,8 @@ public:
uint64_t Size = 0, unsigned ByteAlignment = 0) override; uint64_t Size = 0, unsigned ByteAlignment = 0) override;
void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment = 0) override; uint64_t Size, unsigned ByteAlignment = 0) override;
void EmitValueImpl(const MCExpr *Value, unsigned Size) override; void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc = SMLoc()) override;
void EmitFileDirective(StringRef Filename) override; void EmitFileDirective(StringRef Filename) override;

View File

@ -81,7 +81,8 @@ public:
void EmitLabel(MCSymbol *Symbol) override; void EmitLabel(MCSymbol *Symbol) override;
void EmitDebugLabel(MCSymbol *Symbol) override; void EmitDebugLabel(MCSymbol *Symbol) override;
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
void EmitValueImpl(const MCExpr *Value, unsigned Size) override; void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc = SMLoc()) override;
void EmitULEB128Value(const MCExpr *Value) override; void EmitULEB128Value(const MCExpr *Value) override;
void EmitSLEB128Value(const MCExpr *Value) override; void EmitSLEB128Value(const MCExpr *Value) override;
void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;

View File

@ -529,9 +529,12 @@ public:
/// @param Value - The value to emit. /// @param Value - The value to emit.
/// @param Size - The size of the integer (in bytes) to emit. This must /// @param Size - The size of the integer (in bytes) to emit. This must
/// match a native machine width. /// match a native machine width.
virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) = 0; /// @param Loc - The location of the expression for error reporting.
virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc = SMLoc()) = 0;
void EmitValue(const MCExpr *Value, unsigned Size); void EmitValue(const MCExpr *Value, unsigned Size,
const SMLoc &Loc = SMLoc());
/// EmitIntValue - Special case of EmitValue that avoids the client having /// EmitIntValue - Special case of EmitValue that avoids the client having
/// to pass in a MCExpr for constant integers. /// to pass in a MCExpr for constant integers.

View File

@ -698,7 +698,8 @@ namespace {
void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) override {} uint64_t Size, unsigned ByteAlignment) override {}
void EmitBytes(StringRef Data) override {} void EmitBytes(StringRef Data) override {}
void EmitValueImpl(const MCExpr *Value, unsigned Size) override {} void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc) override {}
void EmitULEB128Value(const MCExpr *Value) override {} void EmitULEB128Value(const MCExpr *Value) override {}
void EmitSLEB128Value(const MCExpr *Value) override {} void EmitSLEB128Value(const MCExpr *Value) override {}
void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,

View File

@ -175,7 +175,8 @@ public:
void EmitBytes(StringRef Data) override; void EmitBytes(StringRef Data) override;
void EmitValueImpl(const MCExpr *Value, unsigned Size) override; void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc = SMLoc()) override;
void EmitIntValue(uint64_t Value, unsigned Size) override; void EmitIntValue(uint64_t Value, unsigned Size) override;
void EmitULEB128Value(const MCExpr *Value) override; void EmitULEB128Value(const MCExpr *Value) override;
@ -702,7 +703,8 @@ void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
EmitValue(MCConstantExpr::Create(Value, getContext()), Size); EmitValue(MCConstantExpr::Create(Value, getContext()), Size);
} }
void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc) {
assert(Size <= 8 && "Invalid size"); assert(Size <= 8 && "Invalid size");
assert(getCurrentSection().first && assert(getCurrentSection().first &&
"Cannot emit contents before setting section!"); "Cannot emit contents before setting section!");

View File

@ -275,11 +275,12 @@ void MCELFStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
EmitCommonSymbol(Symbol, Size, ByteAlignment); EmitCommonSymbol(Symbol, Size, ByteAlignment);
} }
void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc) {
if (getCurrentSectionData()->isBundleLocked()) if (getCurrentSectionData()->isBundleLocked())
report_fatal_error("Emitting values inside a locked bundle is forbidden"); report_fatal_error("Emitting values inside a locked bundle is forbidden");
fixSymbolsInTLSFixups(Value); fixSymbolsInTLSFixups(Value);
MCObjectStreamer::EmitValueImpl(Value, Size); MCObjectStreamer::EmitValueImpl(Value, Size, Loc);
} }
void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,

View File

@ -70,7 +70,8 @@ namespace {
uint64_t Size, unsigned ByteAlignment) override {} uint64_t Size, unsigned ByteAlignment) override {}
void EmitBytes(StringRef Data) override {} void EmitBytes(StringRef Data) override {}
void EmitValueImpl(const MCExpr *Value, unsigned Size) override {} void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc = SMLoc()) override {}
void EmitULEB128Value(const MCExpr *Value) override {} void EmitULEB128Value(const MCExpr *Value) override {}
void EmitSLEB128Value(const MCExpr *Value) override {} void EmitSLEB128Value(const MCExpr *Value) override {}
void EmitGPRel32Value(const MCExpr *Value) override {} void EmitGPRel32Value(const MCExpr *Value) override {}

View File

@ -97,7 +97,8 @@ const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
return Value; return Value;
} }
void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) { void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc) {
MCDataFragment *DF = getOrCreateDataFragment(); MCDataFragment *DF = getOrCreateDataFragment();
MCLineEntry::Make(this, getCurrentSection().first); MCLineEntry::Make(this, getCurrentSection().first);
@ -110,7 +111,7 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size) {
} }
DF->getFixups().push_back( DF->getFixups().push_back(
MCFixup::Create(DF->getContents().size(), Value, MCFixup::Create(DF->getContents().size(), Value,
MCFixup::getKindForSize(Size, false))); MCFixup::getKindForSize(Size, false), Loc));
DF->getContents().resize(DF->getContents().size() + Size, 0); DF->getContents().resize(DF->getContents().size() + Size, 0);
} }

View File

@ -2364,7 +2364,7 @@ bool AsmParser::parseDirectiveValue(unsigned Size) {
return Error(ExprLoc, "literal value out of range for directive"); return Error(ExprLoc, "literal value out of range for directive");
getStreamer().EmitIntValue(IntValue, Size); getStreamer().EmitIntValue(IntValue, Size);
} else } else
getStreamer().EmitValue(Value, Size); getStreamer().EmitValue(Value, Size, ExprLoc);
if (getLexer().is(AsmToken::EndOfStatement)) if (getLexer().is(AsmToken::EndOfStatement))
break; break;

View File

@ -147,8 +147,9 @@ void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size) {
} }
void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size) { void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size,
EmitValueImpl(Value, Size); const SMLoc &Loc) {
EmitValueImpl(Value, Size, Loc);
} }
void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size) { void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size) {

View File

@ -92,9 +92,10 @@ public:
/// This is one of the functions used to emit data into an ELF section, so the /// This is one of the functions used to emit data into an ELF section, so the
/// AArch64 streamer overrides it to add the appropriate mapping symbol ($d) /// AArch64 streamer overrides it to add the appropriate mapping symbol ($d)
/// if necessary. /// if necessary.
virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) { virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc) {
EmitDataMappingSymbol(); EmitDataMappingSymbol();
MCELFStreamer::EmitValueImpl(Value, Size); MCELFStreamer::EmitValueImpl(Value, Size, Loc);
} }
private: private:

View File

@ -531,7 +531,8 @@ public:
/// This is one of the functions used to emit data into an ELF section, so the /// This is one of the functions used to emit data into an ELF section, so the
/// ARM streamer overrides it to add the appropriate mapping symbol ($d) if /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
/// necessary. /// necessary.
void EmitValueImpl(const MCExpr *Value, unsigned Size) override { void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc) override {
EmitDataMappingSymbol(); EmitDataMappingSymbol();
MCELFStreamer::EmitValueImpl(Value, Size); MCELFStreamer::EmitValueImpl(Value, Size);
} }

View File

@ -92,7 +92,8 @@ public:
/// This is one of the functions used to emit data into an ELF section, so the /// This is one of the functions used to emit data into an ELF section, so the
/// ARM64 streamer overrides it to add the appropriate mapping symbol ($d) /// ARM64 streamer overrides it to add the appropriate mapping symbol ($d)
/// if necessary. /// if necessary.
virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) { virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
const SMLoc &Loc) {
EmitDataMappingSymbol(); EmitDataMappingSymbol();
MCELFStreamer::EmitValueImpl(Value, Size); MCELFStreamer::EmitValueImpl(Value, Size);
} }

View File

@ -0,0 +1,6 @@
// RUN: not llvm-mc -triple x86_64-apple-darwin10 %s -filetype=obj -o - 2> %t.err > %t
// RUN: FileCheck --check-prefix=CHECK-ERROR < %t.err %s
.quad (0x1234 + (4 * SOME_VALUE))
// CHECK-ERROR: error: expected relocatable expression
// CHECK-ERROR: ^