blob: c65ab1349cae183d2d43df951f613e04eacf4b5b [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"
18#include "lldb/Core/Module.h"
19#include "lldb/Expression/ClangASTSource.h"
20#include "lldb/Symbol/ClangASTContext.h"
21#include "lldb/Symbol/CompileUnit.h"
22#include "lldb/Symbol/Function.h"
23#include "lldb/Symbol/ObjectFile.h"
24#include "lldb/Symbol/SymbolContext.h"
25#include "lldb/Symbol/Type.h"
26#include "lldb/Symbol/TypeList.h"
27#include "lldb/Symbol/Variable.h"
28#include "lldb/Symbol/VariableList.h"
29#include "lldb/Target/StackFrame.h"
30#include "lldb/Target/ExecutionContext.h"
31
32//#define DEBUG_CEDM
33#ifdef DEBUG_CEDM
34#define DEBUG_PRINTF(...) fprintf(stderr, __VA_ARGS__)
35#else
36#define DEBUG_PRINTF(...)
37#endif
38
39using namespace lldb_private;
40using namespace clang;
41
42ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) :
43 m_exe_ctx(exe_ctx)
44{
45 if (exe_ctx && exe_ctx->frame)
46 m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
47 else
48 m_sym_ctx = NULL;
49}
50
51ClangExpressionDeclMap::~ClangExpressionDeclMap()
52{
53 uint32_t num_tuples = m_tuples.size ();
54 uint32_t tuple_index;
55
56 for (tuple_index = 0; tuple_index < num_tuples; ++tuple_index)
57 delete m_tuples[tuple_index].m_value;
58
59 if (m_sym_ctx)
60 delete m_sym_ctx;
61}
62
63bool
64ClangExpressionDeclMap::GetIndexForDecl (uint32_t &index,
65 const clang::Decl *decl)
66{
67 uint32_t num_tuples = m_tuples.size ();
68 uint32_t tuple_index;
69
70 for (tuple_index = 0; tuple_index < num_tuples; ++tuple_index)
71 {
72 if (m_tuples[tuple_index].m_decl == decl)
73 {
74 index = tuple_index;
75 return true;
76 }
77 }
78
79 return false;
80}
81
82// Interface for DwarfExpression
83Value
84*ClangExpressionDeclMap::GetValueForIndex (uint32_t index)
85{
86 if (index >= m_tuples.size ())
87 return NULL;
88
89 return m_tuples[index].m_value;
90}
91
92// Interface for ClangASTSource
93void
94ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
95 const char *name)
96{
97 DEBUG_PRINTF("Hunting for a definition for %s\n", name);
98
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 {
108 DEBUG_PRINTF("function = %p, block = %p\n", function, block);
109 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 {
150 DEBUG_PRINTF("compile_unit = %p\n", compile_unit);
151 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{
173 Type *var_type = var->GetType();
174
175 if (!var_type)
176 {
Sean Callanan8f0dc342010-06-22 23:46:24 +0000177 DEBUG_PRINTF("Skipped a definition because it has no type\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000178 return;
179 }
180
181 void *var_opaque_type = var_type->GetOpaqueClangQualType();
182
183 if (!var_opaque_type)
184 {
Sean Callanan8f0dc342010-06-22 23:46:24 +0000185 DEBUG_PRINTF("Skipped a definition because it has no Clang type\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000186 return;
187 }
188
189 DWARFExpression &var_location_expr = var->LocationExpression();
190
191 TypeList *type_list = var_type->GetTypeList();
192
193 if (!type_list)
194 {
Sean Callanan8f0dc342010-06-22 23:46:24 +0000195 DEBUG_PRINTF("Skipped a definition because the type has no associated type list\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000196 return;
197 }
198
199 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
200
201 if (!exe_ast_ctx)
202 {
203 DEBUG_PRINTF("There is no AST context for the current execution context\n");
204 return;
205 }
206
207 std::auto_ptr<Value> var_location(new Value);
208
209 Error err;
210
211 if (!var_location_expr.Evaluate(m_exe_ctx, exe_ast_ctx, NULL, *var_location.get(), &err))
212 {
Sean Callanan8f0dc342010-06-22 23:46:24 +0000213 DEBUG_PRINTF("Error evaluating location: %s\n", err.AsCString());
Chris Lattner24943d22010-06-08 16:52:24 +0000214 return;
215 }
216
217 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), type_list->GetClangASTContext().getASTContext(), var_opaque_type);
218
219 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
220 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type);
221
222 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
223 {
224 SymbolContext var_sc;
225 var->CalculateSymbolContext(&var_sc);
226
227 if (!var_sc.module_sp)
228 return;
229
230 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
231
232 if (!object_file)
233 return;
234
235 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
236
237 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->process);
238
239 var_location->GetScalar() = load_addr;
240 var_location->SetValueType(Value::eValueTypeLoadAddress);
241 }
242
243 NamedDecl *var_decl = context.AddVarDecl(copied_type);
244
245 Tuple tuple;
246
247 tuple.m_decl = var_decl;
248 tuple.m_value = var_location.release();
249
250 m_tuples.push_back(tuple);
251
Sean Callanan8f0dc342010-06-22 23:46:24 +0000252 DEBUG_PRINTF("Found variable\n");
253}
254
255void
256ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
257 Function* fun)
258{
259 Type *fun_type = fun->GetType();
260
261 if (!fun_type)
262 {
263 DEBUG_PRINTF("Skipped a function because it has no type\n");
264 return;
265 }
266
267 void *fun_opaque_type = fun_type->GetOpaqueClangQualType();
268
269 if (!fun_opaque_type)
270 {
271 DEBUG_PRINTF("Skipped a function because it has no Clang type\n");
272 return;
273 }
274
275 std::auto_ptr<Value> fun_location(new Value);
276
277 const Address &fun_address = fun->GetAddressRange().GetBaseAddress();
278 lldb::addr_t load_addr = fun_address.GetLoadAddress(m_exe_ctx->process);
279 fun_location->SetValueType(Value::eValueTypeLoadAddress);
280 fun_location->GetScalar() = load_addr;
281
282 TypeList *type_list = fun_type->GetTypeList();
283 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), type_list->GetClangASTContext().getASTContext(), fun_opaque_type);
284
285 NamedDecl *fun_decl = context.AddFunDecl(copied_type);
286
287 Tuple tuple;
288
289 tuple.m_decl = fun_decl;
290 tuple.m_value = fun_location.release();
291
292 m_tuples.push_back(tuple);
293
294 DEBUG_PRINTF("Found function\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000295}