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 @@ -56,6 +56,10 @@ addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data"); addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(".section"); + addDirectiveHandler<&COFFAsmParser::ParseDirectivePushSection>( + ".pushsection"); + addDirectiveHandler<&COFFAsmParser::ParseDirectivePopSection>( + ".popsection"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl"); addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type"); @@ -114,6 +118,9 @@ } bool ParseDirectiveSection(StringRef, SMLoc); + bool ParseSectionArguments(StringRef, SMLoc); + bool ParseDirectivePushSection(StringRef, SMLoc); + bool ParseDirectivePopSection(StringRef, SMLoc); bool ParseDirectiveDef(StringRef, SMLoc); bool ParseDirectiveScl(StringRef, SMLoc); bool ParseDirectiveType(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(); @@ -415,6 +426,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; +} + bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) { StringRef SymbolName; 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,69 @@ // 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 + +.section .data3,"dw"; .quad 1 + +.pushsection .data4,"dw"; .quad 1 +.popsection + +.pushsection .data5,"dr"; .quad 1 +.popsection + +# in section .data3 +.quad 4 + +# Notice the different section flags here. +# This shouldn't overwrite the intial section flags. +.pushsection .data4,"dr"; .quad 1 +.popsection + +// CHECK: Section { +// CHECK-NEXT: Number: +// CHECK-NEXT: Name: .data3 +// CHECK: RawDataSize: 16 +// CHECK: Characteristics [ +// CHECK-NEXT: IMAGE_SCN_ALIGN_1BYTES +// CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA +// CHECK-NEXT: IMAGE_SCN_MEM_READ +// CHECK-NEXT: IMAGE_SCN_MEM_WRITE +// CHECK-NEXT: ] + +// CHECK: Section { +// CHECK-NEXT: Number: +// CHECK-NEXT: Name: .data4 +// CHECK: RawDataSize: 16 +// CHECK: Characteristics [ +// CHECK-NEXT: IMAGE_SCN_ALIGN_1BYTES +// CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA +// CHECK-NEXT: IMAGE_SCN_MEM_READ +// CHECK-NEXT: IMAGE_SCN_MEM_WRITE +// CHECK-NEXT: ] + +// CHECK: Section { +// CHECK-NEXT: Number: +// CHECK-NEXT: Name: .data5 +// CHECK: RawDataSize: 8 +// CHECK: Characteristics [ +// CHECK-NEXT: IMAGE_SCN_ALIGN_1BYTES +// CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA +// CHECK-NEXT: IMAGE_SCN_MEM_READ +// CHECK-NEXT: ]