blob: b83cf4a330e87fa45f8cbf555c71c0f8ac4f092e [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) :
Sean Callanan8bce6652010-07-13 21:41:46 +000041 m_exe_ctx(exe_ctx),
42 m_struct_laid_out(false)
Chris Lattner24943d22010-06-08 16:52:24 +000043{
44 if (exe_ctx && exe_ctx->frame)
45 m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
46 else
47 m_sym_ctx = NULL;
48}
49
50ClangExpressionDeclMap::~ClangExpressionDeclMap()
51{
52 uint32_t num_tuples = m_tuples.size ();
53 uint32_t tuple_index;
54
55 for (tuple_index = 0; tuple_index < num_tuples; ++tuple_index)
56 delete m_tuples[tuple_index].m_value;
57
58 if (m_sym_ctx)
59 delete m_sym_ctx;
60}
61
62bool
63ClangExpressionDeclMap::GetIndexForDecl (uint32_t &index,
64 const clang::Decl *decl)
65{
66 uint32_t num_tuples = m_tuples.size ();
67 uint32_t tuple_index;
68
69 for (tuple_index = 0; tuple_index < num_tuples; ++tuple_index)
70 {
71 if (m_tuples[tuple_index].m_decl == decl)
72 {
73 index = tuple_index;
74 return true;
75 }
76 }
77
78 return false;
79}
80
Sean Callanan8bce6652010-07-13 21:41:46 +000081// Interface for IRForTarget
82
83bool
84ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value,
85 const clang::NamedDecl *decl,
86 size_t size,
87 off_t alignment)
88{
89 m_struct_laid_out = false;
90
91 StructMemberIterator iter;
92
93 for (iter = m_members.begin();
94 iter != m_members.end();
95 ++iter)
96 {
97 if (iter->m_decl == decl)
98 return true;
99 }
100
101 StructMember member;
102
103 member.m_value = value;
104 member.m_decl = decl;
105 member.m_offset = 0;
106 member.m_size = size;
107 member.m_alignment = alignment;
108
109 m_members.push_back(member);
110
111 return true;
112}
113
114bool
115ClangExpressionDeclMap::DoStructLayout ()
116{
117 if (m_struct_laid_out)
118 return true;
119
120 StructMemberIterator iter;
121
122 off_t cursor = 0;
123
124 m_struct_alignment = 0;
125 m_struct_size = 0;
126
127 for (iter = m_members.begin();
128 iter != m_members.end();
129 ++iter)
130 {
131 if (iter == m_members.begin())
132 m_struct_alignment = iter->m_alignment;
133
134 if (cursor % iter->m_alignment)
135 cursor += (iter->m_alignment - (cursor % iter->m_alignment));
136
137 iter->m_offset = cursor;
138 cursor += iter->m_size;
139 }
140
141 m_struct_size = cursor;
142
143 m_struct_laid_out = true;
144 return true;
145}
146
147bool ClangExpressionDeclMap::GetStructInfo (uint32_t &num_elements,
148 size_t &size,
149 off_t &alignment)
150{
151 if (!m_struct_laid_out)
152 return false;
153
154 num_elements = m_members.size();
155 size = m_struct_size;
156 alignment = m_struct_alignment;
157
158 return true;
159}
160
161bool
162ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl,
163 llvm::Value *&value,
164 off_t &offset,
165 uint32_t index)
166{
167 if (!m_struct_laid_out)
168 return false;
169
170 if (index >= m_members.size())
171 return false;
172
173 decl = m_members[index].m_decl;
174 value = m_members[index].m_value;
175 offset = m_members[index].m_offset;
176
177 return true;
178}
179
Chris Lattner24943d22010-06-08 16:52:24 +0000180// Interface for DwarfExpression
181Value
182*ClangExpressionDeclMap::GetValueForIndex (uint32_t index)
183{
184 if (index >= m_tuples.size ())
185 return NULL;
186
187 return m_tuples[index].m_value;
188}
189
190// Interface for ClangASTSource
191void
192ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
193 const char *name)
194{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000195 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
196
197 DEBUG_PRINTF("Hunting for a definition for %s", name);
Chris Lattner24943d22010-06-08 16:52:24 +0000198
199 // Back out in all cases where we're not fully initialized
200 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
201 return;
202
203 Function *function = m_sym_ctx->function;
204 Block *block = m_sym_ctx->block;
205
206 if (!function || !block)
207 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000208 DEBUG_PRINTF("function = %p, block = %p", function, block);
Chris Lattner24943d22010-06-08 16:52:24 +0000209 return;
210 }
211
212 BlockList& blocks = function->GetBlocks(true);
213
214 lldb::user_id_t current_block_id = block->GetID();
215
216 ConstString name_cs(name);
217
Sean Callanan8f0dc342010-06-22 23:46:24 +0000218 Function *fn = m_sym_ctx->FindFunctionByName(name_cs.GetCString());
219
220 if (fn)
221 {
222 AddOneFunction(context, fn);
223 }
224
Chris Lattner24943d22010-06-08 16:52:24 +0000225 for (current_block_id = block->GetID();
226 current_block_id != Block::InvalidID;
227 current_block_id = blocks.GetParent(current_block_id))
228 {
229 Block *current_block = blocks.GetBlockByID(current_block_id);
230
231 lldb::VariableListSP var_list = current_block->GetVariableList(false, true);
232
233 if (!var_list)
234 continue;
235
236 lldb::VariableSP var = var_list->FindVariable(name_cs);
237
238 if (!var)
239 continue;
240
241 AddOneVariable(context, var.get());
242 return;
243 }
244
245 {
246 CompileUnit *compile_unit = m_sym_ctx->comp_unit;
247
248 if (!compile_unit)
249 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000250 DEBUG_PRINTF("compile_unit = %p", compile_unit);
Chris Lattner24943d22010-06-08 16:52:24 +0000251 return;
252 }
253
254 lldb::VariableListSP var_list = compile_unit->GetVariableList(true);
255
256 if (!var_list)
257 return;
258
259 lldb::VariableSP var = var_list->FindVariable(name_cs);
260
261 if (!var)
262 return;
263
264 AddOneVariable(context, var.get());
265 return;
266 }
267}
268
269void
270ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
271 Variable* var)
272{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000273 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
274
Chris Lattner24943d22010-06-08 16:52:24 +0000275 Type *var_type = var->GetType();
276
277 if (!var_type)
278 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000279 DEBUG_PRINTF("Skipped a definition because it has no type");
Chris Lattner24943d22010-06-08 16:52:24 +0000280 return;
281 }
282
283 void *var_opaque_type = var_type->GetOpaqueClangQualType();
284
285 if (!var_opaque_type)
286 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000287 DEBUG_PRINTF("Skipped a definition because it has no Clang type");
Chris Lattner24943d22010-06-08 16:52:24 +0000288 return;
289 }
290
291 DWARFExpression &var_location_expr = var->LocationExpression();
292
293 TypeList *type_list = var_type->GetTypeList();
294
295 if (!type_list)
296 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000297 DEBUG_PRINTF("Skipped a definition because the type has no associated type list");
Chris Lattner24943d22010-06-08 16:52:24 +0000298 return;
299 }
300
301 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
302
303 if (!exe_ast_ctx)
304 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000305 DEBUG_PRINTF("There is no AST context for the current execution context");
Chris Lattner24943d22010-06-08 16:52:24 +0000306 return;
307 }
308
309 std::auto_ptr<Value> var_location(new Value);
310
311 Error err;
312
313 if (!var_location_expr.Evaluate(m_exe_ctx, exe_ast_ctx, NULL, *var_location.get(), &err))
314 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000315 DEBUG_PRINTF("Error evaluating location: %s", err.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000316 return;
317 }
318
319 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), type_list->GetClangASTContext().getASTContext(), var_opaque_type);
320
321 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
322 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type);
323
324 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
325 {
326 SymbolContext var_sc;
327 var->CalculateSymbolContext(&var_sc);
328
329 if (!var_sc.module_sp)
330 return;
331
332 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
333
334 if (!object_file)
335 return;
336
337 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
338
339 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->process);
340
341 var_location->GetScalar() = load_addr;
342 var_location->SetValueType(Value::eValueTypeLoadAddress);
343 }
344
345 NamedDecl *var_decl = context.AddVarDecl(copied_type);
346
347 Tuple tuple;
348
349 tuple.m_decl = var_decl;
350 tuple.m_value = var_location.release();
351
352 m_tuples.push_back(tuple);
353
Sean Callanan6184dfe2010-06-23 00:47:48 +0000354 DEBUG_PRINTF("Found variable");
Sean Callanan8f0dc342010-06-22 23:46:24 +0000355}
356
357void
358ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
359 Function* fun)
360{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000361 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
362
Sean Callanan8f0dc342010-06-22 23:46:24 +0000363 Type *fun_type = fun->GetType();
364
365 if (!fun_type)
366 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000367 DEBUG_PRINTF("Skipped a function because it has no type");
Sean Callanan8f0dc342010-06-22 23:46:24 +0000368 return;
369 }
370
371 void *fun_opaque_type = fun_type->GetOpaqueClangQualType();
372
373 if (!fun_opaque_type)
374 {
Sean Callanan6184dfe2010-06-23 00:47:48 +0000375 DEBUG_PRINTF("Skipped a function because it has no Clang type");
Sean Callanan8f0dc342010-06-22 23:46:24 +0000376 return;
377 }
378
379 std::auto_ptr<Value> fun_location(new Value);
380
381 const Address &fun_address = fun->GetAddressRange().GetBaseAddress();
382 lldb::addr_t load_addr = fun_address.GetLoadAddress(m_exe_ctx->process);
383 fun_location->SetValueType(Value::eValueTypeLoadAddress);
384 fun_location->GetScalar() = load_addr;
385
386 TypeList *type_list = fun_type->GetTypeList();
387 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), type_list->GetClangASTContext().getASTContext(), fun_opaque_type);
388
389 NamedDecl *fun_decl = context.AddFunDecl(copied_type);
390
391 Tuple tuple;
392
393 tuple.m_decl = fun_decl;
394 tuple.m_value = fun_location.release();
395
396 m_tuples.push_back(tuple);
397
Sean Callanan6184dfe2010-06-23 00:47:48 +0000398 DEBUG_PRINTF("Found function");
Chris Lattner24943d22010-06-08 16:52:24 +0000399}