Skip to content

Commit 7f8a88f

Browse files
authored
Merge pull request #7526 from augusto2112/weak-generic-class
[lldb] Fix typealias not being emitted for weakly captured generic
2 parents b96cced + 6fb5c0f commit 7f8a88f

File tree

4 files changed

+105
-39
lines changed

4 files changed

+105
-39
lines changed

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

Lines changed: 68 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -532,11 +532,17 @@ lldb::VariableSP SwiftExpressionParser::FindSelfVariable(Block *block) {
532532
return variable_list_sp->FindVariable(ConstString("self"));
533533
}
534534

535-
static void AddRequiredAliases(Block *block, lldb::StackFrameSP &stack_frame_sp,
536-
SwiftASTContextForExpressions &swift_ast_context,
537-
SwiftASTManipulator &manipulator,
538-
lldb::DynamicValueType use_dynamic,
539-
lldb::BindGenericTypes bind_generic_types) {
535+
/// Adds the type aliases the type-checker needs to type-check the expression.
536+
///
537+
/// - Returns: A `Status` instance that indicates whether the method finished
538+
/// successfully. If the method returns an error status, it contains a string
539+
/// that explain the failure.
540+
static Status
541+
AddRequiredAliases(Block *block, lldb::StackFrameSP &stack_frame_sp,
542+
SwiftASTContextForExpressions &swift_ast_context,
543+
SwiftASTManipulator &manipulator,
544+
lldb::DynamicValueType use_dynamic,
545+
lldb::BindGenericTypes bind_generic_types) {
540546
LLDB_SCOPED_TIMER();
541547

542548
// Alias builtin types, since we can't use them directly in source code.
@@ -548,12 +554,13 @@ static void AddRequiredAliases(Block *block, lldb::StackFrameSP &stack_frame_sp,
548554
manipulator.MakeTypealias(
549555
swift_ast_context.GetASTContext()->getIdentifier("$__lldb_builtin_int_t"),
550556
builtin_int_t, false);
551-
557+
552558
// First emit the typealias for "$__lldb_context".
553559
lldb::VariableSP self_var_sp = SwiftExpressionParser::FindSelfVariable(block);
554560

561+
// If there is no self we don't need to add the "$__lldb_context" alias.
555562
if (!self_var_sp)
556-
return;
563+
return Status();
557564

558565
auto *swift_runtime =
559566
SwiftLanguageRuntime::Get(stack_frame_sp->GetThread()->GetProcess());
@@ -569,50 +576,60 @@ static void AddRequiredAliases(Block *block, lldb::StackFrameSP &stack_frame_sp,
569576

570577
if (!self_type.IsValid() ||
571578
!self_type.GetTypeSystem()->SupportsLanguage(lldb::eLanguageTypeSwift))
572-
return;
579+
return Status("Unable to add the aliases the expression needs because "
580+
"self isn't valid.");
573581

574582
// Import before getting the unbound version, because the unbound
575583
// version may not be in the mangled name map.
576584

577585
CompilerType imported_self_type = ImportType(swift_ast_context, self_type);
578586

579587
if (!imported_self_type.IsValid())
580-
return;
588+
return Status("Unable to add the aliases the expression needs because the "
589+
"self type from an import isn't valid.");
581590

582591
auto *stack_frame = stack_frame_sp.get();
583592
if (bind_generic_types != lldb::eDontBind) {
584593
imported_self_type = swift_runtime->BindGenericTypeParameters(
585594
*stack_frame, imported_self_type);
586595
if (!imported_self_type)
587-
return;
596+
return Status(
597+
"Unable to add the aliases the expression needs because the Swift "
598+
"expression parser couldn't bind the type parameters for self.");
588599
}
589600

590601
{
591602
auto swift_type_system =
592603
imported_self_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>();
593604
if (!swift_type_system)
594-
return;
605+
return Status("Unable to add the aliases the expression needs because "
606+
"self is not a Swift type.");
595607

596608
// This might be a referenced type, in which case we really want to
597609
// extend the referent:
598610
imported_self_type = swift_type_system->GetReferentType(
599611
imported_self_type.GetOpaqueQualType());
600612
if (!imported_self_type)
601-
return;
613+
return Status("Unable to add the aliases the expression needs because "
614+
"the Swift expression parser couldn't get the referent "
615+
"type for self.");
602616
}
603617

604618
{
605619
auto swift_type_system =
606620
imported_self_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>();
607621
if (!swift_type_system)
608-
return;
622+
return Status("Unable to add the aliases the expression needs because "
623+
"self is not a Swift type.");
609624

610625
// If we are extending a generic class it's going to be a metatype,
611626
// and we have to grab the instance type:
612627
imported_self_type = swift_type_system->GetInstanceType(
613628
imported_self_type.GetOpaqueQualType());
614629
if (!imported_self_type)
615-
return;
630+
return Status(
631+
"Unable to add the aliases the expression needs because the Swift "
632+
"expression parser couldn't get the instance type for self.");
616633
}
617634

618635
Flags imported_self_type_flags(imported_self_type.GetTypeInfo());
@@ -622,8 +639,9 @@ static void AddRequiredAliases(Block *block, lldb::StackFrameSP &stack_frame_sp,
622639
LLDB_LOG(GetLog(LLDBLog::Types | LLDBLog::Expressions),
623640
"Couldn't get SwiftASTContext type for self type {0}.",
624641
imported_self_type.GetDisplayTypeName());
625-
626-
return;
642+
return Status(
643+
"Unable to add the aliases the expression needs because the Swift "
644+
"expression parser couldn't get the Swift type for self.");
627645
}
628646

629647
swift::Type object_type = swift_self_type->getWithoutSpecifierType();
@@ -640,36 +658,45 @@ static void AddRequiredAliases(Block *block, lldb::StackFrameSP &stack_frame_sp,
640658
swift::BoundGenericEnumType *optional_type =
641659
referent_type->getAs<swift::BoundGenericEnumType>();
642660

643-
if (!optional_type)
644-
return;
661+
if (!optional_type || optional_type->getGenericArgs().empty())
662+
return Status(
663+
"Unable to add the aliases the expression needs because the Swift "
664+
"expression parser couldn't get an optional type for self.");
645665

646666
swift::Type first_arg_type = optional_type->getGenericArgs()[0];
647667

648-
swift::ClassType *self_class_type =
649-
first_arg_type->getAs<swift::ClassType>();
650-
651-
if (!self_class_type)
652-
return;
668+
// In Swift only class types can be weakly captured.
669+
if (!llvm::isa<swift::ClassType>(first_arg_type) &&
670+
!llvm::isa<swift::BoundGenericClassType>(first_arg_type))
671+
return Status("Unable to add the aliases the expression needs because "
672+
"weakly captured type is not a class type.");
653673

654-
imported_self_type = ToCompilerType(self_class_type);
674+
imported_self_type = ToCompilerType(first_arg_type);
655675
}
656676

657677
imported_self_type_flags.Reset(imported_self_type.GetTypeInfo());
658-
if (imported_self_type_flags.AllClear(lldb::eTypeIsGenericTypeParam)) {
659-
swift::ValueDecl *type_alias_decl = nullptr;
660-
661-
type_alias_decl = manipulator.MakeTypealias(
662-
swift_ast_context.GetASTContext()->getIdentifier("$__lldb_context"),
663-
imported_self_type);
664-
665-
if (!type_alias_decl)
666-
LLDB_LOG(GetLog(LLDBLog::Expressions),
667-
"SEP:AddRequiredAliases: Failed to make the $__lldb_context "
668-
"typealias.");
669-
} else
678+
if (imported_self_type_flags.Test(lldb::eTypeIsGenericTypeParam)) {
670679
LLDB_LOG(GetLog(LLDBLog::Expressions),
671680
"SEP:AddRequiredAliases: Failed to resolve the self archetype - "
672681
"could not make the $__lldb_context typealias.");
682+
return Status(
683+
"Unable to add the aliases the expression needs because the "
684+
"Swift expression parser couldn't resolve the self archetype.");
685+
}
686+
swift::ValueDecl *type_alias_decl = manipulator.MakeTypealias(
687+
swift_ast_context.GetASTContext()->getIdentifier("$__lldb_context"),
688+
imported_self_type);
689+
690+
if (!type_alias_decl) {
691+
LLDB_LOG(GetLog(LLDBLog::Expressions),
692+
"SEP:AddRequiredAliases: Failed to make the $__lldb_context "
693+
"typealias.");
694+
return Status("Unable to add the aliases the expression needs because the "
695+
"Swift expression parser couldn't create a context type "
696+
"alias for lldb");
697+
}
698+
699+
return Status();
673700
}
674701

675702
static void ResolveSpecialNames(
@@ -1407,9 +1434,11 @@ static llvm::Expected<ParsedExpression> ParseAndImport(
14071434
}
14081435

14091436
if (local_context_is_swift) {
1410-
AddRequiredAliases(sc.block, stack_frame_sp, swift_ast_context,
1411-
*code_manipulator, options.GetUseDynamic(),
1412-
options.GetBindGenericTypes());
1437+
Status error = AddRequiredAliases(
1438+
sc.block, stack_frame_sp, swift_ast_context, *code_manipulator,
1439+
options.GetUseDynamic(), options.GetBindGenericTypes());
1440+
if (error.Fail())
1441+
return error.ToError();
14131442
}
14141443
//
14151444
// Register all magic variables.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SWIFT_SOURCES := main.swift
2+
include Makefile.rules
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
from lldbsuite.test.decorators import *
4+
import lldbsuite.test.lldbutil as lldbutil
5+
import unittest2
6+
7+
8+
class TestSwiftWeakGenericSelf(TestBase):
9+
@swiftTest
10+
def test(self):
11+
"""Confirms that expression evaluation works with a generic class
12+
type within a closure that weakly captures it"""
13+
self.build()
14+
_, _, _, _ = lldbutil.run_to_source_breakpoint(
15+
self, "break here", lldb.SBFileSpec("main.swift")
16+
)
17+
18+
self.expect("expression self", substrs=["GenericClass<Int>?", "t = 42"])
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class GenericClass<T> {
2+
let t: T
3+
4+
init(t: T) {
5+
self.t = t
6+
}
7+
8+
func foo() {
9+
{ [weak self] in
10+
print(self) // break here
11+
}()
12+
}
13+
}
14+
15+
let instance = GenericClass<Int>(t: 42)
16+
instance.foo()
17+

0 commit comments

Comments
 (0)