mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add SIL syntax for declaring debug variables.
Debug variable info may be attached to debug_value, debug_value_addr, alloc_box, and alloc_stack instructions. In order to write textual SIL -> SIL testcases that exercise the handling of debug information by SIL passes, we need to make a couple of additions to the textual SIL language. In memory, the debug information attached to SIL instructions references information from the AST. If we want to create debug info from parsing a textual .sil file, these bits need to be made explicit. Performance Notes: This is memory neutral for compilations from Swift source code, because the variable name is still stored in the AST. For compilations from textual source the variable name is stored in tail- allocated memory following the SIL instruction that introduces the variable. <rdar://problem/22707128>
This commit is contained in:
@@ -247,6 +247,7 @@ namespace {
|
||||
}
|
||||
bool parseSILOpcode(ValueKind &Opcode, SourceLoc &OpcodeLoc,
|
||||
StringRef &OpcodeName);
|
||||
bool parseSILDebugVar(SILDebugVariable &Var);
|
||||
|
||||
/// \brief Parses the basic block arguments as part of branch instruction.
|
||||
bool parseSILBBArgsAtBranch(SmallVector<SILValue, 6> &Args, SILBuilder &B);
|
||||
@@ -1322,6 +1323,40 @@ bool SILParser::parseSILOpcode(ValueKind &Opcode, SourceLoc &OpcodeLoc,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SILParser::parseSILDebugVar(SILDebugVariable &Var) {
|
||||
while (P.Tok.is(tok::comma)) {
|
||||
P.consumeToken();
|
||||
StringRef Key = P.Tok.getText();
|
||||
if (Key == "name") {
|
||||
P.consumeToken();
|
||||
if (P.Tok.getKind() != tok::string_literal) {
|
||||
P.diagnose(P.Tok, diag::expected_tok_in_sil_instr, "string");
|
||||
return true;
|
||||
}
|
||||
// Drop the double quotes.
|
||||
StringRef Val = P.Tok.getText().drop_front().drop_back();
|
||||
Var.Name = Val;
|
||||
} else if (Key == "argno") {
|
||||
P.consumeToken();
|
||||
if (P.Tok.getKind() != tok::integer_literal) {
|
||||
P.diagnose(P.Tok, diag::expected_tok_in_sil_instr, "integer");
|
||||
return true;
|
||||
}
|
||||
if (P.Tok.getText().getAsInteger(0, Var.ArgNo))
|
||||
return true;
|
||||
} else if (Key == "let") {
|
||||
Var.Constant = true;
|
||||
} else if (Key == "var") {
|
||||
Var.Constant = false;
|
||||
} else {
|
||||
P.diagnose(P.Tok, diag::sil_dbg_unknown_key, Key);
|
||||
return true;
|
||||
}
|
||||
P.consumeToken();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SILParser::parseSILBBArgsAtBranch(SmallVector<SILValue, 6> &Args,
|
||||
SILBuilder &B) {
|
||||
if (P.Tok.is(tok::l_paren)) {
|
||||
@@ -1659,7 +1694,10 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) {
|
||||
case ValueKind::AllocBoxInst: {
|
||||
SILType Ty;
|
||||
if (parseSILType(Ty)) return true;
|
||||
ResultVal = B.createAllocBox(InstLoc, Ty);
|
||||
SILDebugVariable VarInfo;
|
||||
if (parseSILDebugVar(VarInfo))
|
||||
return true;
|
||||
ResultVal = B.createAllocBox(InstLoc, Ty, VarInfo);
|
||||
break;
|
||||
}
|
||||
case ValueKind::ApplyInst:
|
||||
@@ -1944,34 +1982,47 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) {
|
||||
UNARY_INSTRUCTION(RetainValue)
|
||||
UNARY_INSTRUCTION(Load)
|
||||
UNARY_INSTRUCTION(CondFail)
|
||||
UNARY_INSTRUCTION(DebugValue)
|
||||
UNARY_INSTRUCTION(DebugValueAddr)
|
||||
#undef UNARY_INSTRUCTION
|
||||
|
||||
case ValueKind::LoadUnownedInst:
|
||||
case ValueKind::LoadWeakInst: {
|
||||
bool isTake = false;
|
||||
SourceLoc addrLoc;
|
||||
if (parseSILOptional(isTake, *this, "take") ||
|
||||
parseTypedValueRef(Val, addrLoc, B))
|
||||
return true;
|
||||
case ValueKind::DebugValueInst:
|
||||
case ValueKind::DebugValueAddrInst: {
|
||||
if (parseTypedValueRef(Val, B))
|
||||
return true;
|
||||
|
||||
if (Opcode == ValueKind::LoadUnownedInst) {
|
||||
if (!Val.getType().is<UnownedStorageType>()) {
|
||||
P.diagnose(addrLoc, diag::sil_operand_not_unowned_address,
|
||||
"source", OpcodeName);
|
||||
}
|
||||
ResultVal = B.createLoadUnowned(InstLoc, Val, IsTake_t(isTake));
|
||||
SILDebugVariable VarInfo;
|
||||
if (parseSILDebugVar(VarInfo))
|
||||
return true;
|
||||
if (Opcode == ValueKind::DebugValueInst)
|
||||
ResultVal = B.createDebugValue(InstLoc, Val, VarInfo);
|
||||
else
|
||||
ResultVal = B.createDebugValueAddr(InstLoc, Val, VarInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!Val.getType().is<WeakStorageType>()) {
|
||||
P.diagnose(addrLoc, diag::sil_operand_not_weak_address,
|
||||
"source", OpcodeName);
|
||||
}
|
||||
ResultVal = B.createLoadWeak(InstLoc, Val, IsTake_t(isTake));
|
||||
}
|
||||
case ValueKind::LoadUnownedInst:
|
||||
case ValueKind::LoadWeakInst: {
|
||||
bool isTake = false;
|
||||
SourceLoc addrLoc;
|
||||
if (parseSILOptional(isTake, *this, "take") ||
|
||||
parseTypedValueRef(Val, addrLoc, B))
|
||||
return true;
|
||||
|
||||
break;
|
||||
if (Opcode == ValueKind::LoadUnownedInst) {
|
||||
if (!Val.getType().is<UnownedStorageType>()) {
|
||||
P.diagnose(addrLoc, diag::sil_operand_not_unowned_address, "source",
|
||||
OpcodeName);
|
||||
}
|
||||
ResultVal = B.createLoadUnowned(InstLoc, Val, IsTake_t(isTake));
|
||||
|
||||
} else {
|
||||
if (!Val.getType().is<WeakStorageType>()) {
|
||||
P.diagnose(addrLoc, diag::sil_operand_not_weak_address, "source",
|
||||
OpcodeName);
|
||||
}
|
||||
ResultVal = B.createLoadWeak(InstLoc, Val, IsTake_t(isTake));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ValueKind::MarkDependenceInst: {
|
||||
@@ -2353,10 +2404,13 @@ bool SILParser::parseSILInstruction(SILBasicBlock *BB) {
|
||||
SILType Ty;
|
||||
if (parseSILType(Ty))
|
||||
return true;
|
||||
|
||||
if (Opcode == ValueKind::AllocStackInst)
|
||||
ResultVal = B.createAllocStack(InstLoc, Ty);
|
||||
else if (Opcode == ValueKind::AllocRefInst)
|
||||
|
||||
if (Opcode == ValueKind::AllocStackInst) {
|
||||
SILDebugVariable VarInfo;
|
||||
if (parseSILDebugVar(VarInfo))
|
||||
return true;
|
||||
ResultVal = B.createAllocStack(InstLoc, Ty, VarInfo);
|
||||
} else if (Opcode == ValueKind::AllocRefInst)
|
||||
ResultVal = B.createAllocRef(InstLoc, Ty, IsObjC, OnStack);
|
||||
else {
|
||||
assert(Opcode == ValueKind::MetatypeInst);
|
||||
|
||||
Reference in New Issue
Block a user