blob: 3931cfb2e74e53a8097b39b1dd983ed50a8a0fda [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangExpressionVariable.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/ClangExpressionVariable.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "clang/AST/ASTContext.h"
Sean Callanana6223432010-08-20 01:02:30 +000017#include "lldb/Core/ConstString.h"
18#include "lldb/Core/DataExtractor.h"
19#include "lldb/Core/Stream.h"
20#include "lldb/Core/Value.h"
Sean Callanane8a59a82010-09-13 21:34:21 +000021#include "lldb/Target/ExecutionContext.h"
22#include "lldb/Target/Process.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023
24using namespace lldb_private;
25using namespace clang;
26
Sean Callanana6223432010-08-20 01:02:30 +000027ClangExpressionVariable::ClangExpressionVariable()
Chris Lattner24943d22010-06-08 16:52:24 +000028{
Sean Callanana6223432010-08-20 01:02:30 +000029 m_name = "";
30 m_user_type = TypeFromUser(NULL, NULL);
31 m_parser_vars.reset(NULL);
32 m_jit_vars.reset(NULL);
33 m_data_vars.reset(NULL);
Chris Lattner24943d22010-06-08 16:52:24 +000034}
35
Sean Callanana6223432010-08-20 01:02:30 +000036void ClangExpressionVariable::DisableDataVars()
Chris Lattner24943d22010-06-08 16:52:24 +000037{
Sean Callanana6223432010-08-20 01:02:30 +000038 if (m_data_vars.get() && m_data_vars->m_data)
39 delete m_data_vars->m_data;
40 m_data_vars.reset();
Chris Lattner24943d22010-06-08 16:52:24 +000041}
42
Sean Callanana6223432010-08-20 01:02:30 +000043Error
44ClangExpressionVariable::Print (Stream &output_stream,
45 ExecutionContext &exe_ctx,
46 lldb::Format format,
47 bool show_types,
48 bool show_summary,
49 bool verbose)
Chris Lattner24943d22010-06-08 16:52:24 +000050{
Sean Callanana6223432010-08-20 01:02:30 +000051 Error err;
Chris Lattner24943d22010-06-08 16:52:24 +000052
Sean Callanana6223432010-08-20 01:02:30 +000053 if (!m_data_vars.get() || !m_data_vars->m_data)
Chris Lattner24943d22010-06-08 16:52:24 +000054 {
Sean Callanana6223432010-08-20 01:02:30 +000055 err.SetErrorToGenericError();
56 err.SetErrorStringWithFormat("Variable doesn't contain a value");
57 return err;
Chris Lattner24943d22010-06-08 16:52:24 +000058 }
Chris Lattner24943d22010-06-08 16:52:24 +000059
Sean Callanana6223432010-08-20 01:02:30 +000060 Value val;
Chris Lattner24943d22010-06-08 16:52:24 +000061
Sean Callanana6223432010-08-20 01:02:30 +000062 clang::ASTContext *ast_context = m_user_type.GetASTContext();
Chris Lattner24943d22010-06-08 16:52:24 +000063
Sean Callanana6223432010-08-20 01:02:30 +000064 val.SetContext (Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType ());
65 val.SetValueType (Value::eValueTypeHostAddress);
66 val.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes ();
67
68 val.ResolveValue (&exe_ctx, ast_context);
69
70 if (val.GetContextType () == Value::eContextTypeInvalid &&
71 val.GetValueType () == Value::eValueTypeScalar &&
72 format == lldb::eFormatDefault)
73 {
74 // The expression result is just a scalar with no special formatting
75 val.GetScalar ().GetValue (&output_stream, show_types);
76 output_stream.EOL ();
77 return err;
78 }
79
80 // The expression result is more complex and requires special handling
81 DataExtractor data;
82 Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0);
83
Sean Callanane8a59a82010-09-13 21:34:21 +000084
85 // Set byte order and pointer size to TARGET byte order and pointer size!
86
87 data.SetByteOrder(exe_ctx.process->GetByteOrder());
88 data.SetAddressByteSize(exe_ctx.process->GetAddressByteSize());
89
Sean Callanana6223432010-08-20 01:02:30 +000090 if (!expr_error.Success ())
91 {
92 err.SetErrorToGenericError ();
93 err.SetErrorStringWithFormat ("Couldn't resolve variable value: %s", expr_error.AsCString ());
94 return err;
95 }
96
97 if (format == lldb::eFormatDefault)
98 format = val.GetValueDefaultFormat ();
99
100 void *clang_type = val.GetValueOpaqueClangQualType ();
101
102 output_stream.Printf("%s = ", m_name.c_str());
103
104 if (clang_type)
105 {
106 if (show_types)
107 output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString());
108
109 ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to
110 clang_type, // The opaque clang type we want to dump that value of
111 &exe_ctx, // The execution context for memory and variable access
112 &output_stream, // Stream to dump to
113 format, // Format to use when dumping
114 data, // A buffer containing the bytes for the clang type
115 0, // Byte offset within "data" where value is
116 data.GetByteSize (), // Size in bytes of the value we are dumping
117 0, // Bitfield bit size
118 0, // Bitfield bit offset
119 show_types, // Show types?
120 show_summary, // Show summary?
121 verbose, // Debug logging output?
122 UINT32_MAX); // Depth to dump in case this is an aggregate type
123 }
124 else
125 {
126 data.Dump (&output_stream, // Stream to dump to
127 0, // Byte offset within "data"
128 format, // Format to use when dumping
129 data.GetByteSize (), // Size in bytes of each item we are dumping
130 1, // Number of items to dump
131 UINT32_MAX, // Number of items per line
132 LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context
133 0, // Bitfield bit size
134 0); // Bitfield bit offset
135 }
136
137 output_stream.EOL();
138
139 return err;
Chris Lattner24943d22010-06-08 16:52:24 +0000140}
141
Sean Callanana6223432010-08-20 01:02:30 +0000142ClangExpressionVariable::ClangExpressionVariable(const ClangExpressionVariable &cev) :
143 m_name(cev.m_name),
Sean Callanan8194e422010-08-30 21:15:33 +0000144 m_user_type(cev.m_user_type),
145 m_store(cev.m_store),
146 m_index(cev.m_index)
Chris Lattner24943d22010-06-08 16:52:24 +0000147{
Sean Callanana6223432010-08-20 01:02:30 +0000148 if (cev.m_parser_vars.get())
149 {
150 m_parser_vars.reset(new struct ParserVars);
151 *m_parser_vars.get() = *cev.m_parser_vars.get();
152 }
Chris Lattner24943d22010-06-08 16:52:24 +0000153
Sean Callanana6223432010-08-20 01:02:30 +0000154 if (cev.m_jit_vars.get())
155 {
156 m_jit_vars.reset(new struct JITVars);
157 *m_jit_vars.get() = *cev.m_jit_vars.get();
158 }
159
160 if (cev.m_data_vars.get())
161 {
162 m_data_vars.reset(new struct DataVars);
163 *m_data_vars.get() = *cev.m_data_vars.get();
164 }
165}
166
167bool
168ClangExpressionVariable::PointValueAtData(Value &value)
169{
170 if (!m_data_vars.get())
171 return false;
172
173 value.SetContext(Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType());
174 value.SetValueType(Value::eValueTypeHostAddress);
175 value.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes();
176
177 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000178}