blob: d78f84075dbcdc04f24f585aab1dc74c326b85b2 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangExpressionDeclMap.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/Expression/ClangExpressionDeclMap.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/lldb-private.h"
17#include "lldb/Core/Address.h"
Sean Callanan6184dfe2010-06-23 00:47:48 +000018#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Core/Module.h"
20#include "lldb/Expression/ClangASTSource.h"
21#include "lldb/Symbol/ClangASTContext.h"
22#include "lldb/Symbol/CompileUnit.h"
23#include "lldb/Symbol/Function.h"
24#include "lldb/Symbol/ObjectFile.h"
25#include "lldb/Symbol/SymbolContext.h"
26#include "lldb/Symbol/Type.h"
27#include "lldb/Symbol/TypeList.h"
28#include "lldb/Symbol/Variable.h"
29#include "lldb/Symbol/VariableList.h"
30#include "lldb/Target/StackFrame.h"
31#include "lldb/Target/ExecutionContext.h"
32
Sean Callanan6184dfe2010-06-23 00:47:48 +000033#define DEBUG_PRINTF(...) \
34 if (log) \
35 log->Printf(__VA_ARGS__)
Chris Lattner24943d22010-06-08 16:52:24 +000036
37using namespace lldb_private;
38using namespace clang;
39
40ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) :
41 m_exe_ctx(exe_ctx)
42{
43 if (exe_ctx && exe_ctx->frame)
44 m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
45 else
46 m_sym_ctx = NULL;
47}
48
49ClangExpressionDeclMap::~ClangExpressionDeclMap()
50{
51 uint32_t num_tuples = m_tuples.size ();
52 uint32_t tuple_index;
53
54 for (tuple_index = 0; tuple_index < num_tuples; ++tuple_index)
55 delete m_tuples[tuple_index].m_value;
56
57 if (m_sym_ctx)
58 delete m_sym_ctx;
59}
60
61bool
62ClangExpressionDeclMap::GetIndexForDecl (uint32_t &index,
63 const clang::Decl *decl)
64{
65 uint32_t num_tuples = m_tuples.size ();
66 uint32_t tuple_index;
67
68 for (tuple_index = 0; tuple_index < num_tuples; ++tuple_index)
69 {
70 if (m_tuples[tuple_index].m_decl == decl)
71 {
72 index = tuple_index;
73 return true;
74 }
75 }
76
77 return false;
78}
79
80// Interface for DwarfExpression
81Value
82*ClangExpressionDeclMap::GetValueForIndex (uint32_t index)
83{
84 if (index >= m_tuples.size ())
85 return NULL;
86
87 return m_tuples[index].m_value;
88}
89
90// Interface for ClangASTSource
91void
92ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
93 const char *name)
94{
Sean Callanan6184dfe2010-06-23 00:47:48 +000095 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
96
97 DEBUG_PRINTF("Hunting for a definition for %s", name);
Chris Lattner24943d22010-06-08 16:52:24 +000098
99 // Back out in all cases where we're not fully initialized
100 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
101 return;
102
103 Function *function = m_sym_ctx->function;
104 Block *block = m_sym_ctx->block;
105
106 if (!function || !block)
107 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000108 DEBUG_PRINTF("function = %p, block = %p", function, block);
Chris Lattner24943d22010-06-08 16:52:24 +0000109 return;
110 }
111
112 BlockList& blocks = function->GetBlocks(true);
113
114 lldb::user_id_t current_block_id = block->GetID();
115
116 ConstString name_cs(name);
117
Sean Callanan8f0dc342010-06-22 23:46:24 +0000118 Function *fn = m_sym_ctx->FindFunctionByName(name_cs.GetCString());
119
120 if (fn)
121 {
122 AddOneFunction(context, fn);
123 }
124
Chris Lattner24943d22010-06-08 16:52:24 +0000125 for (current_block_id = block->GetID();
126 current_block_id != Block::InvalidID;
127 current_block_id = blocks.GetParent(current_block_id))
128 {
129 Block *current_block = blocks.GetBlockByID(current_block_id);
130
131 lldb::VariableListSP var_list = current_block->GetVariableList(false, true);
132
133 if (!var_list)
134 continue;
135
136 lldb::VariableSP var = var_list->FindVariable(name_cs);
137
138 if (!var)
139 continue;
140
141 AddOneVariable(context, var.get());
142 return;
143 }
144
145 {
146 CompileUnit *compile_unit = m_sym_ctx->comp_unit;
147
148 if (!compile_unit)
149 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000150 DEBUG_PRINTF("compile_unit = %p", compile_unit);
Chris Lattner24943d22010-06-08 16:52:24 +0000151 return;
152 }
153
154 lldb::VariableListSP var_list = compile_unit->GetVariableList(true);
155
156 if (!var_list)
157 return;
158
159 lldb::VariableSP var = var_list->FindVariable(name_cs);
160
161 if (!var)
162 return;
163
164 AddOneVariable(context, var.get());
165 return;
166 }
167}
168
169void
170ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
171 Variable* var)
172{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000173 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
174
Chris Lattner24943d22010-06-08 16:52:24 +0000175 Type *var_type = var->GetType();
176
177 if (!var_type)
178 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000179 DEBUG_PRINTF("Skipped a definition because it has no type");
Chris Lattner24943d22010-06-08 16:52:24 +0000180 return;
181 }
182
183 void *var_opaque_type = var_type->GetOpaqueClangQualType();
184
185 if (!var_opaque_type)
186 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000187 DEBUG_PRINTF("Skipped a definition because it has no Clang type");
Chris Lattner24943d22010-06-08 16:52:24 +0000188 return;
189 }
190
191 DWARFExpression &var_location_expr = var->LocationExpression();
192
193 TypeList *type_list = var_type->GetTypeList();
194
195 if (!type_list)
196 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000197 DEBUG_PRINTF("Skipped a definition because the type has no associated type list");
Chris Lattner24943d22010-06-08 16:52:24 +0000198 return;
199 }
200
201 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
202
203 if (!exe_ast_ctx)
204 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000205 DEBUG_PRINTF("There is no AST context for the current execution context");
Chris Lattner24943d22010-06-08 16:52:24 +0000206 return;
207 }
208
209 std::auto_ptr<Value> var_location(new Value);
210
211 Error err;
212
213 if (!var_location_expr.Evaluate(m_exe_ctx, exe_ast_ctx, NULL, *var_location.get(), &err))
214 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000215 DEBUG_PRINTF("Error evaluating location: %s", err.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000216 return;
217 }
218
219 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), type_list->GetClangASTContext().getASTContext(), var_opaque_type);
220
221 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
222 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type);
223
224 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
225 {
226 SymbolContext var_sc;
227 var->CalculateSymbolContext(&var_sc);
228
229 if (!var_sc.module_sp)
230 return;
231
232 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
233
234 if (!object_file)
235 return;
236
237 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
238
239 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->process);
240
241 var_location->GetScalar() = load_addr;
242 var_location->SetValueType(Value::eValueTypeLoadAddress);
243 }
244
245 NamedDecl *var_decl = context.AddVarDecl(copied_type);
246
247 Tuple tuple;
248
249 tuple.m_decl = var_decl;
250 tuple.m_value = var_location.release();
251
252 m_tuples.push_back(tuple);
253
Sean Callanan6184dfe2010-06-23 00:47:48 +0000254 DEBUG_PRINTF("Found variable");
Sean Callanan8f0dc342010-06-22 23:46:24 +0000255}
256
257void
258ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
259 Function* fun)
260{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000261 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
262
Sean Callanan8f0dc342010-06-22 23:46:24 +0000263 Type *fun_type = fun->GetType();
264
265 if (!fun_type)
266 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000267 DEBUG_PRINTF("Skipped a function because it has no type");
Sean Callanan8f0dc342010-06-22 23:46:24 +0000268 return;
269 }
270
271 void *fun_opaque_type = fun_type->GetOpaqueClangQualType();
272
273 if (!fun_opaque_type)
274 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000275 DEBUG_PRINTF("Skipped a function because it has no Clang type");
Sean Callanan8f0dc342010-06-22 23:46:24 +0000276 return;
277 }
278
279 std::auto_ptr<Value> fun_location(new Value);
280
281 const Address &fun_address = fun->GetAddressRange().GetBaseAddress();
282 lldb::addr_t load_addr = fun_address.GetLoadAddress(m_exe_ctx->process);
283 fun_location->SetValueType(Value::eValueTypeLoadAddress);
284 fun_location->GetScalar() = load_addr;
285
286 TypeList *type_list = fun_type->GetTypeList();
287 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), type_list->GetClangASTContext().getASTContext(), fun_opaque_type);
288
289 NamedDecl *fun_decl = context.AddFunDecl(copied_type);
290
291 Tuple tuple;
292
293 tuple.m_decl = fun_decl;
294 tuple.m_value = fun_location.release();
295
296 m_tuples.push_back(tuple);
297
Sean Callanan6184dfe2010-06-23 00:47:48 +0000298 DEBUG_PRINTF("Found function");
Chris Lattner24943d22010-06-08 16:52:24 +0000299}