llvm-mc: Parse symbol attribute directives.
authorDaniel Dunbar <daniel@zuster.org>
Tue, 30 Jun 2009 00:33:19 +0000 (00:33 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 30 Jun 2009 00:33:19 +0000 (00:33 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74487 91177308-0d34-0410-b5e6-96231b3b80d8

test/MC/AsmParser/directive_symbol_attrs.s [new file with mode: 0644]
tools/llvm-mc/AsmParser.cpp
tools/llvm-mc/AsmParser.h

diff --git a/test/MC/AsmParser/directive_symbol_attrs.s b/test/MC/AsmParser/directive_symbol_attrs.s
new file mode 100644 (file)
index 0000000..186e967
--- /dev/null
@@ -0,0 +1,7 @@
+# RUN: llvm-mc %s > %t
+
+# RUN: grep -A 3 TEST0 %t > %t2
+# RUN: grep ".globl a" %t2 | count 1
+# RUN: grep ".globl b" %t2 | count 1
+TEST0:  
+        .globl a, b
index 29222d4c0f6b0a85fa94dc46554d044362acded1..9a71139873d77653147a3ec169ec9dccb3c1ab95 100644 (file)
@@ -456,6 +456,32 @@ bool AsmParser::ParseStatement() {
     if (!strcmp(IDVal, ".space"))
       return ParseDirectiveSpace();
 
+    // Symbol attribute directives
+    if (!strcmp(IDVal, ".globl") || !strcmp(IDVal, ".global"))
+      return ParseDirectiveSymbolAttribute(MCStreamer::Global);
+    if (!strcmp(IDVal, ".hidden"))
+      return ParseDirectiveSymbolAttribute(MCStreamer::Hidden);
+    if (!strcmp(IDVal, ".indirect_symbol"))
+      return ParseDirectiveSymbolAttribute(MCStreamer::IndirectSymbol);
+    if (!strcmp(IDVal, ".internal"))
+      return ParseDirectiveSymbolAttribute(MCStreamer::Internal);
+    if (!strcmp(IDVal, ".lazy_reference"))
+      return ParseDirectiveSymbolAttribute(MCStreamer::LazyReference);
+    if (!strcmp(IDVal, ".no_dead_strip"))
+      return ParseDirectiveSymbolAttribute(MCStreamer::NoDeadStrip);
+    if (!strcmp(IDVal, ".private_extern"))
+      return ParseDirectiveSymbolAttribute(MCStreamer::PrivateExtern);
+    if (!strcmp(IDVal, ".protected"))
+      return ParseDirectiveSymbolAttribute(MCStreamer::Protected);
+    if (!strcmp(IDVal, ".reference"))
+      return ParseDirectiveSymbolAttribute(MCStreamer::Reference);
+    if (!strcmp(IDVal, ".weak"))
+      return ParseDirectiveSymbolAttribute(MCStreamer::Weak);
+    if (!strcmp(IDVal, ".weak_definition"))
+      return ParseDirectiveSymbolAttribute(MCStreamer::WeakDefinition);
+    if (!strcmp(IDVal, ".weak_reference"))
+      return ParseDirectiveSymbolAttribute(MCStreamer::WeakReference);
+
     Lexer.PrintMessage(IDLoc, "warning: ignoring directive for now");
     EatToEndOfStatement();
     return false;
@@ -802,3 +828,32 @@ bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
   return false;
 }
 
+/// ParseDirectiveSymbolAttribute
+///  ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
+bool AsmParser::ParseDirectiveSymbolAttribute(MCStreamer::SymbolAttr Attr) {
+  if (Lexer.isNot(asmtok::EndOfStatement)) {
+    for (;;) {
+      if (Lexer.isNot(asmtok::Identifier))
+        return TokError("expected identifier in directive");
+      
+      MCSymbol *Sym = Ctx.GetOrCreateSymbol(Lexer.getCurStrVal());
+      Lexer.Lex();
+
+      // If this is use of an undefined symbol then mark it external.
+      if (!Sym->getSection() && !Ctx.GetSymbolValue(Sym))
+        Sym->setExternal(true);
+
+      Out.EmitSymbolAttribute(Sym, Attr);
+
+      if (Lexer.is(asmtok::EndOfStatement))
+        break;
+
+      if (Lexer.isNot(asmtok::Comma))
+        return TokError("unexpected token in directive");
+      Lexer.Lex();
+    }
+  }
+
+  Lexer.Lex();
+  return false;  
+}
index aa885e6399379fc7887bfa17fe1f7659ff82a70d..f5e372ccd2589dc57714aef26da014effefb0364 100644 (file)
@@ -15,6 +15,7 @@
 #define ASMPARSER_H
 
 #include "AsmLexer.h"
+#include "llvm/MC/MCStreamer.h"
 
 namespace llvm {
 class AsmExpr;
@@ -81,6 +82,10 @@ private:
   bool ParseDirectiveOrg(); // ".org"
   // ".align{,32}", ".p2align{,w,l}"
   bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
+
+  /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
+  /// accepts a single symbol (which should be a label or an external).
+  bool ParseDirectiveSymbolAttribute(MCStreamer::SymbolAttr Attr);
   
 };