diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h index 6e96e8becda..d132a732c41 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -181,6 +181,8 @@ public: MCContext &Ctx) { return 0; } + + virtual void onLabelParsed(MCSymbol *Symbol) { }; }; } // End llvm namespace diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 1fb8480b057..a91bd93105b 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -1262,6 +1262,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) { MCGenDwarfLabelEntry::Make(Sym, &getStreamer(), getSourceManager(), IDLoc); + getTargetParser().onLabelParsed(Sym); + // Consume any end of statement token, if present, to avoid spurious // AddBlankLine calls(). if (Lexer.is(AsmToken::EndOfStatement)) { diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 97b9db92363..ed71b37b471 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -74,6 +74,8 @@ class ARMAsmParser : public MCTargetAsmParser { // Map of register aliases registers via the .req directive. StringMap RegisterReqs; + bool NextSymbolIsThumb; + struct { ARMCC::CondCodes Cond; // Condition for IT block. unsigned Mask:4; // Condition mask for instructions. @@ -268,6 +270,8 @@ public: // Not in an ITBlock to start with. ITState.CurPosition = ~0U; + + NextSymbolIsThumb = false; } // Implementation of the MCTargetAsmParser interface: @@ -284,6 +288,8 @@ public: SmallVectorImpl &Operands, MCStreamer &Out, unsigned &ErrorInfo, bool MatchingInlineAsm); + void onLabelParsed(MCSymbol *Symbol); + }; } // end anonymous namespace @@ -7837,13 +7843,18 @@ bool ARMAsmParser::parseDirectiveARM(SMLoc L) { return false; } +void ARMAsmParser::onLabelParsed(MCSymbol *Symbol) { + if (NextSymbolIsThumb) { + getParser().getStreamer().EmitThumbFunc(Symbol); + NextSymbolIsThumb = false; + } +} + /// parseDirectiveThumbFunc /// ::= .thumbfunc symbol_name bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { const MCAsmInfo *MAI = getParser().getStreamer().getContext().getAsmInfo(); bool isMachO = MAI->hasSubsectionsViaSymbols(); - StringRef Name; - bool needFuncName = true; // Darwin asm has (optionally) function name after .thumb_func direction // ELF doesn't @@ -7852,29 +7863,19 @@ bool ARMAsmParser::parseDirectiveThumbFunc(SMLoc L) { if (Tok.isNot(AsmToken::EndOfStatement)) { if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) return Error(L, "unexpected token in .thumb_func directive"); - Name = Tok.getIdentifier(); + MCSymbol *Func = + getParser().getContext().GetOrCreateSymbol(Tok.getIdentifier()); + getParser().getStreamer().EmitThumbFunc(Func); Parser.Lex(); // Consume the identifier token. - needFuncName = false; + return false; } } if (getLexer().isNot(AsmToken::EndOfStatement)) return Error(L, "unexpected token in directive"); - // Eat the end of statement and any blank lines that follow. - while (getLexer().is(AsmToken::EndOfStatement)) - Parser.Lex(); + NextSymbolIsThumb = true; - // FIXME: assuming function name will be the line following .thumb_func - // We really should be checking the next symbol definition even if there's - // stuff in between. - if (needFuncName) { - Name = Parser.getTok().getIdentifier(); - } - - // Mark symbol as a thumb symbol. - MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name); - getParser().getStreamer().EmitThumbFunc(Func); return false; } diff --git a/test/MC/ARM/elf-thumbfunc.s b/test/MC/ARM/elf-thumbfunc.s index 26f5f0b159a..0ea11821b96 100644 --- a/test/MC/ARM/elf-thumbfunc.s +++ b/test/MC/ARM/elf-thumbfunc.s @@ -5,9 +5,9 @@ .text .globl foo .align 2 - .type foo,%function .code 16 .thumb_func + .type foo,%function foo: bx lr