diff options
| -rw-r--r-- | llvm/test/MC/AsmParser/directive_symbol_attrs.s | 7 | ||||
| -rw-r--r-- | llvm/tools/llvm-mc/AsmParser.cpp | 55 | ||||
| -rw-r--r-- | llvm/tools/llvm-mc/AsmParser.h | 5 | 
3 files changed, 67 insertions, 0 deletions
diff --git a/llvm/test/MC/AsmParser/directive_symbol_attrs.s b/llvm/test/MC/AsmParser/directive_symbol_attrs.s new file mode 100644 index 00000000000..186e9673950 --- /dev/null +++ b/llvm/test/MC/AsmParser/directive_symbol_attrs.s @@ -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 diff --git a/llvm/tools/llvm-mc/AsmParser.cpp b/llvm/tools/llvm-mc/AsmParser.cpp index 29222d4c0f6..9a71139873d 100644 --- a/llvm/tools/llvm-mc/AsmParser.cpp +++ b/llvm/tools/llvm-mc/AsmParser.cpp @@ -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;   +} diff --git a/llvm/tools/llvm-mc/AsmParser.h b/llvm/tools/llvm-mc/AsmParser.h index aa885e63993..f5e372ccd25 100644 --- a/llvm/tools/llvm-mc/AsmParser.h +++ b/llvm/tools/llvm-mc/AsmParser.h @@ -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);  };  | 

