mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[AIX] Print printable byte list as quoted string
.byte supports string, so if the whole byte list are printable, we can actually print the string for readability and LIT tests maintainence. .byte 'H,'e,'l,'l,'o,',,' ,'w,'o,'r,'l,'d -> .byte "Hello, world" Reviewed By: hubert.reinterpretcast Differential Revision: https://reviews.llvm.org/D102814
This commit is contained in:
parent
5d6415281f
commit
068fb4deaa
@ -265,6 +265,11 @@ protected:
|
||||
/// 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 @@ public:
|
||||
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;
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ MCAsmInfoXCOFF::MCAsmInfoXCOFF() {
|
||||
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
|
||||
|
@ -1003,6 +1003,15 @@ void MCAsmStreamer::emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
|
||||
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 @@ void MCAsmStreamer::emitBytes(StringRef Data) {
|
||||
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());
|
||||
|
@ -43,6 +43,6 @@ entry:
|
||||
; 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
|
||||
|
@ -162,7 +162,7 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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
|
||||
|
@ -116,7 +116,7 @@ eh.resume: ; preds = %catch.dispatch
|
||||
; 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
|
||||
|
@ -71,7 +71,7 @@ entry:
|
||||
; 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
|
||||
|
@ -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
|
||||
|
@ -44,7 +44,7 @@ entry:
|
||||
; 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
|
||||
|
@ -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:
|
||||
|
@ -71,7 +71,7 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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
|
||||
|
@ -77,7 +77,7 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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
|
||||
|
@ -72,7 +72,7 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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 @@ entry:
|
||||
; 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
|
||||
|
Loading…
Reference in New Issue
Block a user