Skip to content

Commit 3fd5db3

Browse files
authored
Merge pull request #5791 from augusto2112/check-if-can-eval-before
[lldb][NFC] Check if can eval expr without binding earlier
2 parents 512182b + ee6a78a commit 3fd5db3

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)