diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index 28436f052d9..9e0662071cb 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -57,6 +57,8 @@ namespace llvm { /// reference and return it. /// /// @param Name - The symbol name, which must be unique across all symbols. + /// @param IsTemporary - Whether this symbol is an assembler temporary, + /// which should not survive into the symbol table for the translation unit. MCSymbol *GetOrCreateSymbol(const StringRef &Name); /// CreateTemporarySymbol - Create a new temporary symbol with the specified diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index 37a2755328f..631fa12f3f3 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -63,6 +63,11 @@ namespace llvm { /// @name Symbol Type /// @{ + /// isTemporary - Check if this is an assembler temporary symbol. + bool isTemporary() const { + return IsTemporary; + } + /// isDefined - Check if this symbol is defined (i.e., it has an address). /// /// Defined symbols are either absolute or in some section. diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 9efdfe359bb..9388df8df61 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -557,6 +557,10 @@ public: ie = Asm.symbol_end(); it != ie; ++it) { MCSymbol &Symbol = it->getSymbol(); + // Ignore assembler temporaries. + if (it->getSymbol().isTemporary()) + continue; + if (!it->isExternal() && !Symbol.isUndefined()) continue; @@ -589,6 +593,10 @@ public: ie = Asm.symbol_end(); it != ie; ++it) { MCSymbol &Symbol = it->getSymbol(); + // Ignore assembler temporaries. + if (it->getSymbol().isTemporary()) + continue; + if (it->isExternal() || Symbol.isUndefined()) continue; diff --git a/lib/MC/MCContext.cpp b/lib/MC/MCContext.cpp index 5a3e7f661ec..f36564a6afa 100644 --- a/lib/MC/MCContext.cpp +++ b/lib/MC/MCContext.cpp @@ -38,7 +38,6 @@ MCSymbol *MCContext::GetOrCreateSymbol(const StringRef &Name) { return Entry = new (*this) MCSymbol(Name, false); } - MCSymbol *MCContext::CreateTemporarySymbol(const StringRef &Name) { // If unnamed, just create a symbol. if (Name.empty()) diff --git a/test/MC/MachO/symbols-1.s b/test/MC/MachO/symbols-1.s index 2cf1311eb32..4c72fb3e7c2 100644 --- a/test/MC/MachO/symbols-1.s +++ b/test/MC/MachO/symbols-1.s @@ -13,8 +13,9 @@ sym_local_C: sym_globl_def_A: sym_globl_def_B: sym_globl_def_C: +Lsym_asm_temp: .long 0 - + // CHECK: ('cputype', 7) // CHECK: ('cpusubtype', 3) // CHECK: ('filetype', 1) diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp index 24c830127ac..467f8095e3d 100644 --- a/tools/llvm-mc/AsmParser.cpp +++ b/tools/llvm-mc/AsmParser.cpp @@ -129,6 +129,17 @@ bool AsmParser::ParseParenExpr(AsmExpr *&Res) { return false; } +MCSymbol *AsmParser::CreateSymbol(StringRef Name) { + if (MCSymbol *S = Ctx.LookupSymbol(Name)) + return S; + + // If the label starts with L it is an assembler temporary label. + if (Name.startswith("L")) + return Ctx.CreateTemporarySymbol(Name); + + return Ctx.CreateSymbol(Name); +} + /// ParsePrimaryExpr - Parse a primary expression and return it. /// primaryexpr ::= (parenexpr /// primaryexpr ::= symbol @@ -148,7 +159,7 @@ bool AsmParser::ParsePrimaryExpr(AsmExpr *&Res) { case AsmToken::Identifier: { // This is a label, this should be parsed as part of an expression, to // handle things like LFOO+4. - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Lexer.getTok().getIdentifier()); + MCSymbol *Sym = CreateSymbol(Lexer.getTok().getIdentifier()); Res = new AsmSymbolRefExpr(Sym); Lexer.Lex(); // Eat identifier. @@ -371,13 +382,11 @@ bool AsmParser::ParseStatement() { // FIXME: Diagnostics. Note the location of the definition as a label. // FIXME: This doesn't diagnose assignment to a symbol which has been // implicitly marked as external. - MCSymbol *Sym = Ctx.GetOrCreateSymbol(IDVal); + MCSymbol *Sym = CreateSymbol(IDVal); if (!Sym->isUndefined()) return Error(IDLoc, "invalid symbol redefinition"); - // 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? + // Emit the label. Out.EmitLabel(Sym); return ParseStatement(); @@ -683,7 +692,7 @@ bool AsmParser::ParseAssignment(const StringRef &Name, bool IsDotSet) { // FIXME: Diagnostics. Note the location of the definition as a label. // FIXME: Handle '.'. // FIXME: Diagnose assignment to protected identifier (e.g., register name). - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name); + MCSymbol *Sym = CreateSymbol(Name); if (!Sym->isUndefined() && !Sym->isAbsolute()) return Error(EqualLoc, "symbol has already been defined"); @@ -1110,7 +1119,7 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCStreamer::SymbolAttr Attr) { if (ParseIdentifier(Name)) return TokError("expected identifier in directive"); - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name); + MCSymbol *Sym = CreateSymbol(Name); Out.EmitSymbolAttribute(Sym, Attr); @@ -1135,7 +1144,7 @@ bool AsmParser::ParseDirectiveDarwinSymbolDesc() { return TokError("expected identifier in directive"); // Handle the identifier as the key symbol. - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name); + MCSymbol *Sym = CreateSymbol(Name); if (Lexer.isNot(AsmToken::Comma)) return TokError("unexpected token in '.desc' directive"); @@ -1166,7 +1175,7 @@ bool AsmParser::ParseDirectiveComm(bool IsLocal) { return TokError("expected identifier in directive"); // Handle the identifier as the key symbol. - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name); + MCSymbol *Sym = CreateSymbol(Name); if (Lexer.isNot(AsmToken::Comma)) return TokError("unexpected token in directive"); @@ -1258,7 +1267,7 @@ bool AsmParser::ParseDirectiveDarwinZerofill() { // handle the identifier as the key symbol. SMLoc IDLoc = Lexer.getLoc(); - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Lexer.getTok().getString()); + MCSymbol *Sym = CreateSymbol(Lexer.getTok().getString()); Lexer.Lex(); if (Lexer.isNot(AsmToken::Comma)) @@ -1363,7 +1372,7 @@ bool AsmParser::ParseDirectiveDarwinLsym() { return TokError("expected identifier in directive"); // Handle the identifier as the key symbol. - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name); + MCSymbol *Sym = CreateSymbol(Name); if (Lexer.isNot(AsmToken::Comma)) return TokError("unexpected token in '.lsym' directive"); diff --git a/tools/llvm-mc/AsmParser.h b/tools/llvm-mc/AsmParser.h index c4e505f14eb..21a7f46c70f 100644 --- a/tools/llvm-mc/AsmParser.h +++ b/tools/llvm-mc/AsmParser.h @@ -69,6 +69,8 @@ public: /// } private: + MCSymbol *CreateSymbol(StringRef Name); + bool ParseStatement(); bool TokError(const char *Msg);