diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 3ccc4daa767..8dabb45e9ab 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -56,6 +56,13 @@ namespace llvm { /// @param Name - The symbol name, which must be unique across all symbols. MCSymbol *CreateSymbol(MCAtom *Atom, const char *Name); + /// GetOrCreateSymbol - Lookup the symbol inside with the specified + /// @param Name. If it exists, return it. If not, create a forward + /// reference and return it. + /// + /// @param Name - The symbol name, which must be unique across all symbols. + MCSymbol *GetOrCreateSymbol(const char *Name); + /// CreateTemporarySymbol - Create a new temporary symbol inside @param Atom /// with the specified @param Name. /// diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 1956c2e77bd..d268fb75e8f 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -84,8 +84,8 @@ void MCAsmStreamer::SwitchSection(MCSection *Section) { void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { // FIXME: We need to enforce that we aren't printing atoms which are more // complicated than the assembler understands. - assert(Symbol->getAtom()->getSection() == CurSection && - "The label for a symbol must match its section!"); + //assert(Symbol->getAtom()->getSection() == CurSection && + // "The label for a symbol must match its section!"); OS << Symbol->getName() << ":\n"; } diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index cad0d569902..f7793b918ca 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -44,6 +44,20 @@ MCSymbol *MCContext::CreateSymbol(MCAtom *Atom, const char *Name) { return Entry = new (*this) MCSymbol(Atom, Name, false); } +/// GetOrCreateSymbol - Lookup the symbol inside with the specified +/// @param Name. If it exists, return it. If not, create a forward +/// reference and return it. +/// +/// @param Name - The symbol name, which must be unique across all symbols. +MCSymbol *MCContext::GetOrCreateSymbol(const char *Name) { + MCSymbol *&Entry = Symbols[Name]; + if (Entry) return Entry; + + // FIXME: is a null atom the right way to make a forward ref? + return Entry = new (*this) MCSymbol(0, Name, false); +} + + MCSymbol *MCContext::CreateTemporarySymbol(MCAtom *Atom, const char *Name) { // If unnamed, just create a symbol. if (Name[0] == '\0') diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index 4dd136d0086..ca0b9338415 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -185,6 +185,12 @@ bool AsmParser::ParseStatement() { if (Lexer.Lex() == asmtok::Colon) { // identifier ':' -> Label. Lexer.Lex(); + + // Since we saw a label, create a symbol and emit it. + // FIXME: If the label starts with L it is an assembler temporary label. + // Why does the client of this api need to know this? + Out.EmitLabel(Ctx.GetOrCreateSymbol(IDVal)); + return ParseStatement(); } diff --git a/tools/llvm-mc/AsmParser.h b/tools/llvm-mc/AsmParser.h index 9a2c6dac4d9..95154485cda 100644 --- a/tools/llvm-mc/AsmParser.h +++ b/tools/llvm-mc/AsmParser.h @@ -17,17 +17,20 @@ #include "AsmLexer.h" namespace llvm { +class MCContext; class MCInst; class MCStreamer; class AsmParser { AsmLexer Lexer; + MCContext &Ctx; MCStreamer &Out; struct X86Operand; public: - AsmParser(SourceMgr &SM, MCStreamer &OutStr) : Lexer(SM), Out(OutStr) {} + AsmParser(SourceMgr &SM, MCContext &ctx, MCStreamer &OutStr) + : Lexer(SM), Ctx(ctx), Out(OutStr) {} ~AsmParser() {} bool Run(); diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index fe8af10fb8e..b999109f0bc 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -139,10 +139,9 @@ static int AssembleInput(const char *ProgName) { // it later. SrcMgr.setIncludeDirs(IncludeDirs); - // FIXME: don't leak streamer, own. MCContext Ctx; OwningPtr Str(createAsmStreamer(Ctx, outs())); - AsmParser Parser(SrcMgr, *Str.get()); + AsmParser Parser(SrcMgr, Ctx, *Str.get()); return Parser.Run(); }