diff options
author | Nico Rieck <nico.rieck@gmail.com> | 2013-07-06 12:13:10 +0000 |
---|---|---|
committer | Nico Rieck <nico.rieck@gmail.com> | 2013-07-06 12:13:10 +0000 |
commit | 80646283796b20c6a1b7d8eb69ce6f0478d54383 (patch) | |
tree | 83b9be6b71faffa6cd481cea7736a172d36609ea /lib/MC/MCParser | |
parent | 2be430d251a781e76634e945d56224a7a0ef5a39 (diff) | |
download | llvm-80646283796b20c6a1b7d8eb69ce6f0478d54383.tar.gz llvm-80646283796b20c6a1b7d8eb69ce6f0478d54383.tar.bz2 llvm-80646283796b20c6a1b7d8eb69ce6f0478d54383.tar.xz |
MC: Implement COFF .linkonce directive
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185753 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r-- | lib/MC/MCParser/COFFAsmParser.cpp | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/lib/MC/MCParser/COFFAsmParser.cpp b/lib/MC/MCParser/COFFAsmParser.cpp index c2a22619db..df1794c979 100644 --- a/lib/MC/MCParser/COFFAsmParser.cpp +++ b/lib/MC/MCParser/COFFAsmParser.cpp @@ -51,6 +51,7 @@ class COFFAsmParser : public MCAsmParserExtension { addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32"); + addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce"); // Win64 EH directives. addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>( @@ -110,6 +111,7 @@ class COFFAsmParser : public MCAsmParserExtension { bool ParseDirectiveType(StringRef, SMLoc); bool ParseDirectiveEndef(StringRef, SMLoc); bool ParseDirectiveSecRel32(StringRef, SMLoc); + bool ParseDirectiveLinkOnce(StringRef, SMLoc); // Win64 EH directives. bool ParseSEHDirectiveStartProc(StringRef, SMLoc); @@ -407,6 +409,64 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) { return false; } +/// ParseDirectiveLinkOnce +/// ::= .linkonce [ identifier [ identifier ] ] +bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) { + COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY; + + if (getLexer().is(AsmToken::Identifier)) { + StringRef TypeId = getTok().getIdentifier(); + + Type = StringSwitch<COFF::COMDATType>(TypeId) + .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES) + .Case("discard", COFF::IMAGE_COMDAT_SELECT_ANY) + .Case("same_size", COFF::IMAGE_COMDAT_SELECT_SAME_SIZE) + .Case("same_contents", COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH) + .Case("associative", COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) + .Case("largest", COFF::IMAGE_COMDAT_SELECT_LARGEST) + .Case("newest", COFF::IMAGE_COMDAT_SELECT_NEWEST) + .Default((COFF::COMDATType)0); + + if (Type == 0) + return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'")); + + Lex(); + } + + const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>( + getStreamer().getCurrentSection().first); + + const MCSectionCOFF *Assoc = 0; + if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { + StringRef AssocName; + SMLoc Loc = getTok().getLoc(); + if (ParseSectionName(AssocName)) + return TokError("expected associated section name"); + + Assoc = static_cast<const MCSectionCOFF*>( + getContext().getCOFFSection(AssocName)); + if (!Assoc) + return Error(Loc, "cannot associate unknown section '" + AssocName + "'"); + if (Assoc == Current) + return Error(Loc, "cannot associate a section with itself"); + if (!(Assoc->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT)) + return Error(Loc, "associated section must be a COMDAT section"); + if (Assoc->getSelection() == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) + return Error(Loc, "associated section cannot be itself associative"); + } + + if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) + return Error(Loc, Twine("section '") + Current->getSectionName() + + "' is already linkonce"); + + Current->setSelection(Type, Assoc); + + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); + + return false; +} + bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) { StringRef SymbolID; if (getParser().parseIdentifier(SymbolID)) |