Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 53 additions & 27 deletions lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ void SwiftASTManipulatorBase::DoInitialization() {
swift::FuncDecl *entrypoint_decl = nullptr;
/// This is optional.
swift::FuncDecl *ext_method_decl = nullptr;
/// When evaluating a generic expression this is the inner
/// function containing the user expression.
swift::FuncDecl *user_expr_decl = nullptr;
/// When evaluating self as generic, this is the trampoline function that
/// calls the ext_method_decl.
swift::FuncDecl *trampoline_decl = nullptr;
Expand Down Expand Up @@ -128,6 +131,8 @@ void SwiftASTManipulatorBase::DoInitialization() {
entrypoint_decl = FD;
else if (FD->getNameStr().equals("$__lldb_sink"))
sink_decl = FD;
else if (FD->getNameStr().equals("$__lldb_user_expr"))
user_expr_decl = FD;
return Action::SkipChildren();
}
};
Expand All @@ -136,16 +141,17 @@ void SwiftASTManipulatorBase::DoInitialization() {
m_source_file.walk(func_finder);

m_extension_decl = func_finder.extension_decl;
if (m_extension_decl) {
if (func_finder.ext_method_decl) {
m_function_decl = func_finder.ext_method_decl;
m_entrypoint_decl = func_finder.entrypoint_decl;
m_trampoline_decl = func_finder.trampoline_decl;
m_sink_decl = func_finder.sink_decl;
} else {
} else if (func_finder.user_expr_decl) {
m_function_decl = func_finder.user_expr_decl;
m_entrypoint_decl = func_finder.entrypoint_decl;
} else
m_function_decl = func_finder.entrypoint_decl;
m_entrypoint_decl = nullptr;
}

m_entrypoint_decl = func_finder.entrypoint_decl;
m_trampoline_decl = func_finder.trampoline_decl;
m_sink_decl = func_finder.sink_decl;
assert(m_function_decl);

// Find the body in the function
Expand Down Expand Up @@ -698,25 +704,24 @@ bool SwiftASTManipulator::FixupResultAfterTypeChecking(Status &error) {
swift::Type result_type;
for (size_t i = 0; i < num_results; i++) {
swift::VarDecl *the_decl = m_result_info[i].tmp_var_decl;
if (the_decl->hasInterfaceType()) {
swift::Type its_type = the_decl->getType();
if (result_type.isNull()) {
result_type = its_type;
} else if (!its_type.getPointer()->isEqual(result_type)) {
std::string prev_type_name = result_type.getPointer()->getString();
std::string cur_type_name = its_type.getPointer()->getString();

error.SetErrorStringWithFormat(
"Type for %zuth return value is inconsistent, previous type: %s, "
"current type: %s.",
i, prev_type_name.c_str(), cur_type_name.c_str());
return false;
}
} else {
if (!the_decl->hasInterfaceType()) {
error.SetErrorStringWithFormat(
"Type of %zuth return value could not be determined.", i);
return false;
}
swift::Type its_type = the_decl->getType();
if (result_type.isNull()) {
result_type = its_type;
} else if (!its_type.getPointer()->isEqual(result_type)) {
std::string prev_type_name = result_type.getPointer()->getString();
std::string cur_type_name = its_type.getPointer()->getString();

error.SetErrorStringWithFormat(
"Type for %zuth return value is inconsistent, previous type: %s, "
"current type: %s.",
i, prev_type_name.c_str(), cur_type_name.c_str());
return false;
}
}

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

swift::ASTContext &ast_context = m_source_file.getASTContext();

CompilerType return_ast_type = ToCompilerType(result_type.getPointer());
swift::Identifier result_var_name =
ast_context.getIdentifier(GetResultName());
Expand Down Expand Up @@ -864,7 +868,9 @@ swift::FuncDecl *SwiftASTManipulator::GetFunctionToInjectVariableInto(
// When not binding generic type parameters, we want to inject the metadata
// pointers in the wrapper, so we can pass them as opaque pointers in the
// trampoline function later on.
if (m_bind_generic_types == lldb::eDontBind && variable.IsMetadataPointer())
if (m_bind_generic_types == lldb::eDontBind &&

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we relying in the same --bind-generic-types mechanism to enable this behavior? It seems to me this would never work in the "bind" mode.

(variable.IsMetadataPointer() || variable.IsPackCount() ||
variable.IsUnboundPack()))
return m_entrypoint_decl;

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

// When injecting a value pack or pack count into the outer
// lldb_expr function, treat it as an opaque raw pointer.
if (m_bind_generic_types == lldb::eDontBind && variable.IsUnboundPack()) {
auto swift_ast_ctx = type_system_swift->GetSwiftASTContext();
if (swift_ast_ctx) {
auto it = m_type_aliases.find("$__lldb_builtin_ptr_t");
if (it == m_type_aliases.end())
return {};
return swift::Type(it->second);
}
//swift_ast_ctx->GetBuiltinRawPointerType());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stray commented out line.

return {};
}

// This might be a referenced type, which will confuse the type checker.
// The access pattern for these types is the same as for the referent
// type, so it is fine to just strip it off.
Expand Down Expand Up @@ -930,16 +950,20 @@ swift::VarDecl *SwiftASTManipulator::GetVarDeclForVariableInFunction(
const swift::Identifier name = variable.GetName();
// We may need to mutate the self variable later, so hardcode it to a var
// in that case.
const auto introducer = variable.IsSelf() ? swift::VarDecl::Introducer::Var
: variable.GetVarIntroducer();
const auto introducer = (variable.IsSelf() || variable.IsUnboundPack())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious, why does the unbound pack need to be mutated?

? swift::VarDecl::Introducer::Var
: variable.GetVarIntroducer();

const swift::ASTContext &ast_context = m_source_file.getASTContext();
swift::VarDecl *redirected_var_decl = new (ast_context) swift::VarDecl(
/*is_staic*/ false, introducer, loc, name, containing_function);
/*is_static*/ false, introducer, loc, name, containing_function);

redirected_var_decl->setInterfaceType(swift_type);
redirected_var_decl->setDebuggerVar(true);
redirected_var_decl->setImplicit(true);
redirected_var_decl->setImplInfo(swift::StorageImplInfo(
swift::ReadImplKind::Stored, swift::WriteImplKind::Stored,
swift::ReadWriteImplKind::Stored));

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

m_type_aliases.insert(
{name.str(), type_alias_decl->getStructuralType().getPointer()});
return type_alias_decl;
}

Expand Down
13 changes: 10 additions & 3 deletions lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,22 @@ class SwiftASTManipulatorBase {
return m_name.str().startswith("$τ_0_");
}
bool IsSelf() const {
return !m_name.str().compare("$__lldb_injected_self");
return m_name.str().equals("$__lldb_injected_self");
}
bool IsPackCount() const {
return m_name.str().startswith("$pack_count_");
}
bool IsUnboundPack() const { return m_is_unbound_pack; }

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

VariableInfo(CompilerType &type, swift::Identifier name,
VariableMetadataSP metadata,
swift::VarDecl::Introducer introducer,
bool is_capture_list = false)
bool is_capture_list = false, bool is_unbound_pack = false)
: m_type(type), m_name(name), m_var_introducer(introducer),
m_is_capture_list(is_capture_list), m_metadata(metadata) {}
m_is_capture_list(is_capture_list),
m_is_unbound_pack(is_unbound_pack), m_metadata(metadata) {}

void Print(Stream &stream) const;

Expand All @@ -134,6 +139,7 @@ class SwiftASTManipulatorBase {
swift::VarDecl::Introducer m_var_introducer =
swift::VarDecl::Introducer::Var;
bool m_is_capture_list = false;
bool m_is_unbound_pack = false;

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

std::vector<ResultLocationInfo> m_result_info;
llvm::StringMap<swift::TypeBase *> m_type_aliases;
};
}

Expand Down
Loading