First step of refactoring variable handling in the
expression parser. There shouldn't be four separate
classes encapsulating a variable.
ClangExpressionVariable is now meant to be the
container for all variable information. It has
several optional components that hold data for
different subsystems.
ClangPersistentVariable has been removed; we now
use ClangExpressionVariable instead.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@111600 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangExpressionVariable.cpp b/source/Expression/ClangExpressionVariable.cpp
index dce0316..d41e620 100644
--- a/source/Expression/ClangExpressionVariable.cpp
+++ b/source/Expression/ClangExpressionVariable.cpp
@@ -14,74 +14,155 @@
// Other libraries and framework includes
// Project includes
#include "clang/AST/ASTContext.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/Value.h"
using namespace lldb_private;
using namespace clang;
-ClangExpressionVariableList::ClangExpressionVariableList() :
- m_variables()
+ClangExpressionVariable::ClangExpressionVariable()
{
+ m_name = "";
+ m_user_type = TypeFromUser(NULL, NULL);
+ m_parser_vars.reset(NULL);
+ m_jit_vars.reset(NULL);
+ m_data_vars.reset(NULL);
}
-ClangExpressionVariableList::~ClangExpressionVariableList()
+void ClangExpressionVariable::DisableDataVars()
{
- uint32_t num_variables = m_variables.size();
- uint32_t var_index;
-
- for (var_index = 0; var_index < num_variables; ++var_index)
- delete m_variables[var_index].m_value;
+ if (m_data_vars.get() && m_data_vars->m_data)
+ delete m_data_vars->m_data;
+ m_data_vars.reset();
}
-Value *
-ValueForDecl(const VarDecl *var_decl)
+Error
+ClangExpressionVariable::Print (Stream &output_stream,
+ ExecutionContext &exe_ctx,
+ lldb::Format format,
+ bool show_types,
+ bool show_summary,
+ bool verbose)
{
- Value *ret = new Value;
-
- ret->SetContext(Value::eContextTypeOpaqueClangQualType,
- var_decl->getType().getAsOpaquePtr());
+ Error err;
- uint64_t bit_width = var_decl->getASTContext().getTypeSize(var_decl->getType());
-
- uint32_t byte_size = (bit_width + 7 ) / 8;
-
- ret->ResizeData(byte_size);
-
- return ret;
-}
-
-Value *
-ClangExpressionVariableList::GetVariableForVarDecl (const VarDecl *var_decl, uint32_t& idx, bool can_create)
-{
- uint32_t num_variables = m_variables.size();
- uint32_t var_index;
-
- for (var_index = 0; var_index < num_variables; ++var_index)
+ if (!m_data_vars.get() || !m_data_vars->m_data)
{
- if (m_variables[var_index].m_var_decl == var_decl)
- {
- idx = var_index;
- return m_variables[var_index].m_value;
- }
+ err.SetErrorToGenericError();
+ err.SetErrorStringWithFormat("Variable doesn't contain a value");
+ return err;
}
-
- if (!can_create)
- return NULL;
- idx = m_variables.size();
+ Value val;
- ClangExpressionVariable val;
- val.m_var_decl = var_decl;
- val.m_value = ValueForDecl(var_decl);
- m_variables.push_back(val);
+ clang::ASTContext *ast_context = m_user_type.GetASTContext();
- return m_variables.back().m_value;
+ val.SetContext (Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType ());
+ val.SetValueType (Value::eValueTypeHostAddress);
+ val.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes ();
+
+ val.ResolveValue (&exe_ctx, ast_context);
+
+ if (val.GetContextType () == Value::eContextTypeInvalid &&
+ val.GetValueType () == Value::eValueTypeScalar &&
+ format == lldb::eFormatDefault)
+ {
+ // The expression result is just a scalar with no special formatting
+ val.GetScalar ().GetValue (&output_stream, show_types);
+ output_stream.EOL ();
+ return err;
+ }
+
+ // The expression result is more complex and requires special handling
+ DataExtractor data;
+ Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0);
+
+ if (!expr_error.Success ())
+ {
+ err.SetErrorToGenericError ();
+ err.SetErrorStringWithFormat ("Couldn't resolve variable value: %s", expr_error.AsCString ());
+ return err;
+ }
+
+ if (format == lldb::eFormatDefault)
+ format = val.GetValueDefaultFormat ();
+
+ void *clang_type = val.GetValueOpaqueClangQualType ();
+
+ output_stream.Printf("%s = ", m_name.c_str());
+
+ if (clang_type)
+ {
+ if (show_types)
+ output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString());
+
+ ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to
+ clang_type, // The opaque clang type we want to dump that value of
+ &exe_ctx, // The execution context for memory and variable access
+ &output_stream, // Stream to dump to
+ format, // Format to use when dumping
+ data, // A buffer containing the bytes for the clang type
+ 0, // Byte offset within "data" where value is
+ data.GetByteSize (), // Size in bytes of the value we are dumping
+ 0, // Bitfield bit size
+ 0, // Bitfield bit offset
+ show_types, // Show types?
+ show_summary, // Show summary?
+ verbose, // Debug logging output?
+ UINT32_MAX); // Depth to dump in case this is an aggregate type
+ }
+ else
+ {
+ data.Dump (&output_stream, // Stream to dump to
+ 0, // Byte offset within "data"
+ format, // Format to use when dumping
+ data.GetByteSize (), // Size in bytes of each item we are dumping
+ 1, // Number of items to dump
+ UINT32_MAX, // Number of items per line
+ LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context
+ 0, // Bitfield bit size
+ 0); // Bitfield bit offset
+ }
+
+ output_stream.EOL();
+
+ return err;
}
-Value *
-ClangExpressionVariableList::GetVariableAtIndex (uint32_t idx)
+ClangExpressionVariable::ClangExpressionVariable(const ClangExpressionVariable &cev) :
+ m_name(cev.m_name),
+ m_user_type(cev.m_user_type)
{
- if (idx < m_variables.size())
- return m_variables[idx].m_value;
+ if (cev.m_parser_vars.get())
+ {
+ m_parser_vars.reset(new struct ParserVars);
+ *m_parser_vars.get() = *cev.m_parser_vars.get();
+ }
- return NULL;
+ if (cev.m_jit_vars.get())
+ {
+ m_jit_vars.reset(new struct JITVars);
+ *m_jit_vars.get() = *cev.m_jit_vars.get();
+ }
+
+ if (cev.m_data_vars.get())
+ {
+ m_data_vars.reset(new struct DataVars);
+ *m_data_vars.get() = *cev.m_data_vars.get();
+ }
+}
+
+bool
+ClangExpressionVariable::PointValueAtData(Value &value)
+{
+ if (!m_data_vars.get())
+ return false;
+
+ value.SetContext(Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType());
+ value.SetValueType(Value::eValueTypeHostAddress);
+ value.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes();
+
+ return true;
}