diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -46,8 +46,7 @@ void emitAssemblerFlag(MCAssemblerFlag Flag) override; void emitThumbFunc(MCSymbol *Func) override; void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; - bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute, - SMLoc Loc = SMLoc()) override; + bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -215,6 +215,10 @@ /// PushSection. SmallVector, 4> SectionStack; + /// Pointer to the parser's SMLoc if available. This is used to provide + /// locations for diagnostics. + const SMLoc *StartTokLocPtr = nullptr; + /// The next unique ID to use when creating a WinCFI-related section (.pdata /// or .xdata). This ID ensures that we have a one-to-one mapping from /// code section to unwind info section, which MSVC's incremental linker @@ -259,6 +263,11 @@ TargetStreamer.reset(TS); } + void setStartTokLocPtr(const SMLoc *Loc) { StartTokLocPtr = Loc; } + SMLoc getStartTokLoc() const { + return StartTokLocPtr ? *StartTokLocPtr : SMLoc(); + } + /// State management /// virtual void reset(); @@ -508,8 +517,8 @@ virtual void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); /// Add the given \p Attribute to \p Symbol. - virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute, - SMLoc Loc = SMLoc()) = 0; + virtual bool emitSymbolAttribute(MCSymbol *Symbol, + MCSymbolAttr Attribute) = 0; /// Set the \p DescValue for the \p Symbol. /// diff --git a/llvm/include/llvm/MC/MCWasmStreamer.h b/llvm/include/llvm/MC/MCWasmStreamer.h --- a/llvm/include/llvm/MC/MCWasmStreamer.h +++ b/llvm/include/llvm/MC/MCWasmStreamer.h @@ -44,8 +44,7 @@ void emitAssemblerFlag(MCAssemblerFlag Flag) override; void emitThumbFunc(MCSymbol *Func) override; void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; - bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute, - SMLoc) override; + bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; diff --git a/llvm/include/llvm/MC/MCWinCOFFStreamer.h b/llvm/include/llvm/MC/MCWinCOFFStreamer.h --- a/llvm/include/llvm/MC/MCWinCOFFStreamer.h +++ b/llvm/include/llvm/MC/MCWinCOFFStreamer.h @@ -43,8 +43,7 @@ void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void emitAssemblerFlag(MCAssemblerFlag Flag) override; void emitThumbFunc(MCSymbol *Func) override; - bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute, - SMLoc Loc = SMLoc()) override; + bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; void BeginCOFFSymbolDef(MCSymbol const *Symbol) override; void EmitCOFFSymbolStorageClass(int StorageClass) override; diff --git a/llvm/include/llvm/MC/MCXCOFFStreamer.h b/llvm/include/llvm/MC/MCXCOFFStreamer.h --- a/llvm/include/llvm/MC/MCXCOFFStreamer.h +++ b/llvm/include/llvm/MC/MCXCOFFStreamer.h @@ -19,8 +19,7 @@ std::unique_ptr OW, std::unique_ptr Emitter); - bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute, - SMLoc Loc = SMLoc()) override; + bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr, diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -157,8 +157,7 @@ void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; - bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute, - SMLoc) override; + bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; void BeginCOFFSymbolDef(const MCSymbol *Symbol) override; @@ -636,7 +635,7 @@ } bool MCAsmStreamer::emitSymbolAttribute(MCSymbol *Symbol, - MCSymbolAttr Attribute, SMLoc) { + MCSymbolAttr Attribute) { switch (Attribute) { case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute"); case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -187,8 +187,7 @@ return T2; } -bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute, - SMLoc Loc) { +bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) { auto *Symbol = cast(S); // Adding a symbol attribute always introduces the symbol, note that an @@ -230,8 +229,9 @@ // traditionally set the binding to STB_GLOBAL. This is error-prone, so we // error on such cases. Note, we also disallow changed binding from .local. if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_GLOBAL) - getContext().reportError(Loc, Symbol->getName() + - " changed binding to STB_GLOBAL"); + getContext().reportError(getStartTokLoc(), + Symbol->getName() + + " changed binding to STB_GLOBAL"); Symbol->setBinding(ELF::STB_GLOBAL); Symbol->setExternal(true); break; @@ -241,16 +241,17 @@ // For `.global x; .weak x`, both MC and GNU as set the binding to STB_WEAK. // We emit a warning for now but may switch to an error in the future. if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_WEAK) - getContext().reportWarning(Loc, Symbol->getName() + - " changed binding to STB_WEAK"); + getContext().reportWarning( + getStartTokLoc(), Symbol->getName() + " changed binding to STB_WEAK"); Symbol->setBinding(ELF::STB_WEAK); Symbol->setExternal(true); break; case MCSA_Local: if (Symbol->isBindingSet() && Symbol->getBinding() != ELF::STB_LOCAL) - getContext().reportError(Loc, Symbol->getName() + - " changed binding to STB_LOCAL"); + getContext().reportError(getStartTokLoc(), + Symbol->getName() + + " changed binding to STB_LOCAL"); Symbol->setBinding(ELF::STB_LOCAL); Symbol->setExternal(false); break; diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -93,8 +93,7 @@ void emitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion) override; void emitThumbFunc(MCSymbol *Func) override; - bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute, - SMLoc Loc = SMLoc()) override; + bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override; void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override; @@ -291,8 +290,8 @@ cast(Symbol)->setThumbFunc(); } -bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym, MCSymbolAttr Attribute, - SMLoc) { +bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym, + MCSymbolAttr Attribute) { MCSymbolMachO *Symbol = cast(Sym); // Indirect symbols are handled differently, to match how 'as' handles diff --git a/llvm/lib/MC/MCNullStreamer.cpp b/llvm/lib/MC/MCNullStreamer.cpp --- a/llvm/lib/MC/MCNullStreamer.cpp +++ b/llvm/lib/MC/MCNullStreamer.cpp @@ -25,7 +25,8 @@ bool hasRawTextSupport() const override { return true; } void emitRawTextImpl(StringRef String) override {} - bool emitSymbolAttribute(MCSymbol *, MCSymbolAttr, SMLoc) override { + bool emitSymbolAttribute(MCSymbol *Symbol, + MCSymbolAttr Attribute) override { return true; } diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -126,6 +126,7 @@ SourceMgr::DiagHandlerTy SavedDiagHandler; void *SavedDiagContext; std::unique_ptr PlatformParser; + SMLoc StartTokLoc; /// This is the current buffer index we're lexing from as managed by the /// SourceMgr object. @@ -709,6 +710,8 @@ // Set our own handler which calls the saved handler. SrcMgr.setDiagHandler(DiagHandler, this); Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer()); + // Make MCStreamer aware of the StartTokLoc for locations in diagnostics. + Out.setStartTokLocPtr(&StartTokLoc); // Initialize the platform / file format parser. switch (Ctx.getObjectFileInfo()->getObjectFileType()) { @@ -742,6 +745,8 @@ assert((HadError || ActiveMacros.empty()) && "Unexpected active macro instantiation!"); + // Remove MCStreamer's reference to the parser SMLoc. + Out.setStartTokLocPtr(nullptr); // Restore the saved diagnostics handler and context for use during // finalization. SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext); @@ -1705,6 +1710,7 @@ SMLoc IDLoc = ID.getLoc(); StringRef IDVal; int64_t LocalLabelVal = -1; + StartTokLoc = ID.getLoc(); if (Lexer.is(AsmToken::HashDirective)) return parseCppHashLineFilenameComment(IDLoc, !isInsideMacroInstantiation()); @@ -4881,7 +4887,7 @@ if (Sym->isTemporary()) return Error(Loc, "non-local symbol required"); - if (!getStreamer().emitSymbolAttribute(Sym, Attr, Loc)) + if (!getStreamer().emitSymbolAttribute(Sym, Attr)) return Error(Loc, "unable to emit symbol attribute"); return false; }; diff --git a/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/llvm/lib/MC/MCParser/ELFAsmParser.cpp --- a/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -178,13 +178,13 @@ if (getLexer().isNot(AsmToken::EndOfStatement)) { while (true) { StringRef Name; - SMLoc Loc = getTok().getLoc(); + if (getParser().parseIdentifier(Name)) return TokError("expected identifier in directive"); MCSymbol *Sym = getContext().getOrCreateSymbol(Name); - getStreamer().emitSymbolAttribute(Sym, Attr, Loc); + getStreamer().emitSymbolAttribute(Sym, Attr); if (getLexer().is(AsmToken::EndOfStatement)) break; diff --git a/llvm/lib/MC/MCWasmStreamer.cpp b/llvm/lib/MC/MCWasmStreamer.cpp --- a/llvm/lib/MC/MCWasmStreamer.cpp +++ b/llvm/lib/MC/MCWasmStreamer.cpp @@ -77,8 +77,7 @@ Alias->setVariableValue(Value); } -bool MCWasmStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute, - SMLoc) { +bool MCWasmStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) { assert(Attribute != MCSA_IndirectSymbol && "indirect symbols not supported"); auto *Symbol = cast(S); diff --git a/llvm/lib/MC/MCWinCOFFStreamer.cpp b/llvm/lib/MC/MCWinCOFFStreamer.cpp --- a/llvm/lib/MC/MCWinCOFFStreamer.cpp +++ b/llvm/lib/MC/MCWinCOFFStreamer.cpp @@ -107,8 +107,8 @@ llvm_unreachable("not implemented"); } -bool MCWinCOFFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute, - SMLoc) { +bool MCWinCOFFStreamer::emitSymbolAttribute(MCSymbol *S, + MCSymbolAttr Attribute) { auto *Symbol = cast(S); getAssembler().registerSymbol(*Symbol); diff --git a/llvm/lib/MC/MCXCOFFStreamer.cpp b/llvm/lib/MC/MCXCOFFStreamer.cpp --- a/llvm/lib/MC/MCXCOFFStreamer.cpp +++ b/llvm/lib/MC/MCXCOFFStreamer.cpp @@ -29,8 +29,8 @@ : MCObjectStreamer(Context, std::move(MAB), std::move(OW), std::move(Emitter)) {} -bool MCXCOFFStreamer::emitSymbolAttribute(MCSymbol *Sym, MCSymbolAttr Attribute, - SMLoc) { +bool MCXCOFFStreamer::emitSymbolAttribute(MCSymbol *Sym, + MCSymbolAttr Attribute) { auto *Symbol = cast(Sym); getAssembler().registerSymbol(*Symbol); diff --git a/llvm/lib/Object/RecordStreamer.h b/llvm/lib/Object/RecordStreamer.h --- a/llvm/lib/Object/RecordStreamer.h +++ b/llvm/lib/Object/RecordStreamer.h @@ -48,8 +48,7 @@ void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; - bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute, - SMLoc Loc) override; + bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; void emitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, SMLoc Loc = SMLoc()) override; void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, diff --git a/llvm/lib/Object/RecordStreamer.cpp b/llvm/lib/Object/RecordStreamer.cpp --- a/llvm/lib/Object/RecordStreamer.cpp +++ b/llvm/lib/Object/RecordStreamer.cpp @@ -97,7 +97,7 @@ } bool RecordStreamer::emitSymbolAttribute(MCSymbol *Symbol, - MCSymbolAttr Attribute, SMLoc) { + MCSymbolAttr Attribute) { if (Attribute == MCSA_Global || Attribute == MCSA_Weak) markGlobal(*Symbol, Attribute); if (Attribute == MCSA_LazyReference) @@ -226,7 +226,7 @@ // Don't use EmitAssignment override as it always marks alias as defined. MCStreamer::emitAssignment(Alias, Value); if (Attr != MCSA_Invalid) - emitSymbolAttribute(Alias, Attr, SMLoc()); + emitSymbolAttribute(Alias, Attr); } } } diff --git a/llvm/test/MC/ELF/symbol-binding-changed.s b/llvm/test/MC/ELF/symbol-binding-changed.s --- a/llvm/test/MC/ELF/symbol-binding-changed.s +++ b/llvm/test/MC/ELF/symbol-binding-changed.s @@ -1,17 +1,17 @@ # RUN: not llvm-mc -filetype=obj -triple=x86_64 %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error: -# CHECK: {{.*}}.s:[[#@LINE+3]]:8: error: local changed binding to STB_GLOBAL +# CHECK: {{.*}}.s:[[#@LINE+3]]:1: error: local changed binding to STB_GLOBAL local: .local local .globl local ## `.globl x; .weak x` matches the GNU as behavior. We issue a warning for now. -# CHECK: {{.*}}.s:[[#@LINE+3]]:7: warning: global changed binding to STB_WEAK +# CHECK: {{.*}}.s:[[#@LINE+3]]:1: warning: global changed binding to STB_WEAK global: .global global .weak global -# CHECK: {{.*}}.s:[[#@LINE+3]]:8: error: weak changed binding to STB_LOCAL +# CHECK: {{.*}}.s:[[#@LINE+3]]:1: error: weak changed binding to STB_LOCAL weak: .weak weak .local weak diff --git a/llvm/tools/llvm-exegesis/lib/SnippetFile.cpp b/llvm/tools/llvm-exegesis/lib/SnippetFile.cpp --- a/llvm/tools/llvm-exegesis/lib/SnippetFile.cpp +++ b/llvm/tools/llvm-exegesis/lib/SnippetFile.cpp @@ -89,8 +89,7 @@ // We only care about instructions, we don't implement this part of the API. void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) override {} - bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute, - SMLoc) override { + bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override { return false; } void emitValueToAlignment(unsigned ByteAlignment, int64_t Value, diff --git a/llvm/tools/llvm-mca/CodeRegionGenerator.cpp b/llvm/tools/llvm-mca/CodeRegionGenerator.cpp --- a/llvm/tools/llvm-mca/CodeRegionGenerator.cpp +++ b/llvm/tools/llvm-mca/CodeRegionGenerator.cpp @@ -52,7 +52,7 @@ Regions.addInstruction(Inst); } - bool emitSymbolAttribute(MCSymbol *, MCSymbolAttr, SMLoc) override { + bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override { return true; } diff --git a/llvm/unittests/CodeGen/TestAsmPrinter.h b/llvm/unittests/CodeGen/TestAsmPrinter.h --- a/llvm/unittests/CodeGen/TestAsmPrinter.h +++ b/llvm/unittests/CodeGen/TestAsmPrinter.h @@ -28,8 +28,8 @@ // These methods are pure virtual in MCStreamer, thus, have to be overridden: - MOCK_METHOD3(emitSymbolAttribute, - bool(MCSymbol *Symbol, MCSymbolAttr Attribute, SMLoc Loc)); + MOCK_METHOD2(emitSymbolAttribute, + bool(MCSymbol *Symbol, MCSymbolAttr Attribute)); MOCK_METHOD3(emitCommonSymbol, void(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment)); MOCK_METHOD5(emitZerofill,