blob: d41e6203d3b42c9f7c18dc1632489403278de7a1 [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"
Chris Lattner24943d22010-06-08 16:52:24 +000021
22using namespace lldb_private;
23using namespace clang;
24
Sean Callanana6223432010-08-20 01:02:30 +000025ClangExpressionVariable::ClangExpressionVariable()
Chris Lattner24943d22010-06-08 16:52:24 +000026{
Sean Callanana6223432010-08-20 01:02:30 +000027 m_name = "";
28 m_user_type = TypeFromUser(NULL, NULL);
29 m_parser_vars.reset(NULL);
30 m_jit_vars.reset(NULL);
31 m_data_vars.reset(NULL);
Chris Lattner24943d22010-06-08 16:52:24 +000032}
33
Sean Callanana6223432010-08-20 01:02:30 +000034void ClangExpressionVariable::DisableDataVars()
Chris Lattner24943d22010-06-08 16:52:24 +000035{
Sean Callanana6223432010-08-20 01:02:30 +000036 if (m_data_vars.get() && m_data_vars->m_data)
37 delete m_data_vars->m_data;
38 m_data_vars.reset();
Chris Lattner24943d22010-06-08 16:52:24 +000039}
40
Sean Callanana6223432010-08-20 01:02:30 +000041Error
42ClangExpressionVariable::Print (Stream &output_stream,
43 ExecutionContext &exe_ctx,
44 lldb::Format format,
45 bool show_types,
46 bool show_summary,
47 bool verbose)
Chris Lattner24943d22010-06-08 16:52:24 +000048{
Sean Callanana6223432010-08-20 01:02:30 +000049 Error err;
Chris Lattner24943d22010-06-08 16:52:24 +000050
Sean Callanana6223432010-08-20 01:02:30 +000051 if (!m_data_vars.get() || !m_data_vars->m_data)
Chris Lattner24943d22010-06-08 16:52:24 +000052 {
Sean Callanana6223432010-08-20 01:02:30 +000053 err.SetErrorToGenericError();
54 err.SetErrorStringWithFormat("Variable doesn't contain a value");
55 return err;
Chris Lattner24943d22010-06-08 16:52:24 +000056 }
Chris Lattner24943d22010-06-08 16:52:24 +000057
Sean Callanana6223432010-08-20 01:02:30 +000058 Value val;
Chris Lattner24943d22010-06-08 16:52:24 +000059
Sean Callanana6223432010-08-20 01:02:30 +000060 clang::ASTContext *ast_context = m_user_type.GetASTContext();
Chris Lattner24943d22010-06-08 16:52:24 +000061
Sean Callanana6223432010-08-20 01:02:30 +000062 val.SetContext (Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType ());
63 val.SetValueType (Value::eValueTypeHostAddress);
64 val.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes ();
65
66 val.ResolveValue (&exe_ctx, ast_context);
67
68 if (val.GetContextType () == Value::eContextTypeInvalid &&
69 val.GetValueType () == Value::eValueTypeScalar &&
70 format == lldb::eFormatDefault)
71 {
72 // The expression result is just a scalar with no special formatting
73 val.GetScalar ().GetValue (&output_stream, show_types);
74 output_stream.EOL ();
75 return err;
76 }
77
78 // The expression result is more complex and requires special handling
79 DataExtractor data;
80 Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0);
81
82 if (!expr_error.Success ())
83 {
84 err.SetErrorToGenericError ();
85 err.SetErrorStringWithFormat ("Couldn't resolve variable value: %s", expr_error.AsCString ());
86 return err;
87 }
88
89 if (format == lldb::eFormatDefault)
90 format = val.GetValueDefaultFormat ();
91
92 void *clang_type = val.GetValueOpaqueClangQualType ();
93
94 output_stream.Printf("%s = ", m_name.c_str());
95
96 if (clang_type)
97 {
98 if (show_types)
99 output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString());
100
101 ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to
102 clang_type, // The opaque clang type we want to dump that value of
103 &exe_ctx, // The execution context for memory and variable access
104 &output_stream, // Stream to dump to
105 format, // Format to use when dumping
106 data, // A buffer containing the bytes for the clang type
107 0, // Byte offset within "data" where value is
108 data.GetByteSize (), // Size in bytes of the value we are dumping
109 0, // Bitfield bit size
110 0, // Bitfield bit offset
111 show_types, // Show types?
112 show_summary, // Show summary?
113 verbose, // Debug logging output?
114 UINT32_MAX); // Depth to dump in case this is an aggregate type
115 }
116 else
117 {
118 data.Dump (&output_stream, // Stream to dump to
119 0, // Byte offset within "data"
120 format, // Format to use when dumping
121 data.GetByteSize (), // Size in bytes of each item we are dumping
122 1, // Number of items to dump
123 UINT32_MAX, // Number of items per line
124 LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context
125 0, // Bitfield bit size
126 0); // Bitfield bit offset
127 }
128
129 output_stream.EOL();
130
131 return err;
Chris Lattner24943d22010-06-08 16:52:24 +0000132}
133
Sean Callanana6223432010-08-20 01:02:30 +0000134ClangExpressionVariable::ClangExpressionVariable(const ClangExpressionVariable &cev) :
135 m_name(cev.m_name),
136 m_user_type(cev.m_user_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000137{
Sean Callanana6223432010-08-20 01:02:30 +0000138 if (cev.m_parser_vars.get())
139 {
140 m_parser_vars.reset(new struct ParserVars);
141 *m_parser_vars.get() = *cev.m_parser_vars.get();
142 }
Chris Lattner24943d22010-06-08 16:52:24 +0000143
Sean Callanana6223432010-08-20 01:02:30 +0000144 if (cev.m_jit_vars.get())
145 {
146 m_jit_vars.reset(new struct JITVars);
147 *m_jit_vars.get() = *cev.m_jit_vars.get();
148 }
149
150 if (cev.m_data_vars.get())
151 {
152 m_data_vars.reset(new struct DataVars);
153 *m_data_vars.get() = *cev.m_data_vars.get();
154 }
155}
156
157bool
158ClangExpressionVariable::PointValueAtData(Value &value)
159{
160 if (!m_data_vars.get())
161 return false;
162
163 value.SetContext(Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType());
164 value.SetValueType(Value::eValueTypeHostAddress);
165 value.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes();
166
167 return true;
Chris Lattner24943d22010-06-08 16:52:24 +0000168}