From b1330a5678b050e8c8c1c7afa04488a2d1906829 Mon Sep 17 00:00:00 2001 From: Chad Rosier Date: Thu, 19 Jan 2017 20:06:32 +0000 Subject: [PATCH] [Assembler] Improve error when unable to evaluate expression. Add a SMLoc to MCExpr. Most code does not generate or consume the SMLoc (yet). Patch by Sanne Wouda ! Differential Revision: https://reviews.llvm.org/D28861 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292515 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCExpr.h | 23 ++++++++++++-------- lib/MC/MCExpr.cpp | 13 ++++++----- lib/MC/MCFragment.cpp | 7 +++--- lib/MC/MCParser/AsmParser.cpp | 5 +++-- test/MC/AArch64/error-location-post-layout.s | 9 +++----- test/MC/ARM/error-location-post-layout.s | 12 +++++----- 6 files changed, 36 insertions(+), 33 deletions(-) diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 0d1e675da45..50f4d7597de 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -13,6 +13,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/SMLoc.h" namespace llvm { class MCAsmInfo; @@ -43,6 +44,7 @@ public: private: ExprKind Kind; + SMLoc Loc; MCExpr(const MCExpr&) = delete; void operator=(const MCExpr&) = delete; @@ -56,7 +58,7 @@ private: const SectionAddrMap *Addrs, bool InSet) const; protected: - explicit MCExpr(ExprKind Kind) : Kind(Kind) {} + explicit MCExpr(ExprKind Kind, SMLoc Loc) : Kind(Kind), Loc(Loc) {} bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCAsmLayout *Layout, @@ -68,6 +70,7 @@ public: /// @{ ExprKind getKind() const { return Kind; } + SMLoc getLoc() const { return Loc; } /// @} /// \name Utility Methods @@ -132,7 +135,7 @@ class MCConstantExpr : public MCExpr { int64_t Value; explicit MCConstantExpr(int64_t Value) - : MCExpr(MCExpr::Constant), Value(Value) {} + : MCExpr(MCExpr::Constant, SMLoc()), Value(Value) {} public: /// \name Construction @@ -289,7 +292,7 @@ private: const MCSymbol *Symbol; explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind, - const MCAsmInfo *MAI); + const MCAsmInfo *MAI, SMLoc Loc = SMLoc()); public: /// \name Construction @@ -300,7 +303,7 @@ public: } static const MCSymbolRefExpr *create(const MCSymbol *Symbol, VariantKind Kind, - MCContext &Ctx); + MCContext &Ctx, SMLoc Loc = SMLoc()); static const MCSymbolRefExpr *create(StringRef Name, VariantKind Kind, MCContext &Ctx); @@ -346,7 +349,7 @@ private: const MCExpr *Expr; MCUnaryExpr(Opcode Op, const MCExpr *Expr) - : MCExpr(MCExpr::Unary), Op(Op), Expr(Expr) {} + : MCExpr(MCExpr::Unary, SMLoc()), Op(Op), Expr(Expr) {} public: /// \name Construction @@ -417,15 +420,17 @@ private: Opcode Op; const MCExpr *LHS, *RHS; - MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS) - : MCExpr(MCExpr::Binary), Op(Op), LHS(LHS), RHS(RHS) {} + MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, + SMLoc Loc = SMLoc()) + : MCExpr(MCExpr::Binary, Loc), Op(Op), LHS(LHS), RHS(RHS) {} public: /// \name Construction /// @{ static const MCBinaryExpr *create(Opcode Op, const MCExpr *LHS, - const MCExpr *RHS, MCContext &Ctx); + const MCExpr *RHS, MCContext &Ctx, + SMLoc Loc = SMLoc()); static const MCBinaryExpr *createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx) { return create(Add, LHS, RHS, Ctx); @@ -531,7 +536,7 @@ public: class MCTargetExpr : public MCExpr { virtual void anchor(); protected: - MCTargetExpr() : MCExpr(Target) {} + MCTargetExpr() : MCExpr(Target, SMLoc()) {} virtual ~MCTargetExpr() {} public: virtual void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const = 0; diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index bcc43a54d62..68e135d5cd6 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -137,8 +137,9 @@ LLVM_DUMP_METHOD void MCExpr::dump() const { /* *** */ const MCBinaryExpr *MCBinaryExpr::create(Opcode Opc, const MCExpr *LHS, - const MCExpr *RHS, MCContext &Ctx) { - return new (Ctx) MCBinaryExpr(Opc, LHS, RHS); + const MCExpr *RHS, MCContext &Ctx, + SMLoc Loc) { + return new (Ctx) MCBinaryExpr(Opc, LHS, RHS, Loc); } const MCUnaryExpr *MCUnaryExpr::create(Opcode Opc, const MCExpr *Expr, @@ -153,8 +154,8 @@ const MCConstantExpr *MCConstantExpr::create(int64_t Value, MCContext &Ctx) { /* *** */ MCSymbolRefExpr::MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind, - const MCAsmInfo *MAI) - : MCExpr(MCExpr::SymbolRef), Kind(Kind), + const MCAsmInfo *MAI, SMLoc Loc) + : MCExpr(MCExpr::SymbolRef, Loc), Kind(Kind), UseParensForSymbolVariant(MAI->useParensForSymbolVariant()), HasSubsectionsViaSymbols(MAI->hasSubsectionsViaSymbols()), Symbol(Symbol) { @@ -163,8 +164,8 @@ MCSymbolRefExpr::MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind, const MCSymbolRefExpr *MCSymbolRefExpr::create(const MCSymbol *Sym, VariantKind Kind, - MCContext &Ctx) { - return new (Ctx) MCSymbolRefExpr(Sym, Kind, Ctx.getAsmInfo()); + MCContext &Ctx, SMLoc Loc) { + return new (Ctx) MCSymbolRefExpr(Sym, Kind, Ctx.getAsmInfo(), Loc); } const MCSymbolRefExpr *MCSymbolRefExpr::create(StringRef Name, VariantKind Kind, diff --git a/lib/MC/MCFragment.cpp b/lib/MC/MCFragment.cpp index 8ff8f8aba1c..8f96e06957a 100644 --- a/lib/MC/MCFragment.cpp +++ b/lib/MC/MCFragment.cpp @@ -145,14 +145,14 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const { MCValue Value; if (!Expr->evaluateAsValue(Value, *this)) { Assembler.getContext().reportError( - SMLoc(), "expression could not be evaluated"); + Expr->getLoc(), "expression could not be evaluated"); return nullptr; } const MCSymbolRefExpr *RefB = Value.getSymB(); if (RefB) { Assembler.getContext().reportError( - SMLoc(), Twine("symbol '") + RefB->getSymbol().getName() + + Expr->getLoc(), Twine("symbol '") + RefB->getSymbol().getName() + "' could not be evaluated in a subtraction expression"); return nullptr; } @@ -164,8 +164,7 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const { const MCSymbol &ASym = A->getSymbol(); const MCAssembler &Asm = getAssembler(); if (ASym.isCommon()) { - // FIXME: we should probably add a SMLoc to MCExpr. - Asm.getContext().reportError(SMLoc(), + Asm.getContext().reportError(Expr->getLoc(), "Common symbol '" + ASym.getName() + "' cannot be used in assignment expr"); return nullptr; diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index da54155b3b9..f8744f5542e 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -1005,7 +1005,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { } // Otherwise create a symbol ref. - Res = MCSymbolRefExpr::create(Sym, Variant, getContext()); + Res = MCSymbolRefExpr::create(Sym, Variant, getContext(), FirstTokenLoc); return false; } case AsmToken::BigNum: @@ -1436,6 +1436,7 @@ unsigned AsmParser::getBinOpPrecedence(AsmToken::TokenKind K, /// Res contains the LHS of the expression on input. bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc) { + SMLoc StartLoc = Lexer.getLoc(); while (true) { MCBinaryExpr::Opcode Kind = MCBinaryExpr::Add; unsigned TokPrec = getBinOpPrecedence(Lexer.getKind(), Kind); @@ -1460,7 +1461,7 @@ bool AsmParser::parseBinOpRHS(unsigned Precedence, const MCExpr *&Res, return true; // Merge LHS and RHS according to operator. - Res = MCBinaryExpr::create(Kind, Res, RHS, getContext()); + Res = MCBinaryExpr::create(Kind, Res, RHS, getContext(), StartLoc); } } diff --git a/test/MC/AArch64/error-location-post-layout.s b/test/MC/AArch64/error-location-post-layout.s index 8b41c6780b3..64e2951efba 100644 --- a/test/MC/AArch64/error-location-post-layout.s +++ b/test/MC/AArch64/error-location-post-layout.s @@ -1,14 +1,11 @@ // RUN: not llvm-mc -triple aarch64--none-eabi -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s -// Note: These errors are not always emitted in the order in which the relevant -// source appears, this file is carefully ordered so that that is the case. - -// CHECK: :0: error: expression could not be evaluated .set v1, -undef +// CHECK: :0: error: expression could not be evaluated .comm common, 4 -// CHECK: :0: error: Common symbol 'common' cannot be used in assignment expr .set v3, common +// CHECK: 7:12: error: Common symbol 'common' cannot be used in assignment expr -// CHECK: :0: error: symbol 'undef' could not be evaluated in a subtraction expression .set v2, a-undef +// CHECK: 10:13: error: symbol 'undef' could not be evaluated in a subtraction expression diff --git a/test/MC/ARM/error-location-post-layout.s b/test/MC/ARM/error-location-post-layout.s index d6a59fd1738..637f5941976 100644 --- a/test/MC/ARM/error-location-post-layout.s +++ b/test/MC/ARM/error-location-post-layout.s @@ -1,14 +1,14 @@ @ RUN: not llvm-mc -triple armv7a--none-eabi -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s -@ Note: These errors are not always emitted in the order in which the relevant -@ source appears, this file is carefully ordered so that that is the case. - -@ CHECK: :0: error: expression could not be evaluated .set v1, -undef +@ CHECK: :0: error: expression could not be evaluated .comm common, 4 -@ CHECK: :0: error: Common symbol 'common' cannot be used in assignment expr .set v3, common +@ CHECK: 7:12: error: Common symbol 'common' cannot be used in assignment expr -@ CHECK: :0: error: symbol 'undef' could not be evaluated in a subtraction expression .set v2, a-undef +@ CHECK-DAG: 10:13: error: symbol 'undef' could not be evaluated in a subtraction expression + + .equ STACK_START, (a + undef) +@ CHECK-DAG: 13:24: error: expression could not be evaluated