blob: 7a4e12cad8607d96ffb6d5c40cc1b34734d358e5 [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"
13#include "lldb/Symbol/Block.h"
14#include "lldb/Symbol/Function.h"
15#include "lldb/Symbol/SymbolContext.h"
16#include "lldb/Symbol/Type.h"
Greg Claytoneea26402010-09-14 23:36:40 +000017#include "lldb/Target/Process.h"
Greg Claytonb04e7a82010-08-24 21:05:24 +000018#include "lldb/Target/RegisterContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Target/StackFrame.h"
20#include "lldb/Target/Thread.h"
Greg Claytoneea26402010-09-14 23:36:40 +000021#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022
23using namespace lldb;
24using namespace lldb_private;
25
26//----------------------------------------------------------------------
27// Variable constructor
28//----------------------------------------------------------------------
29Variable::Variable(lldb::user_id_t uid,
30 const ConstString& name,
31 Type *type,
32 ValueType scope,
33 SymbolContextScope *context,
34 Declaration* decl_ptr,
35 const DWARFExpression& location,
36 bool external,
37 bool artificial) :
38 UserID(uid),
39 m_name(name),
40 m_type(type),
41 m_scope(scope),
Greg Clayton4fb08152010-08-30 18:11:35 +000042 m_owner_scope(context),
Chris Lattner24943d22010-06-08 16:52:24 +000043 m_declaration(decl_ptr),
44 m_location(location),
45 m_external(external),
46 m_artificial(artificial)
47{
48}
49
50//----------------------------------------------------------------------
51// Destructor
52//----------------------------------------------------------------------
53Variable::~Variable()
54{
55}
56
57
58void
59Variable::Dump(Stream *s, bool show_context) const
60{
61 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
62 s->Indent();
63 *s << "Variable" << (const UserID&)*this;
64
65 if (m_name)
66 *s << ", name = \"" << m_name << "\"";
67
68 if (m_type != NULL)
69 {
70 *s << ", type = " << (void*)m_type << " (";
71 m_type->DumpTypeName(s);
72 s->PutChar(')');
73 }
74
75 if (m_scope != eValueTypeInvalid)
76 {
77 s->PutCString(", scope = ");
78 switch (m_scope)
79 {
80 case eValueTypeVariableGlobal: s->PutCString(m_external ? "global" : "static"); break;
81 case eValueTypeVariableArgument: s->PutCString("parameter"); break;
82 case eValueTypeVariableLocal: s->PutCString("local"); break;
83 default: *s << "??? (" << m_scope << ')';
84 }
85 }
86
Greg Clayton4fb08152010-08-30 18:11:35 +000087 if (show_context && m_owner_scope != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +000088 {
89 s->PutCString(", context = ( ");
Greg Clayton4fb08152010-08-30 18:11:35 +000090 m_owner_scope->DumpSymbolContext(s);
Chris Lattner24943d22010-06-08 16:52:24 +000091 s->PutCString(" )");
92 }
93
Greg Clayton1924e242010-09-15 05:51:24 +000094 bool show_fullpaths = false;
95 m_declaration.Dump(s, show_fullpaths);
Chris Lattner24943d22010-06-08 16:52:24 +000096
97 if (m_location.IsValid())
98 {
99 s->PutCString(", location = ");
Greg Clayton178710c2010-09-14 02:20:48 +0000100 lldb::addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
101 if (m_location.IsLocationList())
102 {
103 SymbolContext variable_sc;
104 m_owner_scope->CalculateSymbolContext(&variable_sc);
105 if (variable_sc.function)
106 loclist_base_addr = variable_sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
107 }
108 m_location.GetDescription(s, lldb::eDescriptionLevelBrief, loclist_base_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000109 }
110
111 if (m_external)
112 s->PutCString(", external");
113
114 if (m_artificial)
115 s->PutCString(", artificial");
116
117 s->EOL();
118}
119
120
121size_t
122Variable::MemorySize() const
123{
124 return sizeof(Variable);
125}
126
127
128void
129Variable::CalculateSymbolContext (SymbolContext *sc)
130{
Greg Clayton4fb08152010-08-30 18:11:35 +0000131 if (m_owner_scope)
132 m_owner_scope->CalculateSymbolContext(sc);
Chris Lattner24943d22010-06-08 16:52:24 +0000133 else
134 sc->Clear();
135}
136
137
138bool
139Variable::IsInScope (StackFrame *frame)
140{
141 switch (m_scope)
142 {
143 case eValueTypeVariableGlobal:
Greg Clayton178710c2010-09-14 02:20:48 +0000144 case eValueTypeVariableStatic:
Chris Lattner24943d22010-06-08 16:52:24 +0000145 // Globals and statics are always in scope.
146 return true;
147
148 case eValueTypeVariableArgument:
149 case eValueTypeVariableLocal:
150 // Check if the location has a location list that describes the value
151 // of the variable with address ranges and different locations for each
152 // address range?
153 if (m_location.IsLocationList())
154 {
Greg Clayton178710c2010-09-14 02:20:48 +0000155 SymbolContext sc;
156 CalculateSymbolContext(&sc);
157
158 // Currently we only support functions that have things with
159 // locations lists. If this expands, we will need to add support
160 assert (sc.function);
Greg Claytoneea26402010-09-14 23:36:40 +0000161 Target *target = &frame->GetThread().GetProcess().GetTarget();
162 addr_t loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
Greg Clayton178710c2010-09-14 02:20:48 +0000163 if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
164 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000165 // It is a location list. We just need to tell if the location
166 // list contains the current address when converted to a load
167 // address
Greg Claytoneea26402010-09-14 23:36:40 +0000168 return m_location.LocationListContainsAddress (loclist_base_load_addr, frame->GetFrameCodeAddress().GetLoadAddress (target));
Chris Lattner24943d22010-06-08 16:52:24 +0000169 }
170 else
171 {
172 // We don't have a location list, we just need to see if the block
173 // that this variable was defined in is currently
Greg Claytona357ecf2010-09-14 03:16:58 +0000174 Block *deepest_frame_block = frame->GetSymbolContext(eSymbolContextBlock).block;
175 if (deepest_frame_block)
Chris Lattner24943d22010-06-08 16:52:24 +0000176 {
177 SymbolContext variable_sc;
178 CalculateSymbolContext (&variable_sc);
Greg Claytona357ecf2010-09-14 03:16:58 +0000179 if (variable_sc.block == deepest_frame_block)
Greg Clayton178710c2010-09-14 02:20:48 +0000180 return true;
181
Greg Claytona357ecf2010-09-14 03:16:58 +0000182 return variable_sc.block->Contains (deepest_frame_block);
Chris Lattner24943d22010-06-08 16:52:24 +0000183 }
184 }
185 break;
186
187 default:
Greg Clayton178710c2010-09-14 02:20:48 +0000188 assert (!"Unhandled case");
Chris Lattner24943d22010-06-08 16:52:24 +0000189 break;
190 }
191 return false;
192}
193