From f2a35fbd60fbb86465ad2fb4d801cd5c240decd7 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Mon, 25 Jul 2011 17:55:35 +0000 Subject: [PATCH] Move some ELF directives into ELF asm parser. The .local, .hidden, .internal, and .protected are not legal for all supported file formats (in particular, they're invalid for MachO). Move the parsing for them into the ELF assembly parser since that's the format they're for. Similarly, .weak is used by COFF and ELF, but not MachO, so move the parsing to the COFF and ELF asm parsers. Previously, using any of these directives on Darwin would result in an assertion failure in the parser; now we get a diagnostic as we should. rdar://9827089 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135921 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/MCMachOStreamer.cpp | 1 - lib/MC/MCParser/AsmParser.cpp | 11 -------- lib/MC/MCParser/COFFAsmParser.cpp | 34 ++++++++++++++++++++++++ lib/MC/MCParser/ELFAsmParser.cpp | 44 +++++++++++++++++++++++++++++++ test/MC/AsmParser/labels.s | 3 --- 5 files changed, 78 insertions(+), 15 deletions(-) diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 625b6665c53..6dc82d15474 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -207,7 +207,6 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_ELF_TypeCommon: case MCSA_ELF_TypeNoType: case MCSA_ELF_TypeGnuUniqueObject: - case MCSA_IndirectSymbol: case MCSA_Hidden: case MCSA_Internal: case MCSA_Protected: diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 3fc113c6952..556fedbc4d4 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -1117,15 +1117,8 @@ bool AsmParser::ParseStatement() { if (IDVal == ".globl" || IDVal == ".global") return ParseDirectiveSymbolAttribute(MCSA_Global); - // ELF only? Should it be here? - if (IDVal == ".local") - return ParseDirectiveSymbolAttribute(MCSA_Local); - if (IDVal == ".hidden") - return ParseDirectiveSymbolAttribute(MCSA_Hidden); if (IDVal == ".indirect_symbol") return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol); - if (IDVal == ".internal") - return ParseDirectiveSymbolAttribute(MCSA_Internal); if (IDVal == ".lazy_reference") return ParseDirectiveSymbolAttribute(MCSA_LazyReference); if (IDVal == ".no_dead_strip") @@ -1134,12 +1127,8 @@ bool AsmParser::ParseStatement() { return ParseDirectiveSymbolAttribute(MCSA_SymbolResolver); if (IDVal == ".private_extern") return ParseDirectiveSymbolAttribute(MCSA_PrivateExtern); - if (IDVal == ".protected") - return ParseDirectiveSymbolAttribute(MCSA_Protected); if (IDVal == ".reference") return ParseDirectiveSymbolAttribute(MCSA_Reference); - if (IDVal == ".weak") - return ParseDirectiveSymbolAttribute(MCSA_Weak); if (IDVal == ".weak_definition") return ParseDirectiveSymbolAttribute(MCSA_WeakDefinition); if (IDVal == ".weak_reference") diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp index a1cc5cc21d0..af801df4eb5 100644 --- a/lib/MC/MCParser/COFFAsmParser.cpp +++ b/lib/MC/MCParser/COFFAsmParser.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCParser/MCAsmParserExtension.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" @@ -72,6 +73,7 @@ class COFFAsmParser : public MCAsmParserExtension { ".seh_pushframe"); AddDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>( ".seh_endprologue"); + AddDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); } bool ParseSectionDirectiveText(StringRef, SMLoc) { @@ -118,12 +120,44 @@ class COFFAsmParser : public MCAsmParserExtension { bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except); bool ParseSEHRegisterNumber(unsigned &RegNo); + bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc); public: COFFAsmParser() {} }; } // end annonomous namespace. +/// ParseDirectiveSymbolAttribute +/// ::= { ".weak", ... } [ identifier ( , identifier )* ] +bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { + MCSymbolAttr Attr = StringSwitch(Directive) + .Case(".weak", MCSA_Weak) + .Default(MCSA_Invalid); + assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); + if (getLexer().isNot(AsmToken::EndOfStatement)) { + for (;;) { + StringRef Name; + + if (getParser().ParseIdentifier(Name)) + return TokError("expected identifier in directive"); + + MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + + getStreamer().EmitSymbolAttribute(Sym, Attr); + + if (getLexer().is(AsmToken::EndOfStatement)) + break; + + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in directive"); + Lex(); + } + } + + Lex(); + return false; +} + bool COFFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Characteristics, SectionKind Kind) { diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index 972e2465d6f..d89112645cd 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -65,6 +65,14 @@ public: AddDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref"); + AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); + AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local"); + AddDirectiveHandler< + &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected"); + AddDirectiveHandler< + &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal"); + AddDirectiveHandler< + &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden"); } // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is @@ -134,6 +142,7 @@ public: bool ParseDirectiveIdent(StringRef, SMLoc); bool ParseDirectiveSymver(StringRef, SMLoc); bool ParseDirectiveWeakref(StringRef, SMLoc); + bool ParseDirectiveSymbolAttribute(StringRef, SMLoc); private: bool ParseSectionName(StringRef &SectionName); @@ -141,6 +150,41 @@ private: } +/// ParseDirectiveSymbolAttribute +/// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ] +bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { + MCSymbolAttr Attr = StringSwitch(Directive) + .Case(".weak", MCSA_Weak) + .Case(".local", MCSA_Local) + .Case(".hidden", MCSA_Hidden) + .Case(".internal", MCSA_Internal) + .Case(".protected", MCSA_Protected) + .Default(MCSA_Invalid); + assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); + if (getLexer().isNot(AsmToken::EndOfStatement)) { + for (;;) { + StringRef Name; + + if (getParser().ParseIdentifier(Name)) + return TokError("expected identifier in directive"); + + MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); + + getStreamer().EmitSymbolAttribute(Sym, Attr); + + if (getLexer().is(AsmToken::EndOfStatement)) + break; + + if (getLexer().isNot(AsmToken::Comma)) + return TokError("unexpected token in directive"); + Lex(); + } + } + + Lex(); + return false; +} + bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags, SectionKind Kind) { if (getLexer().isNot(AsmToken::EndOfStatement)) diff --git a/test/MC/AsmParser/labels.s b/test/MC/AsmParser/labels.s index 3bc7e630ce4..56091755d96 100644 --- a/test/MC/AsmParser/labels.s +++ b/test/MC/AsmParser/labels.s @@ -35,9 +35,6 @@ foo: // CHECK: .globl "a 3" .globl "a 3" -// CHECK: .weak "a 4" - .weak "a 4" - // CHECK: .desc "a 5",1 .desc "a 5", 1