brintos

brintos / llvm-project-archived public Read only

0
0
Text · 28.6 KiB · 40a05a4 Raw
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