1 //===-- Variable.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/Symbol/Variable.h"
11 
12 #include "lldb/Core/Stream.h"
13 #include "lldb/Symbol/Block.h"
14 #include "lldb/Symbol/Function.h"
15 #include "lldb/Symbol/SymbolContext.h"
16 #include "lldb/Symbol/Type.h"
17 #include "lldb/Target/StackFrame.h"
18 #include "lldb/Target/Thread.h"
19 
20 using namespace lldb;
21 using namespace lldb_private;
22 
23 //----------------------------------------------------------------------
24 // Variable constructor
25 //----------------------------------------------------------------------
26 Variable::Variable(lldb::user_id_t uid,
27                        const ConstString& name,
28                        Type *type,
29                        ValueType scope,
30                        SymbolContextScope *context,
31                        Declaration* decl_ptr,
32                        const DWARFExpression& location,
33                        bool external,
34                        bool artificial) :
35     UserID(uid),
36     m_name(name),
37     m_type(type),
38     m_scope(scope),
39     m_context(context),
40     m_declaration(decl_ptr),
41     m_location(location),
42     m_external(external),
43     m_artificial(artificial)
44 {
45 }
46 
47 //----------------------------------------------------------------------
48 // Destructor
49 //----------------------------------------------------------------------
50 Variable::~Variable()
51 {
52 }
53 
54 
55 void
56 Variable::Dump(Stream *s, bool show_context) const
57 {
58     s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
59     s->Indent();
60     *s << "Variable" << (const UserID&)*this;
61 
62     if (m_name)
63         *s << ", name = \"" << m_name << "\"";
64 
65     if (m_type != NULL)
66     {
67         *s << ", type = " << (void*)m_type << " (";
68         m_type->DumpTypeName(s);
69         s->PutChar(')');
70     }
71 
72     if (m_scope != eValueTypeInvalid)
73     {
74         s->PutCString(", scope = ");
75         switch (m_scope)
76         {
77         case eValueTypeVariableGlobal:       s->PutCString(m_external ? "global" : "static"); break;
78         case eValueTypeVariableArgument:    s->PutCString("parameter"); break;
79         case eValueTypeVariableLocal:        s->PutCString("local"); break;
80         default:            *s << "??? (" << m_scope << ')';
81         }
82     }
83 
84     if (show_context && m_context != NULL)
85     {
86         s->PutCString(", context = ( ");
87         m_context->DumpSymbolContext(s);
88         s->PutCString(" )");
89     }
90 
91     m_declaration.Dump(s);
92 
93     if (m_location.IsValid())
94     {
95         s->PutCString(", location = ");
96         m_location.GetDescription(s, lldb::eDescriptionLevelBrief);
97     }
98 
99     if (m_external)
100         s->PutCString(", external");
101 
102     if (m_artificial)
103         s->PutCString(", artificial");
104 
105     s->EOL();
106 }
107 
108 
109 size_t
110 Variable::MemorySize() const
111 {
112     return sizeof(Variable);
113 }
114 
115 
116 void
117 Variable::CalculateSymbolContext (SymbolContext *sc)
118 {
119     if (m_context)
120         m_context->CalculateSymbolContext(sc);
121     else
122         sc->Clear();
123 }
124 
125 
126 bool
127 Variable::IsInScope (StackFrame *frame)
128 {
129     switch (m_scope)
130     {
131     case eValueTypeVariableGlobal:
132         // Globals and statics are always in scope.
133         return true;
134 
135     case eValueTypeVariableArgument:
136     case eValueTypeVariableLocal:
137         // Check if the location has a location list that describes the value
138         // of the variable with address ranges and different locations for each
139         // address range?
140         if (m_location.IsLocationList())
141         {
142             // It is a location list. We just need to tell if the location
143             // list contains the current address when converted to a load
144             // address
145             return m_location.LocationListContainsLoadAddress (&frame->GetThread().GetProcess(), frame->GetPC());
146         }
147         else
148         {
149             // We don't have a location list, we just need to see if the block
150             // that this variable was defined in is currently
151             Block *frame_block = frame->GetSymbolContext(eSymbolContextBlock).block;
152             if (frame_block)
153             {
154                 SymbolContext variable_sc;
155                 CalculateSymbolContext (&variable_sc);
156                 if (variable_sc.function && variable_sc.block)
157                     return variable_sc.block->ContainsBlockWithID (frame_block->GetID());
158             }
159         }
160         break;
161 
162     default:
163         break;
164     }
165     return false;
166 }
167 
168