PPCAsmParser: Stop leaking names.

Store them in a place that gets cleaned up properly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187700 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2013-08-03 22:43:29 +00:00
parent bd194ced30
commit af00feb1a6

View File

@ -488,6 +488,20 @@ public:
return Op;
}
static PPCOperand *CreateTokenWithStringCopy(StringRef Str, SMLoc S,
bool IsPPC64) {
// Allocate extra memory for the string and copy it.
void *Mem = ::operator new(sizeof(PPCOperand) + Str.size());
PPCOperand *Op = new (Mem) PPCOperand(Token);
Op->Tok.Data = (const char *)(Op + 1);
Op->Tok.Length = Str.size();
std::memcpy((char *)(Op + 1), Str.data(), Str.size());
Op->StartLoc = S;
Op->EndLoc = S;
Op->IsPPC64 = IsPPC64;
return Op;
}
static PPCOperand *CreateImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {
PPCOperand *Op = new PPCOperand(Immediate);
Op->Imm.Val = Val;
@ -1184,29 +1198,36 @@ ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
// The first operand is the token for the instruction name.
// If the next character is a '+' or '-', we need to add it to the
// instruction name, to match what TableGen is doing.
std::string NewOpcode;
if (getLexer().is(AsmToken::Plus)) {
getLexer().Lex();
char *NewOpcode = new char[Name.size() + 1];
memcpy(NewOpcode, Name.data(), Name.size());
NewOpcode[Name.size()] = '+';
Name = StringRef(NewOpcode, Name.size() + 1);
NewOpcode = Name;
NewOpcode += '+';
Name = NewOpcode;
}
if (getLexer().is(AsmToken::Minus)) {
getLexer().Lex();
char *NewOpcode = new char[Name.size() + 1];
memcpy(NewOpcode, Name.data(), Name.size());
NewOpcode[Name.size()] = '-';
Name = StringRef(NewOpcode, Name.size() + 1);
NewOpcode = Name;
NewOpcode += '-';
Name = NewOpcode;
}
// If the instruction ends in a '.', we need to create a separate
// token for it, to match what TableGen is doing.
size_t Dot = Name.find('.');
StringRef Mnemonic = Name.slice(0, Dot);
Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
Operands.push_back(
PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
else
Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
if (Dot != StringRef::npos) {
SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot);
StringRef DotStr = Name.slice(Dot, StringRef::npos);
Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
Operands.push_back(
PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
else
Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
}
// If there are no more operands then finish