ARM: allow .thumb_func to be separated from symbol definition
authorTim Northover <tnorthover@apple.com>
Fri, 25 Oct 2013 12:49:50 +0000 (12:49 +0000)
committerTim Northover <tnorthover@apple.com>
Fri, 25 Oct 2013 12:49:50 +0000 (12:49 +0000)
When assembling, a .thumb_func directive is supposed to be applicable to the
next symbol definition, even if there are intervening directives. We were
racing ahead to try and find it, and this commit should fix the issue.

Patch by Gabor Ballabas

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193403 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCTargetAsmParser.h
lib/MC/MCParser/AsmParser.cpp
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/elf-thumbfunc.s

index 6e96e8becdab1e31d2e4586fff2407e329a03daa..d132a732c4163af55720128d2cb926b567ee57ed 100644 (file)
@@ -181,6 +181,8 @@ public:
                                             MCContext &Ctx) {
     return 0;
   }
+
+  virtual void onLabelParsed(MCSymbol *Symbol) { };
 };
 
 } // End llvm namespace
index 1fb8480b057130e750a5f77ff654845a9d2c214c..a91bd93105b653ad603efcb7aa324dbda6ddf46a 100644 (file)
@@ -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)) {
index 97b9db9236315db35d23c772d1268b3837287ee1..ed71b37b47170309b75898a8693ab0d34dd842ed 100644 (file)
@@ -74,6 +74,8 @@ class ARMAsmParser : public MCTargetAsmParser {
   // Map of register aliases registers via the .req directive.
   StringMap<unsigned> 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<MCParsedAsmOperand*> &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();
-
-  // 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();
-  }
+  NextSymbolIsThumb = true;
 
-  // Mark symbol as a thumb symbol.
-  MCSymbol *Func = getParser().getContext().GetOrCreateSymbol(Name);
-  getParser().getStreamer().EmitThumbFunc(Func);
   return false;
 }
 
index 26f5f0b159afb1fd686b6faaae5ccc2bd1dda29b..0ea11821b96ba6ada8712999d0bffef74eccb673 100644 (file)
@@ -5,9 +5,9 @@
        .text
        .globl  foo
        .align  2
-       .type   foo,%function
        .code   16
        .thumb_func
+       .type   foo,%function
 foo:
        bx      lr