diff --git a/clang/test/CodeGenCXX/debug-info-byval.cpp b/clang/test/CodeGenCXX/debug-info-byval.cpp --- a/clang/test/CodeGenCXX/debug-info-byval.cpp +++ b/clang/test/CodeGenCXX/debug-info-byval.cpp @@ -24,7 +24,7 @@ EVT bar(); void get(int *i, unsigned dl, VAL v, VAL *p, unsigned n, EVT missing_arg) { -//CHECK: .{{asciz|string}} "missing_arg" +//CHECK: .{{asciz|string|byte}} "missing_arg" EVT e = bar(); if (dl == n) foo(missing_arg); diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -265,6 +265,11 @@ /// null. Defaults to null. const char *ByteListDirective = nullptr; + /// This directive allows emission of a zero-terminated ascii string without + /// the standard C escape characters embedded into it. If a target doesn't + /// support this, it can be set to null. Defaults to null. + const char *PlainStringDirective = nullptr; + /// Form used for character literals in the assembly syntax. Useful for /// producing strings as byte lists. If a target does not use or support /// this, it shall be set to ACLS_Unknown. Defaults to ACLS_Unknown. @@ -686,6 +691,7 @@ const char *getAsciiDirective() const { return AsciiDirective; } const char *getAscizDirective() const { return AscizDirective; } const char *getByteListDirective() const { return ByteListDirective; } + const char *getPlainStringDirective() const { return PlainStringDirective; } AsmCharLiteralSyntax characterLiteralSyntax() const { return CharacterLiteralSyntax; } diff --git a/llvm/lib/MC/MCAsmInfoXCOFF.cpp b/llvm/lib/MC/MCAsmInfoXCOFF.cpp --- a/llvm/lib/MC/MCAsmInfoXCOFF.cpp +++ b/llvm/lib/MC/MCAsmInfoXCOFF.cpp @@ -40,6 +40,7 @@ AsciiDirective = nullptr; // not supported AscizDirective = nullptr; // not supported ByteListDirective = "\t.byte\t"; + PlainStringDirective = "\t.string\t"; CharacterLiteralSyntax = ACLS_SingleQuotePrefix; // Use .vbyte for data definition to avoid directives that apply an implicit diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -1003,6 +1003,15 @@ EmitEOL(); } +static inline bool isPrintableString(StringRef Data) { + const auto BeginPtr = Data.begin(), EndPtr = Data.end(); + for (const unsigned char C : make_range(BeginPtr, EndPtr - 1)) { + if (!isPrint(C)) + return false; + } + return isPrint(Data.back()) || Data.back() == 0; +} + static inline char toOctal(int X) { return (X&7)+'0'; } static void PrintByteList(StringRef Data, raw_ostream &OS, @@ -1112,6 +1121,22 @@ Data = Data.substr(0, Data.size() - 1); } else if (LLVM_LIKELY(MAI->getAsciiDirective())) { OS << MAI->getAsciiDirective(); + } else if (MAI->hasPairedDoubleQuoteStringConstants() && + isPrintableString(Data)) { + // For target with DoubleQuoteString constants, .string and .byte are used + // as replacement of .asciz and .ascii. + assert(MAI->getPlainStringDirective() && + "hasPairedDoubleQuoteStringConstants target must support " + "PlainString Directive"); + assert(MAI->getByteListDirective() && + "hasPairedDoubleQuoteStringConstants target must support ByteList " + "Directive"); + if (Data.back() == 0) { + OS << MAI->getPlainStringDirective(); + Data = Data.substr(0, Data.size() - 1); + } else { + OS << MAI->getByteListDirective(); + } } else if (MAI->getByteListDirective()) { OS << MAI->getByteListDirective(); PrintByteList(Data, OS, MAI->characterLiteralSyntax()); diff --git a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll --- a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll +++ b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable-clobber-register.ll @@ -43,6 +43,6 @@ ; CHECK-ASM-NEXT: .vbyte 4, L..bar0-.bar # Function size ; CHECK-FUNC-NEXT: .vbyte 4, L..bar0-.bar[PR] # Function size ; COMMON-NEXT: .vbyte 2, 0x0003 # Function name len = 3 -; COMMON-NEXT: .byte 'b,'a,'r # Function Name +; COMMON-NEXT: .byte "bar" # Function Name ; COMMON-NEXT: .byte 0x1f # AllocaUsed ; COMMON-NEXT: # -- End function diff --git a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable.ll b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable.ll --- a/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable.ll +++ b/llvm/test/CodeGen/PowerPC/aix-emit-tracebacktable.ll @@ -162,7 +162,7 @@ ; CHECK-ASM-NEXT: .vbyte 4, L.._Z10add_structifd1SP2SD1Di0-._Z10add_structifd1SP2SD1Di # Function size ; CHECK-FUNC-NEXT: .vbyte 4, L.._Z10add_structifd1SP2SD1Di0-._Z10add_structifd1SP2SD1Di[PR] # Function size ; COMMON-NEXT: .vbyte 2, 0x001a # Function name len = 26 -; COMMON-NEXT: .byte '_,'Z,'1,'0,'a,'d,'d,'_,'s,'t,'r,'u,'c,'t,'i,'f,'d,'1,'S,'P,'2,'S,'D,'1,'D,'i # Function Name +; COMMON-NEXT: .byte "_Z10add_structifd1SP2SD1Di" # Function Name ; COMMON-NEXT: # -- End function @@ -190,7 +190,7 @@ ; CHECK-ASM-NEXT: .vbyte 4, L..main0-.main # Function size ; CHECK-FUNC-NEXT: .vbyte 4, L..main0-.main[PR] # Function size ; COMMON-NEXT: .vbyte 2, 0x0004 # Function name len = 4 -; COMMON-NEXT: .byte 'm,'a,'i,'n # Function Name +; COMMON-NEXT: .byte "main" # Function Name ; COMMON-NEXT: # -- End function @@ -214,5 +214,5 @@ ; CHECK-ASM-NEXT: .vbyte 4, L.._Z7add_bari1SfdP2SD1Di0-._Z7add_bari1SfdP2SD1Di # Function size ; CHECK-FUNC-NEXT: .vbyte 4, L.._Z7add_bari1SfdP2SD1Di0-._Z7add_bari1SfdP2SD1Di[PR] # Function size ; COMMON-NEXT: .vbyte 2, 0x0016 # Function name len = 22 -; COMMON-NEXT: .byte '_,'Z,'7,'a,'d,'d,'_,'b,'a,'r,'i,'1,'S,'f,'d,'P,'2,'S,'D,'1,'D,'i # Function Name +; COMMON-NEXT: .byte "_Z7add_bari1SfdP2SD1Di" # Function Name ; COMMON-NEXT: # -- End function diff --git a/llvm/test/CodeGen/PowerPC/aix-exception.ll b/llvm/test/CodeGen/PowerPC/aix-exception.ll --- a/llvm/test/CodeGen/PowerPC/aix-exception.ll +++ b/llvm/test/CodeGen/PowerPC/aix-exception.ll @@ -116,7 +116,7 @@ ; ASM: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack ; ASM: .vbyte 4, L.._Z9catchFuncv0-._Z9catchFuncv # Function size ; ASM: .vbyte 2, 0x000d # Function name len = 13 -; ASM: .byte '_,'Z,'9,'c,'a,'t,'c,'h,'F,'u,'n,'c,'v # Function Name +; ASM: .byte "_Z9catchFuncv" # Function Name ; ASM: .byte 0x08 # ExtensionTableFlag = TB_EH_INFO ; ASM: .align 2 ; ASM32: .vbyte 4, L..C1-TOC[TC0] # EHInfo Table diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-data-sections.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-data-sections.ll --- a/llvm/test/CodeGen/PowerPC/aix-xcoff-data-sections.ll +++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-data-sections.ll @@ -71,7 +71,7 @@ ; CHECK-NEXT: .comm a[RW],4,2 ; CHECK-NEXT: .comm f[RW],4,2 ; CHECK-NEXT: .csect .rodata.str1.1L...str[RO],2 -; CHECK-NEXT: .byte 'a,'b,'c,'d,'e,'f,'g,'h,0000 +; CHECK-NEXT: .string "abcdefgh" ; CHECK32: .csect p[RW],2 ; CHECK32-NEXT: .globl p[RW] ; CHECK32-NEXT: .align 2 diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll --- a/llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll +++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll @@ -86,7 +86,7 @@ ; CHECK: .globl chrarray ; CHECK-NEXT: chrarray: -; CHECK-NEXT: .byte 'a,'b,'c,'d +; CHECK-NEXT: .byte "abcd" ; CHECK: .globl dblarr ; CHECK-NEXT: .align 3 diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-mergeable-str.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-mergeable-str.ll --- a/llvm/test/CodeGen/PowerPC/aix-xcoff-mergeable-str.ll +++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-mergeable-str.ll @@ -44,7 +44,7 @@ ; CHECK-NEXT: L..strA: ; CHECK-NEXT: .byte 'h,'e,'l,'l,'o,' ,'w,'o,'r,'l,'d,'!,0012,0000 ; CHECK-NEXT: L...str: -; CHECK-NEXT: .byte 'a,'b,'c,'d,'e,'f,'g,'h,0000 +; CHECK-NEXT: .string "abcdefgh" ; CHECKOBJ: 00000010 <.rodata.str2.2>: ; CHECKOBJ-NEXT: 10: 01 08 01 10 diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-rodata.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-rodata.ll --- a/llvm/test/CodeGen/PowerPC/aix-xcoff-rodata.ll +++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-rodata.ll @@ -55,7 +55,7 @@ ; CHECK64-NEXT: .vbyte 8, 0x408c200000000000 ; CHECK-NEXT: .globl const_chrarray ; CHECK-NEXT: const_chrarray: -; CHECK-NEXT: .byte 'a,'b,'c,'d +; CHECK-NEXT: .byte "abcd" ; CHECK-NEXT: .globl const_dblarr ; CHECK-NEXT: .align 3 ; CHECK-NEXT: const_dblarr: diff --git a/llvm/test/DebugInfo/XCOFF/empty.ll b/llvm/test/DebugInfo/XCOFF/empty.ll --- a/llvm/test/DebugInfo/XCOFF/empty.ll +++ b/llvm/test/DebugInfo/XCOFF/empty.ll @@ -71,7 +71,7 @@ ; ASM32-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack ; ASM32-NEXT: .vbyte 4, L..main0-.main # Function size ; ASM32-NEXT: .vbyte 2, 0x0004 # Function name len = 4 -; ASM32-NEXT: .byte 'm,'a,'i,'n # Function Name +; ASM32-NEXT: .byte "main" # Function Name ; ASM32-NEXT: L..func_end0: ; ASM32-NEXT: # -- End function ; ASM32-NEXT: L..sec_end0: @@ -165,15 +165,15 @@ ; ASM32: .dwsect 0x70000 ; ASM32-NEXT: L...dwstr: ; ASM32-NEXT: L..info_string0: -; ASM32-NEXT: .byte 'c,'l,'a,'n,'g,' ,'v,'e,'r,'s,'i,'o,'n,' ,'1,'2,'.,'0,'.,'0,0000 # string offset=0 +; ASM32-NEXT: .string "clang version 12.0.0" # string offset=0 ; ASM32-NEXT: L..info_string1: -; ASM32-NEXT: .byte '1,'.,'c,0000 # string offset=21 +; ASM32-NEXT: .string "1.c" # string offset=21 ; ASM32-NEXT: L..info_string2: -; ASM32-NEXT: .byte 'd,'e,'b,'u,'g,0000 # string offset=25 +; ASM32-NEXT: .string "debug" # string offset=25 ; ASM32-NEXT: L..info_string3: -; ASM32-NEXT: .byte 'm,'a,'i,'n,0000 # string offset=31 +; ASM32-NEXT: .string "main" # string offset=31 ; ASM32-NEXT: L..info_string4: -; ASM32-NEXT: .byte 'i,'n,'t,0000 # string offset=36 +; ASM32-NEXT: .string "int" # string offset=36 ; ASM32-NEXT: .toc ; ASM32: .dwsect 0x20000 ; ASM32-NEXT: L...dwline: @@ -200,10 +200,10 @@ ; ASM32-NEXT: .byte 0 ; ASM32-NEXT: .byte 0 ; ASM32-NEXT: .byte 1 -; ASM32-NEXT: .byte 'd,'e,'b,'u,'g +; ASM32-NEXT: .byte "debug" ; ASM32-NEXT: .byte 0 ; ASM32-NEXT: .byte 0 -; ASM32-NEXT: .byte '1,'.,'c +; ASM32-NEXT: .byte "1.c" ; ASM32-NEXT: .byte 0 ; ASM32-NEXT: .byte 1 ; ASM32-NEXT: .byte 0 @@ -272,7 +272,7 @@ ; ASM64-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack ; ASM64-NEXT: .vbyte 4, L..main0-.main # Function size ; ASM64-NEXT: .vbyte 2, 0x0004 # Function name len = 4 -; ASM64-NEXT: .byte 'm,'a,'i,'n # Function Name +; ASM64-NEXT: .byte "main" # Function Name ; ASM64-NEXT: L..func_end0: ; ASM64-NEXT: # -- End function ; ASM64-NEXT: L..sec_end0: @@ -366,16 +366,16 @@ ; ASM64: .dwsect 0x70000 ; ASM64-NEXT: L...dwstr: ; ASM64-NEXT: L..info_string0: -; ASM64-NEXT: .byte 'c,'l,'a,'n,'g,' ,'v,'e,'r,'s,'i,'o,'n,' ,'1,'2,'.,'0,'.,'0,0000 # string offset=0 +; ASM64-NEXT: .string "clang version 12.0.0" # string offset=0 ; ASM64-NEXT: L..info_string1: -; ASM64-NEXT: .byte '1,'.,'c,0000 # string offset=21 +; ASM64-NEXT: .string "1.c" # string offset=21 ; ASM64-NEXT: L..info_string2: -; ASM64-NEXT: .byte 'd,'e,'b,'u,'g,0000 # string offset=25 +; ASM64-NEXT: .string "debug" # string offset=25 ; ASM64-NEXT: L..info_string3: -; ASM64-NEXT: .byte 'm,'a,'i,'n,0000 # string offset=31 +; ASM64-NEXT: .string "main" # string offset=31 ; ASM64-NEXT: L..info_string4: -; ASM64-NEXT: .byte 'i,'n,'t,0000 # string offset=36 -; ASM64-NEXT: .toc +; ASM64-NEXT: .string "int" # string offset=36 +; ASM64-NEXT: .toc ; ASM64: .dwsect 0x20000 ; ASM64-NEXT: L...dwline: ; ASM64-NEXT: L..debug_line_0: @@ -401,10 +401,10 @@ ; ASM64-NEXT: .byte 0 ; ASM64-NEXT: .byte 0 ; ASM64-NEXT: .byte 1 -; ASM64-NEXT: .byte 'd,'e,'b,'u,'g +; ASM64-NEXT: .byte "debug" ; ASM64-NEXT: .byte 0 ; ASM64-NEXT: .byte 0 -; ASM64-NEXT: .byte '1,'.,'c +; ASM64-NEXT: .byte "1.c" ; ASM64-NEXT: .byte 0 ; ASM64-NEXT: .byte 1 ; ASM64-NEXT: .byte 0 diff --git a/llvm/test/DebugInfo/XCOFF/explicit-section.ll b/llvm/test/DebugInfo/XCOFF/explicit-section.ll --- a/llvm/test/DebugInfo/XCOFF/explicit-section.ll +++ b/llvm/test/DebugInfo/XCOFF/explicit-section.ll @@ -77,7 +77,7 @@ ; CHECK-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack ; CHECK-NEXT: .vbyte 4, L..bar0-.bar # Function size ; CHECK-NEXT: .vbyte 2, 0x0003 # Function name len = 3 -; CHECK-NEXT: .byte 'b,'a,'r # Function Name +; CHECK-NEXT: .byte "bar" # Function Name ; CHECK-NEXT: L..func_end0: ; CHECK-NEXT: # -- End function ; CHECK-NEXT: .csect explicit_main_sec[PR],2 @@ -125,7 +125,7 @@ ; CHECK-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack ; CHECK-NEXT: .vbyte 4, L..main0-.main # Function size ; CHECK-NEXT: .vbyte 2, 0x0004 # Function name len = 4 -; CHECK-NEXT: .byte 'm,'a,'i,'n # Function Name +; CHECK-NEXT: .byte "main" # Function Name ; CHECK-NEXT: L..func_end1: ; CHECK-NEXT: # -- End function ; CHECK-NEXT: L..sec_end0: @@ -235,17 +235,17 @@ ; CHECK: .dwsect 0x70000 ; CHECK-NEXT: L...dwstr: ; CHECK-NEXT: L..info_string0: -; CHECK-NEXT: .byte 'c,'l,'a,'n,'g,' ,'v,'e,'r,'s,'i,'o,'n,' ,'1,'3,'.,'0,'.,'0,0000 # string offset=0 +; CHECK-NEXT: .string "clang version 13.0.0" # string offset=0 ; CHECK-NEXT: L..info_string1: -; CHECK-NEXT: .byte '2,'.,'c,0000 # string offset=21 +; CHECK-NEXT: .string "2.c" # string offset=21 ; CHECK-NEXT: L..info_string2: -; CHECK-NEXT: .byte 'd,'e,'b,'u,'g,0000 # string offset=25 +; CHECK-NEXT: .string "debug" # string offset=25 ; CHECK-NEXT: L..info_string3: -; CHECK-NEXT: .byte 'b,'a,'r,0000 # string offset=31 +; CHECK-NEXT: .string "bar" # string offset=31 ; CHECK-NEXT: L..info_string4: -; CHECK-NEXT: .byte 'i,'n,'t,0000 # string offset=35 +; CHECK-NEXT: .string "int" # string offset=35 ; CHECK-NEXT: L..info_string5: -; CHECK-NEXT: .byte 'm,'a,'i,'n,0000 # string offset=39 +; CHECK-NEXT: .string "main" # string offset=39 ; CHECK-NEXT: .toc ; CHECK: .dwsect 0x20000 ; CHECK-NEXT: L...dwline: @@ -271,10 +271,10 @@ ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .byte 1 -; CHECK-NEXT: .byte 'd,'e,'b,'u,'g +; CHECK-NEXT: .byte "debug" ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .byte 0 -; CHECK-NEXT: .byte '2,'.,'c +; CHECK-NEXT: .byte "2.c" ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .byte 1 ; CHECK-NEXT: .byte 0 diff --git a/llvm/test/DebugInfo/XCOFF/function-sections.ll b/llvm/test/DebugInfo/XCOFF/function-sections.ll --- a/llvm/test/DebugInfo/XCOFF/function-sections.ll +++ b/llvm/test/DebugInfo/XCOFF/function-sections.ll @@ -72,7 +72,7 @@ ; CHECK-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack ; CHECK-NEXT: .vbyte 4, L..foo0-.foo[PR] # Function size ; CHECK-NEXT: .vbyte 2, 0x0003 # Function name len = 3 -; CHECK-NEXT: .byte 'f,'o,'o # Function Name +; CHECK-NEXT: .byte "foo" # Function Name ; CHECK-NEXT: L..func_end0: ; CHECK-NEXT: # -- End function ; CHECK-NEXT: .csect .bar[PR],2 @@ -108,7 +108,7 @@ ; CHECK-NEXT: .byte 0x01 # NumberOfFPParms = 0, +HasParmsOnStack ; CHECK-NEXT: .vbyte 4, L..bar0-.bar[PR] # Function size ; CHECK-NEXT: .vbyte 2, 0x0003 # Function name len = 3 -; CHECK-NEXT: .byte 'b,'a,'r # Function Name +; CHECK-NEXT: .byte "bar" # Function Name ; CHECK-NEXT: L..func_end1: ; CHECK-NEXT: # -- End function ; CHECK-NEXT: L..sec_end0: @@ -222,17 +222,17 @@ ; CHECK: .dwsect 0x70000 ; CHECK-NEXT: L...dwstr: ; CHECK-NEXT: L..info_string0: -; CHECK-NEXT: .byte 'c,'l,'a,'n,'g,' ,'v,'e,'r,'s,'i,'o,'n,' ,'1,'3,'.,'0,'.,'0,0000 # string offset=0 +; CHECK-NEXT: .string "clang version 13.0.0" # string offset=0 ; CHECK-NEXT: L..info_string1: -; CHECK-NEXT: .byte '1,'.,'c,0000 # string offset=21 +; CHECK-NEXT: .string "1.c" # string offset=21 ; CHECK-NEXT: L..info_string2: -; CHECK-NEXT: .byte 'd,'e,'b,'u,'g,0000 # string offset=25 +; CHECK-NEXT: .string "debug" # string offset=25 ; CHECK-NEXT: L..info_string3: -; CHECK-NEXT: .byte 'f,'o,'o,0000 # string offset=31 +; CHECK-NEXT: .string "foo" # string offset=31 ; CHECK-NEXT: L..info_string4: -; CHECK-NEXT: .byte 'i,'n,'t,0000 # string offset=35 +; CHECK-NEXT: .string "int" # string offset=35 ; CHECK-NEXT: L..info_string5: -; CHECK-NEXT: .byte 'b,'a,'r,0000 # string offset=39 +; CHECK-NEXT: .string "bar" # string offset=39 ; CHECK-NEXT: .toc ; CHECK: .dwsect 0x20000 ; CHECK-NEXT: L...dwline: @@ -258,10 +258,10 @@ ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .byte 1 -; CHECK-NEXT: .byte 'd,'e,'b,'u,'g +; CHECK-NEXT: .byte "debug" ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .byte 0 -; CHECK-NEXT: .byte '1,'.,'c +; CHECK-NEXT: .byte "1.c" ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .byte 1 ; CHECK-NEXT: .byte 0