From 20bb042d74a95970b4942f38cb2606a84fc279f7 Mon Sep 17 00:00:00 2001 From: Oliver Stannard Date: Mon, 16 Nov 2015 16:25:47 +0000 Subject: [PATCH] [ARM,AArch64] Store source location of asm constant pool entries Storing the source location of the expression that created a constant pool entry allows us to emit better error messages if we later discover that the expression cannot be represented by a relocation. Differential Revision: http://reviews.llvm.org/D14646 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253220 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/ConstantPools.h | 10 ++++++---- include/llvm/MC/MCStreamer.h | 2 +- lib/MC/ConstantPools.cpp | 10 +++++----- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 2 +- .../AArch64/MCTargetDesc/AArch64TargetStreamer.cpp | 5 +++-- .../AArch64/MCTargetDesc/AArch64TargetStreamer.h | 2 +- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 7 +++++-- lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp | 4 ++-- test/MC/AArch64/error-location-ldr-pseudo.s | 5 +++++ test/MC/ARM/error-location-ldr-pseudo.s | 5 +++++ 10 files changed, 34 insertions(+), 18 deletions(-) create mode 100644 test/MC/AArch64/error-location-ldr-pseudo.s create mode 100644 test/MC/ARM/error-location-ldr-pseudo.s diff --git a/include/llvm/MC/ConstantPools.h b/include/llvm/MC/ConstantPools.h index 9aa4663ba0f..552e1443e7d 100644 --- a/include/llvm/MC/ConstantPools.h +++ b/include/llvm/MC/ConstantPools.h @@ -17,6 +17,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/SMLoc.h" namespace llvm { class MCContext; @@ -26,11 +27,12 @@ class MCStreamer; class MCSymbol; struct ConstantPoolEntry { - ConstantPoolEntry(MCSymbol *L, const MCExpr *Val, unsigned Sz) - : Label(L), Value(Val), Size(Sz) {} + ConstantPoolEntry(MCSymbol *L, const MCExpr *Val, unsigned Sz, SMLoc Loc_) + : Label(L), Value(Val), Size(Sz), Loc(Loc_) {} MCSymbol *Label; const MCExpr *Value; unsigned Size; + SMLoc Loc; }; // A class to keep track of assembler-generated constant pools that are use to @@ -49,7 +51,7 @@ public: // // \returns a MCExpr that references the newly inserted value const MCExpr *addEntry(const MCExpr *Value, MCContext &Context, - unsigned Size); + unsigned Size, SMLoc Loc); // Emit the contents of the constant pool using the provided streamer. void emitEntries(MCStreamer &Streamer); @@ -80,7 +82,7 @@ public: void emitAll(MCStreamer &Streamer); void emitForCurrentSection(MCStreamer &Streamer); const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr, - unsigned Size); + unsigned Size, SMLoc Loc); private: ConstantPool *getConstantPool(MCSection *Section); diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 02b9d18af5f..46afebebc0d 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -134,7 +134,7 @@ public: /// Callback used to implement the ldr= pseudo. /// Add a new entry to the constant pool for the current section and return an /// MCExpr that can be used to refer to the constant pool location. - const MCExpr *addConstantPoolEntry(const MCExpr *); + const MCExpr *addConstantPoolEntry(const MCExpr *, SMLoc Loc); /// Callback used to implemnt the .ltorg directive. /// Emit contents of constant pool for the current section. diff --git a/lib/MC/ConstantPools.cpp b/lib/MC/ConstantPools.cpp index f7649fba6e8..9643b759468 100644 --- a/lib/MC/ConstantPools.cpp +++ b/lib/MC/ConstantPools.cpp @@ -29,17 +29,17 @@ void ConstantPool::emitEntries(MCStreamer &Streamer) { I != E; ++I) { Streamer.EmitCodeAlignment(I->Size); // align naturally Streamer.EmitLabel(I->Label); - Streamer.EmitValue(I->Value, I->Size); + Streamer.EmitValue(I->Value, I->Size, I->Loc); } Streamer.EmitDataRegion(MCDR_DataRegionEnd); Entries.clear(); } const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context, - unsigned Size) { + unsigned Size, SMLoc Loc) { MCSymbol *CPEntryLabel = Context.createTempSymbol(); - Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size)); + Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc)); return MCSymbolRefExpr::create(CPEntryLabel, Context); } @@ -90,8 +90,8 @@ void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) { const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer, const MCExpr *Expr, - unsigned Size) { + unsigned Size, SMLoc Loc) { MCSection *Section = Streamer.getCurrentSection().first; return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(), - Size); + Size, Loc); } diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 3038ca5f90a..e26420f6ed8 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -3210,7 +3210,7 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, } // If it is a label or an imm that cannot fit in a movz, put it into CP. const MCExpr *CPLoc = - getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4); + getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc); Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx)); return false; } diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp index 52b000d15b8..3e86a42d5be 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp +++ b/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp @@ -26,8 +26,9 @@ AArch64TargetStreamer::~AArch64TargetStreamer() {} // The constant pool handling is shared by all AArch64TargetStreamer // implementations. const MCExpr *AArch64TargetStreamer::addConstantPoolEntry(const MCExpr *Expr, - unsigned Size) { - return ConstantPools->addEntry(Streamer, Expr, Size); + unsigned Size, + SMLoc Loc) { + return ConstantPools->addEntry(Streamer, Expr, Size, Loc); } void AArch64TargetStreamer::emitCurrentConstantPool() { diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h index fcc0d053f6e..51432830f79 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h +++ b/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h @@ -24,7 +24,7 @@ public: /// Callback used to implement the ldr= pseudo. /// Add a new entry to the constant pool for the current section and return an /// MCExpr that can be used to refer to the constant pool location. - const MCExpr *addConstantPoolEntry(const MCExpr *, unsigned Size); + const MCExpr *addConstantPoolEntry(const MCExpr *, unsigned Size, SMLoc Loc); /// Callback used to implemnt the .ltorg directive. /// Emit contents of constant pool for the current section. diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 7540c21d36a..ba144458386 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -5122,6 +5122,7 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { // FALLTHROUGH } case AsmToken::Colon: { + S = Parser.getTok().getLoc(); // ":lower16:" and ":upper16:" expression prefixes // FIXME: Check it's an expression prefix, // e.g. (FOO - :lower16:BAR) isn't legal. @@ -5140,8 +5141,9 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { return false; } case AsmToken::Equal: { + S = Parser.getTok().getLoc(); if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val) - return Error(Parser.getTok().getLoc(), "unexpected token in operand"); + return Error(S, "unexpected token in operand"); Parser.Lex(); // Eat '=' const MCExpr *SubExprVal; @@ -5149,7 +5151,8 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { return true; E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); - const MCExpr *CPLoc = getTargetStreamer().addConstantPoolEntry(SubExprVal); + const MCExpr *CPLoc = + getTargetStreamer().addConstantPoolEntry(SubExprVal, S); Operands.push_back(ARMOperand::CreateImm(CPLoc, S, E)); return false; } diff --git a/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp b/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp index b680db5c3a7..dad50f2834e 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp @@ -27,8 +27,8 @@ ARMTargetStreamer::~ARMTargetStreamer() {} // The constant pool handling is shared by all ARMTargetStreamer // implementations. -const MCExpr *ARMTargetStreamer::addConstantPoolEntry(const MCExpr *Expr) { - return ConstantPools->addEntry(Streamer, Expr, 4); +const MCExpr *ARMTargetStreamer::addConstantPoolEntry(const MCExpr *Expr, SMLoc Loc) { + return ConstantPools->addEntry(Streamer, Expr, 4, Loc); } void ARMTargetStreamer::emitCurrentConstantPool() { diff --git a/test/MC/AArch64/error-location-ldr-pseudo.s b/test/MC/AArch64/error-location-ldr-pseudo.s new file mode 100644 index 00000000000..951373dda61 --- /dev/null +++ b/test/MC/AArch64/error-location-ldr-pseudo.s @@ -0,0 +1,5 @@ +// RUN: not llvm-mc -triple aarch64--none-eabi -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s + + .text +// CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: expected relocatable expression + ldr x0, =(-undef) diff --git a/test/MC/ARM/error-location-ldr-pseudo.s b/test/MC/ARM/error-location-ldr-pseudo.s new file mode 100644 index 00000000000..b5cdcad7259 --- /dev/null +++ b/test/MC/ARM/error-location-ldr-pseudo.s @@ -0,0 +1,5 @@ +@ RUN: not llvm-mc -triple armv7a--none-eabi -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s + + .text +@ CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: expected relocatable expression + ldr r0, =(-undef) -- 2.34.1