ClangExpressionDeclMap.cpp revision 30449d50f5328ca745d09d943b7e3b1ba41bff08
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 "lldb/lldb-private.h"
18#include "lldb/Core/Address.h"
19#include "lldb/Core/Error.h"
20#include "lldb/Core/Log.h"
21#include "lldb/Core/Module.h"
22#include "lldb/Expression/ClangASTSource.h"
23#include "lldb/Expression/ClangPersistentVariables.h"
24#include "lldb/Symbol/ClangASTContext.h"
25#include "lldb/Symbol/CompileUnit.h"
26#include "lldb/Symbol/Function.h"
27#include "lldb/Symbol/ObjectFile.h"
28#include "lldb/Symbol/SymbolContext.h"
29#include "lldb/Symbol/Type.h"
30#include "lldb/Symbol/TypeList.h"
31#include "lldb/Symbol/Variable.h"
32#include "lldb/Symbol/VariableList.h"
33#include "lldb/Target/ExecutionContext.h"
34#include "lldb/Target/Process.h"
35#include "lldb/Target/StackFrame.h"
36#include "lldb/Target/Target.h"
37
38using namespace lldb_private;
39using namespace clang;
40
41ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) :
42    m_exe_ctx(exe_ctx),    m_struct_laid_out(false),
43    m_materialized_location(0)
44{
45    if (exe_ctx && exe_ctx->frame)
46        m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
47    else
48        m_sym_ctx = NULL;
49
50    if (exe_ctx && exe_ctx->process)
51        m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
52}
53
54ClangExpressionDeclMap::~ClangExpressionDeclMap()
55{
56    for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
57         entity_index < num_entities;
58         ++entity_index)
59    {
60        ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
61        if (entity.m_parser_vars.get() &&
62            entity.m_parser_vars->m_lldb_value)
63            delete entity.m_parser_vars->m_lldb_value;
64
65        entity.DisableParserVars();
66    }
67
68    for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size();
69         pvar_index < num_pvars;
70         ++pvar_index)
71    {
72        ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index));
73        pvar.DisableParserVars();
74    }
75
76    if (m_sym_ctx)
77        delete m_sym_ctx;
78}
79
80// Interface for IRForTarget
81
82void
83ClangExpressionDeclMap::GetPersistentResultName (std::string &name)
84{
85    m_persistent_vars->GetNextResultName(m_result_name);
86
87    name = m_result_name;
88}
89
90bool
91ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl,
92                                               const char *name,
93                                               TypeFromParser parser_type)
94{
95    clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
96
97    TypeFromUser user_type(ClangASTContext::CopyType(context,
98                                                     parser_type.GetASTContext(),
99                                                     parser_type.GetOpaqueQualType()),
100                            context);
101
102    if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
103        return false;
104
105    ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
106
107    if (!var)
108        return false;
109
110    var->EnableParserVars();
111
112    var->m_parser_vars->m_named_decl = decl;
113    var->m_parser_vars->m_parser_type = parser_type;
114
115    return true;
116}
117
118bool
119ClangExpressionDeclMap::AddValueToStruct (const clang::NamedDecl *decl,
120                                          const char *name,
121                                          llvm::Value *value,
122                                          size_t size,
123                                          off_t alignment)
124{
125    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
126
127    m_struct_laid_out = false;
128
129    if (m_struct_members.GetVariable(decl))
130        return true;
131
132    ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
133
134    if (!var)
135        var = m_persistent_vars->GetVariable(decl);
136
137    if (!var)
138        return false;
139
140    if (log)
141        log->Printf("Adding value for decl %p [%s - %s] to the structure",
142                    decl,
143                    name,
144                    var->m_name.c_str());
145
146    // We know entity->m_parser_vars is valid because we used a parser variable
147    // to find it
148    var->m_parser_vars->m_llvm_value = value;
149
150    var->EnableJITVars();
151    var->m_jit_vars->m_alignment = alignment;
152    var->m_jit_vars->m_size = size;
153
154    m_struct_members.AddVariable(*var);
155
156    return true;
157}
158
159bool
160ClangExpressionDeclMap::DoStructLayout ()
161{
162    if (m_struct_laid_out)
163        return true;
164
165    off_t cursor = 0;
166
167    m_struct_alignment = 0;
168    m_struct_size = 0;
169
170    for (uint64_t member_index = 0, num_members = m_struct_members.Size();
171         member_index < num_members;
172         ++member_index)
173    {
174        ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
175
176        if (!member.m_jit_vars.get())
177            return false;
178
179        if (member_index == 0)
180            m_struct_alignment = member.m_jit_vars->m_alignment;
181
182        if (cursor % member.m_jit_vars->m_alignment)
183            cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
184
185        member.m_jit_vars->m_offset = cursor;
186        cursor += member.m_jit_vars->m_size;
187    }
188
189    m_struct_size = cursor;
190
191    m_struct_laid_out = true;
192    return true;
193}
194
195bool ClangExpressionDeclMap::GetStructInfo (uint32_t &num_elements,
196                                            size_t &size,
197                                            off_t &alignment)
198{
199    if (!m_struct_laid_out)
200        return false;
201
202    num_elements = m_struct_members.Size();
203    size = m_struct_size;
204    alignment = m_struct_alignment;
205
206    return true;
207}
208
209bool
210ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl,
211                                          llvm::Value *&value,
212                                          off_t &offset,
213                                          const char *&name,
214                                          uint32_t index)
215{
216    if (!m_struct_laid_out)
217        return false;
218
219    if (index >= m_struct_members.Size())
220        return false;
221
222    ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
223
224    if (!member.m_parser_vars.get() ||
225        !member.m_jit_vars.get())
226        return false;
227
228    decl = member.m_parser_vars->m_named_decl;
229    value = member.m_parser_vars->m_llvm_value;
230    offset = member.m_jit_vars->m_offset;
231    name = member.m_name.c_str();
232
233    return true;
234}
235
236bool
237ClangExpressionDeclMap::GetFunctionInfo (const clang::NamedDecl *decl,
238                                         llvm::Value**& value,
239                                         uint64_t &ptr)
240{
241    ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
242
243    if (!entity)
244        return false;
245
246    // We know m_parser_vars is valid since we searched for the variable by
247    // its NamedDecl
248
249    value = &entity->m_parser_vars->m_llvm_value;
250    ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
251
252    return true;
253}
254
255bool
256ClangExpressionDeclMap::GetFunctionAddress (const char *name,
257                                            uint64_t &ptr)
258{
259    // Back out in all cases where we're not fully initialized
260    if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
261        return false;
262
263    ConstString name_cs(name);
264    SymbolContextList sym_ctxs;
265
266    m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
267
268    if (!sym_ctxs.GetSize())
269        return false;
270
271    SymbolContext sym_ctx;
272    sym_ctxs.GetContextAtIndex(0, sym_ctx);
273
274    const Address *fun_address;
275
276    if (sym_ctx.function)
277        fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
278    else if (sym_ctx.symbol)
279        fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
280    else
281        return false;
282
283    ptr = fun_address->GetLoadAddress(m_exe_ctx->target);
284
285    return true;
286}
287
288// Interface for CommandObjectExpression
289
290bool
291ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx,
292                                     lldb::addr_t &struct_address,
293                                     Error &err)
294{
295    bool result = DoMaterialize(false, exe_ctx, NULL, err);
296
297    if (result)
298        struct_address = m_materialized_location;
299
300    return result;
301}
302
303bool
304ClangExpressionDeclMap::GetObjectPointer(lldb::addr_t &object_ptr,
305                                         ExecutionContext *exe_ctx,
306                                         Error &err)
307{
308    if (!exe_ctx || !exe_ctx->frame || !exe_ctx->target || !exe_ctx->process)
309    {
310        err.SetErrorString("Couldn't load 'this' because the context is incomplete");
311        return false;
312    }
313
314    if (!m_object_pointer_type.GetOpaqueQualType())
315    {
316        err.SetErrorString("Couldn't load 'this' because its type is unknown");
317        return false;
318    }
319
320    Variable *object_ptr_var = FindVariableInScope(*exe_ctx->frame, "this", &m_object_pointer_type);
321
322    if (!object_ptr_var)
323    {
324        err.SetErrorString("Couldn't find 'this' with appropriate type in scope");
325        return false;
326    }
327
328    std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(*exe_ctx,
329                                                                       object_ptr_var,
330                                                                       m_object_pointer_type.GetASTContext()));
331
332    if (!location_value.get())
333    {
334        err.SetErrorString("Couldn't get the location for 'this'");
335        return false;
336    }
337
338    if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
339    {
340        lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
341        uint32_t address_byte_size = exe_ctx->target->GetArchitecture().GetAddressByteSize();
342        lldb::ByteOrder address_byte_order = exe_ctx->process->GetByteOrder();
343
344        if (ClangASTType::GetClangTypeBitWidth(m_object_pointer_type.GetASTContext(), m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
345        {
346            err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
347            return false;
348        }
349
350        DataBufferHeap data;
351        data.SetByteSize(address_byte_size);
352        Error read_error;
353
354        if (exe_ctx->process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
355        {
356            err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
357            return false;
358        }
359
360        DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
361
362        uint32_t offset = 0;
363
364        object_ptr = extractor.GetPointer(&offset);
365
366        return true;
367    }
368    else
369    {
370        err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers");
371        return false;
372    }
373}
374
375bool
376ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx,
377                                       ClangExpressionVariable *&result,
378                                       Error &err)
379{
380    return DoMaterialize(true, exe_ctx, &result, err);
381}
382
383bool
384ClangExpressionDeclMap::DumpMaterializedStruct(ExecutionContext *exe_ctx,
385                                               Stream &s,
386                                               Error &err)
387{
388    if (!m_struct_laid_out)
389    {
390        err.SetErrorString("Structure hasn't been laid out yet");
391        return false;
392    }
393
394    if (!exe_ctx)
395    {
396        err.SetErrorString("Received null execution context");
397        return false;
398    }
399
400
401    if (!exe_ctx->process)
402    {
403        err.SetErrorString("Couldn't find the process");
404        return false;
405    }
406
407    if (!exe_ctx->target)
408    {
409        err.SetErrorString("Couldn't find the target");
410        return false;
411    }
412
413    lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
414
415    Error error;
416    if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
417    {
418        err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
419        return false;
420    }
421
422    DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
423
424    for (uint64_t member_index = 0, num_members = m_struct_members.Size();
425         member_index < num_members;
426         ++member_index)
427    {
428        ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
429
430        s.Printf("[%s]\n", member.m_name.c_str());
431
432        if (!member.m_jit_vars.get())
433            return false;
434
435        extractor.Dump(&s,                                                      // stream
436                       member.m_jit_vars->m_offset,                             // offset
437                       lldb::eFormatBytesWithASCII,                             // format
438                       1,                                                       // byte size of individual entries
439                       member.m_jit_vars->m_size,                               // number of entries
440                       16,                                                      // entries per line
441                       m_materialized_location + member.m_jit_vars->m_offset,   // address to print
442                       0,                                                       // bit size (bitfields only; 0 means ignore)
443                       0);                                                      // bit alignment (bitfields only; 0 means ignore)
444
445        s.PutChar('\n');
446    }
447
448    return true;
449}
450
451bool
452ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
453                                       ExecutionContext *exe_ctx,
454                                       ClangExpressionVariable **result,
455                                       Error &err)
456{
457    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
458
459    if (!m_struct_laid_out)
460    {
461        err.SetErrorString("Structure hasn't been laid out yet");
462        return LLDB_INVALID_ADDRESS;
463    }
464
465    if (!exe_ctx)
466    {
467        err.SetErrorString("Received null execution context");
468        return LLDB_INVALID_ADDRESS;
469    }
470
471    if (!exe_ctx->frame)
472    {
473        err.SetErrorString("Received null execution frame");
474        return LLDB_INVALID_ADDRESS;
475    }
476
477    if (!m_struct_size)
478    {
479        if (log)
480            log->PutCString("Not bothering to allocate a struct because no arguments are needed");
481
482        m_allocated_area = NULL;
483
484        return true;
485    }
486
487    const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
488
489    if (!dematerialize)
490    {
491        if (m_materialized_location)
492        {
493            exe_ctx->process->DeallocateMemory(m_materialized_location);
494            m_materialized_location = 0;
495        }
496
497        lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
498                                                            lldb::ePermissionsReadable | lldb::ePermissionsWritable,
499                                                            err);
500
501        if (mem == LLDB_INVALID_ADDRESS)
502            return false;
503
504        m_allocated_area = mem;
505    }
506
507    m_materialized_location = m_allocated_area;
508
509    if (m_materialized_location % m_struct_alignment)
510        m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
511
512    for (uint64_t member_index = 0, num_members = m_struct_members.Size();
513         member_index < num_members;
514         ++member_index)
515    {
516        ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
517
518        if (!member.m_parser_vars.get())
519            return false;
520
521        ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
522        ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name.c_str());
523
524        if (entity)
525        {
526            if (!member.m_jit_vars.get())
527                return false;
528
529            if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, member.m_name.c_str(), member.m_user_type, m_materialized_location + member.m_jit_vars->m_offset, err))
530                return false;
531        }
532        else if (persistent_variable)
533        {
534            if (!member.m_name.compare(m_result_name))
535            {
536                if (!dematerialize)
537                    continue;
538
539                if (log)
540                    log->PutCString("Found result member in the struct");
541
542                *result = &member;
543            }
544
545            if (log)
546                log->Printf("Searched for persistent variable %s and found %s", member.m_name.c_str(), persistent_variable->m_name.c_str());
547
548            if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name.c_str(), m_materialized_location + member.m_jit_vars->m_offset, err))
549                return false;
550        }
551        else
552        {
553            err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.c_str());
554            return false;
555        }
556    }
557
558    return true;
559}
560
561bool
562ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize,
563                                                           ExecutionContext &exe_ctx,
564                                                           const char *name,
565                                                           lldb::addr_t addr,
566                                                           Error &err)
567{
568    ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
569
570    if (!pvar)
571    {
572        err.SetErrorStringWithFormat("Undefined persistent variable %s", name);
573        return LLDB_INVALID_ADDRESS;
574    }
575
576    size_t pvar_size = pvar->Size();
577
578    if (!pvar->m_data_vars.get())
579        return false;
580
581    uint8_t *pvar_data = pvar->m_data_vars->m_data->GetBytes();
582    Error error;
583
584    if (dematerialize)
585    {
586        if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
587        {
588            err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
589            return false;
590        }
591    }
592    else
593    {
594        if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
595        {
596            err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
597            return false;
598        }
599    }
600
601    return true;
602}
603
604bool
605ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
606                                                 ExecutionContext &exe_ctx,
607                                                 const SymbolContext &sym_ctx,
608                                                 const char *name,
609                                                 TypeFromUser type,
610                                                 lldb::addr_t addr,
611                                                 Error &err)
612{
613    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
614
615    if (!exe_ctx.frame)
616        return false;
617
618    Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type);
619
620    if (!var)
621    {
622        err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
623        return false;
624    }
625
626    if (log)
627        log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetOpaqueQualType());
628
629    std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
630                                                                       var,
631                                                                       type.GetASTContext()));
632
633    if (!location_value.get())
634    {
635        err.SetErrorStringWithFormat("Couldn't get value for %s", name);
636        return false;
637    }
638
639    if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
640    {
641        lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
642
643        size_t bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
644        size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
645
646        DataBufferHeap data;
647        data.SetByteSize(byte_size);
648
649        lldb::addr_t src_addr;
650        lldb::addr_t dest_addr;
651
652        if (dematerialize)
653        {
654            src_addr = addr;
655            dest_addr = value_addr;
656        }
657        else
658        {
659            src_addr = value_addr;
660            dest_addr = addr;
661        }
662
663        Error error;
664        if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size)
665        {
666            err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
667            return false;
668        }
669
670        if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), byte_size, error) != byte_size)
671        {
672            err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
673            return false;
674        }
675
676        if (log)
677            log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
678    }
679    else
680    {
681        StreamString ss;
682
683        location_value->Dump(&ss);
684
685        err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
686    }
687
688    return true;
689}
690
691Variable *
692ClangExpressionDeclMap::FindVariableInScope(StackFrame &frame,
693                                            const char *name,
694                                            TypeFromUser *type)
695{
696    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
697
698    ConstString name_cs(name);
699
700    VariableList *var_list = frame.GetVariableList(true);
701
702    lldb::VariableSP var = var_list->FindVariable(name_cs);
703
704    if (!var)
705        return NULL;
706
707    if (!type)
708        return var.get();
709
710    if (type->GetASTContext() == var->GetType()->GetClangAST())
711    {
712        if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetClangType()))
713            return NULL;
714    }
715    else
716    {
717        if (log)
718            log->PutCString("Skipping a candidate variable because of different AST contexts");
719        return NULL;
720    }
721
722    return var.get();
723
724    return NULL;
725}
726
727// Interface for ClangASTSource
728void
729ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
730                                 const char *name)
731{
732    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
733
734    if (log)
735        log->Printf("Hunting for a definition for %s", name);
736
737    // Back out in all cases where we're not fully initialized
738    if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
739        return;
740
741    ConstString name_cs(name);
742
743    if (!strcmp(name, "___clang_class"))
744    {
745        // Clang is looking for the type of "this"
746
747        VariableList *vars = m_exe_ctx->frame->GetVariableList(false);
748
749        if (!vars)
750            return;
751
752        lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
753
754        if (!this_var)
755            return;
756
757        Type *this_type = this_var->GetType();
758
759        if (!this_type)
760            return;
761
762        TypeFromUser this_user_type(this_type->GetClangType(),
763                                    this_type->GetClangAST());
764
765        m_object_pointer_type = this_user_type;
766
767        void *pointer_target_type;
768
769        if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(),
770                                            &pointer_target_type))
771            return;
772
773        TypeFromUser class_user_type(pointer_target_type,
774                                     this_type->GetClangAST());
775
776        AddOneType(context, class_user_type, true);
777
778        return;
779    }
780
781    SymbolContextList sym_ctxs;
782
783    m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
784
785    bool found_generic = false;
786    bool found_specific = false;
787
788    for (uint32_t index = 0, num_indices = sym_ctxs.GetSize();
789         index < num_indices;
790         ++index)
791    {
792        SymbolContext sym_ctx;
793        sym_ctxs.GetContextAtIndex(index, sym_ctx);
794
795        if (sym_ctx.function)
796        {
797            // TODO only do this if it's a C function; C++ functions may be
798            // overloaded
799            if (!found_specific)
800                AddOneFunction(context, sym_ctx.function, NULL);
801            found_specific = true;
802        }
803        else if(sym_ctx.symbol)
804        {
805            if (!found_generic && !found_specific)
806            {
807                AddOneFunction(context, NULL, sym_ctx.symbol);
808                found_generic = true;
809            }
810        }
811    }
812
813    Variable *var = FindVariableInScope(*m_exe_ctx->frame, name);
814
815    if (var)
816        AddOneVariable(context, var);
817
818    ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
819
820    if (pvar)
821        AddOneVariable(context, pvar);
822
823
824    // See information on gating of this operation next to the definition for
825    // m_lookedup_types.
826
827    const char *name_uniq = name_cs.GetCString();
828
829    if (m_lookedup_types.find(name_uniq) == m_lookedup_types.end())
830    {
831        // 1 The name is added to m_lookedup_types.
832        m_lookedup_types.insert(std::pair<const char*, bool>(name_uniq, true));
833
834        // 2 The type is looked up and added, potentially causing more type loookups.
835        lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs);
836
837        if (type.get())
838        {
839            TypeFromUser user_type(type->GetClangType(),
840                                   type->GetClangAST());
841
842            AddOneType(context, user_type, false);
843        }
844
845        // 3 The name is removed from m_lookedup_types.
846        m_lookedup_types.erase(name_uniq);
847    }
848
849}
850
851Value *
852ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
853                                         Variable *var,
854                                         clang::ASTContext *parser_ast_context,
855                                         TypeFromUser *user_type,
856                                         TypeFromParser *parser_type)
857{
858    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
859
860    Type *var_type = var->GetType();
861
862    if (!var_type)
863    {
864        if (log)
865            log->PutCString("Skipped a definition because it has no type");
866        return NULL;
867    }
868
869    void *var_opaque_type = var_type->GetClangType();
870
871    if (!var_opaque_type)
872    {
873        if (log)
874            log->PutCString("Skipped a definition because it has no Clang type");
875        return NULL;
876    }
877
878    TypeList *type_list = var_type->GetTypeList();
879
880    if (!type_list)
881    {
882        if (log)
883            log->PutCString("Skipped a definition because the type has no associated type list");
884        return NULL;
885    }
886
887    clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
888
889    if (!exe_ast_ctx)
890    {
891        if (log)
892            log->PutCString("There is no AST context for the current execution context");
893        return NULL;
894    }
895
896    DWARFExpression &var_location_expr = var->LocationExpression();
897
898    std::auto_ptr<Value> var_location(new Value);
899
900    lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
901
902    if (var_location_expr.IsLocationList())
903    {
904        SymbolContext var_sc;
905        var->CalculateSymbolContext (&var_sc);
906        loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
907    }
908    Error err;
909
910    if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, loclist_base_load_addr, NULL, *var_location.get(), &err))
911    {
912        if (log)
913            log->Printf("Error evaluating location: %s", err.AsCString());
914        return NULL;
915    }
916
917    clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
918
919    void *type_to_use;
920
921    if (parser_ast_context)
922    {
923        type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
924
925        if (parser_type)
926            *parser_type = TypeFromParser(type_to_use, parser_ast_context);
927    }
928    else
929        type_to_use = var_opaque_type;
930
931    if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
932        var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, type_to_use);
933
934    if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
935    {
936        SymbolContext var_sc;
937        var->CalculateSymbolContext(&var_sc);
938
939        if (!var_sc.module_sp)
940            return NULL;
941
942        ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
943
944        if (!object_file)
945            return NULL;
946
947        Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
948
949        lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->target);
950
951        var_location->GetScalar() = load_addr;
952        var_location->SetValueType(Value::eValueTypeLoadAddress);
953    }
954
955    if (user_type)
956        *user_type = TypeFromUser(var_opaque_type, var_ast_context);
957
958    return var_location.release();
959}
960
961void
962ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
963                                       Variable* var)
964{
965    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
966
967    TypeFromUser ut;
968    TypeFromParser pt;
969
970    Value *var_location = GetVariableValue(*m_exe_ctx,
971                                           var,
972                                           context.GetASTContext(),
973                                           &ut,
974                                           &pt);
975
976    NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
977
978    ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
979    entity.m_name       = context.Name.getAsString();
980    entity.m_user_type  = ut;
981
982    entity.EnableParserVars();
983    entity.m_parser_vars->m_parser_type = pt;
984    entity.m_parser_vars->m_named_decl  = var_decl;
985    entity.m_parser_vars->m_llvm_value  = NULL;
986    entity.m_parser_vars->m_lldb_value  = var_location;
987
988    if (log)
989        log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl);
990}
991
992void
993ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
994                                       ClangExpressionVariable *pvar)
995{
996    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
997
998    TypeFromUser user_type = pvar->m_user_type;
999
1000    TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
1001                                                         user_type.GetASTContext(),
1002                                                         user_type.GetOpaqueQualType()),
1003                               context.GetASTContext());
1004
1005    NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1006
1007    pvar->EnableParserVars();
1008    pvar->m_parser_vars->m_parser_type = parser_type;
1009    pvar->m_parser_vars->m_named_decl  = var_decl;
1010    pvar->m_parser_vars->m_llvm_value  = NULL;
1011    pvar->m_parser_vars->m_lldb_value  = NULL;
1012
1013    if (log)
1014        log->Printf("Added pvar %s, returned (NamedDecl)%p", pvar->m_name.c_str(), var_decl);
1015}
1016
1017void
1018ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
1019                                       Function* fun,
1020                                       Symbol* symbol)
1021{
1022    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
1023
1024    NamedDecl *fun_decl;
1025    std::auto_ptr<Value> fun_location(new Value);
1026    const Address *fun_address;
1027
1028    // only valid for Functions, not for Symbols
1029    void *fun_opaque_type = NULL;
1030    clang::ASTContext *fun_ast_context = NULL;
1031
1032    if (fun)
1033    {
1034#define BROKEN_OVERLOADING
1035        // Awaiting a fix on the Clang side
1036#ifndef BROKEN_OVERLOADING
1037        Type *fun_type = fun->GetType();
1038
1039        if (!fun_type)
1040        {
1041            if (log)
1042                log->PutCString("Skipped a function because it has no type");
1043            return;
1044        }
1045
1046        fun_opaque_type = fun_type->GetClangType();
1047
1048        if (!fun_opaque_type)
1049        {
1050            if (log)
1051                log->PutCString("Skipped a function because it has no Clang type");
1052            return;
1053        }
1054
1055        fun_address = &fun->GetAddressRange().GetBaseAddress();
1056
1057        TypeList *type_list = fun_type->GetTypeList();
1058        fun_ast_context = type_list->GetClangASTContext().getASTContext();
1059        void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
1060
1061        fun_decl = context.AddFunDecl(copied_type);
1062#else
1063        fun_address = &fun->GetAddressRange().GetBaseAddress();
1064
1065        fun_decl = context.AddGenericFunDecl();
1066#endif
1067    }
1068    else if (symbol)
1069    {
1070        fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
1071
1072        fun_decl = context.AddGenericFunDecl();
1073    }
1074    else
1075    {
1076        if (log)
1077            log->PutCString("AddOneFunction called with no function and no symbol");
1078        return;
1079    }
1080
1081    lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx->target);
1082    fun_location->SetValueType(Value::eValueTypeLoadAddress);
1083    fun_location->GetScalar() = load_addr;
1084
1085    ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
1086    entity.m_name       = context.Name.getAsString();
1087    entity.m_user_type  = TypeFromUser(fun_opaque_type, fun_ast_context);;
1088
1089    entity.EnableParserVars();
1090    entity.m_parser_vars->m_named_decl  = fun_decl;
1091    entity.m_parser_vars->m_llvm_value  = NULL;
1092    entity.m_parser_vars->m_lldb_value  = fun_location.release();
1093
1094    if (log)
1095        log->Printf("Found %s function %s, returned (NamedDecl)%p", (fun ? "specific" : "generic"), context.Name.getAsString().c_str(), fun_decl);
1096}
1097
1098void
1099ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
1100                                   TypeFromUser &ut,
1101                                   bool add_method)
1102{
1103    clang::ASTContext *parser_ast_context = context.GetASTContext();
1104    clang::ASTContext *user_ast_context = ut.GetASTContext();
1105
1106    void *copied_type = ClangASTContext::CopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
1107
1108    TypeFromParser parser_type(copied_type, parser_ast_context);
1109
1110    if (add_method && ClangASTContext::IsAggregateType(copied_type))
1111    {
1112        void *args[1];
1113
1114        args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
1115
1116        void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
1117                                                                 ClangASTContext::GetBuiltInType_void(parser_ast_context),
1118                                                                 args,
1119                                                                 1,
1120                                                                 false,
1121                                                                 ClangASTContext::GetTypeQualifiers(copied_type));
1122
1123        const bool is_virtual = false;
1124        const bool is_static = false;
1125        const bool is_inline = false;
1126        const bool is_explicit = false;
1127
1128        ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
1129                                                   copied_type,
1130                                                   "___clang_expr",
1131                                                   method_type,
1132                                                   lldb::eAccessPublic,
1133                                                   is_virtual,
1134                                                   is_static,
1135                                                   is_inline,
1136                                                   is_explicit);
1137    }
1138
1139    context.AddTypeDecl(copied_type);
1140}
1141