ClangExpressionDeclMap.cpp revision 06dc17f8eb821d7256fd42e56f85c2779a29f689
1//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Expression/ClangExpressionDeclMap.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "clang/AST/ASTContext.h"
17#include "clang/AST/DeclarationName.h"
18#include "clang/AST/Decl.h"
19#include "lldb/lldb-private.h"
20#include "lldb/Core/Address.h"
21#include "lldb/Core/Error.h"
22#include "lldb/Core/Log.h"
23#include "lldb/Core/Module.h"
24#include "lldb/Core/RegisterValue.h"
25#include "lldb/Core/ValueObjectConstResult.h"
26#include "lldb/Core/ValueObjectVariable.h"
27#include "lldb/Expression/ASTDumper.h"
28#include "lldb/Expression/ClangASTSource.h"
29#include "lldb/Expression/ClangPersistentVariables.h"
30#include "lldb/Host/Endian.h"
31#include "lldb/Symbol/ClangASTContext.h"
32#include "lldb/Symbol/ClangNamespaceDecl.h"
33#include "lldb/Symbol/CompileUnit.h"
34#include "lldb/Symbol/Function.h"
35#include "lldb/Symbol/ObjectFile.h"
36#include "lldb/Symbol/SymbolContext.h"
37#include "lldb/Symbol/SymbolVendor.h"
38#include "lldb/Symbol/Type.h"
39#include "lldb/Symbol/TypeList.h"
40#include "lldb/Symbol/Variable.h"
41#include "lldb/Symbol/VariableList.h"
42#include "lldb/Target/ExecutionContext.h"
43#include "lldb/Target/Process.h"
44#include "lldb/Target/RegisterContext.h"
45#include "lldb/Target/StackFrame.h"
46#include "lldb/Target/Target.h"
47#include "lldb/Target/Thread.h"
48
49using namespace lldb;
50using namespace lldb_private;
51using namespace clang;
52
53ClangExpressionDeclMap::ClangExpressionDeclMap (bool keep_result_in_memory, ExecutionContext &exe_ctx) :
54    ClangASTSource (exe_ctx.GetTargetSP()),
55    m_found_entities (),
56    m_struct_members (),
57    m_keep_result_in_memory (keep_result_in_memory),
58    m_parser_vars (),
59    m_struct_vars ()
60{
61    EnableStructVars();
62}
63
64ClangExpressionDeclMap::~ClangExpressionDeclMap()
65{
66    // Note: The model is now that the parser's AST context and all associated
67    //   data does not vanish until the expression has been executed.  This means
68    //   that valuable lookup data (like namespaces) doesn't vanish, but
69
70    DidParse();
71    DidDematerialize();
72    DisableStructVars();
73}
74
75bool
76ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx)
77{
78    EnableParserVars();
79    m_parser_vars->m_exe_ctx = exe_ctx;
80
81    Target *target = exe_ctx.GetTargetPtr();
82    if (exe_ctx.GetFramePtr())
83        m_parser_vars->m_sym_ctx = exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything);
84    else if (exe_ctx.GetThreadPtr())
85        m_parser_vars->m_sym_ctx = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(lldb::eSymbolContextEverything);
86    else if (exe_ctx.GetProcessPtr())
87    {
88        m_parser_vars->m_sym_ctx.Clear();
89        m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
90    }
91    else if (target)
92    {
93        m_parser_vars->m_sym_ctx.Clear();
94        m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
95    }
96
97    if (target)
98    {
99        m_parser_vars->m_persistent_vars = &target->GetPersistentVariables();
100
101        if (!target->GetScratchClangASTContext())
102            return false;
103    }
104
105    m_parser_vars->m_target_info = GetTargetInfo();
106
107    return true;
108}
109
110void
111ClangExpressionDeclMap::DidParse()
112{
113    if (m_parser_vars.get())
114    {
115        for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();
116             entity_index < num_entities;
117             ++entity_index)
118        {
119            ClangExpressionVariableSP var_sp(m_found_entities.GetVariableAtIndex(entity_index));
120            if (var_sp &&
121                var_sp->m_parser_vars.get() &&
122                var_sp->m_parser_vars->m_lldb_value)
123                delete var_sp->m_parser_vars->m_lldb_value;
124
125            var_sp->DisableParserVars();
126        }
127
128        for (size_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->GetSize();
129             pvar_index < num_pvars;
130             ++pvar_index)
131        {
132            ClangExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index));
133            if (pvar_sp)
134                pvar_sp->DisableParserVars();
135        }
136
137        DisableParserVars();
138    }
139}
140
141// Interface for IRForTarget
142
143ClangExpressionDeclMap::TargetInfo
144ClangExpressionDeclMap::GetTargetInfo()
145{
146    assert (m_parser_vars.get());
147
148    TargetInfo ret;
149
150    ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
151
152    Process *process = exe_ctx.GetProcessPtr();
153    if (process)
154    {
155        ret.byte_order = process->GetByteOrder();
156        ret.address_byte_size = process->GetAddressByteSize();
157    }
158    else
159    {
160        Target *target = exe_ctx.GetTargetPtr();
161        if (target)
162        {
163            ret.byte_order = target->GetArchitecture().GetByteOrder();
164            ret.address_byte_size = target->GetArchitecture().GetAddressByteSize();
165        }
166    }
167
168    return ret;
169}
170
171const ConstString &
172ClangExpressionDeclMap::GetPersistentResultName ()
173{
174    assert (m_struct_vars.get());
175    assert (m_parser_vars.get());
176    if (!m_struct_vars->m_result_name)
177    {
178        Target *target = m_parser_vars->GetTarget();
179        assert (target);
180        m_struct_vars->m_result_name = target->GetPersistentVariables().GetNextPersistentVariableName();
181    }
182    return m_struct_vars->m_result_name;
183}
184
185lldb::ClangExpressionVariableSP
186ClangExpressionDeclMap::BuildIntegerVariable (const ConstString &name,
187                                              lldb_private::TypeFromParser type,
188                                              const llvm::APInt& value)
189{
190    assert (m_parser_vars.get());
191
192    ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
193
194    Target *target = exe_ctx.GetTargetPtr();
195
196    if (!target)
197        return ClangExpressionVariableSP();
198
199    ASTContext *context(target->GetScratchClangASTContext()->getASTContext());
200
201    TypeFromUser user_type(m_ast_importer->CopyType(context,
202                                                    type.GetASTContext(),
203                                                    type.GetOpaqueQualType()),
204                           context);
205
206    if (!user_type.GetOpaqueQualType())
207    {
208        lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
209
210        if (log)
211            log->Printf("ClangExpressionDeclMap::BuildIntegerVariable - Couldn't export the type for a constant integer result");
212
213        return lldb::ClangExpressionVariableSP();
214    }
215
216    if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (exe_ctx.GetBestExecutionContextScope (),
217                                                                     name,
218                                                                     user_type,
219                                                                     m_parser_vars->m_target_info.byte_order,
220                                                                     m_parser_vars->m_target_info.address_byte_size))
221        return lldb::ClangExpressionVariableSP();
222
223    ClangExpressionVariableSP pvar_sp (m_parser_vars->m_persistent_vars->GetVariable(name));
224
225    if (!pvar_sp)
226        return lldb::ClangExpressionVariableSP();
227
228    uint8_t *pvar_data = pvar_sp->GetValueBytes();
229    if (pvar_data == NULL)
230        return lldb::ClangExpressionVariableSP();
231
232    uint64_t value64 = value.getLimitedValue();
233
234    size_t num_val_bytes = sizeof(value64);
235    size_t num_data_bytes = pvar_sp->GetByteSize();
236
237    size_t num_bytes = num_val_bytes;
238    if (num_bytes > num_data_bytes)
239        num_bytes = num_data_bytes;
240
241    for (size_t byte_idx = 0;
242         byte_idx < num_bytes;
243         ++byte_idx)
244    {
245        uint64_t shift = byte_idx * 8;
246        uint64_t mask = 0xffll << shift;
247        uint8_t cur_byte = (uint8_t)((value64 & mask) >> shift);
248
249        switch (m_parser_vars->m_target_info.byte_order)
250        {
251            case eByteOrderBig:
252                //                    High         Low
253                // Original:         |AABBCCDDEEFFGGHH|
254                // Target:                   |EEFFGGHH|
255
256                pvar_data[num_data_bytes - (1 + byte_idx)] = cur_byte;
257                break;
258            case eByteOrderLittle:
259                // Target:                   |HHGGFFEE|
260                pvar_data[byte_idx] = cur_byte;
261                break;
262            default:
263                return lldb::ClangExpressionVariableSP();
264        }
265    }
266
267    pvar_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried;
268    pvar_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
269    pvar_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
270
271    return pvar_sp;
272}
273
274lldb::ClangExpressionVariableSP
275ClangExpressionDeclMap::BuildCastVariable (const ConstString &name,
276                                           VarDecl *decl,
277                                           lldb_private::TypeFromParser type)
278{
279    assert (m_parser_vars.get());
280
281    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
282
283    ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
284    Target *target = exe_ctx.GetTargetPtr();
285    if (target == NULL)
286        return lldb::ClangExpressionVariableSP();
287
288    ASTContext *context(target->GetScratchClangASTContext()->getASTContext());
289
290    ClangExpressionVariableSP var_sp (m_found_entities.GetVariable(decl));
291
292    if (!var_sp)
293        var_sp = m_parser_vars->m_persistent_vars->GetVariable(decl);
294
295    if (!var_sp)
296        return ClangExpressionVariableSP();
297
298    TypeFromUser user_type(m_ast_importer->CopyType(context,
299                                                    type.GetASTContext(),
300                                                    type.GetOpaqueQualType()),
301                           context);
302
303    if (!user_type.GetOpaqueQualType())
304    {
305        lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
306
307        if (log)
308            log->Printf("ClangExpressionDeclMap::BuildCastVariable - Couldn't export the type for a constant cast result");
309
310        return lldb::ClangExpressionVariableSP();
311    }
312
313    TypeFromUser var_type = var_sp->GetTypeFromUser();
314
315    StackFrame *frame = exe_ctx.GetFramePtr();
316    if (frame == NULL)
317        return lldb::ClangExpressionVariableSP();
318
319    VariableSP var = FindVariableInScope (*frame, var_sp->GetName(), &var_type);
320
321    if (!var)
322        return lldb::ClangExpressionVariableSP(); // but we should handle this; it may be a persistent variable
323
324    ValueObjectSP var_valobj = frame->GetValueObjectForFrameVariable(var, lldb::eNoDynamicValues);
325
326    if (!var_valobj)
327        return lldb::ClangExpressionVariableSP();
328
329    ValueObjectSP var_casted_valobj = var_valobj->CastPointerType(name.GetCString(), user_type);
330
331    if (!var_casted_valobj)
332        return lldb::ClangExpressionVariableSP();
333
334    if (log)
335    {
336        StreamString my_stream_string;
337
338        ClangASTType::DumpTypeDescription (var_type.GetASTContext(),
339                                           var_type.GetOpaqueQualType(),
340                                           &my_stream_string);
341
342
343        log->Printf("Building cast variable to type: %s", my_stream_string.GetString().c_str());
344    }
345
346    ClangExpressionVariableSP pvar_sp = m_parser_vars->m_persistent_vars->CreatePersistentVariable (var_casted_valobj);
347
348    if (!pvar_sp)
349        return lldb::ClangExpressionVariableSP();
350
351    if (pvar_sp != m_parser_vars->m_persistent_vars->GetVariable(name))
352        return lldb::ClangExpressionVariableSP();
353
354    pvar_sp->m_flags |= ClangExpressionVariable::EVIsFreezeDried;
355    pvar_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
356    pvar_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
357
358    return pvar_sp;
359}
360
361bool
362ClangExpressionDeclMap::ResultIsReference (const ConstString &name)
363{
364    ClangExpressionVariableSP pvar_sp = m_parser_vars->m_persistent_vars->GetVariable(name);
365
366    return (pvar_sp->m_flags & ClangExpressionVariable::EVIsProgramReference);
367}
368
369bool
370ClangExpressionDeclMap::CompleteResultVariable (lldb::ClangExpressionVariableSP &valobj,
371                                                lldb_private::Value &value,
372                                                const ConstString &name,
373                                                lldb_private::TypeFromParser type,
374                                                bool transient,
375                                                bool maybe_make_load)
376{
377    assert (m_parser_vars.get());
378
379    ClangExpressionVariableSP pvar_sp = m_parser_vars->m_persistent_vars->GetVariable(name);
380
381    if (!pvar_sp)
382        return false;
383
384    if (maybe_make_load &&
385        value.GetValueType() == Value::eValueTypeFileAddress &&
386        m_parser_vars->m_exe_ctx.GetProcessPtr())
387    {
388        value.SetValueType(Value::eValueTypeLoadAddress);
389    }
390
391    if (pvar_sp->m_flags & ClangExpressionVariable::EVIsProgramReference &&
392        !pvar_sp->m_live_sp &&
393        !transient)
394    {
395        // The reference comes from the program.  We need to set up a live SP for it.
396
397        unsigned long long address = value.GetScalar().ULongLong();
398        AddressType address_type = value.GetValueAddressType();
399
400        pvar_sp->m_live_sp = ValueObjectConstResult::Create(m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
401                                                            pvar_sp->GetTypeFromUser().GetASTContext(),
402                                                            pvar_sp->GetTypeFromUser().GetOpaqueQualType(),
403                                                            pvar_sp->GetName(),
404                                                            address,
405                                                            address_type,
406                                                            pvar_sp->GetByteSize());
407    }
408
409    if (pvar_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry)
410    {
411        pvar_sp->ValueUpdated();
412
413        const size_t pvar_byte_size = pvar_sp->GetByteSize();
414        uint8_t *pvar_data = pvar_sp->GetValueBytes();
415
416        if (!ReadTarget(pvar_data, value, pvar_byte_size))
417            return false;
418
419        pvar_sp->m_flags &= ~(ClangExpressionVariable::EVNeedsFreezeDry);
420    }
421
422    valobj = pvar_sp;
423
424    return true;
425}
426
427void
428ClangExpressionDeclMap::RemoveResultVariable
429(
430    const ConstString &name
431)
432{
433    ClangExpressionVariableSP pvar_sp = m_parser_vars->m_persistent_vars->GetVariable(name);
434    m_parser_vars->m_persistent_vars->RemovePersistentVariable(pvar_sp);
435}
436
437bool
438ClangExpressionDeclMap::AddPersistentVariable
439(
440    const NamedDecl *decl,
441    const ConstString &name,
442    TypeFromParser parser_type,
443    bool is_result,
444    bool is_lvalue
445)
446{
447    assert (m_parser_vars.get());
448
449    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
450    ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
451    Target *target = exe_ctx.GetTargetPtr();
452    if (target == NULL)
453        return false;
454
455    ASTContext *context(target->GetScratchClangASTContext()->getASTContext());
456
457    TypeFromUser user_type(m_ast_importer->DeportType(context,
458                                                      parser_type.GetASTContext(),
459                                                      parser_type.GetOpaqueQualType()),
460                           context);
461
462    if (!user_type.GetOpaqueQualType())
463    {
464        if (log)
465            log->Printf("Persistent variable's type wasn't copied successfully");
466        return false;
467    }
468
469    if (!m_parser_vars->m_target_info.IsValid())
470        return false;
471
472    if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (exe_ctx.GetBestExecutionContextScope (),
473                                                                     name,
474                                                                     user_type,
475                                                                     m_parser_vars->m_target_info.byte_order,
476                                                                     m_parser_vars->m_target_info.address_byte_size))
477        return false;
478
479    ClangExpressionVariableSP var_sp (m_parser_vars->m_persistent_vars->GetVariable(name));
480
481    if (!var_sp)
482        return false;
483
484    var_sp->m_frozen_sp->SetHasCompleteType();
485
486    if (is_result)
487        var_sp->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
488    else
489        var_sp->m_flags |= ClangExpressionVariable::EVKeepInTarget; // explicitly-declared persistent variables should persist
490
491    if (is_lvalue)
492    {
493        var_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference;
494    }
495    else
496    {
497        var_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
498        var_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
499    }
500
501    if (log)
502        log->Printf("Created persistent variable with flags 0x%hx", var_sp->m_flags);
503
504    var_sp->EnableParserVars();
505
506    var_sp->m_parser_vars->m_named_decl = decl;
507    var_sp->m_parser_vars->m_parser_type = parser_type;
508
509    return true;
510}
511
512bool
513ClangExpressionDeclMap::AddValueToStruct
514(
515    const NamedDecl *decl,
516    const ConstString &name,
517    llvm::Value *value,
518    size_t size,
519    off_t alignment
520)
521{
522    assert (m_struct_vars.get());
523    assert (m_parser_vars.get());
524
525    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
526
527    m_struct_vars->m_struct_laid_out = false;
528
529    if (m_struct_members.GetVariable(decl))
530        return true;
531
532    ClangExpressionVariableSP var_sp (m_found_entities.GetVariable(decl));
533
534    if (!var_sp)
535        var_sp = m_parser_vars->m_persistent_vars->GetVariable(decl);
536
537    if (!var_sp)
538        return false;
539
540    if (log)
541        log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure",
542                    decl,
543                    name.GetCString(),
544                    var_sp->GetName().GetCString());
545
546    // We know entity->m_parser_vars is valid because we used a parser variable
547    // to find it
548    var_sp->m_parser_vars->m_llvm_value = value;
549
550    var_sp->EnableJITVars();
551    var_sp->m_jit_vars->m_alignment = alignment;
552    var_sp->m_jit_vars->m_size = size;
553
554    m_struct_members.AddVariable(var_sp);
555
556    return true;
557}
558
559bool
560ClangExpressionDeclMap::DoStructLayout ()
561{
562    assert (m_struct_vars.get());
563
564    if (m_struct_vars->m_struct_laid_out)
565        return true;
566
567    off_t cursor = 0;
568
569    m_struct_vars->m_struct_alignment = 0;
570    m_struct_vars->m_struct_size = 0;
571
572    for (size_t member_index = 0, num_members = m_struct_members.GetSize();
573         member_index < num_members;
574         ++member_index)
575    {
576        ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index));
577        if (!member_sp)
578            return false;
579
580        if (!member_sp->m_jit_vars.get())
581            return false;
582
583        if (member_index == 0)
584            m_struct_vars->m_struct_alignment = member_sp->m_jit_vars->m_alignment;
585
586        if (cursor % member_sp->m_jit_vars->m_alignment)
587            cursor += (member_sp->m_jit_vars->m_alignment - (cursor % member_sp->m_jit_vars->m_alignment));
588
589        member_sp->m_jit_vars->m_offset = cursor;
590        cursor += member_sp->m_jit_vars->m_size;
591    }
592
593    m_struct_vars->m_struct_size = cursor;
594
595    m_struct_vars->m_struct_laid_out = true;
596    return true;
597}
598
599bool ClangExpressionDeclMap::GetStructInfo
600(
601    uint32_t &num_elements,
602    size_t &size,
603    off_t &alignment
604)
605{
606    assert (m_struct_vars.get());
607
608    if (!m_struct_vars->m_struct_laid_out)
609        return false;
610
611    num_elements = m_struct_members.GetSize();
612    size = m_struct_vars->m_struct_size;
613    alignment = m_struct_vars->m_struct_alignment;
614
615    return true;
616}
617
618bool
619ClangExpressionDeclMap::GetStructElement
620(
621    const NamedDecl *&decl,
622    llvm::Value *&value,
623    off_t &offset,
624    ConstString &name,
625    uint32_t index
626)
627{
628    assert (m_struct_vars.get());
629
630    if (!m_struct_vars->m_struct_laid_out)
631        return false;
632
633    if (index >= m_struct_members.GetSize())
634        return false;
635
636    ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
637
638    if (!member_sp ||
639        !member_sp->m_parser_vars.get() ||
640        !member_sp->m_jit_vars.get() ||
641        !member_sp->GetValueObject())
642        return false;
643
644    decl = member_sp->m_parser_vars->m_named_decl;
645    value = member_sp->m_parser_vars->m_llvm_value;
646    offset = member_sp->m_jit_vars->m_offset;
647    name = member_sp->GetName();
648
649    return true;
650}
651
652bool
653ClangExpressionDeclMap::GetFunctionInfo
654(
655    const NamedDecl *decl,
656    uint64_t &ptr
657)
658{
659    ClangExpressionVariableSP entity_sp(m_found_entities.GetVariable(decl));
660
661    if (!entity_sp)
662        return false;
663
664    // We know m_parser_vars is valid since we searched for the variable by
665    // its NamedDecl
666
667    ptr = entity_sp->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
668
669    return true;
670}
671
672static void
673FindCodeSymbolInContext
674(
675    const ConstString &name,
676    SymbolContext &sym_ctx,
677    SymbolContextList &sc_list
678)
679{
680    if (sym_ctx.module_sp)
681       sym_ctx.module_sp->FindSymbolsWithNameAndType(name, eSymbolTypeCode, sc_list);
682
683    if (!sc_list.GetSize())
684        sym_ctx.target_sp->GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeCode, sc_list);
685}
686
687bool
688ClangExpressionDeclMap::GetFunctionAddress
689(
690    const ConstString &name,
691    uint64_t &func_addr
692)
693{
694    assert (m_parser_vars.get());
695
696    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
697    ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
698    Target *target = exe_ctx.GetTargetPtr();
699    // Back out in all cases where we're not fully initialized
700    if (target == NULL)
701        return false;
702    if (!m_parser_vars->m_sym_ctx.target_sp)
703        return false;
704
705    SymbolContextList sc_list;
706
707    FindCodeSymbolInContext(name, m_parser_vars->m_sym_ctx, sc_list);
708
709    if (!sc_list.GetSize())
710    {
711        // We occasionally get debug information in which a const function is reported
712        // as non-const, so the mangled name is wrong.  This is a hack to compensate.
713
714        if (!strncmp(name.GetCString(), "_ZN", 3) &&
715            strncmp(name.GetCString(), "_ZNK", 4))
716        {
717            std::string fixed_scratch("_ZNK");
718            fixed_scratch.append(name.GetCString() + 3);
719            ConstString fixed_name(fixed_scratch.c_str());
720
721            if (log)
722                log->Printf("Failed to find symbols given non-const name %s; trying %s", name.GetCString(), fixed_name.GetCString());
723
724            FindCodeSymbolInContext(fixed_name, m_parser_vars->m_sym_ctx, sc_list);
725        }
726    }
727
728    if (!sc_list.GetSize())
729        return false;
730
731    SymbolContext sym_ctx;
732    sc_list.GetContextAtIndex(0, sym_ctx);
733
734    const Address *func_so_addr = NULL;
735
736    if (sym_ctx.function)
737        func_so_addr = &sym_ctx.function->GetAddressRange().GetBaseAddress();
738    else if (sym_ctx.symbol)
739        func_so_addr = &sym_ctx.symbol->GetAddress();
740    else
741        return false;
742
743    if (!func_so_addr || !func_so_addr->IsValid())
744        return false;
745
746    func_addr = func_so_addr->GetCallableLoadAddress (target);
747
748    return true;
749}
750
751addr_t
752ClangExpressionDeclMap::GetSymbolAddress (Target &target, const ConstString &name, lldb::SymbolType symbol_type)
753{
754    SymbolContextList sc_list;
755
756    target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);
757
758    const uint32_t num_matches = sc_list.GetSize();
759    addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
760
761    for (uint32_t i=0; i<num_matches && (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS); i++)
762    {
763        SymbolContext sym_ctx;
764        sc_list.GetContextAtIndex(i, sym_ctx);
765
766        const Address *sym_address = &sym_ctx.symbol->GetAddress();
767
768        if (!sym_address || !sym_address->IsValid())
769            return LLDB_INVALID_ADDRESS;
770
771        if (sym_address)
772        {
773            switch (sym_ctx.symbol->GetType())
774            {
775                case eSymbolTypeCode:
776                case eSymbolTypeTrampoline:
777                    symbol_load_addr = sym_address->GetCallableLoadAddress (&target);
778                    break;
779
780                case eSymbolTypeData:
781                case eSymbolTypeRuntime:
782                case eSymbolTypeVariable:
783                case eSymbolTypeLocal:
784                case eSymbolTypeParam:
785                case eSymbolTypeInvalid:
786                case eSymbolTypeAbsolute:
787                case eSymbolTypeException:
788                case eSymbolTypeSourceFile:
789                case eSymbolTypeHeaderFile:
790                case eSymbolTypeObjectFile:
791                case eSymbolTypeCommonBlock:
792                case eSymbolTypeBlock:
793                case eSymbolTypeVariableType:
794                case eSymbolTypeLineEntry:
795                case eSymbolTypeLineHeader:
796                case eSymbolTypeScopeBegin:
797                case eSymbolTypeScopeEnd:
798                case eSymbolTypeAdditional:
799                case eSymbolTypeCompiler:
800                case eSymbolTypeInstrumentation:
801                case eSymbolTypeUndefined:
802                case eSymbolTypeObjCClass:
803                case eSymbolTypeObjCMetaClass:
804                case eSymbolTypeObjCIVar:
805                    symbol_load_addr = sym_address->GetLoadAddress (&target);
806                    break;
807            }
808        }
809    }
810
811    return symbol_load_addr;
812}
813
814addr_t
815ClangExpressionDeclMap::GetSymbolAddress (const ConstString &name, lldb::SymbolType symbol_type)
816{
817    assert (m_parser_vars.get());
818
819    if (!m_parser_vars->m_exe_ctx.GetTargetPtr())
820        return false;
821
822    return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(), name, symbol_type);
823}
824
825// Interface for IRInterpreter
826
827Value
828ClangExpressionDeclMap::WrapBareAddress (lldb::addr_t addr)
829{
830    Value ret;
831
832    ret.SetContext(Value::eContextTypeInvalid, NULL);
833
834    if (m_parser_vars->m_exe_ctx.GetProcessPtr())
835        ret.SetValueType(Value::eValueTypeLoadAddress);
836    else
837        ret.SetValueType(Value::eValueTypeFileAddress);
838
839    ret.GetScalar() = (unsigned long long)addr;
840
841    return ret;
842}
843
844bool
845ClangExpressionDeclMap::WriteTarget (lldb_private::Value &value,
846                                     const uint8_t *data,
847                                     size_t length)
848{
849    assert (m_parser_vars.get());
850
851    ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
852
853    Process *process = exe_ctx.GetProcessPtr();
854    if (value.GetContextType() == Value::eContextTypeRegisterInfo)
855    {
856        if (!process)
857            return false;
858
859        RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
860        RegisterInfo *reg_info = value.GetRegisterInfo();
861
862        if (!reg_ctx)
863            return false;
864
865        lldb_private::RegisterValue reg_value;
866        Error err;
867
868        if (!reg_value.SetFromMemoryData (reg_info, data, length, process->GetByteOrder(), err))
869            return false;
870
871        return reg_ctx->WriteRegister(reg_info, reg_value);
872    }
873    else
874    {
875        switch (value.GetValueType())
876        {
877        default:
878            return false;
879        case Value::eValueTypeFileAddress:
880            {
881                if (!process)
882                    return false;
883
884                Target *target = exe_ctx.GetTargetPtr();
885                Address file_addr;
886
887                if (!target->GetImages().ResolveFileAddress((lldb::addr_t)value.GetScalar().ULongLong(), file_addr))
888                    return false;
889
890                lldb::addr_t load_addr = file_addr.GetLoadAddress(target);
891
892                Error err;
893                process->WriteMemory(load_addr, data, length, err);
894
895                return err.Success();
896            }
897        case Value::eValueTypeLoadAddress:
898            {
899                if (!process)
900                    return false;
901
902                Error err;
903                process->WriteMemory((lldb::addr_t)value.GetScalar().ULongLong(), data, length, err);
904
905                return err.Success();
906            }
907        case Value::eValueTypeHostAddress:
908            {
909                if (value.GetScalar().ULongLong() == 0 || data == NULL)
910                    return false;
911                memcpy ((void *)value.GetScalar().ULongLong(), data, length);
912                return true;
913            }
914        case Value::eValueTypeScalar:
915            return false;
916        }
917    }
918}
919
920bool
921ClangExpressionDeclMap::ReadTarget (uint8_t *data,
922                                    lldb_private::Value &value,
923                                    size_t length)
924{
925    assert (m_parser_vars.get());
926
927    ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
928
929    Process *process = exe_ctx.GetProcessPtr();
930
931    if (value.GetContextType() == Value::eContextTypeRegisterInfo)
932    {
933        if (!process)
934            return false;
935
936        RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
937        RegisterInfo *reg_info = value.GetRegisterInfo();
938
939        if (!reg_ctx)
940            return false;
941
942        lldb_private::RegisterValue reg_value;
943        Error err;
944
945        if (!reg_ctx->ReadRegister(reg_info, reg_value))
946            return false;
947
948        return reg_value.GetAsMemoryData(reg_info, data, length, process->GetByteOrder(), err);
949    }
950    else
951    {
952        switch (value.GetValueType())
953        {
954            default:
955                return false;
956            case Value::eValueTypeFileAddress:
957            {
958                Target *target = exe_ctx.GetTargetPtr();
959                if (target == NULL)
960                    return false;
961
962                Address file_addr;
963
964                if (!target->GetImages().ResolveFileAddress((lldb::addr_t)value.GetScalar().ULongLong(), file_addr))
965                    return false;
966
967                Error err;
968                target->ReadMemory(file_addr, false, data, length, err);
969
970                return err.Success();
971            }
972            case Value::eValueTypeLoadAddress:
973            {
974                if (!process)
975                    return false;
976
977                Error err;
978                process->ReadMemory((lldb::addr_t)value.GetScalar().ULongLong(), data, length, err);
979
980                return err.Success();
981            }
982            case Value::eValueTypeHostAddress:
983            {
984                void *host_addr = (void*)value.GetScalar().ULongLong();
985
986                if (!host_addr)
987                    return false;
988
989                memcpy (data, host_addr, length);
990                return true;
991            }
992            case Value::eValueTypeScalar:
993                return false;
994        }
995    }
996}
997
998lldb_private::Value
999ClangExpressionDeclMap::LookupDecl (clang::NamedDecl *decl, ClangExpressionVariable::FlagType &flags)
1000{
1001    assert (m_parser_vars.get());
1002
1003    ClangExpressionVariableSP expr_var_sp (m_found_entities.GetVariable(decl));
1004    ClangExpressionVariableSP persistent_var_sp (m_parser_vars->m_persistent_vars->GetVariable(decl));
1005
1006    if (expr_var_sp)
1007    {
1008        flags = expr_var_sp->m_flags;
1009
1010        if (!expr_var_sp->m_parser_vars.get())
1011            return Value();
1012
1013        bool is_reference = expr_var_sp->m_flags & ClangExpressionVariable::EVTypeIsReference;
1014
1015        if (expr_var_sp->m_parser_vars->m_lldb_var)
1016        {
1017            std::auto_ptr<Value> value(GetVariableValue(expr_var_sp->m_parser_vars->m_lldb_var, NULL));
1018
1019            if (is_reference && value.get() && value->GetValueType() == Value::eValueTypeLoadAddress)
1020            {
1021                Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr();
1022
1023                if (!process)
1024                    return Value();
1025
1026                lldb::addr_t value_addr = value->GetScalar().ULongLong();
1027                Error read_error;
1028                addr_t ref_value = process->ReadPointerFromMemory (value_addr, read_error);
1029
1030                if (!read_error.Success())
1031                    return Value();
1032
1033                value->GetScalar() = (unsigned long long)ref_value;
1034            }
1035
1036            if (value.get())
1037                return *value;
1038            else
1039                return Value();
1040        }
1041        else if (expr_var_sp->m_parser_vars->m_lldb_sym)
1042        {
1043            const Address sym_address = expr_var_sp->m_parser_vars->m_lldb_sym->GetAddress();
1044
1045            if (!sym_address.IsValid())
1046                return Value();
1047
1048            Value ret;
1049
1050            ProcessSP process_sp (m_parser_vars->m_exe_ctx.GetProcessSP());
1051
1052            if (process_sp)
1053            {
1054                uint64_t symbol_load_addr = sym_address.GetLoadAddress(&process_sp->GetTarget());
1055
1056                ret.GetScalar() = symbol_load_addr;
1057                ret.SetValueType(Value::eValueTypeLoadAddress);
1058            }
1059            else
1060            {
1061                uint64_t symbol_file_addr = sym_address.GetFileAddress();
1062
1063                ret.GetScalar() = symbol_file_addr;
1064                ret.SetValueType(Value::eValueTypeFileAddress);
1065            }
1066
1067            return ret;
1068        }
1069        else if (RegisterInfo *reg_info = expr_var_sp->GetRegisterInfo())
1070        {
1071            StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1072
1073            if (!frame)
1074                return Value();
1075
1076            RegisterContextSP reg_context_sp(frame->GetRegisterContextSP());
1077
1078            RegisterValue reg_value;
1079
1080            if (!reg_context_sp->ReadRegister(reg_info, reg_value))
1081                return Value();
1082
1083            Value ret;
1084
1085            ret.SetContext(Value::eContextTypeRegisterInfo, reg_info);
1086            if (!reg_value.GetScalarValue(ret.GetScalar()))
1087                return Value();
1088
1089            return ret;
1090        }
1091        else
1092        {
1093            return Value();
1094        }
1095    }
1096    else if (persistent_var_sp)
1097    {
1098        flags = persistent_var_sp->m_flags;
1099
1100        if ((persistent_var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference ||
1101             persistent_var_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) &&
1102            persistent_var_sp->m_live_sp &&
1103            ((persistent_var_sp->m_live_sp->GetValue().GetValueType() == Value::eValueTypeLoadAddress &&
1104              m_parser_vars->m_exe_ctx.GetProcessSP() &&
1105              m_parser_vars->m_exe_ctx.GetProcessSP()->IsAlive()) ||
1106             (persistent_var_sp->m_live_sp->GetValue().GetValueType() == Value::eValueTypeFileAddress)))
1107        {
1108            return persistent_var_sp->m_live_sp->GetValue();
1109        }
1110        else
1111        {
1112            lldb_private::Value ret;
1113            ret.SetValueType(Value::eValueTypeHostAddress);
1114            ret.SetContext(Value::eContextTypeInvalid, NULL);
1115            ret.GetScalar() = (lldb::addr_t)persistent_var_sp->GetValueBytes();
1116            return ret;
1117        }
1118    }
1119    else
1120    {
1121        return Value();
1122    }
1123}
1124
1125Value
1126ClangExpressionDeclMap::GetSpecialValue (const ConstString &name)
1127{
1128    assert(m_parser_vars.get());
1129
1130    StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1131
1132    if (!frame)
1133        return Value();
1134
1135    VariableList *vars = frame->GetVariableList(false);
1136
1137    if (!vars)
1138        return Value();
1139
1140    lldb::VariableSP var = vars->FindVariable(name);
1141
1142    if (!var ||
1143        !var->IsInScope(frame) ||
1144        !var->LocationIsValidForFrame (frame))
1145        return Value();
1146
1147    std::auto_ptr<Value> value(GetVariableValue(var, NULL));
1148
1149    if (value.get() && value->GetValueType() == Value::eValueTypeLoadAddress)
1150    {
1151        Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr();
1152
1153        if (!process)
1154            return Value();
1155
1156        lldb::addr_t value_addr = value->GetScalar().ULongLong();
1157        Error read_error;
1158        addr_t ptr_value = process->ReadPointerFromMemory (value_addr, read_error);
1159
1160        if (!read_error.Success())
1161            return Value();
1162
1163        value->GetScalar() = (unsigned long long)ptr_value;
1164    }
1165
1166    if (value.get())
1167        return *value;
1168    else
1169        return Value();
1170}
1171
1172// Interface for CommandObjectExpression
1173
1174bool
1175ClangExpressionDeclMap::Materialize
1176(
1177    lldb::addr_t &struct_address,
1178    Error &err
1179)
1180{
1181    if (!m_parser_vars.get())
1182        return false;
1183
1184    EnableMaterialVars();
1185
1186    m_material_vars->m_process = m_parser_vars->m_exe_ctx.GetProcessPtr();
1187
1188    bool result = DoMaterialize(false /* dematerialize */,
1189                                LLDB_INVALID_ADDRESS /* top of stack frame */,
1190                                LLDB_INVALID_ADDRESS /* bottom of stack frame */,
1191                                NULL, /* result SP */
1192                                err);
1193
1194    if (result)
1195        struct_address = m_material_vars->m_materialized_location;
1196
1197    return result;
1198}
1199
1200bool
1201ClangExpressionDeclMap::GetObjectPointer
1202(
1203    lldb::addr_t &object_ptr,
1204    ConstString &object_name,
1205    Error &err,
1206    bool suppress_type_check
1207)
1208{
1209    assert (m_struct_vars.get());
1210
1211    Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1212    Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr();
1213    StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1214
1215    if (frame == NULL || process == NULL || target == NULL)
1216    {
1217        err.SetErrorStringWithFormat("Couldn't load '%s' because the context is incomplete", object_name.AsCString());
1218        return false;
1219    }
1220
1221    if (!m_struct_vars->m_object_pointer_type.GetOpaqueQualType())
1222    {
1223        err.SetErrorStringWithFormat("Couldn't load '%s' because its type is unknown", object_name.AsCString());
1224        return false;
1225    }
1226
1227    const bool object_pointer = true;
1228
1229    VariableSP object_ptr_var = FindVariableInScope (*frame,
1230                                                     object_name,
1231                                                     (suppress_type_check ? NULL : &m_struct_vars->m_object_pointer_type),
1232                                                     object_pointer);
1233
1234    if (!object_ptr_var)
1235    {
1236        err.SetErrorStringWithFormat("Couldn't find '%s' with appropriate type in scope", object_name.AsCString());
1237        return false;
1238    }
1239
1240    std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(object_ptr_var,
1241                                                                       NULL));
1242
1243    if (!location_value.get())
1244    {
1245        err.SetErrorStringWithFormat("Couldn't get the location for '%s'", object_name.GetCString());
1246        return false;
1247    }
1248
1249    switch (location_value->GetValueType())
1250    {
1251    default:
1252        err.SetErrorStringWithFormat("'%s' is not in memory; LLDB must be extended to handle registers", object_name.GetCString());
1253        return false;
1254    case Value::eValueTypeLoadAddress:
1255        {
1256            lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
1257            uint32_t address_byte_size = target->GetArchitecture().GetAddressByteSize();
1258
1259            if (ClangASTType::GetClangTypeBitWidth(m_struct_vars->m_object_pointer_type.GetASTContext(),
1260                                                   m_struct_vars->m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
1261            {
1262                err.SetErrorStringWithFormat("'%s' is not of an expected pointer size", object_name.GetCString());
1263                return false;
1264            }
1265
1266            Error read_error;
1267            object_ptr = process->ReadPointerFromMemory (value_addr, read_error);
1268            if (read_error.Fail() || object_ptr == LLDB_INVALID_ADDRESS)
1269            {
1270                err.SetErrorStringWithFormat("Coldn't read '%s' from the target: %s", object_name.GetCString(), read_error.AsCString());
1271                return false;
1272            }
1273            return true;
1274        }
1275    case Value::eValueTypeScalar:
1276        {
1277            if (location_value->GetContextType() != Value::eContextTypeRegisterInfo)
1278            {
1279                StreamString ss;
1280                location_value->Dump(&ss);
1281
1282                err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", object_name.GetCString(), ss.GetString().c_str());
1283                return false;
1284            }
1285
1286            RegisterInfo *reg_info = location_value->GetRegisterInfo();
1287
1288            if (!reg_info)
1289            {
1290                err.SetErrorStringWithFormat("Couldn't get the register information for %s", object_name.GetCString());
1291                return false;
1292            }
1293
1294            RegisterContext *reg_ctx = m_parser_vars->m_exe_ctx.GetRegisterContext();
1295
1296            if (!reg_ctx)
1297            {
1298                err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", object_name.GetCString(), reg_info->name);
1299                return false;
1300            }
1301
1302            uint32_t register_number = reg_info->kinds[lldb::eRegisterKindLLDB];
1303
1304            object_ptr = reg_ctx->ReadRegisterAsUnsigned(register_number, 0x0);
1305
1306            return true;
1307        }
1308    }
1309}
1310
1311bool
1312ClangExpressionDeclMap::Dematerialize
1313(
1314    ClangExpressionVariableSP &result_sp,
1315    lldb::addr_t stack_frame_top,
1316    lldb::addr_t stack_frame_bottom,
1317    Error &err
1318)
1319{
1320    return DoMaterialize(true, stack_frame_top, stack_frame_bottom, &result_sp, err);
1321
1322    DidDematerialize();
1323}
1324
1325void
1326ClangExpressionDeclMap::DidDematerialize()
1327{
1328    if (m_material_vars.get())
1329    {
1330        if (m_material_vars->m_materialized_location)
1331        {
1332            //#define SINGLE_STEP_EXPRESSIONS
1333
1334#ifndef SINGLE_STEP_EXPRESSIONS
1335            m_material_vars->m_process->DeallocateMemory(m_material_vars->m_materialized_location);
1336#endif
1337            m_material_vars->m_materialized_location = 0;
1338        }
1339
1340        DisableMaterialVars();
1341    }
1342}
1343
1344bool
1345ClangExpressionDeclMap::DumpMaterializedStruct
1346(
1347    Stream &s,
1348    Error &err
1349)
1350{
1351    assert (m_struct_vars.get());
1352    assert (m_material_vars.get());
1353
1354    if (!m_struct_vars->m_struct_laid_out)
1355    {
1356        err.SetErrorString("Structure hasn't been laid out yet");
1357        return false;
1358    }
1359    Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr();
1360
1361    if (!process)
1362    {
1363        err.SetErrorString("Couldn't find the process");
1364        return false;
1365    }
1366
1367    Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1368    if (!target)
1369    {
1370        err.SetErrorString("Couldn't find the target");
1371        return false;
1372    }
1373
1374    if (!m_material_vars->m_materialized_location)
1375    {
1376        err.SetErrorString("No materialized location");
1377        return false;
1378    }
1379
1380    lldb::DataBufferSP data_sp(new DataBufferHeap(m_struct_vars->m_struct_size, 0));
1381
1382    Error error;
1383    if (process->ReadMemory (m_material_vars->m_materialized_location,
1384                                     data_sp->GetBytes(),
1385                                     data_sp->GetByteSize(), error) != data_sp->GetByteSize())
1386    {
1387        err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
1388        return false;
1389    }
1390
1391    DataExtractor extractor(data_sp, process->GetByteOrder(), target->GetArchitecture().GetAddressByteSize());
1392
1393    for (size_t member_idx = 0, num_members = m_struct_members.GetSize();
1394         member_idx < num_members;
1395         ++member_idx)
1396    {
1397        ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_idx));
1398
1399        if (!member_sp)
1400            return false;
1401
1402        s.Printf("[%s]\n", member_sp->GetName().GetCString());
1403
1404        if (!member_sp->m_jit_vars.get())
1405            return false;
1406
1407        extractor.Dump (&s,                                                                          // stream
1408                        member_sp->m_jit_vars->m_offset,                                             // offset
1409                        lldb::eFormatBytesWithASCII,                                                 // format
1410                        1,                                                                           // byte size of individual entries
1411                        member_sp->m_jit_vars->m_size,                                               // number of entries
1412                        16,                                                                          // entries per line
1413                        m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset,  // address to print
1414                        0,                                                                           // bit size (bitfields only; 0 means ignore)
1415                        0);                                                                          // bit alignment (bitfields only; 0 means ignore)
1416
1417        s.PutChar('\n');
1418    }
1419
1420    return true;
1421}
1422
1423bool
1424ClangExpressionDeclMap::DoMaterialize
1425(
1426    bool dematerialize,
1427    lldb::addr_t stack_frame_top,
1428    lldb::addr_t stack_frame_bottom,
1429    lldb::ClangExpressionVariableSP *result_sp_ptr,
1430    Error &err
1431)
1432{
1433    if (result_sp_ptr)
1434        result_sp_ptr->reset();
1435
1436    assert (m_struct_vars.get());
1437
1438    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1439
1440    if (!m_struct_vars->m_struct_laid_out)
1441    {
1442        err.SetErrorString("Structure hasn't been laid out yet");
1443        return false;
1444    }
1445
1446    StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1447    if (!frame)
1448    {
1449        err.SetErrorString("Received null execution frame");
1450        return false;
1451    }
1452    Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1453
1454    ClangPersistentVariables &persistent_vars = target->GetPersistentVariables();
1455
1456    if (!m_struct_vars->m_struct_size)
1457    {
1458        if (log)
1459            log->PutCString("Not bothering to allocate a struct because no arguments are needed");
1460
1461        m_material_vars->m_allocated_area = 0UL;
1462
1463        return true;
1464    }
1465
1466    const SymbolContext &sym_ctx(frame->GetSymbolContext(lldb::eSymbolContextEverything));
1467
1468    if (!dematerialize)
1469    {
1470        Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr();
1471        if (m_material_vars->m_materialized_location)
1472        {
1473            process->DeallocateMemory(m_material_vars->m_materialized_location);
1474            m_material_vars->m_materialized_location = 0;
1475        }
1476
1477        if (log)
1478            log->PutCString("Allocating memory for materialized argument struct");
1479
1480        lldb::addr_t mem = process->AllocateMemory(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size,
1481                                                   lldb::ePermissionsReadable | lldb::ePermissionsWritable,
1482                                                   err);
1483
1484        if (mem == LLDB_INVALID_ADDRESS)
1485        {
1486            err.SetErrorStringWithFormat("Couldn't allocate 0x%llx bytes for materialized argument struct",
1487                                         (unsigned long long)(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size));
1488            return false;
1489        }
1490
1491        m_material_vars->m_allocated_area = mem;
1492    }
1493
1494    m_material_vars->m_materialized_location = m_material_vars->m_allocated_area;
1495
1496    if (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment)
1497        m_material_vars->m_materialized_location += (m_struct_vars->m_struct_alignment - (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment));
1498
1499    for (uint64_t member_index = 0, num_members = m_struct_members.GetSize();
1500         member_index < num_members;
1501         ++member_index)
1502    {
1503        ClangExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(member_index));
1504
1505        if (m_found_entities.ContainsVariable (member_sp))
1506        {
1507            if (!member_sp->GetValueObject())
1508            {
1509                err.SetErrorString("Variable being materialized doesn't have a frozen version");
1510                return false;
1511            }
1512
1513            RegisterInfo *reg_info = member_sp->GetRegisterInfo ();
1514            if (reg_info)
1515            {
1516                // This is a register variable
1517
1518                RegisterContext *reg_ctx = m_parser_vars->m_exe_ctx.GetRegisterContext();
1519
1520                if (!reg_ctx)
1521                {
1522                    err.SetErrorString("Couldn't get register context");
1523                    return false;
1524                }
1525
1526                if (!DoMaterializeOneRegister (dematerialize,
1527                                               *reg_ctx,
1528                                               *reg_info,
1529                                               m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset,
1530                                               err))
1531                    return false;
1532            }
1533            else
1534            {
1535                if (!member_sp->m_jit_vars.get())
1536                {
1537                    err.SetErrorString("Variable being materialized doesn't have necessary state");
1538                    return false;
1539                }
1540
1541                if (!DoMaterializeOneVariable (dematerialize,
1542                                               sym_ctx,
1543                                               member_sp,
1544                                               m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset,
1545                                               err))
1546                    return false;
1547            }
1548        }
1549        else
1550        {
1551            // No need to look for presistent variables if the name doesn't start
1552            // with with a '$' character...
1553            if (member_sp->GetName().AsCString ("!")[0] == '$' && persistent_vars.ContainsVariable(member_sp))
1554            {
1555
1556                if (member_sp->GetName() == m_struct_vars->m_result_name)
1557                {
1558                    if (log)
1559                        log->PutCString("Found result member in the struct");
1560
1561                    if (result_sp_ptr)
1562                        *result_sp_ptr = member_sp;
1563
1564                }
1565
1566                if (!DoMaterializeOnePersistentVariable (dematerialize,
1567                                                         member_sp,
1568                                                         m_material_vars->m_materialized_location + member_sp->m_jit_vars->m_offset,
1569                                                         stack_frame_top,
1570                                                         stack_frame_bottom,
1571                                                         err))
1572                    return false;
1573            }
1574            else
1575            {
1576                err.SetErrorStringWithFormat("Unexpected variable %s", member_sp->GetName().GetCString());
1577                return false;
1578            }
1579        }
1580    }
1581
1582    return true;
1583}
1584
1585bool
1586ClangExpressionDeclMap::DoMaterializeOnePersistentVariable
1587(
1588    bool dematerialize,
1589    ClangExpressionVariableSP &var_sp,
1590    lldb::addr_t addr,
1591    lldb::addr_t stack_frame_top,
1592    lldb::addr_t stack_frame_bottom,
1593    Error &err
1594)
1595{
1596    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1597
1598    if (!var_sp)
1599    {
1600        err.SetErrorString("Invalid persistent variable");
1601        return LLDB_INVALID_ADDRESS;
1602    }
1603
1604    const size_t pvar_byte_size = var_sp->GetByteSize();
1605
1606    uint8_t *pvar_data = var_sp->GetValueBytes();
1607    if (pvar_data == NULL)
1608    {
1609        err.SetErrorString("Persistent variable being materialized contains no data");
1610        return false;
1611    }
1612
1613    Error error;
1614    Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr();
1615
1616    lldb::addr_t mem; // The address of a spare memory area used to hold the persistent variable.
1617
1618    if (dematerialize)
1619    {
1620        if (log)
1621            log->Printf("Dematerializing persistent variable with flags 0x%hx", var_sp->m_flags);
1622
1623        if ((var_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) ||
1624            (var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference))
1625        {
1626            // Get the location of the target out of the struct.
1627
1628            Error read_error;
1629            mem = process->ReadPointerFromMemory (addr, read_error);
1630
1631            if (mem == LLDB_INVALID_ADDRESS)
1632            {
1633                err.SetErrorStringWithFormat("Couldn't read address of %s from struct: %s", var_sp->GetName().GetCString(), error.AsCString());
1634                return false;
1635            }
1636
1637            if (var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference &&
1638                !var_sp->m_live_sp)
1639            {
1640                // If the reference comes from the program, then the ClangExpressionVariable's
1641                // live variable data hasn't been set up yet.  Do this now.
1642
1643                var_sp->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
1644                                                                    var_sp->GetTypeFromUser().GetASTContext(),
1645                                                                    var_sp->GetTypeFromUser().GetOpaqueQualType(),
1646                                                                    var_sp->GetName(),
1647                                                                    mem,
1648                                                                    eAddressTypeLoad,
1649                                                                    pvar_byte_size);
1650            }
1651
1652            if (!var_sp->m_live_sp)
1653            {
1654                err.SetErrorStringWithFormat("Couldn't find the memory area used to store %s", var_sp->GetName().GetCString());
1655                return false;
1656            }
1657
1658            if (var_sp->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad)
1659            {
1660                err.SetErrorStringWithFormat("The address of the memory area for %s is in an incorrect format", var_sp->GetName().GetCString());
1661                return false;
1662            }
1663
1664            if (var_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry ||
1665                var_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)
1666            {
1667                mem = var_sp->m_live_sp->GetValue().GetScalar().ULongLong();
1668
1669                if (log)
1670                    log->Printf("Dematerializing %s from 0x%llx (size = %u)", var_sp->GetName().GetCString(), (uint64_t)mem, (unsigned)pvar_byte_size);
1671
1672                // Read the contents of the spare memory area
1673
1674                var_sp->ValueUpdated ();
1675                if (process->ReadMemory (mem, pvar_data, pvar_byte_size, error) != pvar_byte_size)
1676                {
1677                    err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
1678                    return false;
1679                }
1680
1681                if (stack_frame_top != LLDB_INVALID_ADDRESS &&
1682                    stack_frame_bottom != LLDB_INVALID_ADDRESS &&
1683                    mem >= stack_frame_bottom &&
1684                    mem <= stack_frame_top)
1685                {
1686                    // If the variable is resident in the stack frame created by the expression,
1687                    // then it cannot be relied upon to stay around.  We treat it as needing
1688                    // reallocation.
1689
1690                    var_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
1691                    var_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
1692                    var_sp->m_flags &= ~ClangExpressionVariable::EVIsProgramReference;
1693                }
1694
1695                var_sp->m_flags &= ~ClangExpressionVariable::EVNeedsFreezeDry;
1696            }
1697
1698            if (var_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation &&
1699                !(var_sp->m_flags & ClangExpressionVariable::EVKeepInTarget))
1700            {
1701                if (m_keep_result_in_memory)
1702                {
1703                    var_sp->m_flags |= ClangExpressionVariable::EVKeepInTarget;
1704                }
1705                else
1706                {
1707                    Error deallocate_error = process->DeallocateMemory(mem);
1708
1709                    if (!err.Success())
1710                    {
1711                        err.SetErrorStringWithFormat ("Couldn't deallocate memory for %s: %s", var_sp->GetName().GetCString(), deallocate_error.AsCString());
1712                        return false;
1713                    }
1714                }
1715            }
1716        }
1717        else
1718        {
1719            err.SetErrorStringWithFormat("Persistent variables without separate allocations are not currently supported.");
1720            return false;
1721        }
1722    }
1723    else
1724    {
1725        if (log)
1726            log->Printf("Materializing persistent variable with flags 0x%hx", var_sp->m_flags);
1727
1728        if (var_sp->m_flags & ClangExpressionVariable::EVNeedsAllocation)
1729        {
1730            // Allocate a spare memory area to store the persistent variable's contents.
1731
1732            Error allocate_error;
1733
1734            mem = process->AllocateMemory(pvar_byte_size,
1735                                          lldb::ePermissionsReadable | lldb::ePermissionsWritable,
1736                                          allocate_error);
1737
1738            if (mem == LLDB_INVALID_ADDRESS)
1739            {
1740                err.SetErrorStringWithFormat("Couldn't allocate a memory area to store %s: %s", var_sp->GetName().GetCString(), allocate_error.AsCString());
1741                return false;
1742            }
1743
1744            if (log)
1745                log->Printf("Allocated %s (0x%llx) sucessfully", var_sp->GetName().GetCString(), mem);
1746
1747            // Put the location of the spare memory into the live data of the ValueObject.
1748
1749            var_sp->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
1750                                                                var_sp->GetTypeFromUser().GetASTContext(),
1751                                                                var_sp->GetTypeFromUser().GetOpaqueQualType(),
1752                                                                var_sp->GetName(),
1753                                                                mem,
1754                                                                eAddressTypeLoad,
1755                                                                pvar_byte_size);
1756
1757            // Clear the flag if the variable will never be deallocated.
1758
1759            if (var_sp->m_flags & ClangExpressionVariable::EVKeepInTarget)
1760                var_sp->m_flags &= ~ClangExpressionVariable::EVNeedsAllocation;
1761
1762            // Write the contents of the variable to the area.
1763
1764            if (process->WriteMemory (mem, pvar_data, pvar_byte_size, error) != pvar_byte_size)
1765            {
1766                err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
1767                return false;
1768            }
1769        }
1770
1771        if ((var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && var_sp->m_live_sp) ||
1772            var_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated)
1773        {
1774            // Now write the location of the area into the struct.
1775            Error write_error;
1776            if (!process->WriteScalarToMemory (addr,
1777                                               var_sp->m_live_sp->GetValue().GetScalar(),
1778                                               process->GetAddressByteSize(),
1779                                               write_error))
1780            {
1781                err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", var_sp->GetName().GetCString(), write_error.AsCString());
1782                return false;
1783            }
1784
1785            if (log)
1786                log->Printf("Materialized %s into 0x%llx", var_sp->GetName().GetCString(), var_sp->m_live_sp->GetValue().GetScalar().ULongLong());
1787        }
1788        else if (!(var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference))
1789        {
1790            err.SetErrorStringWithFormat("Persistent variables without separate allocations are not currently supported.");
1791            return false;
1792        }
1793    }
1794
1795    return true;
1796}
1797
1798bool
1799ClangExpressionDeclMap::DoMaterializeOneVariable
1800(
1801    bool dematerialize,
1802    const SymbolContext &sym_ctx,
1803    ClangExpressionVariableSP &expr_var,
1804    lldb::addr_t addr,
1805    Error &err
1806)
1807{
1808    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1809    Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1810    Process *process = m_parser_vars->m_exe_ctx.GetProcessPtr();
1811    StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1812
1813    if (!frame || !process || !target || !m_parser_vars.get() || !expr_var->m_parser_vars.get())
1814    {
1815        err.SetErrorString("Necessary state for variable materialization isn't present");
1816        return false;
1817    }
1818
1819    // Vital information about the value
1820
1821    const ConstString &name(expr_var->GetName());
1822    TypeFromUser type(expr_var->GetTypeFromUser());
1823
1824    VariableSP &var(expr_var->m_parser_vars->m_lldb_var);
1825    lldb_private::Symbol *sym(expr_var->m_parser_vars->m_lldb_sym);
1826
1827    bool is_reference(expr_var->m_flags & ClangExpressionVariable::EVTypeIsReference);
1828
1829    std::auto_ptr<lldb_private::Value> location_value;
1830
1831    if (var)
1832    {
1833        location_value.reset(GetVariableValue(var,
1834                                              NULL));
1835    }
1836    else if (sym)
1837    {
1838        addr_t location_load_addr = GetSymbolAddress(*target, name, lldb::eSymbolTypeAny);
1839
1840        if (location_load_addr == LLDB_INVALID_ADDRESS)
1841        {
1842            if (log)
1843                err.SetErrorStringWithFormat ("Couldn't find value for global symbol %s",
1844                                              name.GetCString());
1845        }
1846
1847        location_value.reset(new Value);
1848
1849        location_value->SetValueType(Value::eValueTypeLoadAddress);
1850        location_value->GetScalar() = location_load_addr;
1851    }
1852    else
1853    {
1854        err.SetErrorStringWithFormat ("Couldn't find %s with appropriate type",
1855                                      name.GetCString());
1856        return false;
1857    }
1858
1859    if (log)
1860    {
1861        StreamString my_stream_string;
1862
1863        ClangASTType::DumpTypeDescription (type.GetASTContext(),
1864                                           type.GetOpaqueQualType(),
1865                                           &my_stream_string);
1866
1867        log->Printf ("%s %s with type %s",
1868                     dematerialize ? "Dematerializing" : "Materializing",
1869                     name.GetCString(),
1870                     my_stream_string.GetString().c_str());
1871    }
1872
1873    if (!location_value.get())
1874    {
1875        err.SetErrorStringWithFormat("Couldn't get value for %s", name.GetCString());
1876        return false;
1877    }
1878
1879    // The size of the type contained in addr
1880
1881    size_t value_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
1882    size_t value_byte_size = value_bit_size % 8 ? ((value_bit_size + 8) / 8) : (value_bit_size / 8);
1883
1884    Value::ValueType value_type = location_value->GetValueType();
1885
1886    switch (value_type)
1887    {
1888    default:
1889        {
1890            StreamString ss;
1891
1892            location_value->Dump(&ss);
1893
1894            err.SetErrorStringWithFormat ("%s has a value of unhandled type: %s",
1895                                          name.GetCString(),
1896                                          ss.GetString().c_str());
1897            return false;
1898        }
1899        break;
1900    case Value::eValueTypeLoadAddress:
1901        {
1902            if (!dematerialize)
1903            {
1904                Error write_error;
1905
1906                if (is_reference)
1907                {
1908                    Error read_error;
1909
1910                    addr_t ref_value = process->ReadPointerFromMemory(location_value->GetScalar().ULongLong(), read_error);
1911
1912                    if (!read_error.Success())
1913                    {
1914                        err.SetErrorStringWithFormat ("Couldn't read reference to %s from the target: %s",
1915                                                      name.GetCString(),
1916                                                      read_error.AsCString());
1917                        return false;
1918                    }
1919
1920                    if (!process->WritePointerToMemory(addr,
1921                                                       ref_value,
1922                                                       write_error))
1923                    {
1924                        err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s",
1925                                                      name.GetCString(),
1926                                                      write_error.AsCString());
1927                        return false;
1928                    }
1929                }
1930                else
1931                {
1932                    if (!process->WriteScalarToMemory (addr,
1933                                                       location_value->GetScalar(),
1934                                                       process->GetAddressByteSize(),
1935                                                       write_error))
1936                    {
1937                        err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s",
1938                                                      name.GetCString(),
1939                                                      write_error.AsCString());
1940                        return false;
1941                    }
1942                }
1943            }
1944        }
1945        break;
1946    case Value::eValueTypeScalar:
1947        {
1948            if (location_value->GetContextType() != Value::eContextTypeRegisterInfo)
1949            {
1950                StreamString ss;
1951                location_value->Dump(&ss);
1952
1953                err.SetErrorStringWithFormat ("%s is a scalar of unhandled type: %s",
1954                                              name.GetCString(),
1955                                              ss.GetString().c_str());
1956                return false;
1957            }
1958
1959            RegisterInfo *reg_info = location_value->GetRegisterInfo();
1960
1961            if (!reg_info)
1962            {
1963                err.SetErrorStringWithFormat ("Couldn't get the register information for %s",
1964                                              name.GetCString());
1965                return false;
1966            }
1967
1968            RegisterValue reg_value;
1969
1970            RegisterContext *reg_ctx = m_parser_vars->m_exe_ctx.GetRegisterContext();
1971
1972            if (!reg_ctx)
1973            {
1974                err.SetErrorStringWithFormat ("Couldn't read register context to read %s from %s",
1975                                              name.GetCString(),
1976                                              reg_info->name);
1977                return false;
1978            }
1979
1980            uint32_t register_byte_size = reg_info->byte_size;
1981
1982            if (dematerialize)
1983            {
1984                if (is_reference)
1985                    return true; // reference types don't need demateralizing
1986
1987                // Get the location of the spare memory area out of the variable's live data.
1988
1989                if (!expr_var->m_live_sp)
1990                {
1991                    err.SetErrorStringWithFormat("Couldn't find the memory area used to store %s", name.GetCString());
1992                    return false;
1993                }
1994
1995                if (expr_var->m_live_sp->GetValue().GetValueAddressType() != eAddressTypeLoad)
1996                {
1997                    err.SetErrorStringWithFormat("The address of the memory area for %s is in an incorrect format", name.GetCString());
1998                    return false;
1999                }
2000
2001                Scalar &reg_addr = expr_var->m_live_sp->GetValue().GetScalar();
2002
2003                err = reg_ctx->ReadRegisterValueFromMemory (reg_info,
2004                                                            reg_addr.ULongLong(),
2005                                                            value_byte_size,
2006                                                            reg_value);
2007                if (err.Fail())
2008                    return false;
2009
2010                if (!reg_ctx->WriteRegister (reg_info, reg_value))
2011                {
2012                    err.SetErrorStringWithFormat ("Couldn't write %s to register %s",
2013                                                  name.GetCString(),
2014                                                  reg_info->name);
2015                    return false;
2016                }
2017
2018                // Deallocate the spare area and clear the variable's live data.
2019
2020                Error deallocate_error = process->DeallocateMemory(reg_addr.ULongLong());
2021
2022                if (!deallocate_error.Success())
2023                {
2024                    err.SetErrorStringWithFormat ("Couldn't deallocate spare memory area for %s: %s",
2025                                                  name.GetCString(),
2026                                                  deallocate_error.AsCString());
2027                    return false;
2028                }
2029
2030                expr_var->m_live_sp.reset();
2031            }
2032            else
2033            {
2034                Error write_error;
2035
2036                RegisterValue reg_value;
2037
2038                if (!reg_ctx->ReadRegister (reg_info, reg_value))
2039                {
2040                    err.SetErrorStringWithFormat ("Couldn't read %s from %s",
2041                                                  name.GetCString(),
2042                                                  reg_info->name);
2043                    return false;
2044                }
2045
2046                if (is_reference)
2047                {
2048                    write_error = reg_ctx->WriteRegisterValueToMemory(reg_info,
2049                                                                      addr,
2050                                                                      process->GetAddressByteSize(),
2051                                                                      reg_value);
2052
2053                    if (!write_error.Success())
2054                    {
2055                        err.SetErrorStringWithFormat ("Couldn't write %s from register %s to the target: %s",
2056                                                      name.GetCString(),
2057                                                      reg_info->name,
2058                                                      write_error.AsCString());
2059                        return false;
2060                    }
2061
2062                    return true;
2063                }
2064
2065                // Allocate a spare memory area to place the register's contents into.  This memory area will be pointed to by the slot in the
2066                // struct.
2067
2068                Error allocate_error;
2069
2070                Scalar reg_addr (process->AllocateMemory (value_byte_size,
2071                                                          lldb::ePermissionsReadable | lldb::ePermissionsWritable,
2072                                                          allocate_error));
2073
2074                if (reg_addr.ULongLong() == LLDB_INVALID_ADDRESS)
2075                {
2076                    err.SetErrorStringWithFormat ("Couldn't allocate a memory area to store %s: %s",
2077                                                  name.GetCString(),
2078                                                  allocate_error.AsCString());
2079                    return false;
2080                }
2081
2082                // Put the location of the spare memory into the live data of the ValueObject.
2083
2084                expr_var->m_live_sp = ValueObjectConstResult::Create (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
2085                                                                      type.GetASTContext(),
2086                                                                      type.GetOpaqueQualType(),
2087                                                                      name,
2088                                                                      reg_addr.ULongLong(),
2089                                                                      eAddressTypeLoad,
2090                                                                      value_byte_size);
2091
2092                // Now write the location of the area into the struct.
2093
2094                if (!process->WriteScalarToMemory (addr,
2095                                                   reg_addr,
2096                                                   process->GetAddressByteSize(),
2097                                                   write_error))
2098                {
2099                    err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s",
2100                                                  name.GetCString(),
2101                                                  write_error.AsCString());
2102                    return false;
2103                }
2104
2105                if (value_byte_size > register_byte_size)
2106                {
2107                    err.SetErrorStringWithFormat ("%s is too big to store in %s",
2108                                                  name.GetCString(),
2109                                                  reg_info->name);
2110                    return false;
2111                }
2112
2113                if (!reg_ctx->ReadRegister (reg_info, reg_value))
2114                {
2115                    err.SetErrorStringWithFormat ("Couldn't read %s from %s",
2116                                                  name.GetCString(),
2117                                                  reg_info->name);
2118                    return false;
2119                }
2120
2121                err = reg_ctx->WriteRegisterValueToMemory (reg_info,
2122                                                           reg_addr.ULongLong(),
2123                                                           value_byte_size,
2124                                                           reg_value);
2125                if (err.Fail())
2126                    return false;
2127            }
2128        }
2129    }
2130
2131    return true;
2132}
2133
2134bool
2135ClangExpressionDeclMap::DoMaterializeOneRegister
2136(
2137    bool dematerialize,
2138    RegisterContext &reg_ctx,
2139    const RegisterInfo &reg_info,
2140    lldb::addr_t addr,
2141    Error &err
2142)
2143{
2144    uint32_t register_byte_size = reg_info.byte_size;
2145    RegisterValue reg_value;
2146    if (dematerialize)
2147    {
2148        Error read_error (reg_ctx.ReadRegisterValueFromMemory(&reg_info, addr, register_byte_size, reg_value));
2149        if (read_error.Fail())
2150        {
2151            err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", reg_info.name, read_error.AsCString());
2152            return false;
2153        }
2154
2155        if (!reg_ctx.WriteRegister (&reg_info, reg_value))
2156        {
2157            err.SetErrorStringWithFormat("Couldn't write register %s (dematerialize)", reg_info.name);
2158            return false;
2159        }
2160    }
2161    else
2162    {
2163
2164        if (!reg_ctx.ReadRegister(&reg_info, reg_value))
2165        {
2166            err.SetErrorStringWithFormat("Couldn't read %s (materialize)", reg_info.name);
2167            return false;
2168        }
2169
2170        Error write_error (reg_ctx.WriteRegisterValueToMemory(&reg_info, addr, register_byte_size, reg_value));
2171        if (write_error.Fail())
2172        {
2173            err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", reg_info.name, write_error.AsCString());
2174            return false;
2175        }
2176    }
2177
2178    return true;
2179}
2180
2181lldb::VariableSP
2182ClangExpressionDeclMap::FindVariableInScope
2183(
2184    StackFrame &frame,
2185    const ConstString &name,
2186    TypeFromUser *type,
2187    bool object_pointer
2188)
2189{
2190    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
2191
2192    ValueObjectSP valobj;
2193    VariableSP var_sp;
2194    Error err;
2195
2196    valobj = frame.GetValueForVariableExpressionPath(name.GetCString(),
2197                                                     eNoDynamicValues,
2198                                                     StackFrame::eExpressionPathOptionCheckPtrVsMember,
2199                                                     var_sp,
2200                                                     err);
2201
2202    if (!err.Success() ||
2203        !var_sp ||
2204        !var_sp->IsInScope(&frame) ||
2205        !var_sp->LocationIsValidForFrame (&frame))
2206        return lldb::VariableSP();
2207
2208    if (var_sp)
2209    {
2210        if (!type)
2211            return var_sp;
2212
2213        TypeFromUser candidate_type(var_sp->GetType()->GetClangFullType(),
2214                                    var_sp->GetType()->GetClangAST());
2215
2216        if (candidate_type.GetASTContext() != type->GetASTContext())
2217        {
2218            if (log)
2219                log->PutCString("Skipping a candidate variable because of different AST contexts");
2220            return lldb::VariableSP();
2221        }
2222
2223        if (object_pointer)
2224        {
2225            clang::QualType desired_qual_type = clang::QualType::getFromOpaquePtr(type->GetOpaqueQualType());
2226            clang::QualType candidate_qual_type = clang::QualType::getFromOpaquePtr(candidate_type.GetOpaqueQualType());
2227
2228            const clang::ObjCObjectPointerType *desired_objc_ptr_type = desired_qual_type->getAs<clang::ObjCObjectPointerType>();
2229            const clang::ObjCObjectPointerType *candidate_objc_ptr_type = desired_qual_type->getAs<clang::ObjCObjectPointerType>();
2230
2231            if (desired_objc_ptr_type && candidate_objc_ptr_type) {
2232                clang::QualType desired_target_type = desired_objc_ptr_type->getPointeeType().getUnqualifiedType();
2233                clang::QualType candidate_target_type = candidate_objc_ptr_type->getPointeeType().getUnqualifiedType();
2234
2235                if (ClangASTContext::AreTypesSame(type->GetASTContext(),
2236                                                  desired_target_type.getAsOpaquePtr(),
2237                                                  candidate_target_type.getAsOpaquePtr()))
2238                    return var_sp;
2239            }
2240
2241            const clang::PointerType *desired_ptr_type = desired_qual_type->getAs<clang::PointerType>();
2242            const clang::PointerType *candidate_ptr_type = candidate_qual_type->getAs<clang::PointerType>();
2243
2244            if (desired_ptr_type && candidate_ptr_type) {
2245                clang::QualType desired_target_type = desired_ptr_type->getPointeeType().getUnqualifiedType();
2246                clang::QualType candidate_target_type = candidate_ptr_type->getPointeeType().getUnqualifiedType();
2247
2248                if (ClangASTContext::AreTypesSame(type->GetASTContext(),
2249                                                  desired_target_type.getAsOpaquePtr(),
2250                                                  candidate_target_type.getAsOpaquePtr()))
2251                    return var_sp;
2252            }
2253
2254            return lldb::VariableSP();
2255        }
2256        else
2257        {
2258            if (ClangASTContext::AreTypesSame(type->GetASTContext(),
2259                                               type->GetOpaqueQualType(),
2260                                               var_sp->GetType()->GetClangFullType()))
2261                return var_sp;
2262        }
2263    }
2264
2265    return lldb::VariableSP();
2266}
2267
2268Symbol *
2269ClangExpressionDeclMap::FindGlobalDataSymbol
2270(
2271    Target &target,
2272    const ConstString &name
2273)
2274{
2275    SymbolContextList sc_list;
2276
2277    target.GetImages().FindSymbolsWithNameAndType(name,
2278                                                  eSymbolTypeData,
2279                                                  sc_list);
2280
2281    if (sc_list.GetSize())
2282    {
2283        SymbolContext sym_ctx;
2284        sc_list.GetContextAtIndex(0, sym_ctx);
2285
2286        return sym_ctx.symbol;
2287    }
2288
2289    return NULL;
2290}
2291
2292lldb::VariableSP
2293ClangExpressionDeclMap::FindGlobalVariable
2294(
2295    Target &target,
2296    ModuleSP &module,
2297    const ConstString &name,
2298    ClangNamespaceDecl *namespace_decl,
2299    TypeFromUser *type
2300)
2301{
2302    VariableList vars;
2303
2304    if (module && namespace_decl)
2305        module->FindGlobalVariables (name, namespace_decl, true, -1, vars);
2306    else
2307        target.GetImages().FindGlobalVariables(name, true, -1, vars);
2308
2309    if (vars.GetSize())
2310    {
2311        if (type)
2312        {
2313            for (size_t i = 0; i < vars.GetSize(); ++i)
2314            {
2315                VariableSP var_sp = vars.GetVariableAtIndex(i);
2316
2317                if (type->GetASTContext() == var_sp->GetType()->GetClangAST())
2318                {
2319                    if (ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var_sp->GetType()->GetClangFullType()))
2320                        return var_sp;
2321                }
2322            }
2323        }
2324        else
2325        {
2326            return vars.GetVariableAtIndex(0);
2327        }
2328    }
2329
2330    return VariableSP();
2331}
2332
2333// Interface for ClangASTSource
2334
2335void
2336ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context)
2337{
2338    assert (m_ast_context);
2339
2340    const ConstString name(context.m_decl_name.getAsString().c_str());
2341
2342    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
2343
2344    if (GetImportInProgress())
2345    {
2346        if (log && log->GetVerbose())
2347            log->Printf("Ignoring a query during an import");
2348        return;
2349    }
2350
2351    static unsigned int invocation_id = 0;
2352    unsigned int current_id = invocation_id++;
2353
2354    if (log)
2355    {
2356        if (!context.m_decl_context)
2357            log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a NULL DeclContext", current_id, name.GetCString());
2358        else if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context.m_decl_context))
2359            log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in '%s'", current_id, name.GetCString(), context_named_decl->getNameAsString().c_str());
2360        else
2361            log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for '%s' in a '%s'", current_id, name.GetCString(), context.m_decl_context->getDeclKindName());
2362    }
2363
2364    if (const NamespaceDecl *namespace_context = dyn_cast<NamespaceDecl>(context.m_decl_context))
2365    {
2366        ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
2367
2368        if (log && log->GetVerbose())
2369            log->Printf("  CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
2370                        current_id,
2371                        namespace_map.get(),
2372                        (int)namespace_map->size());
2373
2374        if (!namespace_map)
2375            return;
2376
2377        for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(), e = namespace_map->end();
2378             i != e;
2379             ++i)
2380        {
2381            if (log)
2382                log->Printf("  CEDM::FEVD[%u] Searching namespace %s in module %s",
2383                            current_id,
2384                            i->second.GetNamespaceDecl()->getNameAsString().c_str(),
2385                            i->first->GetFileSpec().GetFilename().GetCString());
2386
2387            FindExternalVisibleDecls(context,
2388                                     i->first,
2389                                     i->second,
2390                                     current_id);
2391        }
2392    }
2393    else if (isa<TranslationUnitDecl>(context.m_decl_context))
2394    {
2395        ClangNamespaceDecl namespace_decl;
2396
2397        if (log)
2398            log->Printf("  CEDM::FEVD[%u] Searching the root namespace", current_id);
2399
2400        FindExternalVisibleDecls(context,
2401                                 lldb::ModuleSP(),
2402                                 namespace_decl,
2403                                 current_id);
2404    }
2405
2406    if (!context.m_found.variable)
2407        ClangASTSource::FindExternalVisibleDecls(context);
2408}
2409
2410void
2411ClangExpressionDeclMap::FindExternalVisibleDecls (NameSearchContext &context,
2412                                                  lldb::ModuleSP module_sp,
2413                                                  ClangNamespaceDecl &namespace_decl,
2414                                                  unsigned int current_id)
2415{
2416    assert (m_ast_context);
2417
2418    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
2419
2420    SymbolContextList sc_list;
2421
2422    const ConstString name(context.m_decl_name.getAsString().c_str());
2423
2424    const char *name_unique_cstr = name.GetCString();
2425
2426    if (name_unique_cstr == NULL)
2427        return;
2428
2429    static ConstString id_name("id");
2430    static ConstString Class_name("Class");
2431
2432    if (name == id_name || name == Class_name)
2433        return;
2434
2435    // Only look for functions by name out in our symbols if the function
2436    // doesn't start with our phony prefix of '$'
2437    Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
2438    StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
2439    if (name_unique_cstr[0] == '$' && !namespace_decl)
2440    {
2441        static ConstString g_lldb_class_name ("$__lldb_class");
2442
2443        if (name == g_lldb_class_name)
2444        {
2445            // Clang is looking for the type of "this"
2446
2447            if (frame == NULL)
2448                return;
2449
2450            SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction);
2451
2452            if (!sym_ctx.function)
2453                return;
2454
2455            // Get the block that defines the function
2456            Block *function_block = sym_ctx.GetFunctionBlock();
2457
2458            if (!function_block)
2459                return;
2460
2461            clang::DeclContext *decl_context = function_block->GetClangDeclContext();
2462
2463            if (!decl_context)
2464                return;
2465
2466            clang::CXXMethodDecl *method_decl = llvm::dyn_cast<clang::CXXMethodDecl>(decl_context);
2467
2468            if (!method_decl)
2469                return;
2470
2471            clang::CXXRecordDecl *class_decl = method_decl->getParent();
2472
2473            QualType class_qual_type(class_decl->getTypeForDecl(), 0);
2474
2475            TypeFromUser class_user_type (class_qual_type.getAsOpaquePtr(),
2476                                          &class_decl->getASTContext());
2477
2478            if (log)
2479            {
2480                ASTDumper ast_dumper(class_qual_type);
2481                log->Printf("  CEDM::FEVD[%u] Adding type for $__lldb_class: %s", current_id, ast_dumper.GetCString());
2482            }
2483
2484            AddOneType(context, class_user_type, current_id, true);
2485
2486            if (method_decl->isInstance())
2487            {
2488                // self is a pointer to the object
2489
2490                QualType class_pointer_type = method_decl->getASTContext().getPointerType(class_qual_type);
2491
2492                TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(),
2493                                            &method_decl->getASTContext());
2494
2495                m_struct_vars->m_object_pointer_type = self_user_type;
2496            }
2497
2498            return;
2499        }
2500
2501        static ConstString g_lldb_objc_class_name ("$__lldb_objc_class");
2502        if (name == g_lldb_objc_class_name)
2503        {
2504            // Clang is looking for the type of "*self"
2505
2506            if (!frame)
2507                return;
2508
2509            SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction);
2510
2511            if (!sym_ctx.function)
2512                return;
2513
2514            // Get the block that defines the function
2515            Block *function_block = sym_ctx.GetFunctionBlock();
2516
2517            if (!function_block)
2518                return;
2519
2520            clang::DeclContext *decl_context = function_block->GetClangDeclContext();
2521
2522            if (!decl_context)
2523                return;
2524
2525            clang::ObjCMethodDecl *method_decl = llvm::dyn_cast<clang::ObjCMethodDecl>(decl_context);
2526
2527            if (!method_decl)
2528                return;
2529
2530            ObjCInterfaceDecl* self_interface = method_decl->getClassInterface();
2531
2532            if (!self_interface)
2533                return;
2534
2535            const clang::Type *interface_type = self_interface->getTypeForDecl();
2536
2537            TypeFromUser class_user_type(QualType(interface_type, 0).getAsOpaquePtr(),
2538                                         &method_decl->getASTContext());
2539
2540            if (log)
2541            {
2542                ASTDumper ast_dumper(interface_type);
2543                log->Printf("  FEVD[%u] Adding type for $__lldb_objc_class: %s", current_id, ast_dumper.GetCString());
2544            }
2545
2546            AddOneType(context, class_user_type, current_id, false);
2547
2548#if 0
2549            VariableList *vars = frame->GetVariableList(false);
2550
2551            lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
2552
2553            if (self_var &&
2554                self_var->IsInScope(frame) &&
2555                self_var->LocationIsValidForFrame (frame)) {
2556                Type *self_type = self_var->GetType();
2557
2558                if (!self_type)
2559                    return;
2560
2561                TypeFromUser self_user_type(self_type->GetClangFullType(),
2562                                            self_type->GetClangAST());
2563            }
2564#endif
2565
2566            if (method_decl->isInstanceMethod())
2567            {
2568                // self is a pointer to the object
2569
2570                QualType class_pointer_type = method_decl->getASTContext().getObjCObjectPointerType(QualType(interface_type, 0));
2571
2572                TypeFromUser self_user_type(class_pointer_type.getAsOpaquePtr(),
2573                                            &method_decl->getASTContext());
2574
2575                m_struct_vars->m_object_pointer_type = self_user_type;
2576            }
2577            else
2578            {
2579                // self is a Class pointer
2580                QualType class_type = method_decl->getASTContext().getObjCClassType();
2581
2582                TypeFromUser self_user_type(class_type.getAsOpaquePtr(),
2583                                            &method_decl->getASTContext());
2584
2585                m_struct_vars->m_object_pointer_type = self_user_type;
2586            }
2587
2588            return;
2589        }
2590
2591        // any other $__lldb names should be weeded out now
2592        if (!::strncmp(name_unique_cstr, "$__lldb", sizeof("$__lldb") - 1))
2593            return;
2594
2595        do
2596        {
2597            if (!target)
2598                break;
2599
2600            ClangASTContext *scratch_clang_ast_context = target->GetScratchClangASTContext();
2601
2602            if (!scratch_clang_ast_context)
2603                break;
2604
2605            ASTContext *scratch_ast_context = scratch_clang_ast_context->getASTContext();
2606
2607            if (!scratch_ast_context)
2608                break;
2609
2610            TypeDecl *ptype_type_decl = m_parser_vars->m_persistent_vars->GetPersistentType(name);
2611
2612            if (!ptype_type_decl)
2613                break;
2614
2615            Decl *parser_ptype_decl = m_ast_importer->CopyDecl(m_ast_context, scratch_ast_context, ptype_type_decl);
2616
2617            if (!parser_ptype_decl)
2618                break;
2619
2620            TypeDecl *parser_ptype_type_decl = dyn_cast<TypeDecl>(parser_ptype_decl);
2621
2622            if (!parser_ptype_type_decl)
2623                break;
2624
2625            if (log)
2626                log->Printf("  CEDM::FEVD[%u] Found persistent type %s", current_id, name.GetCString());
2627
2628            context.AddNamedDecl(parser_ptype_type_decl);
2629        } while (0);
2630
2631        ClangExpressionVariableSP pvar_sp(m_parser_vars->m_persistent_vars->GetVariable(name));
2632
2633        if (pvar_sp)
2634        {
2635            AddOneVariable(context, pvar_sp, current_id);
2636            return;
2637        }
2638
2639        const char *reg_name(&name.GetCString()[1]);
2640
2641        if (m_parser_vars->m_exe_ctx.GetRegisterContext())
2642        {
2643            const RegisterInfo *reg_info(m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(reg_name));
2644
2645            if (reg_info)
2646            {
2647                if (log)
2648                    log->Printf("  CEDM::FEVD[%u] Found register %s", current_id, reg_info->name);
2649
2650                AddOneRegister(context, reg_info, current_id);
2651            }
2652        }
2653    }
2654    else
2655    {
2656        ValueObjectSP valobj;
2657        VariableSP var;
2658        Error err;
2659
2660        if (frame && !namespace_decl)
2661        {
2662            valobj = frame->GetValueForVariableExpressionPath(name_unique_cstr,
2663                                                              eNoDynamicValues,
2664                                                              StackFrame::eExpressionPathOptionCheckPtrVsMember,
2665                                                              var,
2666                                                              err);
2667
2668            // If we found a variable in scope, no need to pull up function names
2669            if (err.Success() && var)
2670            {
2671                AddOneVariable(context, var, valobj, current_id);
2672                context.m_found.variable = true;
2673                return;
2674            }
2675        }
2676
2677        if (target)
2678        {
2679            var = FindGlobalVariable (*target,
2680                                      module_sp,
2681                                      name,
2682                                      &namespace_decl,
2683                                      NULL);
2684
2685            if (var)
2686            {
2687                valobj = ValueObjectVariable::Create(target, var);
2688                AddOneVariable(context, var, valobj, current_id);
2689                context.m_found.variable = true;
2690                return;
2691            }
2692        }
2693
2694        if (!context.m_found.variable)
2695        {
2696            const bool include_inlines = false;
2697            const bool append = false;
2698
2699            if (namespace_decl && module_sp)
2700            {
2701                const bool include_symbols = false;
2702
2703                module_sp->FindFunctions(name,
2704                                         &namespace_decl,
2705                                         eFunctionNameTypeBase,
2706                                         include_symbols,
2707                                         include_inlines,
2708                                         append,
2709                                         sc_list);
2710            }
2711            else if (!namespace_decl)
2712            {
2713                const bool include_symbols = true;
2714
2715                // TODO Fix FindFunctions so that it doesn't return
2716                //   instance methods for eFunctionNameTypeBase.
2717
2718                target->GetImages().FindFunctions(name,
2719                                                  eFunctionNameTypeBase,
2720                                                  include_symbols,
2721                                                  include_inlines,
2722                                                  append,
2723                                                  sc_list);
2724            }
2725
2726            if (sc_list.GetSize())
2727            {
2728                Symbol *generic_symbol = NULL;
2729                Symbol *non_extern_symbol = NULL;
2730
2731                for (uint32_t index = 0, num_indices = sc_list.GetSize();
2732                     index < num_indices;
2733                     ++index)
2734                {
2735                    SymbolContext sym_ctx;
2736                    sc_list.GetContextAtIndex(index, sym_ctx);
2737
2738                    if (sym_ctx.function)
2739                    {
2740                        clang::DeclContext *decl_ctx = sym_ctx.function->GetClangDeclContext();
2741
2742                        // Filter out class/instance methods.
2743                        if (dyn_cast<clang::ObjCMethodDecl>(decl_ctx))
2744                            continue;
2745                        if (dyn_cast<clang::CXXMethodDecl>(decl_ctx))
2746                            continue;
2747
2748                        // TODO only do this if it's a C function; C++ functions may be
2749                        // overloaded
2750                        if (!context.m_found.function_with_type_info)
2751                            AddOneFunction(context, sym_ctx.function, NULL, current_id);
2752                        context.m_found.function_with_type_info = true;
2753                        context.m_found.function = true;
2754                    }
2755                    else if (sym_ctx.symbol)
2756                    {
2757                        if (sym_ctx.symbol->IsExternal())
2758                            generic_symbol = sym_ctx.symbol;
2759                        else
2760                            non_extern_symbol = sym_ctx.symbol;
2761                    }
2762                }
2763
2764                if (!context.m_found.function_with_type_info)
2765                {
2766                    if (generic_symbol)
2767                    {
2768                        AddOneFunction (context, NULL, generic_symbol, current_id);
2769                        context.m_found.function = true;
2770                    }
2771                    else if (non_extern_symbol)
2772                    {
2773                        AddOneFunction (context, NULL, non_extern_symbol, current_id);
2774                        context.m_found.function = true;
2775                    }
2776                }
2777            }
2778
2779            if (!context.m_found.variable && !namespace_decl)
2780            {
2781                // We couldn't find a non-symbol variable for this.  Now we'll hunt for a generic
2782                // data symbol, and -- if it is found -- treat it as a variable.
2783
2784                Symbol *data_symbol = FindGlobalDataSymbol(*target, name);
2785
2786                if (data_symbol)
2787                {
2788                    AddOneGenericVariable(context, *data_symbol, current_id);
2789                    context.m_found.variable = true;
2790                }
2791            }
2792        }
2793    }
2794}
2795
2796static clang_type_t
2797MaybePromoteToBlockPointerType
2798(
2799    ASTContext *ast_context,
2800    clang_type_t candidate_type
2801)
2802{
2803    if (!candidate_type)
2804        return candidate_type;
2805
2806    QualType candidate_qual_type = QualType::getFromOpaquePtr(candidate_type);
2807
2808    const PointerType *candidate_pointer_type = dyn_cast<PointerType>(candidate_qual_type);
2809
2810    if (!candidate_pointer_type)
2811        return candidate_type;
2812
2813    QualType pointee_qual_type = candidate_pointer_type->getPointeeType();
2814
2815    const RecordType *pointee_record_type = dyn_cast<RecordType>(pointee_qual_type);
2816
2817    if (!pointee_record_type)
2818        return candidate_type;
2819
2820    RecordDecl *pointee_record_decl = pointee_record_type->getDecl();
2821
2822    if (!pointee_record_decl->isRecord())
2823        return candidate_type;
2824
2825    if (!pointee_record_decl->getName().startswith(llvm::StringRef("__block_literal_")))
2826        return candidate_type;
2827
2828    QualType generic_function_type = ast_context->getFunctionNoProtoType(ast_context->UnknownAnyTy);
2829    QualType block_pointer_type = ast_context->getBlockPointerType(generic_function_type);
2830
2831    return block_pointer_type.getAsOpaquePtr();
2832}
2833
2834Value *
2835ClangExpressionDeclMap::GetVariableValue
2836(
2837    VariableSP &var,
2838    ASTContext *parser_ast_context,
2839    TypeFromUser *user_type,
2840    TypeFromParser *parser_type
2841)
2842{
2843    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
2844
2845    Type *var_type = var->GetType();
2846
2847    if (!var_type)
2848    {
2849        if (log)
2850            log->PutCString("Skipped a definition because it has no type");
2851        return NULL;
2852    }
2853
2854    clang_type_t var_opaque_type = var_type->GetClangFullType();
2855
2856    if (!var_opaque_type)
2857    {
2858        if (log)
2859            log->PutCString("Skipped a definition because it has no Clang type");
2860        return NULL;
2861    }
2862
2863    ASTContext *ast = var_type->GetClangASTContext().getASTContext();
2864
2865    if (!ast)
2866    {
2867        if (log)
2868            log->PutCString("There is no AST context for the current execution context");
2869        return NULL;
2870    }
2871
2872    // commented out because of <rdar://problem/11024417>
2873    //var_opaque_type = MaybePromoteToBlockPointerType (ast, var_opaque_type);
2874
2875    DWARFExpression &var_location_expr = var->LocationExpression();
2876
2877    std::auto_ptr<Value> var_location(new Value);
2878
2879    lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
2880
2881    Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
2882
2883    if (var_location_expr.IsLocationList())
2884    {
2885        SymbolContext var_sc;
2886        var->CalculateSymbolContext (&var_sc);
2887        loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
2888    }
2889    Error err;
2890
2891    if (!var_location_expr.Evaluate(&m_parser_vars->m_exe_ctx, ast, NULL, NULL, NULL, loclist_base_load_addr, NULL, *var_location.get(), &err))
2892    {
2893        if (log)
2894            log->Printf("Error evaluating location: %s", err.AsCString());
2895        return NULL;
2896    }
2897
2898    void *type_to_use = NULL;
2899
2900    if (parser_ast_context)
2901    {
2902        type_to_use = GuardedCopyType(parser_ast_context, ast, var_opaque_type);
2903
2904        if (!type_to_use)
2905        {
2906            if (log)
2907                log->Printf("Couldn't copy a variable's type into the parser's AST context");
2908
2909            return NULL;
2910        }
2911
2912        if (parser_type)
2913            *parser_type = TypeFromParser(type_to_use, parser_ast_context);
2914    }
2915    else
2916        type_to_use = var_opaque_type;
2917
2918    if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
2919        var_location.get()->SetContext(Value::eContextTypeClangType, type_to_use);
2920
2921    if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
2922    {
2923        SymbolContext var_sc;
2924        var->CalculateSymbolContext(&var_sc);
2925
2926        if (!var_sc.module_sp)
2927            return NULL;
2928
2929        ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
2930
2931        if (!object_file)
2932            return NULL;
2933
2934        Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
2935
2936        lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
2937
2938        if (load_addr != LLDB_INVALID_ADDRESS)
2939        {
2940            var_location->GetScalar() = load_addr;
2941            var_location->SetValueType(Value::eValueTypeLoadAddress);
2942        }
2943    }
2944
2945    if (user_type)
2946        *user_type = TypeFromUser(var_opaque_type, ast);
2947
2948    return var_location.release();
2949}
2950
2951void
2952ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, VariableSP var, ValueObjectSP valobj, unsigned int current_id)
2953{
2954    assert (m_parser_vars.get());
2955
2956    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
2957
2958    TypeFromUser ut;
2959    TypeFromParser pt;
2960
2961    Value *var_location = GetVariableValue (var,
2962                                            m_ast_context,
2963                                            &ut,
2964                                            &pt);
2965
2966    clang::QualType parser_opaque_type = QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
2967
2968    if (parser_opaque_type.isNull())
2969        return;
2970
2971    if (const clang::Type *parser_type = parser_opaque_type.getTypePtr())
2972    {
2973        if (const TagType *tag_type = dyn_cast<TagType>(parser_type))
2974            CompleteType(tag_type->getDecl());
2975    }
2976
2977    if (!var_location)
2978        return;
2979
2980    NamedDecl *var_decl;
2981
2982    bool is_reference = ClangASTContext::IsReferenceType(pt.GetOpaqueQualType());
2983
2984    if (is_reference)
2985        var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
2986    else
2987        var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(pt.GetASTContext(), pt.GetOpaqueQualType()));
2988
2989    std::string decl_name(context.m_decl_name.getAsString());
2990    ConstString entity_name(decl_name.c_str());
2991    ClangExpressionVariableSP entity(m_found_entities.CreateVariable (valobj));
2992
2993    assert (entity.get());
2994    entity->EnableParserVars();
2995    entity->m_parser_vars->m_parser_type = pt;
2996    entity->m_parser_vars->m_named_decl  = var_decl;
2997    entity->m_parser_vars->m_llvm_value  = NULL;
2998    entity->m_parser_vars->m_lldb_value  = var_location;
2999    entity->m_parser_vars->m_lldb_var    = var;
3000
3001    if (is_reference)
3002        entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
3003
3004    if (log)
3005    {
3006        ASTDumper orig_dumper(ut.GetOpaqueQualType());
3007        ASTDumper ast_dumper(var_decl);
3008        log->Printf("  CEDM::FEVD[%u] Found variable %s, returned %s (original %s)", current_id, decl_name.c_str(), ast_dumper.GetCString(), orig_dumper.GetCString());
3009    }
3010}
3011
3012void
3013ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
3014                                       ClangExpressionVariableSP &pvar_sp,
3015                                       unsigned int current_id)
3016{
3017    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
3018
3019    TypeFromUser user_type (pvar_sp->GetTypeFromUser());
3020
3021    TypeFromParser parser_type (GuardedCopyType(m_ast_context,
3022                                                user_type.GetASTContext(),
3023                                                user_type.GetOpaqueQualType()),
3024                                m_ast_context);
3025
3026    if (!parser_type.GetOpaqueQualType())
3027    {
3028        if (log)
3029            log->Printf("  CEDM::FEVD[%u] Couldn't import type for pvar %s", current_id, pvar_sp->GetName().GetCString());
3030        return;
3031    }
3032
3033    NamedDecl *var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(parser_type.GetASTContext(), parser_type.GetOpaqueQualType()));
3034
3035    pvar_sp->EnableParserVars();
3036    pvar_sp->m_parser_vars->m_parser_type = parser_type;
3037    pvar_sp->m_parser_vars->m_named_decl  = var_decl;
3038    pvar_sp->m_parser_vars->m_llvm_value  = NULL;
3039    pvar_sp->m_parser_vars->m_lldb_value  = NULL;
3040
3041    if (log)
3042    {
3043        ASTDumper ast_dumper(var_decl);
3044        log->Printf("  CEDM::FEVD[%u] Added pvar %s, returned %s", current_id, pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
3045    }
3046}
3047
3048void
3049ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
3050                                              Symbol &symbol,
3051                                              unsigned int current_id)
3052{
3053    assert(m_parser_vars.get());
3054
3055    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
3056
3057    Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
3058
3059    if (target == NULL)
3060        return;
3061
3062    ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext();
3063
3064    TypeFromUser user_type (ClangASTContext::CreateLValueReferenceType(scratch_ast_context, ClangASTContext::GetVoidPtrType(scratch_ast_context, true)),
3065                            scratch_ast_context);
3066
3067    TypeFromParser parser_type (ClangASTContext::CreateLValueReferenceType(scratch_ast_context, ClangASTContext::GetVoidPtrType(m_ast_context, true)),
3068                                m_ast_context);
3069
3070    NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
3071
3072    std::string decl_name(context.m_decl_name.getAsString());
3073    ConstString entity_name(decl_name.c_str());
3074    ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
3075                                                                      entity_name,
3076                                                                      user_type,
3077                                                                      m_parser_vars->m_target_info.byte_order,
3078                                                                      m_parser_vars->m_target_info.address_byte_size));
3079    assert (entity.get());
3080
3081    std::auto_ptr<Value> symbol_location(new Value);
3082
3083    Address &symbol_address = symbol.GetAddress();
3084    lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
3085
3086    symbol_location->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
3087    symbol_location->GetScalar() = symbol_load_addr;
3088    symbol_location->SetValueType(Value::eValueTypeLoadAddress);
3089
3090    entity->EnableParserVars();
3091    entity->m_parser_vars->m_parser_type = parser_type;
3092    entity->m_parser_vars->m_named_decl  = var_decl;
3093    entity->m_parser_vars->m_llvm_value  = NULL;
3094    entity->m_parser_vars->m_lldb_value  = symbol_location.release();
3095    entity->m_parser_vars->m_lldb_sym    = &symbol;
3096
3097    if (log)
3098    {
3099        ASTDumper ast_dumper(var_decl);
3100
3101        log->Printf("  CEDM::FEVD[%u] Found variable %s, returned %s", current_id, decl_name.c_str(), ast_dumper.GetCString());
3102    }
3103}
3104
3105bool
3106ClangExpressionDeclMap::ResolveUnknownTypes()
3107{
3108    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
3109    Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
3110
3111    ASTContext *scratch_ast_context = target->GetScratchClangASTContext()->getASTContext();
3112
3113    for (size_t index = 0, num_entities = m_found_entities.GetSize();
3114         index < num_entities;
3115         ++index)
3116    {
3117        ClangExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index);
3118
3119        if (entity->m_flags & ClangExpressionVariable::EVUnknownType)
3120        {
3121            const NamedDecl *named_decl = entity->m_parser_vars->m_named_decl;
3122            const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl);
3123
3124            if (!var_decl)
3125            {
3126                if (log)
3127                    log->Printf("Entity of unknown type does not have a VarDecl");
3128                return false;
3129            }
3130
3131            if (log)
3132            {
3133                ASTDumper ast_dumper(const_cast<VarDecl*>(var_decl));
3134                log->Printf("Variable of unknown type now has Decl %s", ast_dumper.GetCString());
3135            }
3136
3137            QualType var_type = var_decl->getType();
3138            TypeFromParser parser_type(var_type.getAsOpaquePtr(), &var_decl->getASTContext());
3139
3140            lldb::clang_type_t copied_type = m_ast_importer->CopyType(scratch_ast_context, &var_decl->getASTContext(), var_type.getAsOpaquePtr());
3141
3142            if (!copied_type)
3143            {
3144                if (log)
3145                    log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't import the type for a variable");
3146
3147                return (bool) lldb::ClangExpressionVariableSP();
3148            }
3149
3150            TypeFromUser user_type(copied_type, scratch_ast_context);
3151
3152            entity->m_parser_vars->m_lldb_value->SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
3153            entity->m_parser_vars->m_parser_type = parser_type;
3154
3155            entity->SetClangAST(user_type.GetASTContext());
3156            entity->SetClangType(user_type.GetOpaqueQualType());
3157
3158            entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType);
3159        }
3160    }
3161
3162    return true;
3163}
3164
3165void
3166ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context,
3167                                        const RegisterInfo *reg_info,
3168                                        unsigned int current_id)
3169{
3170    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
3171
3172    void *ast_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(m_ast_context,
3173                                                                          reg_info->encoding,
3174                                                                          reg_info->byte_size * 8);
3175
3176    if (!ast_type)
3177    {
3178        if (log)
3179            log->Printf("  Tried to add a type for %s, but couldn't get one", context.m_decl_name.getAsString().c_str());
3180        return;
3181    }
3182
3183    TypeFromParser parser_type (ast_type,
3184                                m_ast_context);
3185
3186    NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
3187
3188    ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
3189                                                                      m_parser_vars->m_target_info.byte_order,
3190                                                                      m_parser_vars->m_target_info.address_byte_size));
3191    assert (entity.get());
3192    std::string decl_name(context.m_decl_name.getAsString());
3193    entity->SetName (ConstString (decl_name.c_str()));
3194    entity->SetRegisterInfo (reg_info);
3195    entity->EnableParserVars();
3196    entity->m_parser_vars->m_parser_type = parser_type;
3197    entity->m_parser_vars->m_named_decl  = var_decl;
3198    entity->m_parser_vars->m_llvm_value  = NULL;
3199    entity->m_parser_vars->m_lldb_value  = NULL;
3200    entity->m_flags |= ClangExpressionVariable::EVBareRegister;
3201
3202    if (log)
3203    {
3204        ASTDumper ast_dumper(var_decl);
3205        log->Printf("  CEDM::FEVD[%d] Added register %s, returned %s", current_id, context.m_decl_name.getAsString().c_str(), ast_dumper.GetCString());
3206    }
3207}
3208
3209void
3210ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
3211                                        Function* fun,
3212                                        Symbol* symbol,
3213                                        unsigned int current_id)
3214{
3215    assert (m_parser_vars.get());
3216
3217    lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
3218
3219    NamedDecl *fun_decl = NULL;
3220    std::auto_ptr<Value> fun_location(new Value);
3221    const Address *fun_address = NULL;
3222
3223    // only valid for Functions, not for Symbols
3224    void *fun_opaque_type = NULL;
3225    ASTContext *fun_ast_context = NULL;
3226
3227    if (fun)
3228    {
3229        Type *fun_type = fun->GetType();
3230
3231        if (!fun_type)
3232        {
3233            if (log)
3234                log->PutCString("  Skipped a function because it has no type");
3235            return;
3236        }
3237
3238        fun_opaque_type = fun_type->GetClangFullType();
3239
3240        if (!fun_opaque_type)
3241        {
3242            if (log)
3243                log->PutCString("  Skipped a function because it has no Clang type");
3244            return;
3245        }
3246
3247        fun_address = &fun->GetAddressRange().GetBaseAddress();
3248
3249        fun_ast_context = fun_type->GetClangASTContext().getASTContext();
3250        void *copied_type = GuardedCopyType(m_ast_context, fun_ast_context, fun_opaque_type);
3251        if (copied_type)
3252        {
3253            fun_decl = context.AddFunDecl(copied_type);
3254        }
3255        else
3256        {
3257            // We failed to copy the type we found
3258            if (log)
3259            {
3260                log->Printf ("  Failed to import the function type '%s' {0x%8.8llx} into the expression parser AST contenxt",
3261                             fun_type->GetName().GetCString(),
3262                             fun_type->GetID());
3263            }
3264
3265            return;
3266        }
3267    }
3268    else if (symbol)
3269    {
3270        fun_address = &symbol->GetAddress();
3271        fun_decl = context.AddGenericFunDecl();
3272    }
3273    else
3274    {
3275        if (log)
3276            log->PutCString("  AddOneFunction called with no function and no symbol");
3277        return;
3278    }
3279
3280    Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
3281
3282    lldb::addr_t load_addr = fun_address->GetCallableLoadAddress(target);
3283    fun_location->SetValueType(Value::eValueTypeLoadAddress);
3284    fun_location->GetScalar() = load_addr;
3285
3286    ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
3287                                                                      m_parser_vars->m_target_info.byte_order,
3288                                                                      m_parser_vars->m_target_info.address_byte_size));
3289    assert (entity.get());
3290    std::string decl_name(context.m_decl_name.getAsString());
3291    entity->SetName(ConstString(decl_name.c_str()));
3292    entity->SetClangType (fun_opaque_type);
3293    entity->SetClangAST (fun_ast_context);
3294
3295    entity->EnableParserVars();
3296    entity->m_parser_vars->m_named_decl  = fun_decl;
3297    entity->m_parser_vars->m_llvm_value  = NULL;
3298    entity->m_parser_vars->m_lldb_value  = fun_location.release();
3299
3300    if (log)
3301    {
3302        ASTDumper ast_dumper(fun_decl);
3303
3304        StreamString ss;
3305
3306        fun_address->Dump(&ss, m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
3307
3308        log->Printf("  CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
3309                    current_id,
3310                    (fun ? "specific" : "generic"),
3311                    decl_name.c_str(),
3312                    ss.GetData(),
3313                    ast_dumper.GetCString());
3314    }
3315}
3316
3317void
3318ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
3319                                   TypeFromUser &ut,
3320                                   unsigned int current_id,
3321                                   bool add_method)
3322{
3323    ASTContext *parser_ast_context = m_ast_context;
3324    ASTContext *user_ast_context = ut.GetASTContext();
3325
3326    void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
3327
3328    if (!copied_type)
3329    {
3330        lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
3331
3332        if (log)
3333            log->Printf("ClangExpressionDeclMap::AddOneType - Couldn't import the type");
3334
3335        return;
3336    }
3337
3338    if (add_method && ClangASTContext::IsAggregateType(copied_type) && ClangASTContext::GetCompleteType (parser_ast_context, copied_type))
3339    {
3340        void *args[1];
3341
3342        args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
3343
3344        clang_type_t method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
3345                                                                        ClangASTContext::GetBuiltInType_void(parser_ast_context),
3346                                                                        args,
3347                                                                        1,
3348                                                                        false,
3349                                                                        ClangASTContext::GetTypeQualifiers(copied_type));
3350
3351        const bool is_virtual = false;
3352        const bool is_static = false;
3353        const bool is_inline = false;
3354        const bool is_explicit = false;
3355        const bool is_attr_used = true;
3356        const bool is_artificial = false;
3357
3358        ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
3359                                                   copied_type,
3360                                                   "$__lldb_expr",
3361                                                   method_type,
3362                                                   lldb::eAccessPublic,
3363                                                   is_virtual,
3364                                                   is_static,
3365                                                   is_inline,
3366                                                   is_explicit,
3367                                                   is_attr_used,
3368                                                   is_artificial);
3369    }
3370
3371    context.AddTypeDecl(copied_type);
3372}
3373