1 //===-- 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 20 using namespace lldb; 21 using namespace lldb_private; 22 23 //---------------------------------------------------------------------- 24 // Variable constructor 25 //---------------------------------------------------------------------- 26 Variable::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 //---------------------------------------------------------------------- 50 Variable::~Variable() 51 { 52 } 53 54 55 void 56 Variable::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 109 size_t 110 Variable::MemorySize() const 111 { 112 return sizeof(Variable); 113 } 114 115 116 void 117 Variable::CalculateSymbolContext (SymbolContext *sc) 118 { 119 if (m_context) 120 m_context->CalculateSymbolContext(sc); 121 else 122 sc->Clear(); 123 } 124 125 126 bool 127 Variable::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 168