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