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