@@ -94,177 +94,180 @@ static CompilerType GetConcreteType(ExecutionContext &exe_ctx,
94
94
return type;
95
95
}
96
96
97
+ // / Determine whether we have a Swift language symbol context. This handles
98
+ // / some special cases, such as when the expression language is unknown, or
99
+ // / when we have to guess from a mangled name.
100
+ static bool isSwiftLanguageSymbolContext (const SwiftUserExpression &expr,
101
+ const SymbolContext &sym_ctx) {
102
+ if (sym_ctx.comp_unit && (expr.Language () == lldb::eLanguageTypeUnknown ||
103
+ expr.Language () == lldb::eLanguageTypeSwift)) {
104
+ if (sym_ctx.comp_unit ->GetLanguage () == lldb::eLanguageTypeSwift)
105
+ return true ;
106
+ } else if (sym_ctx.symbol && expr.Language () == lldb::eLanguageTypeUnknown) {
107
+ if (sym_ctx.symbol ->GetMangled ().GuessLanguage () ==
108
+ lldb::eLanguageTypeSwift)
109
+ return true ;
110
+ }
111
+ return false ;
112
+ }
113
+
114
+ // / Information about `self` in a frame.
115
+ struct SwiftSelfInfo {
116
+ // / Whether `self` is a metatype (i.e. whether we're in a static method).
117
+ bool is_metatype = false ;
118
+
119
+ // / Adjusted type of `self`. If we're in a static method, this is an instance
120
+ // / type.
121
+ CompilerType type = {};
122
+
123
+ // / Underlying Swift type for the adjusted type of `self`.
124
+ swift::TypeBase *swift_type = nullptr ;
125
+
126
+ // / Type flags for the adjusted type of `self`.
127
+ Flags type_flags = {};
128
+ };
129
+
130
+ // / Find information about `self` in the frame.
131
+ static llvm::Optional<SwiftSelfInfo>
132
+ findSwiftSelf (StackFrame &frame, lldb::VariableSP self_var_sp) {
133
+ SwiftSelfInfo info;
134
+
135
+ lldb::ValueObjectSP valobj_sp = frame.GetValueObjectForFrameVariable (
136
+ self_var_sp, lldb::eDynamicDontRunTarget);
137
+
138
+ // 1) Try finding the type of `self` from its ValueObject.
139
+ if (valobj_sp && valobj_sp->GetError ().Success ())
140
+ info.type = valobj_sp->GetCompilerType ();
141
+
142
+ // 2) If (1) fails, try finding the type of `self` from its Variable.
143
+ if (!info.type .IsValid ())
144
+ if (Type *self_lldb_type = self_var_sp->GetType ())
145
+ info.type = self_var_sp->GetType ()->GetForwardCompilerType ();
146
+
147
+ // 3) If (1) and (2) fail, give up.
148
+ if (!info.type .IsValid ())
149
+ return llvm::None;
150
+
151
+ // 4) If `self` is a metatype, get its instance type.
152
+ if (Flags (info.type .GetTypeInfo ())
153
+ .AllSet (lldb::eTypeIsSwift | lldb::eTypeIsMetatype)) {
154
+ info.type = TypeSystemSwift::GetInstanceType (info.type );
155
+ info.is_metatype = true ;
156
+ }
157
+
158
+ // 5) If the adjusted type isn't equal to the type according to the runtime,
159
+ // switch it to the latter type.
160
+ info.swift_type = GetSwiftType (info.type ).getPointer ();
161
+ if (info.swift_type && (info.swift_type != info.type .GetOpaqueQualType ()))
162
+ info.type = ToCompilerType (info.swift_type );
163
+
164
+ info.type_flags = Flags (info.type .GetTypeInfo ());
165
+
166
+ if (!info.type .IsValid ())
167
+ return llvm::None;
168
+ return info;
169
+ }
170
+
97
171
void SwiftUserExpression::ScanContext (ExecutionContext &exe_ctx, Status &err) {
98
172
Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
99
-
100
- if (log)
101
- log->Printf (" SwiftUserExpression::ScanContext()" );
173
+ LLDB_LOG (log, " SwiftUserExpression::ScanContext()" );
102
174
103
175
m_target = exe_ctx.GetTargetPtr ();
104
-
105
176
if (!m_target) {
106
- if (log)
107
- log->Printf (" [SUE::SC] Null target" );
177
+ LLDB_LOG (log, " [SUE::SC] Null target" );
108
178
return ;
109
179
}
110
180
111
181
StackFrame *frame = exe_ctx.GetFramePtr ();
112
182
if (!frame) {
113
- if (log)
114
- log->Printf (" [SUE::SC] Null stack frame" );
183
+ LLDB_LOG (log, " [SUE::SC] Null stack frame" );
115
184
return ;
116
185
}
117
186
118
187
SymbolContext sym_ctx = frame->GetSymbolContext (
119
188
lldb::eSymbolContextFunction | lldb::eSymbolContextBlock |
120
189
lldb::eSymbolContextCompUnit | lldb::eSymbolContextSymbol);
121
-
122
- // This stage of the scan is only for Swift, but when we are going
123
- // to do Swift evaluation we need to do this scan.
124
- // So be sure to cover both cases:
125
- // 1) When the language is eLanguageTypeUnknown, to determine if this IS Swift
126
- // 2) When the language is explicitly set to eLanguageTypeSwift.
127
- bool frame_is_swift = false ;
128
-
129
- if (sym_ctx.comp_unit && (m_language == lldb::eLanguageTypeUnknown ||
130
- m_language == lldb::eLanguageTypeSwift)) {
131
- if (sym_ctx.comp_unit ->GetLanguage () == lldb::eLanguageTypeSwift ||
132
- sym_ctx.comp_unit ->GetLanguage () == lldb::eLanguageTypePLI)
133
- frame_is_swift = true ;
134
- } else if (sym_ctx.symbol && m_language == lldb::eLanguageTypeUnknown) {
135
- if (sym_ctx.symbol ->GetMangled ().GuessLanguage () ==
136
- lldb::eLanguageTypeSwift)
137
- frame_is_swift = true ;
190
+ bool frame_is_swift = isSwiftLanguageSymbolContext (*this , sym_ctx);
191
+ if (!frame_is_swift) {
192
+ LLDB_LOG (log, " [SUE::SC] Frame is not swift-y" );
193
+ return ;
138
194
}
139
195
140
- if (!frame_is_swift)
196
+ // Make sure the target's SwiftASTContext has been setup before doing any
197
+ // Swift name lookups.
198
+ auto swift_ast_ctx = m_target->GetScratchSwiftASTContext (err, *frame);
199
+ if (!swift_ast_ctx) {
200
+ LLDB_LOG (log, " [SUE::SC] NULL Swift AST Context" );
141
201
return ;
202
+ }
142
203
143
- m_is_class = false ;
144
- m_needs_object_ptr = false ;
145
-
146
- // Make sure the target's SwiftASTContext has been setup before
147
- // doing any Swift name lookups.
148
- if (m_target) {
149
- auto swift_ast_ctx = m_target->GetScratchSwiftASTContext (err, *frame);
150
- if (!swift_ast_ctx) {
151
- if (log)
152
- log->Printf (" [SUE::SC] NULL Swift AST Context" );
153
- return ;
154
- }
155
-
156
- if (!swift_ast_ctx->GetClangImporter ()) {
157
- if (log)
158
- log->Printf (" [SUE::SC] Swift AST Context has no Clang importer" );
159
- return ;
160
- }
204
+ if (!swift_ast_ctx->GetClangImporter ()) {
205
+ LLDB_LOG (log, " [SUE::SC] Swift AST Context has no Clang importer" );
206
+ return ;
207
+ }
161
208
162
- if (swift_ast_ctx->HasFatalErrors ()) {
163
- if (log)
164
- log->Printf (" [SUE::SC] Swift AST Context has fatal errors" );
165
- return ;
166
- }
209
+ if (swift_ast_ctx->HasFatalErrors ()) {
210
+ LLDB_LOG (log, " [SUE::SC] Swift AST Context has fatal errors" );
211
+ return ;
167
212
}
168
213
169
- if (log)
170
- log->Printf (" [SUE::SC] Compilation unit is swift" );
214
+ LLDB_LOG (log, " [SUE::SC] Compilation unit is swift" );
171
215
172
216
Block *function_block = sym_ctx.GetFunctionBlock ();
173
- if (!function_block)
217
+ if (!function_block) {
218
+ LLDB_LOG (log, " [SUE::SC] No function block" );
174
219
return ;
220
+ }
175
221
176
222
lldb::VariableListSP variable_list_sp (
177
223
function_block->GetBlockVariableList (true ));
178
-
179
- if (!variable_list_sp)
224
+ if (!variable_list_sp) {
225
+ LLDB_LOG (log, " [SUE::SC] No block variable list " );
180
226
return ;
227
+ }
181
228
182
229
lldb::VariableSP self_var_sp (
183
230
variable_list_sp->FindVariable (ConstString (" self" )));
184
-
185
- if (!self_var_sp || ! SwiftLanguageRuntime::IsSelf (*self_var_sp))
231
+ if (!self_var_sp || ! SwiftLanguageRuntime::IsSelf (*self_var_sp)) {
232
+ LLDB_LOG (log, " [SUE::SC] No valid `self` variable " );
186
233
return ;
187
-
188
- CompilerType self_type;
189
- if (lldb::StackFrameSP stack_frame_sp = exe_ctx.GetFrameSP ()) {
190
- // If we have a self variable, but it has no location at
191
- // the current PC, then we can't use it. Set the self var
192
- // back to empty and we'll just pretend we are in a
193
- // regular frame, which is really the best we can do.
194
- if (!self_var_sp->LocationIsValidForFrame (stack_frame_sp.get ()))
195
- return ;
196
-
197
- lldb::ValueObjectSP valobj_sp =
198
- stack_frame_sp->GetValueObjectForFrameVariable (
199
- self_var_sp, lldb::eDynamicDontRunTarget);
200
-
201
- if (valobj_sp && valobj_sp->GetError ().Success ())
202
- self_type = valobj_sp->GetCompilerType ();
203
234
}
204
235
205
- if (!self_type.IsValid ()) {
206
- Type *self_lldb_type = self_var_sp->GetType ();
207
-
208
- if (self_lldb_type)
209
- self_type = self_var_sp->GetType ()->GetForwardCompilerType ();
236
+ // If we have a self variable, but it has no location at the current PC, then
237
+ // we can't use it. Set the self var back to empty and we'll just pretend we
238
+ // are in a regular frame, which is really the best we can do.
239
+ if (!self_var_sp->LocationIsValidForFrame (frame)) {
240
+ LLDB_LOG (log, " [SUE::SC] `self` variable location not valid for frame" );
241
+ return ;
210
242
}
211
243
212
- if (!self_type.IsValid ()) {
213
- // If the self_type is invalid at this point, reset it.
214
- // Code below the phony do/while will assume the existence
215
- // of this var means something, but it is useless in this
216
- // condition.
244
+ auto maybe_self_info = findSwiftSelf (*frame, self_var_sp);
245
+ if (!maybe_self_info) {
246
+ LLDB_LOG (log, " [SUE::SC] Could not determine info about `self`" );
217
247
return ;
218
248
}
219
249
220
- // Check to see if we are in a class func of a class (or
221
- // static func of a struct) and adjust our self_type to
222
- // point to the instance type.
223
- m_needs_object_ptr = true ;
250
+ // Check to see if we are in a class func of a class (or static func of a
251
+ // struct) and adjust our type to point to the instance type.
252
+ SwiftSelfInfo info = *maybe_self_info;
224
253
225
- Flags self_type_flags (self_type. GetTypeInfo ()) ;
254
+ m_in_static_method = info. is_metatype ;
226
255
227
- if (self_type_flags.AllSet (lldb::eTypeIsSwift | lldb::eTypeIsMetatype)) {
228
- self_type = TypeSystemSwift::GetInstanceType (self_type);
229
- self_type_flags = self_type.GetTypeInfo ();
230
- if (self_type_flags.Test (lldb::eTypeIsClass))
231
- m_is_class = true ;
232
- m_in_static_method = true ;
233
- }
234
-
235
- if (self_type_flags.AllSet (lldb::eTypeIsSwift |
236
- lldb::eTypeInstanceIsPointer)) {
237
- if (self_type_flags.Test (lldb::eTypeIsClass))
238
- m_is_class = true ;
239
- }
240
-
241
- swift::Type object_type = GetSwiftType (self_type);
242
- if (object_type.getPointer () &&
243
- (object_type.getPointer () != self_type.GetOpaqueQualType ()))
244
- self_type = ToCompilerType (object_type.getPointer ());
256
+ if (info.type_flags .AllSet (lldb::eTypeIsSwift | lldb::eTypeInstanceIsPointer))
257
+ m_is_class |= info.type_flags .Test (lldb::eTypeIsClass);
245
258
246
259
// Handle weak self.
247
- if (auto *ref_type = llvm::dyn_cast_or_null<swift::ReferenceStorageType>(
248
- GetSwiftType (self_type).getPointer ())) {
249
- if (ref_type->getOwnership () == swift::ReferenceOwnership::Weak) {
250
- m_is_class = true ;
251
- m_is_weak_self = true ;
252
- }
260
+ auto *ref_type =
261
+ llvm::dyn_cast_or_null<swift::ReferenceStorageType>(info.swift_type );
262
+ if (ref_type && ref_type->getOwnership () == swift::ReferenceOwnership::Weak) {
263
+ m_is_class = true ;
264
+ m_is_weak_self = true ;
253
265
}
254
266
255
- if (Flags (self_type.GetTypeInfo ())
256
- .AllSet (lldb::eTypeIsSwift | lldb::eTypeIsStructUnion |
257
- lldb::eTypeIsGeneric) &&
258
- self_type_flags.AllSet (lldb::eTypeIsSwift | lldb::eTypeIsReference |
259
- lldb::eTypeHasValue)) {
260
- // We can't extend generic structs when "self" is mutating at the
261
- // moment.
262
- m_needs_object_ptr = false ;
263
- }
267
+ m_needs_object_ptr = !m_in_static_method;
264
268
265
- if (log)
266
- log->Printf (" [SUE::SC] Containing class name: %s" ,
267
- self_type.GetTypeName ().AsCString ());
269
+ LLDB_LOGF (log, " [SUE::SC] Containing class name: %s" ,
270
+ info.type .GetTypeName ().AsCString ());
268
271
}
269
272
270
273
static SwiftPersistentExpressionState *
0 commit comments