getParser().addDirectiveHandler(Directive, Handler);
}
- bool ParseSectionSwitch(StringRef Section, unsigned Type,
- unsigned Flags, SectionKind Kind);
- bool SeenIdent;
+ bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags,
+ SectionKind Kind);
public:
- ELFAsmParser() : SeenIdent(false) {
- BracketExpressionsSupported = true;
- }
+ ELFAsmParser() { BracketExpressionsSupported = true; }
virtual void Initialize(MCAsmParser &Parser) {
// Call the base implementation.
return SectionKind::getDataRel();
}
-static int parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) {
- int flags = 0;
+static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) {
+ unsigned flags = 0;
for (unsigned i = 0; i < flagsStr.size(); i++) {
switch (flagsStr[i]) {
case 'a':
flags |= ELF::SHF_ALLOC;
break;
+ case 'e':
+ flags |= ELF::SHF_EXCLUDE;
+ break;
case 'x':
flags |= ELF::SHF_EXECINSTR;
break;
*UseLastGroup = true;
break;
default:
- return -1;
+ return -1U;
}
}
StringRef FlagsStr = getTok().getStringContents();
Lex();
- int extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup);
- if (extraFlags < 0)
+ unsigned extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup);
+ if (extraFlags == -1U)
return TokError("unknown flag");
Flags |= extraFlags;
return TokError("Group section must specify the type");
} else {
Lex();
- if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At))
- return TokError("expected '@' or '%' before type");
+ if (getLexer().is(AsmToken::At) || getLexer().is(AsmToken::Percent) ||
+ getLexer().is(AsmToken::String)) {
+ if (!getLexer().is(AsmToken::String))
+ Lex();
+ } else
+ return TokError("expected '@<type>', '%<type>' or \"<type>\"");
- Lex();
if (getParser().parseIdentifier(TypeName))
return TokError("expected identifier in directive");
}
/// ParseDirectiveELFType
+/// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE>
+/// ::= .type identifier , #attribute
/// ::= .type identifier , @attribute
+/// ::= .type identifier , %attribute
+/// ::= .type identifier , "attribute"
bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
StringRef Name;
if (getParser().parseIdentifier(Name))
return TokError("unexpected token in '.type' directive");
Lex();
- if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At))
- return TokError("expected '@' or '%' before type");
- Lex();
-
StringRef Type;
SMLoc TypeLoc;
+ MCSymbolAttr Attr;
+ if (getLexer().is(AsmToken::Identifier)) {
+ TypeLoc = getLexer().getLoc();
+ if (getParser().parseIdentifier(Type))
+ return TokError("expected symbol type in directive");
+ Attr = StringSwitch<MCSymbolAttr>(Type)
+ .Case("STT_FUNC", MCSA_ELF_TypeFunction)
+ .Case("STT_OBJECT", MCSA_ELF_TypeObject)
+ .Case("STT_TLS", MCSA_ELF_TypeTLS)
+ .Case("STT_COMMON", MCSA_ELF_TypeCommon)
+ .Case("STT_NOTYPE", MCSA_ELF_TypeNoType)
+ .Case("STT_GNU_IFUNC", MCSA_ELF_TypeIndFunction)
+ .Default(MCSA_Invalid);
+ } else if (getLexer().is(AsmToken::Hash) || getLexer().is(AsmToken::At) ||
+ getLexer().is(AsmToken::Percent) ||
+ getLexer().is(AsmToken::String)) {
+ if (!getLexer().is(AsmToken::String))
+ Lex();
- TypeLoc = getLexer().getLoc();
- if (getParser().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)
- .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
- .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction)
- .Default(MCSA_Invalid);
+ TypeLoc = getLexer().getLoc();
+ if (getParser().parseIdentifier(Type))
+ return TokError("expected symbol type in directive");
+ 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)
+ .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
+ .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction)
+ .Default(MCSA_Invalid);
+ } else
+ return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
+ "'%<type>' or \"<type>\"");
if (Attr == MCSA_Invalid)
return Error(TypeLoc, "unsupported attribute in '.type' directive");
Lex();
- const MCSection *Comment =
- getContext().getELFSection(".comment", ELF::SHT_PROGBITS,
- ELF::SHF_MERGE |
- ELF::SHF_STRINGS,
- SectionKind::getReadOnly(),
- 1, "");
-
- getStreamer().PushSection();
- getStreamer().SwitchSection(Comment);
- if (!SeenIdent) {
- getStreamer().EmitIntValue(0, 1);
- SeenIdent = true;
- }
- getStreamer().EmitBytes(Data);
- getStreamer().EmitIntValue(0, 1);
- getStreamer().PopSection();
+ getStreamer().EmitIdent(Data);
return false;
}
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))