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"
16#include "lldb/Target/Target.h"
23#include "llvm/Support/ErrorExtras.h"
24#include "llvm/Support/FormatAdapters.h"
25#include <memory>
26
27namespace lldb_private::dil {
28
30 lldb::BasicType basic_type) {
31 if (type_system)
32 return type_system.get()->GetBasicTypeFromAST(basic_type);
33
34 return CompilerType();
35}
36
39 llvm::StringRef name) {
40 uint64_t addr = valobj.GetLoadAddress();
41 ExecutionContext exe_ctx;
42 ctx.CalculateExecutionContext(exe_ctx);
44 name, addr, exe_ctx,
46 /* do_deref */ false);
47}
48
49static llvm::Expected<lldb::LanguageType>
51 SymbolContext symbol_context =
52 ctx.GetSymbolContext(lldb::eSymbolContextCompUnit);
53 if (!symbol_context.comp_unit)
54 return llvm::createStringErrorV("no compile unit for frame: {}",
55 ctx.GetFunctionName());
56
57 return symbol_context.comp_unit->GetLanguage();
58}
59
60static llvm::Expected<lldb::TypeSystemSP> GetTypeSystemFromCU(StackFrame &ctx) {
61 SymbolContext symbol_context =
62 ctx.GetSymbolContext(lldb::eSymbolContextCompUnit);
63 if (!symbol_context.comp_unit)
64 return llvm::createStringErrorV("no compile unit for frame: {}",
65 ctx.GetFunctionName());
66
67 lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
68 symbol_context = ctx.GetSymbolContext(lldb::eSymbolContextModule);
69 return symbol_context.module_sp->GetTypeSystemForLanguage(language);
70}
71
72llvm::Expected<lldb::ValueObjectSP>
74 if (!valobj)
75 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
76 location);
77 llvm::Expected<lldb::TypeSystemSP> type_system =
79 if (!type_system)
80 return type_system.takeError();
81
82 CompilerType in_type = valobj->GetCompilerType();
83 if (valobj->IsBitfield()) {
84 // Promote bitfields. If `int` can represent the bitfield value, it is
85 // converted to `int`. Otherwise, if `unsigned int` can represent it, it
86 // is converted to `unsigned int`. Otherwise, it is treated as its
87 // underlying type.
88 uint32_t bitfield_size = valobj->GetBitfieldBitSize();
89 // Some bitfields have undefined size (e.g. result of ternary operation).
90 // The AST's `bitfield_size` of those is 0, and no promotion takes place.
91 if (bitfield_size > 0 && in_type.IsInteger()) {
92 CompilerType int_type = GetBasicType(*type_system, lldb::eBasicTypeInt);
93 CompilerType uint_type =
95 llvm::Expected<uint64_t> int_bit_size =
96 int_type.GetBitSize(&m_stack_frame);
97 if (!int_bit_size)
98 return int_bit_size.takeError();
99 llvm::Expected<uint64_t> uint_bit_size =
100 uint_type.GetBitSize(&m_stack_frame);
101 if (!uint_bit_size)
102 return uint_bit_size.takeError();
103 if (bitfield_size < *int_bit_size ||
104 (in_type.IsSigned() && bitfield_size == *int_bit_size)) {
105 auto result = valobj->CastToBasicType(int_type);
106 if (result->GetError().Fail())
107 return llvm::make_error<DILDiagnosticError>(
108 m_expr, result->GetError().AsCString(), location);
109 return result;
110 }
111 if (bitfield_size <= *uint_bit_size) {
112 auto result = valobj->CastToBasicType(uint_type);
113 if (result->GetError().Fail())
114 return llvm::make_error<DILDiagnosticError>(
115 m_expr, result->GetError().AsCString(), location);
116 return result;
117 }
118 // Re-create as a const value with the same underlying type
119 Scalar scalar;
120 bool resolved = valobj->ResolveValue(scalar);
121 if (!resolved)
122 return llvm::createStringError("invalid scalar value");
124 in_type, "result");
125 }
126 }
127
128 if (in_type.IsArrayType())
129 valobj = ArrayToPointerConversion(*valobj, m_stack_frame, "result");
130
131 CompilerType promoted_type =
132 valobj->GetCompilerType().GetPromotedIntegerType();
133 if (promoted_type) {
134 auto result = valobj->CastToBasicType(promoted_type);
135 if (result->GetError().Fail())
136 return llvm::make_error<DILDiagnosticError>(
137 m_expr, result->GetError().AsCString(), location);
138 return result;
139 }
140
141 return valobj;
142}
143
144/// Basic types with a lower rank are converted to the basic type
145/// with a higher rank.
146static size_t ConversionRank(CompilerType type) {
147 switch (type.GetCanonicalType().GetBasicTypeEnumeration()) {
149 return 1;
153 return 2;
156 return 3;
159 return 4;
162 return 5;
165 return 6;
168 return 7;
170 return 8;
172 return 9;
174 return 10;
176 return 11;
177 default:
178 break;
179 }
180 return 0;
181}
182
202
203llvm::Expected<CompilerType>
205 CompilerType &rhs_type) {
206 assert(lhs_type.IsInteger() && rhs_type.IsInteger());
207 if (!lhs_type.IsSigned() && rhs_type.IsSigned()) {
208 llvm::Expected<uint64_t> lhs_size = lhs_type.GetBitSize(&m_stack_frame);
209 if (!lhs_size)
210 return lhs_size.takeError();
211 llvm::Expected<uint64_t> rhs_size = rhs_type.GetBitSize(&m_stack_frame);
212 if (!rhs_size)
213 return rhs_size.takeError();
214
215 if (*rhs_size == *lhs_size) {
216 llvm::Expected<lldb::TypeSystemSP> type_system =
218 if (!type_system)
219 return type_system.takeError();
220 CompilerType r_type_unsigned = GetBasicType(
221 *type_system,
224 return r_type_unsigned;
225 }
226 }
227 return rhs_type;
228}
229
230llvm::Expected<CompilerType>
232 lldb::ValueObjectSP &rhs, uint32_t location) {
233 // Apply unary conversion for both operands.
234 auto lhs_or_err = UnaryConversion(lhs, location);
235 if (!lhs_or_err)
236 return lhs_or_err.takeError();
237 lhs = *lhs_or_err;
238 auto rhs_or_err = UnaryConversion(rhs, location);
239 if (!rhs_or_err)
240 return rhs_or_err.takeError();
241 rhs = *rhs_or_err;
242
243 CompilerType lhs_type = lhs->GetCompilerType();
244 CompilerType rhs_type = rhs->GetCompilerType();
245
246 // If types already match, no need for further conversions.
247 if (lhs_type.CompareTypes(rhs_type))
248 return lhs_type;
249
250 // If either of the operands is not arithmetic (e.g. pointer), we're done.
251 if (!lhs_type.IsScalarType() || !rhs_type.IsScalarType())
252 return CompilerType();
253
254 size_t l_rank = ConversionRank(lhs_type);
255 size_t r_rank = ConversionRank(rhs_type);
256 if (l_rank == 0 || r_rank == 0)
257 return llvm::make_error<DILDiagnosticError>(
258 m_expr, "unexpected basic type in arithmetic operation", location);
259
260 // If both operands are integer, check if we need to promote
261 // the higher ranked signed type.
262 if (lhs_type.IsInteger() && rhs_type.IsInteger()) {
263 using Rank = std::tuple<size_t, bool>;
264 Rank int_l_rank = {l_rank, !lhs_type.IsSigned()};
265 Rank int_r_rank = {r_rank, !rhs_type.IsSigned()};
266 if (int_l_rank < int_r_rank) {
267 auto type_or_err = PromoteSignedInteger(lhs_type, rhs_type);
268 if (!type_or_err)
269 return type_or_err.takeError();
270 return *type_or_err;
271 }
272 if (int_l_rank > int_r_rank) {
273 auto type_or_err = PromoteSignedInteger(rhs_type, lhs_type);
274 if (!type_or_err)
275 return type_or_err.takeError();
276 return *type_or_err;
277 }
278 return lhs_type;
279 }
280
281 // Handle other combinations of integer and floating point operands.
282 if (l_rank < r_rank)
283 return rhs_type;
284 return lhs_type;
285}
286
288 VariableList &variable_list) {
289 lldb::VariableSP exact_match;
290 std::vector<lldb::VariableSP> possible_matches;
291
292 for (lldb::VariableSP var_sp : variable_list) {
293 llvm::StringRef str_ref_name = var_sp->GetName().GetStringRef();
294
295 str_ref_name.consume_front("::");
296 // Check for the exact same match
297 if (str_ref_name == name.GetStringRef())
298 return var_sp;
299
300 // Check for possible matches by base name
301 if (var_sp->NameMatches(name))
302 possible_matches.push_back(var_sp);
303 }
304
305 // If there's a non-exact match, take it.
306 if (possible_matches.size() > 0)
307 return possible_matches[0];
308
309 return nullptr;
310}
311
313 StackFrame &stack_frame,
314 lldb::TargetSP target_sp,
315 lldb::DynamicValueType use_dynamic) {
316 // Get a global variables list without the locals from the current frame
317 SymbolContext symbol_context =
318 stack_frame.GetSymbolContext(lldb::eSymbolContextCompUnit);
319 lldb::VariableListSP variable_list;
320 if (symbol_context.comp_unit)
321 variable_list = symbol_context.comp_unit->GetVariableList(true);
322
323 name_ref.consume_front("::");
324 lldb::ValueObjectSP value_sp;
325 if (variable_list) {
326 lldb::VariableSP var_sp =
327 DILFindVariable(ConstString(name_ref), *variable_list);
328 if (var_sp)
329 value_sp =
330 stack_frame.GetValueObjectForFrameVariable(var_sp, use_dynamic);
331 }
332
333 if (value_sp)
334 return value_sp;
335
336 // Check for match in modules global variables.
337 VariableList modules_var_list;
338 target_sp->GetImages().FindGlobalVariables(
339 ConstString(name_ref), std::numeric_limits<uint32_t>::max(),
340 modules_var_list);
341
342 if (!modules_var_list.Empty()) {
343 lldb::VariableSP var_sp =
344 DILFindVariable(ConstString(name_ref), modules_var_list);
345 if (var_sp)
346 value_sp = ValueObjectVariable::Create(&stack_frame, var_sp);
347
348 if (value_sp)
349 return value_sp;
350 }
351 return nullptr;
352}
353
355 StackFrame &stack_frame,
356 lldb::TargetSP target_sp,
357 lldb::LanguageType language) {
358 if (name_ref.starts_with("$")) {
359 if (auto *state =
360 target_sp->GetPersistentExpressionStateForLanguage(language))
361 if (auto var_sp = state->GetVariable(name_ref))
362 if (auto valobj_sp = var_sp->GetValueObject())
363 return valobj_sp;
364 }
365 return nullptr;
366}
367
368lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
369 StackFrame &stack_frame,
370 lldb::DynamicValueType use_dynamic) {
371 // Support $rax as a special syntax for accessing registers.
372 // Will return an invalid value in case the requested register doesn't exist.
373 if (name_ref.consume_front("$")) {
374 lldb::RegisterContextSP reg_ctx(stack_frame.GetRegisterContext());
375 if (!reg_ctx)
376 return nullptr;
377
378 if (const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name_ref))
379 return ValueObjectRegister::Create(&stack_frame, reg_ctx, reg_info);
380
381 return nullptr;
382 }
383
384 if (!name_ref.contains("::")) {
385 // Lookup in the current frame.
386 // Try looking for a local variable in current scope.
387 lldb::VariableListSP variable_list(
388 stack_frame.GetInScopeVariableList(false));
389
390 lldb::ValueObjectSP value_sp;
391 if (variable_list) {
392 lldb::VariableSP var_sp =
393 variable_list->FindVariable(ConstString(name_ref));
394 if (var_sp)
395 value_sp =
396 stack_frame.GetValueObjectForFrameVariable(var_sp, use_dynamic);
397 }
398
399 if (value_sp)
400 return value_sp;
401
402 // Try looking for an instance variable (class member).
403 SymbolContext sc = stack_frame.GetSymbolContext(
404 lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
405 llvm::StringRef instance_name = sc.GetInstanceName();
406 value_sp = stack_frame.FindVariable(ConstString(instance_name));
407 if (value_sp)
408 value_sp = value_sp->GetChildMemberWithName(name_ref);
409
410 if (value_sp)
411 return value_sp;
412 }
413 return nullptr;
414}
415
416lldb::ValueObjectSP LookupEnumValue(llvm::StringRef name_ref,
417 ExecutionContextScope &ctx_scope) {
418 if (name_ref.contains("::")) {
419 llvm::StringRef enum_typename, enumerator_name;
420 // FIXME: Change this to a structured binding for lambda capturing
421 // once we have C++20.
422 std::tie(enum_typename, enumerator_name) = name_ref.rsplit("::");
423 CompilerType enum_type = ResolveTypeByName(enum_typename.str(), ctx_scope);
424 lldb::ValueObjectSP result;
425 enum_type.ForEachEnumerator([&](const CompilerType &integer_type,
426 ConstString name,
427 const llvm::APSInt &value) -> bool {
428 if (name == enumerator_name) {
429 Scalar scalar(value);
430 result = ValueObject::CreateValueObjectFromScalar(ctx_scope, scalar,
431 enum_type, "result");
432 return false; // Stop iterating
433 }
434 return true;
435 });
436 return result;
437 }
438 return nullptr;
439}
440
441Interpreter::Interpreter(lldb::TargetSP target, llvm::StringRef expr,
442 StackFrame &stack_frame,
443 lldb::DynamicValueType use_dynamic, uint32_t options)
444 : m_target(std::move(target)), m_expr(expr), m_stack_frame(stack_frame),
445 m_use_dynamic(use_dynamic) {
446
447 const bool check_ptr_vs_member =
449 const bool no_synth_child =
451 const bool allow_var_updates =
453 const bool disallow_globals =
455
456 m_use_synthetic = !no_synth_child;
457 m_check_ptr_vs_member = check_ptr_vs_member;
458 m_allow_var_updates = allow_var_updates;
459 m_allow_globals = !disallow_globals;
460}
461
462llvm::Expected<lldb::ValueObjectSP> Interpreter::Evaluate(const ASTNode &node) {
463 // Evaluate an AST.
464 auto value_or_error = node.Accept(this);
465 // Convert SP with a nullptr to an error.
466 if (value_or_error && !*value_or_error)
467 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
468 node.GetLocation());
469 // Return the computed value-or-error. The caller is responsible for
470 // checking if an error occurred during the evaluation.
471 return value_or_error;
472}
473
474llvm::Expected<lldb::ValueObjectSP>
476 auto valobj_or_err = Evaluate(node);
477 if (!valobj_or_err)
478 return valobj_or_err;
479 lldb::ValueObjectSP valobj = *valobj_or_err;
480
482 if (valobj->GetCompilerType().IsReferenceType()) {
483 valobj = valobj->Dereference(error);
484 if (error.Fail())
485 return error.ToError();
486 }
487 return valobj;
488}
489
490llvm::Expected<lldb::ValueObjectSP>
493
494 lldb::ValueObjectSP identifier =
495 LookupIdentifier(node.GetName(), m_stack_frame, use_dynamic);
496
497 if (!identifier && m_allow_globals)
499 use_dynamic);
500
501 if (!identifier)
502 identifier = LookupEnumValue(node.GetName(), m_stack_frame);
503
504 if (!identifier && node.GetName()[0] == '$') {
505 auto language = GetSourceLanguageFromCU(m_stack_frame);
506 if (!language)
507 return language.takeError();
509 m_target, language.get());
510 }
511
512 if (!identifier && node.GetName() == "nullptr") {
513 // If we got a "nullptr" identifier, and there is no defined variable with
514 // this name, resolve it as a null pointer.
515 llvm::Expected<lldb::TypeSystemSP> type_system =
517 if (!type_system)
518 return type_system.takeError();
519 type_system.get()->GetPointerByteSize();
520 llvm::APInt value(type_system.get()->GetPointerByteSize() * CHAR_BIT, 0);
521 Scalar scalar(value);
524 "result");
525 }
526
527 if (!identifier) {
528 std::string errMsg =
529 llvm::formatv("use of undeclared identifier '{0}'", node.GetName());
530 return llvm::make_error<DILDiagnosticError>(
531 m_expr, errMsg, node.GetLocation(), node.GetName().size());
532 }
533
534 return identifier;
535}
536
537llvm::Expected<lldb::ValueObjectSP>
540 auto op_or_err = Evaluate(node.GetOperand());
541 if (!op_or_err)
542 return op_or_err;
543
544 lldb::ValueObjectSP operand = *op_or_err;
545
546 switch (node.GetKind()) {
547 case UnaryOpKind::Deref: {
548 lldb::ValueObjectSP dynamic_op = operand->GetDynamicValue(m_use_dynamic);
549 if (dynamic_op)
550 operand = dynamic_op;
551
552 lldb::ValueObjectSP child_sp = operand->Dereference(error);
553 if (!child_sp && m_use_synthetic) {
554 if (lldb::ValueObjectSP synth_obj_sp = operand->GetSyntheticValue()) {
555 error.Clear();
556 child_sp = synth_obj_sp->Dereference(error);
557 }
558 }
559 if (error.Fail())
560 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
561 node.GetLocation());
562
563 return child_sp;
564 }
565 case UnaryOpKind::AddrOf: {
567 lldb::ValueObjectSP value = operand->AddressOf(error);
568 if (error.Fail())
569 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
570 node.GetLocation());
571
572 return value;
573 }
574 case UnaryOpKind::Minus: {
575 if (operand->GetCompilerType().IsReferenceType()) {
576 operand = operand->Dereference(error);
577 if (error.Fail())
578 return error.ToError();
579 }
580 llvm::Expected<lldb::ValueObjectSP> conv_op =
581 UnaryConversion(operand, node.GetOperand().GetLocation());
582 if (!conv_op)
583 return conv_op;
584 operand = *conv_op;
585 CompilerType operand_type = operand->GetCompilerType();
586 if (!operand_type.IsScalarType()) {
587 std::string errMsg =
588 llvm::formatv("invalid argument type '{0}' to unary expression",
589 operand_type.GetTypeName());
590 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
591 node.GetLocation());
592 }
593 Scalar scalar;
594 bool resolved = operand->ResolveValue(scalar);
595 if (!resolved)
596 break;
597
598 bool negated = scalar.UnaryNegate();
599 if (negated)
601 m_stack_frame, scalar, operand->GetCompilerType(), "result");
602 break;
603 }
604 case UnaryOpKind::Plus: {
605 if (operand->GetCompilerType().IsReferenceType()) {
606 operand = operand->Dereference(error);
607 if (error.Fail())
608 return error.ToError();
609 }
610 llvm::Expected<lldb::ValueObjectSP> conv_op =
611 UnaryConversion(operand, node.GetOperand().GetLocation());
612 if (!conv_op)
613 return conv_op;
614 operand = *conv_op;
615 CompilerType operand_type = operand->GetCompilerType();
616 if (!operand_type.IsScalarType() &&
617 // Unary plus is allowed for pointers.
618 !operand_type.IsPointerType()) {
619 std::string errMsg =
620 llvm::formatv("invalid argument type '{0}' to unary expression",
621 operand_type.GetTypeName());
622 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
623 node.GetLocation());
624 }
625 return operand;
626 }
627 case UnaryOpKind::Not: {
628 if (operand->GetCompilerType().IsReferenceType()) {
629 operand = operand->Dereference(error);
630 if (error.Fail())
631 return error.ToError();
632 }
633 llvm::Expected<lldb::ValueObjectSP> conv_op =
634 UnaryConversion(operand, node.GetLocation());
635 if (!conv_op)
636 return conv_op;
637 operand = *conv_op;
638 CompilerType operand_type = operand->GetCompilerType();
639 if (!operand_type.IsInteger()) {
640 std::string errMsg =
641 llvm::formatv("invalid argument type '{0}' to unary expression",
642 operand_type.GetTypeName());
643 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
644 node.GetLocation());
645 }
646 Scalar scalar;
647 bool resolved = operand->ResolveValue(scalar);
648 if (!resolved) {
649 std::string errMsg = llvm::formatv("invalid operand value: {0}",
650 operand->GetError().AsCString());
651 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
652 node.GetLocation());
653 }
654
655 bool flipped = scalar.OnesComplement();
656 if (flipped)
658 m_stack_frame, scalar, operand->GetCompilerType(), "result");
659 break;
660 }
661 case UnaryOpKind::LNot: {
662 if (operand->GetCompilerType().IsReferenceType()) {
663 operand = operand->Dereference(error);
664 if (error.Fail())
665 return error.ToError();
666 }
667 CompilerType operand_type = operand->GetCompilerType();
668 if (!operand_type.IsContextuallyConvertibleToBool()) {
669 std::string errMsg =
670 llvm::formatv("invalid argument type '{0}' to unary expression",
671 operand_type.GetTypeName());
672 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
673 node.GetLocation());
674 }
675 llvm::Expected<lldb::TypeSystemSP> type_system =
677 if (!type_system)
678 return type_system.takeError();
679 auto value_or_err = operand->GetValueAsBool();
680 if (!value_or_err)
681 return value_or_err.takeError();
683 !(*value_or_err), "result");
684 }
685 }
686 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid unary operation",
687 node.GetLocation());
688}
689
690llvm::Expected<lldb::ValueObjectSP>
692 BinaryOpKind operation, uint32_t location) {
693 assert(operation == BinaryOpKind::Add || operation == BinaryOpKind::Sub);
694 if (ptr->GetCompilerType().IsPointerToVoid())
695 return llvm::make_error<DILDiagnosticError>(
696 m_expr, "arithmetic on a pointer to void", location);
697 if (ptr->GetValueAsUnsigned(0) == 0 && offset != 0)
698 return llvm::make_error<DILDiagnosticError>(
699 m_expr, "arithmetic on a nullptr is undefined", location);
700
701 bool success;
702 int64_t offset_int = offset->GetValueAsSigned(0, &success);
703 if (!success) {
704 std::string errMsg = llvm::formatv("could not get the offset: {0}",
705 offset->GetError().AsCString());
706 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
707 location);
708 }
709
710 llvm::Expected<uint64_t> byte_size =
711 ptr->GetCompilerType().GetPointeeType().GetByteSize(&m_stack_frame);
712 if (!byte_size)
713 return byte_size.takeError();
714 uint64_t ptr_addr = ptr->GetValueAsUnsigned(0);
715 if (operation == BinaryOpKind::Sub)
716 ptr_addr -= offset_int * (*byte_size);
717 else
718 ptr_addr += offset_int * (*byte_size);
719
720 ExecutionContext exe_ctx(m_target.get(), false);
721 Scalar scalar(ptr_addr);
723 m_stack_frame, scalar, ptr->GetCompilerType(), "result");
724}
725
726llvm::Expected<lldb::ValueObjectSP>
728 lldb::ValueObjectSP rhs, CompilerType result_type,
729 uint32_t location) {
730 Scalar l, r;
731 bool l_resolved = lhs->ResolveValue(l);
732 if (!l_resolved) {
733 std::string errMsg =
734 llvm::formatv("invalid lhs value: {0}", lhs->GetError().AsCString());
735 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
736 }
737 bool r_resolved = rhs->ResolveValue(r);
738 if (!r_resolved) {
739 std::string errMsg =
740 llvm::formatv("invalid rhs value: {0}", rhs->GetError().AsCString());
741 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
742 }
743
744 auto value_object = [this, result_type](Scalar scalar) {
746 result_type, "result");
747 };
748
749 switch (kind) {
751 return value_object(l + r);
753 return value_object(l - r);
755 return value_object(l * r);
757 return value_object(l / r);
759 return value_object(l % r);
761 return value_object(l & r);
763 return value_object(l ^ r);
764 case BinaryOpKind::Or:
765 return value_object(l | r);
767 return value_object(l << r);
769 return value_object(l >> r);
770 case BinaryOpKind::LT:
771 return value_object(l < r);
772 case BinaryOpKind::GT:
773 return value_object(l > r);
774 case BinaryOpKind::LE:
775 return value_object(l <= r);
776 case BinaryOpKind::GE:
777 return value_object(l >= r);
778 case BinaryOpKind::EQ:
779 return value_object(l == r);
780 case BinaryOpKind::NE:
781 return value_object(l != r);
782 default:
783 break;
784 }
785 return llvm::make_error<DILDiagnosticError>(
786 m_expr, "invalid arithmetic operation", location);
787}
788
789llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryAddition(
790 lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
791 // Operation '+' works for:
792 // {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
793 // {integer,unscoped_enum} <-> pointer
794 // pointer <-> {integer,unscoped_enum}
795 auto orig_lhs_type = lhs->GetCompilerType();
796 auto orig_rhs_type = rhs->GetCompilerType();
797 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
798 if (!type_or_err)
799 return type_or_err.takeError();
800 CompilerType result_type = *type_or_err;
801
802 if (result_type.IsScalarType())
803 return EvaluateScalarOp(BinaryOpKind::Add, lhs, rhs, result_type, location);
804
805 // Check for pointer arithmetics.
806 // One of the operands must be a pointer and the other one an integer.
807 lldb::ValueObjectSP ptr, offset;
808 if (lhs->GetCompilerType().IsPointerType()) {
809 ptr = lhs;
810 offset = rhs;
811 } else if (rhs->GetCompilerType().IsPointerType()) {
812 ptr = rhs;
813 offset = lhs;
814 }
815
816 if (!ptr || !offset->GetCompilerType().IsInteger()) {
817 std::string errMsg =
818 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
819 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
820 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
821 location);
822 }
823
824 return PointerOffset(ptr, offset, BinaryOpKind::Add, location);
825}
826
827llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinarySubtraction(
828 lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
829 // Operation '-' works for:
830 // {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
831 // pointer <-> {integer,unscoped_enum}
832 // pointer <-> pointer (if pointee types are compatible)
833 auto orig_lhs_type = lhs->GetCompilerType();
834 auto orig_rhs_type = rhs->GetCompilerType();
835 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
836 if (!type_or_err)
837 return type_or_err.takeError();
838 CompilerType result_type = *type_or_err;
839
840 if (result_type.IsScalarType())
841 return EvaluateScalarOp(BinaryOpKind::Sub, lhs, rhs, result_type, location);
842
843 auto lhs_type = lhs->GetCompilerType();
844 auto rhs_type = rhs->GetCompilerType();
845
846 // "pointer - integer" operation.
847 if (lhs_type.IsPointerType() && rhs_type.IsInteger())
848 return PointerOffset(lhs, rhs, BinaryOpKind::Sub, location);
849
850 // "pointer - pointer" operation.
851 if (lhs_type.IsPointerType() && rhs_type.IsPointerType()) {
852 if (lhs_type.IsPointerToVoid() && rhs_type.IsPointerToVoid()) {
853 return llvm::make_error<DILDiagnosticError>(
854 m_expr, "arithmetic on pointers to void", location);
855 }
856 // Compare canonical unqualified pointer types.
857 CompilerType lhs_unqualified_type = lhs_type.GetCanonicalType();
858 CompilerType rhs_unqualified_type = rhs_type.GetCanonicalType();
859 if (!lhs_unqualified_type.CompareTypes(rhs_unqualified_type)) {
860 std::string errMsg = llvm::formatv(
861 "'{0}' and '{1}' are not pointers to compatible types",
862 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
863 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
864 }
865
866 llvm::Expected<uint64_t> lhs_byte_size =
868 if (!lhs_byte_size)
869 return lhs_byte_size.takeError();
870 // Since pointers have compatible types, both have the same pointee size.
871 int64_t item_size = *lhs_byte_size;
872 int64_t diff = static_cast<int64_t>(lhs->GetValueAsUnsigned(0) -
873 rhs->GetValueAsUnsigned(0));
874 assert(item_size > 0 && "Pointee size cannot be 0");
875 if (diff % item_size != 0) {
876 // If address difference isn't divisible by pointee size then performing
877 // the operation is undefined behaviour.
878 return llvm::make_error<DILDiagnosticError>(
879 m_expr, "undefined pointer arithmetic", location);
880 }
881 diff /= item_size;
882
883 llvm::Expected<lldb::TypeSystemSP> type_system =
885 if (!type_system)
886 return type_system.takeError();
887 CompilerType ptrdiff_type = type_system.get()->GetPointerDiffType(true);
888 if (!ptrdiff_type)
889 return llvm::make_error<DILDiagnosticError>(
890 m_expr, "unable to determine pointer diff type", location);
891
892 Scalar scalar(diff);
894 ptrdiff_type, "result");
895 }
896
897 std::string errMsg =
898 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
899 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
900 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
901 location);
902}
903
904llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryMultiplication(
905 lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
906 // Operation '*' works for:
907 // {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
908 auto orig_lhs_type = lhs->GetCompilerType();
909 auto orig_rhs_type = rhs->GetCompilerType();
910 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
911 if (!type_or_err)
912 return type_or_err.takeError();
913 CompilerType result_type = *type_or_err;
914
915 if (!result_type.IsScalarType()) {
916 std::string errMsg =
917 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
918 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
919 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
920 location);
921 }
922
923 return EvaluateScalarOp(BinaryOpKind::Mul, lhs, rhs, result_type, location);
924}
925
926llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryDivision(
927 lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
928 // Operation '/' works for:
929 // {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
930 auto orig_lhs_type = lhs->GetCompilerType();
931 auto orig_rhs_type = rhs->GetCompilerType();
932 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
933 if (!type_or_err)
934 return type_or_err.takeError();
935 CompilerType result_type = *type_or_err;
936
937 if (!result_type.IsScalarType()) {
938 std::string errMsg =
939 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
940 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
941 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
942 location);
943 }
944
945 // Check for zero only for integer division.
946 if (result_type.IsInteger() && rhs->GetValueAsSigned(-1) == 0) {
947 return llvm::make_error<DILDiagnosticError>(
948 m_expr, "division by zero is undefined", location);
949 }
950
951 return EvaluateScalarOp(BinaryOpKind::Div, lhs, rhs, result_type, location);
952}
953
954llvm::Expected<lldb::ValueObjectSP> Interpreter::EvaluateBinaryRemainder(
955 lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location) {
956 // Operation '%' works for:
957 // {integer,unscoped_enum} <-> {integer,unscoped_enum}
958 auto orig_lhs_type = lhs->GetCompilerType();
959 auto orig_rhs_type = rhs->GetCompilerType();
960 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
961 if (!type_or_err)
962 return type_or_err.takeError();
963 CompilerType result_type = *type_or_err;
964
965 if (!result_type.IsInteger()) {
966 std::string errMsg =
967 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
968 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
969 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
970 location);
971 }
972
973 if (rhs->GetValueAsSigned(-1) == 0) {
974 return llvm::make_error<DILDiagnosticError>(
975 m_expr, "division by zero is undefined", location);
976 }
977
978 return EvaluateScalarOp(BinaryOpKind::Rem, lhs, rhs, result_type, location);
979}
980
982 return ct.GetTypeInfo() & lldb::eTypeIsFloat;
983}
984
985static llvm::Expected<bool> VerifyAssignmentTypes(CompilerType lhs_type,
986 CompilerType rhs_type) {
987 // Make sure lhs is a legal type for DIL assignment.
988 if (!lhs_type.IsInteger() && !lhs_type.IsUnscopedEnumerationType() &&
989 !HasFloatingRepresentation(lhs_type) && !lhs_type.IsPointerType() &&
990 !lhs_type.IsScalarType())
991 return llvm::createStringError(
992 "Illegal type for lhs of assignment (not scalar numeric type)");
993
994 // Make sure rhs is a legal type for DIL assignment.
995 if (!rhs_type.IsInteger() && !rhs_type.IsUnscopedEnumerationType() &&
996 !HasFloatingRepresentation(rhs_type) && !rhs_type.IsPointerType())
997 return llvm::createStringError(
998 "Illegal type for rhs of assignment (not scalar numeric type)");
999
1000 // Only allow assigning pointers to pointers.
1001 if ((lhs_type.IsPointerType() && !rhs_type.IsPointerType()) ||
1002 (!lhs_type.IsPointerType() && rhs_type.IsPointerType()))
1003 return llvm::createStringError(
1004 "Invalid assignment: Can only assign pointers to pointers");
1005
1006 // For "real numbers", the types must match exactly.
1007 if ((HasFloatingRepresentation(rhs_type) ||
1008 HasFloatingRepresentation(lhs_type)) &&
1009 lhs_type != rhs_type) {
1010 std::string err_msg =
1011 llvm::formatv("Incompatible types for assignment: Cannot assign {0} "
1012 "to {1}",
1013 rhs_type.TypeDescription(), lhs_type.TypeDescription());
1014 return llvm::createStringError(err_msg);
1015 }
1016
1017 return true;
1018}
1019
1020llvm::Expected<lldb::ValueObjectSP>
1022 lldb::ValueObjectSP rhs, uint32_t location) {
1023
1024 // Verify that lhs can accept an assignment.
1025 if (llvm::Error err = lhs->CanSetValue())
1026 return err;
1027
1028 auto all_ok =
1029 VerifyAssignmentTypes(lhs->GetCompilerType(), rhs->GetCompilerType());
1030 if (!all_ok)
1031 return all_ok.takeError();
1032
1033 if (llvm::Error e = lhs->SetValueFromInteger(rhs, m_allow_var_updates))
1034 return e;
1035
1036 return lhs;
1037}
1038
1039static bool IsLiteralZero(lldb::ValueObjectSP &val, bool is_literal) {
1040 bool is_zero = val->GetValueAsUnsigned(-1) == 0;
1041 bool is_boolean = val->GetCompilerType().IsBoolean();
1042 return is_zero && !is_boolean && is_literal;
1043}
1044
1045llvm::Error
1047 lldb::ValueObjectSP &rhs, bool lhs_is_literal,
1048 bool rhs_is_literal, uint32_t location) {
1049 auto orig_lhs_type = lhs->GetCompilerType();
1050 auto orig_rhs_type = rhs->GetCompilerType();
1051
1052 bool is_ordered = (kind == BinaryOpKind::LT || kind == BinaryOpKind::LE ||
1053 kind == BinaryOpKind::GT || kind == BinaryOpKind::GE);
1054 bool lhs_nullptr_or_zero =
1055 orig_lhs_type.IsNullPtrType() || IsLiteralZero(lhs, lhs_is_literal);
1056 bool rhs_nullptr_or_zero =
1057 orig_rhs_type.IsNullPtrType() || IsLiteralZero(rhs, rhs_is_literal);
1058
1059 if (orig_lhs_type.IsArrayType())
1060 lhs = ArrayToPointerConversion(*lhs, m_stack_frame, "result");
1061 if (orig_rhs_type.IsArrayType())
1062 rhs = ArrayToPointerConversion(*rhs, m_stack_frame, "result");
1063
1064 CompilerType lhs_type = lhs->GetCompilerType();
1065 CompilerType rhs_type = rhs->GetCompilerType();
1066
1067 if (lhs_type == rhs_type)
1068 return llvm::Error::success();
1069
1070 lldb::ValueObjectSP lhs_child;
1071 lldb::ValueObjectSP rhs_child;
1072 bool is_signed;
1073
1074 if (!lhs_nullptr_or_zero && !lhs_type.IsPointerType() &&
1075 !lhs_type.IsIntegerOrEnumerationType(is_signed)) {
1076 // lhs is not a nullptr, pointer, enum or integer. Check to see if its
1077 // first child could be a pointer. If so, update lhs_type accordingly.
1078 lhs_child = lhs->GetChildAtIndex(0);
1079 if (lhs_child && (lhs_child->IsPointerType() ||
1080 lhs_child->GetCompilerType().IsNullPtrType()))
1081 lhs_type = lhs_child->GetCompilerType();
1082 }
1083 if (!rhs_nullptr_or_zero && !rhs_type.IsPointerType() &&
1084 !rhs_type.IsIntegerOrEnumerationType(is_signed)) {
1085 // rhs is not a nullptr, pointer, enum or integer. Check to see if its
1086 // first child could be a pointer. If so, update rhs_type accordingly.
1087 rhs_child = rhs->GetChildAtIndex(0);
1088 if (rhs_child && (rhs_child->IsPointerType() ||
1089 rhs_child->GetCompilerType().IsNullPtrType()))
1090 rhs_type = rhs_child->GetCompilerType();
1091 }
1092
1093 if ((lhs_type != orig_lhs_type) || (rhs_type != orig_rhs_type)) {
1094 if (lhs_type.IsNullPtrType() || rhs_type.IsNullPtrType())
1095 return llvm::Error::success();
1096
1097 // May be an integer or enum.
1098 if (!lhs_type.IsPointerType() || !rhs_type.IsPointerType())
1099 return llvm::Error::success();
1100
1101 CompilerType lhs_unqualified =
1103 CompilerType rhs_unqualified =
1105
1106 if (lhs_unqualified.IsPointerToVoid() || rhs_unqualified.IsPointerToVoid())
1107 return llvm::Error::success();
1108
1109 // We have two pointers, neither of which is nullptr or void *. Make
1110 // sure their types are compatible.
1111 bool comparable = lhs_unqualified.CompareTypes(rhs_unqualified);
1112 if (comparable)
1113 return llvm::Error::success();
1114
1115 std::string errMsg = llvm::formatv(
1116 "comparison of distinct pointer types ({0} and {1})",
1117 orig_lhs_type.TypeDescription(), orig_rhs_type.TypeDescription());
1118 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
1119 }
1120
1121 if (!is_ordered && ((orig_lhs_type.IsNullPtrType() && rhs_nullptr_or_zero) ||
1122 (lhs_nullptr_or_zero && orig_rhs_type.IsNullPtrType())))
1123 return llvm::Error::success();
1124
1125 // If the operands has arithmetic or enumeration type (scoped or unscoped),
1126 // usual arithmetic conversions are performed on both operands following the
1127 // rules for arithmetic operators.
1128 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
1129 if (!type_or_err)
1130 return type_or_err.takeError();
1131
1132 lhs_type = lhs->GetCompilerType();
1133 rhs_type = rhs->GetCompilerType();
1134 if (lhs_type.IsScalarOrUnscopedEnumerationType() &&
1136 return llvm::Error::success();
1137
1138 // Scoped enums can be compared only to the instances of the same type.
1139 if (lhs_type.IsScopedEnumerationType() ||
1140 rhs_type.IsScopedEnumerationType()) {
1141 if (lhs_type.CompareTypes(rhs_type))
1142 return llvm::Error::success();
1143 std::string errMsg = llvm::formatv(
1144 "invalid operands to binary expression ({0} and {1})",
1145 orig_lhs_type.TypeDescription(), orig_rhs_type.TypeDescription());
1146 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
1147 }
1148
1149 // Check if the value can be compared to a pointer. We allow all pointers,
1150 // integers, unscoped enumerations and a `nullptr` literal if it's an
1151 // equality/inequality comparison, including comparing a pointer with an
1152 // integer representing an address. This also allows comparing `nullptr` and
1153 // any integer, not just literal zero, e.g. `nullptr == 1` is false.
1154 auto comparable_to_pointer = [&](CompilerType t) {
1155 return t.IsPointerType() || t.IsInteger() ||
1156 t.IsUnscopedEnumerationType() || (!is_ordered && t.IsNullPtrType());
1157 };
1158
1159 if ((lhs_type.IsPointerType() && comparable_to_pointer(rhs_type)) ||
1160 (comparable_to_pointer(lhs_type) && rhs_type.IsPointerType())) {
1161 // If both are pointers, check if they have comparable types.
1162 if ((lhs_type.IsPointerType() && !lhs_type.IsPointerToVoid()) &&
1163 (rhs_type.IsPointerType() && !rhs_type.IsPointerToVoid())) {
1164 // Compare canonical unqualified pointer types.
1165 CompilerType lhs_unqualified_type =
1167 CompilerType rhs_unqualified_type =
1169 bool comparable = lhs_unqualified_type.CompareTypes(rhs_unqualified_type);
1170
1171 if (!comparable) {
1172
1173 std::string errMsg = llvm::formatv(
1174 "comparison of distinct pointer types ({0} and {1})",
1175 orig_lhs_type.TypeDescription(), orig_rhs_type.TypeDescription());
1176 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
1177 }
1178 }
1179 // Comparing pointers to void is always allowed.
1180 return llvm::Error::success();
1181 }
1182
1183 std::string errMsg = llvm::formatv(
1184 "invalid operands to binary expression ({0} and {1})",
1185 orig_lhs_type.TypeDescription(), orig_rhs_type.TypeDescription());
1186 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
1187}
1188
1189llvm::Expected<lldb::ValueObjectSP>
1191 lldb::ValueObjectSP rhs, bool lhs_is_literal,
1192 bool rhs_is_literal, uint32_t location) {
1193 // Comparison works for:
1194 // nullptr_t <-> {nullptr_t,integer} (if integer is literal zero)
1195 // {nullptr_t,integer} <-> nullptr_t (if integer is literal zero)
1196 // {scalar,unscoped_enum} <-> {scalar,unscoped_enum}
1197 // scoped_enum <-> scoped_enum (if the same type)
1198 // pointer <-> pointer (if pointee types are compatible)
1199 // pointer <-> {integer,unscoped_enum,nullptr_t}
1200 // {integer,unscoped_enum,nullptr_t} <-> pointer
1201 if (auto error = ValidateComparison(kind, lhs, rhs, lhs_is_literal,
1202 rhs_is_literal, location))
1203 return error;
1204
1205 llvm::Expected<lldb::TypeSystemSP> type_system =
1207 if (!type_system)
1208 return type_system.takeError();
1209 CompilerType boolean_type = GetBasicType(*type_system, lldb::eBasicTypeBool);
1210
1211 return EvaluateScalarOp(kind, lhs, rhs, boolean_type, location);
1212}
1213
1214llvm::Expected<lldb::ValueObjectSP>
1216 lldb::ValueObjectSP rhs, uint32_t location) {
1217 // Operations {'&', '|', '^'} work for:
1218 // {integer,unscoped_enum} <-> {integer,unscoped_enum}
1219 auto orig_lhs_type = lhs->GetCompilerType();
1220 auto orig_rhs_type = rhs->GetCompilerType();
1221 auto type_or_err = ArithmeticConversion(lhs, rhs, location);
1222 if (!type_or_err)
1223 return type_or_err.takeError();
1224 CompilerType result_type = *type_or_err;
1225
1226 if (!result_type.IsInteger()) {
1227 std::string errMsg =
1228 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
1229 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
1230 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
1231 }
1232
1233 return EvaluateScalarOp(kind, lhs, rhs, result_type, location);
1234}
1235
1236llvm::Expected<lldb::ValueObjectSP>
1238 lldb::ValueObjectSP rhs, uint32_t location) {
1239 // Operations {'>>', '<<'} work for:
1240 // {integer,unscoped_enum} <-> {integer,unscoped_enum}
1241 CompilerType orig_lhs_type = lhs->GetCompilerType();
1242 CompilerType orig_rhs_type = rhs->GetCompilerType();
1243 auto lhs_or_err = UnaryConversion(lhs, location);
1244 if (!lhs_or_err)
1245 return lhs_or_err.takeError();
1246 lhs = *lhs_or_err;
1247 auto rhs_or_err = UnaryConversion(rhs, location);
1248 if (!rhs_or_err)
1249 return rhs_or_err.takeError();
1250 rhs = *rhs_or_err;
1251
1252 CompilerType lhs_type = lhs->GetCompilerType();
1253 CompilerType rhs_type = rhs->GetCompilerType();
1254 if (!lhs_type.IsInteger() || !rhs_type.IsInteger()) {
1255 std::string errMsg =
1256 llvm::formatv("invalid operands to binary expression ('{0}' and '{1}')",
1257 orig_lhs_type.GetTypeName(), orig_rhs_type.GetTypeName());
1258 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg, location);
1259 }
1260
1261 bool success;
1262 uint64_t amount = rhs->GetValueAsUnsigned(0, &success);
1263 if (!success)
1264 return llvm::make_error<DILDiagnosticError>(
1265 m_expr, "could not get the shift amount as an integer", location);
1266 llvm::Expected<uint64_t> lhs_size = lhs_type.GetBitSize(&m_stack_frame);
1267 if (!lhs_size)
1268 return lhs_size.takeError();
1269 if (amount >= *lhs_size)
1270 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid shift amount",
1271 location);
1272
1273 return EvaluateScalarOp(kind, lhs, rhs, lhs_type, location);
1274}
1275
1276llvm::Expected<lldb::ValueObjectSP>
1278 // Operations {'&&', '||'} work for:
1279 // {IsContextuallyConvertibleToBool} <-> {IsContextuallyConvertibleToBool}
1280 // Note: These operators will not evaluate or check the type of RHS
1281 // if the result is determined after evaluating LHS.
1282 auto lhs_or_err = EvaluateAndDereference(node.GetLHS());
1283 if (!lhs_or_err)
1284 return lhs_or_err;
1285 lldb::ValueObjectSP lhs = *lhs_or_err;
1286 auto lhs_type = lhs->GetCompilerType();
1287 if (!lhs_type.IsContextuallyConvertibleToBool()) {
1288 std::string errMsg = llvm::formatv(
1289 "value of type {0} is not contextually convertible to 'bool'",
1290 lhs_type.TypeDescription());
1291 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
1292 node.GetLocation());
1293 }
1294 llvm::Expected<lldb::TypeSystemSP> type_system =
1296 if (!type_system)
1297 return type_system.takeError();
1298
1299 // For "&&", exit early if LHS is "false"
1300 // For "||", exit early if LHS is "true".
1301 auto lvalue_or_err = lhs->GetValueAsBool();
1302 if (!lvalue_or_err)
1303 return lvalue_or_err.takeError();
1304 bool lhs_val = *lvalue_or_err;
1305 bool exit_early = node.GetKind() == BinaryOpKind::LAnd ? !lhs_val : lhs_val;
1306 if (exit_early)
1308 lhs_val, "result");
1309
1310 // If the result is to be determined, evaluate the RHS.
1311 auto rhs_or_err = EvaluateAndDereference(node.GetRHS());
1312 if (!rhs_or_err)
1313 return rhs_or_err;
1314 lldb::ValueObjectSP rhs = *rhs_or_err;
1315 auto rhs_type = rhs->GetCompilerType();
1316 if (!rhs_type.IsContextuallyConvertibleToBool()) {
1317 std::string errMsg = llvm::formatv(
1318 "value of type {0} is not contextually convertible to 'bool'",
1319 rhs_type.TypeDescription());
1320 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
1321 node.GetLocation());
1322 }
1323
1324 auto rvalue_or_err = rhs->GetValueAsBool();
1325 if (!rvalue_or_err)
1326 return rvalue_or_err.takeError();
1328 *rvalue_or_err, "result");
1329}
1330
1331llvm::Expected<lldb::ValueObjectSP>
1333 // Handle logical operators separately. They may or may not evaluate RHS.
1334 if (node.GetKind() == BinaryOpKind::LAnd ||
1335 node.GetKind() == BinaryOpKind::LOr)
1336 return EvaluateLogical(node);
1337
1338 auto lhs_or_err = EvaluateAndDereference(node.GetLHS());
1339 if (!lhs_or_err)
1340 return lhs_or_err;
1341 lldb::ValueObjectSP lhs = *lhs_or_err;
1342 auto rhs_or_err = EvaluateAndDereference(node.GetRHS());
1343 if (!rhs_or_err)
1344 return rhs_or_err;
1345 lldb::ValueObjectSP rhs = *rhs_or_err;
1346
1347 bool lhs_is_literal = node.GetLHS().IsConstLiteral();
1348 bool rhs_is_literal = node.GetRHS().IsConstLiteral();
1349 lldb::TypeSystemSP lhs_system =
1350 lhs->GetCompilerType().GetTypeSystem().GetSharedPointer();
1351 lldb::TypeSystemSP rhs_system =
1352 rhs->GetCompilerType().GetTypeSystem().GetSharedPointer();
1353 if (lhs_system->GetPluginName() != rhs_system->GetPluginName()) {
1354 // TODO: Attempt to convert values to current CU's type system
1355 return llvm::make_error<DILDiagnosticError>(
1356 m_expr, "operands have different type systems", node.GetLocation());
1357 }
1358
1359 switch (node.GetKind()) {
1361 return EvaluateAssignment(lhs, rhs, node.GetLocation());
1362 case BinaryOpKind::Add:
1363 return EvaluateBinaryAddition(lhs, rhs, node.GetLocation());
1364 case BinaryOpKind::Sub:
1365 return EvaluateBinarySubtraction(lhs, rhs, node.GetLocation());
1366 case BinaryOpKind::Mul:
1367 return EvaluateBinaryMultiplication(lhs, rhs, node.GetLocation());
1368 case BinaryOpKind::Div:
1369 return EvaluateBinaryDivision(lhs, rhs, node.GetLocation());
1370 case BinaryOpKind::Rem:
1371 return EvaluateBinaryRemainder(lhs, rhs, node.GetLocation());
1372 case BinaryOpKind::And:
1373 case BinaryOpKind::Xor:
1374 case BinaryOpKind::Or:
1375 return EvaluateBinaryBitwise(node.GetKind(), lhs, rhs, node.GetLocation());
1376 case BinaryOpKind::Shl:
1377 case BinaryOpKind::Shr:
1378 return EvaluateBinaryShift(node.GetKind(), lhs, rhs, node.GetLocation());
1380 auto ret_or_err = EvaluateBinaryAddition(lhs, rhs, node.GetLocation());
1381 if (!ret_or_err)
1382 return ret_or_err;
1383 return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
1384 }
1386 auto ret_or_err = EvaluateBinarySubtraction(lhs, rhs, node.GetLocation());
1387 if (!ret_or_err)
1388 return ret_or_err;
1389 return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
1390 }
1392 auto ret_or_err =
1393 EvaluateBinaryMultiplication(lhs, rhs, node.GetLocation());
1394 if (!ret_or_err)
1395 return ret_or_err;
1396 return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
1397 }
1399 auto ret_or_err = EvaluateBinaryDivision(lhs, rhs, node.GetLocation());
1400 if (!ret_or_err)
1401 return ret_or_err;
1402 return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
1403 }
1405 auto ret_or_err = EvaluateBinaryRemainder(lhs, rhs, node.GetLocation());
1406 if (!ret_or_err)
1407 return ret_or_err;
1408 return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
1409 }
1411 auto ret_or_err =
1413 if (!ret_or_err)
1414 return ret_or_err;
1415 return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
1416 }
1418 auto ret_or_err =
1420 if (!ret_or_err)
1421 return ret_or_err;
1422 return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
1423 }
1425 auto ret_or_err =
1427 if (!ret_or_err)
1428 return ret_or_err;
1429 return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
1430 }
1432 auto ret_or_err =
1434 if (!ret_or_err)
1435 return ret_or_err;
1436 return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
1437 }
1439 auto ret_or_err =
1441 if (!ret_or_err)
1442 return ret_or_err;
1443 return EvaluateAssignment(lhs, *ret_or_err, node.GetLocation());
1444 }
1445 case BinaryOpKind::EQ:
1446 case BinaryOpKind::NE:
1447 case BinaryOpKind::LT:
1448 case BinaryOpKind::LE:
1449 case BinaryOpKind::GT:
1450 case BinaryOpKind::GE:
1451 return EvaluateComparison(node.GetKind(), lhs, rhs, lhs_is_literal,
1452 rhs_is_literal, node.GetLocation());
1453 default:
1454 break;
1455 }
1456
1457 return llvm::make_error<DILDiagnosticError>(
1458 m_expr, "unimplemented binary operation", node.GetLocation());
1459}
1460
1461llvm::Expected<lldb::ValueObjectSP>
1463 auto base_or_err = Evaluate(node.GetBase());
1464 if (!base_or_err)
1465 return base_or_err;
1466 bool expr_is_ptr = node.GetIsArrow();
1467 lldb::ValueObjectSP base = *base_or_err;
1468
1469 // Perform some basic type & correctness checking.
1470 if (node.GetIsArrow()) {
1471 // If we have a non-pointer type with a synthetic value then lets check
1472 // if we have a synthetic dereference specified.
1473 if (!base->IsPointerType() && base->HasSyntheticValue()) {
1474 Status deref_error;
1475 if (lldb::ValueObjectSP synth_deref_sp =
1476 base->GetSyntheticValue()->Dereference(deref_error);
1477 synth_deref_sp && deref_error.Success()) {
1478 base = std::move(synth_deref_sp);
1479 }
1480 if (!base || deref_error.Fail()) {
1481 std::string errMsg = llvm::formatv(
1482 "Failed to dereference synthetic value: {0}", deref_error);
1483 return llvm::make_error<DILDiagnosticError>(
1484 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
1485 }
1486
1487 // Some synthetic plug-ins fail to set the error in Dereference
1488 if (!base) {
1489 std::string errMsg = "Failed to dereference synthetic value";
1490 return llvm::make_error<DILDiagnosticError>(
1491 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
1492 }
1493 expr_is_ptr = false;
1494 }
1495 }
1496
1498 bool base_is_ptr = base->IsPointerType();
1499
1500 if (expr_is_ptr != base_is_ptr) {
1501 if (base_is_ptr) {
1502 std::string errMsg =
1503 llvm::formatv("member reference type {0} is a pointer; "
1504 "did you mean to use '->'?",
1505 base->GetCompilerType().TypeDescription());
1506 return llvm::make_error<DILDiagnosticError>(
1507 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
1508 } else {
1509 std::string errMsg =
1510 llvm::formatv("member reference type {0} is not a pointer; "
1511 "did you mean to use '.'?",
1512 base->GetCompilerType().TypeDescription());
1513 return llvm::make_error<DILDiagnosticError>(
1514 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
1515 }
1516 }
1517 }
1518
1519 lldb::ValueObjectSP field_obj =
1520 base->GetChildMemberWithName(node.GetFieldName());
1521 if (!field_obj) {
1522 if (m_use_synthetic) {
1523 field_obj = base->GetSyntheticValue();
1524 if (field_obj)
1525 field_obj = field_obj->GetChildMemberWithName(node.GetFieldName());
1526 }
1527
1528 if (!m_use_synthetic || !field_obj) {
1529 std::string errMsg = llvm::formatv(
1530 "\"{0}\" is not a member of \"({1}) {2}\"", node.GetFieldName(),
1531 base->GetTypeName().AsCString("<invalid type>"), base->GetName());
1532 return llvm::make_error<DILDiagnosticError>(
1533 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
1534 }
1535 }
1536
1537 if (field_obj) {
1539 lldb::ValueObjectSP dynamic_val_sp =
1540 field_obj->GetDynamicValue(m_use_dynamic);
1541 if (dynamic_val_sp)
1542 field_obj = dynamic_val_sp;
1543 }
1544 return field_obj;
1545 }
1546
1547 CompilerType base_type = base->GetCompilerType();
1548 if (node.GetIsArrow() && base->IsPointerType())
1549 base_type = base_type.GetPointeeType();
1550 std::string errMsg = llvm::formatv(
1551 "\"{0}\" is not a member of \"({1}) {2}\"", node.GetFieldName(),
1552 base->GetTypeName().AsCString("<invalid type>"), base->GetName());
1553 return llvm::make_error<DILDiagnosticError>(
1554 m_expr, errMsg, node.GetLocation(), node.GetFieldName().size());
1555}
1556
1557llvm::Expected<lldb::ValueObjectSP>
1559 auto idx_or_err = EvaluateAndDereference(node.GetIndex());
1560 if (!idx_or_err)
1561 return idx_or_err;
1562 lldb::ValueObjectSP idx = *idx_or_err;
1563
1564 if (!idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType()) {
1565 return llvm::make_error<DILDiagnosticError>(
1566 m_expr, "array subscript is not an integer", node.GetLocation());
1567 }
1568
1569 StreamString var_expr_path_strm;
1570 uint64_t child_idx = idx->GetValueAsUnsigned(0);
1571 lldb::ValueObjectSP child_valobj_sp;
1572
1573 auto base_or_err = Evaluate(node.GetBase());
1574 if (!base_or_err)
1575 return base_or_err;
1576 lldb::ValueObjectSP base = *base_or_err;
1577
1578 CompilerType base_type = base->GetCompilerType().GetNonReferenceType();
1579 base->GetExpressionPath(var_expr_path_strm);
1580 bool is_incomplete_array = false;
1581 if (base_type.IsPointerType()) {
1582 bool is_objc_pointer = true;
1583
1584 if (base->GetCompilerType().GetMinimumLanguage() != lldb::eLanguageTypeObjC)
1585 is_objc_pointer = false;
1586 else if (!base->GetCompilerType().IsPointerType())
1587 is_objc_pointer = false;
1588
1589 if (!m_use_synthetic && is_objc_pointer) {
1590 std::string err_msg = llvm::formatv(
1591 "\"({0}) {1}\" is an Objective-C pointer, and cannot be subscripted",
1592 base->GetTypeName().AsCString("<invalid type>"),
1593 var_expr_path_strm.GetData());
1594 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1595 node.GetLocation());
1596 }
1597 if (is_objc_pointer) {
1598 lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
1599 if (!synthetic || synthetic == base) {
1600 std::string err_msg =
1601 llvm::formatv("\"({0}) {1}\" is not an array type",
1602 base->GetTypeName().AsCString("<invalid type>"),
1603 var_expr_path_strm.GetData());
1604 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1605 node.GetLocation());
1606 }
1607 if (static_cast<uint32_t>(child_idx) >=
1608 synthetic->GetNumChildrenIgnoringErrors()) {
1609 std::string err_msg = llvm::formatv(
1610 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
1611 base->GetTypeName().AsCString("<invalid type>"),
1612 var_expr_path_strm.GetData());
1613 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1614 node.GetLocation());
1615 }
1616 child_valobj_sp = synthetic->GetChildAtIndex(child_idx);
1617 if (!child_valobj_sp) {
1618 std::string err_msg = llvm::formatv(
1619 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
1620 base->GetTypeName().AsCString("<invalid type>"),
1621 var_expr_path_strm.GetData());
1622 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1623 node.GetLocation());
1624 }
1626 if (auto dynamic_sp = child_valobj_sp->GetDynamicValue(m_use_dynamic))
1627 child_valobj_sp = std::move(dynamic_sp);
1628 }
1629 return child_valobj_sp;
1630 }
1631
1632 child_valobj_sp = base->GetSyntheticArrayMember(child_idx, true);
1633 if (!child_valobj_sp) {
1634 std::string err_msg = llvm::formatv(
1635 "failed to use pointer as array for index {0} for "
1636 "\"({1}) {2}\"",
1637 child_idx, base->GetTypeName().AsCString("<invalid type>"),
1638 var_expr_path_strm.GetData());
1639 if (base_type.IsPointerToVoid())
1640 err_msg = "subscript of pointer to incomplete type 'void'";
1641 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1642 node.GetLocation());
1643 }
1644 } else if (base_type.IsArrayType(nullptr, nullptr, &is_incomplete_array)) {
1645 child_valobj_sp = base->GetChildAtIndex(child_idx);
1646 if (!child_valobj_sp && (is_incomplete_array || m_use_synthetic))
1647 child_valobj_sp = base->GetSyntheticArrayMember(child_idx, true);
1648 if (!child_valobj_sp) {
1649 std::string err_msg = llvm::formatv(
1650 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
1651 base->GetTypeName().AsCString("<invalid type>"),
1652 var_expr_path_strm.GetData());
1653 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1654 node.GetLocation());
1655 }
1656 } else if (base_type.IsScalarType()) {
1657 child_valobj_sp =
1658 base->GetSyntheticBitFieldChild(child_idx, child_idx, true);
1659 if (!child_valobj_sp) {
1660 std::string err_msg = llvm::formatv(
1661 "bitfield range {0}:{1} is not valid for \"({2}) {3}\"", child_idx,
1662 child_idx, base->GetTypeName().AsCString("<invalid type>"),
1663 var_expr_path_strm.GetData());
1664 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1665 node.GetLocation(), 1);
1666 }
1667 } else {
1668 lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
1669 if (!m_use_synthetic || !synthetic || synthetic == base) {
1670 std::string err_msg =
1671 llvm::formatv("\"{0}\" is not an array type",
1672 base->GetTypeName().AsCString("<invalid type>"));
1673 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1674 node.GetLocation(), 1);
1675 }
1676 if (static_cast<uint32_t>(child_idx) >=
1677 synthetic->GetNumChildrenIgnoringErrors(child_idx + 1)) {
1678 std::string err_msg = llvm::formatv(
1679 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
1680 base->GetTypeName().AsCString("<invalid type>"),
1681 var_expr_path_strm.GetData());
1682 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1683 node.GetLocation(), 1);
1684 }
1685 child_valobj_sp = synthetic->GetChildAtIndex(child_idx);
1686 if (!child_valobj_sp) {
1687 std::string err_msg = llvm::formatv(
1688 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
1689 base->GetTypeName().AsCString("<invalid type>"),
1690 var_expr_path_strm.GetData());
1691 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
1692 node.GetLocation(), 1);
1693 }
1694 }
1695
1696 if (child_valobj_sp) {
1698 if (auto dynamic_sp = child_valobj_sp->GetDynamicValue(m_use_dynamic))
1699 child_valobj_sp = std::move(dynamic_sp);
1700 }
1701 return child_valobj_sp;
1702 }
1703
1704 bool success;
1705 int64_t signed_child_idx = idx->GetValueAsSigned(0, &success);
1706 if (!success)
1707 return llvm::make_error<DILDiagnosticError>(
1708 m_expr, "could not get the index as an integer",
1709 node.GetIndex().GetLocation());
1710 return base->GetSyntheticArrayMember(signed_child_idx, true);
1711}
1712
1713llvm::Expected<lldb::ValueObjectSP>
1715 auto first_idx_or_err = EvaluateAndDereference(node.GetFirstIndex());
1716 if (!first_idx_or_err)
1717 return first_idx_or_err;
1718 lldb::ValueObjectSP first_idx = *first_idx_or_err;
1719 auto last_idx_or_err = EvaluateAndDereference(node.GetLastIndex());
1720 if (!last_idx_or_err)
1721 return last_idx_or_err;
1722 lldb::ValueObjectSP last_idx = *last_idx_or_err;
1723
1724 if (!first_idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType() ||
1725 !last_idx->GetCompilerType().IsIntegerOrUnscopedEnumerationType()) {
1726 return llvm::make_error<DILDiagnosticError>(
1727 m_expr, "bit index is not an integer", node.GetLocation());
1728 }
1729
1730 bool success_first, success_last;
1731 int64_t first_index = first_idx->GetValueAsSigned(0, &success_first);
1732 int64_t last_index = last_idx->GetValueAsSigned(0, &success_last);
1733 if (!success_first || !success_last)
1734 return llvm::make_error<DILDiagnosticError>(
1735 m_expr, "could not get the index as an integer", node.GetLocation());
1736
1737 // Reject negative indices before the swap below, so the diagnostic reports
1738 // the range as the user wrote it. A negative index would also wrap to a huge
1739 // offset in the uint32_t GetSyntheticBitFieldChild call below.
1740 if (first_index < 0 || last_index < 0) {
1741 std::string message =
1742 llvm::formatv("bitfield range {0}:{1} is not valid (negative index)",
1743 first_index, last_index);
1744 return llvm::make_error<DILDiagnosticError>(m_expr, message,
1745 node.GetLocation());
1746 }
1747
1748 // if the format given is [high-low], swap range
1749 if (first_index > last_index)
1750 std::swap(first_index, last_index);
1751
1752 // GetMaxU64Bitfield in the data layer only supports up to 64 bits (it asserts
1753 // bitfield_bit_size <= 64 and otherwise shifts out of bounds), so reject a
1754 // wider range here.
1755 if (last_index - first_index >= 64) {
1756 std::string message =
1757 llvm::formatv("bitfield range {0}:{1} is not valid (more than 64 bits)",
1758 first_index, last_index);
1759 return llvm::make_error<DILDiagnosticError>(m_expr, message,
1760 node.GetLocation());
1761 }
1762
1763 auto base_or_err = EvaluateAndDereference(node.GetBase());
1764 if (!base_or_err)
1765 return base_or_err;
1766 lldb::ValueObjectSP base = *base_or_err;
1767
1768 // The high index must lie within the base object's storage; a bit index past
1769 // its bit size shifts out of bounds when the child is later read or formatted
1770 // (GetMaxU64Bitfield).
1771 llvm::Expected<uint64_t> base_bit_size =
1772 base->GetCompilerType().GetBitSize(&m_stack_frame);
1773 if (!base_bit_size)
1774 return base_bit_size.takeError();
1775 if (static_cast<uint64_t>(last_index) >= *base_bit_size) {
1776 std::string message = llvm::formatv(
1777 "bitfield range {0}:{1} is not valid for \"({2}) {3}\"", first_index,
1778 last_index, base->GetTypeName().AsCString("<invalid type>"),
1779 base->GetName().GetStringRef());
1780 return llvm::make_error<DILDiagnosticError>(m_expr, message,
1781 node.GetLocation());
1782 }
1783
1784 lldb::ValueObjectSP child_valobj_sp =
1785 base->GetSyntheticBitFieldChild(first_index, last_index, true);
1786 if (!child_valobj_sp) {
1787 std::string message = llvm::formatv(
1788 "bitfield range {0}:{1} is not valid for \"({2}) {3}\"", first_index,
1789 last_index, base->GetTypeName().AsCString("<invalid type>"),
1790 base->GetName().GetStringRef());
1791 return llvm::make_error<DILDiagnosticError>(m_expr, message,
1792 node.GetLocation());
1793 }
1794 return child_valobj_sp;
1795}
1796
1797llvm::Expected<CompilerType>
1800 const IntegerLiteralNode &literal) {
1801 // Binary, Octal, Hexadecimal and literals with a U suffix are allowed to be
1802 // an unsigned integer.
1803 bool unsigned_is_allowed = literal.IsUnsigned() || literal.GetRadix() != 10;
1804 llvm::APInt apint = literal.GetValue();
1805
1806 llvm::SmallVector<std::pair<lldb::BasicType, lldb::BasicType>, 3> candidates;
1807 if (literal.GetTypeSuffix() <= IntegerTypeSuffix::None)
1808 candidates.emplace_back(lldb::eBasicTypeInt,
1809 unsigned_is_allowed ? lldb::eBasicTypeUnsignedInt
1811 if (literal.GetTypeSuffix() <= IntegerTypeSuffix::Long)
1812 candidates.emplace_back(lldb::eBasicTypeLong,
1813 unsigned_is_allowed ? lldb::eBasicTypeUnsignedLong
1815 candidates.emplace_back(lldb::eBasicTypeLongLong,
1817 for (auto [signed_, unsigned_] : candidates) {
1818 CompilerType signed_type = type_system->GetBasicTypeFromAST(signed_);
1819 if (!signed_type)
1820 continue;
1821 llvm::Expected<uint64_t> size = signed_type.GetBitSize(&ctx);
1822 if (!size)
1823 return size.takeError();
1824 if (!literal.IsUnsigned() && apint.isIntN(*size - 1))
1825 return signed_type;
1826 if (unsigned_ != lldb::eBasicTypeInvalid && apint.isIntN(*size))
1827 return type_system->GetBasicTypeFromAST(unsigned_);
1828 }
1829
1830 return llvm::make_error<DILDiagnosticError>(
1831 m_expr,
1832 "integer literal is too large to be represented in any integer type",
1833 literal.GetLocation());
1834}
1835
1836llvm::Expected<lldb::ValueObjectSP>
1838 llvm::Expected<lldb::TypeSystemSP> type_system =
1840 if (!type_system)
1841 return type_system.takeError();
1842
1843 llvm::Expected<CompilerType> type =
1844 PickIntegerType(*type_system, m_stack_frame, node);
1845 if (!type)
1846 return type.takeError();
1847
1848 Scalar scalar = node.GetValue();
1849 // APInt from StringRef::getAsInteger comes with just enough bitwidth to
1850 // hold the value. This adjusts APInt bitwidth to match the compiler type.
1851 llvm::Expected<uint64_t> type_bitsize = type->GetBitSize(&m_stack_frame);
1852 if (!type_bitsize)
1853 return type_bitsize.takeError();
1854 // Literal itself cannot be a negative value, so we do an unsigned extension.
1855 scalar.TruncOrExtendTo(*type_bitsize, false);
1856 // If the picked compiler type is signed, make the scalar signed as well.
1857 if (type->IsSigned())
1858 scalar.MakeSigned();
1860 "result");
1861}
1862
1863llvm::Expected<lldb::ValueObjectSP>
1865 llvm::Expected<lldb::TypeSystemSP> type_system =
1867 if (!type_system)
1868 return type_system.takeError();
1869
1870 bool isFloat =
1871 &node.GetValue().getSemantics() == &llvm::APFloat::IEEEsingle();
1872 lldb::BasicType basic_type =
1874 CompilerType type = GetBasicType(*type_system, basic_type);
1875
1876 if (!type)
1877 return llvm::make_error<DILDiagnosticError>(
1878 m_expr, "unable to create a const literal", node.GetLocation());
1879
1880 Scalar scalar = node.GetValue();
1882 "result");
1883}
1884
1885llvm::Expected<lldb::ValueObjectSP>
1887 bool value = node.GetValue();
1888 llvm::Expected<lldb::TypeSystemSP> type_system =
1890 if (!type_system)
1891 return type_system.takeError();
1893 value, "result");
1894}
1895
1896llvm::Expected<CastKind>
1898 CompilerType target_type, int location) {
1899 if (source_type.IsPointerType() || source_type.IsNullPtrType()) {
1900 // Cast from pointer to float/double is not allowed.
1901 if (target_type.GetTypeInfo() & lldb::eTypeIsFloat) {
1902 std::string errMsg = llvm::formatv("Cast from {0} to {1} is not allowed",
1903 source_type.TypeDescription(),
1904 target_type.TypeDescription());
1905 return llvm::make_error<DILDiagnosticError>(
1906 m_expr, std::move(errMsg), location,
1907 source_type.TypeDescription().length());
1908 }
1909
1910 // Casting from pointer to bool is always valid.
1911 if (target_type.IsBoolean())
1912 return CastKind::eArithmetic;
1913
1914 // Otherwise check if the result type is at least as big as the pointer
1915 // size.
1916 uint64_t type_byte_size = 0;
1917 uint64_t rhs_type_byte_size = 0;
1918 if (auto temp = target_type.GetByteSize(&m_stack_frame)) {
1919 type_byte_size = *temp;
1920 } else {
1921 std::string errMsg = llvm::formatv("unable to get byte size for type {0}",
1922 target_type.TypeDescription());
1923 LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), temp.takeError(),
1924 "GetByteSize failed: {0}");
1925 return llvm::make_error<DILDiagnosticError>(
1926 m_expr, std::move(errMsg), location,
1927 target_type.TypeDescription().length());
1928 }
1929
1930 if (auto temp = source_type.GetByteSize(&m_stack_frame)) {
1931 rhs_type_byte_size = *temp;
1932 } else {
1933 std::string errMsg = llvm::formatv("unable to get byte size for type {0}",
1934 source_type.TypeDescription());
1935 LLDB_LOG_ERROR(GetLog(LLDBLog::Expressions), temp.takeError(),
1936 "GetByteSize failed: {0}");
1937 return llvm::make_error<DILDiagnosticError>(
1938 m_expr, std::move(errMsg), location,
1939 source_type.TypeDescription().length());
1940 }
1941
1942 if (type_byte_size < rhs_type_byte_size) {
1943 std::string errMsg = llvm::formatv(
1944 "cast from pointer to smaller type {0} loses information",
1945 target_type.TypeDescription());
1946 return llvm::make_error<DILDiagnosticError>(
1947 m_expr, std::move(errMsg), location,
1948 source_type.TypeDescription().length());
1949 }
1950 } else if (!source_type.IsScalarType() && !source_type.IsEnumerationType()) {
1951 // Otherwise accept only arithmetic types and enums.
1952 std::string errMsg = llvm::formatv("cannot convert {0} to {1}",
1953 source_type.TypeDescription(),
1954 target_type.TypeDescription());
1955
1956 return llvm::make_error<DILDiagnosticError>(
1957 m_expr, std::move(errMsg), location,
1958 source_type.TypeDescription().length());
1959 }
1960 return CastKind::eArithmetic;
1961}
1962
1963llvm::Expected<CastKind>
1965 CompilerType source_type, CompilerType target_type,
1966 int location) {
1967
1968 if (target_type.IsScalarType())
1969 return VerifyArithmeticCast(source_type, target_type, location);
1970
1971 if (target_type.IsEnumerationType()) {
1972 // Cast to enum type.
1973 if (!source_type.IsScalarType() && !source_type.IsEnumerationType()) {
1974 std::string errMsg = llvm::formatv("Cast from {0} to {1} is not allowed",
1975 source_type.TypeDescription(),
1976 target_type.TypeDescription());
1977
1978 return llvm::make_error<DILDiagnosticError>(
1979 m_expr, std::move(errMsg), location,
1980 source_type.TypeDescription().length());
1981 }
1983 }
1984
1985 if (target_type.IsPointerType()) {
1986 if (!source_type.IsInteger() && !source_type.IsEnumerationType() &&
1987 !source_type.IsArrayType() && !source_type.IsPointerType() &&
1988 !source_type.IsNullPtrType()) {
1989 std::string errMsg = llvm::formatv(
1990 "cannot cast from type {0} to pointer type {1}",
1991 source_type.TypeDescription(), target_type.TypeDescription());
1992
1993 return llvm::make_error<DILDiagnosticError>(
1994 m_expr, std::move(errMsg), location,
1995 source_type.TypeDescription().length());
1996 }
1997 return CastKind::ePointer;
1998 }
1999
2000 // Unsupported cast.
2001 std::string errMsg = llvm::formatv(
2002 "casting of {0} to {1} is not implemented yet",
2003 source_type.TypeDescription(), target_type.TypeDescription());
2004 return llvm::make_error<DILDiagnosticError>(
2005 m_expr, std::move(errMsg), location,
2006 source_type.TypeDescription().length());
2007}
2008
2009llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const CastNode &node) {
2010 auto operand_or_err = Evaluate(node.GetOperand());
2011
2012 if (!operand_or_err)
2013 return operand_or_err;
2014
2015 lldb::ValueObjectSP operand = *operand_or_err;
2016 CompilerType op_type = operand->GetCompilerType();
2017 CompilerType target_type = node.GetType();
2018
2019 if (op_type.IsReferenceType())
2020 op_type = op_type.GetNonReferenceType();
2021 if (target_type.IsScalarType() && op_type.IsArrayType()) {
2022 operand = ArrayToPointerConversion(*operand, m_stack_frame,
2023 operand->GetName().GetStringRef());
2024 op_type = operand->GetCompilerType();
2025 }
2026 auto type_or_err =
2027 VerifyCastType(operand, op_type, target_type, node.GetLocation());
2028 if (!type_or_err)
2029 return type_or_err.takeError();
2030
2031 CastKind cast_kind = *type_or_err;
2032 if (operand->GetCompilerType().IsReferenceType()) {
2033 Status error;
2034 operand = operand->Dereference(error);
2035 if (error.Fail())
2036 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
2037 node.GetLocation());
2038 }
2039
2040 lldb::ValueObjectSP result;
2041 switch (cast_kind) {
2043 // FIXME: is this correct for float vector types?
2044 if (op_type.GetTypeInfo() & lldb::eTypeIsFloat || op_type.IsInteger() ||
2045 op_type.IsEnumerationType())
2046 result = operand->CastToEnumType(target_type);
2047 break;
2048 }
2049 case CastKind::eArithmetic: {
2050 if (op_type.IsPointerType() || op_type.IsNullPtrType() ||
2051 op_type.IsScalarType() || op_type.IsEnumerationType())
2052 result = operand->CastToBasicType(target_type);
2053 break;
2054 }
2055 case CastKind::ePointer: {
2056 uint64_t addr = op_type.IsArrayType()
2057 ? operand->GetLoadAddress()
2058 : (op_type.IsSigned() ? operand->GetValueAsSigned(0)
2059 : operand->GetValueAsUnsigned(0));
2060 llvm::StringRef name = "result";
2061 ExecutionContext exe_ctx(m_target.get(), false);
2062 result = ValueObject::CreateValueObjectFromAddress(name, addr, exe_ctx,
2063 target_type,
2064 /* do_deref */ false);
2065 break;
2066 }
2067 case CastKind::eNone: {
2068 return lldb::ValueObjectSP();
2069 }
2070 } // switch
2071
2072 if (result) {
2073 // If cast failed, retrieve the error message from the result.
2074 if (result->GetError().Fail())
2075 return llvm::make_error<DILDiagnosticError>(
2076 m_expr, result->GetError().AsCString(), node.GetLocation());
2077 return result;
2078 }
2079
2080 std::string errMsg =
2081 llvm::formatv("unable to cast from '{0}' to '{1}'",
2082 op_type.TypeDescription(), target_type.TypeDescription());
2083 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(errMsg),
2084 node.GetLocation());
2085}
2086
2087llvm::Expected<lldb::ValueObjectSP>
2089 auto cond_or_err = EvaluateAndDereference(node.GetCondition());
2090 if (!cond_or_err)
2091 return cond_or_err;
2092 lldb::ValueObjectSP condition = *cond_or_err;
2093
2094 CompilerType cond_type = condition->GetCompilerType();
2095 if (!cond_type.IsContextuallyConvertibleToBool()) {
2096 std::string errMsg = llvm::formatv(
2097 "value of type {0} is not contextually convertible to 'bool'",
2098 cond_type.TypeDescription());
2099 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
2100 node.GetLocation());
2101 }
2102 // Note: DIL evaluates only the operand chosen by the condition,
2103 // and doesn't check the type or evaluate the other operand.
2104 auto value_or_err = condition->GetValueAsBool();
2105 if (value_or_err) {
2106 if (*value_or_err) {
2107 auto true_or_err = EvaluateAndDereference(node.GetTrueOperand());
2108 if (!true_or_err)
2109 return true_or_err;
2110 return *true_or_err;
2111 }
2112 auto false_or_err = EvaluateAndDereference(node.GetFalseOperand());
2113 if (!false_or_err)
2114 return false_or_err;
2115 return *false_or_err;
2116 }
2117 return value_or_err.takeError();
2118}
2119
2120llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const SizeOfNode &node) {
2121 CompilerType typearg = node.GetTypeArg();
2122 Scalar size;
2123 if (typearg.IsValid()) {
2124 if (typearg.IsReferenceType())
2125 typearg = typearg.GetNonReferenceType();
2126 llvm::Expected<uint64_t> byte_size = typearg.GetByteSize(m_target.get());
2127 if (!byte_size)
2128 return byte_size.takeError();
2129 size = *byte_size;
2130 } else {
2131 auto arg_or_err = EvaluateAndDereference(node.GetNodeArg());
2132 if (!arg_or_err)
2133 return arg_or_err;
2134 lldb::ValueObjectSP arg = *arg_or_err;
2135
2136 if (arg->IsBitfield())
2137 return llvm::make_error<DILDiagnosticError>(
2138 m_expr, "invalid application of 'sizeof' to bit-field",
2139 node.GetLocation());
2140
2141 llvm::Expected<uint64_t> byte_size = arg->GetByteSize();
2142 if (!byte_size)
2143 return byte_size.takeError();
2144 size = *byte_size;
2145 }
2146
2147 llvm::Expected<lldb::TypeSystemSP> type_system =
2149 if (!type_system)
2150 return type_system.takeError();
2151 CompilerType size_type = type_system.get()->GetSizeType();
2152 if (!size_type)
2153 return llvm::make_error<DILDiagnosticError>(
2154 m_expr, "unable to determine size type", node.GetLocation());
2155
2157 size_type, "result");
2158}
2159
2160} // 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
bool IsScalarOrUnscopedEnumerationType() const
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
bool IsContextuallyConvertibleToBool() const
This may only be defined in TypeSystemClang.
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.
bool IsIntegerOrEnumerationType(bool &is_signed) const
bool IsScopedEnumerationType() const
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 GetFullyUnqualifiedType() const
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:205
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:105
uint32_t GetLocation() const
Definition DILAST.h:115
virtual bool IsConstLiteral() const
Definition DILAST.h:113
virtual llvm::Expected< lldb::ValueObjectSP > Accept(Visitor *v) const =0
ASTNode & GetLHS() const
Definition DILAST.h:205
BinaryOpKind GetKind() const
Definition DILAST.h:204
ASTNode & GetRHS() const
Definition DILAST.h:206
ASTNode & GetOperand() const
Definition DILAST.h:338
CompilerType GetType() const
Definition DILAST.h:337
ASTNode & GetFalseOperand() const
Definition DILAST.h:363
ASTNode & GetTrueOperand() const
Definition DILAST.h:362
ASTNode & GetCondition() const
Definition DILAST.h:361
const llvm::APFloat & GetValue() const
Definition DILAST.h:300
std::string GetName() const
Definition DILAST.h:142
IntegerTypeSuffix GetTypeSuffix() const
Definition DILAST.h:278
const llvm::APInt & GetValue() const
Definition DILAST.h:275
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryRemainder(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:954
llvm::Error ValidateComparison(BinaryOpKind kind, lldb::ValueObjectSP &lhs, lldb::ValueObjectSP &rhs, bool lhs_is_literal, bool rhs_is_literal, uint32_t location)
Definition DILEval.cpp:1046
llvm::Expected< lldb::ValueObjectSP > Evaluate(const ASTNode &node)
Evaluate an ASTNode.
Definition DILEval.cpp:462
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryAddition(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:789
llvm::Expected< lldb::ValueObjectSP > EvaluateAndDereference(const ASTNode &node)
Evaluate an ASTNode.
Definition DILEval.cpp:475
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:691
llvm::Expected< lldb::ValueObjectSP > EvaluateScalarOp(BinaryOpKind kind, lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, CompilerType result_type, uint32_t location)
Definition DILEval.cpp:727
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:204
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryShift(BinaryOpKind kind, lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:1237
llvm::Expected< lldb::ValueObjectSP > EvaluateLogical(const BinaryOpNode &node)
Definition DILEval.cpp:1277
llvm::Expected< lldb::ValueObjectSP > EvaluateBinarySubtraction(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:827
llvm::Expected< lldb::ValueObjectSP > UnaryConversion(lldb::ValueObjectSP valobj, uint32_t location)
Perform usual unary conversions on a value.
Definition DILEval.cpp:73
llvm::Expected< lldb::ValueObjectSP > EvaluateComparison(BinaryOpKind kind, lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, bool lhs_is_literal, bool rhs_is_literal, uint32_t location)
Definition DILEval.cpp:1190
llvm::Expected< lldb::ValueObjectSP > Visit(const IdentifierNode &node) override
Definition DILEval.cpp:491
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryDivision(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:926
lldb::DynamicValueType m_use_dynamic
Definition DILEval.h:179
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:231
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryMultiplication(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:904
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:1964
Interpreter(lldb::TargetSP target, llvm::StringRef expr, StackFrame &stack_frame, lldb::DynamicValueType use_dynamic, uint32_t options)
Definition DILEval.cpp:441
llvm::Expected< CompilerType > PickIntegerType(lldb::TypeSystemSP type_system, ExecutionContextScope &ctx, const IntegerLiteralNode &literal)
Definition DILEval.cpp:1798
llvm::Expected< lldb::ValueObjectSP > EvaluateAssignment(lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:1021
llvm::Expected< CastKind > VerifyArithmeticCast(CompilerType source_type, CompilerType target_type, int location)
A helper function for VerifyCastType (below).
Definition DILEval.cpp:1897
llvm::Expected< lldb::ValueObjectSP > EvaluateBinaryBitwise(BinaryOpKind kind, lldb::ValueObjectSP lhs, lldb::ValueObjectSP rhs, uint32_t location)
Definition DILEval.cpp:1215
llvm::StringRef GetFieldName() const
Definition DILAST.h:163
ASTNode & GetBase() const
Definition DILAST.h:161
ASTNode & GetNodeArg() const
Definition DILAST.h:385
CompilerType GetTypeArg() const
Definition DILAST.h:386
UnaryOpKind GetKind() const
Definition DILAST.h:183
ASTNode & GetOperand() const
Definition DILAST.h:184
CastKind
The type casts allowed by DIL.
Definition DILAST.h:84
@ eEnumeration
Casting from a scalar to an enumeration type.
Definition DILAST.h:86
@ ePointer
Casting to a pointer type.
Definition DILAST.h:87
@ eNone
Invalid promotion type (results in error).
Definition DILAST.h:88
@ eArithmetic
Casting to a scalar.
Definition DILAST.h:85
lldb::ValueObjectSP LookupPersistentIdentifier(llvm::StringRef name_ref, StackFrame &stack_frame, lldb::TargetSP target_sp, lldb::LanguageType language)
Given the name of a persistent identifier (i.e., one that starts with a $), find the ValueObject for ...
Definition DILEval.cpp:354
static lldb::BasicType BasicTypeToUnsigned(lldb::BasicType basic_type)
Definition DILEval.cpp:183
static bool IsLiteralZero(lldb::ValueObjectSP &val, bool is_literal)
Definition DILEval.cpp:1039
static llvm::Expected< lldb::TypeSystemSP > GetTypeSystemFromCU(StackFrame &ctx)
Definition DILEval.cpp:60
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:368
static CompilerType GetBasicType(lldb::TypeSystemSP type_system, lldb::BasicType basic_type)
Definition DILEval.cpp:29
static lldb::ValueObjectSP ArrayToPointerConversion(ValueObject &valobj, ExecutionContextScope &ctx, llvm::StringRef name)
Definition DILEval.cpp:37
BinaryOpKind
The binary operators recognized by DIL.
Definition DILAST.h:48
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:312
static llvm::Expected< bool > VerifyAssignmentTypes(CompilerType lhs_type, CompilerType rhs_type)
Definition DILEval.cpp:985
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:416
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:146
static lldb::VariableSP DILFindVariable(ConstString name, VariableList &variable_list)
Definition DILEval.cpp:287
CompilerType ResolveTypeByName(const std::string &name, ExecutionContextScope &ctx_scope)
Definition DILParser.cpp:62
static bool HasFloatingRepresentation(CompilerType ct)
Definition DILEval.cpp:981
static llvm::Expected< lldb::LanguageType > GetSourceLanguageFromCU(StackFrame &ctx)
Definition DILEval.cpp:50
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),...