diff --git a/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/llvm/lib/MC/MCParser/COFFAsmParser.cpp --- a/llvm/lib/MC/MCParser/COFFAsmParser.cpp +++ b/llvm/lib/MC/MCParser/COFFAsmParser.cpp @@ -68,6 +68,10 @@ addDirectiveHandler<&COFFAsmParser::ParseDirectiveRVA>(".rva"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveCGProfile>(".cg_profile"); + addDirectiveHandler<&COFFAsmParser::ParseDirectivePushSection>( + ".pushsection"); + addDirectiveHandler<&COFFAsmParser::ParseDirectivePopSection>( + ".popsection"); // Win64 EH directives. addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>( @@ -126,6 +130,9 @@ bool ParseDirectiveLinkOnce(StringRef, SMLoc); bool ParseDirectiveRVA(StringRef, SMLoc); bool ParseDirectiveCGProfile(StringRef, SMLoc); + bool ParseDirectivePushSection(StringRef, SMLoc); + bool ParseDirectivePopSection(StringRef, SMLoc); + bool ParseSectionArguments(StringRef, SMLoc); // Win64 EH directives. bool ParseSEHDirectiveStartProc(StringRef, SMLoc); @@ -341,7 +348,12 @@ return false; } +bool COFFAsmParser::ParseDirectiveSection(StringRef Directive, SMLoc Loc) { + return ParseSectionArguments(Directive, Loc); +} + // .section name [, "flags"] [, identifier [ identifier ], identifier] +// .pushsection // // Supported flags: // a: Ignored. @@ -356,15 +368,14 @@ // y: Not-readable section (clears 'r') // // Subsections are not supported. -bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { +bool COFFAsmParser::ParseSectionArguments(StringRef, SMLoc) { StringRef SectionName; if (ParseSectionName(SectionName)) return TokError("expected identifier in directive"); unsigned Flags = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | - COFF::IMAGE_SCN_MEM_READ | - COFF::IMAGE_SCN_MEM_WRITE; + COFF::IMAGE_SCN_MEM_READ | COFF::IMAGE_SCN_MEM_WRITE; if (getLexer().is(AsmToken::Comma)) { Lex(); @@ -721,6 +732,23 @@ return false; } +bool COFFAsmParser::ParseDirectivePushSection(StringRef Directive, SMLoc Loc) { + getStreamer().pushSection(); + + if (ParseSectionArguments(Directive, Loc)) { + getStreamer().popSection(); + return true; + } + + return false; +} + +bool COFFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) { + if (!getStreamer().popSection()) + return TokError(".popsection without corresponding .pushsection"); + return false; +} + namespace llvm { MCAsmParserExtension *createCOFFAsmParser() { diff --git a/llvm/test/MC/COFF/section.s b/llvm/test/MC/COFF/section.s --- a/llvm/test/MC/COFF/section.s +++ b/llvm/test/MC/COFF/section.s @@ -208,3 +208,21 @@ // CHECK-NOT: Section { // CHECK: ] + +.section data1; .quad 0 + +.pushsection data2; .quad 0 +.popsection + +// Back to section data1 +.quad 2 + +// CHECK: Section { +// CHECK-NEXT: Number: +// CHECK-NEXT: Name: data1 +// CHECK: RawDataSize: 16 + +// CHECK: Section { +// CHECK-NEXT: Number: +// CHECK-NEXT: Name: data2 +// CHECK: RawDataSize: 8