Added automatically generated result variables for each
expression. It is now possible to do things like this:
(lldb) expr int $i = 5; $i + 1
$0 = (int) 6
(lldb) expr $i + 3
$1 = (int) 8
(lldb) expr $1 + $0
$2 = (int) 14
As a bonus, this allowed us to move printing of
expression results into the ClangPersistentVariable
class. This code needs a bit of refactoring -- in
particular, ClangExpressionDeclMap has eaten one too
many bacteria and needs to undergo mitosis -- but the
infrastructure appears to be holding up nicely.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@110896 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangPersistentVariables.cpp b/source/Expression/ClangPersistentVariables.cpp
index dbeac00..7e16648 100644
--- a/source/Expression/ClangPersistentVariables.cpp
+++ b/source/Expression/ClangPersistentVariables.cpp
@@ -8,11 +8,98 @@
//===----------------------------------------------------------------------===//
#include "ClangPersistentVariables.h"
+#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Core/Value.h"
using namespace lldb_private;
-using namespace clang;
+
+Error
+ClangPersistentVariable::Print (Stream &output_stream,
+ ExecutionContext &exe_ctx,
+ lldb::Format format,
+ bool show_types,
+ bool show_summary,
+ bool verbose)
+{
+ Error err;
+
+ Value val;
+
+ clang::ASTContext *ast_context = m_user_type.GetASTContext();
+
+ val.SetContext (Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType ());
+ val.SetValueType (Value::eValueTypeHostAddress);
+ val.GetScalar() = (uint64_t)Data ();
+
+ 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 complext 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 result 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.AsCString("<anonymous>"));
+
+ 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;
+}
ClangPersistentVariables::ClangPersistentVariables () :
m_variables(),
@@ -24,7 +111,7 @@
ClangPersistentVariables::CreateVariable (ConstString name,
TypeFromUser user_type)
{
- ClangPersistentVariable new_var(user_type);
+ ClangPersistentVariable new_var(name, user_type);
if (m_variables.find(name) != m_variables.end())
return NULL;
@@ -35,21 +122,6 @@
}
ClangPersistentVariable *
-ClangPersistentVariables::CreateResultVariable (TypeFromUser user_type)
-{
- StreamString s;
- s.Printf("$%llu", m_result_counter);
- ConstString name(s.GetString().c_str());
-
- ClangPersistentVariable *ret = CreateVariable (name, user_type);
-
- if (ret != NULL)
- ++m_result_counter;
-
- return ret;
-}
-
-ClangPersistentVariable *
ClangPersistentVariables::GetVariable (ConstString name)
{
if (m_variables.find(name) == m_variables.end())
@@ -57,3 +129,14 @@
return &m_variables[name];
}
+
+void
+ClangPersistentVariables::GetNextResultName (std::string &name)
+{
+ StreamString s;
+ s.Printf("$%llu", m_result_counter);
+
+ m_result_counter++;
+
+ name = s.GetString();
+}