LLDB mainline
DILEval.cpp
Go to the documentation of this file.
1//===-- DILEval.cpp -------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "lldb/Core/Module.h"
19#include "llvm/Support/FormatAdapters.h"
20#include <memory>
21
22namespace lldb_private::dil {
23
26 lldb::DynamicValueType use_dynamic,
27 bool use_synthetic) {
28 if (!value_sp)
29 return nullptr;
30
31 if (use_dynamic != lldb::eNoDynamicValues) {
32 lldb::ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(use_dynamic);
33 if (dynamic_sp)
34 value_sp = dynamic_sp;
35 }
36
37 if (use_synthetic) {
38 lldb::ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue();
39 if (synthetic_sp)
40 value_sp = synthetic_sp;
41 }
42
43 return value_sp;
44}
45
46static llvm::Expected<lldb::TypeSystemSP>
47GetTypeSystemFromCU(std::shared_ptr<ExecutionContextScope> ctx) {
48 auto stack_frame = ctx->CalculateStackFrame();
49 if (!stack_frame)
50 return llvm::createStringError("no stack frame in this context");
51 SymbolContext symbol_context =
52 stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
53 lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
54
55 symbol_context = stack_frame->GetSymbolContext(lldb::eSymbolContextModule);
56 return symbol_context.module_sp->GetTypeSystemForLanguage(language);
57}
58
60 lldb::BasicType basic_type) {
61 if (type_system)
62 return type_system.get()->GetBasicTypeFromAST(basic_type);
63
64 return CompilerType();
65}
66
69 llvm::StringRef name) {
70 uint64_t addr = valobj.GetLoadAddress();
71 ExecutionContext exe_ctx;
72 ctx.CalculateExecutionContext(exe_ctx);
74 name, addr, exe_ctx,
76 /* do_deref */ false);
77}
78
79llvm::Expected<lldb::ValueObjectSP>
81 if (!valobj)
82 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
83 location);
84 llvm::Expected<lldb::TypeSystemSP> type_system =
86 if (!type_system)
87 return type_system.takeError();
88
89 CompilerType in_type = valobj->GetCompilerType();
90 if (valobj->IsBitfield()) {
91 // Promote bitfields. If `int` can represent the bitfield value, it is
92 // converted to `int`. Otherwise, if `unsigned int` can represent it, it
93 // is converted to `unsigned int`. Otherwise, it is treated as its
94 // underlying type.
95 uint32_t bitfield_size = valobj->GetBitfieldBitSize();
96 // Some bitfields have undefined size (e.g. result of ternary operation).
97 // The AST's `bitfield_size` of those is 0, and no promotion takes place.
98 if (bitfield_size > 0 && in_type.IsInteger()) {
99 CompilerType int_type = GetBasicType(*type_system, lldb::eBasicTypeInt);
100 CompilerType uint_type =
102 llvm::Expected<uint64_t> int_bit_size =
103 int_type.GetBitSize(m_exe_ctx_scope.get());
104 if (!int_bit_size)
105 return int_bit_size.takeError();
106 llvm::Expected<uint64_t> uint_bit_size =
107 uint_type.GetBitSize(m_exe_ctx_scope.get());
108 if (!uint_bit_size)
109 return int_bit_size.takeError();
110 if (bitfield_size < *int_bit_size ||
111 (in_type.IsSigned() && bitfield_size == *int_bit_size))
112 return valobj->CastToBasicType(int_type);
113 if (bitfield_size <= *uint_bit_size)
114 return valobj->CastToBasicType(uint_type);
115 // Re-create as a const value with the same underlying type
116 Scalar scalar;
117 bool resolved = valobj->ResolveValue(scalar);
118 if (!resolved)
119 return llvm::createStringError("invalid scalar value");
121 "result");
122 }
123 }
124
125 if (in_type.IsArrayType())
126 valobj = ArrayToPointerConversion(*valobj, *m_exe_ctx_scope, "result");
127
128 if (valobj->GetCompilerType().IsInteger() ||
129 valobj->GetCompilerType().IsUnscopedEnumerationType()) {
130 llvm::Expected<CompilerType> promoted_type =
131 type_system.get()->DoIntegralPromotion(valobj->GetCompilerType(),
132 m_exe_ctx_scope.get());
133 if (!promoted_type)
134 return promoted_type.takeError();
135 if (!promoted_type->CompareTypes(valobj->GetCompilerType()))
136 return valobj->CastToBasicType(*promoted_type);
137 }
138
139 return valobj;
140}
141
143 VariableList &variable_list) {
144 lldb::VariableSP exact_match;
145 std::vector<lldb::VariableSP> possible_matches;
146
147 for (lldb::VariableSP var_sp : variable_list) {
148 llvm::StringRef str_ref_name = var_sp->GetName().GetStringRef();
149
150 str_ref_name.consume_front("::");
151 // Check for the exact same match
152 if (str_ref_name == name.GetStringRef())
153 return var_sp;
154
155 // Check for possible matches by base name
156 if (var_sp->NameMatches(name))
157 possible_matches.push_back(var_sp);
158 }
159
160 // If there's a non-exact match, take it.
161 if (possible_matches.size() > 0)
162 return possible_matches[0];
163
164 return nullptr;
165}
166
168 llvm::StringRef name_ref, std::shared_ptr<StackFrame> stack_frame,
169 lldb::TargetSP target_sp, lldb::DynamicValueType use_dynamic) {
170 // Get a global variables list without the locals from the current frame
171 SymbolContext symbol_context =
172 stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
173 lldb::VariableListSP variable_list;
174 if (symbol_context.comp_unit)
175 variable_list = symbol_context.comp_unit->GetVariableList(true);
176
177 name_ref.consume_front("::");
178 lldb::ValueObjectSP value_sp;
179 if (variable_list) {
180 lldb::VariableSP var_sp =
181 DILFindVariable(ConstString(name_ref), *variable_list);
182 if (var_sp)
183 value_sp =
184 stack_frame->GetValueObjectForFrameVariable(var_sp, use_dynamic);
185 }
186
187 if (value_sp)
188 return value_sp;
189
190 // Check for match in modules global variables.
191 VariableList modules_var_list;
192 target_sp->GetImages().FindGlobalVariables(
193 ConstString(name_ref), std::numeric_limits<uint32_t>::max(),
194 modules_var_list);
195
196 if (!modules_var_list.Empty()) {
197 lldb::VariableSP var_sp =
198 DILFindVariable(ConstString(name_ref), modules_var_list);
199 if (var_sp)
200 value_sp = ValueObjectVariable::Create(stack_frame.get(), var_sp);
201
202 if (value_sp)
203 return value_sp;
204 }
205 return nullptr;
206}
207
208lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
209 std::shared_ptr<StackFrame> stack_frame,
210 lldb::DynamicValueType use_dynamic) {
211 // Support $rax as a special syntax for accessing registers.
212 // Will return an invalid value in case the requested register doesn't exist.
213 if (name_ref.consume_front("$")) {
214 lldb::RegisterContextSP reg_ctx(stack_frame->GetRegisterContext());
215 if (!reg_ctx)
216 return nullptr;
217
218 if (const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name_ref))
219 return ValueObjectRegister::Create(stack_frame.get(), reg_ctx, reg_info);
220
221 return nullptr;
222 }
223
224 if (!name_ref.contains("::")) {
225 // Lookup in the current frame.
226 // Try looking for a local variable in current scope.
227 lldb::VariableListSP variable_list(
228 stack_frame->GetInScopeVariableList(false));
229
230 lldb::ValueObjectSP value_sp;
231 if (variable_list) {
232 lldb::VariableSP var_sp =
233 variable_list->FindVariable(ConstString(name_ref));
234 if (var_sp)
235 value_sp =
236 stack_frame->GetValueObjectForFrameVariable(var_sp, use_dynamic);
237 }
238
239 if (value_sp)
240 return value_sp;
241
242 // Try looking for an instance variable (class member).
243 SymbolContext sc = stack_frame->GetSymbolContext(
244 lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
245 llvm::StringRef ivar_name = sc.GetInstanceVariableName();
246 value_sp = stack_frame->FindVariable(ConstString(ivar_name));
247 if (value_sp)
248 value_sp = value_sp->GetChildMemberWithName(name_ref);
249
250 if (value_sp)
251 return value_sp;
252 }
253 return nullptr;
254}
255
256Interpreter::Interpreter(lldb::TargetSP target, llvm::StringRef expr,
257 std::shared_ptr<StackFrame> frame_sp,
258 lldb::DynamicValueType use_dynamic, bool use_synthetic,
259 bool fragile_ivar, bool check_ptr_vs_member)
260 : m_target(std::move(target)), m_expr(expr), m_exe_ctx_scope(frame_sp),
261 m_use_dynamic(use_dynamic), m_use_synthetic(use_synthetic),
262 m_fragile_ivar(fragile_ivar), m_check_ptr_vs_member(check_ptr_vs_member) {
263}
264
265llvm::Expected<lldb::ValueObjectSP> Interpreter::Evaluate(const ASTNode &node) {
266 // Evaluate an AST.
267 auto value_or_error = node.Accept(this);
268 // Convert SP with a nullptr to an error.
269 if (value_or_error && !*value_or_error)
270 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
271 node.GetLocation());
272 // Return the computed value-or-error. The caller is responsible for
273 // checking if an error occured during the evaluation.
274 return value_or_error;
275}
276
277llvm::Expected<lldb::ValueObjectSP>
279 auto valobj_or_err = Evaluate(node);
280 if (!valobj_or_err)
281 return valobj_or_err;
282 lldb::ValueObjectSP valobj = *valobj_or_err;
283
285 if (valobj->GetCompilerType().IsReferenceType()) {
286 valobj = valobj->Dereference(error);
287 if (error.Fail())
288 return error.ToError();
289 }
290 return valobj;
291}
292
293llvm::Expected<lldb::ValueObjectSP>
296
297 lldb::ValueObjectSP identifier =
298 LookupIdentifier(node.GetName(), m_exe_ctx_scope, use_dynamic);
299
300 if (!identifier)
302 m_target, use_dynamic);
303 if (!identifier) {
304 std::string errMsg =
305 llvm::formatv("use of undeclared identifier '{0}'", node.GetName());
306 return llvm::make_error<DILDiagnosticError>(
307 m_expr, errMsg, node.GetLocation(), node.GetName().size());
308 }
309
310 return identifier;
311}
312
313llvm::Expected<lldb::ValueObjectSP>
316 auto op_or_err = Evaluate(node.GetOperand());
317 if (!op_or_err)
318 return op_or_err;
319
320 lldb::ValueObjectSP operand = *op_or_err;
321
322 switch (node.GetKind()) {
323 case UnaryOpKind::Deref: {
324 lldb::ValueObjectSP dynamic_op = operand->GetDynamicValue(m_use_dynamic);
325 if (dynamic_op)
326 operand = dynamic_op;
327
328 lldb::ValueObjectSP child_sp = operand->Dereference(error);
329 if (!child_sp && m_use_synthetic) {
330 if (lldb::ValueObjectSP synth_obj_sp = operand->GetSyntheticValue()) {
331 error.Clear();
332 child_sp = synth_obj_sp->Dereference(error);
333 }
334 }
335 if (error.Fail())
336 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
337 node.GetLocation());
338
339 return child_sp;
340 }
341 case UnaryOpKind::AddrOf: {
343 lldb::ValueObjectSP value = operand->AddressOf(error);
344 if (error.Fail())
345 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
346 node.GetLocation());
347
348 return value;
349 }
350 case UnaryOpKind::Minus: {
351 if (operand->GetCompilerType().IsReferenceType()) {
352 operand = operand->Dereference(error);
353 if (error.Fail())
354 return error.ToError();
355 }
356 llvm::Expected<lldb::ValueObjectSP> conv_op =
357 UnaryConversion(operand, node.GetOperand().GetLocation());
358 if (!conv_op)
359 return conv_op;
360 operand = *conv_op;
361 CompilerType operand_type = operand->GetCompilerType();
362 if (!operand_type.IsScalarType()) {
363 std::string errMsg =
364 llvm::formatv("invalid argument type '{0}' to unary expression",
365 operand_type.GetTypeName());
366 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
367 node.GetLocation());
368 }
369 Scalar scalar;
370 bool resolved = operand->ResolveValue(scalar);
371 if (!resolved)
372 break;
373
374 bool negated = scalar.UnaryNegate();
375 if (negated)
377 m_target, scalar, operand->GetCompilerType(), "result");
378 break;
379 }
380 case UnaryOpKind::Plus: {
381 if (operand->GetCompilerType().IsReferenceType()) {
382 operand = operand->Dereference(error);
383 if (error.Fail())
384 return error.ToError();
385 }
386 llvm::Expected<lldb::ValueObjectSP> conv_op =
387 UnaryConversion(operand, node.GetOperand().GetLocation());
388 if (!conv_op)
389 return conv_op;
390 operand = *conv_op;
391 CompilerType operand_type = operand->GetCompilerType();
392 if (!operand_type.IsScalarType() &&
393 // Unary plus is allowed for pointers.
394 !operand_type.IsPointerType()) {
395 std::string errMsg =
396 llvm::formatv("invalid argument type '{0}' to unary expression",
397 operand_type.GetTypeName());
398 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
399 node.GetLocation());
400 }
401 return operand;
402 }
403 }
404 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid unary operation",
405 node.GetLocation());
406}
407
408llvm::Expected<lldb::ValueObjectSP>
410 auto base_or_err = Evaluate(node.GetBase());
411 if (!base_or_err)
412 return base_or_err;
413 bool expr_is_ptr = node.GetIsArrow();
414 lldb::ValueObjectSP base = *base_or_err;
415
416 // Perform some basic type & correctness checking.
417 if (node.GetIsArrow()) {
418 if (!m_fragile_ivar) {
419 // Make sure we aren't trying to deref an objective
420 // C ivar if this is not allowed
421 const uint32_t pointer_type_flags =
422 base->GetCompilerType().GetTypeInfo(nullptr);
423 if ((pointer_type_flags & lldb::eTypeIsObjC) &&
424 (pointer_type_flags & lldb::eTypeIsPointer)) {
425 // This was an objective C object pointer and it was requested we
426 // skip any fragile ivars so return nothing here
427 return lldb::ValueObjectSP();
428 }
429 }
430
431 // If we have a non-pointer type with a synthetic value then lets check
432 // if we have a synthetic dereference specified.
433 if (!base->IsPointerType() && base->HasSyntheticValue()) {
434 Status deref_error;
435 if (lldb::ValueObjectSP synth_deref_sp =
436 base->GetSyntheticValue()->Dereference(deref_error);
437 synth_deref_sp && deref_error.Success()) {
438 base = std::move(synth_deref_sp);
439 }
440 if (!base || deref_error.Fail()) {
441 std::string errMsg = llvm::formatv(
442 "Failed to dereference synthetic value: {0}", deref_error);
443 return llvm::make_error<DILDiagnosticError>(
444 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
445 }
446
447 // Some synthetic plug-ins fail to set the error in Dereference
448 if (!base) {
449 std::string errMsg = "Failed to dereference synthetic value";
450 return llvm::make_error<DILDiagnosticError>(
451 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
452 }
453 expr_is_ptr = false;
454 }
455 }
456
458 bool base_is_ptr = base->IsPointerType();
459
460 if (expr_is_ptr != base_is_ptr) {
461 if (base_is_ptr) {
462 std::string errMsg =
463 llvm::formatv("member reference type {0} is a pointer; "
464 "did you mean to use '->'?",
465 base->GetCompilerType().TypeDescription());
466 return llvm::make_error<DILDiagnosticError>(
467 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
468 } else {
469 std::string errMsg =
470 llvm::formatv("member reference type {0} is not a pointer; "
471 "did you mean to use '.'?",
472 base->GetCompilerType().TypeDescription());
473 return llvm::make_error<DILDiagnosticError>(
474 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
475 }
476 }
477 }
478
479 lldb::ValueObjectSP field_obj =
480 base->GetChildMemberWithName(node.GetFieldName());
481 if (!field_obj) {
482 if (m_use_synthetic) {
483 field_obj = base->GetSyntheticValue();
484 if (field_obj)
485 field_obj = field_obj->GetChildMemberWithName(node.GetFieldName());
486 }
487
488 if (!m_use_synthetic || !field_obj) {
489 std::string errMsg = llvm::formatv(
490 "\"{0}\" is not a member of \"({1}) {2}\"", node.GetFieldName(),
491 base->GetTypeName().AsCString("<invalid type>"), base->GetName());
492 return llvm::make_error<DILDiagnosticError>(
493 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
494 }
495 }
496
497 if (field_obj) {
499 lldb::ValueObjectSP dynamic_val_sp =
500 field_obj->GetDynamicValue(m_use_dynamic);
501 if (dynamic_val_sp)
502 field_obj = dynamic_val_sp;
503 }
504 return field_obj;
505 }
506
507 CompilerType base_type = base->GetCompilerType();
508 if (node.GetIsArrow() && base->IsPointerType())
509 base_type = base_type.GetPointeeType();
510 std::string errMsg = llvm::formatv(
511 "\"{0}\" is not a member of \"({1}) {2}\"", node.GetFieldName(),
512 base->GetTypeName().AsCString("<invalid type>"), base->GetName());
513 return llvm::make_error<DILDiagnosticError>(
514 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
515}
516
517llvm::Expected<lldb::ValueObjectSP>
519 auto idx_or_err = EvaluateAndDereference(node.GetIndex());
520 if (!idx_or_err)
521 return idx_or_err;
522 lldb::ValueObjectSP idx = *idx_or_err;
523
524 if (!idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType()) {
525 return llvm::make_error<DILDiagnosticError>(
526 m_expr, "array subscript is not an integer", node.GetLocation());
527 }
528
529 StreamString var_expr_path_strm;
530 uint64_t child_idx = idx->GetValueAsUnsigned(0);
531 lldb::ValueObjectSP child_valobj_sp;
532
533 auto base_or_err = Evaluate(node.GetBase());
534 if (!base_or_err)
535 return base_or_err;
536 lldb::ValueObjectSP base = *base_or_err;
537
538 CompilerType base_type = base->GetCompilerType().GetNonReferenceType();
539 base->GetExpressionPath(var_expr_path_strm);
540 bool is_incomplete_array = false;
541 if (base_type.IsPointerType()) {
542 bool is_objc_pointer = true;
543
544 if (base->GetCompilerType().GetMinimumLanguage() != lldb::eLanguageTypeObjC)
545 is_objc_pointer = false;
546 else if (!base->GetCompilerType().IsPointerType())
547 is_objc_pointer = false;
548
549 if (!m_use_synthetic && is_objc_pointer) {
550 std::string err_msg = llvm::formatv(
551 "\"({0}) {1}\" is an Objective-C pointer, and cannot be subscripted",
552 base->GetTypeName().AsCString("<invalid type>"),
553 var_expr_path_strm.GetData());
554 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
555 node.GetLocation());
556 }
557 if (is_objc_pointer) {
558 lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
559 if (!synthetic || synthetic == base) {
560 std::string err_msg =
561 llvm::formatv("\"({0}) {1}\" is not an array type",
562 base->GetTypeName().AsCString("<invalid type>"),
563 var_expr_path_strm.GetData());
564 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
565 node.GetLocation());
566 }
567 if (static_cast<uint32_t>(child_idx) >=
568 synthetic->GetNumChildrenIgnoringErrors()) {
569 std::string err_msg = llvm::formatv(
570 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
571 base->GetTypeName().AsCString("<invalid type>"),
572 var_expr_path_strm.GetData());
573 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
574 node.GetLocation());
575 }
576 child_valobj_sp = synthetic->GetChildAtIndex(child_idx);
577 if (!child_valobj_sp) {
578 std::string err_msg = llvm::formatv(
579 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
580 base->GetTypeName().AsCString("<invalid type>"),
581 var_expr_path_strm.GetData());
582 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
583 node.GetLocation());
584 }
586 if (auto dynamic_sp = child_valobj_sp->GetDynamicValue(m_use_dynamic))
587 child_valobj_sp = std::move(dynamic_sp);
588 }
589 return child_valobj_sp;
590 }
591
592 child_valobj_sp = base->GetSyntheticArrayMember(child_idx, true);
593 if (!child_valobj_sp) {
594 std::string err_msg = llvm::formatv(
595 "failed to use pointer as array for index {0} for "
596 "\"({1}) {2}\"",
597 child_idx, base->GetTypeName().AsCString("<invalid type>"),
598 var_expr_path_strm.GetData());
599 if (base_type.IsPointerToVoid())
600 err_msg = "subscript of pointer to incomplete type 'void'";
601 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
602 node.GetLocation());
603 }
604 } else if (base_type.IsArrayType(nullptr, nullptr, &is_incomplete_array)) {
605 child_valobj_sp = base->GetChildAtIndex(child_idx);
606 if (!child_valobj_sp && (is_incomplete_array || m_use_synthetic))
607 child_valobj_sp = base->GetSyntheticArrayMember(child_idx, true);
608 if (!child_valobj_sp) {
609 std::string err_msg = llvm::formatv(
610 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
611 base->GetTypeName().AsCString("<invalid type>"),
612 var_expr_path_strm.GetData());
613 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
614 node.GetLocation());
615 }
616 } else if (base_type.IsScalarType()) {
617 child_valobj_sp =
618 base->GetSyntheticBitFieldChild(child_idx, child_idx, true);
619 if (!child_valobj_sp) {
620 std::string err_msg = llvm::formatv(
621 "bitfield range {0}-{1} is not valid for \"({2}) {3}\"", child_idx,
622 child_idx, base->GetTypeName().AsCString("<invalid type>"),
623 var_expr_path_strm.GetData());
624 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
625 node.GetLocation(), 1);
626 }
627 } else {
628 lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
629 if (!m_use_synthetic || !synthetic || synthetic == base) {
630 std::string err_msg =
631 llvm::formatv("\"{0}\" is not an array type",
632 base->GetTypeName().AsCString("<invalid type>"));
633 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
634 node.GetLocation(), 1);
635 }
636 if (static_cast<uint32_t>(child_idx) >=
637 synthetic->GetNumChildrenIgnoringErrors(child_idx + 1)) {
638 std::string err_msg = llvm::formatv(
639 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
640 base->GetTypeName().AsCString("<invalid type>"),
641 var_expr_path_strm.GetData());
642 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
643 node.GetLocation(), 1);
644 }
645 child_valobj_sp = synthetic->GetChildAtIndex(child_idx);
646 if (!child_valobj_sp) {
647 std::string err_msg = llvm::formatv(
648 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
649 base->GetTypeName().AsCString("<invalid type>"),
650 var_expr_path_strm.GetData());
651 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
652 node.GetLocation(), 1);
653 }
654 }
655
656 if (child_valobj_sp) {
658 if (auto dynamic_sp = child_valobj_sp->GetDynamicValue(m_use_dynamic))
659 child_valobj_sp = std::move(dynamic_sp);
660 }
661 return child_valobj_sp;
662 }
663
664 bool success;
665 int64_t signed_child_idx = idx->GetValueAsSigned(0, &success);
666 if (!success)
667 return llvm::make_error<DILDiagnosticError>(
668 m_expr, "could not get the index as an integer",
669 node.GetIndex().GetLocation());
670 return base->GetSyntheticArrayMember(signed_child_idx, true);
671}
672
673llvm::Expected<lldb::ValueObjectSP>
675 auto first_idx_or_err = EvaluateAndDereference(node.GetFirstIndex());
676 if (!first_idx_or_err)
677 return first_idx_or_err;
678 lldb::ValueObjectSP first_idx = *first_idx_or_err;
679 auto last_idx_or_err = EvaluateAndDereference(node.GetLastIndex());
680 if (!last_idx_or_err)
681 return last_idx_or_err;
682 lldb::ValueObjectSP last_idx = *last_idx_or_err;
683
684 if (!first_idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType() ||
685 !last_idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType()) {
686 return llvm::make_error<DILDiagnosticError>(
687 m_expr, "bit index is not an integer", node.GetLocation());
688 }
689
690 bool success_first, success_last;
691 int64_t first_index = first_idx->GetValueAsSigned(0, &success_first);
692 int64_t last_index = last_idx->GetValueAsSigned(0, &success_last);
693 if (!success_first || !success_last)
694 return llvm::make_error<DILDiagnosticError>(
695 m_expr, "could not get the index as an integer", node.GetLocation());
696
697 // if the format given is [high-low], swap range
698 if (first_index > last_index)
699 std::swap(first_index, last_index);
700
701 auto base_or_err = EvaluateAndDereference(node.GetBase());
702 if (!base_or_err)
703 return base_or_err;
704 lldb::ValueObjectSP base = *base_or_err;
705 lldb::ValueObjectSP child_valobj_sp =
706 base->GetSyntheticBitFieldChild(first_index, last_index, true);
707 if (!child_valobj_sp) {
708 std::string message = llvm::formatv(
709 "bitfield range {0}-{1} is not valid for \"({2}) {3}\"", first_index,
710 last_index, base->GetTypeName().AsCString("<invalid type>"),
711 base->GetName().AsCString());
712 return llvm::make_error<DILDiagnosticError>(m_expr, message,
713 node.GetLocation());
714 }
715 return child_valobj_sp;
716}
717
718llvm::Expected<CompilerType>
720 std::shared_ptr<ExecutionContextScope> ctx,
721 const IntegerLiteralNode &literal) {
722 // Binary, Octal, Hexadecimal and literals with a U suffix are allowed to be
723 // an unsigned integer.
724 bool unsigned_is_allowed = literal.IsUnsigned() || literal.GetRadix() != 10;
725 llvm::APInt apint = literal.GetValue();
726
727 llvm::SmallVector<std::pair<lldb::BasicType, lldb::BasicType>, 3> candidates;
728 if (literal.GetTypeSuffix() <= IntegerTypeSuffix::None)
729 candidates.emplace_back(lldb::eBasicTypeInt,
730 unsigned_is_allowed ? lldb::eBasicTypeUnsignedInt
732 if (literal.GetTypeSuffix() <= IntegerTypeSuffix::Long)
733 candidates.emplace_back(lldb::eBasicTypeLong,
734 unsigned_is_allowed ? lldb::eBasicTypeUnsignedLong
736 candidates.emplace_back(lldb::eBasicTypeLongLong,
738 for (auto [signed_, unsigned_] : candidates) {
739 CompilerType signed_type = type_system->GetBasicTypeFromAST(signed_);
740 if (!signed_type)
741 continue;
742 llvm::Expected<uint64_t> size = signed_type.GetBitSize(ctx.get());
743 if (!size)
744 return size.takeError();
745 if (!literal.IsUnsigned() && apint.isIntN(*size - 1))
746 return signed_type;
747 if (unsigned_ != lldb::eBasicTypeInvalid && apint.isIntN(*size))
748 return type_system->GetBasicTypeFromAST(unsigned_);
749 }
750
751 return llvm::make_error<DILDiagnosticError>(
752 m_expr,
753 "integer literal is too large to be represented in any integer type",
754 literal.GetLocation());
755}
756
757llvm::Expected<lldb::ValueObjectSP>
759 llvm::Expected<lldb::TypeSystemSP> type_system =
761 if (!type_system)
762 return type_system.takeError();
763
764 llvm::Expected<CompilerType> type =
765 PickIntegerType(*type_system, m_exe_ctx_scope, node);
766 if (!type)
767 return type.takeError();
768
769 Scalar scalar = node.GetValue();
770 // APInt from StringRef::getAsInteger comes with just enough bitwidth to
771 // hold the value. This adjusts APInt bitwidth to match the compiler type.
772 llvm::Expected<uint64_t> type_bitsize =
773 type->GetBitSize(m_exe_ctx_scope.get());
774 if (!type_bitsize)
775 return type_bitsize.takeError();
776 scalar.TruncOrExtendTo(*type_bitsize, false);
778 "result");
779}
780
781llvm::Expected<lldb::ValueObjectSP>
783 llvm::Expected<lldb::TypeSystemSP> type_system =
785 if (!type_system)
786 return type_system.takeError();
787
788 bool isFloat =
789 &node.GetValue().getSemantics() == &llvm::APFloat::IEEEsingle();
790 lldb::BasicType basic_type =
792 CompilerType type = GetBasicType(*type_system, basic_type);
793
794 if (!type)
795 return llvm::make_error<DILDiagnosticError>(
796 m_expr, "unable to create a const literal", node.GetLocation());
797
798 Scalar scalar = node.GetValue();
800 "result");
801}
802
803llvm::Expected<lldb::ValueObjectSP>
805 bool value = node.GetValue();
806 return ValueObject::CreateValueObjectFromBool(m_target, value, "result");
807}
808
809llvm::Expected<CastKind>
811 CompilerType target_type, int location) {
812 if (source_type.IsPointerType() || source_type.IsNullPtrType()) {
813 // Cast from pointer to float/double is not allowed.
814 if (target_type.IsFloat()) {
815 std::string errMsg = llvm::formatv("Cast from {0} to {1} is not allowed",
816 source_type.TypeDescription(),
817 target_type.TypeDescription());
818 return llvm::make_error<DILDiagnosticError>(
819 m_expr, std::move(errMsg), location,
820 source_type.TypeDescription().length());
821 }
822
823 // Casting from pointer to bool is always valid.
824 if (target_type.IsBoolean())
826
827 // Otherwise check if the result type is at least as big as the pointer
828 // size.
829 uint64_t type_byte_size = 0;
830 uint64_t rhs_type_byte_size = 0;
831 if (auto temp = target_type.GetByteSize(m_exe_ctx_scope.get())) {
832 type_byte_size = *temp;
833 } else {
834 std::string errMsg = llvm::formatv("unable to get byte size for type {0}",
835 target_type.TypeDescription());
836 return llvm::make_error<DILDiagnosticError>(
837 m_expr, std::move(errMsg), location,
838 target_type.TypeDescription().length());
839 }
840
841 if (auto temp = source_type.GetByteSize(m_exe_ctx_scope.get())) {
842 rhs_type_byte_size = *temp;
843 } else {
844 std::string errMsg = llvm::formatv("unable to get byte size for type {0}",
845 source_type.TypeDescription());
846 return llvm::make_error<DILDiagnosticError>(
847 m_expr, std::move(errMsg), location,
848 source_type.TypeDescription().length());
849 }
850
851 if (type_byte_size < rhs_type_byte_size) {
852 std::string errMsg = llvm::formatv(
853 "cast from pointer to smaller type {0} loses information",
854 target_type.TypeDescription());
855 return llvm::make_error<DILDiagnosticError>(
856 m_expr, std::move(errMsg), location,
857 source_type.TypeDescription().length());
858 }
859 } else if (!source_type.IsScalarType() && !source_type.IsEnumerationType()) {
860 // Otherwise accept only arithmetic types and enums.
861 std::string errMsg = llvm::formatv("cannot convert {0} to {1}",
862 source_type.TypeDescription(),
863 target_type.TypeDescription());
864
865 return llvm::make_error<DILDiagnosticError>(
866 m_expr, std::move(errMsg), location,
867 source_type.TypeDescription().length());
868 }
870}
871
872llvm::Expected<CastKind>
874 CompilerType source_type, CompilerType target_type,
875 int location) {
876
877 if (target_type.IsScalarType())
878 return VerifyArithmeticCast(source_type, target_type, location);
879
880 if (target_type.IsEnumerationType()) {
881 // Cast to enum type.
882 if (!source_type.IsScalarType() && !source_type.IsEnumerationType()) {
883 std::string errMsg = llvm::formatv("Cast from {0} to {1} is not allowed",
884 source_type.TypeDescription(),
885 target_type.TypeDescription());
886
887 return llvm::make_error<DILDiagnosticError>(
888 m_expr, std::move(errMsg), location,
889 source_type.TypeDescription().length());
890 }
892 }
893
894 if (target_type.IsPointerType()) {
895 if (!source_type.IsInteger() && !source_type.IsEnumerationType() &&
896 !source_type.IsArrayType() && !source_type.IsPointerType() &&
897 !source_type.IsNullPtrType()) {
898 std::string errMsg = llvm::formatv(
899 "cannot cast from type {0} to pointer type {1}",
900 source_type.TypeDescription(), target_type.TypeDescription());
901
902 return llvm::make_error<DILDiagnosticError>(
903 m_expr, std::move(errMsg), location,
904 source_type.TypeDescription().length());
905 }
906 return CastKind::ePointer;
907 }
908
909 // Unsupported cast.
910 std::string errMsg = llvm::formatv(
911 "casting of {0} to {1} is not implemented yet",
912 source_type.TypeDescription(), target_type.TypeDescription());
913 return llvm::make_error<DILDiagnosticError>(
914 m_expr, std::move(errMsg), location,
915 source_type.TypeDescription().length());
916}
917
918llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const CastNode &node) {
919 auto operand_or_err = Evaluate(node.GetOperand());
920
921 if (!operand_or_err)
922 return operand_or_err;
923
924 lldb::ValueObjectSP operand = *operand_or_err;
925 CompilerType op_type = operand->GetCompilerType();
926 CompilerType target_type = node.GetType();
927
928 if (op_type.IsReferenceType())
929 op_type = op_type.GetNonReferenceType();
930 if (target_type.IsScalarType() && op_type.IsArrayType()) {
931 operand = ArrayToPointerConversion(*operand, *m_exe_ctx_scope,
932 operand->GetName().GetStringRef());
933 op_type = operand->GetCompilerType();
934 }
935 auto type_or_err =
936 VerifyCastType(operand, op_type, target_type, node.GetLocation());
937 if (!type_or_err)
938 return type_or_err.takeError();
939
940 CastKind cast_kind = *type_or_err;
941 if (operand->GetCompilerType().IsReferenceType()) {
943 operand = operand->Dereference(error);
944 if (error.Fail())
945 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
946 node.GetLocation());
947 }
948
949 switch (cast_kind) {
951 if (op_type.IsFloat() || op_type.IsInteger() || op_type.IsEnumerationType())
952 return operand->CastToEnumType(target_type);
953 break;
954 }
956 if (op_type.IsPointerType() || op_type.IsNullPtrType() ||
957 op_type.IsScalarType() || op_type.IsEnumerationType())
958 return operand->CastToBasicType(target_type);
959 break;
960 }
961 case CastKind::ePointer: {
962 uint64_t addr = op_type.IsArrayType()
963 ? operand->GetLoadAddress()
964 : (op_type.IsSigned() ? operand->GetValueAsSigned(0)
965 : operand->GetValueAsUnsigned(0));
966 llvm::StringRef name = "result";
967 ExecutionContext exe_ctx(m_target.get(), false);
968 return ValueObject::CreateValueObjectFromAddress(name, addr, exe_ctx,
969 target_type,
970 /* do_deref */ false);
971 }
972 case CastKind::eNone: {
973 return lldb::ValueObjectSP();
974 }
975 } // switch
976
977 std::string errMsg =
978 llvm::formatv("unable to cast from '{0}' to '{1}'",
979 op_type.TypeDescription(), target_type.TypeDescription());
980 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
981 node.GetLocation());
982}
983
984} // namespace lldb_private::dil
static llvm::raw_ostream & error(Stream &strm)
lldb::VariableListSP GetVariableList(bool can_create)
Get the variable list for a compile unit.
lldb::LanguageType GetLanguage()
Generic representation of a type in a programming language.
bool IsEnumerationType(bool &is_signed) const
bool IsArrayType(CompilerType *element_type=nullptr, uint64_t *size=nullptr, bool *is_incomplete=nullptr) const
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bytes.
CompilerType GetNonReferenceType() const
If this type is a reference to a type (L value or R value reference), return a new type with the refe...
ConstString GetTypeName(bool BaseOnly=false) const
bool IsReferenceType(CompilerType *pointee_type=nullptr, bool *is_rvalue=nullptr) const
CompilerType GetArrayElementType(ExecutionContextScope *exe_scope) const
Creating related types.
bool IsInteger() const
This is used when you don't care about the signedness of the integer.
CompilerType GetPointeeType() const
If this type is a pointer type, return the type that the pointer points to, else return an invalid ty...
llvm::Expected< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
bool IsPointerType(CompilerType *pointee_type=nullptr) const
A uniqued constant string class.
Definition ConstString.h:40
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
"lldb/Target/ExecutionContextScope.h" Inherit from this if your object can reconstruct its execution ...
virtual void CalculateExecutionContext(ExecutionContext &exe_ctx)=0
Reconstruct the object's execution context into sc.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
void TruncOrExtendTo(uint16_t bits, bool sign)
Convert to an integer with bits and the given signedness.
Definition Scalar.cpp:204
An error handling class.
Definition Status.h:118
bool Fail() const
Test for error condition.
Definition Status.cpp:294
bool Success() const
Test for success condition.
Definition Status.cpp:304
const char * GetData() const
Defines a symbol context baton that can be handed other debug core functions.
llvm::StringRef GetInstanceVariableName()
Determines the name of the instance variable for the this decl context.
lldb::ModuleSP module_sp
The Module for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, const RegisterInfo *reg_info)
static lldb::ValueObjectSP Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
static lldb::ValueObjectSP CreateValueObjectFromBool(lldb::TargetSP target, bool value, llvm::StringRef name)
Create a value object containing the given boolean value.
CompilerType GetCompilerType()
static lldb::ValueObjectSP CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, CompilerType type, bool do_deref=true)
Given an address either create a value object containing the value at that address,...
lldb::addr_t GetLoadAddress()
Return the target load address associated with this value object.
static lldb::ValueObjectSP CreateValueObjectFromScalar(lldb::TargetSP target, Scalar &s, CompilerType type, llvm::StringRef name)
Create a value object containing the given Scalar value.
The rest of the classes in this file, except for the Visitor class at the very end,...
Definition DILAST.h:63
uint32_t GetLocation() const
Definition DILAST.h:71
virtual llvm::Expected< lldb::ValueObjectSP > Accept(Visitor *v) const =0
ASTNode & GetOperand() const
Definition DILAST.h:268
CompilerType GetType() const
Definition DILAST.h:267
const llvm::APFloat & GetValue() const
Definition DILAST.h:231
std::string GetName() const
Definition DILAST.h:98
IntegerTypeSuffix GetTypeSuffix() const
Definition DILAST.h:210
const llvm::APInt & GetValue() const
Definition DILAST.h:207
std::shared_ptr< StackFrame > m_exe_ctx_scope
Definition DILEval.h:101
llvm::Expected< lldb::ValueObjectSP > Evaluate(const ASTNode &node)
Evaluate an ASTNode.
Definition DILEval.cpp:265
llvm::Expected< lldb::ValueObjectSP > EvaluateAndDereference(const ASTNode &node)
Evaluate an ASTNode.
Definition DILEval.cpp:278
Interpreter(lldb::TargetSP target, llvm::StringRef expr, std::shared_ptr< StackFrame > frame_sp, lldb::DynamicValueType use_dynamic, bool use_synthetic, bool fragile_ivar, bool check_ptr_vs_member)
Definition DILEval.cpp:256
llvm::Expected< lldb::ValueObjectSP > UnaryConversion(lldb::ValueObjectSP valobj, uint32_t location)
Perform usual unary conversions on a value.
Definition DILEval.cpp:80
llvm::Expected< lldb::ValueObjectSP > Visit(const IdentifierNode &node) override
Definition DILEval.cpp:294
llvm::Expected< CompilerType > PickIntegerType(lldb::TypeSystemSP type_system, std::shared_ptr< ExecutionContextScope > ctx, const IntegerLiteralNode &literal)
Definition DILEval.cpp:719
lldb::DynamicValueType m_use_dynamic
Definition DILEval.h:102
llvm::Expected< CastKind > VerifyCastType(lldb::ValueObjectSP operand, CompilerType source_type, CompilerType target_type, int location)
As a preparation for type casting, compare the requested 'target' type of the cast with the type of t...
Definition DILEval.cpp:873
llvm::Expected< CastKind > VerifyArithmeticCast(CompilerType source_type, CompilerType target_type, int location)
A helper function for VerifyCastType (below).
Definition DILEval.cpp:810
llvm::StringRef GetFieldName() const
Definition DILAST.h:119
ASTNode & GetBase() const
Definition DILAST.h:117
UnaryOpKind GetKind() const
Definition DILAST.h:139
ASTNode & GetOperand() const
Definition DILAST.h:140
CastKind
The type casts allowed by DIL.
Definition DILAST.h:42
@ eEnumeration
Casting from a scalar to an enumeration type.
Definition DILAST.h:44
@ ePointer
Casting to a pointer type.
Definition DILAST.h:45
@ eNone
Invalid promotion type (results in error).
Definition DILAST.h:46
@ eArithmetic
Casting to a scalar.
Definition DILAST.h:43
lldb::ValueObjectSP GetDynamicOrSyntheticValue(lldb::ValueObjectSP value_sp, lldb::DynamicValueType use_dynamic, bool use_synthetic)
Definition DILEval.cpp:25
static CompilerType GetBasicType(lldb::TypeSystemSP type_system, lldb::BasicType basic_type)
Definition DILEval.cpp:59
static lldb::ValueObjectSP ArrayToPointerConversion(ValueObject &valobj, ExecutionContextScope &ctx, llvm::StringRef name)
Definition DILEval.cpp:67
static llvm::Expected< lldb::TypeSystemSP > GetTypeSystemFromCU(std::shared_ptr< ExecutionContextScope > ctx)
Definition DILEval.cpp:47
static lldb::VariableSP DILFindVariable(ConstString name, VariableList &variable_list)
Definition DILEval.cpp:142
lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref, std::shared_ptr< StackFrame > frame_sp, lldb::TargetSP target_sp, lldb::DynamicValueType use_dynamic)
Given the name of an identifier, check to see if it matches the name of a global variable.
Definition DILEval.cpp:167
lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref, std::shared_ptr< StackFrame > frame_sp, lldb::DynamicValueType use_dynamic)
Given the name of an identifier (variable name, member name, type name, etc.), find the ValueObject f...
Definition DILEval.cpp:208
std::shared_ptr< lldb_private::TypeSystem > TypeSystemSP
BasicType
Basic types enumeration for the public API SBType::GetBasicType().
@ eBasicTypeUnsignedLong
@ eBasicTypeUnsignedLongLong
@ eBasicTypeUnsignedInt
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
LanguageType
Programming language type.
@ eLanguageTypeObjC
Objective-C.
std::shared_ptr< lldb_private::VariableList > VariableListSP
std::shared_ptr< lldb_private::Variable > VariableSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
Every register is described in detail including its name, alternate name (optional),...