Ejemplo n.º 1
0
CompilerType
GoUserExpression::GoInterpreter::EvaluateType(const GoASTExpr *e)
{
    TargetSP target = m_exe_ctx.GetTargetSP();
    if (auto *id = llvm::dyn_cast<GoASTIdent>(e))
    {
        CompilerType result = LookupType(target, ConstString(id->GetName().m_value));
        if (result.IsValid())
            return result;
        std::string fullname = (m_package + "." + id->GetName().m_value).str();
        result = LookupType(target, ConstString(fullname));
        if (!result)
            m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
        return result;
    }
    if (auto *sel = llvm::dyn_cast<GoASTSelectorExpr>(e))
    {
        std::string package;
        if (auto *pkg_node = llvm::dyn_cast<GoASTIdent>(sel->GetX()))
        {
            package = pkg_node->GetName().m_value.str();
        }
        else if (auto *str_node = llvm::dyn_cast<GoASTBasicLit>(sel->GetX()))
        {
            if (str_node->GetValue().m_type == GoLexer::LIT_STRING)
            {
                package = str_node->GetValue().m_value.substr(1).str();
                package.resize(package.length() - 1);
            }
        }
        if (package.empty())
        {
            m_error.SetErrorStringWithFormat("Invalid %s in type expression", sel->GetX()->GetKindName());
            return CompilerType();
        }
        std::string fullname = (package + "." + sel->GetSel()->GetName().m_value).str();
        CompilerType result = LookupType(target, ConstString(fullname));
        if (!result)
            m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str());
        return result;
    }
    if (auto *star = llvm::dyn_cast<GoASTStarExpr>(e))
    {
        CompilerType elem = EvaluateType(star->GetX());
        return elem.GetPointerType();
    }
    if (auto *paren = llvm::dyn_cast<GoASTParenExpr>(e))
        return EvaluateType(paren->GetX());
    if (auto *array = llvm::dyn_cast<GoASTArrayType>(e))
    {
        CompilerType elem = EvaluateType(array->GetElt());
    }

    m_error.SetErrorStringWithFormat("Invalid %s in type expression", e->GetKindName());
    return CompilerType();
}
Ejemplo n.º 2
0
bool lldb_private::formatters::swift::SwiftOptionSetSummaryProvider::
    WouldEvenConsiderFormatting(CompilerType clang_type) {
  SwiftASTContext *swift_ast_ctx =
      llvm::dyn_cast_or_null<SwiftASTContext>(clang_type.GetTypeSystem());
  if (!swift_ast_ctx)
    return false;

  return clang_type.IsValid() &&
         swift_ast_ctx->IsTrivialOptionSetType(clang_type) &&
         swift_ast_ctx->IsImportedType(clang_type, nullptr);
}
Ejemplo n.º 3
0
ValueObjectSP ABI::GetReturnValueObject(Thread &thread, CompilerType &ast_type,
                                        bool persistent) const {
  if (!ast_type.IsValid())
    return ValueObjectSP();

  ValueObjectSP return_valobj_sp;

  return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type);
  if (!return_valobj_sp)
    return return_valobj_sp;

  // Now turn this into a persistent variable.
  // FIXME: This code is duplicated from Target::EvaluateExpression, and it is
  // used in similar form in a couple
  // of other places.  Figure out the correct Create function to do all this
  // work.

  if (persistent) {
    PersistentExpressionState *persistent_expression_state =
        thread.CalculateTarget()->GetPersistentExpressionStateForLanguage(
            ast_type.GetMinimumLanguage());

    if (!persistent_expression_state)
      return ValueObjectSP();

    ConstString persistent_variable_name(
        persistent_expression_state->GetNextPersistentVariableName());

    lldb::ValueObjectSP const_valobj_sp;

    // Check in case our value is already a constant value
    if (return_valobj_sp->GetIsConstant()) {
      const_valobj_sp = return_valobj_sp;
      const_valobj_sp->SetName(persistent_variable_name);
    } else
      const_valobj_sp =
          return_valobj_sp->CreateConstantValue(persistent_variable_name);

    lldb::ValueObjectSP live_valobj_sp = return_valobj_sp;

    return_valobj_sp = const_valobj_sp;

    ExpressionVariableSP clang_expr_variable_sp(
        persistent_expression_state->CreatePersistentVariable(
            return_valobj_sp));

    assert(clang_expr_variable_sp);

    // Set flags and live data as appropriate

    const Value &result_value = live_valobj_sp->GetValue();

    switch (result_value.GetValueType()) {
    case Value::eValueTypeHostAddress:
    case Value::eValueTypeFileAddress:
      // we don't do anything with these for now
      break;
    case Value::eValueTypeScalar:
    case Value::eValueTypeVector:
      clang_expr_variable_sp->m_flags |=
          ClangExpressionVariable::EVIsFreezeDried;
      clang_expr_variable_sp->m_flags |=
          ClangExpressionVariable::EVIsLLDBAllocated;
      clang_expr_variable_sp->m_flags |=
          ClangExpressionVariable::EVNeedsAllocation;
      break;
    case Value::eValueTypeLoadAddress:
      clang_expr_variable_sp->m_live_sp = live_valobj_sp;
      clang_expr_variable_sp->m_flags |=
          ClangExpressionVariable::EVIsProgramReference;
      break;
    }

    return_valobj_sp = clang_expr_variable_sp->GetValueObject();
  }
  return return_valobj_sp;
}
Ejemplo n.º 4
0
static void
PrivateAutoComplete (StackFrame *frame,
                     const std::string &partial_path,
                     const std::string &prefix_path, // Anything that has been resolved already will be in here
                     const CompilerType& compiler_type,
                     StringList &matches,
                     bool &word_complete)
{
//    printf ("\nPrivateAutoComplete()\n\tprefix_path = '%s'\n\tpartial_path = '%s'\n", prefix_path.c_str(), partial_path.c_str());
    std::string remaining_partial_path;

    const lldb::TypeClass type_class = compiler_type.GetTypeClass();
    if (partial_path.empty())
    {
        if (compiler_type.IsValid())
        {
            switch (type_class)
            {
                default:
                case eTypeClassArray:
                case eTypeClassBlockPointer:
                case eTypeClassBuiltin:
                case eTypeClassComplexFloat:
                case eTypeClassComplexInteger:
                case eTypeClassEnumeration:
                case eTypeClassFunction:
                case eTypeClassMemberPointer:
                case eTypeClassReference:
                case eTypeClassTypedef:
                case eTypeClassVector:
                    {
                        matches.AppendString (prefix_path);
                        word_complete = matches.GetSize() == 1;
                    }
                    break;
                    
                case eTypeClassClass:
                case eTypeClassStruct:
                case eTypeClassUnion:
                    if (prefix_path.back() != '.')
                        matches.AppendString (prefix_path + '.');
                    break;

                case eTypeClassObjCObject:
                case eTypeClassObjCInterface:
                    break;
                case eTypeClassObjCObjectPointer:
                case eTypeClassPointer:
                    {
                        bool omit_empty_base_classes = true;
                        if (compiler_type.GetNumChildren (omit_empty_base_classes) > 0)
                            matches.AppendString (prefix_path + "->");
                        else
                        {
                            matches.AppendString (prefix_path);
                            word_complete = true;
                        }
                    }
                    break;
            }
        }
        else
        {
            if (frame)
            {
                const bool get_file_globals = true;
                
                VariableList *variable_list = frame->GetVariableList(get_file_globals);
                
                if (variable_list)
                {
                    const size_t num_variables = variable_list->GetSize();
                    for (size_t i=0; i<num_variables; ++i)
                    {
                        Variable *variable = variable_list->GetVariableAtIndex(i).get();
                        matches.AppendString (variable->GetName().AsCString());
                    }
                }
            }
        }
    }
    else
    {
        const char ch = partial_path[0];
        switch (ch)
        {
        case '*':
            if (prefix_path.empty())
            {
                PrivateAutoComplete (frame,
                                     partial_path.substr(1),
                                     std::string("*"),
                                     compiler_type,
                                     matches,
                                     word_complete);
            }
            break;

        case '&':
            if (prefix_path.empty())
            {
                PrivateAutoComplete (frame,
                                     partial_path.substr(1),
                                     std::string("&"),
                                     compiler_type,
                                     matches,
                                     word_complete);
            }
            break;

        case '-':
            if (partial_path[1] == '>' && !prefix_path.empty())
            {
                switch (type_class)
                {
                    case lldb::eTypeClassPointer:
                        {
                            CompilerType pointee_type(compiler_type.GetPointeeType());
                            if (partial_path[2])
                            {
                                // If there is more after the "->", then search deeper
                                PrivateAutoComplete (frame,
                                                     partial_path.substr(2),
                                                     prefix_path + "->",
                                                     pointee_type.GetCanonicalType(),
                                                     matches,
                                                     word_complete);
                            }
                            else
                            {
                                // Nothing after the "->", so list all members
                                PrivateAutoCompleteMembers (frame,
                                                            std::string(),
                                                            std::string(),
                                                            prefix_path + "->",
                                                            pointee_type.GetCanonicalType(),
                                                            matches,
                                                            word_complete);                            
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
            break;
            
        case '.':
            if (compiler_type.IsValid())
            {
                switch (type_class)
                {
                    case lldb::eTypeClassUnion:
                    case lldb::eTypeClassStruct:
                    case lldb::eTypeClassClass:
                        if (partial_path[1])
                        {
                            // If there is more after the ".", then search deeper
                            PrivateAutoComplete (frame,
                                                 partial_path.substr(1),
                                                 prefix_path + ".",
                                                 compiler_type,
                                                 matches,
                                                 word_complete);
                            
                        }
                        else
                        {
                            // Nothing after the ".", so list all members
                            PrivateAutoCompleteMembers (frame,
                                                        std::string(),
                                                        partial_path,
                                                        prefix_path + ".",
                                                        compiler_type,
                                                        matches,
                                                        word_complete);
                        }
                        break;
                    default:
                        break;
                }
            }
            break;
        default:
            if (isalpha(ch) || ch == '_' || ch == '$')
            {
                const size_t partial_path_len = partial_path.size();
                size_t pos = 1;
                while (pos < partial_path_len)
                {
                    const char curr_ch = partial_path[pos];
                    if (isalnum(curr_ch) || curr_ch == '_'  || curr_ch == '$')
                    {
                        ++pos;
                        continue;
                    }
                    break;
                }

                std::string token(partial_path, 0, pos);
                remaining_partial_path = partial_path.substr(pos);
                
                if (compiler_type.IsValid())
                {
                    PrivateAutoCompleteMembers (frame,
                                                token,
                                                remaining_partial_path,
                                                prefix_path,
                                                compiler_type,
                                                matches,
                                                word_complete);
                }
                else if (frame)
                {
                    // We haven't found our variable yet
                    const bool get_file_globals = true;
                    
                    VariableList *variable_list = frame->GetVariableList(get_file_globals);
                    
                    if (!variable_list)
                        break;
                    
                    const size_t num_variables = variable_list->GetSize();
                    for (size_t i=0; i<num_variables; ++i)
                    {
                        Variable *variable = variable_list->GetVariableAtIndex(i).get();
                        
                        if (!variable)
                            continue;
                        
                        const char *variable_name = variable->GetName().AsCString();
                        if (strstr(variable_name, token.c_str()) == variable_name)
                        {
                            if (strcmp (variable_name, token.c_str()) == 0)
                            {
                                Type *variable_type = variable->GetType();
                                if (variable_type)
                                {
                                    CompilerType variable_compiler_type (variable_type->GetForwardCompilerType ());
                                    PrivateAutoComplete (frame,
                                                         remaining_partial_path,
                                                         prefix_path + token, // Anything that has been resolved already will be in here
                                                         variable_compiler_type.GetCanonicalType(),
                                                         matches,
                                                         word_complete);
                                }
                                else
                                {
                                    matches.AppendString (prefix_path + variable_name);
                                }
                            }
                            else if (remaining_partial_path.empty())
                            {
                                matches.AppendString (prefix_path + variable_name);
                            }
                        }
                    }
                }
            }
            break;
        }
    }
}
Ejemplo n.º 5
0
CompilerType
GoASTContext::GetChildCompilerTypeAtIndex(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, bool transparent_pointers,
                                          bool omit_empty_base_classes, bool ignore_array_bounds, std::string &child_name,
                                          uint32_t &child_byte_size, int32_t &child_byte_offset,
                                          uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
                                          bool &child_is_base_class, bool &child_is_deref_of_parent, ValueObject *valobj, uint64_t &language_flags)
{
    child_name.clear();
    child_byte_size = 0;
    child_byte_offset = 0;
    child_bitfield_bit_size = 0;
    child_bitfield_bit_offset = 0;
    child_is_base_class = false;
    child_is_deref_of_parent = false;
    language_flags = 0;

    if (!type || !GetCompleteType(type))
        return CompilerType();

    GoType *t = static_cast<GoType *>(type);
    if (t->GetStruct())
    {
        uint64_t bit_offset;
        CompilerType ret = GetFieldAtIndex(type, idx, child_name, &bit_offset, nullptr, nullptr);
        child_byte_size = ret.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
        child_byte_offset = bit_offset / 8;
        return ret;
    }
    else if (t->GetGoKind() == GoType::KIND_PTR)
    {
        CompilerType pointee = t->GetElementType();
        if (!pointee.IsValid() || pointee.IsVoidType())
            return CompilerType();
        if (transparent_pointers && pointee.IsAggregateType())
        {
            bool tmp_child_is_deref_of_parent = false;
            return pointee.GetChildCompilerTypeAtIndex(exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
                                                    ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
                                                    child_bitfield_bit_size, child_bitfield_bit_offset,
                                                       child_is_base_class, tmp_child_is_deref_of_parent, valobj, language_flags);
        }
        else
        {
            child_is_deref_of_parent = true;
            const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL;
            if (parent_name)
            {
                child_name.assign(1, '*');
                child_name += parent_name;
            }

            // We have a pointer to an simple type
            if (idx == 0 && pointee.GetCompleteType())
            {
                child_byte_size = pointee.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
                child_byte_offset = 0;
                return pointee;
            }
        }
    }
    else if (GoArray *a = t->GetArray())
    {
        if (ignore_array_bounds || idx < a->GetLength())
        {
            CompilerType element_type = a->GetElementType();
            if (element_type.GetCompleteType())
            {
                char element_name[64];
                ::snprintf(element_name, sizeof(element_name), "[%zu]", idx);
                child_name.assign(element_name);
                child_byte_size = element_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL);
                child_byte_offset = (int32_t)idx * (int32_t)child_byte_size;
                return element_type;
            }
        }
    }
    else if (t->IsTypedef())
    {
        return t->GetElementType().GetChildCompilerTypeAtIndex(
            exe_ctx, idx, transparent_pointers, omit_empty_base_classes, ignore_array_bounds, child_name,
            child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
            child_is_deref_of_parent, valobj, language_flags);
    }
    return CompilerType();
}
Ejemplo n.º 6
0
void FormatManager::GetPossibleMatches(
    ValueObject &valobj, CompilerType compiler_type, uint32_t reason,
    lldb::DynamicValueType use_dynamic, FormattersMatchVector &entries,
    bool did_strip_ptr, bool did_strip_ref, bool did_strip_typedef,
    bool root_level) {
  compiler_type = compiler_type.GetTypeForFormatters();
  ConstString type_name(compiler_type.GetConstTypeName());
  if (valobj.GetBitfieldBitSize() > 0) {
    StreamString sstring;
    sstring.Printf("%s:%d", type_name.AsCString(), valobj.GetBitfieldBitSize());
    ConstString bitfieldname(sstring.GetString());
    entries.push_back(
        {bitfieldname, 0, did_strip_ptr, did_strip_ref, did_strip_typedef});
    reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
  }

  if (!compiler_type.IsMeaninglessWithoutDynamicResolution()) {
    entries.push_back(
        {type_name, reason, did_strip_ptr, did_strip_ref, did_strip_typedef});

    ConstString display_type_name(compiler_type.GetDisplayTypeName());
    if (display_type_name != type_name)
      entries.push_back({display_type_name, reason, did_strip_ptr,
                         did_strip_ref, did_strip_typedef});
  }

  for (bool is_rvalue_ref = true, j = true;
       j && compiler_type.IsReferenceType(nullptr, &is_rvalue_ref); j = false) {
    CompilerType non_ref_type = compiler_type.GetNonReferenceType();
    GetPossibleMatches(
        valobj, non_ref_type,
        reason |
            lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
        use_dynamic, entries, did_strip_ptr, true, did_strip_typedef);
    if (non_ref_type.IsTypedefType()) {
      CompilerType deffed_referenced_type = non_ref_type.GetTypedefedType();
      deffed_referenced_type =
          is_rvalue_ref ? deffed_referenced_type.GetRValueReferenceType()
                        : deffed_referenced_type.GetLValueReferenceType();
      GetPossibleMatches(
          valobj, deffed_referenced_type,
          reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
          use_dynamic, entries, did_strip_ptr, did_strip_ref,
          true); // this is not exactly the usual meaning of stripping typedefs
    }
  }

  if (compiler_type.IsPointerType()) {
    CompilerType non_ptr_type = compiler_type.GetPointeeType();
    GetPossibleMatches(
        valobj, non_ptr_type,
        reason |
            lldb_private::eFormatterChoiceCriterionStrippedPointerReference,
        use_dynamic, entries, true, did_strip_ref, did_strip_typedef);
    if (non_ptr_type.IsTypedefType()) {
      CompilerType deffed_pointed_type =
          non_ptr_type.GetTypedefedType().GetPointerType();
      GetPossibleMatches(
          valobj, deffed_pointed_type,
          reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
          use_dynamic, entries, did_strip_ptr, did_strip_ref,
          true); // this is not exactly the usual meaning of stripping typedefs
    }
  }

  for (lldb::LanguageType language_type : GetCandidateLanguages(valobj)) {
    if (Language *language = Language::FindPlugin(language_type)) {
      for (ConstString candidate :
           language->GetPossibleFormattersMatches(valobj, use_dynamic)) {
        entries.push_back(
            {candidate,
             reason | lldb_private::eFormatterChoiceCriterionLanguagePlugin,
             did_strip_ptr, did_strip_ref, did_strip_typedef});
      }
    }
  }

  // try to strip typedef chains
  if (compiler_type.IsTypedefType()) {
    CompilerType deffed_type = compiler_type.GetTypedefedType();
    GetPossibleMatches(
        valobj, deffed_type,
        reason | lldb_private::eFormatterChoiceCriterionNavigatedTypedefs,
        use_dynamic, entries, did_strip_ptr, did_strip_ref, true);
  }

  if (root_level) {
    do {
      if (!compiler_type.IsValid())
        break;

      CompilerType unqual_compiler_ast_type =
          compiler_type.GetFullyUnqualifiedType();
      if (!unqual_compiler_ast_type.IsValid())
        break;
      if (unqual_compiler_ast_type.GetOpaqueQualType() !=
          compiler_type.GetOpaqueQualType())
        GetPossibleMatches(valobj, unqual_compiler_ast_type, reason,
                           use_dynamic, entries, did_strip_ptr, did_strip_ref,
                           did_strip_typedef);
    } while (false);

    // if all else fails, go to static type
    if (valobj.IsDynamic()) {
      lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
      if (static_value_sp)
        GetPossibleMatches(
            *static_value_sp.get(), static_value_sp->GetCompilerType(),
            reason | lldb_private::eFormatterChoiceCriterionWentToStaticValue,
            use_dynamic, entries, did_strip_ptr, did_strip_ref,
            did_strip_typedef, true);
    }
  }
}