Skip to content

Commit ee6a78a

Browse files
committed
[lldb][NFC] Check if can eval expr without binding earlier
Move the check that we can evaluate the expression without binding the generic paramaters from SwiftExpressionParser (after we generate an AST from the user's expression) to SwiftUserExpression, before we get the text binding the user's expression.
1 parent 8d91261 commit ee6a78a

File tree

3 files changed

+108
-99
lines changed

3 files changed

+108
-99
lines changed

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

Lines changed: 2 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ CompilerType SwiftExpressionParser::ResolveVariable(
482482
return var_type;
483483
}
484484

485-
static lldb::VariableSP FindSelfVariable(Block *block) {
485+
lldb::VariableSP SwiftExpressionParser::FindSelfVariable(Block *block) {
486486
if (!block)
487487
return {};
488488

@@ -529,7 +529,7 @@ static void AddRequiredAliases(Block *block, lldb::StackFrameSP &stack_frame_sp,
529529
LLDB_SCOPED_TIMER();
530530

531531
// First emit the typealias for "$__lldb_context".
532-
lldb::VariableSP self_var_sp = FindSelfVariable(block);
532+
lldb::VariableSP self_var_sp = SwiftExpressionParser::FindSelfVariable(block);
533533

534534
if (!self_var_sp)
535535
return;
@@ -1067,91 +1067,6 @@ struct ParsedExpression {
10671067

10681068
} // namespace
10691069

1070-
/// Check if we can evaluate the expression as generic.
1071-
/// Currently, evaluating expression as a generic has several limitations:
1072-
/// - Only self will be evaluated with unbound generics.
1073-
/// - The Self type can only have one generic parameter.
1074-
/// - The Self type has to be the outermost type with unbound generics.
1075-
static bool CanEvaluateExpressionAsGeneric(
1076-
llvm::ArrayRef<SwiftASTManipulator::VariableInfo> variables, Block *block,
1077-
StackFrame &stack_frame) {
1078-
// First, find the compiler type of self with the generic parameters not
1079-
// bound.
1080-
auto self_var = FindSelfVariable(block);
1081-
if (!self_var)
1082-
return false;
1083-
1084-
lldb::ValueObjectSP self_valobj =
1085-
stack_frame.GetValueObjectForFrameVariable(self_var,
1086-
lldb::eNoDynamicValues);
1087-
if (!self_valobj)
1088-
return false;
1089-
1090-
auto self_type = self_valobj->GetCompilerType();
1091-
if (!self_type)
1092-
return false;
1093-
1094-
auto *ts = self_type.GetTypeSystem()
1095-
.dyn_cast_or_null<TypeSystemSwift>()
1096-
->GetSwiftASTContext();
1097-
1098-
if (!ts)
1099-
return false;
1100-
1101-
auto swift_type = ts->GetSwiftType(self_type);
1102-
if (!swift_type)
1103-
return false;
1104-
1105-
auto *decl = swift_type->getAnyGeneric();
1106-
if (!decl)
1107-
return false;
1108-
1109-
1110-
auto *env = decl->getGenericEnvironment();
1111-
if (!env)
1112-
return false;
1113-
auto params = env->getGenericParams();
1114-
1115-
// If there aren't any generic parameters we can't evaluate the expression as
1116-
// generic.
1117-
if (params.empty())
1118-
return false;
1119-
1120-
auto *first_param = params[0];
1121-
// Currently we only support evaluating self as generic if the generic
1122-
// parameter is the first one.
1123-
if (first_param->getDepth() != 0 || first_param->getIndex() != 0)
1124-
return false;
1125-
1126-
bool contains_0_0 = false;
1127-
bool contains_other_0_depth_params = false;
1128-
for (auto *pair : params) {
1129-
if (pair->getDepth() == 0) {
1130-
if (pair->getIndex() == 0)
1131-
contains_0_0 = true;
1132-
else
1133-
contains_other_0_depth_params = true;
1134-
}
1135-
}
1136-
1137-
// We only allow generic evaluation when the Self type contains the outermost
1138-
// generic parameter.
1139-
if (!contains_0_0)
1140-
return false;
1141-
1142-
// We only allow the Self type to have one generic parameter.
1143-
if (contains_other_0_depth_params)
1144-
return false;
1145-
1146-
// Now, check that we do have the metadata pointer as a local variable.
1147-
for (auto &variable : variables) {
1148-
if (variable.GetName().str() == "$τ_0_0")
1149-
return true;
1150-
}
1151-
// Couldn't find the metadata pointer, so can't evaluate as generic.
1152-
return false;
1153-
}
1154-
11551070
/// Attempt to parse an expression and import all the Swift modules
11561071
/// the expression and its context depend on.
11571072
static llvm::Expected<ParsedExpression> ParseAndImport(
@@ -1363,13 +1278,6 @@ static llvm::Expected<ParsedExpression> ParseAndImport(
13631278
ResolveSpecialNames(sc, exe_scope, swift_ast_context, special_names,
13641279
local_variables);
13651280

1366-
if (options.GetBindGenericTypes() == lldb::eDontBind &&
1367-
!CanEvaluateExpressionAsGeneric(local_variables, sc.block,
1368-
*stack_frame_sp.get()))
1369-
return make_error<StringError>(
1370-
inconvertibleErrorCode(),
1371-
"Could not evaluate the expression without binding generic types.");
1372-
13731281
if (!code_manipulator->AddExternalVariables(local_variables))
13741282
return make_error<StringError>(inconvertibleErrorCode(),
13751283
"Could not add external variables.");

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ class SwiftExpressionParser : public ExpressionParser {
149149
SwiftLanguageRuntime *runtime, lldb::DynamicValueType use_dynamic,
150150
lldb::BindGenericTypes bind_generic_types);
151151

152+
static lldb::VariableSP FindSelfVariable(Block *block);
153+
152154
//------------------------------------------------------------------
153155
/// Information about each variable provided to the expression, so
154156
/// that we can generate proper accesses in the SIL.

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

Lines changed: 104 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,16 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#include "swift/AST/ASTContext.h"
14-
#include "swift/Demangling/Demangler.h"
1513
#include <stdio.h>
1614
#if HAVE_SYS_TYPES_H
1715
#include <sys/types.h>
1816
#endif
1917

20-
#include "SwiftASTManipulator.h""
18+
#include "SwiftASTManipulator.h"
2119
#include "SwiftExpressionParser.h"
2220
#include "SwiftExpressionSourceCode.h"
2321
#include "SwiftREPLMaterializer.h"
22+
#include "SwiftASTManipulator.h"
2423

2524
#include "Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h"
2625
#include "lldb/Core/Module.h"
@@ -40,6 +39,10 @@
4039

4140
#include "swift/AST/Type.h"
4241
#include "swift/AST/Types.h"
42+
#include "swift/AST/ASTContext.h"
43+
#include "swift/Demangling/Demangler.h"
44+
#include "swift/AST/GenericEnvironment.h"
45+
4346

4447
#include <cstdlib>
4548
#include <map>
@@ -451,14 +454,99 @@ GetPersistentState(Target *target, ExecutionContext &exe_ctx) {
451454
return target->GetSwiftPersistentExpressionState(*exe_scope);
452455
}
453456

457+
/// Check if we can evaluate the expression as generic.
458+
/// Currently, evaluating expression as a generic has several limitations:
459+
/// - Only self will be evaluated with unbound generics.
460+
/// - The Self type can only have one generic parameter.
461+
/// - The Self type has to be the outermost type with unbound generics.
462+
static bool CanEvaluateExpressionWithoutBindingGenericParams(
463+
const llvm::SmallVectorImpl<SwiftASTManipulator::VariableInfo>
464+
&variables,
465+
Block *block, StackFrame &stack_frame) {
466+
// First, find the compiler type of self with the generic parameters not
467+
// bound.
468+
auto self_var = SwiftExpressionParser::FindSelfVariable(block);
469+
if (!self_var)
470+
return false;
471+
472+
lldb::ValueObjectSP self_valobj =
473+
stack_frame.GetValueObjectForFrameVariable(self_var,
474+
lldb::eNoDynamicValues);
475+
if (!self_valobj)
476+
return false;
477+
478+
auto self_type = self_valobj->GetCompilerType();
479+
if (!self_type)
480+
return false;
481+
482+
auto *ts = self_type.GetTypeSystem()
483+
.dyn_cast_or_null<TypeSystemSwift>()
484+
->GetSwiftASTContext();
485+
486+
if (!ts)
487+
return false;
488+
489+
auto swift_type = ts->GetSwiftType(self_type);
490+
if (!swift_type)
491+
return false;
492+
493+
auto *decl = swift_type->getAnyGeneric();
494+
if (!decl)
495+
return false;
496+
497+
498+
auto *env = decl->getGenericEnvironment();
499+
if (!env)
500+
return false;
501+
auto params = env->getGenericParams();
502+
503+
// If there aren't any generic parameters we can't evaluate the expression as
504+
// generic.
505+
if (params.empty())
506+
return false;
507+
508+
auto *first_param = params[0];
509+
// Currently we only support evaluating self as generic if the generic
510+
// parameter is the first one.
511+
if (first_param->getDepth() != 0 || first_param->getIndex() != 0)
512+
return false;
513+
514+
bool contains_0_0 = false;
515+
bool contains_other_0_depth_params = false;
516+
for (auto *pair : params) {
517+
if (pair->getDepth() == 0) {
518+
if (pair->getIndex() == 0)
519+
contains_0_0 = true;
520+
else
521+
contains_other_0_depth_params = true;
522+
}
523+
}
524+
525+
// We only allow generic evaluation when the Self type contains the outermost
526+
// generic parameter.
527+
if (!contains_0_0)
528+
return false;
529+
530+
// We only allow the Self type to have one generic parameter.
531+
if (contains_other_0_depth_params)
532+
return false;
533+
534+
// Now, check that we do have the metadata pointer as a local variable.
535+
for (auto &variable : variables) {
536+
if (variable.GetName().str() == "$τ_0_0")
537+
return true;
538+
}
539+
// Couldn't find the metadata pointer, so can't evaluate as generic.
540+
return false;
541+
}
542+
454543
SwiftExpressionParser::ParseResult
455544
SwiftUserExpression::GetTextAndSetExpressionParser(
456545
DiagnosticManager &diagnostic_manager,
457546
std::unique_ptr<SwiftExpressionSourceCode> &source_code,
458547
ExecutionContext &exe_ctx, ExecutionContextScope *exe_scope) {
459548
using ParseResult = SwiftExpressionParser::ParseResult;
460549
Log *log = GetLog(LLDBLog::Expressions);
461-
uint32_t first_body_line = 0;
462550

463551
lldb::TargetSP target_sp;
464552
SymbolContext sc;
@@ -468,9 +556,10 @@ SwiftUserExpression::GetTextAndSetExpressionParser(
468556
stack_frame = exe_scope->CalculateStackFrame();
469557

470558
if (stack_frame) {
471-
sc = stack_frame->GetSymbolContext(lldb::eSymbolContextEverything);
559+
sc = stack_frame->GetSymbolContext(lldb::eSymbolContextEverything);
472560
}
473561
}
562+
474563
llvm::SmallVector<SwiftASTManipulator::VariableInfo> local_variables;
475564

476565
if (!RegisterAllVariables(sc, stack_frame, *m_swift_ast_ctx, local_variables,
@@ -483,6 +572,16 @@ SwiftUserExpression::GetTextAndSetExpressionParser(
483572
return ParseResult::retry_no_bind_generic_params;
484573
}
485574

575+
if (m_options.GetBindGenericTypes() == lldb::eDontBind &&
576+
!CanEvaluateExpressionWithoutBindingGenericParams(
577+
local_variables, sc.block, *stack_frame.get())) {
578+
diagnostic_manager.PutString(
579+
eDiagnosticSeverityError,
580+
"Could not evaluate the expression without binding generic types.");
581+
return ParseResult::unrecoverable_error;
582+
}
583+
584+
uint32_t first_body_line = 0;
486585
if (!source_code->GetText(m_transformed_text, m_options.GetLanguage(),
487586
m_needs_object_ptr, m_in_static_method, m_is_class,
488587
m_is_weak_self, m_options, exe_ctx,

0 commit comments

Comments
 (0)