Fix parsing of .symver directive on ARM
authorDavid Peixotto <dpeixott@codeaurora.org>
Wed, 15 Jan 2014 22:40:02 +0000 (22:40 +0000)
committerDavid Peixotto <dpeixott@codeaurora.org>
Wed, 15 Jan 2014 22:40:02 +0000 (22:40 +0000)
ARM assembly syntax uses @ for a comment, execpt for the second
parameter of the .symver directive which requires @ as part of the
symbol name. This commit fixes the parsing of this directive by
adding a special case for ARM for this one argumnet.

To make the change we had to move the AllowAtInIdentifier variable
to the MCAsmLexer interface (from AsmLexer) and expose a setter for
the value.  The ELFAsmParser then toggles this value when parsing
the second argument to the .symver directive for a target that
uses @ as a comment symbol

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

include/llvm/MC/MCParser/AsmLexer.h
include/llvm/MC/MCParser/MCAsmLexer.h
lib/MC/MCParser/ELFAsmParser.cpp
test/MC/ARM/arm-elf-symver.s [new file with mode: 0644]
test/MC/ARM/comment.s

index a97b450a46d87acf480698e33508cbf54760d472..1b3ab577519ba43d10d5505584bb0f121e1268b0 100644 (file)
@@ -30,7 +30,6 @@ class AsmLexer : public MCAsmLexer {
   const char *CurPtr;
   const MemoryBuffer *CurBuf;
   bool isAtStartOfLine;
-  bool AllowAtInIdentifier; // Cached here to avoid repeated MAI query.
 
   void operator=(const AsmLexer&) LLVM_DELETED_FUNCTION;
   AsmLexer(const AsmLexer&) LLVM_DELETED_FUNCTION;
index 53b380f12f715a68d5a7864d5317a966facf9f02..8edf3a4423f5b7b04b347581ffcc526164cf7d71 100644 (file)
@@ -118,6 +118,7 @@ class MCAsmLexer {
 protected: // Can only create subclasses.
   const char *TokStart;
   bool SkipSpace;
+  bool AllowAtInIdentifier;
 
   MCAsmLexer();
 
@@ -170,6 +171,9 @@ public:
 
   /// setSkipSpace - Set whether spaces should be ignored by the lexer
   void setSkipSpace(bool val) { SkipSpace = val; }
+
+  bool getAllowAtInIdentifier() { return AllowAtInIdentifier; }
+  void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; }
 };
 
 } // End llvm namespace
index 8807975e85457d9a3cf90cde140a7272c101d9f9..ca5532d4851eb52f5b7887ef2f1e76a3da153eae 100644 (file)
@@ -590,7 +590,14 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
   if (getLexer().isNot(AsmToken::Comma))
     return TokError("expected a comma");
 
+  // ARM assembly uses @ for a comment...
+  // except when parsing the second parameter of the .symver directive.
+  // Force the next symbol to allow @ in the identifier, which is
+  // required for this directive and then reset it to its initial state.
+  const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
+  getLexer().setAllowAtInIdentifier(true);
   Lex();
+  getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
 
   StringRef AliasName;
   if (getParser().parseIdentifier(AliasName))
diff --git a/test/MC/ARM/arm-elf-symver.s b/test/MC/ARM/arm-elf-symver.s
new file mode 100644 (file)
index 0000000..0d141b7
--- /dev/null
@@ -0,0 +1,152 @@
+@ RUN: llvm-mc -filetype=obj -triple arm-none-linux-gnueabi %s -o - | llvm-readobj -r -t | FileCheck %s
+@ RUN: llvm-mc -filetype=obj -triple thumb-none-linux-gnueabi %s -o - | llvm-readobj -r -t | FileCheck %s
+
+defined1:
+defined2:
+defined3:
+        .symver defined1, bar1@zed
+        .symver undefined1, bar2@zed
+
+        .symver defined2, bar3@@zed
+
+        .symver defined3, bar5@@@zed
+        .symver undefined3, bar6@@@zed
+
+        .long defined1
+        .long undefined1
+        .long defined2
+        .long defined3
+        .long undefined3
+
+        .global global1
+        .symver global1, g1@@zed
+global1:
+
+@ CHECK: Relocations [
+@ CHECK-NEXT:   Section (2) .rel.text {
+@ CHECK-NEXT:     0x0 R_ARM_ABS32 defined1 0x0
+@ CHECK-NEXT:     0x4 R_ARM_ABS32 bar2@zed 0x0
+@ CHECK-NEXT:     0x8 R_ARM_ABS32 defined2 0x0
+@ CHECK-NEXT:     0xC R_ARM_ABS32 defined3 0x0
+@ CHECK-NEXT:     0x10 R_ARM_ABS32 bar6@zed 0x0
+@ CHECK-NEXT:   }
+@ CHECK-NEXT: ]
+
+@ CHECK:  Symbol {
+@ CHECK:    Name: bar1@zed (28)
+@ CHECK-NEXT:     Value: 0x0
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Local (0x0)
+@ CHECK-NEXT:     Type: None (0x0)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section: .text (0x1)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT:   Symbol {
+@ CHECK-NEXT:     Name: bar3@@zed (46)
+@ CHECK-NEXT:     Value: 0x0
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Local (0x0)
+@ CHECK-NEXT:     Type: None (0x0)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section: .text (0x1)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT:   Symbol {
+@ CHECK-NEXT:     Name: bar5@@zed (56)
+@ CHECK-NEXT:     Value: 0x0
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Local (0x0)
+@ CHECK-NEXT:     Type: None (0x0)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section: .text (0x1)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT:   Symbol {
+@ CHECK-NEXT:     Name: defined1 (1)
+@ CHECK-NEXT:     Value: 0x0
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Local (0x0)
+@ CHECK-NEXT:     Type: None (0x0)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section: .text (0x1)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT:   Symbol {
+@ CHECK-NEXT:     Name: defined2 (10)
+@ CHECK-NEXT:     Value: 0x0
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Local (0x0)
+@ CHECK-NEXT:     Type: None (0x0)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section: .text (0x1)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT:   Symbol {
+@ CHECK-NEXT:     Name: defined3 (19)
+@ CHECK-NEXT:     Value: 0x0
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Local (0x0)
+@ CHECK-NEXT:     Type: None (0x0)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section: .text (0x1)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT:   Symbol {
+@ CHECK-NEXT:     Name: .text (0)
+@ CHECK-NEXT:     Value: 0x0
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Local (0x0)
+@ CHECK-NEXT:     Type: Section (0x3)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section: .text (0x1)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT:   Symbol {
+@ CHECK-NEXT:     Name: .data (0)
+@ CHECK-NEXT:     Value: 0x0
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Local (0x0)
+@ CHECK-NEXT:     Type: Section (0x3)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section: .data (0x3)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT:   Symbol {
+@ CHECK-NEXT:     Name: .bss (0)
+@ CHECK-NEXT:     Value: 0x0
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Local (0x0)
+@ CHECK-NEXT:     Type: Section (0x3)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section: .bss (0x4)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT:   Symbol {
+@ CHECK-NEXT:     Name: g1@@zed (88)
+@ CHECK-NEXT:     Value: 0x14
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Global (0x1)
+@ CHECK-NEXT:     Type: None (0x0)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section: .text (0x1)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT:   Symbol {
+@ CHECK-NEXT:     Name: global1 (80)
+@ CHECK-NEXT:     Value: 0x14
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Global (0x1)
+@ CHECK-NEXT:     Type: None (0x0)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section: .text (0x1)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT:   Symbol {
+@ CHECK-NEXT:     Name: bar2@zed (37)
+@ CHECK-NEXT:     Value: 0x0
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Global (0x1)
+@ CHECK-NEXT:     Type: None (0x0)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section:  (0x0)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT:   Symbol {
+@ CHECK-NEXT:     Name: bar6@zed (66)
+@ CHECK-NEXT:     Value: 0x0
+@ CHECK-NEXT:     Size: 0
+@ CHECK-NEXT:     Binding: Global (0x1)
+@ CHECK-NEXT:     Type: None (0x0)
+@ CHECK-NEXT:     Other: 0
+@ CHECK-NEXT:     Section:  (0x0)
+@ CHECK-NEXT:   }
+@ CHECK-NEXT: ]
index e95f313aca274d2bc5be381a3330debd57e4c48c..c24bc1aaa406d6fd32d559cde9bbfca7ad948eb0 100644 (file)
@@ -9,6 +9,18 @@ foo:
   .long baz@got
   add r0, r0@ignore this extra junk
 
+@ the symver directive should allow @ in the second symbol name
+defined1:
+defined2:
+defined3:
+bar:
+  .symver defined1, bar1@zed
+  .symver defined2, bar3@@zed
+  .symver defined3, bar5@@@zed
+
+far:
+  .long baz@got
+
 @CHECK-LABEL: foo:
 @CHECK: bl boo
 @CHECK-NOT: @
@@ -21,4 +33,15 @@ foo:
 @CHECK: add r0, r0
 @CHECK-NOT: @
 
+@CHECK-LABEL: bar:
+@CHECK: bar1@zed = defined1
+@CHECK: bar3@@zed = defined2
+@CHECK: bar5@@@zed = defined3
+
+@ Make sure we did not mess up the parser state and it still lexes
+@ comments correctly by excluding the @ in normal symbols
+@CHECK-LABEL: far:
+@CHECK:  .long baz
+@CHECK-NOT: @
+
 @ERROR-NOT: error: