blob: 7f841b4856a543aee4f6b35bd7d8c2d213958754 [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
Greg Clayton82f07462011-05-30 00:49:24 +0000159bool
160Variable::LocationIsValidForFrame (StackFrame *frame)
161{
162 // Is the variable is described by a single location?
163 if (!m_location.IsLocationList())
164 {
165 // Yes it is, the location is valid.
166 return true;
167 }
168
169 if (frame)
170 {
171 Target *target = &frame->GetThread().GetProcess().GetTarget();
172
173 Function *function = frame->GetSymbolContext(eSymbolContextFunction).function;
174 if (function)
175 {
176 addr_t loclist_base_load_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
177 if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
178 return false;
179 // It is a location list. We just need to tell if the location
180 // list contains the current address when converted to a load
181 // address
182 return m_location.LocationListContainsAddress (loclist_base_load_addr,
183 frame->GetFrameCodeAddress().GetLoadAddress (target));
184 }
185 }
186 return false;
187}
Chris Lattner24943d22010-06-08 16:52:24 +0000188
189bool
190Variable::IsInScope (StackFrame *frame)
191{
192 switch (m_scope)
193 {
Greg Clayton82f07462011-05-30 00:49:24 +0000194 case eValueTypeRegister:
195 case eValueTypeRegisterSet:
196 return frame != NULL;
197
198 case eValueTypeConstResult:
Chris Lattner24943d22010-06-08 16:52:24 +0000199 return true;
200
Greg Clayton82f07462011-05-30 00:49:24 +0000201 case eValueTypeVariableGlobal:
202 case eValueTypeVariableStatic:
Chris Lattner24943d22010-06-08 16:52:24 +0000203 case eValueTypeVariableArgument:
204 case eValueTypeVariableLocal:
Greg Clayton82f07462011-05-30 00:49:24 +0000205 if (frame)
Chris Lattner24943d22010-06-08 16:52:24 +0000206 {
207 // We don't have a location list, we just need to see if the block
208 // that this variable was defined in is currently
Greg Claytona357ecf2010-09-14 03:16:58 +0000209 Block *deepest_frame_block = frame->GetSymbolContext(eSymbolContextBlock).block;
210 if (deepest_frame_block)
Chris Lattner24943d22010-06-08 16:52:24 +0000211 {
212 SymbolContext variable_sc;
213 CalculateSymbolContext (&variable_sc);
Greg Clayton82f07462011-05-30 00:49:24 +0000214 // Check for static or global variable defined at the compile unit
215 // level that wasn't defined in a block
216 if (variable_sc.block == NULL)
217 return true;
218
Greg Claytona357ecf2010-09-14 03:16:58 +0000219 if (variable_sc.block == deepest_frame_block)
Greg Clayton178710c2010-09-14 02:20:48 +0000220 return true;
Greg Claytona357ecf2010-09-14 03:16:58 +0000221 return variable_sc.block->Contains (deepest_frame_block);
Chris Lattner24943d22010-06-08 16:52:24 +0000222 }
223 }
224 break;
225
226 default:
Chris Lattner24943d22010-06-08 16:52:24 +0000227 break;
228 }
229 return false;
230}
231