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
24static llvm::Expected<lldb::TypeSystemSP>
25GetTypeSystemFromCU(std::shared_ptr<ExecutionContextScope> ctx) {
26 auto stack_frame = ctx->CalculateStackFrame();
27 if (!stack_frame)
28 return llvm::createStringError("no stack frame in this context");
29 SymbolContext symbol_context =
30 stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
31 lldb::LanguageType language = symbol_context.comp_unit->GetLanguage();
32
33 symbol_context = stack_frame->GetSymbolContext(lldb::eSymbolContextModule);
34 return symbol_context.module_sp->GetTypeSystemForLanguage(language);
35}
36
38 lldb::BasicType basic_type) {
39 if (type_system)
40 return type_system.get()->GetBasicTypeFromAST(basic_type);
41
42 return CompilerType();
43}
44
47 uint64_t addr = valobj.GetLoadAddress();
48 ExecutionContext exe_ctx;
49 ctx.CalculateExecutionContext(exe_ctx);
51 "result", addr, exe_ctx,
53 /* do_deref */ false);
54}
55
56llvm::Expected<lldb::ValueObjectSP>
58 if (!valobj)
59 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
60 location);
61 llvm::Expected<lldb::TypeSystemSP> type_system =
63 if (!type_system)
64 return type_system.takeError();
65
66 CompilerType in_type = valobj->GetCompilerType();
67 if (valobj->IsBitfield()) {
68 // Promote bitfields. If `int` can represent the bitfield value, it is
69 // converted to `int`. Otherwise, if `unsigned int` can represent it, it
70 // is converted to `unsigned int`. Otherwise, it is treated as its
71 // underlying type.
72 uint32_t bitfield_size = valobj->GetBitfieldBitSize();
73 // Some bitfields have undefined size (e.g. result of ternary operation).
74 // The AST's `bitfield_size` of those is 0, and no promotion takes place.
75 if (bitfield_size > 0 && in_type.IsInteger()) {
76 CompilerType int_type = GetBasicType(*type_system, lldb::eBasicTypeInt);
77 CompilerType uint_type =
79 llvm::Expected<uint64_t> int_bit_size =
80 int_type.GetBitSize(m_exe_ctx_scope.get());
81 if (!int_bit_size)
82 return int_bit_size.takeError();
83 llvm::Expected<uint64_t> uint_bit_size =
84 uint_type.GetBitSize(m_exe_ctx_scope.get());
85 if (!uint_bit_size)
86 return int_bit_size.takeError();
87 if (bitfield_size < *int_bit_size ||
88 (in_type.IsSigned() && bitfield_size == *int_bit_size))
89 return valobj->CastToBasicType(int_type);
90 if (bitfield_size <= *uint_bit_size)
91 return valobj->CastToBasicType(uint_type);
92 // Re-create as a const value with the same underlying type
93 Scalar scalar;
94 bool resolved = valobj->ResolveValue(scalar);
95 if (!resolved)
96 return llvm::createStringError("invalid scalar value");
98 "result");
99 }
100 }
101
102 if (in_type.IsArrayType())
103 valobj = ArrayToPointerConversion(*valobj, *m_exe_ctx_scope);
104
105 if (valobj->GetCompilerType().IsInteger() ||
106 valobj->GetCompilerType().IsUnscopedEnumerationType()) {
107 llvm::Expected<CompilerType> promoted_type =
108 type_system.get()->DoIntegralPromotion(valobj->GetCompilerType(),
109 m_exe_ctx_scope.get());
110 if (!promoted_type)
111 return promoted_type.takeError();
112 if (!promoted_type->CompareTypes(valobj->GetCompilerType()))
113 return valobj->CastToBasicType(*promoted_type);
114 }
115
116 return valobj;
117}
118
120 VariableList &variable_list) {
121 lldb::VariableSP exact_match;
122 std::vector<lldb::VariableSP> possible_matches;
123
124 for (lldb::VariableSP var_sp : variable_list) {
125 llvm::StringRef str_ref_name = var_sp->GetName().GetStringRef();
126
127 str_ref_name.consume_front("::");
128 // Check for the exact same match
129 if (str_ref_name == name.GetStringRef())
130 return var_sp;
131
132 // Check for possible matches by base name
133 if (var_sp->NameMatches(name))
134 possible_matches.push_back(var_sp);
135 }
136
137 // If there's a non-exact match, take it.
138 if (possible_matches.size() > 0)
139 return possible_matches[0];
140
141 return nullptr;
142}
143
145 llvm::StringRef name_ref, std::shared_ptr<StackFrame> stack_frame,
146 lldb::TargetSP target_sp, lldb::DynamicValueType use_dynamic) {
147 // Get a global variables list without the locals from the current frame
148 SymbolContext symbol_context =
149 stack_frame->GetSymbolContext(lldb::eSymbolContextCompUnit);
150 lldb::VariableListSP variable_list;
151 if (symbol_context.comp_unit)
152 variable_list = symbol_context.comp_unit->GetVariableList(true);
153
154 name_ref.consume_front("::");
155 lldb::ValueObjectSP value_sp;
156 if (variable_list) {
157 lldb::VariableSP var_sp =
158 DILFindVariable(ConstString(name_ref), *variable_list);
159 if (var_sp)
160 value_sp =
161 stack_frame->GetValueObjectForFrameVariable(var_sp, use_dynamic);
162 }
163
164 if (value_sp)
165 return value_sp;
166
167 // Check for match in modules global variables.
168 VariableList modules_var_list;
169 target_sp->GetImages().FindGlobalVariables(
170 ConstString(name_ref), std::numeric_limits<uint32_t>::max(),
171 modules_var_list);
172
173 if (!modules_var_list.Empty()) {
174 lldb::VariableSP var_sp =
175 DILFindVariable(ConstString(name_ref), modules_var_list);
176 if (var_sp)
177 value_sp = ValueObjectVariable::Create(stack_frame.get(), var_sp);
178
179 if (value_sp)
180 return value_sp;
181 }
182 return nullptr;
183}
184
185lldb::ValueObjectSP LookupIdentifier(llvm::StringRef name_ref,
186 std::shared_ptr<StackFrame> stack_frame,
187 lldb::DynamicValueType use_dynamic) {
188 // Support $rax as a special syntax for accessing registers.
189 // Will return an invalid value in case the requested register doesn't exist.
190 if (name_ref.consume_front("$")) {
191 lldb::RegisterContextSP reg_ctx(stack_frame->GetRegisterContext());
192 if (!reg_ctx)
193 return nullptr;
194
195 if (const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(name_ref))
196 return ValueObjectRegister::Create(stack_frame.get(), reg_ctx, reg_info);
197
198 return nullptr;
199 }
200
201 if (!name_ref.contains("::")) {
202 // Lookup in the current frame.
203 // Try looking for a local variable in current scope.
204 lldb::VariableListSP variable_list(
205 stack_frame->GetInScopeVariableList(false));
206
207 lldb::ValueObjectSP value_sp;
208 if (variable_list) {
209 lldb::VariableSP var_sp =
210 variable_list->FindVariable(ConstString(name_ref));
211 if (var_sp)
212 value_sp =
213 stack_frame->GetValueObjectForFrameVariable(var_sp, use_dynamic);
214 }
215
216 if (value_sp)
217 return value_sp;
218
219 // Try looking for an instance variable (class member).
220 SymbolContext sc = stack_frame->GetSymbolContext(
221 lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
222 llvm::StringRef ivar_name = sc.GetInstanceVariableName();
223 value_sp = stack_frame->FindVariable(ConstString(ivar_name));
224 if (value_sp)
225 value_sp = value_sp->GetChildMemberWithName(name_ref);
226
227 if (value_sp)
228 return value_sp;
229 }
230 return nullptr;
231}
232
233Interpreter::Interpreter(lldb::TargetSP target, llvm::StringRef expr,
234 std::shared_ptr<StackFrame> frame_sp,
235 lldb::DynamicValueType use_dynamic, bool use_synthetic,
236 bool fragile_ivar, bool check_ptr_vs_member)
237 : m_target(std::move(target)), m_expr(expr), m_exe_ctx_scope(frame_sp),
238 m_use_dynamic(use_dynamic), m_use_synthetic(use_synthetic),
239 m_fragile_ivar(fragile_ivar), m_check_ptr_vs_member(check_ptr_vs_member) {
240}
241
242llvm::Expected<lldb::ValueObjectSP> Interpreter::Evaluate(const ASTNode *node) {
243 // Evaluate an AST.
244 auto value_or_error = node->Accept(this);
245 // Convert SP with a nullptr to an error.
246 if (value_or_error && !*value_or_error)
247 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",
248 node->GetLocation());
249 // Return the computed value-or-error. The caller is responsible for
250 // checking if an error occured during the evaluation.
251 return value_or_error;
252}
253
254llvm::Expected<lldb::ValueObjectSP>
257
258 lldb::ValueObjectSP identifier =
259 LookupIdentifier(node->GetName(), m_exe_ctx_scope, use_dynamic);
260
261 if (!identifier)
262 identifier = LookupGlobalIdentifier(node->GetName(), m_exe_ctx_scope,
263 m_target, use_dynamic);
264 if (!identifier) {
265 std::string errMsg =
266 llvm::formatv("use of undeclared identifier '{0}'", node->GetName());
267 return llvm::make_error<DILDiagnosticError>(
268 m_expr, errMsg, node->GetLocation(), node->GetName().size());
269 }
270
271 return identifier;
272}
273
274llvm::Expected<lldb::ValueObjectSP>
277 auto op_or_err = Evaluate(node->GetOperand());
278 if (!op_or_err)
279 return op_or_err;
280
281 lldb::ValueObjectSP operand = *op_or_err;
282
283 switch (node->GetKind()) {
284 case UnaryOpKind::Deref: {
285 lldb::ValueObjectSP dynamic_op = operand->GetDynamicValue(m_use_dynamic);
286 if (dynamic_op)
287 operand = dynamic_op;
288
289 lldb::ValueObjectSP child_sp = operand->Dereference(error);
290 if (!child_sp && m_use_synthetic) {
291 if (lldb::ValueObjectSP synth_obj_sp = operand->GetSyntheticValue()) {
292 error.Clear();
293 child_sp = synth_obj_sp->Dereference(error);
294 }
295 }
296 if (error.Fail())
297 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
298 node->GetLocation());
299
300 return child_sp;
301 }
302 case UnaryOpKind::AddrOf: {
304 lldb::ValueObjectSP value = operand->AddressOf(error);
305 if (error.Fail())
306 return llvm::make_error<DILDiagnosticError>(m_expr, error.AsCString(),
307 node->GetLocation());
308
309 return value;
310 }
311 case UnaryOpKind::Minus: {
312 if (operand->GetCompilerType().IsReferenceType()) {
313 operand = operand->Dereference(error);
314 if (error.Fail())
315 return error.ToError();
316 }
317 llvm::Expected<lldb::ValueObjectSP> conv_op =
318 UnaryConversion(operand, node->GetOperand()->GetLocation());
319 if (!conv_op)
320 return conv_op;
321 operand = *conv_op;
322 CompilerType operand_type = operand->GetCompilerType();
323 if (!operand_type.IsScalarType()) {
324 std::string errMsg =
325 llvm::formatv("invalid argument type '{0}' to unary expression",
326 operand_type.GetTypeName());
327 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
328 node->GetLocation());
329 }
330 Scalar scalar;
331 bool resolved = operand->ResolveValue(scalar);
332 if (!resolved)
333 break;
334
335 bool negated = scalar.UnaryNegate();
336 if (negated)
338 m_target, scalar, operand->GetCompilerType(), "result");
339 break;
340 }
341 case UnaryOpKind::Plus: {
342 if (operand->GetCompilerType().IsReferenceType()) {
343 operand = operand->Dereference(error);
344 if (error.Fail())
345 return error.ToError();
346 }
347 llvm::Expected<lldb::ValueObjectSP> conv_op =
348 UnaryConversion(operand, node->GetOperand()->GetLocation());
349 if (!conv_op)
350 return conv_op;
351 operand = *conv_op;
352 CompilerType operand_type = operand->GetCompilerType();
353 if (!operand_type.IsScalarType() &&
354 // Unary plus is allowed for pointers.
355 !operand_type.IsPointerType()) {
356 std::string errMsg =
357 llvm::formatv("invalid argument type '{0}' to unary expression",
358 operand_type.GetTypeName());
359 return llvm::make_error<DILDiagnosticError>(m_expr, errMsg,
360 node->GetLocation());
361 }
362 return operand;
363 }
364 }
365 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid unary operation",
366 node->GetLocation());
367}
368
369llvm::Expected<lldb::ValueObjectSP>
371 auto base_or_err = Evaluate(node->GetBase());
372 if (!base_or_err)
373 return base_or_err;
374 bool expr_is_ptr = node->GetIsArrow();
375 lldb::ValueObjectSP base = *base_or_err;
376
377 // Perform some basic type & correctness checking.
378 if (node->GetIsArrow()) {
379 if (!m_fragile_ivar) {
380 // Make sure we aren't trying to deref an objective
381 // C ivar if this is not allowed
382 const uint32_t pointer_type_flags =
383 base->GetCompilerType().GetTypeInfo(nullptr);
384 if ((pointer_type_flags & lldb::eTypeIsObjC) &&
385 (pointer_type_flags & lldb::eTypeIsPointer)) {
386 // This was an objective C object pointer and it was requested we
387 // skip any fragile ivars so return nothing here
388 return lldb::ValueObjectSP();
389 }
390 }
391
392 // If we have a non-pointer type with a synthetic value then lets check
393 // if we have a synthetic dereference specified.
394 if (!base->IsPointerType() && base->HasSyntheticValue()) {
395 Status deref_error;
396 if (lldb::ValueObjectSP synth_deref_sp =
397 base->GetSyntheticValue()->Dereference(deref_error);
398 synth_deref_sp && deref_error.Success()) {
399 base = std::move(synth_deref_sp);
400 }
401 if (!base || deref_error.Fail()) {
402 std::string errMsg = llvm::formatv(
403 "Failed to dereference synthetic value: {0}", deref_error);
404 return llvm::make_error<DILDiagnosticError>(
405 m_expr, errMsg, node->GetLocation(), node->GetFieldName().size());
406 }
407
408 // Some synthetic plug-ins fail to set the error in Dereference
409 if (!base) {
410 std::string errMsg = "Failed to dereference synthetic value";
411 return llvm::make_error<DILDiagnosticError>(
412 m_expr, errMsg, node->GetLocation(), node->GetFieldName().size());
413 }
414 expr_is_ptr = false;
415 }
416 }
417
419 bool base_is_ptr = base->IsPointerType();
420
421 if (expr_is_ptr != base_is_ptr) {
422 if (base_is_ptr) {
423 std::string errMsg =
424 llvm::formatv("member reference type {0} is a pointer; "
425 "did you mean to use '->'?",
426 base->GetCompilerType().TypeDescription());
427 return llvm::make_error<DILDiagnosticError>(
428 m_expr, errMsg, node->GetLocation(), node->GetFieldName().size());
429 } else {
430 std::string errMsg =
431 llvm::formatv("member reference type {0} is not a pointer; "
432 "did you mean to use '.'?",
433 base->GetCompilerType().TypeDescription());
434 return llvm::make_error<DILDiagnosticError>(
435 m_expr, errMsg, node->GetLocation(), node->GetFieldName().size());
436 }
437 }
438 }
439
440 lldb::ValueObjectSP field_obj =
441 base->GetChildMemberWithName(node->GetFieldName());
442 if (!field_obj) {
443 if (m_use_synthetic) {
444 field_obj = base->GetSyntheticValue();
445 if (field_obj)
446 field_obj = field_obj->GetChildMemberWithName(node->GetFieldName());
447 }
448
449 if (!m_use_synthetic || !field_obj) {
450 std::string errMsg = llvm::formatv(
451 "\"{0}\" is not a member of \"({1}) {2}\"", node->GetFieldName(),
452 base->GetTypeName().AsCString("<invalid type>"), base->GetName());
453 return llvm::make_error<DILDiagnosticError>(
454 m_expr, errMsg, node->GetLocation(), node->GetFieldName().size());
455 }
456 }
457
458 if (field_obj) {
460 lldb::ValueObjectSP dynamic_val_sp =
461 field_obj->GetDynamicValue(m_use_dynamic);
462 if (dynamic_val_sp)
463 field_obj = dynamic_val_sp;
464 }
465 return field_obj;
466 }
467
468 CompilerType base_type = base->GetCompilerType();
469 if (node->GetIsArrow() && base->IsPointerType())
470 base_type = base_type.GetPointeeType();
471 std::string errMsg = llvm::formatv(
472 "\"{0}\" is not a member of \"({1}) {2}\"", node->GetFieldName(),
473 base->GetTypeName().AsCString("<invalid type>"), base->GetName());
474 return llvm::make_error<DILDiagnosticError>(
475 m_expr, errMsg, node->GetLocation(), node->GetFieldName().size());
476}
477
478llvm::Expected<lldb::ValueObjectSP>
480 auto lhs_or_err = Evaluate(node->GetBase());
481 if (!lhs_or_err)
482 return lhs_or_err;
483 lldb::ValueObjectSP base = *lhs_or_err;
484
485 StreamString var_expr_path_strm;
486 uint64_t child_idx = node->GetIndex();
487 lldb::ValueObjectSP child_valobj_sp;
488
489 bool is_incomplete_array = false;
490 CompilerType base_type = base->GetCompilerType().GetNonReferenceType();
491 base->GetExpressionPath(var_expr_path_strm);
492
493 if (base_type.IsPointerType()) {
494 bool is_objc_pointer = true;
495
496 if (base->GetCompilerType().GetMinimumLanguage() != lldb::eLanguageTypeObjC)
497 is_objc_pointer = false;
498 else if (!base->GetCompilerType().IsPointerType())
499 is_objc_pointer = false;
500
501 if (!m_use_synthetic && is_objc_pointer) {
502 std::string err_msg = llvm::formatv(
503 "\"({0}) {1}\" is an Objective-C pointer, and cannot be subscripted",
504 base->GetTypeName().AsCString("<invalid type>"),
505 var_expr_path_strm.GetData());
506 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
507 node->GetLocation());
508 }
509 if (is_objc_pointer) {
510 lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
511 if (!synthetic || synthetic == base) {
512 std::string err_msg =
513 llvm::formatv("\"({0}) {1}\" is not an array type",
514 base->GetTypeName().AsCString("<invalid type>"),
515 var_expr_path_strm.GetData());
516 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
517 node->GetLocation());
518 }
519 if (static_cast<uint32_t>(child_idx) >=
520 synthetic->GetNumChildrenIgnoringErrors()) {
521 std::string err_msg = llvm::formatv(
522 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
523 base->GetTypeName().AsCString("<invalid type>"),
524 var_expr_path_strm.GetData());
525 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
526 node->GetLocation());
527 }
528 child_valobj_sp = synthetic->GetChildAtIndex(child_idx);
529 if (!child_valobj_sp) {
530 std::string err_msg = llvm::formatv(
531 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
532 base->GetTypeName().AsCString("<invalid type>"),
533 var_expr_path_strm.GetData());
534 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
535 node->GetLocation());
536 }
538 if (auto dynamic_sp = child_valobj_sp->GetDynamicValue(m_use_dynamic))
539 child_valobj_sp = std::move(dynamic_sp);
540 }
541 return child_valobj_sp;
542 }
543
544 child_valobj_sp = base->GetSyntheticArrayMember(child_idx, true);
545 if (!child_valobj_sp) {
546 std::string err_msg = llvm::formatv(
547 "failed to use pointer as array for index {0} for "
548 "\"({1}) {2}\"",
549 child_idx, base->GetTypeName().AsCString("<invalid type>"),
550 var_expr_path_strm.GetData());
551 if (base_type.IsPointerToVoid())
552 err_msg = "subscript of pointer to incomplete type 'void'";
553 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
554 node->GetLocation());
555 }
556 } else if (base_type.IsArrayType(nullptr, nullptr, &is_incomplete_array)) {
557 child_valobj_sp = base->GetChildAtIndex(child_idx);
558 if (!child_valobj_sp && (is_incomplete_array || m_use_synthetic))
559 child_valobj_sp = base->GetSyntheticArrayMember(child_idx, true);
560 if (!child_valobj_sp) {
561 std::string err_msg = llvm::formatv(
562 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
563 base->GetTypeName().AsCString("<invalid type>"),
564 var_expr_path_strm.GetData());
565 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
566 node->GetLocation());
567 }
568 } else if (base_type.IsScalarType()) {
569 child_valobj_sp =
570 base->GetSyntheticBitFieldChild(child_idx, child_idx, true);
571 if (!child_valobj_sp) {
572 std::string err_msg = llvm::formatv(
573 "bitfield range {0}-{1} is not valid for \"({2}) {3}\"", child_idx,
574 child_idx, 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(), 1);
578 }
579 } else {
580 lldb::ValueObjectSP synthetic = base->GetSyntheticValue();
581 if (!m_use_synthetic || !synthetic || synthetic == base) {
582 std::string err_msg =
583 llvm::formatv("\"{0}\" is not an array type",
584 base->GetTypeName().AsCString("<invalid type>"));
585 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
586 node->GetLocation(), 1);
587 }
588 if (static_cast<uint32_t>(child_idx) >=
589 synthetic->GetNumChildrenIgnoringErrors(child_idx + 1)) {
590 std::string err_msg = llvm::formatv(
591 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
592 base->GetTypeName().AsCString("<invalid type>"),
593 var_expr_path_strm.GetData());
594 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
595 node->GetLocation(), 1);
596 }
597 child_valobj_sp = synthetic->GetChildAtIndex(child_idx);
598 if (!child_valobj_sp) {
599 std::string err_msg = llvm::formatv(
600 "array index {0} is not valid for \"({1}) {2}\"", child_idx,
601 base->GetTypeName().AsCString("<invalid type>"),
602 var_expr_path_strm.GetData());
603 return llvm::make_error<DILDiagnosticError>(m_expr, std::move(err_msg),
604 node->GetLocation(), 1);
605 }
606 }
607
608 if (child_valobj_sp) {
610 if (auto dynamic_sp = child_valobj_sp->GetDynamicValue(m_use_dynamic))
611 child_valobj_sp = std::move(dynamic_sp);
612 }
613 return child_valobj_sp;
614 }
615
616 int64_t signed_child_idx = node->GetIndex();
617 return base->GetSyntheticArrayMember(signed_child_idx, true);
618}
619
620llvm::Expected<lldb::ValueObjectSP>
622 auto lhs_or_err = Evaluate(node->GetBase());
623 if (!lhs_or_err)
624 return lhs_or_err;
625 lldb::ValueObjectSP base = *lhs_or_err;
626 int64_t first_index = node->GetFirstIndex();
627 int64_t last_index = node->GetLastIndex();
628
629 // if the format given is [high-low], swap range
630 if (first_index > last_index)
631 std::swap(first_index, last_index);
632
634 if (base->GetCompilerType().IsReferenceType()) {
635 base = base->Dereference(error);
636 if (error.Fail())
637 return error.ToError();
638 }
639 lldb::ValueObjectSP child_valobj_sp =
640 base->GetSyntheticBitFieldChild(first_index, last_index, true);
641 if (!child_valobj_sp) {
642 std::string message = llvm::formatv(
643 "bitfield range {0}-{1} is not valid for \"({2}) {3}\"", first_index,
644 last_index, base->GetTypeName().AsCString("<invalid type>"),
645 base->GetName().AsCString());
646 return llvm::make_error<DILDiagnosticError>(m_expr, message,
647 node->GetLocation());
648 }
649 return child_valobj_sp;
650}
651
652llvm::Expected<CompilerType>
654 std::shared_ptr<ExecutionContextScope> ctx,
655 const IntegerLiteralNode *literal) {
656 // Binary, Octal, Hexadecimal and literals with a U suffix are allowed to be
657 // an unsigned integer.
658 bool unsigned_is_allowed = literal->IsUnsigned() || literal->GetRadix() != 10;
659 llvm::APInt apint = literal->GetValue();
660
661 llvm::SmallVector<std::pair<lldb::BasicType, lldb::BasicType>, 3> candidates;
662 if (literal->GetTypeSuffix() <= IntegerTypeSuffix::None)
663 candidates.emplace_back(lldb::eBasicTypeInt,
664 unsigned_is_allowed ? lldb::eBasicTypeUnsignedInt
666 if (literal->GetTypeSuffix() <= IntegerTypeSuffix::Long)
667 candidates.emplace_back(lldb::eBasicTypeLong,
668 unsigned_is_allowed ? lldb::eBasicTypeUnsignedLong
670 candidates.emplace_back(lldb::eBasicTypeLongLong,
672 for (auto [signed_, unsigned_] : candidates) {
673 CompilerType signed_type = type_system->GetBasicTypeFromAST(signed_);
674 if (!signed_type)
675 continue;
676 llvm::Expected<uint64_t> size = signed_type.GetBitSize(ctx.get());
677 if (!size)
678 return size.takeError();
679 if (!literal->IsUnsigned() && apint.isIntN(*size - 1))
680 return signed_type;
681 if (unsigned_ != lldb::eBasicTypeInvalid && apint.isIntN(*size))
682 return type_system->GetBasicTypeFromAST(unsigned_);
683 }
684
685 return llvm::make_error<DILDiagnosticError>(
686 m_expr,
687 "integer literal is too large to be represented in any integer type",
688 literal->GetLocation());
689}
690
691llvm::Expected<lldb::ValueObjectSP>
693 llvm::Expected<lldb::TypeSystemSP> type_system =
695 if (!type_system)
696 return type_system.takeError();
697
698 llvm::Expected<CompilerType> type =
699 PickIntegerType(*type_system, m_exe_ctx_scope, node);
700 if (!type)
701 return type.takeError();
702
703 Scalar scalar = node->GetValue();
704 // APInt from StringRef::getAsInteger comes with just enough bitwidth to
705 // hold the value. This adjusts APInt bitwidth to match the compiler type.
706 llvm::Expected<uint64_t> type_bitsize =
707 type->GetBitSize(m_exe_ctx_scope.get());
708 if (!type_bitsize)
709 return type_bitsize.takeError();
710 scalar.TruncOrExtendTo(*type_bitsize, false);
712 "result");
713}
714
715llvm::Expected<lldb::ValueObjectSP>
717 llvm::Expected<lldb::TypeSystemSP> type_system =
719 if (!type_system)
720 return type_system.takeError();
721
722 bool isFloat =
723 &node->GetValue().getSemantics() == &llvm::APFloat::IEEEsingle();
724 lldb::BasicType basic_type =
726 CompilerType type = GetBasicType(*type_system, basic_type);
727
728 if (!type)
729 return llvm::make_error<DILDiagnosticError>(
730 m_expr, "unable to create a const literal", node->GetLocation());
731
732 Scalar scalar = node->GetValue();
734 "result");
735}
736
737llvm::Expected<lldb::ValueObjectSP>
739 bool value = node->GetValue();
740 return ValueObject::CreateValueObjectFromBool(m_target, value, "result");
741}
742
743llvm::Expected<lldb::ValueObjectSP> Interpreter::Visit(const CastNode *node) {
744 auto operand_or_err = Evaluate(node->GetOperand());
745 if (!operand_or_err)
746 return operand_or_err;
747
748 lldb::ValueObjectSP operand = *operand_or_err;
749 // Don't actually do the cast for now -- that code will be added later.
750 // For now just return an error message.
751 return llvm::make_error<DILDiagnosticError>(
752 m_expr, "Type casting is not supported here.", node->GetLocation());
753}
754
755} // 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 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.
ConstString GetTypeName(bool BaseOnly=false) 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
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:78
llvm::Expected< lldb::ValueObjectSP > Visit(const IdentifierNode *node) override
Definition DILEval.cpp:255
llvm::Expected< lldb::ValueObjectSP > Evaluate(const ASTNode *node)
Definition DILEval.cpp:242
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:233
llvm::Expected< lldb::ValueObjectSP > UnaryConversion(lldb::ValueObjectSP valobj, uint32_t location)
Perform usual unary conversions on a value.
Definition DILEval.cpp:57
lldb::DynamicValueType m_use_dynamic
Definition DILEval.h:79
llvm::Expected< CompilerType > PickIntegerType(lldb::TypeSystemSP type_system, std::shared_ptr< ExecutionContextScope > ctx, const IntegerLiteralNode *literal)
Definition DILEval.cpp:653
llvm::StringRef GetFieldName() const
Definition DILAST.h:119
ASTNode * GetBase() const
Definition DILAST.h:117
ASTNode * GetOperand() const
Definition DILAST.h:140
UnaryOpKind GetKind() const
Definition DILAST.h:139
static CompilerType GetBasicType(lldb::TypeSystemSP type_system, lldb::BasicType basic_type)
Definition DILEval.cpp:37
static llvm::Expected< lldb::TypeSystemSP > GetTypeSystemFromCU(std::shared_ptr< ExecutionContextScope > ctx)
Definition DILEval.cpp:25
static lldb::VariableSP DILFindVariable(ConstString name, VariableList &variable_list)
Definition DILEval.cpp:119
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:144
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:185
static lldb::ValueObjectSP ArrayToPointerConversion(ValueObject &valobj, ExecutionContextScope &ctx)
Definition DILEval.cpp:46
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),...