blob: 1065211e45b68e1d4ce0bad9f03f43d61b84385c [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
118 for (current_block_id = block->GetID();
119 current_block_id != Block::InvalidID;
120 current_block_id = blocks.GetParent(current_block_id))
121 {
122 Block *current_block = blocks.GetBlockByID(current_block_id);
123
124 lldb::VariableListSP var_list = current_block->GetVariableList(false, true);
125
126 if (!var_list)
127 continue;
128
129 lldb::VariableSP var = var_list->FindVariable(name_cs);
130
131 if (!var)
132 continue;
133
134 AddOneVariable(context, var.get());
135 return;
136 }
137
138 {
139 CompileUnit *compile_unit = m_sym_ctx->comp_unit;
140
141 if (!compile_unit)
142 {
143 DEBUG_PRINTF("compile_unit = %p\n", compile_unit);
144 return;
145 }
146
147 lldb::VariableListSP var_list = compile_unit->GetVariableList(true);
148
149 if (!var_list)
150 return;
151
152 lldb::VariableSP var = var_list->FindVariable(name_cs);
153
154 if (!var)
155 return;
156
157 AddOneVariable(context, var.get());
158 return;
159 }
160}
161
162void
163ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
164 Variable* var)
165{
166 Type *var_type = var->GetType();
167
168 if (!var_type)
169 {
170 DEBUG_PRINTF("Skipped a definition for %s because it has no type\n", name);
171 return;
172 }
173
174 void *var_opaque_type = var_type->GetOpaqueClangQualType();
175
176 if (!var_opaque_type)
177 {
178 DEBUG_PRINTF("Skipped a definition for %s because it has no Clang type\n", name);
179 return;
180 }
181
182 DWARFExpression &var_location_expr = var->LocationExpression();
183
184 TypeList *type_list = var_type->GetTypeList();
185
186 if (!type_list)
187 {
188 DEBUG_PRINTF("Skipped a definition for %s because the type has no associated type list\n", name);
189 return;
190 }
191
192 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
193
194 if (!exe_ast_ctx)
195 {
196 DEBUG_PRINTF("There is no AST context for the current execution context\n");
197 return;
198 }
199
200 std::auto_ptr<Value> var_location(new Value);
201
202 Error err;
203
204 if (!var_location_expr.Evaluate(m_exe_ctx, exe_ast_ctx, NULL, *var_location.get(), &err))
205 {
206 DEBUG_PRINTF("Error evaluating the location of %s: %s\n", name, err.AsCString());
207 return;
208 }
209
210 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), type_list->GetClangASTContext().getASTContext(), var_opaque_type);
211
212 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
213 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type);
214
215 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
216 {
217 SymbolContext var_sc;
218 var->CalculateSymbolContext(&var_sc);
219
220 if (!var_sc.module_sp)
221 return;
222
223 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
224
225 if (!object_file)
226 return;
227
228 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
229
230 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->process);
231
232 var_location->GetScalar() = load_addr;
233 var_location->SetValueType(Value::eValueTypeLoadAddress);
234 }
235
236 NamedDecl *var_decl = context.AddVarDecl(copied_type);
237
238 Tuple tuple;
239
240 tuple.m_decl = var_decl;
241 tuple.m_value = var_location.release();
242
243 m_tuples.push_back(tuple);
244
245 DEBUG_PRINTF("Found for a definition for %s\n", name);
246}