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"
20#include "llvm/Support/FormatAdapters.h"
21#include <memory>
22
23namespace lldb_private::dil {
24
27 lldb::DynamicValueType use_dynamic,
28 bool use_synthetic) {
29 if (!value_sp)
30 return nullptr;
31
32 if (use_dynamic != lldb::eNoDynamicValues) {
33 lldb::ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(use_dynamic);
34 if (dynamic_sp)
35 value_sp = dynamic_sp;
36 }
37
38 if (use_synthetic) {
39 lldb::ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue();
40 if (synthetic_sp)
41 value_sp = synthetic_sp;
42 }
43
44 return value_sp;
45}
46
48 lldb::BasicType basic_type) {
49 if (type_system)
50 return type_system.get()->GetBasicTypeFromAST(basic_type);
51
52 return CompilerType();
53}
54
57 llvm::StringRef name) {
58 uint64_t addr = valobj.GetLoadAddress();
59 ExecutionContext exe_ctx;
60 ctx.CalculateExecutionContext(exe_ctx);
62 name, addr, exe_ctx,
64 /* do_deref */ false);
65}
66
67llvm::Expected<lldb::ValueObjectSP>
69 if (!valobj)
70 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
71 location);
72 llvm::Expected<lldb::TypeSystemSP> type_system =
74 if (!type_system)
75 return type_system.takeError();
76
77 CompilerType in_type = valobj->GetCompilerType();
78 if (valobj->IsBitfield()) {
79 // Promote bitfields. If `int` can represent the bitfield value, it is
80 // converted to `int`. Otherwise, if `unsigned int` can represent it, it
81 // is converted to `unsigned int`. Otherwise, it is treated as its
82 // underlying type.
83 uint32_t bitfield_size = valobj->GetBitfieldBitSize();
84 // Some bitfields have undefined size (e.g. result of ternary operation).
85 // The AST's `bitfield_size` of those is 0, and no promotion takes place.
86 if (bitfield_size > 0 && in_type.IsInteger()) {
87 CompilerType int_type = GetBasicType(*type_system, lldb::eBasicTypeInt);
88 CompilerType uint_type =
90 llvm::Expected<uint64_t> int_bit_size =
91 int_type.GetBitSize(m_exe_ctx_scope.get());
92 if (!int_bit_size)
93 return int_bit_size.takeError();
94 llvm::Expected<uint64_t> uint_bit_size =
95 uint_type.GetBitSize(m_exe_ctx_scope.get());
96 if (!uint_bit_size)
97 return int_bit_size.takeError();
98 if (bitfield_size < *int_bit_size ||
99 (in_type.IsSigned() && bitfield_size == *int_bit_size))
100 return valobj->CastToBasicType(int_type);
101 if (bitfield_size <= *uint_bit_size)
102 return valobj->CastToBasicType(uint_type);
103 // Re-create as a const value with the same underlying type
104 Scalar scalar;
105 bool resolved = valobj->ResolveValue(scalar);
106 if (!resolved)
107 return llvm::createStringError("invalid scalar value");
109 "result");
110 }
111 }
112
113 if (in_type.IsArrayType())
114 valobj = ArrayToPointerConversion(*valobj, *m_exe_ctx_scope, "result");
115
116 if (valobj->GetCompilerType().IsInteger() ||
117 valobj->GetCompilerType().IsUnscopedEnumerationType()) {
118 llvm::Expected<CompilerType> promoted_type =
119 type_system.get()->DoIntegralPromotion(valobj->GetCompilerType(),
120 m_exe_ctx_scope.get());
121 if (!promoted_type)
122 return promoted_type.takeError();
123 if (!promoted_type->CompareTypes(valobj->GetCompilerType()))
124 return valobj->CastToBasicType(*promoted_type);
125 }
126
127 return valobj;
128}
129
130/// Basic types with a lower rank are converted to the basic type
131/// with a higher rank.
132static size_t ConversionRank(CompilerType type) {
133 switch (type.GetCanonicalType().GetBasicTypeEnumeration()) {
135 return 1;
139 return 2;
142 return 3;
145 return 4;
148 return 5;
151 return 6;
154 return 7;
156 return 8;
158 return 9;
160 return 10;
162 return 11;
163 default:
164 break;
165 }
166 return 0;
167}
168
188
189llvm::Expected<CompilerType>
191 CompilerType &rhs_type) {
192 assert(lhs_type.IsInteger() && rhs_type.IsInteger());
193 if (!lhs_type.IsSigned() && rhs_type.IsSigned()) {
194 llvm::Expected<uint64_t> lhs_size =
195 lhs_type.GetBitSize(m_exe_ctx_scope.get());
196 if (!lhs_size)
197 return lhs_size.takeError();
198 llvm::Expected<uint64_t> rhs_size =
199 rhs_type.GetBitSize(m_exe_ctx_scope.get());
200 if (!rhs_size)
201 return rhs_size.takeError();
202
203 if (*rhs_size == *lhs_size) {
204 llvm::Expected<lldb::TypeSystemSP> type_system =
206 if (!type_system)
207 return type_system.takeError();
208 CompilerType r_type_unsigned = GetBasicType(
209 *type_system,
212 return r_type_unsigned;
213 }
214 }
215 return rhs_type;
216}
217
218llvm::Expected<CompilerType>
220 lldb::ValueObjectSP &rhs, uint32_t location) {
221 // Apply unary conversion for both operands.
222 auto lhs_or_err = UnaryConversion(lhs, location);
223 if (!lhs_or_err)
224 return lhs_or_err.takeError();
225 lhs = *lhs_or_err;
226 auto rhs_or_err = UnaryConversion(rhs, location);
227 if (!rhs_or_err)
228 return rhs_or_err.takeError();
229 rhs = *rhs_or_err;
230
231 CompilerType lhs_type = lhs->GetCompilerType();
232 CompilerType rhs_type = rhs->GetCompilerType();
233
234 // If types already match, no need for further conversions.
235 if (lhs_type.CompareTypes(rhs_type))
236 return lhs_type;
237
238 // If either of the operands is not arithmetic (e.g. pointer), we're done.
239 if (!lhs_type.IsScalarType() || !rhs_type.IsScalarType())
240 return CompilerType();
241
242 size_t l_rank = ConversionRank(lhs_type);
243 size_t r_rank = ConversionRank(rhs_type);
244 if (l_rank == 0 || r_rank == 0)
245 return llvm::make_error<DILDiagnosticError>(
246 m_expr, "unexpected basic type in arithmetic operation", location);
247
248 // If both operands are integer, check if we need to promote
249 // the higher ranked signed type.
250 if (lhs_type.IsInteger() && rhs_type.IsInteger()) {
251 using Rank = std::tuple<size_t, bool>;
252 Rank int_l_rank = {l_rank, !lhs_type.IsSigned()};
253 Rank int_r_rank = {r_rank, !rhs_type.IsSigned()};
254 if (int_l_rank < int_r_rank) {
255 auto type_or_err = PromoteSignedInteger(lhs_type, rhs_type);
256 if (!type_or_err)
257 return type_or_err.takeError();
258 return *type_or_err;
259 }
260 if (int_l_rank > int_r_rank) {
261 auto type_or_err = PromoteSignedInteger(rhs_type, lhs_type);
262 if (!type_or_err)
263 return type_or_err.takeError();
264 return *type_or_err;
265 }
266 return lhs_type;
267 }
268
269 // Handle other combinations of integer and floating point operands.
270 if (l_rank < r_rank)
271 return rhs_type;
272 return lhs_type;
273}
274
276 VariableList &variable_list) {
277 lldb::VariableSP exact_match;
278 std::vector<lldb::VariableSP> possible_matches;
279
280 for (lldb::VariableSP var_sp : variable_list) {
281 llvm::StringRef str_ref_name = var_sp->GetName().GetStringRef();
282
283 str_ref_name.consume_front("::");
284 // Check for the exact same match
285 if (str_ref_name == name.GetStringRef())
286 return var_sp;
287
288 // Check for possible matches by base name
289 if (var_sp->NameMatches(name))
290 possible_matches.push_back(var_sp);
291 }
292
293 // If there's a non-exact match, take it.
294 if (possible_matches.size() > 0)
295 return possible_matches[0];
296
297 return nullptr;
298}
299
301 llvm::StringRef name_ref, std::shared_ptr<StackFrame> stack_frame,
302 lldb::TargetSP target_sp, lldb::DynamicValueType use_dynamic) {
303 // Get a global variables list without the locals from the current frame
304 SymbolContext symbol_context =
305 stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
306 lldb::VariableListSP variable_list;
307 if (symbol_context.comp_unit)
308 variable_list = symbol_context.comp_unit->GetVariableList(true);
309
310 name_ref.consume_front("::");
311 lldb::ValueObjectSP value_sp;
312 if (variable_list) {
313 lldb::VariableSP var_sp =
314 DILFindVariable(ConstString(name_ref), *variable_list);
315 if (var_sp)
316 value_sp =
317 stack_frame->GetValueObjectForFrameVariable(var_sp, use_dynamic);
318 }
319
320 if (value_sp)
321 return value_sp;
322
323 // Check for match in modules global variables.
324 VariableList modules_var_list;
325 target_sp->GetImages().FindGlobalVariables(
326 ConstString(name_ref), std::numeric_limits<uint32_t>::max(),
327 modules_var_list);
328
329 if (!modules_var_list.Empty()) {
330 lldb::VariableSP var_sp =
331 DILFindVariable(ConstString(name_ref), modules_var_list);
332 if (var_sp)
333 value_sp = ValueObjectVariable::Create(stack_frame.get(), var_sp);
334
335 if (value_sp)
336 return value_sp;
337 }
338 return nullptr;
339}
340
341lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
342 std::shared_ptr<StackFrame> stack_frame,
343 lldb::DynamicValueType use_dynamic) {
344 // Support $rax as a special syntax for accessing registers.
345 // Will return an invalid value in case the requested register doesn't exist.
346 if (name_ref.consume_front("$")) {
347 lldb::RegisterContextSP reg_ctx(stack_frame->GetRegisterContext());
348 if (!reg_ctx)
349 return nullptr;
350
351 if (const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name_ref))
352 return ValueObjectRegister::Create(stack_frame.get(), reg_ctx, reg_info);
353
354 return nullptr;
355 }
356
357 if (!name_ref.contains("::")) {
358 // Lookup in the current frame.
359 // Try looking for a local variable in current scope.
360 lldb::VariableListSP variable_list(
361 stack_frame->GetInScopeVariableList(false));
362
363 lldb::ValueObjectSP value_sp;
364 if (variable_list) {
365 lldb::VariableSP var_sp =
366 variable_list->FindVariable(ConstString(name_ref));
367 if (var_sp)
368 value_sp =
369 stack_frame->GetValueObjectForFrameVariable(var_sp, use_dynamic);
370 }
371
372 if (value_sp)
373 return value_sp;
374
375 // Try looking for an instance variable (class member).
376 SymbolContext sc = stack_frame->GetSymbolContext(
377 lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
378 llvm::StringRef ivar_name = sc.GetInstanceVariableName();
379 value_sp = stack_frame->FindVariable(ConstString(ivar_name));
380 if (value_sp)
381 value_sp = value_sp->GetChildMemberWithName(name_ref);
382
383 if (value_sp)
384 return value_sp;
385 }
386 return nullptr;
387}
388
389Interpreter::Interpreter(lldb::TargetSP target, llvm::StringRef expr,
390 std::shared_ptr<StackFrame> frame_sp,
391 lldb::DynamicValueType use_dynamic, bool use_synthetic,
392 bool fragile_ivar, bool check_ptr_vs_member)
393 : m_target(std::move(target)), m_expr(expr), m_exe_ctx_scope(frame_sp),
394 m_use_dynamic(use_dynamic), m_use_synthetic(use_synthetic),
395 m_fragile_ivar(fragile_ivar), m_check_ptr_vs_member(check_ptr_vs_member) {
396}
397
398llvm::Expected<lldb::ValueObjectSP> Interpreter::Evaluate(const ASTNode &node) {
399 // Evaluate an AST.
400 auto value_or_error = node.Accept(this);
401 // Convert SP with a nullptr to an error.
402 if (value_or_error && !*value_or_error)
403 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
404 node.GetLocation());
405 // Return the computed value-or-error. The caller is responsible for
406 // checking if an error occurred during the evaluation.
407 return value_or_error;
408}
409
410llvm::Expected<lldb::ValueObjectSP>
412 auto valobj_or_err = Evaluate(node);
413 if (!valobj_or_err)
414 return valobj_or_err;
415 lldb::ValueObjectSP valobj = *valobj_or_err;
416
418 if (valobj->GetCompilerType().IsReferenceType()) {
419 valobj = valobj->Dereference(error);
420 if (error.Fail())
421 return error.ToError();
422 }
423 return valobj;
424}
425
426llvm::Expected<lldb::ValueObjectSP>
429
430 lldb::ValueObjectSP identifier =
431 LookupIdentifier(node.GetName(), m_exe_ctx_scope, use_dynamic);
432
433 if (!identifier)
435 m_target, use_dynamic);
436 if (!identifier) {
437 std::string errMsg =
438 llvm::formatv("use of undeclared identifier '{0}'", node.GetName());
439 return llvm::make_error<DILDiagnosticError>(
440 m_expr, errMsg, node.GetLocation(), node.GetName().size());
441 }
442
443 return identifier;
444}
445
446llvm::Expected<lldb::ValueObjectSP>
449 auto op_or_err = Evaluate(node.GetOperand());
450 if (!op_or_err)
451 return op_or_err;
452
453 lldb::ValueObjectSP operand = *op_or_err;
454
455 switch (node.GetKind()) {
456 case UnaryOpKind::Deref: {
457 lldb::ValueObjectSP dynamic_op = operand->GetDynamicValue(m_use_dynamic);
458 if (dynamic_op)
459 operand = dynamic_op;
460
461 lldb::ValueObjectSP child_sp = operand->Dereference(error);
462 if (!child_sp && m_use_synthetic) {
463 if (lldb::ValueObjectSP synth_obj_sp = operand->GetSyntheticValue()) {
464 error.Clear();
465 child_sp = synth_obj_sp->Dereference(error);
466 }
467 }
468 if (error.Fail())
469 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
470 node.GetLocation());
471
472 return child_sp;
473 }
474 case UnaryOpKind::AddrOf: {
476 lldb::ValueObjectSP value = operand->AddressOf(error);
477 if (error.Fail())
478 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
479 node.GetLocation());
480
481 return value;
482 }
483 case UnaryOpKind::Minus: {
484 if (operand->GetCompilerType().IsReferenceType()) {
485 operand = operand->Dereference(error);
486 if (error.Fail())
487 return error.ToError();
488 }
489 llvm::Expected<lldb::ValueObjectSP> conv_op =
490 UnaryConversion(operand, node.GetOperand().GetLocation());
491 if (!conv_op)
492 return conv_op;
493 operand = *conv_op;
494 CompilerType operand_type = operand->GetCompilerType();
495 if (!operand_type.IsScalarType()) {
496 std::string errMsg =
497 llvm::formatv("invalid argument type '{0}' to unary expression",
498 operand_type.GetTypeName());
499 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
500 node.GetLocation());
501 }
502 Scalar scalar;
503 bool resolved = operand->ResolveValue(scalar);
504 if (!resolved)
505 break;
506
507 bool negated = scalar.UnaryNegate();
508 if (negated)
510 m_target, scalar, operand->GetCompilerType(), "result");
511 break;
512 }
513 case UnaryOpKind::Plus: {
514 if (operand->GetCompilerType().IsReferenceType()) {
515 operand = operand->Dereference(error);
516 if (error.Fail())
517 return error.ToError();
518 }
519 llvm::Expected<lldb::ValueObjectSP> conv_op =
520 UnaryConversion(operand, node.GetOperand().GetLocation());
521 if (!conv_op)
522 return conv_op;
523 operand = *conv_op;
524 CompilerType operand_type = operand->GetCompilerType();
525 if (!operand_type.IsScalarType() &&
526 // Unary plus is allowed for pointers.
527 !operand_type.IsPointerType()) {
528 std::string errMsg =
529 llvm::formatv("invalid argument type '{0}' to unary expression",
530 operand_type.GetTypeName());
531 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
532 node.GetLocation());
533 }
534 return operand;
535 }
536 }
537 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid unary operation",
538 node.GetLocation());
539}
540
541llvm::Expected<lldb::ValueObjectSP>
543 lldb::ValueObjectSP rhs, CompilerType result_type,
544 uint32_t location) {
545 Scalar l, r;
546 bool l_resolved = lhs->ResolveValue(l);
547 bool r_resolved = rhs->ResolveValue(r);
548
549 if (!l_resolved || !r_resolved)
550 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid scalar value",
551 location);
552
553 auto value_object = [this, result_type](Scalar scalar) {
555 result_type, "result");
556 };
557
558 switch (kind) {
560 return value_object(l + r);
562 return value_object(l - r);
563 }
564 return llvm::make_error<DILDiagnosticError>(
565 m_expr, "invalid arithmetic operation", location);
566}
567
568llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryAddition(
569 lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
570 // Operation '+' works for:
571 // {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
572 // TODO: Pointer arithmetics
573 auto orig_lhs_type = lhs->GetCompilerType();
574 auto orig_rhs_type = rhs->GetCompilerType();
575 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
576 if (!type_or_err)
577 return type_or_err.takeError();
578 CompilerType result_type = *type_or_err;
579
580 if (result_type.IsScalarType())
581 return EvaluateScalarOp(BinaryOpKind::Add, lhs, rhs, result_type, location);
582
583 std::string errMsg =
584 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
585 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
586 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
587 location);
588}
589
590llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinarySubtraction(
591 lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
592 // Operation '-' works for:
593 // {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
594 // TODO: Pointer arithmetics
595 auto orig_lhs_type = lhs->GetCompilerType();
596 auto orig_rhs_type = rhs->GetCompilerType();
597 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
598 if (!type_or_err)
599 return type_or_err.takeError();
600 CompilerType result_type = *type_or_err;
601
602 if (result_type.IsScalarType())
603 return EvaluateScalarOp(BinaryOpKind::Sub, lhs, rhs, result_type, location);
604
605 std::string errMsg =
606 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
607 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
608 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
609 location);
610}
611
612llvm::Expected<lldb::ValueObjectSP>
614 auto lhs_or_err = EvaluateAndDereference(node.GetLHS());
615 if (!lhs_or_err)
616 return lhs_or_err;
617 lldb::ValueObjectSP lhs = *lhs_or_err;
618 auto rhs_or_err = EvaluateAndDereference(node.GetRHS());
619 if (!rhs_or_err)
620 return rhs_or_err;
621 lldb::ValueObjectSP rhs = *rhs_or_err;
622
623 lldb::TypeSystemSP lhs_system =
624 lhs->GetCompilerType().GetTypeSystem().GetSharedPointer();
625 lldb::TypeSystemSP rhs_system =
626 rhs->GetCompilerType().GetTypeSystem().GetSharedPointer();
627 if (lhs_system->GetPluginName() != rhs_system->GetPluginName()) {
628 // TODO: Attempt to convert values to current CU's type system
629 return llvm::make_error<DILDiagnosticError>(
630 m_expr, "operands have different type systems", node.GetLocation());
631 }
632
633 switch (node.GetKind()) {
635 return EvaluateBinaryAddition(lhs, rhs, node.GetLocation());
637 return EvaluateBinarySubtraction(lhs, rhs, node.GetLocation());
638 }
639
640 return llvm::make_error<DILDiagnosticError>(
641 m_expr, "unimplemented binary operation", node.GetLocation());
642}
643
644llvm::Expected<lldb::ValueObjectSP>
646 auto base_or_err = Evaluate(node.GetBase());
647 if (!base_or_err)
648 return base_or_err;
649 bool expr_is_ptr = node.GetIsArrow();
650 lldb::ValueObjectSP base = *base_or_err;
651
652 // Perform some basic type & correctness checking.
653 if (node.GetIsArrow()) {
654 if (!m_fragile_ivar) {
655 // Make sure we aren't trying to deref an objective
656 // C ivar if this is not allowed
657 const uint32_t pointer_type_flags =
658 base->GetCompilerType().GetTypeInfo(nullptr);
659 if ((pointer_type_flags & lldb::eTypeIsObjC) &&
660 (pointer_type_flags & lldb::eTypeIsPointer)) {
661 // This was an objective C object pointer and it was requested we
662 // skip any fragile ivars so return nothing here
663 return lldb::ValueObjectSP();
664 }
665 }
666
667 // If we have a non-pointer type with a synthetic value then lets check
668 // if we have a synthetic dereference specified.
669 if (!base->IsPointerType() && base->HasSyntheticValue()) {
670 Status deref_error;
671 if (lldb::ValueObjectSP synth_deref_sp =
672 base->GetSyntheticValue()->Dereference(deref_error);
673 synth_deref_sp && deref_error.Success()) {
674 base = std::move(synth_deref_sp);
675 }
676 if (!base || deref_error.Fail()) {
677 std::string errMsg = llvm::formatv(
678 "Failed to dereference synthetic value: {0}", deref_error);
679 return llvm::make_error<DILDiagnosticError>(
680 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
681 }
682
683 // Some synthetic plug-ins fail to set the error in Dereference
684 if (!base) {
685 std::string errMsg = "Failed to dereference synthetic value";
686 return llvm::make_error<DILDiagnosticError>(
687 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
688 }
689 expr_is_ptr = false;
690 }
691 }
692
694 bool base_is_ptr = base->IsPointerType();
695
696 if (expr_is_ptr != base_is_ptr) {
697 if (base_is_ptr) {
698 std::string errMsg =
699 llvm::formatv("member reference type {0} is a pointer; "
700 "did you mean to use '->'?",
701 base->GetCompilerType().TypeDescription());
702 return llvm::make_error<DILDiagnosticError>(
703 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
704 } else {
705 std::string errMsg =
706 llvm::formatv("member reference type {0} is not a pointer; "
707 "did you mean to use '.'?",
708 base->GetCompilerType().TypeDescription());
709 return llvm::make_error<DILDiagnosticError>(
710 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
711 }
712 }
713 }
714
715 lldb::ValueObjectSP field_obj =
716 base->GetChildMemberWithName(node.GetFieldName());
717 if (!field_obj) {
718 if (m_use_synthetic) {
719 field_obj = base->GetSyntheticValue();
720 if (field_obj)
721 field_obj = field_obj->GetChildMemberWithName(node.GetFieldName());
722 }
723
724 if (!m_use_synthetic || !field_obj) {
725 std::string errMsg = llvm::formatv(
726 "\"{0}\" is not a member of \"({1}) {2}\"", node.GetFieldName(),
727 base->GetTypeName().AsCString("<invalid type>"), base->GetName());
728 return llvm::make_error<DILDiagnosticError>(
729 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
730 }
731 }
732
733 if (field_obj) {
735 lldb::ValueObjectSP dynamic_val_sp =
736 field_obj->GetDynamicValue(m_use_dynamic);
737 if (dynamic_val_sp)
738 field_obj = dynamic_val_sp;
739 }
740 return field_obj;
741 }
742
743 CompilerType base_type = base->GetCompilerType();
744 if (node.GetIsArrow() && base->IsPointerType())
745 base_type = base_type.GetPointeeType();
746 std::string errMsg = llvm::formatv(
747 "\"{0}\" is not a member of \"({1}) {2}\"", node.GetFieldName(),
748 base->GetTypeName().AsCString("<invalid type>"), base->GetName());
749 return llvm::make_error<DILDiagnosticError>(
750 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
751}
752
753llvm::Expected<lldb::ValueObjectSP>
755 auto idx_or_err = EvaluateAndDereference(node.GetIndex());
756 if (!idx_or_err)
757 return idx_or_err;
758 lldb::ValueObjectSP idx = *idx_or_err;
759
760 if (!idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType()) {
761 return llvm::make_error<DILDiagnosticError>(
762 m_expr, "array subscript is not an integer", node.GetLocation());
763 }
764
765 StreamString var_expr_path_strm;
766 uint64_t child_idx = idx->GetValueAsUnsigned(0);
767 lldb::ValueObjectSP child_valobj_sp;
768
769 auto base_or_err = Evaluate(node.GetBase());
770 if (!base_or_err)
771 return base_or_err;
772 lldb::ValueObjectSP base = *base_or_err;
773
774 CompilerType base_type = base->GetCompilerType().GetNonReferenceType();
775 base->GetExpressionPath(var_expr_path_strm);
776 bool is_incomplete_array = false;
777 if (base_type.IsPointerType()) {
778 bool is_objc_pointer = true;
779
780 if (base->GetCompilerType().GetMinimumLanguage() != lldb::eLanguageTypeObjC)
781 is_objc_pointer = false;
782 else if (!base->GetCompilerType().IsPointerType())
783 is_objc_pointer = false;
784
785 if (!m_use_synthetic && is_objc_pointer) {
786 std::string err_msg = llvm::formatv(
787 "\"({0}) {1}\" is an Objective-C pointer, and cannot be subscripted",
788 base->GetTypeName().AsCString("<invalid type>"),
789 var_expr_path_strm.GetData());
790 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
791 node.GetLocation());
792 }
793 if (is_objc_pointer) {
794 lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
795 if (!synthetic || synthetic == base) {
796 std::string err_msg =
797 llvm::formatv("\"({0}) {1}\" is not an array type",
798 base->GetTypeName().AsCString("<invalid type>"),
799 var_expr_path_strm.GetData());
800 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
801 node.GetLocation());
802 }
803 if (static_cast<uint32_t>(child_idx) >=
804 synthetic->GetNumChildrenIgnoringErrors()) {
805 std::string err_msg = llvm::formatv(
806 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
807 base->GetTypeName().AsCString("<invalid type>"),
808 var_expr_path_strm.GetData());
809 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
810 node.GetLocation());
811 }
812 child_valobj_sp = synthetic->GetChildAtIndex(child_idx);
813 if (!child_valobj_sp) {
814 std::string err_msg = llvm::formatv(
815 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
816 base->GetTypeName().AsCString("<invalid type>"),
817 var_expr_path_strm.GetData());
818 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
819 node.GetLocation());
820 }
822 if (auto dynamic_sp = child_valobj_sp->GetDynamicValue(m_use_dynamic))
823 child_valobj_sp = std::move(dynamic_sp);
824 }
825 return child_valobj_sp;
826 }
827
828 child_valobj_sp = base->GetSyntheticArrayMember(child_idx, true);
829 if (!child_valobj_sp) {
830 std::string err_msg = llvm::formatv(
831 "failed to use pointer as array for index {0} for "
832 "\"({1}) {2}\"",
833 child_idx, base->GetTypeName().AsCString("<invalid type>"),
834 var_expr_path_strm.GetData());
835 if (base_type.IsPointerToVoid())
836 err_msg = "subscript of pointer to incomplete type 'void'";
837 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
838 node.GetLocation());
839 }
840 } else if (base_type.IsArrayType(nullptr, nullptr, &is_incomplete_array)) {
841 child_valobj_sp = base->GetChildAtIndex(child_idx);
842 if (!child_valobj_sp && (is_incomplete_array || m_use_synthetic))
843 child_valobj_sp = base->GetSyntheticArrayMember(child_idx, true);
844 if (!child_valobj_sp) {
845 std::string err_msg = llvm::formatv(
846 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
847 base->GetTypeName().AsCString("<invalid type>"),
848 var_expr_path_strm.GetData());
849 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
850 node.GetLocation());
851 }
852 } else if (base_type.IsScalarType()) {
853 child_valobj_sp =
854 base->GetSyntheticBitFieldChild(child_idx, child_idx, true);
855 if (!child_valobj_sp) {
856 std::string err_msg = llvm::formatv(
857 "bitfield range {0}:{1} is not valid for \"({2}) {3}\"", child_idx,
858 child_idx, base->GetTypeName().AsCString("<invalid type>"),
859 var_expr_path_strm.GetData());
860 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
861 node.GetLocation(), 1);
862 }
863 } else {
864 lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
865 if (!m_use_synthetic || !synthetic || synthetic == base) {
866 std::string err_msg =
867 llvm::formatv("\"{0}\" is not an array type",
868 base->GetTypeName().AsCString("<invalid type>"));
869 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
870 node.GetLocation(), 1);
871 }
872 if (static_cast<uint32_t>(child_idx) >=
873 synthetic->GetNumChildrenIgnoringErrors(child_idx + 1)) {
874 std::string err_msg = llvm::formatv(
875 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
876 base->GetTypeName().AsCString("<invalid type>"),
877 var_expr_path_strm.GetData());
878 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
879 node.GetLocation(), 1);
880 }
881 child_valobj_sp = synthetic->GetChildAtIndex(child_idx);
882 if (!child_valobj_sp) {
883 std::string err_msg = llvm::formatv(
884 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
885 base->GetTypeName().AsCString("<invalid type>"),
886 var_expr_path_strm.GetData());
887 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
888 node.GetLocation(), 1);
889 }
890 }
891
892 if (child_valobj_sp) {
894 if (auto dynamic_sp = child_valobj_sp->GetDynamicValue(m_use_dynamic))
895 child_valobj_sp = std::move(dynamic_sp);
896 }
897 return child_valobj_sp;
898 }
899
900 bool success;
901 int64_t signed_child_idx = idx->GetValueAsSigned(0, &success);
902 if (!success)
903 return llvm::make_error<DILDiagnosticError>(
904 m_expr, "could not get the index as an integer",
905 node.GetIndex().GetLocation());
906 return base->GetSyntheticArrayMember(signed_child_idx, true);
907}
908
909llvm::Expected<lldb::ValueObjectSP>
911 auto first_idx_or_err = EvaluateAndDereference(node.GetFirstIndex());
912 if (!first_idx_or_err)
913 return first_idx_or_err;
914 lldb::ValueObjectSP first_idx = *first_idx_or_err;
915 auto last_idx_or_err = EvaluateAndDereference(node.GetLastIndex());
916 if (!last_idx_or_err)
917 return last_idx_or_err;
918 lldb::ValueObjectSP last_idx = *last_idx_or_err;
919
920 if (!first_idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType() ||
921 !last_idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType()) {
922 return llvm::make_error<DILDiagnosticError>(
923 m_expr, "bit index is not an integer", node.GetLocation());
924 }
925
926 bool success_first, success_last;
927 int64_t first_index = first_idx->GetValueAsSigned(0, &success_first);
928 int64_t last_index = last_idx->GetValueAsSigned(0, &success_last);
929 if (!success_first || !success_last)
930 return llvm::make_error<DILDiagnosticError>(
931 m_expr, "could not get the index as an integer", node.GetLocation());
932
933 // if the format given is [high-low], swap range
934 if (first_index > last_index)
935 std::swap(first_index, last_index);
936
937 auto base_or_err = EvaluateAndDereference(node.GetBase());
938 if (!base_or_err)
939 return base_or_err;
940 lldb::ValueObjectSP base = *base_or_err;
941 lldb::ValueObjectSP child_valobj_sp =
942 base->GetSyntheticBitFieldChild(first_index, last_index, true);
943 if (!child_valobj_sp) {
944 std::string message = llvm::formatv(
945 "bitfield range {0}:{1} is not valid for \"({2}) {3}\"", first_index,
946 last_index, base->GetTypeName().AsCString("<invalid type>"),
947 base->GetName().AsCString());
948 return llvm::make_error<DILDiagnosticError>(m_expr, message,
949 node.GetLocation());
950 }
951 return child_valobj_sp;
952}
953
954llvm::Expected<CompilerType>
956 std::shared_ptr<ExecutionContextScope> ctx,
957 const IntegerLiteralNode &literal) {
958 // Binary, Octal, Hexadecimal and literals with a U suffix are allowed to be
959 // an unsigned integer.
960 bool unsigned_is_allowed = literal.IsUnsigned() || literal.GetRadix() != 10;
961 llvm::APInt apint = literal.GetValue();
962
963 llvm::SmallVector<std::pair<lldb::BasicType, lldb::BasicType>, 3> candidates;
964 if (literal.GetTypeSuffix() <= IntegerTypeSuffix::None)
965 candidates.emplace_back(lldb::eBasicTypeInt,
966 unsigned_is_allowed ? lldb::eBasicTypeUnsignedInt
968 if (literal.GetTypeSuffix() <= IntegerTypeSuffix::Long)
969 candidates.emplace_back(lldb::eBasicTypeLong,
970 unsigned_is_allowed ? lldb::eBasicTypeUnsignedLong
972 candidates.emplace_back(lldb::eBasicTypeLongLong,
974 for (auto [signed_, unsigned_] : candidates) {
975 CompilerType signed_type = type_system->GetBasicTypeFromAST(signed_);
976 if (!signed_type)
977 continue;
978 llvm::Expected<uint64_t> size = signed_type.GetBitSize(ctx.get());
979 if (!size)
980 return size.takeError();
981 if (!literal.IsUnsigned() && apint.isIntN(*size - 1))
982 return signed_type;
983 if (unsigned_ != lldb::eBasicTypeInvalid && apint.isIntN(*size))
984 return type_system->GetBasicTypeFromAST(unsigned_);
985 }
986
987 return llvm::make_error<DILDiagnosticError>(
988 m_expr,
989 "integer literal is too large to be represented in any integer type",
990 literal.GetLocation());
991}
992
993llvm::Expected<lldb::ValueObjectSP>
995 llvm::Expected<lldb::TypeSystemSP> type_system =
997 if (!type_system)
998 return type_system.takeError();
999
1000 llvm::Expected<CompilerType> type =
1001 PickIntegerType(*type_system, m_exe_ctx_scope, node);
1002 if (!type)
1003 return type.takeError();
1004
1005 Scalar scalar = node.GetValue();
1006 // APInt from StringRef::getAsInteger comes with just enough bitwidth to
1007 // hold the value. This adjusts APInt bitwidth to match the compiler type.
1008 llvm::Expected<uint64_t> type_bitsize =
1009 type->GetBitSize(m_exe_ctx_scope.get());
1010 if (!type_bitsize)
1011 return type_bitsize.takeError();
1012 scalar.TruncOrExtendTo(*type_bitsize, false);
1014 "result");
1015}
1016
1017llvm::Expected<lldb::ValueObjectSP>
1019 llvm::Expected<lldb::TypeSystemSP> type_system =
1021 if (!type_system)
1022 return type_system.takeError();
1023
1024 bool isFloat =
1025 &node.GetValue().getSemantics() == &llvm::APFloat::IEEEsingle();
1026 lldb::BasicType basic_type =
1028 CompilerType type = GetBasicType(*type_system, basic_type);
1029
1030 if (!type)
1031 return llvm::make_error<DILDiagnosticError>(
1032 m_expr, "unable to create a const literal", node.GetLocation());
1033
1034 Scalar scalar = node.GetValue();
1036 "result");
1037}
1038
1039llvm::Expected<lldb::ValueObjectSP>
1041 bool value = node.GetValue();
1042 return ValueObject::CreateValueObjectFromBool(m_target, value, "result");
1043}
1044
1045llvm::Expected<CastKind>
1047 CompilerType target_type, int location) {
1048 if (source_type.IsPointerType() || source_type.IsNullPtrType()) {
1049 // Cast from pointer to float/double is not allowed.
1050 if (target_type.GetTypeInfo() & lldb::eTypeIsFloat) {
1051 std::string errMsg = llvm::formatv("Cast from {0} to {1} is not allowed",
1052 source_type.TypeDescription(),
1053 target_type.TypeDescription());
1054 return llvm::make_error<DILDiagnosticError>(
1055 m_expr, std::move(errMsg), location,
1056 source_type.TypeDescription().length());
1057 }
1058
1059 // Casting from pointer to bool is always valid.
1060 if (target_type.IsBoolean())
1061 return CastKind::eArithmetic;
1062
1063 // Otherwise check if the result type is at least as big as the pointer
1064 // size.
1065 uint64_t type_byte_size = 0;
1066 uint64_t rhs_type_byte_size = 0;
1067 if (auto temp = target_type.GetByteSize(m_exe_ctx_scope.get())) {
1068 type_byte_size = *temp;
1069 } else {
1070 std::string errMsg = llvm::formatv("unable to get byte size for type {0}",
1071 target_type.TypeDescription());
1072 return llvm::make_error<DILDiagnosticError>(
1073 m_expr, std::move(errMsg), location,
1074 target_type.TypeDescription().length());
1075 }
1076
1077 if (auto temp = source_type.GetByteSize(m_exe_ctx_scope.get())) {
1078 rhs_type_byte_size = *temp;
1079 } else {
1080 std::string errMsg = llvm::formatv("unable to get byte size for type {0}",
1081 source_type.TypeDescription());
1082 return llvm::make_error<DILDiagnosticError>(
1083 m_expr, std::move(errMsg), location,
1084 source_type.TypeDescription().length());
1085 }
1086
1087 if (type_byte_size < rhs_type_byte_size) {
1088 std::string errMsg = llvm::formatv(
1089 "cast from pointer to smaller type {0} loses information",
1090 target_type.TypeDescription());
1091 return llvm::make_error<DILDiagnosticError>(
1092 m_expr, std::move(errMsg), location,
1093 source_type.TypeDescription().length());
1094 }
1095 } else if (!source_type.IsScalarType() && !source_type.IsEnumerationType()) {
1096 // Otherwise accept only arithmetic types and enums.
1097 std::string errMsg = llvm::formatv("cannot convert {0} to {1}",
1098 source_type.TypeDescription(),
1099 target_type.TypeDescription());
1100
1101 return llvm::make_error<DILDiagnosticError>(
1102 m_expr, std::move(errMsg), location,
1103 source_type.TypeDescription().length());
1104 }
1105 return CastKind::eArithmetic;
1106}
1107
1108llvm::Expected<CastKind>
1110 CompilerType source_type, CompilerType target_type,
1111 int location) {
1112
1113 if (target_type.IsScalarType())
1114 return VerifyArithmeticCast(source_type, target_type, location);
1115
1116 if (target_type.IsEnumerationType()) {
1117 // Cast to enum type.
1118 if (!source_type.IsScalarType() && !source_type.IsEnumerationType()) {
1119 std::string errMsg = llvm::formatv("Cast from {0} to {1} is not allowed",
1120 source_type.TypeDescription(),
1121 target_type.TypeDescription());
1122
1123 return llvm::make_error<DILDiagnosticError>(
1124 m_expr, std::move(errMsg), location,
1125 source_type.TypeDescription().length());
1126 }
1128 }
1129
1130 if (target_type.IsPointerType()) {
1131 if (!source_type.IsInteger() && !source_type.IsEnumerationType() &&
1132 !source_type.IsArrayType() && !source_type.IsPointerType() &&
1133 !source_type.IsNullPtrType()) {
1134 std::string errMsg = llvm::formatv(
1135 "cannot cast from type {0} to pointer type {1}",
1136 source_type.TypeDescription(), target_type.TypeDescription());
1137
1138 return llvm::make_error<DILDiagnosticError>(
1139 m_expr, std::move(errMsg), location,
1140 source_type.TypeDescription().length());
1141 }
1142 return CastKind::ePointer;
1143 }
1144
1145 // Unsupported cast.
1146 std::string errMsg = llvm::formatv(
1147 "casting of {0} to {1} is not implemented yet",
1148 source_type.TypeDescription(), target_type.TypeDescription());
1149 return llvm::make_error<DILDiagnosticError>(
1150 m_expr, std::move(errMsg), location,
1151 source_type.TypeDescription().length());
1152}
1153
1154llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const CastNode &node) {
1155 auto operand_or_err = Evaluate(node.GetOperand());
1156
1157 if (!operand_or_err)
1158 return operand_or_err;
1159
1160 lldb::ValueObjectSP operand = *operand_or_err;
1161 CompilerType op_type = operand->GetCompilerType();
1162 CompilerType target_type = node.GetType();
1163
1164 if (op_type.IsReferenceType())
1165 op_type = op_type.GetNonReferenceType();
1166 if (target_type.IsScalarType() && op_type.IsArrayType()) {
1167 operand = ArrayToPointerConversion(*operand, *m_exe_ctx_scope,
1168 operand->GetName().GetStringRef());
1169 op_type = operand->GetCompilerType();
1170 }
1171 auto type_or_err =
1172 VerifyCastType(operand, op_type, target_type, node.GetLocation());
1173 if (!type_or_err)
1174 return type_or_err.takeError();
1175
1176 CastKind cast_kind = *type_or_err;
1177 if (operand->GetCompilerType().IsReferenceType()) {
1178 Status error;
1179 operand = operand->Dereference(error);
1180 if (error.Fail())
1181 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
1182 node.GetLocation());
1183 }
1184
1185 switch (cast_kind) {
1187 // FIXME: is this correct for float vector types?
1188 if (op_type.GetTypeInfo() & lldb::eTypeIsFloat || op_type.IsInteger() ||
1189 op_type.IsEnumerationType())
1190 return operand->CastToEnumType(target_type);
1191 break;
1192 }
1193 case CastKind::eArithmetic: {
1194 if (op_type.IsPointerType() || op_type.IsNullPtrType() ||
1195 op_type.IsScalarType() || op_type.IsEnumerationType())
1196 return operand->CastToBasicType(target_type);
1197 break;
1198 }
1199 case CastKind::ePointer: {
1200 uint64_t addr = op_type.IsArrayType()
1201 ? operand->GetLoadAddress()
1202 : (op_type.IsSigned() ? operand->GetValueAsSigned(0)
1203 : operand->GetValueAsUnsigned(0));
1204 llvm::StringRef name = "result";
1205 ExecutionContext exe_ctx(m_target.get(), false);
1206 return ValueObject::CreateValueObjectFromAddress(name, addr, exe_ctx,
1207 target_type,
1208 /* do_deref */ false);
1209 }
1210 case CastKind::eNone: {
1211 return lldb::ValueObjectSP();
1212 }
1213 } // switch
1214
1215 std::string errMsg =
1216 llvm::formatv("unable to cast from '{0}' to '{1}'",
1217 op_type.TypeDescription(), target_type.TypeDescription());
1218 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
1219 node.GetLocation());
1220}
1221
1222} // 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.
Generic representation of a type in a programming language.
bool IsEnumerationType(bool &is_signed) const
lldb::BasicType GetBasicTypeEnumeration() 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...
uint32_t GetTypeInfo(CompilerType *pointee_or_element_compiler_type=nullptr) const
bool CompareTypes(CompilerType rhs) const
llvm::Expected< uint64_t > GetBitSize(ExecutionContextScope *exe_scope) const
Return the size of the type in bits.
CompilerType GetCanonicalType() const
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:293
bool Success() const
Test for success condition.
Definition Status.cpp:303
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.
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.
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.
CompilerType GetCompilerType()
The rest of the classes in this file, except for the Visitor class at the very end,...
Definition DILAST.h:74
uint32_t GetLocation() const
Definition DILAST.h:82
virtual llvm::Expected< lldb::ValueObjectSP > Accept(Visitor *v) const =0
ASTNode & GetLHS() const
Definition DILAST.h:172
BinaryOpKind GetKind() const
Definition DILAST.h:171
ASTNode & GetRHS() const
Definition DILAST.h:173
ASTNode & GetOperand() const
Definition DILAST.h:302
CompilerType GetType() const
Definition DILAST.h:301
const llvm::APFloat & GetValue() const
Definition DILAST.h:265
std::string GetName() const
Definition DILAST.h:109
IntegerTypeSuffix GetTypeSuffix() const
Definition DILAST.h:244
const llvm::APInt & GetValue() const
Definition DILAST.h:241
std::shared_ptr< StackFrame > m_exe_ctx_scope
Definition DILEval.h:128
llvm::Expected< lldb::ValueObjectSP > Evaluate(const ASTNode &node)
Evaluate an ASTNode.
Definition DILEval.cpp:398
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryAddition(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:568
llvm::Expected< lldb::ValueObjectSP > EvaluateAndDereference(const ASTNode &node)
Evaluate an ASTNode.
Definition DILEval.cpp:411
llvm::Expected< lldb::ValueObjectSP > EvaluateScalarOp(BinaryOpKind kind, lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, CompilerType result_type, uint32_t location)
Definition DILEval.cpp:542
llvm::Expected< CompilerType > PromoteSignedInteger(CompilerType &lhs_type, CompilerType &rhs_type)
If lhs_type is unsigned and rhs_type is signed, check whether it can represent all of the values of l...
Definition DILEval.cpp:190
llvm::Expected< lldb::ValueObjectSP > EvaluateBinarySubtraction(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:590
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:389
llvm::Expected< lldb::ValueObjectSP > UnaryConversion(lldb::ValueObjectSP valobj, uint32_t location)
Perform usual unary conversions on a value.
Definition DILEval.cpp:68
llvm::Expected< lldb::ValueObjectSP > Visit(const IdentifierNode &node) override
Definition DILEval.cpp:427
llvm::Expected< CompilerType > PickIntegerType(lldb::TypeSystemSP type_system, std::shared_ptr< ExecutionContextScope > ctx, const IntegerLiteralNode &literal)
Definition DILEval.cpp:955
lldb::DynamicValueType m_use_dynamic
Definition DILEval.h:129
llvm::Expected< CompilerType > ArithmeticConversion(lldb::ValueObjectSP &lhs, lldb::ValueObjectSP &rhs, uint32_t location)
Perform an arithmetic conversion on two values from an arithmetic operation.
Definition DILEval.cpp:219
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:1109
llvm::Expected< CastKind > VerifyArithmeticCast(CompilerType source_type, CompilerType target_type, int location)
A helper function for VerifyCastType (below).
Definition DILEval.cpp:1046
llvm::StringRef GetFieldName() const
Definition DILAST.h:130
ASTNode & GetBase() const
Definition DILAST.h:128
UnaryOpKind GetKind() const
Definition DILAST.h:150
ASTNode & GetOperand() const
Definition DILAST.h:151
CastKind
The type casts allowed by DIL.
Definition DILAST.h:53
@ eEnumeration
Casting from a scalar to an enumeration type.
Definition DILAST.h:55
@ ePointer
Casting to a pointer type.
Definition DILAST.h:56
@ eNone
Invalid promotion type (results in error).
Definition DILAST.h:57
@ eArithmetic
Casting to a scalar.
Definition DILAST.h:54
static lldb::BasicType BasicTypeToUnsigned(lldb::BasicType basic_type)
Definition DILEval.cpp:169
llvm::Expected< lldb::TypeSystemSP > GetTypeSystemFromCU(std::shared_ptr< StackFrame > ctx)
Definition DILParser.cpp:49
lldb::ValueObjectSP GetDynamicOrSyntheticValue(lldb::ValueObjectSP value_sp, lldb::DynamicValueType use_dynamic, bool use_synthetic)
Definition DILEval.cpp:26
static CompilerType GetBasicType(lldb::TypeSystemSP type_system, lldb::BasicType basic_type)
Definition DILEval.cpp:47
static lldb::ValueObjectSP ArrayToPointerConversion(ValueObject &valobj, ExecutionContextScope &ctx, llvm::StringRef name)
Definition DILEval.cpp:55
BinaryOpKind
The binary operators recognized by DIL.
Definition DILAST.h:44
static size_t ConversionRank(CompilerType type)
Basic types with a lower rank are converted to the basic type with a higher rank.
Definition DILEval.cpp:132
static lldb::VariableSP DILFindVariable(ConstString name, VariableList &variable_list)
Definition DILEval.cpp:275
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:300
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:341
std::shared_ptr< lldb_private::TypeSystem > TypeSystemSP
BasicType
Basic types enumeration for the public API SBType::GetBasicType().
@ eBasicTypeUnsignedShort
@ eBasicTypeSignedChar
@ eBasicTypeUnsignedInt128
@ eBasicTypeUnsignedLong
@ eBasicTypeUnsignedChar
@ eBasicTypeUnsignedLongLong
@ eBasicTypeLongDouble
@ eBasicTypeUnsignedInt
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
@ 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),...