blob: f264e142fef89440a2e806148eec78f3cc4f0374 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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"
Greg Clayton3bc52d02010-11-14 22:13:40 +000013#include "lldb/Core/RegularExpression.h"
Chris Lattner24943d22010-06-08 16:52:24 +000014#include "lldb/Symbol/Block.h"
15#include "lldb/Symbol/Function.h"
16#include "lldb/Symbol/SymbolContext.h"
17#include "lldb/Symbol/Type.h"
Greg Claytoneea26402010-09-14 23:36:40 +000018#include "lldb/Target/Process.h"
Greg Claytonb04e7a82010-08-24 21:05:24 +000019#include "lldb/Target/RegisterContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020#include "lldb/Target/StackFrame.h"
21#include "lldb/Target/Thread.h"
Greg Claytoneea26402010-09-14 23:36:40 +000022#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023
24using namespace lldb;
25using namespace lldb_private;
26
27//----------------------------------------------------------------------
28// Variable constructor
29//----------------------------------------------------------------------
Greg Clayton3bc52d02010-11-14 22:13:40 +000030Variable::Variable
31(
32 lldb::user_id_t uid,
33 const char *name,
34 const char *mangled, // The mangled variable name for variables in namespaces
35 Type *type,
36 ValueType scope,
37 SymbolContextScope *context,
38 Declaration* decl_ptr,
39 const DWARFExpression& location,
40 bool external,
41 bool artificial
42) :
Chris Lattner24943d22010-06-08 16:52:24 +000043 UserID(uid),
44 m_name(name),
Greg Clayton3bc52d02010-11-14 22:13:40 +000045 m_mangled (mangled, true),
Chris Lattner24943d22010-06-08 16:52:24 +000046 m_type(type),
47 m_scope(scope),
Greg Clayton4fb08152010-08-30 18:11:35 +000048 m_owner_scope(context),
Chris Lattner24943d22010-06-08 16:52:24 +000049 m_declaration(decl_ptr),
50 m_location(location),
51 m_external(external),
52 m_artificial(artificial)
53{
54}
55
56//----------------------------------------------------------------------
57// Destructor
58//----------------------------------------------------------------------
59Variable::~Variable()
60{
61}
62
63
Greg Clayton3bc52d02010-11-14 22:13:40 +000064const ConstString&
65Variable::GetName() const
66{
67 if (m_mangled)
68 return m_mangled.GetName();
69 return m_name;
70}
71
72bool
73Variable::NameMatches (const RegularExpression& regex) const
74{
75 if (regex.Execute (m_name.AsCString()))
76 return true;
77 return m_mangled.NameMatches (regex);
78}
79
Chris Lattner24943d22010-06-08 16:52:24 +000080void
81Variable::Dump(Stream *s, bool show_context) const
82{
83 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
84 s->Indent();
85 *s << "Variable" << (const UserID&)*this;
86
87 if (m_name)
88 *s << ", name = \"" << m_name << "\"";
89
90 if (m_type != NULL)
91 {
Greg Claytonfb7c51c2010-10-13 03:15:28 +000092 *s << ", type = {" << m_type->GetID() << "} " << (void*)m_type << " (";
Chris Lattner24943d22010-06-08 16:52:24 +000093 m_type->DumpTypeName(s);
94 s->PutChar(')');
95 }
96
97 if (m_scope != eValueTypeInvalid)
98 {
99 s->PutCString(", scope = ");
100 switch (m_scope)
101 {
102 case eValueTypeVariableGlobal: s->PutCString(m_external ? "global" : "static"); break;
103 case eValueTypeVariableArgument: s->PutCString("parameter"); break;
104 case eValueTypeVariableLocal: s->PutCString("local"); break;
105 default: *s << "??? (" << m_scope << ')';
106 }
107 }
108
Greg Clayton4fb08152010-08-30 18:11:35 +0000109 if (show_context && m_owner_scope != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000110 {
111 s->PutCString(", context = ( ");
Greg Clayton4fb08152010-08-30 18:11:35 +0000112 m_owner_scope->DumpSymbolContext(s);
Chris Lattner24943d22010-06-08 16:52:24 +0000113 s->PutCString(" )");
114 }
115
Greg Clayton1924e242010-09-15 05:51:24 +0000116 bool show_fullpaths = false;
117 m_declaration.Dump(s, show_fullpaths);
Chris Lattner24943d22010-06-08 16:52:24 +0000118
119 if (m_location.IsValid())
120 {
121 s->PutCString(", location = ");
Greg Clayton178710c2010-09-14 02:20:48 +0000122 lldb::addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
123 if (m_location.IsLocationList())
124 {
125 SymbolContext variable_sc;
126 m_owner_scope->CalculateSymbolContext(&variable_sc);
127 if (variable_sc.function)
128 loclist_base_addr = variable_sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
129 }
130 m_location.GetDescription(s, lldb::eDescriptionLevelBrief, loclist_base_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000131 }
132
133 if (m_external)
134 s->PutCString(", external");
135
136 if (m_artificial)
137 s->PutCString(", artificial");
138
139 s->EOL();
140}
141
142
143size_t
144Variable::MemorySize() const
145{
146 return sizeof(Variable);
147}
148
149
150void
151Variable::CalculateSymbolContext (SymbolContext *sc)
152{
Greg Clayton4fb08152010-08-30 18:11:35 +0000153 if (m_owner_scope)
154 m_owner_scope->CalculateSymbolContext(sc);
Chris Lattner24943d22010-06-08 16:52:24 +0000155 else
156 sc->Clear();
157}
158
159
160bool
161Variable::IsInScope (StackFrame *frame)
162{
163 switch (m_scope)
164 {
165 case eValueTypeVariableGlobal:
Greg Clayton178710c2010-09-14 02:20:48 +0000166 case eValueTypeVariableStatic:
Chris Lattner24943d22010-06-08 16:52:24 +0000167 // Globals and statics are always in scope.
168 return true;
169
170 case eValueTypeVariableArgument:
171 case eValueTypeVariableLocal:
172 // Check if the location has a location list that describes the value
173 // of the variable with address ranges and different locations for each
174 // address range?
175 if (m_location.IsLocationList())
176 {
Greg Clayton178710c2010-09-14 02:20:48 +0000177 SymbolContext sc;
178 CalculateSymbolContext(&sc);
179
180 // Currently we only support functions that have things with
181 // locations lists. If this expands, we will need to add support
182 assert (sc.function);
Greg Claytoneea26402010-09-14 23:36:40 +0000183 Target *target = &frame->GetThread().GetProcess().GetTarget();
184 addr_t loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
Greg Clayton178710c2010-09-14 02:20:48 +0000185 if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
186 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000187 // It is a location list. We just need to tell if the location
188 // list contains the current address when converted to a load
189 // address
Greg Claytoneea26402010-09-14 23:36:40 +0000190 return m_location.LocationListContainsAddress (loclist_base_load_addr, frame->GetFrameCodeAddress().GetLoadAddress (target));
Chris Lattner24943d22010-06-08 16:52:24 +0000191 }
192 else
193 {
194 // We don't have a location list, we just need to see if the block
195 // that this variable was defined in is currently
Greg Claytona357ecf2010-09-14 03:16:58 +0000196 Block *deepest_frame_block = frame->GetSymbolContext(eSymbolContextBlock).block;
197 if (deepest_frame_block)
Chris Lattner24943d22010-06-08 16:52:24 +0000198 {
199 SymbolContext variable_sc;
200 CalculateSymbolContext (&variable_sc);
Greg Claytona357ecf2010-09-14 03:16:58 +0000201 if (variable_sc.block == deepest_frame_block)
Greg Clayton178710c2010-09-14 02:20:48 +0000202 return true;
203
Greg Claytona357ecf2010-09-14 03:16:58 +0000204 return variable_sc.block->Contains (deepest_frame_block);
Chris Lattner24943d22010-06-08 16:52:24 +0000205 }
206 }
207 break;
208
209 default:
Greg Clayton178710c2010-09-14 02:20:48 +0000210 assert (!"Unhandled case");
Chris Lattner24943d22010-06-08 16:52:24 +0000211 break;
212 }
213 return false;
214}
215