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;
/// PushSection.
SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 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
TargetStreamer.reset(TS);
}
+ void setStartTokLocPtr(const SMLoc *Loc) { StartTokLocPtr = Loc; }
+ SMLoc getStartTokLoc() const {
+ return StartTokLocPtr ? *StartTokLocPtr : SMLoc();
+ }
+
/// State management
///
virtual void reset();
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.
///
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;
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;
std::unique_ptr<MCObjectWriter> OW,
std::unique_ptr<MCCodeEmitter> 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,
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;
}
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
return T2;
}
-bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute,
- SMLoc Loc) {
+bool MCELFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute) {
auto *Symbol = cast<MCSymbolELF>(S);
// Adding a symbol attribute always introduces the symbol, note that an
// 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;
// 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;
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;
cast<MCSymbolMachO>(Symbol)->setThumbFunc();
}
-bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym, MCSymbolAttr Attribute,
- SMLoc) {
+bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym,
+ MCSymbolAttr Attribute) {
MCSymbolMachO *Symbol = cast<MCSymbolMachO>(Sym);
// Indirect symbols are handled differently, to match how 'as' handles
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;
}
SourceMgr::DiagHandlerTy SavedDiagHandler;
void *SavedDiagContext;
std::unique_ptr<MCAsmParserExtension> PlatformParser;
+ SMLoc StartTokLoc;
/// This is the current buffer index we're lexing from as managed by the
/// SourceMgr object.
// 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()) {
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);
SMLoc IDLoc = ID.getLoc();
StringRef IDVal;
int64_t LocalLabelVal = -1;
+ StartTokLoc = ID.getLoc();
if (Lexer.is(AsmToken::HashDirective))
return parseCppHashLineFilenameComment(IDLoc,
!isInsideMacroInstantiation());
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;
};
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;
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<MCSymbolWasm>(S);
llvm_unreachable("not implemented");
}
-bool MCWinCOFFStreamer::emitSymbolAttribute(MCSymbol *S, MCSymbolAttr Attribute,
- SMLoc) {
+bool MCWinCOFFStreamer::emitSymbolAttribute(MCSymbol *S,
+ MCSymbolAttr Attribute) {
auto *Symbol = cast<MCSymbolCOFF>(S);
getAssembler().registerSymbol(*Symbol);
: 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<MCSymbolXCOFF>(Sym);
getAssembler().registerSymbol(*Symbol);
}
bool RecordStreamer::emitSymbolAttribute(MCSymbol *Symbol,
- MCSymbolAttr Attribute, SMLoc) {
+ MCSymbolAttr Attribute) {
if (Attribute == MCSA_Global || Attribute == MCSA_Weak)
markGlobal(*Symbol, Attribute);
if (Attribute == MCSA_LazyReference)
// 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);
}
}
}
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,
# 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
// 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,
Regions.addInstruction(Inst);
}
- bool emitSymbolAttribute(MCSymbol *, MCSymbolAttr, SMLoc) override {
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
return true;
}
// 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,