744 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/ValueObject/DILEval.h"10#include "lldb/Core/Module.h"11#include "lldb/Symbol/CompileUnit.h"12#include "lldb/Symbol/TypeSystem.h"13#include "lldb/Symbol/VariableList.h"14#include "lldb/Target/RegisterContext.h"15#include "lldb/ValueObject/DILAST.h"16#include "lldb/ValueObject/ValueObject.h"17#include "lldb/ValueObject/ValueObjectRegister.h"18#include "lldb/ValueObject/ValueObjectVariable.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 37static CompilerType GetBasicType(lldb::TypeSystemSP type_system,38 lldb::BasicType basic_type) {39 if (type_system)40 return type_system.get()->GetBasicTypeFromAST(basic_type);41 42 return CompilerType();43}44 45static lldb::ValueObjectSP46ArrayToPointerConversion(ValueObject &valobj, ExecutionContextScope &ctx) {47 uint64_t addr = valobj.GetLoadAddress();48 ExecutionContext exe_ctx;49 ctx.CalculateExecutionContext(exe_ctx);50 return ValueObject::CreateValueObjectFromAddress(51 "result", addr, exe_ctx,52 valobj.GetCompilerType().GetArrayElementType(&ctx).GetPointerType(),53 /* do_deref */ false);54}55 56llvm::Expected<lldb::ValueObjectSP>57Interpreter::UnaryConversion(lldb::ValueObjectSP valobj, uint32_t location) {58 if (!valobj)59 return llvm::make_error<DILDiagnosticError>(m_expr, "invalid value object",60 location);61 llvm::Expected<lldb::TypeSystemSP> type_system =62 GetTypeSystemFromCU(m_exe_ctx_scope);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 is69 // converted to `int`. Otherwise, if `unsigned int` can represent it, it70 // is converted to `unsigned int`. Otherwise, it is treated as its71 // 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 =78 GetBasicType(*type_system, lldb::eBasicTypeUnsignedInt);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 type93 Scalar scalar;94 bool resolved = valobj->ResolveValue(scalar);95 if (!resolved)96 return llvm::createStringError("invalid scalar value");97 return ValueObject::CreateValueObjectFromScalar(m_target, scalar, in_type,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 119static lldb::VariableSP DILFindVariable(ConstString name,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 match129 if (str_ref_name == name.GetStringRef())130 return var_sp;131 132 // Check for possible matches by base name133 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 144lldb::ValueObjectSP LookupGlobalIdentifier(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 frame148 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 for250 // checking if an error occured during the evaluation.251 return value_or_error;252}253 254llvm::Expected<lldb::ValueObjectSP>255Interpreter::Visit(const IdentifierNode *node) {256 lldb::DynamicValueType use_dynamic = m_use_dynamic;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>275Interpreter::Visit(const UnaryOpNode *node) {276 Status error;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: {303 Status error;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)337 return ValueObject::CreateValueObjectFromScalar(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>370Interpreter::Visit(const MemberOfNode *node) {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 objective381 // C ivar if this is not allowed382 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 we387 // skip any fragile ivars so return nothing here388 return lldb::ValueObjectSP();389 }390 }391 392 // If we have a non-pointer type with a synthetic value then lets check393 // 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 Dereference409 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 418 if (m_check_ptr_vs_member) {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) {459 if (m_use_dynamic != lldb::eNoDynamicValues) {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>479Interpreter::Visit(const ArraySubscriptNode *node) {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 }537 if (m_use_dynamic != lldb::eNoDynamicValues) {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) {609 if (m_use_dynamic != lldb::eNoDynamicValues) {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>621Interpreter::Visit(const BitFieldExtractionNode *node) {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 range630 if (first_index > last_index)631 std::swap(first_index, last_index);632 633 Status error;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>653Interpreter::PickIntegerType(lldb::TypeSystemSP type_system,654 std::shared_ptr<ExecutionContextScope> ctx,655 const IntegerLiteralNode *literal) {656 // Binary, Octal, Hexadecimal and literals with a U suffix are allowed to be657 // 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::eBasicTypeUnsignedInt665 : lldb::eBasicTypeInvalid);666 if (literal->GetTypeSuffix() <= IntegerTypeSuffix::Long)667 candidates.emplace_back(lldb::eBasicTypeLong,668 unsigned_is_allowed ? lldb::eBasicTypeUnsignedLong669 : lldb::eBasicTypeInvalid);670 candidates.emplace_back(lldb::eBasicTypeLongLong,671 lldb::eBasicTypeUnsignedLongLong);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>692Interpreter::Visit(const IntegerLiteralNode *node) {693 llvm::Expected<lldb::TypeSystemSP> type_system =694 GetTypeSystemFromCU(m_exe_ctx_scope);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 to705 // 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);711 return ValueObject::CreateValueObjectFromScalar(m_target, scalar, *type,712 "result");713}714 715llvm::Expected<lldb::ValueObjectSP>716Interpreter::Visit(const FloatLiteralNode *node) {717 llvm::Expected<lldb::TypeSystemSP> type_system =718 GetTypeSystemFromCU(m_exe_ctx_scope);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 =725 isFloat ? lldb::eBasicTypeFloat : lldb::eBasicTypeDouble;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();733 return ValueObject::CreateValueObjectFromScalar(m_target, scalar, type,734 "result");735}736 737llvm::Expected<lldb::ValueObjectSP>738Interpreter::Visit(const BooleanLiteralNode *node) {739 bool value = node->GetValue();740 return ValueObject::CreateValueObjectFromBool(m_target, value, "result");741}742 743} // namespace lldb_private::dil744