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