Skip to content

Commit ab2b421

Browse files
Merge pull request #6505 from adrian-prantl/variadic-expression-context
Add support for generic expression evaluation in variadic generic con…
2 parents a293232 + 58a6524 commit ab2b421

File tree

12 files changed

+421
-149
lines changed

12 files changed

+421
-149
lines changed

lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ void SwiftASTManipulatorBase::DoInitialization() {
9494
swift::FuncDecl *entrypoint_decl = nullptr;
9595
/// This is optional.
9696
swift::FuncDecl *ext_method_decl = nullptr;
97+
/// When evaluating a generic expression this is the inner
98+
/// function containing the user expression.
99+
swift::FuncDecl *user_expr_decl = nullptr;
97100
/// When evaluating self as generic, this is the trampoline function that
98101
/// calls the ext_method_decl.
99102
swift::FuncDecl *trampoline_decl = nullptr;
@@ -128,6 +131,8 @@ void SwiftASTManipulatorBase::DoInitialization() {
128131
entrypoint_decl = FD;
129132
else if (FD->getNameStr().equals("$__lldb_sink"))
130133
sink_decl = FD;
134+
else if (FD->getNameStr().equals("$__lldb_user_expr"))
135+
user_expr_decl = FD;
131136
return Action::SkipChildren();
132137
}
133138
};
@@ -136,16 +141,17 @@ void SwiftASTManipulatorBase::DoInitialization() {
136141
m_source_file.walk(func_finder);
137142

138143
m_extension_decl = func_finder.extension_decl;
139-
if (m_extension_decl) {
144+
if (func_finder.ext_method_decl) {
140145
m_function_decl = func_finder.ext_method_decl;
141146
m_entrypoint_decl = func_finder.entrypoint_decl;
142-
m_trampoline_decl = func_finder.trampoline_decl;
143-
m_sink_decl = func_finder.sink_decl;
144-
} else {
147+
} else if (func_finder.user_expr_decl) {
148+
m_function_decl = func_finder.user_expr_decl;
149+
m_entrypoint_decl = func_finder.entrypoint_decl;
150+
} else
145151
m_function_decl = func_finder.entrypoint_decl;
146-
m_entrypoint_decl = nullptr;
147-
}
148-
152+
m_entrypoint_decl = func_finder.entrypoint_decl;
153+
m_trampoline_decl = func_finder.trampoline_decl;
154+
m_sink_decl = func_finder.sink_decl;
149155
assert(m_function_decl);
150156

151157
// Find the body in the function
@@ -698,25 +704,24 @@ bool SwiftASTManipulator::FixupResultAfterTypeChecking(Status &error) {
698704
swift::Type result_type;
699705
for (size_t i = 0; i < num_results; i++) {
700706
swift::VarDecl *the_decl = m_result_info[i].tmp_var_decl;
701-
if (the_decl->hasInterfaceType()) {
702-
swift::Type its_type = the_decl->getType();
703-
if (result_type.isNull()) {
704-
result_type = its_type;
705-
} else if (!its_type.getPointer()->isEqual(result_type)) {
706-
std::string prev_type_name = result_type.getPointer()->getString();
707-
std::string cur_type_name = its_type.getPointer()->getString();
708-
709-
error.SetErrorStringWithFormat(
710-
"Type for %zuth return value is inconsistent, previous type: %s, "
711-
"current type: %s.",
712-
i, prev_type_name.c_str(), cur_type_name.c_str());
713-
return false;
714-
}
715-
} else {
707+
if (!the_decl->hasInterfaceType()) {
716708
error.SetErrorStringWithFormat(
717709
"Type of %zuth return value could not be determined.", i);
718710
return false;
719711
}
712+
swift::Type its_type = the_decl->getType();
713+
if (result_type.isNull()) {
714+
result_type = its_type;
715+
} else if (!its_type.getPointer()->isEqual(result_type)) {
716+
std::string prev_type_name = result_type.getPointer()->getString();
717+
std::string cur_type_name = its_type.getPointer()->getString();
718+
719+
error.SetErrorStringWithFormat(
720+
"Type for %zuth return value is inconsistent, previous type: %s, "
721+
"current type: %s.",
722+
i, prev_type_name.c_str(), cur_type_name.c_str());
723+
return false;
724+
}
720725
}
721726

722727
if (result_type.isNull()) {
@@ -728,7 +733,6 @@ bool SwiftASTManipulator::FixupResultAfterTypeChecking(Status &error) {
728733
}
729734

730735
swift::ASTContext &ast_context = m_source_file.getASTContext();
731-
732736
CompilerType return_ast_type = ToCompilerType(result_type.getPointer());
733737
swift::Identifier result_var_name =
734738
ast_context.getIdentifier(GetResultName());
@@ -864,7 +868,9 @@ swift::FuncDecl *SwiftASTManipulator::GetFunctionToInjectVariableInto(
864868
// When not binding generic type parameters, we want to inject the metadata
865869
// pointers in the wrapper, so we can pass them as opaque pointers in the
866870
// trampoline function later on.
867-
if (m_bind_generic_types == lldb::eDontBind && variable.IsMetadataPointer())
871+
if (m_bind_generic_types == lldb::eDontBind &&
872+
(variable.IsMetadataPointer() || variable.IsPackCount() ||
873+
variable.IsUnboundPack()))
868874
return m_entrypoint_decl;
869875

870876
return m_function_decl;
@@ -878,6 +884,20 @@ llvm::Optional<swift::Type> SwiftASTManipulator::GetSwiftTypeForVariable(
878884
if (!type_system_swift)
879885
return {};
880886

887+
// When injecting a value pack or pack count into the outer
888+
// lldb_expr function, treat it as an opaque raw pointer.
889+
if (m_bind_generic_types == lldb::eDontBind && variable.IsUnboundPack()) {
890+
auto swift_ast_ctx = type_system_swift->GetSwiftASTContext();
891+
if (swift_ast_ctx) {
892+
auto it = m_type_aliases.find("$__lldb_builtin_ptr_t");
893+
if (it == m_type_aliases.end())
894+
return {};
895+
return swift::Type(it->second);
896+
}
897+
//swift_ast_ctx->GetBuiltinRawPointerType());
898+
return {};
899+
}
900+
881901
// This might be a referenced type, which will confuse the type checker.
882902
// The access pattern for these types is the same as for the referent
883903
// type, so it is fine to just strip it off.
@@ -930,16 +950,20 @@ swift::VarDecl *SwiftASTManipulator::GetVarDeclForVariableInFunction(
930950
const swift::Identifier name = variable.GetName();
931951
// We may need to mutate the self variable later, so hardcode it to a var
932952
// in that case.
933-
const auto introducer = variable.IsSelf() ? swift::VarDecl::Introducer::Var
934-
: variable.GetVarIntroducer();
953+
const auto introducer = (variable.IsSelf() || variable.IsUnboundPack())
954+
? swift::VarDecl::Introducer::Var
955+
: variable.GetVarIntroducer();
935956

936957
const swift::ASTContext &ast_context = m_source_file.getASTContext();
937958
swift::VarDecl *redirected_var_decl = new (ast_context) swift::VarDecl(
938-
/*is_staic*/ false, introducer, loc, name, containing_function);
959+
/*is_static*/ false, introducer, loc, name, containing_function);
939960

940961
redirected_var_decl->setInterfaceType(swift_type);
941962
redirected_var_decl->setDebuggerVar(true);
942963
redirected_var_decl->setImplicit(true);
964+
redirected_var_decl->setImplInfo(swift::StorageImplInfo(
965+
swift::ReadImplKind::Stored, swift::WriteImplKind::Stored,
966+
swift::ReadWriteImplKind::Stored));
943967

944968
// This avoids having local variables filtered out by
945969
// swift::namelookup::filterForDiscriminator().
@@ -1245,6 +1269,8 @@ SwiftASTManipulator::MakeTypealias(swift::Identifier name, CompilerType &type,
12451269
m_source_file.addTopLevelDecl(type_alias_decl);
12461270
}
12471271

1272+
m_type_aliases.insert(
1273+
{name.str(), type_alias_decl->getStructuralType().getPointer()});
12481274
return type_alias_decl;
12491275
}
12501276

lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,22 @@ class SwiftASTManipulatorBase {
109109
return m_name.str().startswith("$τ_0_");
110110
}
111111
bool IsSelf() const {
112-
return !m_name.str().compare("$__lldb_injected_self");
112+
return m_name.str().equals("$__lldb_injected_self");
113113
}
114+
bool IsPackCount() const {
115+
return m_name.str().startswith("$pack_count_");
116+
}
117+
bool IsUnboundPack() const { return m_is_unbound_pack; }
114118

115119
VariableInfo() : m_type(), m_name(), m_metadata() {}
116120

117121
VariableInfo(CompilerType &type, swift::Identifier name,
118122
VariableMetadataSP metadata,
119123
swift::VarDecl::Introducer introducer,
120-
bool is_capture_list = false)
124+
bool is_capture_list = false, bool is_unbound_pack = false)
121125
: m_type(type), m_name(name), m_var_introducer(introducer),
122-
m_is_capture_list(is_capture_list), m_metadata(metadata) {}
126+
m_is_capture_list(is_capture_list),
127+
m_is_unbound_pack(is_unbound_pack), m_metadata(metadata) {}
123128

124129
void Print(Stream &stream) const;
125130

@@ -134,6 +139,7 @@ class SwiftASTManipulatorBase {
134139
swift::VarDecl::Introducer m_var_introducer =
135140
swift::VarDecl::Introducer::Var;
136141
bool m_is_capture_list = false;
142+
bool m_is_unbound_pack = false;
137143

138144
public:
139145
VariableMetadataSP m_metadata;
@@ -287,6 +293,7 @@ class SwiftASTManipulator : public SwiftASTManipulatorBase {
287293
void InsertError(swift::VarDecl *error_var, swift::Type &error_type);
288294

289295
std::vector<ResultLocationInfo> m_result_info;
296+
llvm::StringMap<swift::TypeBase *> m_type_aliases;
290297
};
291298
}
292299

0 commit comments

Comments
 (0)