diff options
author | Matt Fleming <matt@console-pimps.org> | 2010-05-21 11:36:59 +0000 |
---|---|---|
committer | Matt Fleming <matt@console-pimps.org> | 2010-05-21 11:36:59 +0000 |
commit | 924c5e58f2a7c89019000e7dee3391dcebdf8a21 (patch) | |
tree | a513b07de9c979d5ed1a619c98a1599250890c67 /lib/MC | |
parent | 24cdd2f82c73de23a183ec6d93498be34dc02de7 (diff) | |
download | external_llvm-924c5e58f2a7c89019000e7dee3391dcebdf8a21.zip external_llvm-924c5e58f2a7c89019000e7dee3391dcebdf8a21.tar.gz external_llvm-924c5e58f2a7c89019000e7dee3391dcebdf8a21.tar.bz2 |
Add support for parsing the ELF .type assembler directive.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104316 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r-- | lib/MC/MCParser/AsmLexer.cpp | 1 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 49 |
2 files changed, 50 insertions, 0 deletions
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp index 7c098a6..1cbe09a 100644 --- a/lib/MC/MCParser/AsmLexer.cpp +++ b/lib/MC/MCParser/AsmLexer.cpp @@ -281,6 +281,7 @@ AsmToken AsmLexer::LexToken() { case '*': return AsmToken(AsmToken::Star, StringRef(TokStart, 1)); case ',': return AsmToken(AsmToken::Comma, StringRef(TokStart, 1)); case '$': return AsmToken(AsmToken::Dollar, StringRef(TokStart, 1)); + case '@': return AsmToken(AsmToken::At, StringRef(TokStart, 1)); case '=': if (*CurPtr == '=') return ++CurPtr, AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2)); diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 3607522..0134519 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -13,6 +13,7 @@ #include "llvm/MC/MCParser/AsmParser.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" @@ -738,6 +739,8 @@ bool AsmParser::ParseStatement() { return ParseDirectiveSymbolAttribute(MCSA_Protected); if (IDVal == ".reference") return ParseDirectiveSymbolAttribute(MCSA_Reference); + if (IDVal == ".type") + return ParseDirectiveELFType(); if (IDVal == ".weak") return ParseDirectiveSymbolAttribute(MCSA_Weak); if (IDVal == ".weak_definition") @@ -1307,6 +1310,52 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) { return false; } +/// ParseDirectiveELFType +/// ::= .type identifier , @attribute +bool AsmParser::ParseDirectiveELFType() { + StringRef Name; + if (ParseIdentifier(Name)) + return TokError("expected identifier in directive"); + + // Handle the identifier as the key symbol. + MCSymbol *Sym = CreateSymbol(Name); + + if (Lexer.isNot(AsmToken::Comma)) + return TokError("unexpected token in '.type' directive"); + Lex(); + + if (Lexer.isNot(AsmToken::At)) + return TokError("expected '@' before type"); + Lex(); + + StringRef Type; + SMLoc TypeLoc; + + TypeLoc = Lexer.getLoc(); + if (ParseIdentifier(Type)) + return TokError("expected symbol type in directive"); + + MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type) + .Case("function", MCSA_ELF_TypeFunction) + .Case("object", MCSA_ELF_TypeObject) + .Case("tls_object", MCSA_ELF_TypeTLS) + .Case("common", MCSA_ELF_TypeCommon) + .Case("notype", MCSA_ELF_TypeNoType) + .Default(MCSA_Invalid); + + if (Attr == MCSA_Invalid) + return Error(TypeLoc, "unsupported attribute in '.type' directive"); + + if (Lexer.isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in '.type' directive"); + + Lex(); + + Out.EmitSymbolAttribute(Sym, Attr); + + return false; +} + /// ParseDirectiveDarwinSymbolDesc /// ::= .desc identifier , expression bool AsmParser::ParseDirectiveDarwinSymbolDesc() { |