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"
21#include "llvm/Support/ErrorExtras.h"
22#include "llvm/Support/FormatAdapters.h"
23#include <memory>
24
25namespace lldb_private::dil {
26
28 lldb::BasicType basic_type) {
29 if (type_system)
30 return type_system.get()->GetBasicTypeFromAST(basic_type);
31
32 return CompilerType();
33}
34
37 llvm::StringRef name) {
38 uint64_t addr = valobj.GetLoadAddress();
39 ExecutionContext exe_ctx;
40 ctx.CalculateExecutionContext(exe_ctx);
42 name, addr, exe_ctx,
44 /* do_deref */ false);
45}
46
47static llvm::Expected<lldb::TypeSystemSP> GetTypeSystemFromCU(StackFrame &ctx) {
48 SymbolContext symbol_context =
49 ctx.GetSymbolContext(lldb::eSymbolContextCompUnit);
50 if (!symbol_context.comp_unit)
51 return llvm::createStringErrorV("no compile unit for frame: {}",
52 ctx.GetFunctionName());
53
54 lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
55 symbol_context = ctx.GetSymbolContext(lldb::eSymbolContextModule);
56 return symbol_context.module_sp->GetTypeSystemForLanguage(language);
57}
58
59llvm::Expected<lldb::ValueObjectSP>
61 if (!valobj)
62 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
63 location);
64 llvm::Expected<lldb::TypeSystemSP> type_system =
66 if (!type_system)
67 return type_system.takeError();
68
69 CompilerType in_type = valobj->GetCompilerType();
70 if (valobj->IsBitfield()) {
71 // Promote bitfields. If `int` can represent the bitfield value, it is
72 // converted to `int`. Otherwise, if `unsigned int` can represent it, it
73 // is converted to `unsigned int`. Otherwise, it is treated as its
74 // underlying type.
75 uint32_t bitfield_size = valobj->GetBitfieldBitSize();
76 // Some bitfields have undefined size (e.g. result of ternary operation).
77 // The AST's `bitfield_size` of those is 0, and no promotion takes place.
78 if (bitfield_size > 0 && in_type.IsInteger()) {
79 CompilerType int_type = GetBasicType(*type_system, lldb::eBasicTypeInt);
80 CompilerType uint_type =
82 llvm::Expected<uint64_t> int_bit_size =
83 int_type.GetBitSize(&m_stack_frame);
84 if (!int_bit_size)
85 return int_bit_size.takeError();
86 llvm::Expected<uint64_t> uint_bit_size =
87 uint_type.GetBitSize(&m_stack_frame);
88 if (!uint_bit_size)
89 return uint_bit_size.takeError();
90 if (bitfield_size < *int_bit_size ||
91 (in_type.IsSigned() && bitfield_size == *int_bit_size))
92 return valobj->CastToBasicType(int_type);
93 if (bitfield_size <= *uint_bit_size)
94 return valobj->CastToBasicType(uint_type);
95 // Re-create as a const value with the same underlying type
96 Scalar scalar;
97 bool resolved = valobj->ResolveValue(scalar);
98 if (!resolved)
99 return llvm::createStringError("invalid scalar value");
101 in_type, "result");
102 }
103 }
104
105 if (in_type.IsArrayType())
106 valobj = ArrayToPointerConversion(*valobj, m_stack_frame, "result");
107
108 CompilerType promoted_type =
109 valobj->GetCompilerType().GetPromotedIntegerType();
110 if (promoted_type)
111 return valobj->CastToBasicType(promoted_type);
112
113 return valobj;
114}
115
116/// Basic types with a lower rank are converted to the basic type
117/// with a higher rank.
118static size_t ConversionRank(CompilerType type) {
119 switch (type.GetCanonicalType().GetBasicTypeEnumeration()) {
121 return 1;
125 return 2;
128 return 3;
131 return 4;
134 return 5;
137 return 6;
140 return 7;
142 return 8;
144 return 9;
146 return 10;
148 return 11;
149 default:
150 break;
151 }
152 return 0;
153}
154
174
175llvm::Expected<CompilerType>
177 CompilerType &rhs_type) {
178 assert(lhs_type.IsInteger() && rhs_type.IsInteger());
179 if (!lhs_type.IsSigned() && rhs_type.IsSigned()) {
180 llvm::Expected<uint64_t> lhs_size = lhs_type.GetBitSize(&m_stack_frame);
181 if (!lhs_size)
182 return lhs_size.takeError();
183 llvm::Expected<uint64_t> rhs_size = rhs_type.GetBitSize(&m_stack_frame);
184 if (!rhs_size)
185 return rhs_size.takeError();
186
187 if (*rhs_size == *lhs_size) {
188 llvm::Expected<lldb::TypeSystemSP> type_system =
190 if (!type_system)
191 return type_system.takeError();
192 CompilerType r_type_unsigned = GetBasicType(
193 *type_system,
196 return r_type_unsigned;
197 }
198 }
199 return rhs_type;
200}
201
202llvm::Expected<CompilerType>
204 lldb::ValueObjectSP &rhs, uint32_t location) {
205 // Apply unary conversion for both operands.
206 auto lhs_or_err = UnaryConversion(lhs, location);
207 if (!lhs_or_err)
208 return lhs_or_err.takeError();
209 lhs = *lhs_or_err;
210 auto rhs_or_err = UnaryConversion(rhs, location);
211 if (!rhs_or_err)
212 return rhs_or_err.takeError();
213 rhs = *rhs_or_err;
214
215 CompilerType lhs_type = lhs->GetCompilerType();
216 CompilerType rhs_type = rhs->GetCompilerType();
217
218 // If types already match, no need for further conversions.
219 if (lhs_type.CompareTypes(rhs_type))
220 return lhs_type;
221
222 // If either of the operands is not arithmetic (e.g. pointer), we're done.
223 if (!lhs_type.IsScalarType() || !rhs_type.IsScalarType())
224 return CompilerType();
225
226 size_t l_rank = ConversionRank(lhs_type);
227 size_t r_rank = ConversionRank(rhs_type);
228 if (l_rank == 0 || r_rank == 0)
229 return llvm::make_error<DILDiagnosticError>(
230 m_expr, "unexpected basic type in arithmetic operation", location);
231
232 // If both operands are integer, check if we need to promote
233 // the higher ranked signed type.
234 if (lhs_type.IsInteger() && rhs_type.IsInteger()) {
235 using Rank = std::tuple<size_t, bool>;
236 Rank int_l_rank = {l_rank, !lhs_type.IsSigned()};
237 Rank int_r_rank = {r_rank, !rhs_type.IsSigned()};
238 if (int_l_rank < int_r_rank) {
239 auto type_or_err = PromoteSignedInteger(lhs_type, rhs_type);
240 if (!type_or_err)
241 return type_or_err.takeError();
242 return *type_or_err;
243 }
244 if (int_l_rank > int_r_rank) {
245 auto type_or_err = PromoteSignedInteger(rhs_type, lhs_type);
246 if (!type_or_err)
247 return type_or_err.takeError();
248 return *type_or_err;
249 }
250 return lhs_type;
251 }
252
253 // Handle other combinations of integer and floating point operands.
254 if (l_rank < r_rank)
255 return rhs_type;
256 return lhs_type;
257}
258
260 VariableList &variable_list) {
261 lldb::VariableSP exact_match;
262 std::vector<lldb::VariableSP> possible_matches;
263
264 for (lldb::VariableSP var_sp : variable_list) {
265 llvm::StringRef str_ref_name = var_sp->GetName().GetStringRef();
266
267 str_ref_name.consume_front("::");
268 // Check for the exact same match
269 if (str_ref_name == name.GetStringRef())
270 return var_sp;
271
272 // Check for possible matches by base name
273 if (var_sp->NameMatches(name))
274 possible_matches.push_back(var_sp);
275 }
276
277 // If there's a non-exact match, take it.
278 if (possible_matches.size() > 0)
279 return possible_matches[0];
280
281 return nullptr;
282}
283
285 StackFrame &stack_frame,
286 lldb::TargetSP target_sp,
287 lldb::DynamicValueType use_dynamic) {
288 // Get a global variables list without the locals from the current frame
289 SymbolContext symbol_context =
290 stack_frame.GetSymbolContext(lldb::eSymbolContextCompUnit);
291 lldb::VariableListSP variable_list;
292 if (symbol_context.comp_unit)
293 variable_list = symbol_context.comp_unit->GetVariableList(true);
294
295 name_ref.consume_front("::");
296 lldb::ValueObjectSP value_sp;
297 if (variable_list) {
298 lldb::VariableSP var_sp =
299 DILFindVariable(ConstString(name_ref), *variable_list);
300 if (var_sp)
301 value_sp =
302 stack_frame.GetValueObjectForFrameVariable(var_sp, use_dynamic);
303 }
304
305 if (value_sp)
306 return value_sp;
307
308 // Check for match in modules global variables.
309 VariableList modules_var_list;
310 target_sp->GetImages().FindGlobalVariables(
311 ConstString(name_ref), std::numeric_limits<uint32_t>::max(),
312 modules_var_list);
313
314 if (!modules_var_list.Empty()) {
315 lldb::VariableSP var_sp =
316 DILFindVariable(ConstString(name_ref), modules_var_list);
317 if (var_sp)
318 value_sp = ValueObjectVariable::Create(&stack_frame, var_sp);
319
320 if (value_sp)
321 return value_sp;
322 }
323 return nullptr;
324}
325
326lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
327 StackFrame &stack_frame,
328 lldb::DynamicValueType use_dynamic) {
329 // Support $rax as a special syntax for accessing registers.
330 // Will return an invalid value in case the requested register doesn't exist.
331 if (name_ref.consume_front("$")) {
332 lldb::RegisterContextSP reg_ctx(stack_frame.GetRegisterContext());
333 if (!reg_ctx)
334 return nullptr;
335
336 if (const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name_ref))
337 return ValueObjectRegister::Create(&stack_frame, reg_ctx, reg_info);
338
339 return nullptr;
340 }
341
342 if (!name_ref.contains("::")) {
343 // Lookup in the current frame.
344 // Try looking for a local variable in current scope.
345 lldb::VariableListSP variable_list(
346 stack_frame.GetInScopeVariableList(false));
347
348 lldb::ValueObjectSP value_sp;
349 if (variable_list) {
350 lldb::VariableSP var_sp =
351 variable_list->FindVariable(ConstString(name_ref));
352 if (var_sp)
353 value_sp =
354 stack_frame.GetValueObjectForFrameVariable(var_sp, use_dynamic);
355 }
356
357 if (value_sp)
358 return value_sp;
359
360 // Try looking for an instance variable (class member).
361 SymbolContext sc = stack_frame.GetSymbolContext(
362 lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
363 llvm::StringRef instance_name = sc.GetInstanceName();
364 value_sp = stack_frame.FindVariable(ConstString(instance_name));
365 if (value_sp)
366 value_sp = value_sp->GetChildMemberWithName(name_ref);
367
368 if (value_sp)
369 return value_sp;
370 }
371 return nullptr;
372}
373
374lldb::ValueObjectSP LookupEnumValue(llvm::StringRef name_ref,
375 ExecutionContextScope &ctx_scope) {
376 if (name_ref.contains("::")) {
377 llvm::StringRef enum_typename, enumerator_name;
378 // FIXME: Change this to a structured binding for lambda capturing
379 // once we have C++20.
380 std::tie(enum_typename, enumerator_name) = name_ref.rsplit("::");
381 CompilerType enum_type = ResolveTypeByName(enum_typename.str(), ctx_scope);
382 lldb::ValueObjectSP result;
383 enum_type.ForEachEnumerator([&](const CompilerType &integer_type,
384 ConstString name,
385 const llvm::APSInt &value) -> bool {
386 if (name == enumerator_name) {
387 Scalar scalar(value);
388 result = ValueObject::CreateValueObjectFromScalar(ctx_scope, scalar,
389 enum_type, "result");
390 return false; // Stop iterating
391 }
392 return true;
393 });
394 return result;
395 }
396 return nullptr;
397}
398
399Interpreter::Interpreter(lldb::TargetSP target, llvm::StringRef expr,
400 StackFrame &stack_frame,
401 lldb::DynamicValueType use_dynamic, uint32_t options)
402 : m_target(std::move(target)), m_expr(expr), m_stack_frame(stack_frame),
403 m_use_dynamic(use_dynamic) {
404
405 const bool check_ptr_vs_member =
407 const bool no_synth_child =
409 const bool allow_var_updates =
411 const bool disallow_globals =
413
414 m_use_synthetic = !no_synth_child;
415 m_check_ptr_vs_member = check_ptr_vs_member;
416 m_allow_var_updates = allow_var_updates;
417 m_allow_globals = !disallow_globals;
418}
419
420llvm::Expected<lldb::ValueObjectSP> Interpreter::Evaluate(const ASTNode &node) {
421 // Evaluate an AST.
422 auto value_or_error = node.Accept(this);
423 // Convert SP with a nullptr to an error.
424 if (value_or_error && !*value_or_error)
425 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
426 node.GetLocation());
427 // Return the computed value-or-error. The caller is responsible for
428 // checking if an error occurred during the evaluation.
429 return value_or_error;
430}
431
432llvm::Expected<lldb::ValueObjectSP>
434 auto valobj_or_err = Evaluate(node);
435 if (!valobj_or_err)
436 return valobj_or_err;
437 lldb::ValueObjectSP valobj = *valobj_or_err;
438
440 if (valobj->GetCompilerType().IsReferenceType()) {
441 valobj = valobj->Dereference(error);
442 if (error.Fail())
443 return error.ToError();
444 }
445 return valobj;
446}
447
448llvm::Expected<lldb::ValueObjectSP>
451
452 lldb::ValueObjectSP identifier =
453 LookupIdentifier(node.GetName(), m_stack_frame, use_dynamic);
454
455 if (!identifier && m_allow_globals)
457 use_dynamic);
458
459 if (!identifier)
460 identifier = LookupEnumValue(node.GetName(), m_stack_frame);
461
462 if (!identifier && node.GetName() == "nullptr") {
463 // If we got a "nullptr" identifier, and there is no defined variable with
464 // this name, resolve it as a null pointer.
465 llvm::Expected<lldb::TypeSystemSP> type_system =
467 if (!type_system)
468 return type_system.takeError();
469 type_system.get()->GetPointerByteSize();
470 llvm::APInt value(type_system.get()->GetPointerByteSize() * CHAR_BIT, 0);
471 Scalar scalar(value);
474 "result");
475 }
476
477 if (!identifier) {
478 std::string errMsg =
479 llvm::formatv("use of undeclared identifier '{0}'", node.GetName());
480 return llvm::make_error<DILDiagnosticError>(
481 m_expr, errMsg, node.GetLocation(), node.GetName().size());
482 }
483
484 return identifier;
485}
486
487llvm::Expected<lldb::ValueObjectSP>
490 auto op_or_err = Evaluate(node.GetOperand());
491 if (!op_or_err)
492 return op_or_err;
493
494 lldb::ValueObjectSP operand = *op_or_err;
495
496 switch (node.GetKind()) {
497 case UnaryOpKind::Deref: {
498 lldb::ValueObjectSP dynamic_op = operand->GetDynamicValue(m_use_dynamic);
499 if (dynamic_op)
500 operand = dynamic_op;
501
502 lldb::ValueObjectSP child_sp = operand->Dereference(error);
503 if (!child_sp && m_use_synthetic) {
504 if (lldb::ValueObjectSP synth_obj_sp = operand->GetSyntheticValue()) {
505 error.Clear();
506 child_sp = synth_obj_sp->Dereference(error);
507 }
508 }
509 if (error.Fail())
510 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
511 node.GetLocation());
512
513 return child_sp;
514 }
515 case UnaryOpKind::AddrOf: {
517 lldb::ValueObjectSP value = operand->AddressOf(error);
518 if (error.Fail())
519 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
520 node.GetLocation());
521
522 return value;
523 }
524 case UnaryOpKind::Minus: {
525 if (operand->GetCompilerType().IsReferenceType()) {
526 operand = operand->Dereference(error);
527 if (error.Fail())
528 return error.ToError();
529 }
530 llvm::Expected<lldb::ValueObjectSP> conv_op =
531 UnaryConversion(operand, node.GetOperand().GetLocation());
532 if (!conv_op)
533 return conv_op;
534 operand = *conv_op;
535 CompilerType operand_type = operand->GetCompilerType();
536 if (!operand_type.IsScalarType()) {
537 std::string errMsg =
538 llvm::formatv("invalid argument type '{0}' to unary expression",
539 operand_type.GetTypeName());
540 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
541 node.GetLocation());
542 }
543 Scalar scalar;
544 bool resolved = operand->ResolveValue(scalar);
545 if (!resolved)
546 break;
547
548 bool negated = scalar.UnaryNegate();
549 if (negated)
551 m_stack_frame, scalar, operand->GetCompilerType(), "result");
552 break;
553 }
554 case UnaryOpKind::Plus: {
555 if (operand->GetCompilerType().IsReferenceType()) {
556 operand = operand->Dereference(error);
557 if (error.Fail())
558 return error.ToError();
559 }
560 llvm::Expected<lldb::ValueObjectSP> conv_op =
561 UnaryConversion(operand, node.GetOperand().GetLocation());
562 if (!conv_op)
563 return conv_op;
564 operand = *conv_op;
565 CompilerType operand_type = operand->GetCompilerType();
566 if (!operand_type.IsScalarType() &&
567 // Unary plus is allowed for pointers.
568 !operand_type.IsPointerType()) {
569 std::string errMsg =
570 llvm::formatv("invalid argument type '{0}' to unary expression",
571 operand_type.GetTypeName());
572 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
573 node.GetLocation());
574 }
575 return operand;
576 }
577 case UnaryOpKind::Not: {
578 if (operand->GetCompilerType().IsReferenceType()) {
579 operand = operand->Dereference(error);
580 if (error.Fail())
581 return error.ToError();
582 }
583 llvm::Expected<lldb::ValueObjectSP> conv_op =
584 UnaryConversion(operand, node.GetLocation());
585 if (!conv_op)
586 return conv_op;
587 operand = *conv_op;
588 CompilerType operand_type = operand->GetCompilerType();
589 if (!operand_type.IsInteger()) {
590 std::string errMsg =
591 llvm::formatv("invalid argument type '{0}' to unary expression",
592 operand_type.GetTypeName());
593 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
594 node.GetLocation());
595 }
596 Scalar scalar;
597 bool resolved = operand->ResolveValue(scalar);
598 if (!resolved) {
599 std::string errMsg = llvm::formatv("invalid operand value: {0}",
600 operand->GetError().AsCString());
601 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
602 node.GetLocation());
603 }
604
605 bool flipped = scalar.OnesComplement();
606 if (flipped)
608 m_stack_frame, scalar, operand->GetCompilerType(), "result");
609 }
610 }
611 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid unary operation",
612 node.GetLocation());
613}
614
615llvm::Expected<lldb::ValueObjectSP>
617 BinaryOpKind operation, uint32_t location) {
618 assert(operation == BinaryOpKind::Add || operation == BinaryOpKind::Sub);
619 if (ptr->GetCompilerType().IsPointerToVoid())
620 return llvm::make_error<DILDiagnosticError>(
621 m_expr, "arithmetic on a pointer to void", location);
622 if (ptr->GetValueAsUnsigned(0) == 0 && offset != 0)
623 return llvm::make_error<DILDiagnosticError>(
624 m_expr, "arithmetic on a nullptr is undefined", location);
625
626 bool success;
627 int64_t offset_int = offset->GetValueAsSigned(0, &success);
628 if (!success) {
629 std::string errMsg = llvm::formatv("could not get the offset: {0}",
630 offset->GetError().AsCString());
631 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
632 location);
633 }
634
635 llvm::Expected<uint64_t> byte_size =
636 ptr->GetCompilerType().GetPointeeType().GetByteSize(&m_stack_frame);
637 if (!byte_size)
638 return byte_size.takeError();
639 uint64_t ptr_addr = ptr->GetValueAsUnsigned(0);
640 if (operation == BinaryOpKind::Sub)
641 ptr_addr -= offset_int * (*byte_size);
642 else
643 ptr_addr += offset_int * (*byte_size);
644
645 ExecutionContext exe_ctx(m_target.get(), false);
646 Scalar scalar(ptr_addr);
648 m_stack_frame, scalar, ptr->GetCompilerType(), "result");
649}
650
651llvm::Expected<lldb::ValueObjectSP>
653 lldb::ValueObjectSP rhs, CompilerType result_type,
654 uint32_t location) {
655 Scalar l, r;
656 bool l_resolved = lhs->ResolveValue(l);
657 if (!l_resolved) {
658 std::string errMsg =
659 llvm::formatv("invalid lhs value: {0}", lhs->GetError().AsCString());
660 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
661 }
662 bool r_resolved = rhs->ResolveValue(r);
663 if (!r_resolved) {
664 std::string errMsg =
665 llvm::formatv("invalid rhs value: {0}", rhs->GetError().AsCString());
666 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
667 }
668
669 auto value_object = [this, result_type](Scalar scalar) {
671 result_type, "result");
672 };
673
674 switch (kind) {
676 return value_object(l + r);
678 return value_object(l - r);
680 return value_object(l * r);
682 return value_object(l / r);
684 return value_object(l % r);
686 return value_object(l & r);
688 return value_object(l ^ r);
689 case BinaryOpKind::Or:
690 return value_object(l | r);
692 return value_object(l << r);
694 return value_object(l >> r);
695 default:
696 break;
697 }
698 return llvm::make_error<DILDiagnosticError>(
699 m_expr, "invalid arithmetic operation", location);
700}
701
702llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryAddition(
703 lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
704 // Operation '+' works for:
705 // {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
706 // {integer,unscoped_enum} <-> pointer
707 // pointer <-> {integer,unscoped_enum}
708 auto orig_lhs_type = lhs->GetCompilerType();
709 auto orig_rhs_type = rhs->GetCompilerType();
710 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
711 if (!type_or_err)
712 return type_or_err.takeError();
713 CompilerType result_type = *type_or_err;
714
715 if (result_type.IsScalarType())
716 return EvaluateScalarOp(BinaryOpKind::Add, lhs, rhs, result_type, location);
717
718 // Check for pointer arithmetics.
719 // One of the operands must be a pointer and the other one an integer.
720 lldb::ValueObjectSP ptr, offset;
721 if (lhs->GetCompilerType().IsPointerType()) {
722 ptr = lhs;
723 offset = rhs;
724 } else if (rhs->GetCompilerType().IsPointerType()) {
725 ptr = rhs;
726 offset = lhs;
727 }
728
729 if (!ptr || !offset->GetCompilerType().IsInteger()) {
730 std::string errMsg =
731 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
732 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
733 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
734 location);
735 }
736
737 return PointerOffset(ptr, offset, BinaryOpKind::Add, location);
738}
739
740llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinarySubtraction(
741 lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
742 // Operation '-' works for:
743 // {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
744 // pointer <-> {integer,unscoped_enum}
745 // pointer <-> pointer (if pointee types are compatible)
746 auto orig_lhs_type = lhs->GetCompilerType();
747 auto orig_rhs_type = rhs->GetCompilerType();
748 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
749 if (!type_or_err)
750 return type_or_err.takeError();
751 CompilerType result_type = *type_or_err;
752
753 if (result_type.IsScalarType())
754 return EvaluateScalarOp(BinaryOpKind::Sub, lhs, rhs, result_type, location);
755
756 auto lhs_type = lhs->GetCompilerType();
757 auto rhs_type = rhs->GetCompilerType();
758
759 // "pointer - integer" operation.
760 if (lhs_type.IsPointerType() && rhs_type.IsInteger())
761 return PointerOffset(lhs, rhs, BinaryOpKind::Sub, location);
762
763 // "pointer - pointer" operation.
764 if (lhs_type.IsPointerType() && rhs_type.IsPointerType()) {
765 if (lhs_type.IsPointerToVoid() && rhs_type.IsPointerToVoid()) {
766 return llvm::make_error<DILDiagnosticError>(
767 m_expr, "arithmetic on pointers to void", location);
768 }
769 // Compare canonical unqualified pointer types.
770 CompilerType lhs_unqualified_type = lhs_type.GetCanonicalType();
771 CompilerType rhs_unqualified_type = rhs_type.GetCanonicalType();
772 if (!lhs_unqualified_type.CompareTypes(rhs_unqualified_type)) {
773 std::string errMsg = llvm::formatv(
774 "'{0}' and '{1}' are not pointers to compatible types",
775 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
776 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
777 }
778
779 llvm::Expected<uint64_t> lhs_byte_size =
781 if (!lhs_byte_size)
782 return lhs_byte_size.takeError();
783 // Since pointers have compatible types, both have the same pointee size.
784 int64_t item_size = *lhs_byte_size;
785 int64_t diff = static_cast<int64_t>(lhs->GetValueAsUnsigned(0) -
786 rhs->GetValueAsUnsigned(0));
787 assert(item_size > 0 && "Pointee size cannot be 0");
788 if (diff % item_size != 0) {
789 // If address difference isn't divisible by pointee size then performing
790 // the operation is undefined behaviour.
791 return llvm::make_error<DILDiagnosticError>(
792 m_expr, "undefined pointer arithmetic", location);
793 }
794 diff /= item_size;
795
796 llvm::Expected<lldb::TypeSystemSP> type_system =
798 if (!type_system)
799 return type_system.takeError();
800 CompilerType ptrdiff_type = type_system.get()->GetPointerDiffType(true);
801 if (!ptrdiff_type)
802 return llvm::make_error<DILDiagnosticError>(
803 m_expr, "unable to determine pointer diff type", location);
804
805 Scalar scalar(diff);
807 ptrdiff_type, "result");
808 }
809
810 std::string errMsg =
811 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
812 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
813 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
814 location);
815}
816
817llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryMultiplication(
818 lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
819 // Operation '*' works for:
820 // {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
821 auto orig_lhs_type = lhs->GetCompilerType();
822 auto orig_rhs_type = rhs->GetCompilerType();
823 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
824 if (!type_or_err)
825 return type_or_err.takeError();
826 CompilerType result_type = *type_or_err;
827
828 if (!result_type.IsScalarType()) {
829 std::string errMsg =
830 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
831 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
832 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
833 location);
834 }
835
836 return EvaluateScalarOp(BinaryOpKind::Mul, lhs, rhs, result_type, location);
837}
838
839llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryDivision(
840 lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
841 // Operation '/' works for:
842 // {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
843 auto orig_lhs_type = lhs->GetCompilerType();
844 auto orig_rhs_type = rhs->GetCompilerType();
845 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
846 if (!type_or_err)
847 return type_or_err.takeError();
848 CompilerType result_type = *type_or_err;
849
850 if (!result_type.IsScalarType()) {
851 std::string errMsg =
852 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
853 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
854 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
855 location);
856 }
857
858 // Check for zero only for integer division.
859 if (result_type.IsInteger() && rhs->GetValueAsSigned(-1) == 0) {
860 return llvm::make_error<DILDiagnosticError>(
861 m_expr, "division by zero is undefined", location);
862 }
863
864 return EvaluateScalarOp(BinaryOpKind::Div, lhs, rhs, result_type, location);
865}
866
867llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryRemainder(
868 lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
869 // Operation '%' works for:
870 // {integer,unscoped_enum} <-> {integer,unscoped_enum}
871 auto orig_lhs_type = lhs->GetCompilerType();
872 auto orig_rhs_type = rhs->GetCompilerType();
873 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
874 if (!type_or_err)
875 return type_or_err.takeError();
876 CompilerType result_type = *type_or_err;
877
878 if (!result_type.IsInteger()) {
879 std::string errMsg =
880 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
881 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
882 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
883 location);
884 }
885
886 if (rhs->GetValueAsSigned(-1) == 0) {
887 return llvm::make_error<DILDiagnosticError>(
888 m_expr, "division by zero is undefined", location);
889 }
890
891 return EvaluateScalarOp(BinaryOpKind::Rem, lhs, rhs, result_type, location);
892}
893
895 return ct.GetTypeInfo() & lldb::eTypeIsFloat;
896}
897
898static llvm::Expected<bool> VerifyAssignmentTypes(CompilerType lhs_type,
899 CompilerType rhs_type) {
900 // Make sure lhs is a legal type for DIL assignment.
901 if (!lhs_type.IsInteger() && !lhs_type.IsUnscopedEnumerationType() &&
902 !HasFloatingRepresentation(lhs_type) && !lhs_type.IsPointerType() &&
903 !lhs_type.IsScalarType())
904 return llvm::createStringError(
905 "Illegal type for lhs of assignment (not scalar numeric type)");
906
907 // Make sure rhs is a legal type for DIL assignment.
908 if (!rhs_type.IsInteger() && !rhs_type.IsUnscopedEnumerationType() &&
909 !HasFloatingRepresentation(rhs_type) && !rhs_type.IsPointerType())
910 return llvm::createStringError(
911 "Illegal type for rhs of assignment (not scalar numeric type)");
912
913 // Only allow assigning pointers to pointers.
914 if ((lhs_type.IsPointerType() && !rhs_type.IsPointerType()) ||
915 (!lhs_type.IsPointerType() && rhs_type.IsPointerType()))
916 return llvm::createStringError(
917 "Invalid assignment: Can only assign pointers to pointers");
918
919 // For "real numbers", the types must match exactly.
920 if ((HasFloatingRepresentation(rhs_type) ||
921 HasFloatingRepresentation(lhs_type)) &&
922 lhs_type != rhs_type) {
923 std::string err_msg =
924 llvm::formatv("Incompatible types for assignment: Cannot assign {0} "
925 "to {1}",
926 rhs_type.TypeDescription(), lhs_type.TypeDescription());
927 return llvm::createStringError(err_msg);
928 }
929
930 return true;
931}
932
933llvm::Expected<lldb::ValueObjectSP>
935 lldb::ValueObjectSP rhs, uint32_t location) {
936
937 auto all_ok =
938 VerifyAssignmentTypes(lhs->GetCompilerType(), rhs->GetCompilerType());
939 if (!all_ok)
940 return all_ok.takeError();
941
942 if (llvm::Error e = lhs->SetValueFromInteger(rhs, m_allow_var_updates))
943 return e;
944
945 return lhs;
946}
947
948llvm::Expected<lldb::ValueObjectSP>
950 lldb::ValueObjectSP rhs, uint32_t location) {
951 // Operations {'&', '|', '^'} work for:
952 // {integer,unscoped_enum} <-> {integer,unscoped_enum}
953 auto orig_lhs_type = lhs->GetCompilerType();
954 auto orig_rhs_type = rhs->GetCompilerType();
955 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
956 if (!type_or_err)
957 return type_or_err.takeError();
958 CompilerType result_type = *type_or_err;
959
960 if (!result_type.IsInteger()) {
961 std::string errMsg =
962 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
963 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
964 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
965 }
966
967 return EvaluateScalarOp(kind, lhs, rhs, result_type, location);
968}
969
970llvm::Expected<lldb::ValueObjectSP>
972 lldb::ValueObjectSP rhs, uint32_t location) {
973 // Operations {'>>', '<<'} work for:
974 // {integer,unscoped_enum} <-> {integer,unscoped_enum}
975 CompilerType orig_lhs_type = lhs->GetCompilerType();
976 CompilerType orig_rhs_type = rhs->GetCompilerType();
977 auto lhs_or_err = UnaryConversion(lhs, location);
978 if (!lhs_or_err)
979 return lhs_or_err.takeError();
980 lhs = *lhs_or_err;
981 auto rhs_or_err = UnaryConversion(rhs, location);
982 if (!rhs_or_err)
983 return rhs_or_err.takeError();
984 rhs = *rhs_or_err;
985
986 CompilerType lhs_type = lhs->GetCompilerType();
987 CompilerType rhs_type = rhs->GetCompilerType();
988 if (!lhs_type.IsInteger() || !rhs_type.IsInteger()) {
989 std::string errMsg =
990 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
991 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
992 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
993 }
994
995 bool success;
996 uint64_t amount = rhs->GetValueAsUnsigned(0, &success);
997 if (!success)
998 return llvm::make_error<DILDiagnosticError>(
999 m_expr, "could not get the shift amount as an integer", location);
1000 llvm::Expected<uint64_t> lhs_size = lhs_type.GetBitSize(&m_stack_frame);
1001 if (!lhs_size)
1002 return lhs_size.takeError();
1003 if (amount >= *lhs_size)
1004 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid shift amount",
1005 location);
1006
1007 return EvaluateScalarOp(kind, lhs, rhs, lhs_type, location);
1008}
1009
1010llvm::Expected<lldb::ValueObjectSP>
1012 auto lhs_or_err = EvaluateAndDereference(node.GetLHS());
1013 if (!lhs_or_err)
1014 return lhs_or_err;
1015 lldb::ValueObjectSP lhs = *lhs_or_err;
1016 auto rhs_or_err = EvaluateAndDereference(node.GetRHS());
1017 if (!rhs_or_err)
1018 return rhs_or_err;
1019 lldb::ValueObjectSP rhs = *rhs_or_err;
1020
1021 lldb::TypeSystemSP lhs_system =
1022 lhs->GetCompilerType().GetTypeSystem().GetSharedPointer();
1023 lldb::TypeSystemSP rhs_system =
1024 rhs->GetCompilerType().GetTypeSystem().GetSharedPointer();
1025 if (lhs_system->GetPluginName() != rhs_system->GetPluginName()) {
1026 // TODO: Attempt to convert values to current CU's type system
1027 return llvm::make_error<DILDiagnosticError>(
1028 m_expr, "operands have different type systems", node.GetLocation());
1029 }
1030
1031 switch (node.GetKind()) {
1032 case BinaryOpKind::Add:
1033 return EvaluateBinaryAddition(lhs, rhs, node.GetLocation());
1035 auto ret_or_err = EvaluateBinaryAddition(lhs, rhs, node.GetLocation());
1036 if (!ret_or_err)
1037 return ret_or_err;
1038 return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
1039 }
1041 return EvaluateAssignment(lhs, rhs, node.GetLocation());
1042 case BinaryOpKind::Sub:
1043 return EvaluateBinarySubtraction(lhs, rhs, node.GetLocation());
1045 auto ret_or_err = EvaluateBinarySubtraction(lhs, rhs, node.GetLocation());
1046 if (!ret_or_err)
1047 return ret_or_err;
1048 return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
1049 }
1050 case BinaryOpKind::Mul:
1051 return EvaluateBinaryMultiplication(lhs, rhs, node.GetLocation());
1052 case BinaryOpKind::Div:
1053 return EvaluateBinaryDivision(lhs, rhs, node.GetLocation());
1054 case BinaryOpKind::Rem:
1055 return EvaluateBinaryRemainder(lhs, rhs, node.GetLocation());
1056 case BinaryOpKind::And:
1057 case BinaryOpKind::Xor:
1058 case BinaryOpKind::Or:
1059 return EvaluateBinaryBitwise(node.GetKind(), lhs, rhs, node.GetLocation());
1060 case BinaryOpKind::Shl:
1061 case BinaryOpKind::Shr:
1062 return EvaluateBinaryShift(node.GetKind(), lhs, rhs, node.GetLocation());
1063 }
1064
1065 return llvm::make_error<DILDiagnosticError>(
1066 m_expr, "unimplemented binary operation", node.GetLocation());
1067}
1068
1069llvm::Expected<lldb::ValueObjectSP>
1071 auto base_or_err = Evaluate(node.GetBase());
1072 if (!base_or_err)
1073 return base_or_err;
1074 bool expr_is_ptr = node.GetIsArrow();
1075 lldb::ValueObjectSP base = *base_or_err;
1076
1077 // Perform some basic type & correctness checking.
1078 if (node.GetIsArrow()) {
1079 // If we have a non-pointer type with a synthetic value then lets check
1080 // if we have a synthetic dereference specified.
1081 if (!base->IsPointerType() && base->HasSyntheticValue()) {
1082 Status deref_error;
1083 if (lldb::ValueObjectSP synth_deref_sp =
1084 base->GetSyntheticValue()->Dereference(deref_error);
1085 synth_deref_sp && deref_error.Success()) {
1086 base = std::move(synth_deref_sp);
1087 }
1088 if (!base || deref_error.Fail()) {
1089 std::string errMsg = llvm::formatv(
1090 "Failed to dereference synthetic value: {0}", deref_error);
1091 return llvm::make_error<DILDiagnosticError>(
1092 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
1093 }
1094
1095 // Some synthetic plug-ins fail to set the error in Dereference
1096 if (!base) {
1097 std::string errMsg = "Failed to dereference synthetic value";
1098 return llvm::make_error<DILDiagnosticError>(
1099 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
1100 }
1101 expr_is_ptr = false;
1102 }
1103 }
1104
1106 bool base_is_ptr = base->IsPointerType();
1107
1108 if (expr_is_ptr != base_is_ptr) {
1109 if (base_is_ptr) {
1110 std::string errMsg =
1111 llvm::formatv("member reference type {0} is a pointer; "
1112 "did you mean to use '->'?",
1113 base->GetCompilerType().TypeDescription());
1114 return llvm::make_error<DILDiagnosticError>(
1115 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
1116 } else {
1117 std::string errMsg =
1118 llvm::formatv("member reference type {0} is not a pointer; "
1119 "did you mean to use '.'?",
1120 base->GetCompilerType().TypeDescription());
1121 return llvm::make_error<DILDiagnosticError>(
1122 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
1123 }
1124 }
1125 }
1126
1127 lldb::ValueObjectSP field_obj =
1128 base->GetChildMemberWithName(node.GetFieldName());
1129 if (!field_obj) {
1130 if (m_use_synthetic) {
1131 field_obj = base->GetSyntheticValue();
1132 if (field_obj)
1133 field_obj = field_obj->GetChildMemberWithName(node.GetFieldName());
1134 }
1135
1136 if (!m_use_synthetic || !field_obj) {
1137 std::string errMsg = llvm::formatv(
1138 "\"{0}\" is not a member of \"({1}) {2}\"", node.GetFieldName(),
1139 base->GetTypeName().AsCString("<invalid type>"), base->GetName());
1140 return llvm::make_error<DILDiagnosticError>(
1141 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
1142 }
1143 }
1144
1145 if (field_obj) {
1147 lldb::ValueObjectSP dynamic_val_sp =
1148 field_obj->GetDynamicValue(m_use_dynamic);
1149 if (dynamic_val_sp)
1150 field_obj = dynamic_val_sp;
1151 }
1152 return field_obj;
1153 }
1154
1155 CompilerType base_type = base->GetCompilerType();
1156 if (node.GetIsArrow() && base->IsPointerType())
1157 base_type = base_type.GetPointeeType();
1158 std::string errMsg = llvm::formatv(
1159 "\"{0}\" is not a member of \"({1}) {2}\"", node.GetFieldName(),
1160 base->GetTypeName().AsCString("<invalid type>"), base->GetName());
1161 return llvm::make_error<DILDiagnosticError>(
1162 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
1163}
1164
1165llvm::Expected<lldb::ValueObjectSP>
1167 auto idx_or_err = EvaluateAndDereference(node.GetIndex());
1168 if (!idx_or_err)
1169 return idx_or_err;
1170 lldb::ValueObjectSP idx = *idx_or_err;
1171
1172 if (!idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType()) {
1173 return llvm::make_error<DILDiagnosticError>(
1174 m_expr, "array subscript is not an integer", node.GetLocation());
1175 }
1176
1177 StreamString var_expr_path_strm;
1178 uint64_t child_idx = idx->GetValueAsUnsigned(0);
1179 lldb::ValueObjectSP child_valobj_sp;
1180
1181 auto base_or_err = Evaluate(node.GetBase());
1182 if (!base_or_err)
1183 return base_or_err;
1184 lldb::ValueObjectSP base = *base_or_err;
1185
1186 CompilerType base_type = base->GetCompilerType().GetNonReferenceType();
1187 base->GetExpressionPath(var_expr_path_strm);
1188 bool is_incomplete_array = false;
1189 if (base_type.IsPointerType()) {
1190 bool is_objc_pointer = true;
1191
1192 if (base->GetCompilerType().GetMinimumLanguage() != lldb::eLanguageTypeObjC)
1193 is_objc_pointer = false;
1194 else if (!base->GetCompilerType().IsPointerType())
1195 is_objc_pointer = false;
1196
1197 if (!m_use_synthetic && is_objc_pointer) {
1198 std::string err_msg = llvm::formatv(
1199 "\"({0}) {1}\" is an Objective-C pointer, and cannot be subscripted",
1200 base->GetTypeName().AsCString("<invalid type>"),
1201 var_expr_path_strm.GetData());
1202 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1203 node.GetLocation());
1204 }
1205 if (is_objc_pointer) {
1206 lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
1207 if (!synthetic || synthetic == base) {
1208 std::string err_msg =
1209 llvm::formatv("\"({0}) {1}\" is not an array type",
1210 base->GetTypeName().AsCString("<invalid type>"),
1211 var_expr_path_strm.GetData());
1212 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1213 node.GetLocation());
1214 }
1215 if (static_cast<uint32_t>(child_idx) >=
1216 synthetic->GetNumChildrenIgnoringErrors()) {
1217 std::string err_msg = llvm::formatv(
1218 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
1219 base->GetTypeName().AsCString("<invalid type>"),
1220 var_expr_path_strm.GetData());
1221 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1222 node.GetLocation());
1223 }
1224 child_valobj_sp = synthetic->GetChildAtIndex(child_idx);
1225 if (!child_valobj_sp) {
1226 std::string err_msg = llvm::formatv(
1227 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
1228 base->GetTypeName().AsCString("<invalid type>"),
1229 var_expr_path_strm.GetData());
1230 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1231 node.GetLocation());
1232 }
1234 if (auto dynamic_sp = child_valobj_sp->GetDynamicValue(m_use_dynamic))
1235 child_valobj_sp = std::move(dynamic_sp);
1236 }
1237 return child_valobj_sp;
1238 }
1239
1240 child_valobj_sp = base->GetSyntheticArrayMember(child_idx, true);
1241 if (!child_valobj_sp) {
1242 std::string err_msg = llvm::formatv(
1243 "failed to use pointer as array for index {0} for "
1244 "\"({1}) {2}\"",
1245 child_idx, base->GetTypeName().AsCString("<invalid type>"),
1246 var_expr_path_strm.GetData());
1247 if (base_type.IsPointerToVoid())
1248 err_msg = "subscript of pointer to incomplete type 'void'";
1249 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1250 node.GetLocation());
1251 }
1252 } else if (base_type.IsArrayType(nullptr, nullptr, &is_incomplete_array)) {
1253 child_valobj_sp = base->GetChildAtIndex(child_idx);
1254 if (!child_valobj_sp && (is_incomplete_array || m_use_synthetic))
1255 child_valobj_sp = base->GetSyntheticArrayMember(child_idx, true);
1256 if (!child_valobj_sp) {
1257 std::string err_msg = llvm::formatv(
1258 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
1259 base->GetTypeName().AsCString("<invalid type>"),
1260 var_expr_path_strm.GetData());
1261 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1262 node.GetLocation());
1263 }
1264 } else if (base_type.IsScalarType()) {
1265 child_valobj_sp =
1266 base->GetSyntheticBitFieldChild(child_idx, child_idx, true);
1267 if (!child_valobj_sp) {
1268 std::string err_msg = llvm::formatv(
1269 "bitfield range {0}:{1} is not valid for \"({2}) {3}\"", child_idx,
1270 child_idx, base->GetTypeName().AsCString("<invalid type>"),
1271 var_expr_path_strm.GetData());
1272 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1273 node.GetLocation(), 1);
1274 }
1275 } else {
1276 lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
1277 if (!m_use_synthetic || !synthetic || synthetic == base) {
1278 std::string err_msg =
1279 llvm::formatv("\"{0}\" is not an array type",
1280 base->GetTypeName().AsCString("<invalid type>"));
1281 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1282 node.GetLocation(), 1);
1283 }
1284 if (static_cast<uint32_t>(child_idx) >=
1285 synthetic->GetNumChildrenIgnoringErrors(child_idx + 1)) {
1286 std::string err_msg = llvm::formatv(
1287 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
1288 base->GetTypeName().AsCString("<invalid type>"),
1289 var_expr_path_strm.GetData());
1290 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1291 node.GetLocation(), 1);
1292 }
1293 child_valobj_sp = synthetic->GetChildAtIndex(child_idx);
1294 if (!child_valobj_sp) {
1295 std::string err_msg = llvm::formatv(
1296 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
1297 base->GetTypeName().AsCString("<invalid type>"),
1298 var_expr_path_strm.GetData());
1299 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1300 node.GetLocation(), 1);
1301 }
1302 }
1303
1304 if (child_valobj_sp) {
1306 if (auto dynamic_sp = child_valobj_sp->GetDynamicValue(m_use_dynamic))
1307 child_valobj_sp = std::move(dynamic_sp);
1308 }
1309 return child_valobj_sp;
1310 }
1311
1312 bool success;
1313 int64_t signed_child_idx = idx->GetValueAsSigned(0, &success);
1314 if (!success)
1315 return llvm::make_error<DILDiagnosticError>(
1316 m_expr, "could not get the index as an integer",
1317 node.GetIndex().GetLocation());
1318 return base->GetSyntheticArrayMember(signed_child_idx, true);
1319}
1320
1321llvm::Expected<lldb::ValueObjectSP>
1323 auto first_idx_or_err = EvaluateAndDereference(node.GetFirstIndex());
1324 if (!first_idx_or_err)
1325 return first_idx_or_err;
1326 lldb::ValueObjectSP first_idx = *first_idx_or_err;
1327 auto last_idx_or_err = EvaluateAndDereference(node.GetLastIndex());
1328 if (!last_idx_or_err)
1329 return last_idx_or_err;
1330 lldb::ValueObjectSP last_idx = *last_idx_or_err;
1331
1332 if (!first_idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType() ||
1333 !last_idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType()) {
1334 return llvm::make_error<DILDiagnosticError>(
1335 m_expr, "bit index is not an integer", node.GetLocation());
1336 }
1337
1338 bool success_first, success_last;
1339 int64_t first_index = first_idx->GetValueAsSigned(0, &success_first);
1340 int64_t last_index = last_idx->GetValueAsSigned(0, &success_last);
1341 if (!success_first || !success_last)
1342 return llvm::make_error<DILDiagnosticError>(
1343 m_expr, "could not get the index as an integer", node.GetLocation());
1344
1345 // if the format given is [high-low], swap range
1346 if (first_index > last_index)
1347 std::swap(first_index, last_index);
1348
1349 auto base_or_err = EvaluateAndDereference(node.GetBase());
1350 if (!base_or_err)
1351 return base_or_err;
1352 lldb::ValueObjectSP base = *base_or_err;
1353 lldb::ValueObjectSP child_valobj_sp =
1354 base->GetSyntheticBitFieldChild(first_index, last_index, true);
1355 if (!child_valobj_sp) {
1356 std::string message = llvm::formatv(
1357 "bitfield range {0}:{1} is not valid for \"({2}) {3}\"", first_index,
1358 last_index, base->GetTypeName().AsCString("<invalid type>"),
1359 base->GetName().GetStringRef());
1360 return llvm::make_error<DILDiagnosticError>(m_expr, message,
1361 node.GetLocation());
1362 }
1363 return child_valobj_sp;
1364}
1365
1366llvm::Expected<CompilerType>
1369 const IntegerLiteralNode &literal) {
1370 // Binary, Octal, Hexadecimal and literals with a U suffix are allowed to be
1371 // an unsigned integer.
1372 bool unsigned_is_allowed = literal.IsUnsigned() || literal.GetRadix() != 10;
1373 llvm::APInt apint = literal.GetValue();
1374
1375 llvm::SmallVector<std::pair<lldb::BasicType, lldb::BasicType>, 3> candidates;
1376 if (literal.GetTypeSuffix() <= IntegerTypeSuffix::None)
1377 candidates.emplace_back(lldb::eBasicTypeInt,
1378 unsigned_is_allowed ? lldb::eBasicTypeUnsignedInt
1380 if (literal.GetTypeSuffix() <= IntegerTypeSuffix::Long)
1381 candidates.emplace_back(lldb::eBasicTypeLong,
1382 unsigned_is_allowed ? lldb::eBasicTypeUnsignedLong
1384 candidates.emplace_back(lldb::eBasicTypeLongLong,
1386 for (auto [signed_, unsigned_] : candidates) {
1387 CompilerType signed_type = type_system->GetBasicTypeFromAST(signed_);
1388 if (!signed_type)
1389 continue;
1390 llvm::Expected<uint64_t> size = signed_type.GetBitSize(&ctx);
1391 if (!size)
1392 return size.takeError();
1393 if (!literal.IsUnsigned() && apint.isIntN(*size - 1))
1394 return signed_type;
1395 if (unsigned_ != lldb::eBasicTypeInvalid && apint.isIntN(*size))
1396 return type_system->GetBasicTypeFromAST(unsigned_);
1397 }
1398
1399 return llvm::make_error<DILDiagnosticError>(
1400 m_expr,
1401 "integer literal is too large to be represented in any integer type",
1402 literal.GetLocation());
1403}
1404
1405llvm::Expected<lldb::ValueObjectSP>
1407 llvm::Expected<lldb::TypeSystemSP> type_system =
1409 if (!type_system)
1410 return type_system.takeError();
1411
1412 llvm::Expected<CompilerType> type =
1413 PickIntegerType(*type_system, m_stack_frame, node);
1414 if (!type)
1415 return type.takeError();
1416
1417 Scalar scalar = node.GetValue();
1418 // APInt from StringRef::getAsInteger comes with just enough bitwidth to
1419 // hold the value. This adjusts APInt bitwidth to match the compiler type.
1420 llvm::Expected<uint64_t> type_bitsize = type->GetBitSize(&m_stack_frame);
1421 if (!type_bitsize)
1422 return type_bitsize.takeError();
1423 // Literal itself cannot be a negative value, so we do an unsigned extension.
1424 scalar.TruncOrExtendTo(*type_bitsize, false);
1425 // If the picked compiler type is signed, make the scalar signed as well.
1426 if (type->IsSigned())
1427 scalar.MakeSigned();
1429 "result");
1430}
1431
1432llvm::Expected<lldb::ValueObjectSP>
1434 llvm::Expected<lldb::TypeSystemSP> type_system =
1436 if (!type_system)
1437 return type_system.takeError();
1438
1439 bool isFloat =
1440 &node.GetValue().getSemantics() == &llvm::APFloat::IEEEsingle();
1441 lldb::BasicType basic_type =
1443 CompilerType type = GetBasicType(*type_system, basic_type);
1444
1445 if (!type)
1446 return llvm::make_error<DILDiagnosticError>(
1447 m_expr, "unable to create a const literal", node.GetLocation());
1448
1449 Scalar scalar = node.GetValue();
1451 "result");
1452}
1453
1454llvm::Expected<lldb::ValueObjectSP>
1456 bool value = node.GetValue();
1457 llvm::Expected<lldb::TypeSystemSP> type_system =
1459 if (!type_system)
1460 return type_system.takeError();
1462 value, "result");
1463}
1464
1465llvm::Expected<CastKind>
1467 CompilerType target_type, int location) {
1468 if (source_type.IsPointerType() || source_type.IsNullPtrType()) {
1469 // Cast from pointer to float/double is not allowed.
1470 if (target_type.GetTypeInfo() & lldb::eTypeIsFloat) {
1471 std::string errMsg = llvm::formatv("Cast from {0} to {1} is not allowed",
1472 source_type.TypeDescription(),
1473 target_type.TypeDescription());
1474 return llvm::make_error<DILDiagnosticError>(
1475 m_expr, std::move(errMsg), location,
1476 source_type.TypeDescription().length());
1477 }
1478
1479 // Casting from pointer to bool is always valid.
1480 if (target_type.IsBoolean())
1481 return CastKind::eArithmetic;
1482
1483 // Otherwise check if the result type is at least as big as the pointer
1484 // size.
1485 uint64_t type_byte_size = 0;
1486 uint64_t rhs_type_byte_size = 0;
1487 if (auto temp = target_type.GetByteSize(&m_stack_frame)) {
1488 type_byte_size = *temp;
1489 } else {
1490 std::string errMsg = llvm::formatv("unable to get byte size for type {0}",
1491 target_type.TypeDescription());
1492 LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), temp.takeError(),
1493 "GetByteSize failed: {0}");
1494 return llvm::make_error<DILDiagnosticError>(
1495 m_expr, std::move(errMsg), location,
1496 target_type.TypeDescription().length());
1497 }
1498
1499 if (auto temp = source_type.GetByteSize(&m_stack_frame)) {
1500 rhs_type_byte_size = *temp;
1501 } else {
1502 std::string errMsg = llvm::formatv("unable to get byte size for type {0}",
1503 source_type.TypeDescription());
1504 LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), temp.takeError(),
1505 "GetByteSize failed: {0}");
1506 return llvm::make_error<DILDiagnosticError>(
1507 m_expr, std::move(errMsg), location,
1508 source_type.TypeDescription().length());
1509 }
1510
1511 if (type_byte_size < rhs_type_byte_size) {
1512 std::string errMsg = llvm::formatv(
1513 "cast from pointer to smaller type {0} loses information",
1514 target_type.TypeDescription());
1515 return llvm::make_error<DILDiagnosticError>(
1516 m_expr, std::move(errMsg), location,
1517 source_type.TypeDescription().length());
1518 }
1519 } else if (!source_type.IsScalarType() && !source_type.IsEnumerationType()) {
1520 // Otherwise accept only arithmetic types and enums.
1521 std::string errMsg = llvm::formatv("cannot convert {0} to {1}",
1522 source_type.TypeDescription(),
1523 target_type.TypeDescription());
1524
1525 return llvm::make_error<DILDiagnosticError>(
1526 m_expr, std::move(errMsg), location,
1527 source_type.TypeDescription().length());
1528 }
1529 return CastKind::eArithmetic;
1530}
1531
1532llvm::Expected<CastKind>
1534 CompilerType source_type, CompilerType target_type,
1535 int location) {
1536
1537 if (target_type.IsScalarType())
1538 return VerifyArithmeticCast(source_type, target_type, location);
1539
1540 if (target_type.IsEnumerationType()) {
1541 // Cast to enum type.
1542 if (!source_type.IsScalarType() && !source_type.IsEnumerationType()) {
1543 std::string errMsg = llvm::formatv("Cast from {0} to {1} is not allowed",
1544 source_type.TypeDescription(),
1545 target_type.TypeDescription());
1546
1547 return llvm::make_error<DILDiagnosticError>(
1548 m_expr, std::move(errMsg), location,
1549 source_type.TypeDescription().length());
1550 }
1552 }
1553
1554 if (target_type.IsPointerType()) {
1555 if (!source_type.IsInteger() && !source_type.IsEnumerationType() &&
1556 !source_type.IsArrayType() && !source_type.IsPointerType() &&
1557 !source_type.IsNullPtrType()) {
1558 std::string errMsg = llvm::formatv(
1559 "cannot cast from type {0} to pointer type {1}",
1560 source_type.TypeDescription(), target_type.TypeDescription());
1561
1562 return llvm::make_error<DILDiagnosticError>(
1563 m_expr, std::move(errMsg), location,
1564 source_type.TypeDescription().length());
1565 }
1566 return CastKind::ePointer;
1567 }
1568
1569 // Unsupported cast.
1570 std::string errMsg = llvm::formatv(
1571 "casting of {0} to {1} is not implemented yet",
1572 source_type.TypeDescription(), target_type.TypeDescription());
1573 return llvm::make_error<DILDiagnosticError>(
1574 m_expr, std::move(errMsg), location,
1575 source_type.TypeDescription().length());
1576}
1577
1578llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const CastNode &node) {
1579 auto operand_or_err = Evaluate(node.GetOperand());
1580
1581 if (!operand_or_err)
1582 return operand_or_err;
1583
1584 lldb::ValueObjectSP operand = *operand_or_err;
1585 CompilerType op_type = operand->GetCompilerType();
1586 CompilerType target_type = node.GetType();
1587
1588 if (op_type.IsReferenceType())
1589 op_type = op_type.GetNonReferenceType();
1590 if (target_type.IsScalarType() && op_type.IsArrayType()) {
1591 operand = ArrayToPointerConversion(*operand, m_stack_frame,
1592 operand->GetName().GetStringRef());
1593 op_type = operand->GetCompilerType();
1594 }
1595 auto type_or_err =
1596 VerifyCastType(operand, op_type, target_type, node.GetLocation());
1597 if (!type_or_err)
1598 return type_or_err.takeError();
1599
1600 CastKind cast_kind = *type_or_err;
1601 if (operand->GetCompilerType().IsReferenceType()) {
1602 Status error;
1603 operand = operand->Dereference(error);
1604 if (error.Fail())
1605 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
1606 node.GetLocation());
1607 }
1608
1609 switch (cast_kind) {
1611 // FIXME: is this correct for float vector types?
1612 if (op_type.GetTypeInfo() & lldb::eTypeIsFloat || op_type.IsInteger() ||
1613 op_type.IsEnumerationType())
1614 return operand->CastToEnumType(target_type);
1615 break;
1616 }
1617 case CastKind::eArithmetic: {
1618 if (op_type.IsPointerType() || op_type.IsNullPtrType() ||
1619 op_type.IsScalarType() || op_type.IsEnumerationType())
1620 return operand->CastToBasicType(target_type);
1621 break;
1622 }
1623 case CastKind::ePointer: {
1624 uint64_t addr = op_type.IsArrayType()
1625 ? operand->GetLoadAddress()
1626 : (op_type.IsSigned() ? operand->GetValueAsSigned(0)
1627 : operand->GetValueAsUnsigned(0));
1628 llvm::StringRef name = "result";
1629 ExecutionContext exe_ctx(m_target.get(), false);
1630 return ValueObject::CreateValueObjectFromAddress(name, addr, exe_ctx,
1631 target_type,
1632 /* do_deref */ false);
1633 }
1634 case CastKind::eNone: {
1635 return lldb::ValueObjectSP();
1636 }
1637 } // switch
1638
1639 std::string errMsg =
1640 llvm::formatv("unable to cast from '{0}' to '{1}'",
1641 op_type.TypeDescription(), target_type.TypeDescription());
1642 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
1643 node.GetLocation());
1644}
1645
1646} // namespace lldb_private::dil
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:405
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
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.
void ForEachEnumerator(std::function< bool(const CompilerType &integer_type, ConstString name, const llvm::APSInt &value)> const &callback) const
If this type is an enumeration, iterate through all of its enumerators using a callback.
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...
bool IsUnscopedEnumerationType() const
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
This base class provides an interface to stack frames.
Definition StackFrame.h:44
virtual const char * GetFunctionName()
Get the frame's demangled name.
virtual lldb::RegisterContextSP GetRegisterContext()
Get the RegisterContext for this frame, if possible.
virtual lldb::ValueObjectSP GetValueObjectForFrameVariable(const lldb::VariableSP &variable_sp, lldb::DynamicValueType use_dynamic)
Create a ValueObject for a given Variable in this StackFrame.
virtual const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
virtual lldb::VariableListSP GetInScopeVariableList(bool get_file_globals, bool include_synthetic_vars=true, bool must_have_valid_location=false)
Retrieve the list of variables that are in scope at this StackFrame's pc.
virtual lldb::ValueObjectSP FindVariable(ConstString name)
Attempt to reconstruct the ValueObject for a variable with a given name from within the current Stack...
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 GetInstanceName()
Determines the name of the instance for 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 CreateValueObjectFromScalar(const ExecutionContext &exe_ctx, Scalar &s, CompilerType type, llvm::StringRef name, ValueObject *parent=nullptr)
Create a value object containing the given Scalar value.
static lldb::ValueObjectSP CreateValueObjectFromBool(const ExecutionContext &exe_ctx, lldb::TypeSystemSP typesystem, bool value, llvm::StringRef name, ValueObject *parent=nullptr)
Create a value object containing the given boolean value.
lldb::addr_t GetLoadAddress()
Return the target load address associated with this value object.
CompilerType GetCompilerType()
static lldb::ValueObjectSP CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, CompilerType type, bool do_deref=true, ValueObject *parent=nullptr)
Given an address either create a value object containing the value at that address,...
The rest of the classes in this file, except for the Visitor class at the very end,...
Definition DILAST.h:86
uint32_t GetLocation() const
Definition DILAST.h:94
virtual llvm::Expected< lldb::ValueObjectSP > Accept(Visitor *v) const =0
ASTNode & GetLHS() const
Definition DILAST.h:184
BinaryOpKind GetKind() const
Definition DILAST.h:183
ASTNode & GetRHS() const
Definition DILAST.h:185
ASTNode & GetOperand() const
Definition DILAST.h:314
CompilerType GetType() const
Definition DILAST.h:313
const llvm::APFloat & GetValue() const
Definition DILAST.h:277
std::string GetName() const
Definition DILAST.h:121
IntegerTypeSuffix GetTypeSuffix() const
Definition DILAST.h:256
const llvm::APInt & GetValue() const
Definition DILAST.h:253
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryRemainder(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:867
llvm::Expected< lldb::ValueObjectSP > Evaluate(const ASTNode &node)
Evaluate an ASTNode.
Definition DILEval.cpp:420
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryAddition(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:702
llvm::Expected< lldb::ValueObjectSP > EvaluateAndDereference(const ASTNode &node)
Evaluate an ASTNode.
Definition DILEval.cpp:433
llvm::Expected< lldb::ValueObjectSP > PointerOffset(lldb::ValueObjectSP ptr, lldb::ValueObjectSP offset, BinaryOpKind operation, uint32_t location)
Add or subtract the offset to the pointer according to the pointee type byte size.
Definition DILEval.cpp:616
llvm::Expected< lldb::ValueObjectSP > EvaluateScalarOp(BinaryOpKind kind, lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, CompilerType result_type, uint32_t location)
Definition DILEval.cpp:652
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:176
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryShift(BinaryOpKind kind, lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:971
llvm::Expected< lldb::ValueObjectSP > EvaluateBinarySubtraction(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:740
llvm::Expected< lldb::ValueObjectSP > UnaryConversion(lldb::ValueObjectSP valobj, uint32_t location)
Perform usual unary conversions on a value.
Definition DILEval.cpp:60
llvm::Expected< lldb::ValueObjectSP > Visit(const IdentifierNode &node) override
Definition DILEval.cpp:449
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryDivision(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:839
lldb::DynamicValueType m_use_dynamic
Definition DILEval.h:161
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:203
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryMultiplication(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:817
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:1533
Interpreter(lldb::TargetSP target, llvm::StringRef expr, StackFrame &stack_frame, lldb::DynamicValueType use_dynamic, uint32_t options)
Definition DILEval.cpp:399
llvm::Expected< CompilerType > PickIntegerType(lldb::TypeSystemSP type_system, ExecutionContextScope &ctx, const IntegerLiteralNode &literal)
Definition DILEval.cpp:1367
llvm::Expected< lldb::ValueObjectSP > EvaluateAssignment(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:934
llvm::Expected< CastKind > VerifyArithmeticCast(CompilerType source_type, CompilerType target_type, int location)
A helper function for VerifyCastType (below).
Definition DILEval.cpp:1466
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryBitwise(BinaryOpKind kind, lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:949
llvm::StringRef GetFieldName() const
Definition DILAST.h:142
ASTNode & GetBase() const
Definition DILAST.h:140
UnaryOpKind GetKind() const
Definition DILAST.h:162
ASTNode & GetOperand() const
Definition DILAST.h:163
CastKind
The type casts allowed by DIL.
Definition DILAST.h:65
@ eEnumeration
Casting from a scalar to an enumeration type.
Definition DILAST.h:67
@ ePointer
Casting to a pointer type.
Definition DILAST.h:68
@ eNone
Invalid promotion type (results in error).
Definition DILAST.h:69
@ eArithmetic
Casting to a scalar.
Definition DILAST.h:66
static lldb::BasicType BasicTypeToUnsigned(lldb::BasicType basic_type)
Definition DILEval.cpp:155
static llvm::Expected< lldb::TypeSystemSP > GetTypeSystemFromCU(StackFrame &ctx)
Definition DILEval.cpp:47
lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref, StackFrame &stack_frame, lldb::DynamicValueType use_dynamic)
Given the name of an identifier (variable name, member name, type name, etc.), find the ValueObject f...
Definition DILEval.cpp:326
static CompilerType GetBasicType(lldb::TypeSystemSP type_system, lldb::BasicType basic_type)
Definition DILEval.cpp:27
static lldb::ValueObjectSP ArrayToPointerConversion(ValueObject &valobj, ExecutionContextScope &ctx, llvm::StringRef name)
Definition DILEval.cpp:35
BinaryOpKind
The binary operators recognized by DIL.
Definition DILAST.h:45
lldb::ValueObjectSP LookupGlobalIdentifier(llvm::StringRef name_ref, StackFrame &stack_frame, 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:284
static llvm::Expected< bool > VerifyAssignmentTypes(CompilerType lhs_type, CompilerType rhs_type)
Definition DILEval.cpp:898
lldb::ValueObjectSP LookupEnumValue(llvm::StringRef name_ref, ExecutionContextScope &ctx_scope)
Given the name of an identifier, attempt to find an enumeration value.
Definition DILEval.cpp:374
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:118
static lldb::VariableSP DILFindVariable(ConstString name, VariableList &variable_list)
Definition DILEval.cpp:259
CompilerType ResolveTypeByName(const std::string &name, ExecutionContextScope &ctx_scope)
Definition DILParser.cpp:62
static bool HasFloatingRepresentation(CompilerType ct)
Definition DILEval.cpp:894
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
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
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),...