Move some error handling down to MCStreamer.

This makes sure we get the same redefinition rules regardless of who
is printing (asm parser, codegen) and to what (asm, obj).

This fixes an unintentional regression in r293936.

llvm-svn: 294752
This commit is contained in:
Rafael Espindola 2017-02-10 15:13:12 +00:00
parent 01496fe455
commit be99157127
16 changed files with 37 additions and 34 deletions

View File

@ -41,7 +41,7 @@ public:
void InitSections(bool NoExecStack) override; void InitSections(bool NoExecStack) override;
void ChangeSection(MCSection *Section, const MCExpr *Subsection) override; void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
void EmitLabel(MCSymbol *Symbol) override; void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override; void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
void EmitThumbFunc(MCSymbol *Func) override; void EmitThumbFunc(MCSymbol *Func) override;
void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;

View File

@ -89,7 +89,7 @@ public:
/// \name MCStreamer Interface /// \name MCStreamer Interface
/// @{ /// @{
void EmitLabel(MCSymbol *Symbol) override; void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
void EmitValueImpl(const MCExpr *Value, unsigned Size, void EmitValueImpl(const MCExpr *Value, unsigned Size,
SMLoc Loc = SMLoc()) override; SMLoc Loc = SMLoc()) override;

View File

@ -398,7 +398,7 @@ public:
/// used in an assignment. /// used in an assignment.
// FIXME: These emission are non-const because we mutate the symbol to // FIXME: These emission are non-const because we mutate the symbol to
// add the section we're emitting it to later. // add the section we're emitting it to later.
virtual void EmitLabel(MCSymbol *Symbol); virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc());
virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol); virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol);

View File

@ -40,7 +40,7 @@ public:
/// \{ /// \{
void InitSections(bool NoExecStack) override; void InitSections(bool NoExecStack) override;
void EmitLabel(MCSymbol *Symbol) override; void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override; void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
void EmitThumbFunc(MCSymbol *Func) override; void EmitThumbFunc(MCSymbol *Func) override;
bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;

View File

@ -130,7 +130,7 @@ public:
void ChangeSection(MCSection *Section, const MCExpr *Subsection) override; void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override; void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
void EmitLabel(MCSymbol *Symbol) override; void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override; void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
void EmitLinkerOptions(ArrayRef<std::string> Options) override; void EmitLinkerOptions(ArrayRef<std::string> Options) override;
@ -397,9 +397,8 @@ void MCAsmStreamer::ChangeSection(MCSection *Section,
Subsection); Subsection);
} }
void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { void MCAsmStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); MCStreamer::EmitLabel(Symbol, Loc);
MCStreamer::EmitLabel(Symbol);
Symbol->print(OS, MAI); Symbol->print(OS, MAI);
OS << MAI->getLabelSuffix(); OS << MAI->getLabelSuffix();

View File

@ -93,11 +93,9 @@ void MCELFStreamer::InitSections(bool NoExecStack) {
SwitchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx)); SwitchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx));
} }
void MCELFStreamer::EmitLabel(MCSymbol *S) { void MCELFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc) {
auto *Symbol = cast<MCSymbolELF>(S); auto *Symbol = cast<MCSymbolELF>(S);
assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); MCObjectStreamer::EmitLabel(Symbol, Loc);
MCObjectStreamer::EmitLabel(Symbol);
const MCSectionELF &Section = const MCSectionELF &Section =
static_cast<const MCSectionELF &>(*getCurrentSectionOnly()); static_cast<const MCSectionELF &>(*getCurrentSectionOnly());

View File

@ -78,7 +78,7 @@ public:
/// @{ /// @{
void ChangeSection(MCSection *Sect, const MCExpr *Subsect) override; void ChangeSection(MCSection *Sect, const MCExpr *Subsect) override;
void EmitLabel(MCSymbol *Symbol) override; void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override; void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol) override;
void EmitAssemblerFlag(MCAssemblerFlag Flag) override; void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
@ -194,15 +194,13 @@ void MCMachOStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern); EmitSymbolAttribute(EHSymbol, MCSA_PrivateExtern);
} }
void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { void MCMachOStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
// We have to create a new fragment if this is an atom defining symbol, // We have to create a new fragment if this is an atom defining symbol,
// fragments cannot span atoms. // fragments cannot span atoms.
if (getAssembler().isSymbolLinkerVisible(*Symbol)) if (getAssembler().isSymbolLinkerVisible(*Symbol))
insert(new MCDataFragment()); insert(new MCDataFragment());
MCObjectStreamer::EmitLabel(Symbol); MCObjectStreamer::EmitLabel(Symbol, Loc);
// This causes the reference type flag to be cleared. Darwin 'as' was "trying" // This causes the reference type flag to be cleared. Darwin 'as' was "trying"
// to clear the weak reference and weak definition bits too, but the // to clear the weak reference and weak definition bits too, but the

View File

@ -153,8 +153,8 @@ void MCObjectStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
EmitLabel(Frame.End); EmitLabel(Frame.End);
} }
void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
MCStreamer::EmitLabel(Symbol); MCStreamer::EmitLabel(Symbol, Loc);
getAssembler().registerSymbol(*Symbol); getAssembler().registerSymbol(*Symbol);

View File

@ -1630,12 +1630,6 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
Sym = getContext().getOrCreateSymbol(IDVal); Sym = getContext().getOrCreateSymbol(IDVal);
} else } else
Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal); Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal);
Sym->redefineIfPossible();
if (!Sym->isUndefined() || Sym->isVariable())
return Error(IDLoc, "invalid symbol redefinition");
// End of Labels should be treated as end of line for lexing // End of Labels should be treated as end of line for lexing
// purposes but that information is not available to the Lexer who // purposes but that information is not available to the Lexer who
// does not understand Labels. This may cause us to see a Hash // does not understand Labels. This may cause us to see a Hash
@ -1654,7 +1648,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
// Emit the label. // Emit the label.
if (!ParsingInlineAsm) if (!ParsingInlineAsm)
Out.EmitLabel(Sym); Out.EmitLabel(Sym, IDLoc);
// If we are generating dwarf for assembly source files then gather the // If we are generating dwarf for assembly source files then gather the
// info to make a dwarf label entry for this label if needed. // info to make a dwarf label entry for this label if needed.

View File

@ -298,10 +298,17 @@ void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
SymbolOrdering[Symbol] = 1 + SymbolOrdering.size(); SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
} }
void MCStreamer::EmitLabel(MCSymbol *Symbol) { void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
Symbol->redefineIfPossible();
if (!Symbol->isUndefined() || Symbol->isVariable())
return getContext().reportError(Loc, "invalid symbol redefinition");
assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
assert(getCurrentSectionOnly() && "Cannot emit before setting section!"); assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!"); assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment()); Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
MCTargetStreamer *TS = getTargetStreamer(); MCTargetStreamer *TS = getTargetStreamer();

View File

@ -79,10 +79,9 @@ void MCWinCOFFStreamer::InitSections(bool NoExecStack) {
SwitchSection(getContext().getObjectFileInfo()->getTextSection()); SwitchSection(getContext().getObjectFileInfo()->getTextSection());
} }
void MCWinCOFFStreamer::EmitLabel(MCSymbol *S) { void MCWinCOFFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc) {
auto *Symbol = cast<MCSymbolCOFF>(S); auto *Symbol = cast<MCSymbolCOFF>(S);
assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); MCObjectStreamer::EmitLabel(Symbol, Loc);
MCObjectStreamer::EmitLabel(Symbol);
} }
void MCWinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { void MCWinCOFFStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {

View File

@ -82,7 +82,7 @@ void RecordStreamer::EmitInstruction(const MCInst &Inst,
MCStreamer::EmitInstruction(Inst, STI); MCStreamer::EmitInstruction(Inst, STI);
} }
void RecordStreamer::EmitLabel(MCSymbol *Symbol) { void RecordStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
MCStreamer::EmitLabel(Symbol); MCStreamer::EmitLabel(Symbol);
markDefined(*Symbol); markDefined(*Symbol);
} }

View File

@ -31,7 +31,7 @@ public:
const_iterator end(); const_iterator end();
RecordStreamer(MCContext &Context); RecordStreamer(MCContext &Context);
void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override; void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
void EmitLabel(MCSymbol *Symbol) override; void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override; bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size, void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,

View File

@ -55,7 +55,7 @@ void MipsELFStreamer::createPendingLabelRelocs() {
Labels.clear(); Labels.clear();
} }
void MipsELFStreamer::EmitLabel(MCSymbol *Symbol) { void MipsELFStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
MCELFStreamer::EmitLabel(Symbol); MCELFStreamer::EmitLabel(Symbol);
Labels.push_back(Symbol); Labels.push_back(Symbol);
} }

View File

@ -50,7 +50,7 @@ public:
/// Overriding this function allows us to record all labels that should be /// Overriding this function allows us to record all labels that should be
/// marked as microMIPS. Based on this data marking is done in /// marked as microMIPS. Based on this data marking is done in
/// EmitInstruction. /// EmitInstruction.
void EmitLabel(MCSymbol *Symbol) override; void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
/// Overriding this function allows us to dismiss all labels that are /// Overriding this function allows us to dismiss all labels that are
/// candidates for marking as microMIPS when .section directive is processed. /// candidates for marking as microMIPS when .section directive is processed.

View File

@ -0,0 +1,8 @@
; RUN: llc < %s -march=xcore
; we used to crash in this.
@bar = internal global i32 zeroinitializer
define void @".dp.bss"() {
ret void
}