blob: 35dcabfdd591a01a5743df7913dc174135d36426 [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"
17#include "lldb/Target/StackFrame.h"
18#include "lldb/Target/Thread.h"
19
20using namespace lldb;
21using namespace lldb_private;
22
23//----------------------------------------------------------------------
24// Variable constructor
25//----------------------------------------------------------------------
26Variable::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//----------------------------------------------------------------------
50Variable::~Variable()
51{
52}
53
54
55void
56Variable::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
109size_t
110Variable::MemorySize() const
111{
112 return sizeof(Variable);
113}
114
115
116void
117Variable::CalculateSymbolContext (SymbolContext *sc)
118{
119 if (m_context)
120 m_context->CalculateSymbolContext(sc);
121 else
122 sc->Clear();
123}
124
125
126bool
127Variable::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