blob: 4ab9fa30bec4a9c42f745a8eeeabefcbf031bf5c [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 Claytonb04e7a82010-08-24 21:05:24 +000017#include "lldb/Target/RegisterContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/Target/StackFrame.h"
19#include "lldb/Target/Thread.h"
20
21using namespace lldb;
22using namespace lldb_private;
23
24//----------------------------------------------------------------------
25// Variable constructor
26//----------------------------------------------------------------------
27Variable::Variable(lldb::user_id_t uid,
28 const ConstString& name,
29 Type *type,
30 ValueType scope,
31 SymbolContextScope *context,
32 Declaration* decl_ptr,
33 const DWARFExpression& location,
34 bool external,
35 bool artificial) :
36 UserID(uid),
37 m_name(name),
38 m_type(type),
39 m_scope(scope),
Greg Clayton4fb08152010-08-30 18:11:35 +000040 m_owner_scope(context),
Chris Lattner24943d22010-06-08 16:52:24 +000041 m_declaration(decl_ptr),
42 m_location(location),
43 m_external(external),
44 m_artificial(artificial)
45{
46}
47
48//----------------------------------------------------------------------
49// Destructor
50//----------------------------------------------------------------------
51Variable::~Variable()
52{
53}
54
55
56void
57Variable::Dump(Stream *s, bool show_context) const
58{
59 s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
60 s->Indent();
61 *s << "Variable" << (const UserID&)*this;
62
63 if (m_name)
64 *s << ", name = \"" << m_name << "\"";
65
66 if (m_type != NULL)
67 {
68 *s << ", type = " << (void*)m_type << " (";
69 m_type->DumpTypeName(s);
70 s->PutChar(')');
71 }
72
73 if (m_scope != eValueTypeInvalid)
74 {
75 s->PutCString(", scope = ");
76 switch (m_scope)
77 {
78 case eValueTypeVariableGlobal: s->PutCString(m_external ? "global" : "static"); break;
79 case eValueTypeVariableArgument: s->PutCString("parameter"); break;
80 case eValueTypeVariableLocal: s->PutCString("local"); break;
81 default: *s << "??? (" << m_scope << ')';
82 }
83 }
84
Greg Clayton4fb08152010-08-30 18:11:35 +000085 if (show_context && m_owner_scope != NULL)
Chris Lattner24943d22010-06-08 16:52:24 +000086 {
87 s->PutCString(", context = ( ");
Greg Clayton4fb08152010-08-30 18:11:35 +000088 m_owner_scope->DumpSymbolContext(s);
Chris Lattner24943d22010-06-08 16:52:24 +000089 s->PutCString(" )");
90 }
91
92 m_declaration.Dump(s);
93
94 if (m_location.IsValid())
95 {
96 s->PutCString(", location = ");
Greg Clayton178710c2010-09-14 02:20:48 +000097 lldb::addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
98 if (m_location.IsLocationList())
99 {
100 SymbolContext variable_sc;
101 m_owner_scope->CalculateSymbolContext(&variable_sc);
102 if (variable_sc.function)
103 loclist_base_addr = variable_sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
104 }
105 m_location.GetDescription(s, lldb::eDescriptionLevelBrief, loclist_base_addr);
Chris Lattner24943d22010-06-08 16:52:24 +0000106 }
107
108 if (m_external)
109 s->PutCString(", external");
110
111 if (m_artificial)
112 s->PutCString(", artificial");
113
114 s->EOL();
115}
116
117
118size_t
119Variable::MemorySize() const
120{
121 return sizeof(Variable);
122}
123
124
125void
126Variable::CalculateSymbolContext (SymbolContext *sc)
127{
Greg Clayton4fb08152010-08-30 18:11:35 +0000128 if (m_owner_scope)
129 m_owner_scope->CalculateSymbolContext(sc);
Chris Lattner24943d22010-06-08 16:52:24 +0000130 else
131 sc->Clear();
132}
133
134
135bool
136Variable::IsInScope (StackFrame *frame)
137{
138 switch (m_scope)
139 {
140 case eValueTypeVariableGlobal:
Greg Clayton178710c2010-09-14 02:20:48 +0000141 case eValueTypeVariableStatic:
Chris Lattner24943d22010-06-08 16:52:24 +0000142 // Globals and statics are always in scope.
143 return true;
144
145 case eValueTypeVariableArgument:
146 case eValueTypeVariableLocal:
147 // Check if the location has a location list that describes the value
148 // of the variable with address ranges and different locations for each
149 // address range?
150 if (m_location.IsLocationList())
151 {
Greg Clayton178710c2010-09-14 02:20:48 +0000152 SymbolContext sc;
153 CalculateSymbolContext(&sc);
154
155 // Currently we only support functions that have things with
156 // locations lists. If this expands, we will need to add support
157 assert (sc.function);
158 Process *process = &frame->GetThread().GetProcess();
159 addr_t loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (process);
160 if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
161 return false;
Chris Lattner24943d22010-06-08 16:52:24 +0000162 // It is a location list. We just need to tell if the location
163 // list contains the current address when converted to a load
164 // address
Greg Clayton178710c2010-09-14 02:20:48 +0000165 return m_location.LocationListContainsAddress (loclist_base_load_addr, frame->GetFrameCodeAddress().GetLoadAddress (process));
Chris Lattner24943d22010-06-08 16:52:24 +0000166 }
167 else
168 {
169 // We don't have a location list, we just need to see if the block
170 // that this variable was defined in is currently
Greg Claytona357ecf2010-09-14 03:16:58 +0000171 Block *deepest_frame_block = frame->GetSymbolContext(eSymbolContextBlock).block;
172 if (deepest_frame_block)
Chris Lattner24943d22010-06-08 16:52:24 +0000173 {
174 SymbolContext variable_sc;
175 CalculateSymbolContext (&variable_sc);
Greg Claytona357ecf2010-09-14 03:16:58 +0000176 if (variable_sc.block == deepest_frame_block)
Greg Clayton178710c2010-09-14 02:20:48 +0000177 return true;
178
Greg Claytona357ecf2010-09-14 03:16:58 +0000179 return variable_sc.block->Contains (deepest_frame_block);
Chris Lattner24943d22010-06-08 16:52:24 +0000180 }
181 }
182 break;
183
184 default:
Greg Clayton178710c2010-09-14 02:20:48 +0000185 assert (!"Unhandled case");
Chris Lattner24943d22010-06-08 16:52:24 +0000186 break;
187 }
188 return false;
189}
190