Example #1
0
ValueObjectSP
ABI::GetReturnValueObject (Thread &thread,
                          ClangASTType &ast_type) const
{
    if (!ast_type.IsValid())
        return ValueObjectSP();
        
    Value ret_value;
    ret_value.SetContext(Value::eContextTypeClangType, 
                       ast_type.GetOpaqueQualType());
    if (GetReturnValue (thread, ret_value))
    {
        return ValueObjectConstResult::Create(
                                        thread.GetStackFrameAtIndex(0).get(),
                                        ast_type.GetASTContext(),
                                        ret_value,
                                        ConstString("FunctionReturn"));

    }
    else
        return ValueObjectSP();
}
Example #2
0
ValueObjectSP
ABI::GetReturnValueObject (Thread &thread,
                           ClangASTType &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)
    {
        ClangPersistentVariables& persistent_variables = thread.CalculateTarget()->GetPersistentVariables();
        ConstString persistent_variable_name (persistent_variables.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;

        ClangExpressionVariableSP clang_expr_variable_sp(persistent_variables.CreatePersistentVariable(return_valobj_sp));
               
        assert (clang_expr_variable_sp.get());
        
        // 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;
}
Example #3
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 ClangASTType& clang_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 = clang_type.GetTypeClass();
    if (partial_path.empty())
    {
        if (clang_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 (clang_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("*"),
                                     clang_type,
                                     matches,
                                     word_complete);
            }
            break;

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

        case '-':
            if (partial_path[1] == '>' && !prefix_path.empty())
            {
                switch (type_class)
                {
                    case lldb::eTypeClassPointer:
                        {
                            ClangASTType pointee_type(clang_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);                            
                            }
                        }
                    default:
                        break;
                }
            }
            break;
            
        case '.':
            if (clang_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 + ".",
                                                 clang_type,
                                                 matches,
                                                 word_complete);
                            
                        }
                        else
                        {
                            // Nothing after the ".", so list all members
                            PrivateAutoCompleteMembers (frame,
                                                        std::string(),
                                                        partial_path,
                                                        prefix_path + ".",
                                                        clang_type,
                                                        matches,
                                                        word_complete);
                        }
                    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 (clang_type.IsValid())
                {
                    PrivateAutoCompleteMembers (frame,
                                                token,
                                                remaining_partial_path,
                                                prefix_path,
                                                clang_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)
                                {
                                    ClangASTType variable_clang_type (variable_type->GetClangForwardType());
                                    PrivateAutoComplete (frame,
                                                         remaining_partial_path,
                                                         prefix_path + token, // Anything that has been resolved already will be in here
                                                         variable_clang_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;
        }
    }
}