mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
Make MCInstrInfo available to the MCInstPrinter. This will be used to remove getInstructionName and the static data it contains since the same tables are already in MCInstrInfo.
llvm-svn: 153860
This commit is contained in:
parent
8ee5b8754f
commit
dbc259a436
@ -14,6 +14,7 @@ namespace llvm {
|
||||
class MCInst;
|
||||
class raw_ostream;
|
||||
class MCAsmInfo;
|
||||
class MCInstrInfo;
|
||||
class MCRegisterInfo;
|
||||
class StringRef;
|
||||
|
||||
@ -26,6 +27,7 @@ protected:
|
||||
/// assembly emission is disable.
|
||||
raw_ostream *CommentStream;
|
||||
const MCAsmInfo &MAI;
|
||||
const MCInstrInfo &MII;
|
||||
const MCRegisterInfo &MRI;
|
||||
|
||||
/// The current set of available features.
|
||||
@ -34,8 +36,9 @@ protected:
|
||||
/// Utility function for printing annotations.
|
||||
void printAnnotation(raw_ostream &OS, StringRef Annot);
|
||||
public:
|
||||
MCInstPrinter(const MCAsmInfo &mai, const MCRegisterInfo &mri)
|
||||
: CommentStream(0), MAI(mai), MRI(mri), AvailableFeatures(0) {}
|
||||
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
|
||||
const MCRegisterInfo &mri)
|
||||
: CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0) {}
|
||||
|
||||
virtual ~MCInstPrinter();
|
||||
|
||||
|
@ -104,6 +104,7 @@ namespace llvm {
|
||||
typedef MCInstPrinter *(*MCInstPrinterCtorTy)(const Target &T,
|
||||
unsigned SyntaxVariant,
|
||||
const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI);
|
||||
typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
|
||||
@ -393,11 +394,12 @@ namespace llvm {
|
||||
|
||||
MCInstPrinter *createMCInstPrinter(unsigned SyntaxVariant,
|
||||
const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
if (!MCInstPrinterCtorFn)
|
||||
return 0;
|
||||
return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MRI, STI);
|
||||
return MCInstPrinterCtorFn(*this, SyntaxVariant, MAI, MII, MRI, STI);
|
||||
}
|
||||
|
||||
|
||||
|
@ -172,6 +172,7 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
|
||||
case CGFT_AssemblyFile: {
|
||||
MCInstPrinter *InstPrinter =
|
||||
getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI,
|
||||
*getInstrInfo(),
|
||||
Context->getRegisterInfo(), STI);
|
||||
|
||||
// Create a code emitter if asked to show the encoding.
|
||||
|
@ -57,6 +57,9 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
|
||||
const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(TripleName);
|
||||
assert(MAI && "Unable to create target asm info!");
|
||||
|
||||
const MCInstrInfo *MII = TheTarget->createMCInstrInfo();
|
||||
assert(MII && "Unable to create target instruction info!");
|
||||
|
||||
const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(TripleName);
|
||||
assert(MRI && "Unable to create target register info!");
|
||||
|
||||
@ -80,7 +83,7 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo,
|
||||
// Set up the instruction printer.
|
||||
int AsmPrinterVariant = MAI->getAssemblerDialect();
|
||||
MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant,
|
||||
*MAI, *MRI, *STI);
|
||||
*MAI, *MII, *MRI, *STI);
|
||||
assert(IP && "Unable to create instruction printer!");
|
||||
|
||||
LLVMDisasmContext *DC = new LLVMDisasmContext(TripleName, DisInfo, TagType,
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstPrinter.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
@ -166,10 +167,15 @@ EDDisassembler::EDDisassembler(CPUKey &key) :
|
||||
|
||||
InstInfos = Disassembler->getEDInfo();
|
||||
|
||||
MII.reset(Tgt->createMCInstrInfo());
|
||||
|
||||
if (!MII)
|
||||
return;
|
||||
|
||||
InstString.reset(new std::string);
|
||||
InstStream.reset(new raw_string_ostream(*InstString));
|
||||
InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo,
|
||||
*MRI, *STI));
|
||||
*MII, *MRI, *STI));
|
||||
|
||||
if (!InstPrinter)
|
||||
return;
|
||||
|
@ -36,8 +36,9 @@ class MCContext;
|
||||
class MCAsmInfo;
|
||||
class MCAsmLexer;
|
||||
class MCDisassembler;
|
||||
class MCInstPrinter;
|
||||
class MCInst;
|
||||
class MCInstPrinter;
|
||||
class MCInstrInfo;
|
||||
class MCParsedAsmOperand;
|
||||
class MCRegisterInfo;
|
||||
class MCStreamer;
|
||||
@ -137,6 +138,8 @@ struct EDDisassembler {
|
||||
llvm::OwningPtr<const llvm::MCAsmInfo> AsmInfo;
|
||||
/// The subtarget information for the target architecture
|
||||
llvm::OwningPtr<const llvm::MCSubtargetInfo> STI;
|
||||
// The instruction information for the target architecture.
|
||||
llvm::OwningPtr<const llvm::MCInstrInfo> MII;
|
||||
// The register information for the target architecture.
|
||||
llvm::OwningPtr<const llvm::MCRegisterInfo> MRI;
|
||||
/// The disassembler for the target architecture
|
||||
|
@ -36,9 +36,10 @@ static unsigned translateShiftImm(unsigned imm) {
|
||||
|
||||
|
||||
ARMInstPrinter::ARMInstPrinter(const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI) :
|
||||
MCInstPrinter(MAI, MRI) {
|
||||
MCInstPrinter(MAI, MII, MRI) {
|
||||
// Initialize the set of available features.
|
||||
setAvailableFeatures(STI.getFeatureBits());
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ class MCOperand;
|
||||
|
||||
class ARMInstPrinter : public MCInstPrinter {
|
||||
public:
|
||||
ARMInstPrinter(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI);
|
||||
ARMInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI, const MCSubtargetInfo &STI);
|
||||
|
||||
virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
|
||||
virtual StringRef getOpcodeName(unsigned Opcode) const;
|
||||
|
@ -163,10 +163,11 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
|
||||
static MCInstPrinter *createARMMCInstPrinter(const Target &T,
|
||||
unsigned SyntaxVariant,
|
||||
const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI) {
|
||||
if (SyntaxVariant == 0)
|
||||
return new ARMInstPrinter(MAI, MRI, STI);
|
||||
return new ARMInstPrinter(MAI, MII, MRI, STI);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,9 @@ namespace llvm {
|
||||
|
||||
class MBlazeInstPrinter : public MCInstPrinter {
|
||||
public:
|
||||
MBlazeInstPrinter(const MCAsmInfo &MAI, const MCRegisterInfo &MRI)
|
||||
: MCInstPrinter(MAI, MRI) {}
|
||||
MBlazeInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI)
|
||||
: MCInstPrinter(MAI, MII, MRI) {}
|
||||
|
||||
virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
|
||||
|
||||
|
@ -95,10 +95,11 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
|
||||
static MCInstPrinter *createMBlazeMCInstPrinter(const Target &T,
|
||||
unsigned SyntaxVariant,
|
||||
const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI) {
|
||||
if (SyntaxVariant == 0)
|
||||
return new MBlazeInstPrinter(MAI, MRI);
|
||||
return new MBlazeInstPrinter(MAI, MII, MRI);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -21,8 +21,9 @@ namespace llvm {
|
||||
|
||||
class MSP430InstPrinter : public MCInstPrinter {
|
||||
public:
|
||||
MSP430InstPrinter(const MCAsmInfo &MAI, const MCRegisterInfo &MRI)
|
||||
: MCInstPrinter(MAI, MRI) {}
|
||||
MSP430InstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI)
|
||||
: MCInstPrinter(MAI, MII, MRI) {}
|
||||
|
||||
virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
|
||||
|
||||
|
@ -61,10 +61,11 @@ static MCCodeGenInfo *createMSP430MCCodeGenInfo(StringRef TT, Reloc::Model RM,
|
||||
static MCInstPrinter *createMSP430MCInstPrinter(const Target &T,
|
||||
unsigned SyntaxVariant,
|
||||
const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI) {
|
||||
if (SyntaxVariant == 0)
|
||||
return new MSP430InstPrinter(MAI, MRI);
|
||||
return new MSP430InstPrinter(MAI, MII, MRI);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -77,8 +77,9 @@ class TargetMachine;
|
||||
|
||||
class MipsInstPrinter : public MCInstPrinter {
|
||||
public:
|
||||
MipsInstPrinter(const MCAsmInfo &MAI, const MCRegisterInfo &MRI) :
|
||||
MCInstPrinter(MAI, MRI) {}
|
||||
MipsInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI)
|
||||
: MCInstPrinter(MAI, MII, MRI) {}
|
||||
|
||||
// Autogenerated by tblgen.
|
||||
void printInstruction(const MCInst *MI, raw_ostream &O);
|
||||
|
@ -78,9 +78,10 @@ static MCCodeGenInfo *createMipsMCCodeGenInfo(StringRef TT, Reloc::Model RM,
|
||||
static MCInstPrinter *createMipsMCInstPrinter(const Target &T,
|
||||
unsigned SyntaxVariant,
|
||||
const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI) {
|
||||
return new MipsInstPrinter(MAI, MRI);
|
||||
return new MipsInstPrinter(MAI, MII, MRI);
|
||||
}
|
||||
|
||||
static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
|
||||
|
@ -28,9 +28,10 @@ using namespace llvm;
|
||||
#include "PTXGenAsmWriter.inc"
|
||||
|
||||
PTXInstPrinter::PTXInstPrinter(const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI) :
|
||||
MCInstPrinter(MAI, MRI) {
|
||||
MCInstPrinter(MAI, MII, MRI) {
|
||||
// Initialize the set of available features.
|
||||
setAvailableFeatures(STI.getFeatureBits());
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ class MCOperand;
|
||||
|
||||
class PTXInstPrinter : public MCInstPrinter {
|
||||
public:
|
||||
PTXInstPrinter(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI);
|
||||
PTXInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI, const MCSubtargetInfo &STI);
|
||||
|
||||
virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
|
||||
virtual StringRef getOpcodeName(unsigned Opcode) const;
|
||||
|
@ -62,10 +62,11 @@ static MCCodeGenInfo *createPTXMCCodeGenInfo(StringRef TT, Reloc::Model RM,
|
||||
static MCInstPrinter *createPTXMCInstPrinter(const Target &T,
|
||||
unsigned SyntaxVariant,
|
||||
const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI) {
|
||||
assert(SyntaxVariant == 0 && "We only have one syntax variant");
|
||||
return new PTXInstPrinter(MAI, MRI, STI);
|
||||
return new PTXInstPrinter(MAI, MII, MRI, STI);
|
||||
}
|
||||
|
||||
extern "C" void LLVMInitializePTXTargetMC() {
|
||||
|
@ -24,9 +24,9 @@ class PPCInstPrinter : public MCInstPrinter {
|
||||
// 0 -> AIX, 1 -> Darwin.
|
||||
unsigned SyntaxVariant;
|
||||
public:
|
||||
PPCInstPrinter(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
|
||||
unsigned syntaxVariant)
|
||||
: MCInstPrinter(MAI, MRI), SyntaxVariant(syntaxVariant) {}
|
||||
PPCInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI, unsigned syntaxVariant)
|
||||
: MCInstPrinter(MAI, MII, MRI), SyntaxVariant(syntaxVariant) {}
|
||||
|
||||
bool isDarwinSyntax() const {
|
||||
return SyntaxVariant == 1;
|
||||
|
@ -108,9 +108,10 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
|
||||
static MCInstPrinter *createPPCMCInstPrinter(const Target &T,
|
||||
unsigned SyntaxVariant,
|
||||
const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI) {
|
||||
return new PPCInstPrinter(MAI, MRI, SyntaxVariant);
|
||||
return new PPCInstPrinter(MAI, MII, MRI, SyntaxVariant);
|
||||
}
|
||||
|
||||
extern "C" void LLVMInitializePowerPCTargetMC() {
|
||||
|
@ -22,8 +22,9 @@ class MCOperand;
|
||||
|
||||
class X86ATTInstPrinter : public MCInstPrinter {
|
||||
public:
|
||||
X86ATTInstPrinter(const MCAsmInfo &MAI, const MCRegisterInfo &MRI)
|
||||
: MCInstPrinter(MAI, MRI) {}
|
||||
X86ATTInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI)
|
||||
: MCInstPrinter(MAI, MII, MRI) {}
|
||||
|
||||
virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
|
||||
virtual void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot);
|
||||
|
@ -23,8 +23,9 @@ class MCOperand;
|
||||
|
||||
class X86IntelInstPrinter : public MCInstPrinter {
|
||||
public:
|
||||
X86IntelInstPrinter(const MCAsmInfo &MAI, const MCRegisterInfo &MRI)
|
||||
: MCInstPrinter(MAI, MRI) {}
|
||||
X86IntelInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI)
|
||||
: MCInstPrinter(MAI, MII, MRI) {}
|
||||
|
||||
virtual void printRegName(raw_ostream &OS, unsigned RegNo) const;
|
||||
virtual void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot);
|
||||
|
@ -474,12 +474,13 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
|
||||
static MCInstPrinter *createX86MCInstPrinter(const Target &T,
|
||||
unsigned SyntaxVariant,
|
||||
const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI) {
|
||||
if (SyntaxVariant == 0)
|
||||
return new X86ATTInstPrinter(MAI, MRI);
|
||||
return new X86ATTInstPrinter(MAI, MII, MRI);
|
||||
if (SyntaxVariant == 1)
|
||||
return new X86IntelInstPrinter(MAI, MRI);
|
||||
return new X86IntelInstPrinter(MAI, MII, MRI);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "llvm/MC/MCDisassembler.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstPrinter.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
@ -156,7 +157,8 @@ int Disassembler::disassemble(const Target &T,
|
||||
return -1;
|
||||
}
|
||||
|
||||
OwningPtr<const MCSubtargetInfo> STI(T.createMCSubtargetInfo(Triple, Cpu, FeaturesStr));
|
||||
OwningPtr<const MCSubtargetInfo> STI(T.createMCSubtargetInfo(Triple, Cpu,
|
||||
FeaturesStr));
|
||||
if (!STI) {
|
||||
errs() << "error: no subtarget info for target " << Triple << "\n";
|
||||
return -1;
|
||||
@ -174,9 +176,15 @@ int Disassembler::disassemble(const Target &T,
|
||||
return -1;
|
||||
}
|
||||
|
||||
OwningPtr<const MCInstrInfo> MII(T.createMCInstrInfo());
|
||||
if (!MII) {
|
||||
errs() << "error: no instruction info for target " << Triple << "\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
|
||||
OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant,
|
||||
*AsmInfo, *MRI, *STI));
|
||||
OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant, *AsmInfo,
|
||||
*MII, *MRI, *STI));
|
||||
if (!IP) {
|
||||
errs() << "error: no instruction printer for target " << Triple << '\n';
|
||||
return -1;
|
||||
|
@ -416,7 +416,7 @@ static int AssembleInput(const char *ProgName) {
|
||||
// FIXME: There is a bit of code duplication with addPassesToEmitFile.
|
||||
if (FileType == OFT_AssemblyFile) {
|
||||
MCInstPrinter *IP =
|
||||
TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MRI, *STI);
|
||||
TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI);
|
||||
MCCodeEmitter *CE = 0;
|
||||
MCAsmBackend *MAB = 0;
|
||||
if (ShowEncoding) {
|
||||
|
@ -260,8 +260,9 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
|
||||
OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
|
||||
OwningPtr<const MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
|
||||
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
|
||||
OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
|
||||
AsmPrinterVariant, *AsmInfo, *MRI, *STI));
|
||||
OwningPtr<MCInstPrinter>
|
||||
IP(TheTarget->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, *InstrInfo,
|
||||
*MRI, *STI));
|
||||
|
||||
if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) {
|
||||
errs() << "error: couldn't initialize disassembler for target "
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "llvm/MC/MCDisassembler.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstPrinter.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
@ -254,9 +255,15 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
|
||||
return;
|
||||
}
|
||||
|
||||
OwningPtr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo());
|
||||
if (!MII) {
|
||||
errs() << "error: no instruction info for target " << TripleName << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
|
||||
OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
|
||||
AsmPrinterVariant, *AsmInfo, *MRI, *STI));
|
||||
AsmPrinterVariant, *AsmInfo, *MII, *MRI, *STI));
|
||||
if (!IP) {
|
||||
errs() << "error: no instruction printer for target " << TripleName
|
||||
<< '\n';
|
||||
|
Loading…
Reference in New Issue
Block a user